mirror of
https://github.com/fankes/beszel.git
synced 2025-10-19 17:59:28 +08:00
i18n tweaks / layout fixes
This commit is contained in:
@@ -9,12 +9,7 @@ import {
|
|||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
} from '@/components/ui/dialog'
|
} from '@/components/ui/dialog'
|
||||||
import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from '@/components/ui/tooltip'
|
import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from '@/components/ui/tooltip'
|
||||||
import {
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
||||||
Tabs,
|
|
||||||
TabsContent,
|
|
||||||
TabsList,
|
|
||||||
TabsTrigger,
|
|
||||||
} from "@/components/ui/tabs"
|
|
||||||
|
|
||||||
import { Input } from '@/components/ui/input'
|
import { Input } from '@/components/ui/input'
|
||||||
import { Label } from '@/components/ui/label'
|
import { Label } from '@/components/ui/label'
|
||||||
@@ -51,7 +46,9 @@ export function AddSystemButton({ className }: { className?: string }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function copyInstallCommand(port: string) {
|
function copyInstallCommand(port: string) {
|
||||||
copyToClipboard(`curl -sL https://raw.githubusercontent.com/henrygd/beszel/main/supplemental/scripts/install-agent.sh -o install-agent.sh && chmod +x install-agent.sh && ./install-agent.sh -p ${port} -k "${publicKey}"`)
|
copyToClipboard(
|
||||||
|
`curl -sL https://raw.githubusercontent.com/henrygd/beszel/main/supplemental/scripts/install-agent.sh -o install-agent.sh && chmod +x install-agent.sh && ./install-agent.sh -p ${port} -k "${publicKey}"`
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleSubmit(e: SubmitEvent) {
|
async function handleSubmit(e: SubmitEvent) {
|
||||||
@@ -77,10 +74,11 @@ export function AddSystemButton({ className }: { className?: string }) {
|
|||||||
className={cn('flex gap-1 max-xs:h-[2.4rem]', className, isReadOnlyUser() && 'hidden')}
|
className={cn('flex gap-1 max-xs:h-[2.4rem]', className, isReadOnlyUser() && 'hidden')}
|
||||||
>
|
>
|
||||||
<PlusIcon className="h-4 w-4 -ml-1" />
|
<PlusIcon className="h-4 w-4 -ml-1" />
|
||||||
{t('add')}<span className="hidden xs:inline">{t('system')}</span>
|
{t('add')}
|
||||||
|
<span className="hidden sm:inline">{t('system')}</span>
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="w-[90%] sm:max-w-[425px] rounded-lg">
|
<DialogContent className="w-[90%] sm:max-w-[440px] rounded-lg">
|
||||||
<Tabs defaultValue="docker">
|
<Tabs defaultValue="docker">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className="mb-2">{t('add_system.add_new_system')}</DialogTitle>
|
<DialogTitle className="mb-2">{t('add_system.add_new_system')}</DialogTitle>
|
||||||
@@ -93,14 +91,16 @@ export function AddSystemButton({ className }: { className?: string }) {
|
|||||||
<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>
|
</TabsContent>
|
||||||
{/* Binary */}
|
{/* Binary */}
|
||||||
<TabsContent value="binary">
|
<TabsContent value="binary">
|
||||||
<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">install command</code> {t('add_system.dialog_des_2')}
|
<code className="bg-muted px-1 rounded-sm">install command</code>{' '}
|
||||||
|
{t('add_system.dialog_des_2')}
|
||||||
</DialogDescription>
|
</DialogDescription>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<form onSubmit={handleSubmit as any}>
|
<form onSubmit={handleSubmit as any}>
|
||||||
@@ -161,7 +161,7 @@ export function AddSystemButton({ className }: { className?: string }) {
|
|||||||
</div>
|
</div>
|
||||||
{/* Docker */}
|
{/* Docker */}
|
||||||
<TabsContent value="docker">
|
<TabsContent value="docker">
|
||||||
<DialogFooter className="flex justify-end gap-2">
|
<DialogFooter className="flex justify-end gap-2 sm:w-[calc(100%+20px)] sm:-ml-[20px]">
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
variant={'ghost'}
|
variant={'ghost'}
|
||||||
@@ -174,7 +174,7 @@ export function AddSystemButton({ className }: { className?: string }) {
|
|||||||
</TabsContent>
|
</TabsContent>
|
||||||
{/* Binary */}
|
{/* Binary */}
|
||||||
<TabsContent value="binary">
|
<TabsContent value="binary">
|
||||||
<DialogFooter className="flex justify-end gap-2">
|
<DialogFooter className="flex justify-end gap-2 sm:w-[calc(100%+20px)] sm:-ml-[20px]">
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
variant={'ghost'}
|
variant={'ghost'}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { GlobeIcon, Languages } from 'lucide-react'
|
import { LanguagesIcon } from 'lucide-react'
|
||||||
|
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import {
|
import {
|
||||||
@@ -10,19 +10,20 @@ import {
|
|||||||
} from '@/components/ui/dropdown-menu'
|
} from '@/components/ui/dropdown-menu'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import languages from '../lib/languages.json'
|
import languages from '../lib/languages.json'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
export function LangToggle() {
|
export function LangToggle() {
|
||||||
const { i18n } = useTranslation();
|
const { i18n } = useTranslation()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.documentElement.lang = i18n.language;
|
document.documentElement.lang = i18n.language
|
||||||
}, [i18n.language]);
|
}, [i18n.language])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button variant={'ghost'} size="icon">
|
<Button variant={'ghost'} size="icon" className="hidden 450:flex">
|
||||||
<GlobeIcon className="absolute h-[1.2rem] w-[1.2rem]" />
|
<LanguagesIcon className="absolute h-[1.2rem] w-[1.2rem]" />
|
||||||
<span className="sr-only">Language</span>
|
<span className="sr-only">Language</span>
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
@@ -30,7 +31,7 @@ export function LangToggle() {
|
|||||||
{languages.map(({ lang, label }) => (
|
{languages.map(({ lang, label }) => (
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
key={lang}
|
key={lang}
|
||||||
className={lang === i18n.language ? 'font-bold' : ''}
|
className={cn('pl-4', lang === i18n.language ? 'font-bold' : '')}
|
||||||
onClick={() => i18n.changeLanguage(lang)}
|
onClick={() => i18n.changeLanguage(lang)}
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
|
@@ -13,7 +13,7 @@ import { useTranslation } from 'react-i18next'
|
|||||||
|
|
||||||
const SystemsTable = lazy(() => import('../systems-table/systems-table'))
|
const SystemsTable = lazy(() => import('../systems-table/systems-table'))
|
||||||
|
|
||||||
const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
|
const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
@@ -78,13 +78,13 @@ export default function () {
|
|||||||
>
|
>
|
||||||
<info.icon className="h-4 w-4" />
|
<info.icon className="h-4 w-4" />
|
||||||
<AlertTitle>
|
<AlertTitle>
|
||||||
{alert.sysname} {info.name}
|
{alert.sysname} {t(info.name)}
|
||||||
</AlertTitle>
|
</AlertTitle>
|
||||||
<AlertDescription>
|
<AlertDescription>
|
||||||
{t('active_des', {
|
{t('home.active_des', {
|
||||||
value: alert.value,
|
value: alert.value,
|
||||||
unit: info.unit,
|
unit: info.unit,
|
||||||
minutes: alert.min
|
minutes: alert.min,
|
||||||
})}
|
})}
|
||||||
</AlertDescription>
|
</AlertDescription>
|
||||||
<Link
|
<Link
|
||||||
@@ -108,7 +108,7 @@ export default function () {
|
|||||||
<CardDescription>
|
<CardDescription>
|
||||||
{t('home.subtitle_1')}{' '}
|
{t('home.subtitle_1')}{' '}
|
||||||
<kbd className="pointer-events-none inline-flex h-5 select-none items-center gap-0.5 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100">
|
<kbd className="pointer-events-none inline-flex h-5 select-none items-center gap-0.5 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100">
|
||||||
<span className="text-xs">{isMac ? '⌘' : "Ctrl"}</span>K
|
<span className="text-xs">{isMac ? '⌘' : 'Ctrl'}</span>K
|
||||||
</kbd>{' '}
|
</kbd>{' '}
|
||||||
{t('home.subtitle_2')}
|
{t('home.subtitle_2')}
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
|
@@ -9,7 +9,7 @@ import {
|
|||||||
} from '@/components/ui/select'
|
} from '@/components/ui/select'
|
||||||
import { chartTimeData } from '@/lib/utils'
|
import { chartTimeData } from '@/lib/utils'
|
||||||
import { Separator } from '@/components/ui/separator'
|
import { Separator } from '@/components/ui/separator'
|
||||||
import { LoaderCircleIcon, SaveIcon } from 'lucide-react'
|
import { LanguagesIcon, LoaderCircleIcon, SaveIcon } from 'lucide-react'
|
||||||
import { UserSettings } from '@/types'
|
import { UserSettings } from '@/types'
|
||||||
import { saveSettings } from './layout'
|
import { saveSettings } from './layout'
|
||||||
import { useState, useEffect } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
@@ -21,8 +21,8 @@ export default function SettingsProfilePage({ userSettings }: { userSettings: Us
|
|||||||
const { t, i18n } = useTranslation()
|
const { t, i18n } = useTranslation()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.documentElement.lang = i18n.language;
|
document.documentElement.lang = i18n.language
|
||||||
}, [i18n.language]);
|
}, [i18n.language])
|
||||||
|
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
|
||||||
@@ -47,7 +47,10 @@ export default function SettingsProfilePage({ userSettings }: { userSettings: Us
|
|||||||
<form onSubmit={handleSubmit} className="space-y-5">
|
<form onSubmit={handleSubmit} 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">{t('settings.general.language.title')}</h3>
|
<h3 className="mb-1 text-lg font-medium flex items-center gap-2">
|
||||||
|
<LanguagesIcon className="h-4 w-4" />
|
||||||
|
{t('settings.general.language.title')}
|
||||||
|
</h3>
|
||||||
<p className="text-sm text-muted-foreground leading-relaxed">
|
<p className="text-sm text-muted-foreground leading-relaxed">
|
||||||
{t('settings.general.language.subtitle_1')}{' '}
|
{t('settings.general.language.subtitle_1')}{' '}
|
||||||
<a href="https://crowdin.com/project/beszel" className="link" target="_blank">
|
<a href="https://crowdin.com/project/beszel" className="link" target="_blank">
|
||||||
@@ -59,7 +62,7 @@ export default function SettingsProfilePage({ userSettings }: { userSettings: Us
|
|||||||
<Label className="block" htmlFor="lang">
|
<Label className="block" htmlFor="lang">
|
||||||
{t('settings.general.language.preferred_language')}
|
{t('settings.general.language.preferred_language')}
|
||||||
</Label>
|
</Label>
|
||||||
<Select defaultValue={i18n.language} onValueChange={(lang: string) => i18n.changeLanguage(lang)}>
|
<Select value={i18n.language} onValueChange={(lang: string) => i18n.changeLanguage(lang)}>
|
||||||
<SelectTrigger id="lang">
|
<SelectTrigger id="lang">
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
@@ -72,9 +75,12 @@ export default function SettingsProfilePage({ userSettings }: { userSettings: Us
|
|||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
<Separator />
|
||||||
<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">{t('settings.general.chart_options.title')}</h3>
|
<h3 className="mb-1 text-lg font-medium">
|
||||||
|
{t('settings.general.chart_options.title')}
|
||||||
|
</h3>
|
||||||
<p className="text-sm text-muted-foreground leading-relaxed">
|
<p className="text-sm text-muted-foreground leading-relaxed">
|
||||||
{t('settings.general.chart_options.subtitle')}
|
{t('settings.general.chart_options.subtitle')}
|
||||||
</p>
|
</p>
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
"continue": "Continue",
|
"continue": "Continue",
|
||||||
"home": {
|
"home": {
|
||||||
"active_alerts": "Active Alerts",
|
"active_alerts": "Active Alerts",
|
||||||
"active_des": "Exceeds {{value}}{{unit}} average in last {{minutes}} minutes",
|
"active_des": "Exceeds {{value}}{{unit}} average in last {{minutes}} min",
|
||||||
"subtitle_1": "Updated in real time. Press",
|
"subtitle_1": "Updated in real time. Press",
|
||||||
"subtitle_2": "to open the command palette."
|
"subtitle_2": "to open the command palette."
|
||||||
},
|
},
|
||||||
|
@@ -51,6 +51,7 @@ import { AddSystemButton } from './components/add-system.tsx'
|
|||||||
|
|
||||||
import './lib/i18n.ts'
|
import './lib/i18n.ts'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { TFunction } from 'i18next'
|
||||||
|
|
||||||
// const ServerDetail = lazy(() => import('./components/routes/system.tsx'))
|
// const ServerDetail = lazy(() => import('./components/routes/system.tsx'))
|
||||||
const CommandPalette = lazy(() => import('./components/command-palette.tsx'))
|
const CommandPalette = lazy(() => import('./components/command-palette.tsx'))
|
||||||
@@ -114,23 +115,8 @@ const App = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Layout = () => {
|
const Navbar = (t: TFunction<'translation', undefined>) => {
|
||||||
const { t } = useTranslation()
|
|
||||||
|
|
||||||
const authenticated = useStore($authenticated)
|
|
||||||
const copyContent = useStore($copyContent)
|
|
||||||
|
|
||||||
if (!authenticated) {
|
|
||||||
return (
|
return (
|
||||||
<Suspense>
|
|
||||||
<LoginPage />
|
|
||||||
</Suspense>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="container">
|
|
||||||
<div className="flex items-center h-14 md:h-16 bg-card px-4 pr-3 sm:px-6 border bt-0 rounded-md my-4">
|
<div className="flex items-center h-14 md:h-16 bg-card px-4 pr-3 sm:px-6 border bt-0 rounded-md my-4">
|
||||||
<Link href="/" aria-label="Home" className={'p-2 pl-0'}>
|
<Link href="/" aria-label="Home" className={'p-2 pl-0'}>
|
||||||
<Logo className="h-[1.15em] fill-foreground" />
|
<Logo className="h-[1.15em] fill-foreground" />
|
||||||
@@ -204,7 +190,26 @@ const Layout = () => {
|
|||||||
<AddSystemButton className="ml-2" />
|
<AddSystemButton className="ml-2" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const Layout = () => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
const authenticated = useStore($authenticated)
|
||||||
|
const copyContent = useStore($copyContent)
|
||||||
|
|
||||||
|
if (!authenticated) {
|
||||||
|
return (
|
||||||
|
<Suspense>
|
||||||
|
<LoginPage />
|
||||||
|
</Suspense>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="container">{Navbar(t)}</div>
|
||||||
<div className="container mb-14 relative">
|
<div className="container mb-14 relative">
|
||||||
<App />
|
<App />
|
||||||
<Suspense>
|
<Suspense>
|
||||||
|
@@ -24,6 +24,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
screens: {
|
screens: {
|
||||||
xs: '425px',
|
xs: '425px',
|
||||||
|
450: '450px',
|
||||||
},
|
},
|
||||||
colors: {
|
colors: {
|
||||||
green: {
|
green: {
|
||||||
|
Reference in New Issue
Block a user