mirror of
https://github.com/crocofied/CoreControl.git
synced 2025-12-17 15:36:50 +00:00
Servers.tsx i18n
This commit is contained in:
parent
58e2466875
commit
c4f3b47fc7
@ -28,6 +28,8 @@ import {
|
|||||||
Copy,
|
Copy,
|
||||||
History,
|
History,
|
||||||
Thermometer,
|
Thermometer,
|
||||||
|
ChevronLeft,
|
||||||
|
ChevronRight,
|
||||||
} from "lucide-react"
|
} from "lucide-react"
|
||||||
import { Card, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
import { Card, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
||||||
import {
|
import {
|
||||||
@ -124,7 +126,7 @@ interface MonitoringData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function Servers() {
|
export default function Servers() {
|
||||||
const t = useTranslations('Servers')
|
const t = useTranslations()
|
||||||
const [host, setHost] = useState<boolean>(false)
|
const [host, setHost] = useState<boolean>(false)
|
||||||
const [hostServer, setHostServer] = useState<number>(0)
|
const [hostServer, setHostServer] = useState<number>(0)
|
||||||
const [name, setName] = useState<string>("")
|
const [name, setName] = useState<string>("")
|
||||||
@ -527,11 +529,11 @@ export default function Servers() {
|
|||||||
</BreadcrumbItem>
|
</BreadcrumbItem>
|
||||||
<BreadcrumbSeparator className="hidden md:block" />
|
<BreadcrumbSeparator className="hidden md:block" />
|
||||||
<BreadcrumbItem>
|
<BreadcrumbItem>
|
||||||
<BreadcrumbPage>{t('MyInfrastructure')}</BreadcrumbPage>
|
<BreadcrumbPage>{t('Servers.MyInfrastructure')}</BreadcrumbPage>
|
||||||
</BreadcrumbItem>
|
</BreadcrumbItem>
|
||||||
<BreadcrumbSeparator className="hidden md:block" />
|
<BreadcrumbSeparator className="hidden md:block" />
|
||||||
<BreadcrumbItem>
|
<BreadcrumbItem>
|
||||||
<BreadcrumbPage>{t('Servers')}</BreadcrumbPage>
|
<BreadcrumbPage>{t('Servers.Title')}</BreadcrumbPage>
|
||||||
</BreadcrumbItem>
|
</BreadcrumbItem>
|
||||||
</BreadcrumbList>
|
</BreadcrumbList>
|
||||||
</Breadcrumb>
|
</Breadcrumb>
|
||||||
@ -540,11 +542,11 @@ export default function Servers() {
|
|||||||
<Toaster />
|
<Toaster />
|
||||||
<div className="p-6">
|
<div className="p-6">
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<span className="text-3xl font-bold">{t('YourServers')}</span>
|
<span className="text-3xl font-bold">{t('Servers.YourServers')}</span>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button variant="outline" size="icon" title={t('ChangeView')}>
|
<Button variant="outline" size="icon" title={t('Common.ChangeView')}>
|
||||||
{isGridLayout ? (
|
{isGridLayout ? (
|
||||||
<LayoutGrid className="h-4 w-4" />
|
<LayoutGrid className="h-4 w-4" />
|
||||||
) : (
|
) : (
|
||||||
@ -554,10 +556,10 @@ export default function Servers() {
|
|||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent align="end">
|
<DropdownMenuContent align="end">
|
||||||
<DropdownMenuItem onClick={() => toggleLayout(false)}>
|
<DropdownMenuItem onClick={() => toggleLayout(false)}>
|
||||||
<List className="h-4 w-4 mr-2" /> {t('ListView')}
|
<List className="h-4 w-4 mr-2" /> {t('Common.ListView')}
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem onClick={() => toggleLayout(true)}>
|
<DropdownMenuItem onClick={() => toggleLayout(true)}>
|
||||||
<LayoutGrid className="h-4 w-4 mr-2" /> {t('GridView')}
|
<LayoutGrid className="h-4 w-4 mr-2" /> {t('Common.GridView')}
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
@ -573,23 +575,23 @@ export default function Servers() {
|
|||||||
>
|
>
|
||||||
<SelectTrigger className="w-[140px]">
|
<SelectTrigger className="w-[140px]">
|
||||||
<SelectValue>
|
<SelectValue>
|
||||||
{itemsPerPage} {itemsPerPage === 1 ? t('ItemsPerPage.item') : t('ItemsPerPage.items')}
|
{itemsPerPage} {itemsPerPage === 1 ? t('Common.ItemsPerPage.item') : t('Common.ItemsPerPage.items')}
|
||||||
</SelectValue>
|
</SelectValue>
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{![4, 6, 10, 15, 20, 25].includes(itemsPerPage) ? (
|
{![4, 6, 10, 15, 20, 25].includes(itemsPerPage) ? (
|
||||||
<SelectItem value={String(itemsPerPage)}>
|
<SelectItem value={String(itemsPerPage)}>
|
||||||
{itemsPerPage} {itemsPerPage === 1 ? t('ItemsPerPage.item') : t('ItemsPerPage.items')} ({t('ItemsPerPage.Custom')})
|
{itemsPerPage} {itemsPerPage === 1 ? t('Common.ItemsPerPage.item') : t('Common.ItemsPerPage.items')} ({t('Common.ItemsPerPage.Custom')})
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
) : null}
|
) : null}
|
||||||
<SelectItem value="4">{t('4')}</SelectItem>
|
<SelectItem value="4">{t('Common.ItemsPerPage.4')}</SelectItem>
|
||||||
<SelectItem value="6">{t('6')}</SelectItem>
|
<SelectItem value="6">{t('Common.ItemsPerPage.6')}</SelectItem>
|
||||||
<SelectItem value="10">{t('10')}</SelectItem>
|
<SelectItem value="10">{t('Common.ItemsPerPage.10')}</SelectItem>
|
||||||
<SelectItem value="15">{t('15')}</SelectItem>
|
<SelectItem value="15">{t('Common.ItemsPerPage.15')}</SelectItem>
|
||||||
<SelectItem value="20">{t('20')}</SelectItem>
|
<SelectItem value="20">{t('Common.ItemsPerPage.20')}</SelectItem>
|
||||||
<SelectItem value="25">{t('25')}</SelectItem>
|
<SelectItem value="25">{t('Common.ItemsPerPage.25')}</SelectItem>
|
||||||
<div className="p-2 border-t mt-1">
|
<div className="p-2 border-t mt-1">
|
||||||
<Label htmlFor="custom-items" className="text-xs font-medium">{t('ItemsPerPage.Custom')}</Label>
|
<Label htmlFor="custom-items" className="text-xs font-medium">{t('Common.ItemsPerPage.Custom')}</Label>
|
||||||
<div className="flex items-center gap-2 mt-1">
|
<div className="flex items-center gap-2 mt-1">
|
||||||
<Input
|
<Input
|
||||||
id="custom-items"
|
id="custom-items"
|
||||||
@ -640,7 +642,7 @@ export default function Servers() {
|
|||||||
}}
|
}}
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
/>
|
/>
|
||||||
<span className="text-xs text-muted-foreground whitespace-nowrap">{t('ItemsPerPage.items')}</span>
|
<span className="text-xs text-muted-foreground whitespace-nowrap">{t('Common.ItemsPerPage.items')}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
@ -655,7 +657,7 @@ export default function Servers() {
|
|||||||
<AlertDialogContent className="max-w-[95vw] w-[600px] max-h-[90vh] overflow-y-auto">
|
<AlertDialogContent className="max-w-[95vw] w-[600px] max-h-[90vh] overflow-y-auto">
|
||||||
<AlertDialogHeader>
|
<AlertDialogHeader>
|
||||||
<AlertDialogTitle className="flex flex-col sm:flex-row sm:justify-between sm:items-center gap-4">
|
<AlertDialogTitle className="flex flex-col sm:flex-row sm:justify-between sm:items-center gap-4">
|
||||||
<span>{t('AddServer.Title')}</span>
|
<span>{t('Servers.AddServer.Title')}</span>
|
||||||
<Select
|
<Select
|
||||||
onValueChange={(value) => {
|
onValueChange={(value) => {
|
||||||
if (!value) return;
|
if (!value) return;
|
||||||
@ -696,7 +698,7 @@ export default function Servers() {
|
|||||||
<SelectTrigger className="w-[140px] h-8 text-xs">
|
<SelectTrigger className="w-[140px] h-8 text-xs">
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<Copy className="h-3 w-3 text-muted-foreground" />
|
<Copy className="h-3 w-3 text-muted-foreground" />
|
||||||
<SelectValue placeholder="Copy server" />
|
<SelectValue placeholder={t('Servers.AddServer.General.CopyServer')} />
|
||||||
</div>
|
</div>
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
@ -711,20 +713,20 @@ export default function Servers() {
|
|||||||
<AlertDialogDescription>
|
<AlertDialogDescription>
|
||||||
<Tabs defaultValue="general" className="w-full">
|
<Tabs defaultValue="general" className="w-full">
|
||||||
<TabsList className="w-full">
|
<TabsList className="w-full">
|
||||||
<TabsTrigger value="general">{t('Tabs.General')}</TabsTrigger>
|
<TabsTrigger value="general">{t('Common.Server.Tabs.General')}</TabsTrigger>
|
||||||
<TabsTrigger value="hardware">{t('Tabs.Hardware')}</TabsTrigger>
|
<TabsTrigger value="hardware">{t('Common.Server.Tabs.Hardware')}</TabsTrigger>
|
||||||
<TabsTrigger value="virtualization">{t('Tabs.Host')}</TabsTrigger>
|
<TabsTrigger value="virtualization">{t('Common.Server.Tabs.Host')}</TabsTrigger>
|
||||||
<TabsTrigger value="monitoring">{t('Tabs.Monitoring')}</TabsTrigger>
|
<TabsTrigger value="monitoring">{t('Common.Server.Tabs.Monitoring')}</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
<TabsContent value="general">
|
<TabsContent value="general">
|
||||||
<div className="space-y-4 pt-4">
|
<div className="space-y-4 pt-4">
|
||||||
<div className="flex flex-col sm:flex-row items-start sm:items-center gap-4">
|
<div className="flex flex-col sm:flex-row items-start sm:items-center gap-4">
|
||||||
<div className="grid w-full sm:w-[calc(100%-52px)] items-center gap-1.5">
|
<div className="grid w-full sm:w-[calc(100%-52px)] items-center gap-1.5">
|
||||||
<Label htmlFor="icon">{t('AddServer.General.Icon')}</Label>
|
<Label htmlFor="icon">{t('Servers.AddServer.General.Icon')}</Label>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Select value={icon} onValueChange={(value) => setIcon(value)}>
|
<Select value={icon} onValueChange={(value) => setIcon(value)}>
|
||||||
<SelectTrigger className="w-full">
|
<SelectTrigger className="w-full">
|
||||||
<SelectValue placeholder={t('AddServer.General.IconPlaceholder')}>
|
<SelectValue placeholder={t('Servers.AddServer.General.IconPlaceholder')}>
|
||||||
{icon && (
|
{icon && (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<DynamicIcon name={icon as any} size={18} />
|
<DynamicIcon name={icon as any} size={18} />
|
||||||
@ -735,7 +737,7 @@ export default function Servers() {
|
|||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent className="max-h-[300px]">
|
<SelectContent className="max-h-[300px]">
|
||||||
<Input
|
<Input
|
||||||
placeholder={t('AddServer.General.IconSearchPlaceholder')}
|
placeholder={t('Servers.AddServer.General.IconSearchPlaceholder')}
|
||||||
className="mb-2"
|
className="mb-2"
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const iconElements = document.querySelectorAll("[data-icon-item]")
|
const iconElements = document.querySelectorAll("[data-icon-item]")
|
||||||
@ -776,14 +778,14 @@ export default function Servers() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid w-[52px] items-center gap-1.5">
|
<div className="grid w-[52px] items-center gap-1.5">
|
||||||
<Label htmlFor="icon">{t('AddServer.General.Preview')}</Label>
|
<Label htmlFor="icon">{t('Servers.AddServer.General.Preview')}</Label>
|
||||||
<div className="flex items-center justify-center">
|
<div className="flex items-center justify-center">
|
||||||
{icon && <DynamicIcon name={icon as any} size={36} />}
|
{icon && <DynamicIcon name={icon as any} size={36} />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="name">{t('AddServer.General.Name')}</Label>
|
<Label htmlFor="name">{t('Servers.AddServer.General.Name')}</Label>
|
||||||
<Input
|
<Input
|
||||||
id="name"
|
id="name"
|
||||||
type="text"
|
type="text"
|
||||||
@ -794,11 +796,11 @@ export default function Servers() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="description">
|
<Label htmlFor="description">
|
||||||
{t('AddServer.General.OperatingSystem')} <span className="text-stone-600">({t('optional')})</span>
|
{t('Servers.AddServer.General.OperatingSystem')} <span className="text-stone-600">({t('Common.optional')})</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Select value={os} onValueChange={(value) => setOs(value)}>
|
<Select value={os} onValueChange={(value) => setOs(value)}>
|
||||||
<SelectTrigger className="w-full">
|
<SelectTrigger className="w-full">
|
||||||
<SelectValue placeholder={t('AddServer.General.OperatingSystemPlaceholder')} />
|
<SelectValue placeholder={t('Servers.AddServer.General.OperatingSystemPlaceholder')} />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="Windows">Windows</SelectItem>
|
<SelectItem value="Windows">Windows</SelectItem>
|
||||||
@ -809,7 +811,7 @@ export default function Servers() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="ip">
|
<Label htmlFor="ip">
|
||||||
{t('AddServer.General.IPAdress')} <span className="text-stone-600">({t('optional')})</span>
|
{t('Servers.AddServer.General.IPAdress')} <span className="text-stone-600">({t('Common.optional')})</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
id="ip"
|
id="ip"
|
||||||
@ -824,11 +826,11 @@ export default function Servers() {
|
|||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger>
|
<TooltipTrigger>
|
||||||
<Label htmlFor="publicURL">
|
<Label htmlFor="publicURL">
|
||||||
{t('AddServer.General.ManagementURL')} <span className="text-stone-600">({t('optional')})</span>
|
{t('Servers.AddServer.General.ManagementURL')} <span className="text-stone-600">({t('Common.optional')})</span>
|
||||||
</Label>
|
</Label>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
{t('AddServer.General.ManagementURLTooltip')}
|
{t('Servers.AddServer.General.ManagementURLTooltip')}
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
@ -846,7 +848,7 @@ export default function Servers() {
|
|||||||
<div className="space-y-4 pt-4">
|
<div className="space-y-4 pt-4">
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="cpu">
|
<Label htmlFor="cpu">
|
||||||
{t('AddServer.Hardware.CPU')} <span className="text-stone-600">({t('optional')})</span>
|
{t('Common.Server.CPU')} <span className="text-stone-600">({t('Common.optional')})</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
id="cpu"
|
id="cpu"
|
||||||
@ -858,7 +860,7 @@ export default function Servers() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="gpu">
|
<Label htmlFor="gpu">
|
||||||
{t('AddServer.Hardware.GPU')} <span className="text-stone-600">({t('optional')})</span>
|
{t('Common.Server.GPU')} <span className="text-stone-600">({t('Common.optional')})</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
id="gpu"
|
id="gpu"
|
||||||
@ -870,7 +872,7 @@ export default function Servers() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="ram">
|
<Label htmlFor="ram">
|
||||||
{t('AddServer.Hardware.RAM')} <span className="text-stone-600">({t('optional')})</span>
|
{t('Common.Server.RAM')} <span className="text-stone-600">({t('Common.optional')})</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
id="ram"
|
id="ram"
|
||||||
@ -882,7 +884,7 @@ export default function Servers() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="disk">
|
<Label htmlFor="disk">
|
||||||
{t('AddServer.Hardware.Disk')} <span className="text-stone-600">({t('optional')})</span>
|
{t('Common.Server.Disk')} <span className="text-stone-600">({t('Common.optional')})</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
id="disk"
|
id="disk"
|
||||||
@ -902,11 +904,11 @@ export default function Servers() {
|
|||||||
checked={host}
|
checked={host}
|
||||||
onCheckedChange={(checked) => setHost(checked === true)}
|
onCheckedChange={(checked) => setHost(checked === true)}
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="hostCheckbox">{t('AddServer.Host.MarkAsHostServer')}</Label>
|
<Label htmlFor="hostCheckbox">{t('Servers.AddServer.Host.MarkAsHostServer')}</Label>
|
||||||
</div>
|
</div>
|
||||||
{!host && (
|
{!host && (
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label>{t('AddServer.Host.SelectHostServer')}</Label>
|
<Label>{t('Servers.AddServer.Host.SelectHostServer')}</Label>
|
||||||
<Select
|
<Select
|
||||||
value={hostServer?.toString()}
|
value={hostServer?.toString()}
|
||||||
onValueChange={(value) => {
|
onValueChange={(value) => {
|
||||||
@ -918,10 +920,10 @@ export default function Servers() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder={t('AddServer.Host.SelectHostServerPlaceholder')} />
|
<SelectValue placeholder={t('Servers.AddServer.Host.SelectHostServerPlaceholder')} />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="0">{t('AddServer.Host.NoHostServer')}</SelectItem>
|
<SelectItem value="0">{t('Servers.AddServer.Host.NoHostServer')}</SelectItem>
|
||||||
{hostServers.map((server) => (
|
{hostServers.map((server) => (
|
||||||
<SelectItem key={server.id} value={server.id.toString()}>
|
<SelectItem key={server.id} value={server.id.toString()}>
|
||||||
{server.name}
|
{server.name}
|
||||||
@ -941,12 +943,12 @@ export default function Servers() {
|
|||||||
checked={monitoring}
|
checked={monitoring}
|
||||||
onCheckedChange={(checked) => setMonitoring(checked === true)}
|
onCheckedChange={(checked) => setMonitoring(checked === true)}
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="monitoringCheckbox">{t('AddServer.Monitoring.Enable')}</Label>
|
<Label htmlFor="monitoringCheckbox">{t('Servers.AddServer.Monitoring.Enable')}</Label>
|
||||||
</div>
|
</div>
|
||||||
{monitoring && (
|
{monitoring && (
|
||||||
<>
|
<>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="monitoringURL">{t('AddServer.Monitoring.URL')}</Label>
|
<Label htmlFor="monitoringURL">{t('Servers.AddServer.Monitoring.URL')}</Label>
|
||||||
<Input
|
<Input
|
||||||
id="monitoringURL"
|
id="monitoringURL"
|
||||||
type="text"
|
type="text"
|
||||||
@ -956,9 +958,9 @@ export default function Servers() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-4 p-4 border rounded-lg bg-muted">
|
<div className="mt-4 p-4 border rounded-lg bg-muted">
|
||||||
<h4 className="text-sm font-semibold mb-2">{t('AddServer.Monitoring.SetupTitle')}</h4>
|
<h4 className="text-sm font-semibold mb-2">{t('Servers.AddServer.Monitoring.SetupTitle')}</h4>
|
||||||
<p className="text-sm text-muted-foreground mb-3">
|
<p className="text-sm text-muted-foreground mb-3">
|
||||||
{t('AddServer.Monitoring.SetupDescription')}
|
{t('Servers.AddServer.Monitoring.SetupDescription')}
|
||||||
</p>
|
</p>
|
||||||
<pre className="bg-background p-4 rounded-md text-sm overflow-x-auto">
|
<pre className="bg-background p-4 rounded-md text-sm overflow-x-auto">
|
||||||
<code>{`services:
|
<code>{`services:
|
||||||
@ -983,8 +985,8 @@ export default function Servers() {
|
|||||||
</AlertDialogDescription>
|
</AlertDialogDescription>
|
||||||
</AlertDialogHeader>
|
</AlertDialogHeader>
|
||||||
<AlertDialogFooter>
|
<AlertDialogFooter>
|
||||||
<AlertDialogCancel>{t('cancel')}</AlertDialogCancel>
|
<AlertDialogCancel>{t('Common.cancel')}</AlertDialogCancel>
|
||||||
<AlertDialogAction onClick={add}>{t('add')}</AlertDialogAction>
|
<AlertDialogAction onClick={add}>{t('Common.add')}</AlertDialogAction>
|
||||||
</AlertDialogFooter>
|
</AlertDialogFooter>
|
||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
@ -993,7 +995,7 @@ export default function Servers() {
|
|||||||
<div className="flex flex-col gap-2 mb-4 pt-2">
|
<div className="flex flex-col gap-2 mb-4 pt-2">
|
||||||
<Input
|
<Input
|
||||||
id="application-search"
|
id="application-search"
|
||||||
placeholder="Type to search..."
|
placeholder={t('Servers.Search.Placeholder')}
|
||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
/>
|
/>
|
||||||
@ -1016,7 +1018,7 @@ export default function Servers() {
|
|||||||
<StatusIndicator isOnline={server.online} />
|
<StatusIndicator isOnline={server.online} />
|
||||||
{server.online && server.uptime && (
|
{server.online && server.uptime && (
|
||||||
<span className="text-xs text-muted-foreground mt-1">
|
<span className="text-xs text-muted-foreground mt-1">
|
||||||
since {server.uptime}
|
{t('Common.since', { date: server.uptime })}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -1045,13 +1047,13 @@ export default function Servers() {
|
|||||||
<div className="flex items-center gap-2 text-foreground/80">
|
<div className="flex items-center gap-2 text-foreground/80">
|
||||||
<MonitorCog className="h-4 w-4 text-muted-foreground" />
|
<MonitorCog className="h-4 w-4 text-muted-foreground" />
|
||||||
<span>
|
<span>
|
||||||
<b>OS:</b> {server.os || "-"}
|
<b>{t('Common.Server.OS')}:</b> {server.os || "-"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 text-foreground/80">
|
<div className="flex items-center gap-2 text-foreground/80">
|
||||||
<FileDigit className="h-4 w-4 text-muted-foreground" />
|
<FileDigit className="h-4 w-4 text-muted-foreground" />
|
||||||
<span>
|
<span>
|
||||||
<b>IP:</b> {server.ip || "Not set"}
|
<b>{t('Common.Server.IP')}:</b> {server.ip || t('Common.notSet')}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -1059,7 +1061,7 @@ export default function Servers() {
|
|||||||
<div className="flex items-center gap-2 text-foreground/80">
|
<div className="flex items-center gap-2 text-foreground/80">
|
||||||
<LucideServer className="h-4 w-4 text-muted-foreground" />
|
<LucideServer className="h-4 w-4 text-muted-foreground" />
|
||||||
<span>
|
<span>
|
||||||
<b>Host:</b> {getHostServerName(server.hostServer)}
|
<b>{t('Common.Server.Host')}:</b> {getHostServerName(server.hostServer)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -1069,31 +1071,31 @@ export default function Servers() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-span-full mb-2">
|
<div className="col-span-full mb-2">
|
||||||
<h4 className="text-sm font-semibold">Hardware Information</h4>
|
<h4 className="text-sm font-semibold">{t('Servers.ServerCard.HardwareInformation')}</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-2 text-foreground/80">
|
<div className="flex items-center gap-2 text-foreground/80">
|
||||||
<Cpu className="h-4 w-4 text-muted-foreground" />
|
<Cpu className="h-4 w-4 text-muted-foreground" />
|
||||||
<span>
|
<span>
|
||||||
<b>CPU:</b> {server.cpu || "-"}
|
<b>{t('Common.Server.CPU')}:</b> {server.cpu || "-"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 text-foreground/80">
|
<div className="flex items-center gap-2 text-foreground/80">
|
||||||
<Microchip className="h-4 w-4 text-muted-foreground" />
|
<Microchip className="h-4 w-4 text-muted-foreground" />
|
||||||
<span>
|
<span>
|
||||||
<b>GPU:</b> {server.gpu || "-"}
|
<b>{t('Common.Server.GPU')}:</b> {server.gpu || "-"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 text-foreground/80">
|
<div className="flex items-center gap-2 text-foreground/80">
|
||||||
<MemoryStick className="h-4 w-4 text-muted-foreground" />
|
<MemoryStick className="h-4 w-4 text-muted-foreground" />
|
||||||
<span>
|
<span>
|
||||||
<b>RAM:</b> {server.ram || "-"}
|
<b>{t('Common.Server.RAM')}:</b> {server.ram || "-"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 text-foreground/80">
|
<div className="flex items-center gap-2 text-foreground/80">
|
||||||
<HardDrive className="h-4 w-4 text-muted-foreground" />
|
<HardDrive className="h-4 w-4 text-muted-foreground" />
|
||||||
<span>
|
<span>
|
||||||
<b>Disk:</b> {server.disk || "-"}
|
<b>{t('Common.Server.Disk')}:</b> {server.disk || "-"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -1104,15 +1106,15 @@ export default function Servers() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-span-full">
|
<div className="col-span-full">
|
||||||
<h4 className="text-sm font-semibold mb-3">Resource Usage</h4>
|
<h4 className="text-sm font-semibold mb-3">{t('Servers.ServerCard.ResourceUsage')}</h4>
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Cpu className="h-4 w-4 text-muted-foreground" />
|
<Cpu className="h-4 w-4 text-muted-foreground" />
|
||||||
<span className="text-sm font-medium">CPU</span>
|
<span className="text-sm font-medium">{t('Common.Server.CPU')}</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-xs font-medium">{server.cpuUsage !== null && server.cpuUsage !== undefined ? `${server.cpuUsage}%` : "NO DATA"}</span>
|
<span className="text-xs font-medium">{server.cpuUsage !== null && server.cpuUsage !== undefined ? `${server.cpuUsage}%` : t('Common.noData')}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="h-2 w-full overflow-hidden rounded-full bg-secondary mt-1">
|
<div className="h-2 w-full overflow-hidden rounded-full bg-secondary mt-1">
|
||||||
<div
|
<div
|
||||||
@ -1126,9 +1128,9 @@ export default function Servers() {
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<MemoryStick className="h-4 w-4 text-muted-foreground" />
|
<MemoryStick className="h-4 w-4 text-muted-foreground" />
|
||||||
<span className="text-sm font-medium">RAM</span>
|
<span className="text-sm font-medium">{t('Common.Server.RAM')}</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-xs font-medium">{server.ramUsage !== null && server.ramUsage !== undefined ? `${server.ramUsage}%` : "NO DATA"}</span>
|
<span className="text-xs font-medium">{server.ramUsage !== null && server.ramUsage !== undefined ? `${server.ramUsage}%` : t('Common.noData')}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="h-2 w-full overflow-hidden rounded-full bg-secondary mt-1">
|
<div className="h-2 w-full overflow-hidden rounded-full bg-secondary mt-1">
|
||||||
<div
|
<div
|
||||||
@ -1142,9 +1144,9 @@ export default function Servers() {
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<HardDrive className="h-4 w-4 text-muted-foreground" />
|
<HardDrive className="h-4 w-4 text-muted-foreground" />
|
||||||
<span className="text-sm font-medium">Disk</span>
|
<span className="text-sm font-medium">{t('Common.Server.Disk')}</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-xs font-medium">{server.diskUsage !== null && server.diskUsage !== undefined ? `${server.diskUsage}%` : "NO DATA"}</span>
|
<span className="text-xs font-medium">{server.diskUsage !== null && server.diskUsage !== undefined ? `${server.diskUsage}%` : t('Common.noData')}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="h-2 w-full overflow-hidden rounded-full bg-secondary mt-1">
|
<div className="h-2 w-full overflow-hidden rounded-full bg-secondary mt-1">
|
||||||
<div
|
<div
|
||||||
@ -1155,21 +1157,21 @@ export default function Servers() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Microchip className="h-4 w-4 text-muted-foreground" />
|
<Microchip className="h-4 w-4 text-muted-foreground" />
|
||||||
<span className="text-sm font-medium">GPU</span>
|
<span className="text-sm font-medium">{t('Common.Server.GPU')}</span>
|
||||||
|
</div>
|
||||||
|
<span className="text-xs font-medium">
|
||||||
|
{server.online &&
|
||||||
|
server.gpuUsage &&
|
||||||
|
server.gpuUsage !== null &&
|
||||||
|
server.gpuUsage !== undefined &&
|
||||||
|
server.gpuUsage.toString() !== "0"
|
||||||
|
? `${server.gpuUsage}%`
|
||||||
|
: t('Common.noData')}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-xs font-medium">
|
|
||||||
{server.online &&
|
|
||||||
server.gpuUsage &&
|
|
||||||
server.gpuUsage !== null &&
|
|
||||||
server.gpuUsage !== undefined &&
|
|
||||||
server.gpuUsage.toString() !== "0"
|
|
||||||
? `${server.gpuUsage}%`
|
|
||||||
: "NO DATA"}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="h-2 w-full overflow-hidden rounded-full bg-secondary mt-1">
|
<div className="h-2 w-full overflow-hidden rounded-full bg-secondary mt-1">
|
||||||
<div
|
<div
|
||||||
className={`h-full ${server.gpuUsage && server.gpuUsage > 80 ? "bg-destructive" : server.gpuUsage && server.gpuUsage > 60 ? "bg-amber-500" : "bg-emerald-500"}`}
|
className={`h-full ${server.gpuUsage && server.gpuUsage > 80 ? "bg-destructive" : server.gpuUsage && server.gpuUsage > 60 ? "bg-amber-500" : "bg-emerald-500"}`}
|
||||||
@ -1180,20 +1182,20 @@ export default function Servers() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Thermometer className="h-4 w-4 text-muted-foreground" />
|
<Thermometer className="h-4 w-4 text-muted-foreground" />
|
||||||
<span className="text-sm font-medium">Temp</span>
|
<span className="text-sm font-medium">{t('Common.Server.Temperature')}</span>
|
||||||
|
</div>
|
||||||
|
<span className="text-xs font-medium">
|
||||||
|
{server.online &&
|
||||||
|
server.temp !== null &&
|
||||||
|
server.temp !== undefined &&
|
||||||
|
server.temp.toString() !== "0"
|
||||||
|
? `${server.temp}°C`
|
||||||
|
: t('Common.noData')}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-xs font-medium">
|
|
||||||
{server.online &&
|
|
||||||
server.temp !== null &&
|
|
||||||
server.temp !== undefined &&
|
|
||||||
server.temp.toString() !== "0"
|
|
||||||
? `${server.temp}°C`
|
|
||||||
: "NO DATA"}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="h-2 w-full overflow-hidden rounded-full bg-secondary mt-1">
|
<div className="h-2 w-full overflow-hidden rounded-full bg-secondary mt-1">
|
||||||
<div
|
<div
|
||||||
className={`h-full ${server.temp && server.temp > 80 ? "bg-destructive" : server.temp && server.temp > 60 ? "bg-amber-500" : "bg-emerald-500"}`}
|
className={`h-full ${server.temp && server.temp > 80 ? "bg-destructive" : server.temp && server.temp > 60 ? "bg-amber-500" : "bg-emerald-500"}`}
|
||||||
@ -1214,7 +1216,7 @@ export default function Servers() {
|
|||||||
<NextLink href={`/dashboard/servers/${server.id}`} className="flex-1">
|
<NextLink href={`/dashboard/servers/${server.id}`} className="flex-1">
|
||||||
<Button variant="outline" className="w-full">
|
<Button variant="outline" className="w-full">
|
||||||
<History className="h-4 w-4 mr-2" />
|
<History className="h-4 w-4 mr-2" />
|
||||||
View Details
|
{t('Servers.ServerCard.ViewDetails')}
|
||||||
</Button>
|
</Button>
|
||||||
</NextLink>
|
</NextLink>
|
||||||
|
|
||||||
@ -1230,7 +1232,7 @@ export default function Servers() {
|
|||||||
<LinkIcon className="h-4 w-4" />
|
<LinkIcon className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>Open Management URL</TooltipContent>
|
<TooltipContent>{t('Servers.ServerCard.OpenManagementURL')}</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
)}
|
)}
|
||||||
@ -1254,7 +1256,7 @@ export default function Servers() {
|
|||||||
<Pencil className="h-4 w-4" />
|
<Pencil className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>Edit server</TooltipContent>
|
<TooltipContent>{t('Servers.ServerCard.EditServer')}</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
|
|
||||||
@ -1270,7 +1272,7 @@ export default function Servers() {
|
|||||||
</AlertDialogTrigger>
|
</AlertDialogTrigger>
|
||||||
<AlertDialogContent>
|
<AlertDialogContent>
|
||||||
<AlertDialogHeader>
|
<AlertDialogHeader>
|
||||||
<AlertDialogTitle>Hosted VMs</AlertDialogTitle>
|
<AlertDialogTitle>{t('Servers.ServerCard.HostedVMs')}</AlertDialogTitle>
|
||||||
<AlertDialogDescription>
|
<AlertDialogDescription>
|
||||||
{server.host && (
|
{server.host && (
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
@ -1325,21 +1327,21 @@ export default function Servers() {
|
|||||||
</AlertDialogTrigger>
|
</AlertDialogTrigger>
|
||||||
<AlertDialogContent className="max-w-[95vw] w-[600px] max-h-[90vh] overflow-y-auto">
|
<AlertDialogContent className="max-w-[95vw] w-[600px] max-h-[90vh] overflow-y-auto">
|
||||||
<AlertDialogHeader>
|
<AlertDialogHeader>
|
||||||
<AlertDialogTitle>Edit VM</AlertDialogTitle>
|
<AlertDialogTitle>{t('Servers.EditServer.Title', { name: hostedVM.name })}</AlertDialogTitle>
|
||||||
<AlertDialogDescription>
|
<AlertDialogDescription>
|
||||||
<Tabs defaultValue="general" className="w-full">
|
<Tabs defaultValue="general" className="w-full">
|
||||||
<TabsList className="w-full">
|
<TabsList className="w-full">
|
||||||
<TabsTrigger value="general">General</TabsTrigger>
|
<TabsTrigger value="general">{t('Common.Server.Tabs.General')}</TabsTrigger>
|
||||||
<TabsTrigger value="hardware">Hardware</TabsTrigger>
|
<TabsTrigger value="hardware">{t('Common.Server.Tabs.Hardware')}</TabsTrigger>
|
||||||
<TabsTrigger value="virtualization">
|
<TabsTrigger value="virtualization">
|
||||||
Host
|
{t('Common.Server.Tabs.Host')}
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
<TabsContent value="general">
|
<TabsContent value="general">
|
||||||
<div className="space-y-4 pt-4">
|
<div className="space-y-4 pt-4">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<div className="grid w-[calc(100%-52px)] items-center gap-1.5">
|
<div className="grid w-[calc(100%-52px)] items-center gap-1.5">
|
||||||
<Label htmlFor="editIcon">Icon</Label>
|
<Label htmlFor="editIcon">{t('Servers.EditServer.General.Icon')}</Label>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Select
|
<Select
|
||||||
value={editIcon}
|
value={editIcon}
|
||||||
@ -1348,7 +1350,7 @@ export default function Servers() {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="w-full">
|
<SelectTrigger className="w-full">
|
||||||
<SelectValue placeholder="Select an icon">
|
<SelectValue placeholder={t('Servers.AddServer.General.IconPlaceholder')}>
|
||||||
{editIcon && (
|
{editIcon && (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<DynamicIcon
|
<DynamicIcon
|
||||||
@ -1362,7 +1364,7 @@ export default function Servers() {
|
|||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent className="max-h-[300px]">
|
<SelectContent className="max-h-[300px]">
|
||||||
<Input
|
<Input
|
||||||
placeholder="Search icons..."
|
placeholder={t('Servers.AddServer.General.IconSearchPlaceholder')}
|
||||||
className="mb-2"
|
className="mb-2"
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const iconElements =
|
const iconElements =
|
||||||
@ -1426,7 +1428,7 @@ export default function Servers() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid w-[52px] items-center gap-1.5">
|
<div className="grid w-[52px] items-center gap-1.5">
|
||||||
<Label htmlFor="editIcon">Preview</Label>
|
<Label htmlFor="editIcon">{t('Servers.AddServer.General.Preview')}</Label>
|
||||||
<div className="flex items-center justify-center">
|
<div className="flex items-center justify-center">
|
||||||
{editIcon && (
|
{editIcon && (
|
||||||
<DynamicIcon
|
<DynamicIcon
|
||||||
@ -1438,7 +1440,7 @@ export default function Servers() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="editName">Name</Label>
|
<Label htmlFor="editName">{t('Servers.EditServer.General.Name')}</Label>
|
||||||
<Input
|
<Input
|
||||||
id="editName"
|
id="editName"
|
||||||
type="text"
|
type="text"
|
||||||
@ -1448,13 +1450,13 @@ export default function Servers() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="editOs">Operating System</Label>
|
<Label htmlFor="editOs">{t('Servers.EditServer.General.OperatingSystem')}</Label>
|
||||||
<Select
|
<Select
|
||||||
value={editOs}
|
value={editOs}
|
||||||
onValueChange={setEditOs}
|
onValueChange={setEditOs}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="w-full">
|
<SelectTrigger className="w-full">
|
||||||
<SelectValue placeholder="Select OS" />
|
<SelectValue placeholder={t('Servers.AddServer.General.OperatingSystemPlaceholder')} />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="Windows">
|
<SelectItem value="Windows">
|
||||||
@ -1466,7 +1468,7 @@ export default function Servers() {
|
|||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="editIp">IP Adress</Label>
|
<Label htmlFor="editIp">{t('Servers.EditServer.General.IPAddress')}</Label>
|
||||||
<Input
|
<Input
|
||||||
id="editIp"
|
id="editIp"
|
||||||
type="text"
|
type="text"
|
||||||
@ -1476,7 +1478,7 @@ export default function Servers() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="editUrl">Management URL</Label>
|
<Label htmlFor="editUrl">{t('Servers.EditServer.General.ManagementURL')}</Label>
|
||||||
<Input
|
<Input
|
||||||
id="editUrl"
|
id="editUrl"
|
||||||
type="text"
|
type="text"
|
||||||
@ -1491,7 +1493,7 @@ export default function Servers() {
|
|||||||
<TabsContent value="hardware">
|
<TabsContent value="hardware">
|
||||||
<div className="space-y-4 pt-4">
|
<div className="space-y-4 pt-4">
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="editCpu">CPU</Label>
|
<Label htmlFor="editCpu">{t('Servers.EditServer.Hardware.CPU')}</Label>
|
||||||
<Input
|
<Input
|
||||||
id="editCpu"
|
id="editCpu"
|
||||||
value={editCpu}
|
value={editCpu}
|
||||||
@ -1499,7 +1501,7 @@ export default function Servers() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="editGpu">GPU</Label>
|
<Label htmlFor="editGpu">{t('Servers.EditServer.Hardware.GPU')}</Label>
|
||||||
<Input
|
<Input
|
||||||
id="editGpu"
|
id="editGpu"
|
||||||
value={editGpu}
|
value={editGpu}
|
||||||
@ -1507,7 +1509,7 @@ export default function Servers() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="editRam">RAM</Label>
|
<Label htmlFor="editRam">{t('Servers.EditServer.Hardware.RAM')}</Label>
|
||||||
<Input
|
<Input
|
||||||
id="editRam"
|
id="editRam"
|
||||||
value={editRam}
|
value={editRam}
|
||||||
@ -1515,7 +1517,7 @@ export default function Servers() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="editDisk">Disk</Label>
|
<Label htmlFor="editDisk">{t('Servers.EditServer.Hardware.Disk')}</Label>
|
||||||
<Input
|
<Input
|
||||||
id="editDisk"
|
id="editDisk"
|
||||||
value={editDisk}
|
value={editDisk}
|
||||||
@ -1539,18 +1541,18 @@ export default function Servers() {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="editHostCheckbox">
|
<Label htmlFor="editHostCheckbox">
|
||||||
Mark as host server
|
{t('Servers.EditServer.Host.MarkAsHostServer')}
|
||||||
{server.hostedVMs &&
|
{server.hostedVMs &&
|
||||||
server.hostedVMs.length > 0 && (
|
server.hostedVMs.length > 0 && (
|
||||||
<span className="text-muted-foreground text-sm ml-2">
|
<span className="text-muted-foreground text-sm ml-2">
|
||||||
(Cannot be disabled while hosting VMs)
|
({t('Servers.EditServer.Host.CannotDisableHost')})
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
{!editHost && (
|
{!editHost && (
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label>Host Server</Label>
|
<Label>{t('Servers.EditServer.Host.SelectHostServer')}</Label>
|
||||||
<Select
|
<Select
|
||||||
value={editHostServer?.toString()}
|
value={editHostServer?.toString()}
|
||||||
onValueChange={(value) => {
|
onValueChange={(value) => {
|
||||||
@ -1562,10 +1564,10 @@ export default function Servers() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder="Select a host server" />
|
<SelectValue placeholder={t('Servers.AddServer.Host.SelectHostServerPlaceholder')} />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="0">No host server</SelectItem>
|
<SelectItem value="0">{t('Servers.AddServer.Host.NoHostServer')}</SelectItem>
|
||||||
{hostServers
|
{hostServers
|
||||||
.filter(
|
.filter(
|
||||||
(server) => server.id !== editId,
|
(server) => server.id !== editId,
|
||||||
@ -1585,8 +1587,8 @@ export default function Servers() {
|
|||||||
</AlertDialogDescription>
|
</AlertDialogDescription>
|
||||||
</AlertDialogHeader>
|
</AlertDialogHeader>
|
||||||
<AlertDialogFooter>
|
<AlertDialogFooter>
|
||||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
<AlertDialogCancel>{t('Common.cancel')}</AlertDialogCancel>
|
||||||
<Button onClick={edit}>Save</Button>
|
<Button onClick={edit}>{t('Servers.EditServer.Save')}</Button>
|
||||||
</AlertDialogFooter>
|
</AlertDialogFooter>
|
||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
@ -1601,43 +1603,43 @@ export default function Servers() {
|
|||||||
<div className="flex items-center gap-2 text-foreground/80">
|
<div className="flex items-center gap-2 text-foreground/80">
|
||||||
<MonitorCog className="h-4 w-4 text-muted-foreground" />
|
<MonitorCog className="h-4 w-4 text-muted-foreground" />
|
||||||
<span>
|
<span>
|
||||||
<b>OS:</b> {hostedVM.os || "-"}
|
<b>{t('Common.Server.OS')}:</b> {hostedVM.os || "-"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 text-foreground/80">
|
<div className="flex items-center gap-2 text-foreground/80">
|
||||||
<FileDigit className="h-4 w-4 text-muted-foreground" />
|
<FileDigit className="h-4 w-4 text-muted-foreground" />
|
||||||
<span>
|
<span>
|
||||||
<b>IP:</b> {hostedVM.ip || "Not set"}
|
<b>{t('Common.Server.IP')}:</b> {hostedVM.ip || t('Common.notSet')}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-span-full mb-2">
|
<div className="col-span-full mb-2">
|
||||||
<h4 className="text-sm font-semibold">Hardware Information</h4>
|
<h4 className="text-sm font-semibold">{t('Servers.ServerCard.HardwareInformation')}</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-2 text-foreground/80">
|
<div className="flex items-center gap-2 text-foreground/80">
|
||||||
<Cpu className="h-4 w-4 text-muted-foreground" />
|
<Cpu className="h-4 w-4 text-muted-foreground" />
|
||||||
<span>
|
<span>
|
||||||
<b>CPU:</b> {hostedVM.cpu || "-"}
|
<b>{t('Common.Server.CPU')}:</b> {hostedVM.cpu || "-"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 text-foreground/80">
|
<div className="flex items-center gap-2 text-foreground/80">
|
||||||
<Microchip className="h-4 w-4 text-muted-foreground" />
|
<Microchip className="h-4 w-4 text-muted-foreground" />
|
||||||
<span>
|
<span>
|
||||||
<b>GPU:</b> {hostedVM.gpu || "-"}
|
<b>{t('Common.Server.GPU')}:</b> {hostedVM.gpu || "-"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 text-foreground/80">
|
<div className="flex items-center gap-2 text-foreground/80">
|
||||||
<MemoryStick className="h-4 w-4 text-muted-foreground" />
|
<MemoryStick className="h-4 w-4 text-muted-foreground" />
|
||||||
<span>
|
<span>
|
||||||
<b>RAM:</b> {hostedVM.ram || "-"}
|
<b>{t('Common.Server.RAM')}:</b> {hostedVM.ram || "-"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 text-foreground/80">
|
<div className="flex items-center gap-2 text-foreground/80">
|
||||||
<HardDrive className="h-4 w-4 text-muted-foreground" />
|
<HardDrive className="h-4 w-4 text-muted-foreground" />
|
||||||
<span>
|
<span>
|
||||||
<b>Disk:</b> {hostedVM.disk || "-"}
|
<b>{t('Common.Server.Disk')}:</b> {hostedVM.disk || "-"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -1652,7 +1654,7 @@ export default function Servers() {
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Cpu className="h-4 w-4 text-muted-foreground" />
|
<Cpu className="h-4 w-4 text-muted-foreground" />
|
||||||
<span className="text-sm font-medium">CPU</span>
|
<span className="text-sm font-medium">{t('Common.Server.CPU')}</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-xs font-medium">
|
<span className="text-xs font-medium">
|
||||||
{hostedVM.cpuUsage || 0}%
|
{hostedVM.cpuUsage || 0}%
|
||||||
@ -1670,7 +1672,7 @@ export default function Servers() {
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<MemoryStick className="h-4 w-4 text-muted-foreground" />
|
<MemoryStick className="h-4 w-4 text-muted-foreground" />
|
||||||
<span className="text-sm font-medium">RAM</span>
|
<span className="text-sm font-medium">{t('Common.Server.RAM')}</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-xs font-medium">
|
<span className="text-xs font-medium">
|
||||||
{hostedVM.ramUsage || 0}%
|
{hostedVM.ramUsage || 0}%
|
||||||
@ -1688,7 +1690,7 @@ export default function Servers() {
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<HardDrive className="h-4 w-4 text-muted-foreground" />
|
<HardDrive className="h-4 w-4 text-muted-foreground" />
|
||||||
<span className="text-sm font-medium">Disk</span>
|
<span className="text-sm font-medium">{t('Common.Server.Disk')}</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-xs font-medium">
|
<span className="text-xs font-medium">
|
||||||
{hostedVM.diskUsage || 0}%
|
{hostedVM.diskUsage || 0}%
|
||||||
@ -1713,12 +1715,12 @@ export default function Servers() {
|
|||||||
</AlertDialogDescription>
|
</AlertDialogDescription>
|
||||||
</AlertDialogHeader>
|
</AlertDialogHeader>
|
||||||
<AlertDialogFooter>
|
<AlertDialogFooter>
|
||||||
<AlertDialogCancel>Close</AlertDialogCancel>
|
<AlertDialogCancel>{t('Common.cancel')}</AlertDialogCancel>
|
||||||
</AlertDialogFooter>
|
</AlertDialogFooter>
|
||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>View VMs ({server.hostedVMs.length})</TooltipContent>
|
<TooltipContent>{t('Servers.ServerCard.HostedVMs')} ({server.hostedVMs.length})</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
)}
|
)}
|
||||||
@ -1734,27 +1736,27 @@ export default function Servers() {
|
|||||||
</AlertDialogTrigger>
|
</AlertDialogTrigger>
|
||||||
<AlertDialogContent className="max-w-[95vw] w-[600px] max-h-[90vh] overflow-y-auto">
|
<AlertDialogContent className="max-w-[95vw] w-[600px] max-h-[90vh] overflow-y-auto">
|
||||||
<AlertDialogHeader>
|
<AlertDialogHeader>
|
||||||
<AlertDialogTitle>Edit {server.name}</AlertDialogTitle>
|
<AlertDialogTitle>{t('Servers.EditServer.Title', { name: server.name })}</AlertDialogTitle>
|
||||||
<AlertDialogDescription>
|
<AlertDialogDescription>
|
||||||
<Tabs defaultValue="general" className="w-full">
|
<Tabs defaultValue="general" className="w-full">
|
||||||
<TabsList className="w-full">
|
<TabsList className="w-full">
|
||||||
<TabsTrigger value="general">General</TabsTrigger>
|
<TabsTrigger value="general">{t('Common.Server.Tabs.General')}</TabsTrigger>
|
||||||
<TabsTrigger value="hardware">Hardware</TabsTrigger>
|
<TabsTrigger value="hardware">{t('Common.Server.Tabs.Hardware')}</TabsTrigger>
|
||||||
<TabsTrigger value="virtualization">Host</TabsTrigger>
|
<TabsTrigger value="virtualization">{t('Common.Server.Tabs.Host')}</TabsTrigger>
|
||||||
<TabsTrigger value="monitoring">Monitoring</TabsTrigger>
|
<TabsTrigger value="monitoring">{t('Common.Server.Tabs.Monitoring')}</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
<TabsContent value="general">
|
<TabsContent value="general">
|
||||||
<div className="space-y-4 pt-4">
|
<div className="space-y-4 pt-4">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<div className="grid w-[calc(100%-52px)] items-center gap-1.5">
|
<div className="grid w-[calc(100%-52px)] items-center gap-1.5">
|
||||||
<Label htmlFor="editIcon">Icon</Label>
|
<Label htmlFor="editIcon">{t('Servers.EditServer.General.Icon')}</Label>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Select
|
<Select
|
||||||
value={editIcon}
|
value={editIcon}
|
||||||
onValueChange={(value) => setEditIcon(value)}
|
onValueChange={(value) => setEditIcon(value)}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="w-full">
|
<SelectTrigger className="w-full">
|
||||||
<SelectValue placeholder="Select an icon">
|
<SelectValue placeholder={t('Servers.AddServer.General.IconPlaceholder')}>
|
||||||
{editIcon && (
|
{editIcon && (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<DynamicIcon name={editIcon as any} size={18} />
|
<DynamicIcon name={editIcon as any} size={18} />
|
||||||
@ -1765,7 +1767,7 @@ export default function Servers() {
|
|||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent className="max-h-[300px]">
|
<SelectContent className="max-h-[300px]">
|
||||||
<Input
|
<Input
|
||||||
placeholder="Search icons..."
|
placeholder={t('Servers.AddServer.General.IconSearchPlaceholder')}
|
||||||
className="mb-2"
|
className="mb-2"
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const iconElements = document.querySelectorAll(
|
const iconElements = document.querySelectorAll(
|
||||||
@ -1811,14 +1813,14 @@ export default function Servers() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid w-[52px] items-center gap-1.5">
|
<div className="grid w-[52px] items-center gap-1.5">
|
||||||
<Label htmlFor="editIcon">Preview</Label>
|
<Label htmlFor="editIcon">{t('Servers.AddServer.General.Preview')}</Label>
|
||||||
<div className="flex items-center justify-center">
|
<div className="flex items-center justify-center">
|
||||||
{editIcon && <DynamicIcon name={editIcon as any} size={36} />}
|
{editIcon && <DynamicIcon name={editIcon as any} size={36} />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="editName">Name</Label>
|
<Label htmlFor="editName">{t('Servers.EditServer.General.Name')}</Label>
|
||||||
<Input
|
<Input
|
||||||
id="editName"
|
id="editName"
|
||||||
type="text"
|
type="text"
|
||||||
@ -1828,11 +1830,11 @@ export default function Servers() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="editOs">
|
<Label htmlFor="editOs">
|
||||||
Operating System <span className="text-stone-600">(optional)</span>
|
{t('Servers.EditServer.General.OperatingSystem')} <span className="text-stone-600">({t('Common.optional')})</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Select value={editOs} onValueChange={(value) => setEditOs(value)}>
|
<Select value={editOs} onValueChange={(value) => setEditOs(value)}>
|
||||||
<SelectTrigger className="w-full">
|
<SelectTrigger className="w-full">
|
||||||
<SelectValue placeholder="Select OS" />
|
<SelectValue placeholder={t('Servers.AddServer.General.OperatingSystemPlaceholder')} />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="Windows">Windows</SelectItem>
|
<SelectItem value="Windows">Windows</SelectItem>
|
||||||
@ -1843,7 +1845,7 @@ export default function Servers() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="editIp">
|
<Label htmlFor="editIp">
|
||||||
IP Address <span className="text-stone-600">(optional)</span>
|
{t('Servers.EditServer.General.IPAddress')} <span className="text-stone-600">({t('Common.optional')})</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
id="editIp"
|
id="editIp"
|
||||||
@ -1854,7 +1856,7 @@ export default function Servers() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="editUrl">
|
<Label htmlFor="editUrl">
|
||||||
Management URL <span className="text-stone-600">(optional)</span>
|
{t('Servers.EditServer.General.ManagementURL')} <span className="text-stone-600">({t('Common.optional')})</span>
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
id="editUrl"
|
id="editUrl"
|
||||||
@ -1868,7 +1870,7 @@ export default function Servers() {
|
|||||||
<TabsContent value="hardware">
|
<TabsContent value="hardware">
|
||||||
<div className="space-y-4 pt-4">
|
<div className="space-y-4 pt-4">
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="editCpu">CPU</Label>
|
<Label htmlFor="editCpu">{t('Servers.EditServer.Hardware.CPU')}</Label>
|
||||||
<Input
|
<Input
|
||||||
id="editCpu"
|
id="editCpu"
|
||||||
value={editCpu}
|
value={editCpu}
|
||||||
@ -1876,7 +1878,7 @@ export default function Servers() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="editGpu">GPU</Label>
|
<Label htmlFor="editGpu">{t('Servers.EditServer.Hardware.GPU')}</Label>
|
||||||
<Input
|
<Input
|
||||||
id="editGpu"
|
id="editGpu"
|
||||||
value={editGpu}
|
value={editGpu}
|
||||||
@ -1884,7 +1886,7 @@ export default function Servers() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="editRam">RAM</Label>
|
<Label htmlFor="editRam">{t('Servers.EditServer.Hardware.RAM')}</Label>
|
||||||
<Input
|
<Input
|
||||||
id="editRam"
|
id="editRam"
|
||||||
value={editRam}
|
value={editRam}
|
||||||
@ -1892,7 +1894,7 @@ export default function Servers() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="editDisk">Disk</Label>
|
<Label htmlFor="editDisk">{t('Servers.EditServer.Hardware.Disk')}</Label>
|
||||||
<Input
|
<Input
|
||||||
id="editDisk"
|
id="editDisk"
|
||||||
value={editDisk}
|
value={editDisk}
|
||||||
@ -1911,11 +1913,11 @@ export default function Servers() {
|
|||||||
setEditHost(checked === true)
|
setEditHost(checked === true)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="editHostCheckbox">Mark as host server</Label>
|
<Label htmlFor="editHostCheckbox">{t('Servers.EditServer.Host.MarkAsHostServer')}</Label>
|
||||||
</div>
|
</div>
|
||||||
{!editHost && (
|
{!editHost && (
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label>Host Server</Label>
|
<Label>{t('Servers.EditServer.Host.SelectHostServer')}</Label>
|
||||||
<Select
|
<Select
|
||||||
value={editHostServer?.toString()}
|
value={editHostServer?.toString()}
|
||||||
onValueChange={(value) => {
|
onValueChange={(value) => {
|
||||||
@ -1927,10 +1929,10 @@ export default function Servers() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SelectTrigger>
|
<SelectTrigger>
|
||||||
<SelectValue placeholder="Select a host server" />
|
<SelectValue placeholder={t('Servers.AddServer.Host.SelectHostServerPlaceholder')} />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectItem value="0">No host server</SelectItem>
|
<SelectItem value="0">{t('Servers.AddServer.Host.NoHostServer')}</SelectItem>
|
||||||
{hostServers
|
{hostServers
|
||||||
.filter(
|
.filter(
|
||||||
(server) => server.id !== editId,
|
(server) => server.id !== editId,
|
||||||
@ -1954,12 +1956,12 @@ export default function Servers() {
|
|||||||
checked={editMonitoring}
|
checked={editMonitoring}
|
||||||
onCheckedChange={(checked) => setEditMonitoring(checked === true)}
|
onCheckedChange={(checked) => setEditMonitoring(checked === true)}
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="editMonitoringCheckbox">Enable monitoring</Label>
|
<Label htmlFor="editMonitoringCheckbox">{t('Servers.EditServer.Monitoring.Enable')}</Label>
|
||||||
</div>
|
</div>
|
||||||
{editMonitoring && (
|
{editMonitoring && (
|
||||||
<>
|
<>
|
||||||
<div className="grid w-full items-center gap-1.5">
|
<div className="grid w-full items-center gap-1.5">
|
||||||
<Label htmlFor="editMonitoringURL">Monitoring URL</Label>
|
<Label htmlFor="editMonitoringURL">{t('Servers.EditServer.Monitoring.URL')}</Label>
|
||||||
<Input
|
<Input
|
||||||
id="editMonitoringURL"
|
id="editMonitoringURL"
|
||||||
type="text"
|
type="text"
|
||||||
@ -1969,9 +1971,9 @@ export default function Servers() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-4 p-4 border rounded-lg bg-muted">
|
<div className="mt-4 p-4 border rounded-lg bg-muted">
|
||||||
<h4 className="text-sm font-semibold mb-2">Required Server Setup</h4>
|
<h4 className="text-sm font-semibold mb-2">{t('Servers.EditServer.Monitoring.SetupTitle')}</h4>
|
||||||
<p className="text-sm text-muted-foreground mb-3">
|
<p className="text-sm text-muted-foreground mb-3">
|
||||||
To enable monitoring, you need to install Glances on your server. Here's an example Docker Compose configuration:
|
{t('Servers.EditServer.Monitoring.SetupDescription')}
|
||||||
</p>
|
</p>
|
||||||
<pre className="bg-background p-4 rounded-md text-sm">
|
<pre className="bg-background p-4 rounded-md text-sm">
|
||||||
<code>{`services:
|
<code>{`services:
|
||||||
@ -1996,8 +1998,8 @@ export default function Servers() {
|
|||||||
</AlertDialogDescription>
|
</AlertDialogDescription>
|
||||||
</AlertDialogHeader>
|
</AlertDialogHeader>
|
||||||
<AlertDialogFooter>
|
<AlertDialogFooter>
|
||||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
<AlertDialogCancel>{t('Common.cancel')}</AlertDialogCancel>
|
||||||
<Button onClick={edit}>Save</Button>
|
<Button onClick={edit}>{t('Servers.EditServer.Save')}</Button>
|
||||||
</AlertDialogFooter>
|
</AlertDialogFooter>
|
||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
@ -2013,24 +2015,24 @@ export default function Servers() {
|
|||||||
</AlertDialogTrigger>
|
</AlertDialogTrigger>
|
||||||
<AlertDialogContent>
|
<AlertDialogContent>
|
||||||
<AlertDialogHeader>
|
<AlertDialogHeader>
|
||||||
<AlertDialogTitle>Delete {server.name}</AlertDialogTitle>
|
<AlertDialogTitle>{t('Servers.ServerCard.DeleteConfirmation.Title', { name: server.name })}</AlertDialogTitle>
|
||||||
<AlertDialogDescription>
|
<AlertDialogDescription>
|
||||||
Are you sure you want to delete this server? This action cannot be undone.
|
{t('Servers.ServerCard.DeleteConfirmation.Description')}
|
||||||
</AlertDialogDescription>
|
</AlertDialogDescription>
|
||||||
</AlertDialogHeader>
|
</AlertDialogHeader>
|
||||||
<AlertDialogFooter>
|
<AlertDialogFooter>
|
||||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
<AlertDialogCancel>{t('Servers.ServerCard.DeleteConfirmation.Cancel')}</AlertDialogCancel>
|
||||||
<AlertDialogAction
|
<AlertDialogAction
|
||||||
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
||||||
onClick={() => deleteApplication(server.id)}
|
onClick={() => deleteApplication(server.id)}
|
||||||
>
|
>
|
||||||
Delete
|
{t('Servers.ServerCard.DeleteConfirmation.Delete')}
|
||||||
</AlertDialogAction>
|
</AlertDialogAction>
|
||||||
</AlertDialogFooter>
|
</AlertDialogFooter>
|
||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>Delete server</TooltipContent>
|
<TooltipContent>{t('Servers.ServerCard.DeleteServer')}</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
</div>
|
</div>
|
||||||
@ -2071,8 +2073,12 @@ export default function Servers() {
|
|||||||
<div className="flex justify-between items-center mb-2">
|
<div className="flex justify-between items-center mb-2">
|
||||||
<div className="text-sm text-muted-foreground">
|
<div className="text-sm text-muted-foreground">
|
||||||
{totalItems > 0
|
{totalItems > 0
|
||||||
? `Showing ${((currentPage - 1) * itemsPerPage) + 1}-${Math.min(currentPage * itemsPerPage, totalItems)} of ${totalItems} servers`
|
? t('Servers.Pagination.Showing', {
|
||||||
: "No servers found"}
|
start: ((currentPage - 1) * itemsPerPage) + 1,
|
||||||
|
end: Math.min(currentPage * itemsPerPage, totalItems),
|
||||||
|
total: totalItems
|
||||||
|
})
|
||||||
|
: t('Servers.Pagination.NoServers')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Pagination>
|
<Pagination>
|
||||||
|
|||||||
@ -1,114 +1,178 @@
|
|||||||
{
|
{
|
||||||
"Sidebar": {
|
"Common": {
|
||||||
"Main Navigation": "Main Navigation",
|
"ChangeView": "Change View",
|
||||||
"Dashboard": "Dashboard",
|
"ListView": "List View",
|
||||||
"My Infrastructure": "My Infrastructure",
|
"GridView": "Grid View",
|
||||||
"Servers": "Servers",
|
"optional": "optional",
|
||||||
"Applications": "Applications",
|
"cancel": "Cancel",
|
||||||
"Uptime": "Uptime",
|
"add": "Add",
|
||||||
"Network": "Network",
|
"since": "since {date}",
|
||||||
"Settings": "Settings",
|
"notSet": "Not set",
|
||||||
"Logout": "Logout"
|
"noData": "No data",
|
||||||
},
|
"ItemsPerPage": {
|
||||||
"Home": {
|
"items": "items",
|
||||||
"TitleUnder": "Dashboard to manage your entire server infrastructure",
|
"item": "item",
|
||||||
"LoginCardTitle": "Login",
|
"4": "4 items",
|
||||||
"LoginCardDescription": "Enter your credentials to continue",
|
"6": "6 items",
|
||||||
"AuthenticationError": "Authentication Error",
|
"10": "10 items",
|
||||||
"Email": "Email",
|
"15": "15 items",
|
||||||
"Password": "Password",
|
"20": "20 items",
|
||||||
"SigninButton": "Sign in",
|
"25": "25 items",
|
||||||
"SigninButtonSigningIn": "Signing in..."
|
"Custom": "Custom (1-100)"
|
||||||
},
|
},
|
||||||
"Dashboard": {
|
"Server": {
|
||||||
"Title": "Dashboard",
|
"CPU": "CPU",
|
||||||
"Servers": {
|
"GPU": "GPU",
|
||||||
"Title": "Servers",
|
"RAM": "RAM",
|
||||||
"Description": "Physical and virtual servers overview",
|
"Disk": "Disk",
|
||||||
"PhysicalServers": "Physical Servers",
|
"OS": "OS",
|
||||||
"VirtualServers": "Virtual Servers",
|
"IP": "IP",
|
||||||
"ManageServers": "Manage Servers"
|
"Host": "Host",
|
||||||
},
|
"Temperature": "Temperature",
|
||||||
"Applications": {
|
|
||||||
"Title": "Applications",
|
|
||||||
"Description": "Manage your deployed applications",
|
|
||||||
"OnlineApplications": "Running Applications",
|
|
||||||
"ViewAllApplications": "View all applications"
|
|
||||||
},
|
|
||||||
"Uptime": {
|
|
||||||
"Title": "Uptime",
|
|
||||||
"Description": "Monitor your service availability",
|
|
||||||
"OnlineApplications": "Online Applications",
|
|
||||||
"ViewUptimeMetrics": "View uptime metrics"
|
|
||||||
},
|
|
||||||
"Network": {
|
|
||||||
"Title": "Network",
|
|
||||||
"Description": "Manage network configuration",
|
|
||||||
"ActiveConnections": "Active Connections",
|
|
||||||
"ViewNetworkDetails": "View network details"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Servers": {
|
|
||||||
"MyInfrastructure": "My Infrastructure",
|
|
||||||
"Title": "Servers",
|
|
||||||
"YourServers": "Your Servers",
|
|
||||||
"ChangeView": "Change View",
|
|
||||||
"ListView": "List View",
|
|
||||||
"GridView": "Grid View",
|
|
||||||
"ItemsPerPage": {
|
|
||||||
"items": "items",
|
|
||||||
"item": "item",
|
|
||||||
"4": "4 items",
|
|
||||||
"6": "6 items",
|
|
||||||
"10": "10 items",
|
|
||||||
"15": "15 items",
|
|
||||||
"20": "20 items",
|
|
||||||
"25": "25 items",
|
|
||||||
"Custom": "Custom (1-100)"
|
|
||||||
},
|
|
||||||
"Tabs": {
|
"Tabs": {
|
||||||
"General": "General",
|
"General": "General",
|
||||||
"Hardware": "Hardware",
|
"Hardware": "Hardware",
|
||||||
"Host": "Host",
|
"Host": "Host",
|
||||||
"Monitoring": "Monitoring"
|
"Monitoring": "Monitoring"
|
||||||
},
|
|
||||||
"optional": "optional",
|
|
||||||
"cancel": "Cancel",
|
|
||||||
"add": "Add",
|
|
||||||
"AddServer": {
|
|
||||||
"Title": "Add a server",
|
|
||||||
"General": {
|
|
||||||
"Title": "Add a server",
|
|
||||||
"CopyServer": "Copy server",
|
|
||||||
"Icon": "Icon",
|
|
||||||
"IconPlaceholder": "Select an icon",
|
|
||||||
"IconSearchPlaceholder": "Search icons...",
|
|
||||||
"Preview": "Preview",
|
|
||||||
"Name": "Name",
|
|
||||||
"OperatingSystem": "Operating System",
|
|
||||||
"OperatingSystemPlaceholder": "Select OS",
|
|
||||||
"IPAdress": "IP Adress",
|
|
||||||
"ManagementURL": "Management URL",
|
|
||||||
"ManagementURLTooltip": "Link to a web interface (e.g. Proxmox or Portainer) with which the server can be managed"
|
|
||||||
},
|
|
||||||
"Hardware": {
|
|
||||||
"CPU": "CPU",
|
|
||||||
"GPU": "GPU",
|
|
||||||
"RAM": "RAM",
|
|
||||||
"Storage": "Storage"
|
|
||||||
},
|
|
||||||
"Host": {
|
|
||||||
"MarkAsHostServer": "Mark as host server",
|
|
||||||
"SelectHostServer": "Select a host server",
|
|
||||||
"SelectHostServerPlaceholder": "Select a host server",
|
|
||||||
"NoHostServer": "No host server"
|
|
||||||
},
|
|
||||||
"Monitoring": {
|
|
||||||
"Enable": "Enable monitoring",
|
|
||||||
"URL": "Monitoring URL",
|
|
||||||
"SetupTitle": "Required Server Setup",
|
|
||||||
"SetupDescription": "To enable monitoring, you need to install Glances on your server. Here's an example Docker Compose configuration:"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Sidebar": {
|
||||||
|
"Main Navigation": "Main Navigation",
|
||||||
|
"Dashboard": "Dashboard",
|
||||||
|
"My Infrastructure": "My Infrastructure",
|
||||||
|
"Servers": "Servers",
|
||||||
|
"Applications": "Applications",
|
||||||
|
"Uptime": "Uptime",
|
||||||
|
"Network": "Network",
|
||||||
|
"Settings": "Settings",
|
||||||
|
"Logout": "Logout"
|
||||||
|
},
|
||||||
|
"Home": {
|
||||||
|
"TitleUnder": "Dashboard to manage your entire server infrastructure",
|
||||||
|
"LoginCardTitle": "Login",
|
||||||
|
"LoginCardDescription": "Enter your credentials to continue",
|
||||||
|
"AuthenticationError": "Authentication Error",
|
||||||
|
"Email": "Email",
|
||||||
|
"Password": "Password",
|
||||||
|
"SigninButton": "Sign in",
|
||||||
|
"SigninButtonSigningIn": "Signing in..."
|
||||||
|
},
|
||||||
|
"Dashboard": {
|
||||||
|
"Title": "Dashboard",
|
||||||
|
"Servers": {
|
||||||
|
"Title": "Servers",
|
||||||
|
"Description": "Physical and virtual servers overview",
|
||||||
|
"PhysicalServers": "Physical Servers",
|
||||||
|
"VirtualServers": "Virtual Servers",
|
||||||
|
"ManageServers": "Manage Servers"
|
||||||
|
},
|
||||||
|
"Applications": {
|
||||||
|
"Title": "Applications",
|
||||||
|
"Description": "Manage your deployed applications",
|
||||||
|
"OnlineApplications": "Running Applications",
|
||||||
|
"ViewAllApplications": "View all applications"
|
||||||
|
},
|
||||||
|
"Uptime": {
|
||||||
|
"Title": "Uptime",
|
||||||
|
"Description": "Monitor your service availability",
|
||||||
|
"OnlineApplications": "Online Applications",
|
||||||
|
"ViewUptimeMetrics": "View uptime metrics"
|
||||||
|
},
|
||||||
|
"Network": {
|
||||||
|
"Title": "Network",
|
||||||
|
"Description": "Manage network configuration",
|
||||||
|
"ActiveConnections": "Active Connections",
|
||||||
|
"ViewNetworkDetails": "View network details"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Servers": {
|
||||||
|
"Title": "Servers",
|
||||||
|
"MyInfrastructure": "My Infrastructure",
|
||||||
|
"YourServers": "Your Servers",
|
||||||
|
"AddServer": {
|
||||||
|
"Title": "Add a server",
|
||||||
|
"General": {
|
||||||
|
"Title": "Add a server",
|
||||||
|
"CopyServer": "Copy server",
|
||||||
|
"Icon": "Icon",
|
||||||
|
"IconPlaceholder": "Select an icon",
|
||||||
|
"IconSearchPlaceholder": "Search icons...",
|
||||||
|
"Preview": "Preview",
|
||||||
|
"Name": "Name",
|
||||||
|
"OperatingSystem": "Operating System",
|
||||||
|
"OperatingSystemPlaceholder": "Select OS",
|
||||||
|
"IPAdress": "IP Adress",
|
||||||
|
"ManagementURL": "Management URL",
|
||||||
|
"ManagementURLTooltip": "Link to a web interface (e.g. Proxmox or Portainer) with which the server can be managed"
|
||||||
|
},
|
||||||
|
"Host": {
|
||||||
|
"MarkAsHostServer": "Mark as host server",
|
||||||
|
"SelectHostServer": "Select a host server",
|
||||||
|
"SelectHostServerPlaceholder": "Select a host server",
|
||||||
|
"NoHostServer": "No host server"
|
||||||
|
},
|
||||||
|
"Monitoring": {
|
||||||
|
"Enable": "Enable monitoring",
|
||||||
|
"URL": "Monitoring URL",
|
||||||
|
"SetupTitle": "Required Server Setup",
|
||||||
|
"SetupDescription": "To enable monitoring, you need to install Glances on your server. Here's an example Docker Compose configuration:"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ServerCard": {
|
||||||
|
"HardwareInformation": "Hardware Information",
|
||||||
|
"ViewDetails": "View Details",
|
||||||
|
"OpenManagementURL": "Open Management URL",
|
||||||
|
"EditServer": "Edit Server",
|
||||||
|
"DeleteServer": "Delete Server",
|
||||||
|
"HostedVMs": "Hosted VMs",
|
||||||
|
"ResourceUsage": "Resource Usage",
|
||||||
|
"DeleteConfirmation": {
|
||||||
|
"Title": "Delete {name}",
|
||||||
|
"Description": "Are you sure you want to delete this server? This action cannot be undone.",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Delete": "Delete"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"EditServer": {
|
||||||
|
"Title": "Edit {name}",
|
||||||
|
"Save": "Save",
|
||||||
|
"General": {
|
||||||
|
"Title": "General",
|
||||||
|
"Icon": "Icon",
|
||||||
|
"Name": "Name",
|
||||||
|
"OperatingSystem": "Operating System",
|
||||||
|
"IPAddress": "IP Address",
|
||||||
|
"ManagementURL": "Management URL"
|
||||||
|
},
|
||||||
|
"Hardware": {
|
||||||
|
"Title": "Hardware",
|
||||||
|
"CPU": "CPU",
|
||||||
|
"GPU": "GPU",
|
||||||
|
"RAM": "RAM",
|
||||||
|
"Disk": "Disk"
|
||||||
|
},
|
||||||
|
"Host": {
|
||||||
|
"Title": "Host",
|
||||||
|
"MarkAsHostServer": "Mark as host server",
|
||||||
|
"CannotDisableHost": "Cannot be disabled while hosting VMs",
|
||||||
|
"SelectHostServer": "Select a host server"
|
||||||
|
},
|
||||||
|
"Monitoring": {
|
||||||
|
"Title": "Monitoring",
|
||||||
|
"Enable": "Enable monitoring",
|
||||||
|
"URL": "Monitoring URL",
|
||||||
|
"SetupTitle": "Required Server Setup",
|
||||||
|
"SetupDescription": "To enable monitoring, you need to install Glances on your server. Here's an example Docker Compose configuration:"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Pagination": {
|
||||||
|
"Showing": "Showing {start}-{end} of {total} servers",
|
||||||
|
"NoServers": "No servers found"
|
||||||
|
},
|
||||||
|
"Search": {
|
||||||
|
"Placeholder": "Type to search..."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user