This commit is contained in:
Arsfy
2024-10-28 18:44:04 +08:00
parent 376e8d4621
commit 5c2e2d7d36
18 changed files with 1261 additions and 228 deletions

Binary file not shown.

View File

@@ -89,11 +89,20 @@ export function AddSystemButton({ className }: { className?: string }) {
<TabsTrigger value="binary">{t('add_system.binary')}</TabsTrigger> <TabsTrigger value="binary">{t('add_system.binary')}</TabsTrigger>
</TabsList> </TabsList>
</DialogHeader> </DialogHeader>
{/* Docker */}
<TabsContent value="docker"> <TabsContent value="docker">
<DialogDescription className={'mb-4'}> <DialogDescription className={'mb-4'}>
{t('add_system.dialog_des_1')}{' '} {t('add_system.dialog_des_1')}{' '}
<code className="bg-muted px-1 rounded-sm">docker-compose.yml</code> {t('add_system.dialog_des_2')} <code className="bg-muted px-1 rounded-sm">docker-compose.yml</code> {t('add_system.dialog_des_2')}
</DialogDescription> </DialogDescription>
</TabsContent>
{/* Binary */}
<TabsContent value="binary">
<DialogDescription className={'mb-4'}>
{t('add_system.dialog_des_1')}{' '}
<code className="bg-muted px-1 rounded-sm">install command</code> {t('add_system.dialog_des_2')}
</DialogDescription>
</TabsContent>
<form onSubmit={handleSubmit as any}> <form onSubmit={handleSubmit as any}>
<div className="grid gap-3 mt-1 mb-4"> <div className="grid gap-3 mt-1 mb-4">
<div className="grid grid-cols-4 items-center gap-4"> <div className="grid grid-cols-4 items-center gap-4">
@@ -150,6 +159,8 @@ export function AddSystemButton({ className }: { className?: string }) {
</TooltipProvider> </TooltipProvider>
</div> </div>
</div> </div>
{/* Docker */}
<TabsContent value="docker">
<DialogFooter className="flex justify-end gap-2"> <DialogFooter className="flex justify-end gap-2">
<Button <Button
type="button" type="button"
@@ -160,69 +171,9 @@ export function AddSystemButton({ className }: { className?: string }) {
</Button> </Button>
<Button>{t('add_system.add_system')}</Button> <Button>{t('add_system.add_system')}</Button>
</DialogFooter> </DialogFooter>
</form>
</TabsContent> </TabsContent>
{/* Binary */}
<TabsContent value="binary"> <TabsContent value="binary">
<DialogDescription className={'mb-4'}>
{t('add_system.dialog_des_1')}{' '}
<code className="bg-muted px-1 rounded-sm">install command</code> {t('add_system.dialog_des_2')}
</DialogDescription>
<form onSubmit={handleSubmit as any}>
<div className="grid gap-3 mt-1 mb-4">
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="name" className="text-right">
{t('add_system.name')}
</Label>
<Input id="name" name="name" className="col-span-3" required />
</div>
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="host" className="text-right">
{t('add_system.host_ip')}
</Label>
<Input id="host" name="host" className="col-span-3" required />
</div>
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="port" className="text-right">
{t('add_system.port')}
</Label>
<Input
ref={port}
name="port"
id="port"
defaultValue="45876"
className="col-span-3"
required
/>
</div>
<div className="grid grid-cols-4 items-center gap-4 relative">
<Label htmlFor="pkey" className="text-right whitespace-pre">
{t('add_system.public_key')}
</Label>
<Input readOnly id="pkey" value={publicKey} className="col-span-3" required></Input>
<div
className={
'h-6 w-24 bg-gradient-to-r from-transparent to-background to-65% absolute right-1 pointer-events-none'
}
></div>
<TooltipProvider delayDuration={100}>
<Tooltip>
<TooltipTrigger asChild>
<Button
type="button"
variant={'link'}
className="absolute right-0"
onClick={() => copyToClipboard(publicKey)}
>
<Copy className="h-4 w-4 " />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>{t('add_system.click_to_copy')}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
</div>
<DialogFooter className="flex justify-end gap-2"> <DialogFooter className="flex justify-end gap-2">
<Button <Button
type="button" type="button"
@@ -233,8 +184,8 @@ export function AddSystemButton({ className }: { className?: string }) {
</Button> </Button>
<Button>{t('add_system.add_system')}</Button> <Button>{t('add_system.add_system')}</Button>
</DialogFooter> </DialogFooter>
</form>
</TabsContent> </TabsContent>
</form>
</Tabs> </Tabs>
</DialogContent> </DialogContent>
</Dialog> </Dialog>

View File

@@ -6,6 +6,7 @@ import { lazy, Suspense, useRef, useState } from 'react'
import { toast } from '../ui/use-toast' import { toast } from '../ui/use-toast'
import { RecordOptions } from 'pocketbase' import { RecordOptions } from 'pocketbase'
import { newQueue, Queue } from '@henrygd/queue' import { newQueue, Queue } from '@henrygd/queue'
import { useTranslation } from 'react-i18next'
interface AlertData { interface AlertData {
checked?: boolean checked?: boolean
@@ -157,6 +158,8 @@ export function SystemAlertGlobal({
} }
function AlertContent({ data }: { data: AlertData }) { function AlertContent({ data }: { data: AlertData }) {
const { t } = useTranslation()
const { key } = data const { key } = data
const hasSliders = !('single' in data.alert) const hasSliders = !('single' in data.alert)
@@ -185,10 +188,10 @@ function AlertContent({ data }: { data: AlertData }) {
> >
<div className="grid gap-1 select-none"> <div className="grid gap-1 select-none">
<p className="font-semibold flex gap-3 items-center capitalize"> <p className="font-semibold flex gap-3 items-center capitalize">
<Icon className="h-4 w-4 opacity-85" /> {data.alert.name} <Icon className="h-4 w-4 opacity-85" /> {t(data.alert.name)}
</p> </p>
{!showSliders && ( {!showSliders && (
<span className="block text-sm text-muted-foreground">{data.alert.desc}</span> <span className="block text-sm text-muted-foreground">{t(data.alert.desc)}</span>
)} )}
</div> </div>
<Switch <Switch
@@ -205,7 +208,7 @@ function AlertContent({ data }: { data: AlertData }) {
<Suspense fallback={<div className="h-10" />}> <Suspense fallback={<div className="h-10" />}>
<div> <div>
<p id={`v${key}`} className="text-sm block h-8"> <p id={`v${key}`} className="text-sm block h-8">
Average exceeds{' '} {t('alerts.average_exceeds')}{' '}
<strong className="text-foreground"> <strong className="text-foreground">
{value} {value}
{data.alert.unit} {data.alert.unit}
@@ -224,8 +227,7 @@ function AlertContent({ data }: { data: AlertData }) {
</div> </div>
<div> <div>
<p id={`t${key}`} className="text-sm block h-8"> <p id={`t${key}`} className="text-sm block h-8">
For <strong className="text-foreground">{min}</strong> minute {t('alerts.for')} <strong className="text-foreground">{min}</strong> {min > 1 ? t('alerts.minutes') : t('alerts.minute')}
{min > 1 && 's'}
</p> </p>
<div className="flex gap-3"> <div className="flex gap-3">
<Slider <Slider

View File

@@ -25,8 +25,11 @@ import { useStore } from '@nanostores/react'
import { $systems } from '@/lib/stores' import { $systems } from '@/lib/stores'
import { isAdmin } from '@/lib/utils' import { isAdmin } from '@/lib/utils'
import { navigate } from './router' import { navigate } from './router'
import { useTranslation } from 'react-i18next'
export default function CommandPalette() { export default function CommandPalette() {
const { t } = useTranslation()
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const systems = useStore($systems) const systems = useStore($systems)
@@ -44,7 +47,7 @@ export default function CommandPalette() {
return ( return (
<CommandDialog open={open} onOpenChange={setOpen}> <CommandDialog open={open} onOpenChange={setOpen}>
<CommandInput placeholder="Search for systems or settings..." /> <CommandInput placeholder={t('command.search')} />
<CommandList> <CommandList>
<CommandEmpty>No results found.</CommandEmpty> <CommandEmpty>No results found.</CommandEmpty>
{systems.length > 0 && ( {systems.length > 0 && (
@@ -67,7 +70,7 @@ export default function CommandPalette() {
<CommandSeparator className="mb-1.5" /> <CommandSeparator className="mb-1.5" />
</> </>
)} )}
<CommandGroup heading="Pages / Settings"> <CommandGroup heading={t('command.pages_settings')}>
<CommandItem <CommandItem
keywords={['home']} keywords={['home']}
onSelect={() => { onSelect={() => {
@@ -76,8 +79,8 @@ export default function CommandPalette() {
}} }}
> >
<LayoutDashboard className="mr-2 h-4 w-4" /> <LayoutDashboard className="mr-2 h-4 w-4" />
<span>Dashboard</span> <span>{t('command.dashboard')}</span>
<CommandShortcut>Page</CommandShortcut> <CommandShortcut>{t('command.page')}</CommandShortcut>
</CommandItem> </CommandItem>
<CommandItem <CommandItem
onSelect={() => { onSelect={() => {
@@ -86,8 +89,8 @@ export default function CommandPalette() {
}} }}
> >
<SettingsIcon className="mr-2 h-4 w-4" /> <SettingsIcon className="mr-2 h-4 w-4" />
<span>Settings</span> <span>{t('settings.settings')}</span>
<CommandShortcut>Settings</CommandShortcut> <CommandShortcut>{t('settings.settings')}</CommandShortcut>
</CommandItem> </CommandItem>
<CommandItem <CommandItem
keywords={['alerts']} keywords={['alerts']}
@@ -97,8 +100,8 @@ export default function CommandPalette() {
}} }}
> >
<MailIcon className="mr-2 h-4 w-4" /> <MailIcon className="mr-2 h-4 w-4" />
<span>Notification settings</span> <span>{t('settings.notifications.title')}</span>
<CommandShortcut>Settings</CommandShortcut> <CommandShortcut>{t('settings.settings')}</CommandShortcut>
</CommandItem> </CommandItem>
<CommandItem <CommandItem
keywords={['github']} keywords={['github']}
@@ -107,14 +110,14 @@ export default function CommandPalette() {
}} }}
> >
<Github className="mr-2 h-4 w-4" /> <Github className="mr-2 h-4 w-4" />
<span>Documentation</span> <span>{t('command.documentation')}</span>
<CommandShortcut>GitHub</CommandShortcut> <CommandShortcut>GitHub</CommandShortcut>
</CommandItem> </CommandItem>
</CommandGroup> </CommandGroup>
{isAdmin() && ( {isAdmin() && (
<> <>
<CommandSeparator className="mb-1.5" /> <CommandSeparator className="mb-1.5" />
<CommandGroup heading="Admin"> <CommandGroup heading={t("command.admin")}>
<CommandItem <CommandItem
keywords={['pocketbase']} keywords={['pocketbase']}
onSelect={() => { onSelect={() => {
@@ -123,8 +126,8 @@ export default function CommandPalette() {
}} }}
> >
<UsersIcon className="mr-2 h-4 w-4" /> <UsersIcon className="mr-2 h-4 w-4" />
<span>Users</span> <span>{t('user_dm.users')}</span>
<CommandShortcut>Admin</CommandShortcut> <CommandShortcut>{t("command.admin")}</CommandShortcut>
</CommandItem> </CommandItem>
<CommandItem <CommandItem
onSelect={() => { onSelect={() => {
@@ -133,8 +136,8 @@ export default function CommandPalette() {
}} }}
> >
<LogsIcon className="mr-2 h-4 w-4" /> <LogsIcon className="mr-2 h-4 w-4" />
<span>Logs</span> <span>{t('user_dm.logs')}</span>
<CommandShortcut>Admin</CommandShortcut> <CommandShortcut>{t("command.admin")}</CommandShortcut>
</CommandItem> </CommandItem>
<CommandItem <CommandItem
onSelect={() => { onSelect={() => {
@@ -143,8 +146,8 @@ export default function CommandPalette() {
}} }}
> >
<DatabaseBackupIcon className="mr-2 h-4 w-4" /> <DatabaseBackupIcon className="mr-2 h-4 w-4" />
<span>Backups</span> <span>{t('user_dm.backups')}</span>
<CommandShortcut>Admin</CommandShortcut> <CommandShortcut>{t("command.admin")}</CommandShortcut>
</CommandItem> </CommandItem>
<CommandItem <CommandItem
keywords={['oauth', 'oicd']} keywords={['oauth', 'oicd']}
@@ -154,8 +157,8 @@ export default function CommandPalette() {
}} }}
> >
<LockKeyholeIcon className="mr-2 h-4 w-4" /> <LockKeyholeIcon className="mr-2 h-4 w-4" />
<span>Auth Providers</span> <span>{t('user_dm.auth_providers')}</span>
<CommandShortcut>Admin</CommandShortcut> <CommandShortcut>{t("command.admin")}</CommandShortcut>
</CommandItem> </CommandItem>
<CommandItem <CommandItem
keywords={['email']} keywords={['email']}
@@ -165,8 +168,8 @@ export default function CommandPalette() {
}} }}
> >
<MailIcon className="mr-2 h-4 w-4" /> <MailIcon className="mr-2 h-4 w-4" />
<span>SMTP settings</span> <span>{t('command.SMTP_settings')}</span>
<CommandShortcut>Admin</CommandShortcut> <CommandShortcut>{t("command.admin")}</CommandShortcut>
</CommandItem> </CommandItem>
</CommandGroup> </CommandGroup>
</> </>

View File

@@ -10,8 +10,11 @@ import { useState } from 'react'
import { Textarea } from '@/components/ui/textarea' import { Textarea } from '@/components/ui/textarea'
import { toast } from '@/components/ui/use-toast' import { toast } from '@/components/ui/use-toast'
import clsx from 'clsx' import clsx from 'clsx'
import { useTranslation } from 'react-i18next'
export default function ConfigYaml() { export default function ConfigYaml() {
const { t } = useTranslation()
const [configContent, setConfigContent] = useState<string>('') const [configContent, setConfigContent] = useState<string>('')
const [isLoading, setIsLoading] = useState(false) const [isLoading, setIsLoading] = useState(false)
@@ -40,30 +43,27 @@ export default function ConfigYaml() {
return ( return (
<div> <div>
<div> <div>
<h3 className="text-xl font-medium mb-2">YAML Configuration</h3> <h3 className="text-xl font-medium mb-2">{t('settings.yaml_config.title')}</h3>
<p className="text-sm text-muted-foreground leading-relaxed"> <p className="text-sm text-muted-foreground leading-relaxed">
Export your current systems configuration. {t('settings.yaml_config.subtitle')}
</p> </p>
</div> </div>
<Separator className="my-4" /> <Separator className="my-4" />
<div className="space-y-2"> <div className="space-y-2">
<div className="mb-4"> <div className="mb-4">
<p className="text-sm text-muted-foreground leading-relaxed my-1"> <p className="text-sm text-muted-foreground leading-relaxed my-1">
Systems may be managed in a{' '} {t('settings.yaml_config.des_1')}{' '}
<code className="bg-muted rounded-sm px-1 text-primary">config.yml</code> file inside <code className="bg-muted rounded-sm px-1 text-primary">config.yml</code> {t('settings.yaml_config.des_2')}
your data directory.
</p> </p>
<p className="text-sm text-muted-foreground leading-relaxed"> <p className="text-sm text-muted-foreground leading-relaxed">
On each restart, systems in the database will be updated to match the systems defined in {t('settings.yaml_config.des_3')}
the file.
</p> </p>
<Alert className="my-4 border-destructive text-destructive w-auto table md:pr-6"> <Alert className="my-4 border-destructive text-destructive w-auto table md:pr-6">
<AlertCircleIcon className="h-4 w-4 stroke-destructive" /> <AlertCircleIcon className="h-4 w-4 stroke-destructive" />
<AlertTitle>Caution - potential data loss</AlertTitle> <AlertTitle>{t('settings.yaml_config.alert.title')}</AlertTitle>
<AlertDescription> <AlertDescription>
<p> <p>
Existing systems not defined in <code>config.yml</code> will be deleted. Please make {t('settings.yaml_config.alert.des_1')} <code>config.yml</code> {t('settings.yaml_config.alert.des_2')}
regular backups.
</p> </p>
</AlertDescription> </AlertDescription>
</Alert> </Alert>
@@ -86,7 +86,7 @@ export default function ConfigYaml() {
disabled={isLoading} disabled={isLoading}
> >
<ButtonIcon className={clsx('h-4 w-4 mr-0.5', isLoading && 'animate-spin')} /> <ButtonIcon className={clsx('h-4 w-4 mr-0.5', isLoading && 'animate-spin')} />
Export configuration {t('settings.export_configuration')}
</Button> </Button>
</div> </div>
) )

View File

@@ -61,7 +61,7 @@ export default function SettingsLayout() {
if (isAdmin()) { if (isAdmin()) {
sidebarNavItems.push({ sidebarNavItems.push({
title: 'YAML Config', title: t('settings.yaml_config.short_title'),
href: '/settings/config', href: '/settings/config',
icon: FileSlidersIcon, icon: FileSlidersIcon,
}) })

View File

@@ -85,38 +85,42 @@ const SettingsNotificationsPage = ({ userSettings }: { userSettings: UserSetting
<div className="space-y-5"> <div className="space-y-5">
<div className="space-y-2"> <div className="space-y-2">
<div className="mb-4"> <div className="mb-4">
<h3 className="mb-1 text-lg font-medium">Email notifications</h3> <h3 className="mb-1 text-lg font-medium">
{t('settings.notifications.email.title')}
</h3>
{isAdmin() && ( {isAdmin() && (
<p className="text-sm text-muted-foreground leading-relaxed"> <p className="text-sm text-muted-foreground leading-relaxed">
Please{' '} {t('settings.notifications.email.please')}{' '}
<a href="/_/#/settings/mail" className="link" target="_blank"> <a href="/_/#/settings/mail" className="link" target="_blank">
configure an SMTP server {t('settings.notifications.email.configure_an_SMTP_server')}
</a>{' '} </a>{' '}
to ensure alerts are delivered.{' '} {t('settings.notifications.email.to_ensure_alerts_are_delivered')}{' '}
</p> </p>
)} )}
</div> </div>
<Label className="block" htmlFor="email"> <Label className="block" htmlFor="email">
To email(s) {t('settings.notifications.email.to_email_s')}
</Label> </Label>
<InputTags <InputTags
value={emails} value={emails}
onChange={setEmails} onChange={setEmails}
placeholder="Enter email address..." placeholder={t('settings.notifications.email.enter_email_address')}
className="w-full" className="w-full"
type="email" type="email"
id="email" id="email"
/> />
<p className="text-[0.8rem] text-muted-foreground"> <p className="text-[0.8rem] text-muted-foreground">
Save address using enter key or comma. Leave blank to disable email notifications. {t('settings.notifications.email.des')}
</p> </p>
</div> </div>
<Separator /> <Separator />
<div className="space-y-3"> <div className="space-y-3">
<div> <div>
<h3 className="mb-1 text-lg font-medium">Webhook / Push notifications</h3> <h3 className="mb-1 text-lg font-medium">
{t('settings.notifications.webhook_push.title')}
</h3>
<p className="text-sm text-muted-foreground leading-relaxed"> <p className="text-sm text-muted-foreground leading-relaxed">
Beszel uses{' '} {t('settings.notifications.webhook_push.des_1')}{' '}
<a <a
href="https://containrrr.dev/shoutrrr/services/overview/" href="https://containrrr.dev/shoutrrr/services/overview/"
target="_blank" target="_blank"
@@ -124,7 +128,7 @@ const SettingsNotificationsPage = ({ userSettings }: { userSettings: UserSetting
> >
Shoutrrr Shoutrrr
</a>{' '} </a>{' '}
to integrate with popular notification services. {t('settings.notifications.webhook_push.des_2')}
</p> </p>
</div> </div>
{webhooks.length > 0 && ( {webhooks.length > 0 && (
@@ -149,7 +153,7 @@ const SettingsNotificationsPage = ({ userSettings }: { userSettings: UserSetting
onClick={addWebhook} onClick={addWebhook}
> >
<PlusIcon className="h-4 w-4 -ml-0.5" /> <PlusIcon className="h-4 w-4 -ml-0.5" />
Add URL {t('settings.notifications.webhook_push.add_url')}
</Button> </Button>
</div> </div>
<Separator /> <Separator />

View File

@@ -97,6 +97,8 @@ async function getStats<T>(
} }
export default function SystemDetail({ name }: { name: string }) { export default function SystemDetail({ name }: { name: string }) {
const { t } = useTranslation()
const systems = useStore($systems) const systems = useStore($systems)
const chartTime = useStore($chartTime) const chartTime = useStore($chartTime)
/** Max CPU toggle value */ /** Max CPU toggle value */
@@ -350,7 +352,7 @@ export default function SystemDetail({ name }: { name: string }) {
<Tooltip> <Tooltip>
<TooltipTrigger asChild> <TooltipTrigger asChild>
<Button <Button
aria-label="Toggle grid" aria-label={t('monitor.toggle_grid')}
variant="outline" variant="outline"
size="icon" size="icon"
className="hidden lg:flex p-0 text-primary" className="hidden lg:flex p-0 text-primary"
@@ -363,7 +365,7 @@ export default function SystemDetail({ name }: { name: string }) {
)} )}
</Button> </Button>
</TooltipTrigger> </TooltipTrigger>
<TooltipContent>Toggle grid</TooltipContent> <TooltipContent>{t('monitor.toggle_grid')}</TooltipContent>
</Tooltip> </Tooltip>
</TooltipProvider> </TooltipProvider>
</div> </div>
@@ -374,9 +376,8 @@ export default function SystemDetail({ name }: { name: string }) {
<div className="grid lg:grid-cols-2 gap-4"> <div className="grid lg:grid-cols-2 gap-4">
<ChartCard <ChartCard
grid={grid} grid={grid}
title="Total CPU Usage" title={t('monitor.total_cpu_usage')}
description={`${cpuMaxStore[0] && isLongerChart ? 'Max 1 min ' : 'Average' description={`${cpuMaxStore[0] && isLongerChart ? t('monitor.max_1_min') : t('monitor.average') } ${t('monitor.cpu_des')}`}
} system-wide CPU utilization`}
cornerEl={isLongerChart ? <SelectAvgMax store={cpuMaxStore} /> : null} cornerEl={isLongerChart ? <SelectAvgMax store={cpuMaxStore} /> : null}
> >
<AreaChartDefault <AreaChartDefault
@@ -390,8 +391,8 @@ export default function SystemDetail({ name }: { name: string }) {
{containerFilterBar && ( {containerFilterBar && (
<ChartCard <ChartCard
grid={grid} grid={grid}
title="Docker CPU Usage" title={t('monitor.docker_cpu_usage')}
description="Average CPU utilization of containers" description={t('monitor.docker_cpu_des')}
cornerEl={containerFilterBar} cornerEl={containerFilterBar}
> >
<ContainerChart chartData={chartData} dataKey="c" chartName="cpu" /> <ContainerChart chartData={chartData} dataKey="c" chartName="cpu" />
@@ -400,8 +401,8 @@ export default function SystemDetail({ name }: { name: string }) {
<ChartCard <ChartCard
grid={grid} grid={grid}
title="Total Memory Usage" title={t('monitor.total_memory_usage')}
description="Precise utilization at the recorded time" description={t('monitor.memory_des')}
> >
<MemChart chartData={chartData} /> <MemChart chartData={chartData} />
</ChartCard> </ChartCard>
@@ -409,15 +410,15 @@ export default function SystemDetail({ name }: { name: string }) {
{containerFilterBar && ( {containerFilterBar && (
<ChartCard <ChartCard
grid={grid} grid={grid}
title="Docker Memory Usage" title={t('monitor.docker_memory_usage')}
description="Memory usage of docker containers" description={t('monitor.docker_memory_des')}
cornerEl={containerFilterBar} cornerEl={containerFilterBar}
> >
<ContainerChart chartData={chartData} chartName="mem" dataKey="m" unit=" MB" /> <ContainerChart chartData={chartData} chartName="mem" dataKey="m" unit=" MB" />
</ChartCard> </ChartCard>
)} )}
<ChartCard grid={grid} title="Disk Space" description="Usage of root partition"> <ChartCard grid={grid} title={t('monitor.disk_space')} description={t('monitor.disk_des')}>
<DiskChart <DiskChart
chartData={chartData} chartData={chartData}
dataKey="stats.du" dataKey="stats.du"
@@ -427,8 +428,8 @@ export default function SystemDetail({ name }: { name: string }) {
<ChartCard <ChartCard
grid={grid} grid={grid}
title="Disk I/O" title={t('monitor.disk_io')}
description="Throughput of root filesystem" description={t('monitor.disk_io_des')}
cornerEl={isLongerChart ? <SelectAvgMax store={diskIoMaxStore} /> : null} cornerEl={isLongerChart ? <SelectAvgMax store={diskIoMaxStore} /> : null}
> >
<AreaChartDefault <AreaChartDefault
@@ -440,9 +441,9 @@ export default function SystemDetail({ name }: { name: string }) {
<ChartCard <ChartCard
grid={grid} grid={grid}
title="Bandwidth" title={t('monitor.bandwidth')}
cornerEl={isLongerChart ? <SelectAvgMax store={bandwidthMaxStore} /> : null} cornerEl={isLongerChart ? <SelectAvgMax store={bandwidthMaxStore} /> : null}
description="Network traffic of public interfaces" description={t('monitor.bandwidth_des')}
> >
<AreaChartDefault <AreaChartDefault
chartData={chartData} chartData={chartData}
@@ -459,8 +460,8 @@ export default function SystemDetail({ name }: { name: string }) {
})} })}
> >
<ChartCard <ChartCard
title="Docker Network I/O" title={t('monitor.docker_network_io')}
description="Includes traffic between internal services" description={t('monitor.docker_network_io_des')}
cornerEl={containerFilterBar} cornerEl={containerFilterBar}
> >
{/* @ts-ignore */} {/* @ts-ignore */}
@@ -470,13 +471,13 @@ export default function SystemDetail({ name }: { name: string }) {
)} )}
{(systemStats.at(-1)?.stats.su ?? 0) > 0 && ( {(systemStats.at(-1)?.stats.su ?? 0) > 0 && (
<ChartCard grid={grid} title="Swap Usage" description="Swap space used by the system"> <ChartCard grid={grid} title={t('monitor.swap_usage')} description={t('monitor.swap_des')}>
<SwapChart chartData={chartData} /> <SwapChart chartData={chartData} />
</ChartCard> </ChartCard>
)} )}
{systemStats.at(-1)?.stats.t && ( {systemStats.at(-1)?.stats.t && (
<ChartCard grid={grid} title="Temperature" description="Temperatures of system sensors"> <ChartCard grid={grid} title={t('monitor.temperature')} description={t('monitor.temperature_des')}>
<TemperatureChart chartData={chartData} /> <TemperatureChart chartData={chartData} />
</ChartCard> </ChartCard>
)} )}
@@ -490,8 +491,8 @@ export default function SystemDetail({ name }: { name: string }) {
<div key={extraFsName} className="contents"> <div key={extraFsName} className="contents">
<ChartCard <ChartCard
grid={grid} grid={grid}
title={`${extraFsName} Usage`} title={`${extraFsName} ${t('monitor.usage')}`}
description={`Disk usage of ${extraFsName}`} description={`${t('monitor.disk_usage_of')} ${extraFsName}`}
> >
<DiskChart <DiskChart
chartData={chartData} chartData={chartData}
@@ -502,7 +503,7 @@ export default function SystemDetail({ name }: { name: string }) {
<ChartCard <ChartCard
grid={grid} grid={grid}
title={`${extraFsName} I/O`} title={`${extraFsName} I/O`}
description={`Throughput of ${extraFsName}`} description={`${t('monitor.throughput_of')} ${extraFsName}`}
cornerEl={isLongerChart ? <SelectAvgMax store={diskIoMaxStore} /> : null} cornerEl={isLongerChart ? <SelectAvgMax store={diskIoMaxStore} /> : null}
> >
<AreaChartDefault <AreaChartDefault
@@ -562,6 +563,8 @@ function SelectAvgMax({
}: { }: {
store: [boolean, React.Dispatch<React.SetStateAction<boolean>>] store: [boolean, React.Dispatch<React.SetStateAction<boolean>>]
}) { }) {
const { t } = useTranslation()
const [max, setMax] = store const [max, setMax] = store
const Icon = max ? ChartMax : ChartAverage const Icon = max ? ChartMax : ChartAverage
@@ -573,10 +576,10 @@ function SelectAvgMax({
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
<SelectItem key="avg" value="avg"> <SelectItem key="avg" value="avg">
Average {t('monitor.average')}
</SelectItem> </SelectItem>
<SelectItem key="max" value="max"> <SelectItem key="max" value="max">
Max 1 min {t('monitor.max_1_min')}
</SelectItem> </SelectItem>
</SelectContent> </SelectContent>
</Select> </Select>

View File

@@ -4,6 +4,11 @@ import LanguageDetector from 'i18next-browser-languagedetector';
import en from '../locales/en/translation.json'; import en from '../locales/en/translation.json';
import es from '../locales/es/translation.json'; import es from '../locales/es/translation.json';
import fr from '../locales/fr/translation.json';
import de from '../locales/de/translation.json';
import ru from '../locales/ru/translation.json';
import zhHans from '../locales/zh-CN/translation.json';
import zhHant from '../locales/zh-HK/translation.json';
i18n i18n
.use(LanguageDetector) .use(LanguageDetector)
@@ -11,7 +16,14 @@ i18n
.init({ .init({
resources: { resources: {
en: { translation: en }, en: { translation: en },
es: { translation: es } es: { translation: es },
fr: { translation: fr },
de: { translation: de },
ru: { translation: ru },
// Chinese (Simplified)
'zh-CN': { translation: zhHans },
// Chinese (Traditional)
'zh-HK': { translation: zhHant },
}, },
fallbackLng: 'en', fallbackLng: 'en',
interpolation: { interpolation: {

View File

@@ -20,11 +20,11 @@
"label": "Русский" "label": "Русский"
}, },
{ {
"lang": "zh-Hans", "lang": "zh-CN",
"label": "简体中文" "label": "简体中文"
}, },
{ {
"lang": "zh-Hant", "lang": "zh-HK",
"label": "繁體中文" "label": "繁體中文"
} }
] ]

View File

@@ -301,40 +301,40 @@ export const chartMargin = { top: 12 }
export const alertInfo = { export const alertInfo = {
Status: { Status: {
name: 'Status', name: 'alerts.info.status',
unit: '', unit: '',
icon: ServerIcon, icon: ServerIcon,
desc: 'Triggers when status switches between up and down.', desc: 'alerts.info.status_des',
single: true, single: true,
}, },
CPU: { CPU: {
name: 'CPU usage', name: 'alerts.info.cpu_usage',
unit: '%', unit: '%',
icon: CpuIcon, icon: CpuIcon,
desc: 'Triggers when CPU usage exceeds a threshold.', desc: 'alerts.info.cpu_usage_des',
}, },
Memory: { Memory: {
name: 'memory usage', name: 'alerts.info.memory_usage',
unit: '%', unit: '%',
icon: MemoryStickIcon, icon: MemoryStickIcon,
desc: 'Triggers when memory usage exceeds a threshold.', desc: 'alerts.info.memory_usage_des',
}, },
Disk: { Disk: {
name: 'disk usage', name: 'alerts.info.disk_usage',
unit: '%', unit: '%',
icon: HardDriveIcon, icon: HardDriveIcon,
desc: 'Triggers when usage of any disk exceeds a threshold.', desc: 'alerts.info.disk_usage_des',
}, },
Bandwidth: { Bandwidth: {
name: 'bandwidth', name: 'alerts.info.bandwidth',
unit: ' MB/s', unit: ' MB/s',
icon: EthernetIcon, icon: EthernetIcon,
desc: 'Triggers when combined up/down exceeds a threshold.', desc: 'alerts.info.bandwidth_des',
}, },
Temperature: { Temperature: {
name: 'temperature', name: 'alerts.info.temperature',
unit: '°C', unit: '°C',
icon: ThermometerIcon, icon: ThermometerIcon,
desc: 'Triggers when any sensor exceeds a threshold.', desc: 'alerts.info.temperature_des',
}, },
} }

View File

@@ -0,0 +1,178 @@
{
"all_systems": "Alle Systeme",
"filter": "Filtern...",
"copy": "Kopieren",
"add": "Hinzufügen",
"system": "System",
"systems": "Systeme",
"cancel": "Abbrechen",
"continue": "Fortsetzen",
"home": {
"active_alerts": "Aktive Warnungen",
"active_des": "Überschreitet {{value}}{{unit}} Durchschnitt in den letzten {{minutes}} Minuten",
"subtitle_1": "In Echtzeit aktualisiert. Drücken Sie",
"subtitle_2": "um die Befehlsübersicht zu öffnen."
},
"systems_table": {
"system": "System",
"memory": "Speicher",
"cpu": "CPU",
"disk": "Festplatte",
"net": "Netzwerk",
"agent": "Agent",
"no_systems_found": "Keine Systeme gefunden.",
"open_menu": "Menü öffnen",
"resume": "Fortsetzen",
"pause": "Pause",
"copy_host": "Host kopieren",
"delete": "Löschen",
"delete_confirm": "Sind Sie sicher, dass Sie {{name}} löschen möchten?",
"delete_confirm_des_1": "Diese Aktion kann nicht rückgängig gemacht werden. Dies wird alle aktuellen Aufzeichnungen für",
"delete_confirm_des_2": "dauerhaft aus der Datenbank löschen."
},
"alerts": {
"title": "Warnungen",
"subtitle_1": "Siehe",
"notification_settings": "Benachrichtigungseinstellungen",
"subtitle_2": "um zu konfigurieren, wie Sie Warnungen erhalten.",
"overwrite_existing_alerts": "Bestehende Warnungen überschreiben",
"info": {
"status": "Status",
"status_des": "Löst aus, wenn der Status zwischen oben und unten wechselt.",
"cpu_usage": "CPU-Auslastung",
"cpu_usage_des": "Löst aus, wenn die CPU-Auslastung einen Schwellenwert überschreitet.",
"memory_usage": "Speicherauslastung",
"memory_usage_des": "Löst aus, wenn die Speicherauslastung einen Schwellenwert überschreitet.",
"disk_usage": "Festplattennutzung",
"disk_usage_des": "Löst aus, wenn die Nutzung einer Festplatte einen Schwellenwert überschreitet.",
"bandwidth": "Bandbreite",
"bandwidth_des": "Löst aus, wenn die kombinierte Auf-/Abwärtsbandbreite einen Schwellenwert überschreitet.",
"temperature": "Temperatur",
"temperature_des": "Löst aus, wenn ein Sensor einen Schwellenwert überschreitet."
},
"average_exceeds": "Durchschnitt überschreitet",
"for": "Für",
"minute": "Minute",
"minutes": "Minuten"
},
"settings": {
"settings": "Einstellungen",
"subtitle": "Anzeige- und Benachrichtigungseinstellungen verwalten.",
"save_settings": "Einstellungen speichern",
"export_configuration": "Konfiguration exportieren",
"general": {
"title": "Allgemein",
"subtitle": "Allgemeine Anwendungsoptionen ändern.",
"language": {
"title": "Sprache",
"subtitle_1": "Möchten Sie uns helfen, unsere Übersetzungen noch besser zu machen? Schauen Sie sich",
"subtitle_2": "für weitere Details an.",
"preferred_language": "Bevorzugte Sprache"
},
"chart_options": {
"title": "Diagrammoptionen",
"subtitle": "Anzeigeoptionen für Diagramme anpassen.",
"default_time_period": "Standardzeitraum",
"default_time_period_des": "Legt den Standardzeitraum für Diagramme fest, wenn ein System angezeigt wird."
}
},
"notifications": {
"title": "Benachrichtigungen",
"subtitle_1": "Konfigurieren Sie, wie Sie Warnbenachrichtigungen erhalten.",
"subtitle_2": "Suchen Sie stattdessen nach dem Ort, an dem Sie Warnungen erstellen können? Klicken Sie auf die Glocke",
"subtitle_3": "Symbole in der Systemtabelle.",
"email": {
"title": "E-Mail-Benachrichtigungen",
"please": "Bitte",
"configure_an_SMTP_server": "konfigurieren Sie einen SMTP-Server",
"to_ensure_alerts_are_delivered": "um sicherzustellen, dass Warnungen zugestellt werden.",
"to_email_s": "An E-Mail(s)",
"enter_email_address": "E-Mail-Adresse eingeben...",
"des": "Adresse mit der Eingabetaste oder dem Komma speichern. Leer lassen, um E-Mail-Benachrichtigungen zu deaktivieren."
},
"webhook_push": {
"title": "Webhook / Push-Benachrichtigungen",
"des_1": "Beszel verwendet",
"des_2": "um sich mit beliebten Benachrichtigungsdiensten zu integrieren.",
"add_url": "URL hinzufügen"
}
},
"yaml_config": {
"short_title": "YAML-Konfig",
"title": "YAML-Konfiguration",
"subtitle": "Aktuelle Systemkonfiguration exportieren.",
"des_1": "Systeme können in einer",
"des_2": "Datei im Datenverzeichnis verwaltet werden.",
"des_3": "Bei jedem Neustart werden die Systeme in der Datenbank aktualisiert, um den in der Datei definierten Systemen zu entsprechen.",
"alert": {
"title": "Achtung - potenzieller Datenverlust",
"des_1": "Bestehende Systeme, die nicht in",
"des_2": "definiert sind, werden gelöscht. Bitte machen Sie regelmäßige Backups."
}
},
"language": "Sprache"
},
"user_dm": {
"users": "Benutzer",
"logs": "Protokolle",
"backups": "Backups",
"auth_providers": "Authentifizierungsanbieter",
"log_out": "Abmelden"
},
"themes": {
"toggle_theme": "Thema wechseln",
"light": "Hell",
"dark": "Dunkel",
"system": "System"
},
"add_system": {
"add_new_system": "Neues System hinzufügen",
"binary": "Binär",
"dialog_des_1": "Der Agent muss auf dem System laufen, um eine Verbindung herzustellen. Kopieren Sie den",
"dialog_des_2": "für den Agenten unten.",
"name": "Name",
"host_ip": "Host / IP",
"port": "Port",
"public_key": "Öffentlicher Schlüssel",
"click_to_copy": "Zum Kopieren klicken",
"command": "Befehl",
"add_system": "System hinzufügen"
},
"command": {
"search": "Nach Systemen oder Einstellungen suchen...",
"pages_settings": "Seiten / Einstellungen",
"dashboard": "Dashboard",
"documentation": "Dokumentation",
"SMTP_settings": "SMTP-Einstellungen",
"page": "Seite",
"admin": "Admin"
},
"monitor": {
"toggle_grid": "Raster umschalten",
"average": "Durchschnitt",
"max_1_min": "Max 1 Min",
"total_cpu_usage": "Gesamte CPU-Auslastung",
"cpu_des": "Systemweite CPU-Auslastung",
"docker_cpu_usage": "Docker-CPU-Auslastung",
"docker_cpu_des": "Durchschnittliche CPU-Auslastung der Container",
"total_memory_usage": "Gesamte Speicherauslastung",
"memory_des": "Genaue Nutzung zum aufgezeichneten Zeitpunkt",
"docker_memory_usage": "Docker-Speicherauslastung",
"docker_memory_des": "Speichernutzung der Docker-Container",
"disk_space": "Festplattenspeicher",
"disk_des": "Nutzung der Root-Partition",
"disk_io": "Festplatten-I/O",
"disk_io_des": "Durchsatz des Root-Dateisystems",
"bandwidth": "Bandbreite",
"bandwidth_des": "Netzwerkverkehr der öffentlichen Schnittstellen",
"docker_network_io": "Docker-Netzwerk-I/O",
"docker_network_io_des": "Netzwerkverkehr der Docker-Container",
"swap_usage": "Swap-Nutzung",
"swap_des": "Vom System genutzter Swap-Speicher",
"temperature": "Temperatur",
"temperature_des": "Temperaturen der System-Sensoren",
"usage": "Nutzung",
"disk_usage_of": "Festplattennutzung von",
"throughput_of": "Durchsatz von"
}
}

View File

@@ -35,12 +35,31 @@
"subtitle_1": "See", "subtitle_1": "See",
"notification_settings": "notification settings", "notification_settings": "notification settings",
"subtitle_2": "to configure how you receive alerts.", "subtitle_2": "to configure how you receive alerts.",
"overwrite_existing_alerts": "Overwrite existing alerts" "overwrite_existing_alerts": "Overwrite existing alerts",
"info": {
"status": "Status",
"status_des": "Triggers when status switches between up and down.",
"cpu_usage": "CPU Usage",
"cpu_usage_des": "Triggers when CPU usage exceeds a threshold.",
"memory_usage": "Memory Usage",
"memory_usage_des": "Triggers when memory usage exceeds a threshold.",
"disk_usage": "Disk Usage",
"disk_usage_des": "Triggers when usage of any disk exceeds a threshold.",
"bandwidth": "Bandwidth",
"bandwidth_des": "Triggers when combined up/down exceeds a threshold.",
"temperature": "Temperature",
"temperature_des": "Triggers when any sensor exceeds a threshold."
},
"average_exceeds": "Average exceeds",
"for": "For",
"minute": "minute",
"minutes": "minutes"
}, },
"settings": { "settings": {
"settings": "Settings", "settings": "Settings",
"subtitle": "Manage display and notification preferences.", "subtitle": "Manage display and notification preferences.",
"save_settings": "Save Settings", "save_settings": "Save Settings",
"export_configuration": "Export configuration",
"general": { "general": {
"title": "General", "title": "General",
"subtitle": "Change general application options.", "subtitle": "Change general application options.",
@@ -61,7 +80,35 @@
"title": "Notifications", "title": "Notifications",
"subtitle_1": "Configure how you receive alert notifications.", "subtitle_1": "Configure how you receive alert notifications.",
"subtitle_2": "Looking instead for where to create alerts? Click the bell", "subtitle_2": "Looking instead for where to create alerts? Click the bell",
"subtitle_3": "icons in the systems table." "subtitle_3": "icons in the systems table.",
"email": {
"title": "Email notifications",
"please": "Please",
"configure_an_SMTP_server": "configure an SMTP server",
"to_ensure_alerts_are_delivered": "to ensure alerts are delivered.",
"to_email_s": "To email(s)",
"enter_email_address": "Enter email address...",
"des": "Save address using enter key or comma. Leave blank to disable email notifications."
},
"webhook_push": {
"title": "Webhook / Push notifications",
"des_1": "Beszel uses",
"des_2": "to integrate with popular notification services.",
"add_url": "Add URL"
}
},
"yaml_config": {
"short_title": "YAML Config",
"title": "YAML Configuration",
"subtitle": "Export your current systems configuration.",
"des_1": "Systems may be managed in a",
"des_2": "file inside your data directory.",
"des_3": "On each restart, systems in the database will be updated to match the systems defined in the file.",
"alert": {
"title": "Caution - potential data loss",
"des_1": "Existing systems not defined in",
"des_2": "will be deleted. Please make regular backups."
}
}, },
"language": "Language" "language": "Language"
}, },
@@ -90,5 +137,42 @@
"click_to_copy": "Click to copy", "click_to_copy": "Click to copy",
"command": "command", "command": "command",
"add_system": "Add system" "add_system": "Add system"
},
"command": {
"search": "Search for systems or settings...",
"pages_settings": "Pages / Settings",
"dashboard": "Dashboard",
"documentation": "Documentation",
"SMTP_settings": "SMTP settings",
"page": "Page",
"admin": "Admin"
},
"monitor": {
"toggle_grid": "Toggle grid",
"average": "Average",
"max_1_min": "Max 1 min ",
"total_cpu_usage": "Total CPU Usage",
"cpu_des": "system-wide CPU utilization",
"docker_cpu_usage": "Docker CPU Usage",
"docker_cpu_des": "Average CPU utilization of containers",
"total_memory_usage": "Total Memory Usage",
"memory_des": "Precise utilization at the recorded time",
"docker_memory_usage": "Docker Memory Usage",
"docker_memory_des": "Memory usage of docker containers",
"disk_space": "Disk Space",
"disk_des": "Usage of root partition",
"disk_io": "Disk I/O",
"disk_io_des": "Throughput of root filesystem",
"bandwidth": "Bandwidth",
"bandwidth_des": "Network traffic of public interfaces",
"docker_network_io": "Docker Network I/O",
"docker_network_io_des": "Network traffic of docker containers",
"swap_usage": "Swap Usage",
"swap_des": "Swap space used by the system",
"temperature": "Temperature",
"temperature_des": "Temperatures of system sensors",
"usage": "Usage",
"disk_usage_of": "Disk usage of",
"throughput_of": "Throughput of"
} }
} }

View File

@@ -33,35 +33,82 @@
"alerts": { "alerts": {
"title": "Alertas", "title": "Alertas",
"subtitle_1": "Ver", "subtitle_1": "Ver",
"notification_settings": "configuración de notificaciones", "notification_settings": "configuraciones de notificación",
"subtitle_2": "para configurar cómo recibe las alertas.", "subtitle_2": "para configurar cómo recibes las alertas.",
"overwrite_existing_alerts": "Sobrescribir alertas existentes" "overwrite_existing_alerts": "Sobrescribir alertas existentes",
"info": {
"status": "Estado",
"status_des": "Se activa cuando el estado cambia entre arriba y abajo.",
"cpu_usage": "Uso de CPU",
"cpu_usage_des": "Se activa cuando el uso de la CPU supera un umbral.",
"memory_usage": "Uso de memoria",
"memory_usage_des": "Se activa cuando el uso de la memoria supera un umbral.",
"disk_usage": "Uso de disco",
"disk_usage_des": "Se activa cuando el uso de cualquier disco supera un umbral.",
"bandwidth": "Ancho de banda",
"bandwidth_des": "Se activa cuando el combinado arriba/abajo supera un umbral.",
"temperature": "Temperatura",
"temperature_des": "Se activa cuando cualquier sensor supera un umbral."
},
"average_exceeds": "Promedio excede",
"for": "Por",
"minute": "minuto",
"minutes": "minutos"
}, },
"settings": { "settings": {
"settings": "Configuración", "settings": "Configuraciones",
"subtitle": "Administrar las preferencias de visualización y notificación.", "subtitle": "Administre las preferencias de visualización y notificación.",
"save_settings": "Guardar configuración", "save_settings": "Guardar configuraciones",
"export_configuration": "Exportar configuración",
"general": { "general": {
"title": "General", "title": "General",
"subtitle": "Cambiar las opciones generales de la aplicación.", "subtitle": "Cambie las opciones generales de la aplicación.",
"language": { "language": {
"title": "Idioma", "title": "Idioma",
"subtitle_1": "¿Quieres ayudarnos a mejorar nuestras traducciones? Consulta", "subtitle_1": "¿Quiere ayudarnos a mejorar nuestras traducciones? Consulte",
"subtitle_2": "para más detalles.", "subtitle_2": "para más detalles.",
"preferred_language": "Idioma preferido" "preferred_language": "Idioma preferido"
}, },
"chart_options": { "chart_options": {
"title": "Opciones de gráfico", "title": "Opciones de gráficos",
"subtitle": "Ajustar las opciones de visualización para los gráficos.", "subtitle": "Ajuste las opciones de visualización para los gráficos.",
"default_time_period": "Periodo de tiempo predeterminado", "default_time_period": "Período de tiempo predeterminado",
"default_time_period_des": "Establece el rango de tiempo predeterminado para los gráficos cuando se visualiza un sistema." "default_time_period_des": "Establezca el rango de tiempo predeterminado para los gráficos cuando se visualiza un sistema."
} }
}, },
"notifications": { "notifications": {
"title": "Notificaciones", "title": "Notificaciones",
"subtitle_1": "Configure cómo recibe las notificaciones de alerta.", "subtitle_1": "Configure cómo recibe las notificaciones de alerta.",
"subtitle_2": "¿Busca dónde crear alertas? Haga clic en el icono de campana", "subtitle_2": "¿Busca en su lugar dónde crear alertas? Haga clic en el icono de campana",
"subtitle_3": "en la tabla de sistemas." "subtitle_3": "en la tabla de sistemas.",
"email": {
"title": "Notificaciones por correo electrónico",
"please": "Por favor",
"configure_an_SMTP_server": "configure un servidor SMTP",
"to_ensure_alerts_are_delivered": "para asegurarse de que se entreguen las alertas.",
"to_email_s": "A correo electrónico(s)",
"enter_email_address": "Ingrese la dirección de correo electrónico...",
"des": "Guarde la dirección presionando Enter o usando una coma. Deje en blanco para desactivar las notificaciones por correo electrónico."
},
"webhook_push": {
"title": "Notificaciones Webhook/Push",
"des_1": "Beszel utiliza",
"des_2": "para integrarse con populares servicios de notificación.",
"add_url": "Agregar URL"
}
},
"yaml_config": {
"short_title": "Configuración YAML",
"title": "Configuración YAML",
"subtitle": "Exporta tu configuración actual de sistemas.",
"des_1": "Los sistemas pueden gestionarse en un",
"des_2": "archivo dentro de tu directorio de datos.",
"des_3": "En cada reinicio, los sistemas de la base de datos se actualizarán para coincidir con los sistemas definidos en el archivo.",
"alert": {
"title": "Advertencia - posible pérdida de datos",
"des_1": "Los sistemas existentes no definidos en",
"des_2": "serán eliminados. Por favor, haz copias de seguridad regulares."
}
}, },
"language": "Idioma" "language": "Idioma"
}, },
@@ -81,14 +128,51 @@
"add_system": { "add_system": {
"add_new_system": "Agregar nuevo sistema", "add_new_system": "Agregar nuevo sistema",
"binary": "Binario", "binary": "Binario",
"dialog_des_1": "El agente debe estar ejecutándose en el sistema para conectarse. Copie el", "dialog_des_1": "El agente debe estar ejecutándose en el sistema para conectarse. Copia el",
"dialog_des_2": "para el agente a continuación.", "dialog_des_2": "para el agente a continuación.",
"name": "Nombre", "name": "Nombre",
"host_ip": "Host/IP", "host_ip": "Host/IP",
"port": "Puerto", "port": "Puerto",
"public_key": "Clave pública", "public_key": "Clave pública",
"click_to_copy": "Haga clic para copiar", "click_to_copy": "Haz clic para copiar",
"command": "comando", "command": "comando",
"add_system": "Agregar sistema" "add_system": "Agregar sistema"
},
"command": {
"search": "Buscar sistemas o configuraciones...",
"pages_settings": "Páginas/Configuraciones",
"dashboard": "Panel de control",
"documentation": "Documentación",
"SMTP_settings": "Configuraciones SMTP",
"page": "Página",
"admin": "Administrador"
},
"monitor": {
"toggle_grid": "Alternar cuadrícula",
"average": "Promedio",
"max_1_min": "Máx. 1 min ",
"total_cpu_usage": "Uso total de CPU",
"cpu_des": "Utilización de CPU de todo el sistema",
"docker_cpu_usage": "Uso de CPU de Docker",
"docker_cpu_des": "Uso promedio de CPU de los contenedores",
"total_memory_usage": "Uso total de memoria",
"memory_des": "Utilización precisa en el momento registrado",
"docker_memory_usage": "Uso de memoria de Docker",
"docker_memory_des": "Uso de memoria de los contenedores de Docker",
"disk_space": "Espacio en disco",
"disk_des": "Uso de la partición raíz",
"disk_io": "E/S de disco",
"disk_io_des": "Rendimiento de la raíz del sistema de archivos",
"bandwidth": "Ancho de banda",
"bandwidth_des": "Tráfico de red de interfaces públicas",
"docker_network_io": "E/S de red de Docker",
"docker_network_io_des": "Tráfico de red de los contenedores de Docker",
"swap_usage": "Uso de intercambio",
"swap_des": "Espacio de intercambio utilizado por el sistema",
"temperature": "Temperatura",
"temperature_des": "Temperaturas de los sensores del sistema",
"usage": "Uso",
"disk_usage_of": "Uso de disco de",
"throughput_of": "Rendimiento de"
} }
} }

View File

@@ -0,0 +1,178 @@
{
"all_systems": "Tous les systèmes",
"filter": "Filtrer...",
"copy": "Copier",
"add": "Ajouter",
"system": "Système",
"systems": "Systèmes",
"cancel": "Annuler",
"continue": "Continuer",
"home": {
"active_alerts": "Alertes actives",
"active_des": "Dépasse {{value}}{{unit}} en moyenne au cours des {{minutes}} dernières minutes",
"subtitle_1": "Mis à jour en temps réel. Appuyez sur",
"subtitle_2": "pour ouvrir la palette de commandes."
},
"systems_table": {
"system": "Système",
"memory": "Mémoire",
"cpu": "CPU",
"disk": "Disque",
"net": "Réseau",
"agent": "Agent",
"no_systems_found": "Aucun système trouvé.",
"open_menu": "Ouvrir le menu",
"resume": "Reprendre",
"pause": "Pause",
"copy_host": "Copier l'hôte",
"delete": "Supprimer",
"delete_confirm": "Êtes-vous sûr de vouloir supprimer {{name}}?",
"delete_confirm_des_1": "Cette action est irréversible. Cela supprimera définitivement tous les enregistrements actuels de",
"delete_confirm_des_2": "de la base de données."
},
"alerts": {
"title": "Alertes",
"subtitle_1": "Voir",
"notification_settings": "paramètres de notification",
"subtitle_2": "pour configurer comment vous recevez les alertes.",
"overwrite_existing_alerts": "Écraser les alertes existantes",
"info": {
"status": "Statut",
"status_des": "Déclenchement lorsque le statut passe de haut en bas.",
"cpu_usage": "Utilisation du CPU",
"cpu_usage_des": "Déclenchement lorsque l'utilisation du CPU dépasse un seuil.",
"memory_usage": "Utilisation de la mémoire",
"memory_usage_des": "Déclenchement lorsque l'utilisation de la mémoire dépasse un seuil.",
"disk_usage": "Utilisation du disque",
"disk_usage_des": "Déclenchement lorsque l'utilisation de n'importe quel disque dépasse un seuil.",
"bandwidth": "Bande passante",
"bandwidth_des": "Déclenchement lorsque le total montant/descendant dépasse un seuil.",
"temperature": "Température",
"temperature_des": "Déclenchement lorsque n'importe quel capteur dépasse un seuil."
},
"average_exceeds": "La moyenne dépasse",
"for": "Pour",
"minute": "minute",
"minutes": "minutes"
},
"settings": {
"settings": "Paramètres",
"subtitle": "Gérer les préférences d'affichage et de notification.",
"save_settings": "Enregistrer les paramètres",
"export_configuration": "Exporter la configuration",
"general": {
"title": "Général",
"subtitle": "Modifier les options générales de l'application.",
"language": {
"title": "Langue",
"subtitle_1": "Vous voulez nous aider à améliorer nos traductions? Consultez",
"subtitle_2": "pour plus de détails.",
"preferred_language": "Langue préférée"
},
"chart_options": {
"title": "Options de graphique",
"subtitle": "Ajuster les options d'affichage pour les graphiques.",
"default_time_period": "Période de temps par défaut",
"default_time_period_des": "Définit la plage de temps par défaut pour les graphiques lorsqu'un système est consulté."
}
},
"notifications": {
"title": "Notifications",
"subtitle_1": "Configurer comment vous recevez les notifications d'alerte.",
"subtitle_2": "Vous cherchez plutôt où créer des alertes? Cliquez sur la cloche",
"subtitle_3": "icônes dans le tableau des systèmes.",
"email": {
"title": "Notifications par email",
"please": "Veuillez",
"configure_an_SMTP_server": "configurer un serveur SMTP",
"to_ensure_alerts_are_delivered": "pour garantir la livraison des alertes.",
"to_email_s": "À email(s)",
"enter_email_address": "Entrez l'adresse email...",
"des": "Enregistrez l'adresse en utilisant la touche entrée ou la virgule. Laissez vide pour désactiver les notifications par email."
},
"webhook_push": {
"title": "Notifications Webhook / Push",
"des_1": "Beszel utilise",
"des_2": "pour s'intégrer avec des services de notification populaires.",
"add_url": "Ajouter une URL"
}
},
"yaml_config": {
"short_title": "Config YAML",
"title": "Configuration YAML",
"subtitle": "Exporter la configuration actuelle de vos systèmes.",
"des_1": "Les systèmes peuvent être gérés dans un fichier",
"des_2": "à l'intérieur de votre répertoire de données.",
"des_3": "À chaque redémarrage, les systèmes dans la base de données seront mis à jour pour correspondre aux systèmes définis dans le fichier.",
"alert": {
"title": "Attention - perte de données potentielle",
"des_1": "Les systèmes existants non définis dans",
"des_2": "seront supprimés. Veuillez faire des sauvegardes régulières."
}
},
"language": "Langue"
},
"user_dm": {
"users": "Utilisateurs",
"logs": "Journaux",
"backups": "Sauvegardes",
"auth_providers": "Fournisseurs d'authentification",
"log_out": "Déconnexion"
},
"themes": {
"toggle_theme": "Changer de thème",
"light": "Clair",
"dark": "Sombre",
"system": "Système"
},
"add_system": {
"add_new_system": "Ajouter un nouveau système",
"binary": "Binaire",
"dialog_des_1": "L'agent doit être en cours d'exécution sur le système pour se connecter. Copiez le",
"dialog_des_2": "pour l'agent ci-dessous.",
"name": "Nom",
"host_ip": "Hôte / IP",
"port": "Port",
"public_key": "Clé publique",
"click_to_copy": "Cliquez pour copier",
"command": "commande",
"add_system": "Ajouter un système"
},
"command": {
"search": "Rechercher des systèmes ou des paramètres...",
"pages_settings": "Pages / Paramètres",
"dashboard": "Tableau de bord",
"documentation": "Documentation",
"SMTP_settings": "Paramètres SMTP",
"page": "Page",
"admin": "Admin"
},
"monitor": {
"toggle_grid": "Changer de grille",
"average": "Moyenne",
"max_1_min": "Max 1 min",
"total_cpu_usage": "Utilisation totale du CPU",
"cpu_des": "utilisation du CPU à l'échelle du système",
"docker_cpu_usage": "Utilisation du CPU Docker",
"docker_cpu_des": "Utilisation moyenne du CPU des conteneurs",
"total_memory_usage": "Utilisation totale de la mémoire",
"memory_des": "Utilisation précise au moment enregistré",
"docker_memory_usage": "Utilisation de la mémoire Docker",
"docker_memory_des": "Utilisation de la mémoire des conteneurs Docker",
"disk_space": "Espace disque",
"disk_des": "Utilisation de la partition racine",
"disk_io": "E/S disque",
"disk_io_des": "Débit du système de fichiers racine",
"bandwidth": "Bande passante",
"bandwidth_des": "Trafic réseau des interfaces publiques",
"docker_network_io": "E/S réseau Docker",
"docker_network_io_des": "Trafic réseau des conteneurs Docker",
"swap_usage": "Utilisation du swap",
"swap_des": "Espace swap utilisé par le système",
"temperature": "Température",
"temperature_des": "Températures des capteurs du système",
"usage": "Utilisation",
"disk_usage_of": "Utilisation du disque de",
"throughput_of": "Débit de"
}
}

View File

@@ -0,0 +1,178 @@
{
"all_systems": "Все системы",
"filter": "Фильтр...",
"copy": "Копировать",
"add": "Добавить",
"system": "Система",
"systems": "Системы",
"cancel": "Отмена",
"continue": "Продолжить",
"home": {
"active_alerts": "Активные предупреждения",
"active_des": "Превышает {{value}}{{unit}} в среднем за последние {{minutes}} минут",
"subtitle_1": "Обновляется в реальном времени. Нажмите",
"subtitle_2": "чтобы открыть палитру команд."
},
"systems_table": {
"system": "Система",
"memory": "Память",
"cpu": "ЦП",
"disk": "Диск",
"net": "Сеть",
"agent": "Агент",
"no_systems_found": "Систем не найдено.",
"open_menu": "Открыть меню",
"resume": "Возобновить",
"pause": "Пауза",
"copy_host": "Копировать хост",
"delete": "Удалить",
"delete_confirm": "Вы уверены, что хотите удалить {{name}}?",
"delete_confirm_des_1": "Это действие нельзя отменить. Это навсегда удалит все текущие записи для",
"delete_confirm_des_2": "из базы данных."
},
"alerts": {
"title": "Предупреждения",
"subtitle_1": "См.",
"notification_settings": "настройки уведомлений",
"subtitle_2": "чтобы настроить, как вы получаете предупреждения.",
"overwrite_existing_alerts": "Перезаписать существующие предупреждения",
"info": {
"status": "Статус",
"status_des": "Срабатывает, когда статус переключается между вверх и вниз.",
"cpu_usage": "Использование ЦП",
"cpu_usage_des": "Срабатывает, когда использование ЦП превышает порог.",
"memory_usage": "Использование памяти",
"memory_usage_des": "Срабатывает, когда использование памяти превышает порог.",
"disk_usage": "Использование диска",
"disk_usage_des": "Срабатывает, когда использование любого диска превышает порог.",
"bandwidth": "Пропускная способность",
"bandwidth_des": "Срабатывает, когда суммарная загрузка/выгрузка превышает порог.",
"temperature": "Температура",
"temperature_des": "Срабатывает, когда любой датчик превышает порог."
},
"average_exceeds": "Среднее значение превышает",
"for": "За",
"minute": "минуту",
"minutes": "минут"
},
"settings": {
"settings": "Настройки",
"subtitle": "Управление предпочтениями отображения и уведомлений.",
"save_settings": "Сохранить настройки",
"export_configuration": "Экспорт конфигурации",
"general": {
"title": "Общие",
"subtitle": "Изменить общие параметры приложения.",
"language": {
"title": "Язык",
"subtitle_1": "Хотите помочь нам улучшить наши переводы? Ознакомьтесь с",
"subtitle_2": "для получения дополнительной информации.",
"preferred_language": "Предпочитаемый язык"
},
"chart_options": {
"title": "Параметры диаграммы",
"subtitle": "Настроить параметры отображения для диаграмм.",
"default_time_period": "Период по умолчанию",
"default_time_period_des": "Устанавливает диапазон времени по умолчанию для диаграмм при просмотре системы."
}
},
"notifications": {
"title": "Уведомления",
"subtitle_1": "Настройте, как вы получаете уведомления о предупреждениях.",
"subtitle_2": "Ищете, где создать предупреждения? Нажмите на колокольчик",
"subtitle_3": "значки в таблице систем.",
"email": {
"title": "Уведомления по электронной почте",
"please": "Пожалуйста",
"configure_an_SMTP_server": "настройте SMTP-сервер",
"to_ensure_alerts_are_delivered": "чтобы гарантировать доставку предупреждений.",
"to_email_s": "На электронную почту(ы)",
"enter_email_address": "Введите адрес электронной почты...",
"des": "Сохраните адрес, используя клавишу ввода или запятую. Оставьте пустым, чтобы отключить уведомления по электронной почте."
},
"webhook_push": {
"title": "Webhook / Push уведомления",
"des_1": "Beszel использует",
"des_2": "для интеграции с популярными сервисами уведомлений.",
"add_url": "Добавить URL"
}
},
"yaml_config": {
"short_title": "YAML Конфиг",
"title": "YAML Конфигурация",
"subtitle": "Экспорт текущей конфигурации ваших систем.",
"des_1": "Системы могут управляться в",
"des_2": "файле в вашем каталоге данных.",
"des_3": "При каждом перезапуске системы в базе данных будут обновлены, чтобы соответствовать системам, определенным в файле.",
"alert": {
"title": "Внимание - возможная потеря данных",
"des_1": "Существующие системы, не определенные в",
"des_2": "будут удалены. Пожалуйста, делайте регулярные резервные копии."
}
},
"language": "Язык"
},
"user_dm": {
"users": "Пользователи",
"logs": "Журналы",
"backups": "Резервные копии",
"auth_providers": "Поставщики аутентификации",
"log_out": "Выйти"
},
"themes": {
"toggle_theme": "Переключить тему",
"light": "Светлая",
"dark": "Темная",
"system": "Система"
},
"add_system": {
"add_new_system": "Добавить новую систему",
"binary": "Бинарный",
"dialog_des_1": "Агент должен работать на системе для подключения. Скопируйте",
"dialog_des_2": "для агента ниже.",
"name": "Имя",
"host_ip": "Хост / IP",
"port": "Порт",
"public_key": "Публичный ключ",
"click_to_copy": "Нажмите, чтобы скопировать",
"command": "команда",
"add_system": "Добавить систему"
},
"command": {
"search": "Поиск систем или настроек...",
"pages_settings": "Страницы / Настройки",
"dashboard": "Панель управления",
"documentation": "Документация",
"SMTP_settings": "Настройки SMTP",
"page": "Страница",
"admin": "Админ"
},
"monitor": {
"toggle_grid": "Переключить сетку",
"average": "Среднее",
"max_1_min": "Макс 1 мин",
"total_cpu_usage": "Общее использование ЦП",
"cpu_des": "системное использование ЦП",
"docker_cpu_usage": "Использование ЦП Docker",
"docker_cpu_des": "Среднее использование ЦП контейнеров",
"total_memory_usage": "Общее использование памяти",
"memory_des": "Точное использование на момент записи",
"docker_memory_usage": "Использование памяти Docker",
"docker_memory_des": "Использование памяти контейнеров Docker",
"disk_space": "Место на диске",
"disk_des": "Использование корневого раздела",
"disk_io": "Дисковый ввод/вывод",
"disk_io_des": "Пропускная способность корневой файловой системы",
"bandwidth": "Пропускная способность",
"bandwidth_des": "Сетевой трафик публичных интерфейсов",
"docker_network_io": "Сетевой ввод/вывод Docker",
"docker_network_io_des": "Сетевой трафик контейнеров Docker",
"swap_usage": "Использование swap",
"swap_des": "Использование swap пространства системой",
"temperature": "Температура",
"temperature_des": "Температуры датчиков системы",
"usage": "Использование",
"disk_usage_of": "Использование диска",
"throughput_of": "Пропускная способность"
}
}

View File

@@ -0,0 +1,178 @@
{
"all_systems": "所有服务器",
"filter": "筛选...",
"copy": "复制",
"add": "添加",
"system": "服务器",
"systems": "服务器",
"cancel": "取消",
"continue": "继续",
"home": {
"active_alerts": "活动警报",
"active_des": "在过去 {{minutes}} 分钟内超过 {{value}}{{unit}} 平均值",
"subtitle_1": "实时更新。按",
"subtitle_2": "打开命令面板。"
},
"systems_table": {
"system": "服务器",
"memory": "内存",
"cpu": "CPU",
"disk": "磁盘",
"net": "网络",
"agent": "客户端",
"no_systems_found": "未找到服务器。",
"open_menu": "打开菜单",
"resume": "恢复",
"pause": "暂停",
"copy_host": "复制主机",
"delete": "删除",
"delete_confirm": "您确定要删除 {{name}} 吗?",
"delete_confirm_des_1": "此操作无法撤消。这将永久从数据库中删除",
"delete_confirm_des_2": "的所有记录。"
},
"alerts": {
"title": "警报",
"subtitle_1": "查看",
"notification_settings": "通知设置",
"subtitle_2": "配置如何接收警报。",
"overwrite_existing_alerts": "覆盖现有警报",
"info": {
"status": "状态",
"status_des": "状态在 在线/离线 之间切换时触发。",
"cpu_usage": "CPU 使用率",
"cpu_usage_des": "当 CPU 使用率超过阈值时触发。",
"memory_usage": "内存使用率",
"memory_usage_des": "当内存使用率超过阈值时触发。",
"disk_usage": "磁盘使用率",
"disk_usage_des": "当任何磁盘的使用率超过阈值时触发。",
"bandwidth": "带宽",
"bandwidth_des": "当组合的 上行/下行 流量超过阈值时触发。",
"temperature": "温度",
"temperature_des": "当任何传感器超过阈值时触发。"
},
"average_exceeds": "平均值超过",
"for": "持续",
"minute": "分钟",
"minutes": "分钟"
},
"settings": {
"settings": "设置",
"subtitle": "管理显示和通知偏好。",
"save_settings": "保存设置",
"export_configuration": "导出配置",
"general": {
"title": "常规",
"subtitle": "更改通用应用程序选项。",
"language": {
"title": "语言",
"subtitle_1": "想帮助我们改进翻译吗?查看",
"subtitle_2": "了解更多详情。",
"preferred_language": "首选语言"
},
"chart_options": {
"title": "图表选项",
"subtitle": "调整图表的显示选项。",
"default_time_period": "默认时间段",
"default_time_period_des": "设置查看服务器时图表的默认时间范围。"
}
},
"notifications": {
"title": "通知",
"subtitle_1": "设置如何接收警报通知。",
"subtitle_2": "正在寻找创建警报的位置?点击服务器列表中的",
"subtitle_3": "图标。",
"email": {
"title": "电子邮件通知",
"please": "配置",
"configure_an_SMTP_server": "SMTP 服务器",
"to_ensure_alerts_are_delivered": "以确保邮件可以成功发送。",
"to_email_s": "收件人邮箱",
"enter_email_address": "输入邮箱地址...",
"des": "使用 Enter 键或逗号保存地址。留空以禁用电子邮件通知。"
},
"webhook_push": {
"title": "Webhook / 推送通知",
"des_1": "Beszel 使用",
"des_2": "与流行的通知服务集成。",
"add_url": "添加 URL"
}
},
"yaml_config": {
"short_title": "YAML 配置",
"title": "YAML 配置",
"subtitle": "导出当前系统配置。",
"des_1": "系统使用",
"des_2": "配置文件储存管理数据",
"des_3": "每次重启时,数据库中的系统将更新以匹配文件中定义的系统。",
"alert": {
"title": "警告 - 潜在数据丢失",
"des_1": "未在",
"des_2": "中定义的现有系统将被删除。请定期备份。"
}
},
"language": "语言"
},
"user_dm": {
"users": "用户",
"logs": "日志",
"backups": "备份",
"auth_providers": "身份验证提供者",
"log_out": "登出"
},
"themes": {
"toggle_theme": "切换主题",
"light": "浅色",
"dark": "深色",
"system": "系统"
},
"add_system": {
"add_new_system": "添加新服务器",
"binary": "二进制文件",
"dialog_des_1": "客户端必须在服务器上运行才能连接。复制",
"dialog_des_2": "到目标服务器以安装。",
"name": "名称",
"host_ip": "主机/IP",
"port": "端口",
"public_key": "公钥",
"click_to_copy": "点击复制",
"command": "命令",
"add_system": "添加服务器"
},
"command": {
"search": "在设置或系统中搜索...",
"pages_settings": "页面 / 设置",
"dashboard": "仪表盘",
"documentation": "文档",
"SMTP_settings": "SMTP 设置",
"page": "页面",
"admin": "管理员"
},
"monitor": {
"toggle_grid": "切换布局",
"average": "平均值",
"max_1_min": "1 分钟最大",
"total_cpu_usage": "总 CPU 使用率",
"cpu_des": "系统范围的 CPU 利用率",
"docker_cpu_usage": "Docker CPU 使用率",
"docker_cpu_des": "Docker 的平均 CPU 利用率",
"total_memory_usage": "总内存使用率",
"memory_des": "记录时间点的精确利用率",
"docker_memory_usage": "Docker 内存使用率",
"docker_memory_des": "Docker 容器的内存使用率",
"disk_space": "磁盘空间",
"disk_des": "根分区的使用情况",
"disk_io": "磁盘 I/O",
"disk_io_des": "根文件系统的吞吐量",
"bandwidth": "带宽",
"bandwidth_des": "公共接口的网络流量",
"docker_network_io": "Docker 网络 I/O",
"docker_network_io_des": "Docker 容器的网络流量",
"swap_usage": "交换空间使用率",
"swap_des": "系统使用的交换空间",
"temperature": "温度",
"temperature_des": "系统传感器的温度",
"usage": "使用率",
"disk_usage_of": "的磁盘使用率",
"throughput_of": "的吞吐量"
}
}

View File

@@ -0,0 +1,178 @@
{
"all_systems": "所有伺服器",
"filter": "篩選...",
"copy": "複製",
"add": "新增",
"system": "伺服器",
"systems": "伺服器",
"cancel": "取消",
"continue": "繼續",
"home": {
"active_alerts": "活動警報",
"active_des": "在過去 {{minutes}} 分鐘內超過 {{value}}{{unit}} 平均值",
"subtitle_1": "即時更新。按",
"subtitle_2": "打開指令面板。"
},
"systems_table": {
"system": "伺服器",
"memory": "記憶體",
"cpu": "CPU",
"disk": "磁碟",
"net": "網絡",
"agent": "客戶端",
"no_systems_found": "未找到伺服器。",
"open_menu": "打開選單",
"resume": "恢復",
"pause": "暫停",
"copy_host": "複製主機",
"delete": "刪除",
"delete_confirm": "您確定要刪除 {{name}} 嗎?",
"delete_confirm_des_1": "此操作無法撤銷。這將永久從資料庫中刪除",
"delete_confirm_des_2": "的所有記錄。"
},
"alerts": {
"title": "警報",
"subtitle_1": "查看",
"notification_settings": "通知設定",
"subtitle_2": "配置如何接收警報。",
"overwrite_existing_alerts": "覆蓋現有警報",
"info": {
"status": "狀態",
"status_des": "狀態在 在線/離線 之間切換時觸發。",
"cpu_usage": "CPU 使用率",
"cpu_usage_des": "當 CPU 使用率超過閾值時觸發。",
"memory_usage": "記憶體使用率",
"memory_usage_des": "當記憶體使用率超過閾值時觸發。",
"disk_usage": "磁碟使用率",
"disk_usage_des": "當任何磁碟的使用率超過閾值時觸發。",
"bandwidth": "頻寬",
"bandwidth_des": "當組合的 上行/下行 流量超過閾值時觸發。",
"temperature": "溫度",
"temperature_des": "當任何感應器超過閾值時觸發。"
},
"average_exceeds": "平均值超過",
"for": "持續",
"minute": "分鐘",
"minutes": "分鐘"
},
"settings": {
"settings": "設定",
"subtitle": "管理顯示和通知偏好。",
"save_settings": "儲存設定",
"export_configuration": "匯出配置",
"general": {
"title": "一般",
"subtitle": "更改通用應用程式選項。",
"language": {
"title": "語言",
"subtitle_1": "想幫助我們改進翻譯嗎?查看",
"subtitle_2": "了解更多詳情。",
"preferred_language": "首選語言"
},
"chart_options": {
"title": "圖表選項",
"subtitle": "調整圖表的顯示選項。",
"default_time_period": "預設時間段",
"default_time_period_des": "設定查看伺服器時圖表的預設時間範圍。"
}
},
"notifications": {
"title": "通知",
"subtitle_1": "設定如何接收警報通知。",
"subtitle_2": "正在尋找建立警報的位置?點擊伺服器列表中的",
"subtitle_3": "圖示。",
"email": {
"title": "電郵通知",
"please": "配置",
"configure_an_SMTP_server": "SMTP 伺服器",
"to_ensure_alerts_are_delivered": "以確保郵件可以成功發送。",
"to_email_s": "收件人電郵",
"enter_email_address": "輸入電郵地址...",
"des": "使用 Enter 鍵或逗號儲存地址。留空以禁用電郵通知。"
},
"webhook_push": {
"title": "Webhook / 推送通知",
"des_1": "Beszel 使用",
"des_2": "與流行的通知服務整合。",
"add_url": "新增 URL"
}
},
"yaml_config": {
"short_title": "YAML 配置",
"title": "YAML 配置",
"subtitle": "匯出當前系統配置。",
"des_1": "系統使用",
"des_2": "配置檔案儲存管理數據",
"des_3": "每次重啟時,資料庫中的系統將更新以匹配檔案中定義的系統。",
"alert": {
"title": "警告 - 潛在數據丟失",
"des_1": "未在",
"des_2": "中定義的現有系統將被刪除。請定期備份。"
}
},
"language": "語言"
},
"user_dm": {
"users": "用戶",
"logs": "日誌",
"backups": "備份",
"auth_providers": "身份驗證提供者",
"log_out": "登出"
},
"themes": {
"toggle_theme": "切換主題",
"light": "淺色",
"dark": "深色",
"system": "系統"
},
"add_system": {
"add_new_system": "新增新伺服器",
"binary": "二進制檔案",
"dialog_des_1": "客戶端必須在伺服器上運行才能連接。複製",
"dialog_des_2": "到目標伺服器以安裝。",
"name": "名稱",
"host_ip": "主機/IP",
"port": "端口",
"public_key": "公鑰",
"click_to_copy": "點擊複製",
"command": "指令",
"add_system": "新增伺服器"
},
"command": {
"search": "在設定或系統中搜尋...",
"pages_settings": "頁面 / 設定",
"dashboard": "儀表板",
"documentation": "文件",
"SMTP_settings": "SMTP 設定",
"page": "頁面",
"admin": "管理員"
},
"monitor": {
"toggle_grid": "切換佈局",
"average": "平均值",
"max_1_min": "1 分鐘最大",
"total_cpu_usage": "總 CPU 使用率",
"cpu_des": "系統範圍的 CPU 利用率",
"docker_cpu_usage": "Docker CPU 使用率",
"docker_cpu_des": "Docker 的平均 CPU 利用率",
"total_memory_usage": "總記憶體使用率",
"memory_des": "記錄時間點的精確利用率",
"docker_memory_usage": "Docker 記憶體使用率",
"docker_memory_des": "Docker 容器的記憶體使用率",
"disk_space": "磁碟空間",
"disk_des": "根分區的使用情況",
"disk_io": "磁碟 I/O",
"disk_io_des": "根檔案系統的吞吐量",
"bandwidth": "頻寬",
"bandwidth_des": "公共介面的網絡流量",
"docker_network_io": "Docker 網絡 I/O",
"docker_network_io_des": "Docker 容器的網絡流量",
"swap_usage": "交換空間使用率",
"swap_des": "系統使用的交換空間",
"temperature": "溫度",
"temperature_des": "系統感應器的溫度",
"usage": "使用率",
"disk_usage_of": "的磁碟使用率",
"throughput_of": "的吞吐量"
}
}