From 062796b38c107dba83d27f7b5200ed0e6e7afac7 Mon Sep 17 00:00:00 2001 From: Henry Dollman Date: Tue, 29 Oct 2024 22:22:35 -0400 Subject: [PATCH] update navbar and home subtitle * adds search button to navbar * removes need for home.subtitle_2 --- .../site/src/components/command-palette.tsx | 34 +- beszel/site/src/components/lang-toggle.tsx | 2 +- beszel/site/src/components/navbar.tsx | 147 ++++++++ beszel/site/src/components/routes/home.tsx | 12 +- beszel/site/src/locales/en/translation.json | 354 +++++++++--------- beszel/site/src/main.tsx | 120 +----- 6 files changed, 349 insertions(+), 320 deletions(-) create mode 100644 beszel/site/src/components/navbar.tsx diff --git a/beszel/site/src/components/command-palette.tsx b/beszel/site/src/components/command-palette.tsx index 66f482d..72ea73e 100644 --- a/beszel/site/src/components/command-palette.tsx +++ b/beszel/site/src/components/command-palette.tsx @@ -20,30 +20,34 @@ import { CommandSeparator, CommandShortcut, } from '@/components/ui/command' -import { useEffect, useState } from 'react' +import { useEffect } from 'react' import { useStore } from '@nanostores/react' import { $systems } from '@/lib/stores' import { isAdmin } from '@/lib/utils' import { navigate } from './router' import { useTranslation } from 'react-i18next' -export default function CommandPalette() { +export default function CommandPalette({ + open, + setOpen, +}: { + open: boolean + setOpen: (open: boolean) => void +}) { const { t } = useTranslation() - - const [open, setOpen] = useState(false) const systems = useStore($systems) useEffect(() => { const down = (e: KeyboardEvent) => { if (e.key === 'k' && (e.metaKey || e.ctrlKey)) { e.preventDefault() - setOpen((open) => !open) + setOpen(!open) } } document.addEventListener('keydown', down) return () => document.removeEventListener('keydown', down) - }, []) + }, [open, setOpen]) return ( @@ -75,7 +79,7 @@ export default function CommandPalette() { keywords={['home']} onSelect={() => { navigate('/') - setOpen((open) => !open) + setOpen(false) }} > @@ -85,7 +89,7 @@ export default function CommandPalette() { { navigate('/settings/general') - setOpen((open) => !open) + setOpen(false) }} > @@ -96,7 +100,7 @@ export default function CommandPalette() { keywords={['alerts']} onSelect={() => { navigate('/settings/notifications') - setOpen((open) => !open) + setOpen(false) }} > @@ -117,7 +121,7 @@ export default function CommandPalette() { {isAdmin() && ( <> - + { @@ -127,7 +131,7 @@ export default function CommandPalette() { > {t('user_dm.users')} - {t("command.admin")} + {t('command.admin')} { @@ -137,7 +141,7 @@ export default function CommandPalette() { > {t('user_dm.logs')} - {t("command.admin")} + {t('command.admin')} { @@ -147,7 +151,7 @@ export default function CommandPalette() { > {t('user_dm.backups')} - {t("command.admin")} + {t('command.admin')} {t('user_dm.auth_providers')} - {t("command.admin")} + {t('command.admin')} {t('command.SMTP_settings')} - {t("command.admin")} + {t('command.admin')} diff --git a/beszel/site/src/components/lang-toggle.tsx b/beszel/site/src/components/lang-toggle.tsx index 6736a38..cb91c98 100644 --- a/beszel/site/src/components/lang-toggle.tsx +++ b/beszel/site/src/components/lang-toggle.tsx @@ -23,7 +23,7 @@ export function LangToggle() { diff --git a/beszel/site/src/components/navbar.tsx b/beszel/site/src/components/navbar.tsx new file mode 100644 index 0000000..0573b58 --- /dev/null +++ b/beszel/site/src/components/navbar.tsx @@ -0,0 +1,147 @@ +import { useState, lazy, Suspense } from 'react' +import { Button, buttonVariants } from '@/components/ui/button' +import { + DatabaseBackupIcon, + LockKeyholeIcon, + LogOutIcon, + LogsIcon, + SearchIcon, + ServerIcon, + SettingsIcon, + UserIcon, + UsersIcon, +} from 'lucide-react' +import { TFunction } from 'i18next' +import { Link } from './router' +import { LangToggle } from './lang-toggle' +import { ModeToggle } from './mode-toggle' +import { Logo } from './logo' +import { pb } from '@/lib/stores' +import { cn, isReadOnlyUser, isAdmin } from '@/lib/utils' +import { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuGroup, + DropdownMenuItem, +} from '@/components/ui/dropdown-menu' +import { AddSystemButton } from './add-system' + +const CommandPalette = lazy(() => import('./command-palette.tsx')) + +const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0 + +export default function Navbar(t: TFunction<'translation', undefined>) { + return ( +
+ + + + + + +
+ + + + + + + + + + + {pb.authStore.model?.email} + + + {isAdmin() && ( + <> + + + + {t('user_dm.users')} + + + + + + {t('systems')} + + + + + + {t('user_dm.logs')} + + + + + + {t('user_dm.backups')} + + + + + + {t('user_dm.auth_providers')} + + + + + )} + + pb.authStore.clear()}> + + {t('user_dm.log_out')} + + + + +
+
+ ) +} + +function SearchButton() { + const [open, setOpen] = useState(false) + + const Kbd = ({ children }: { children: React.ReactNode }) => ( + + {children} + + ) + + return ( + <> + + + + + + ) +} diff --git a/beszel/site/src/components/routes/home.tsx b/beszel/site/src/components/routes/home.tsx index 5bb9e11..1085edb 100644 --- a/beszel/site/src/components/routes/home.tsx +++ b/beszel/site/src/components/routes/home.tsx @@ -13,8 +13,6 @@ import { useTranslation } from 'react-i18next' const SystemsTable = lazy(() => import('../systems-table/systems-table')) -const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0 - export default function () { const { t } = useTranslation() @@ -105,18 +103,12 @@ export default function () {
{t('all_systems')} - - {t('home.subtitle_1')}{' '} - - {isMac ? '⌘' : 'Ctrl'}K - {' '} - {t('home.subtitle_2')} - + {t('home.subtitle_1')}
setFilter(e.target.value)} - className="w-full md:w-56 lg:w-80 ml-auto px-4" + className="w-full md:w-56 lg:w-72 ml-auto px-4" />
diff --git a/beszel/site/src/locales/en/translation.json b/beszel/site/src/locales/en/translation.json index 59fccd5..5db9249 100644 --- a/beszel/site/src/locales/en/translation.json +++ b/beszel/site/src/locales/en/translation.json @@ -1,178 +1,178 @@ { - "all_systems": "All Systems", - "filter": "Filter...", - "copy": "Copy", - "add": "Add", - "system": "System", - "systems": "Systems", - "cancel": "Cancel", - "continue": "Continue", - "home": { - "active_alerts": "Active Alerts", - "active_des": "Exceeds {{value}}{{unit}} average in last {{minutes}} min", - "subtitle_1": "Updated in real time. Press", - "subtitle_2": "to open the command palette." - }, - "systems_table": { - "system": "System", - "memory": "Memory", - "cpu": "CPU", - "disk": "Disk", - "net": "Net", - "agent": "Agent", - "no_systems_found": "No systems found.", - "open_menu": "Open menu", - "resume": "Resume", - "pause": "Pause", - "copy_host": "Copy host", - "delete": "Delete", - "delete_confirm": "Are you sure you want to delete {{name}}?", - "delete_confirm_des_1": "This action cannot be undone. This will permanently delete all current records for", - "delete_confirm_des_2": "from the database." - }, - "alerts": { - "title": "Alerts", - "subtitle_1": "See", - "notification_settings": "notification settings", - "subtitle_2": "to configure how you receive 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", - "subtitle": "Manage display and notification preferences.", - "save_settings": "Save Settings", - "export_configuration": "Export configuration", - "general": { - "title": "General", - "subtitle": "Change general application options.", - "language": { - "title": "Language", - "subtitle_1": "Want to help us make our translations even better? Check out", - "subtitle_2": "for more details.", - "preferred_language": "Preferred Language" - }, - "chart_options": { - "title": "Chart options", - "subtitle": "Adjust display options for charts.", - "default_time_period": "Default time period", - "default_time_period_des": "Sets the default time range for charts when a system is viewed." - } - }, - "notifications": { - "title": "Notifications", - "subtitle_1": "Configure how you receive alert notifications.", - "subtitle_2": "Looking instead for where to create alerts? Click the bell", - "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" - }, - "user_dm": { - "users": "Users", - "logs": "Logs", - "backups": "Backups", - "auth_providers": "Auth Providers", - "log_out": "Log Out" - }, - "themes": { - "toggle_theme": "Toggle theme", - "light": "Light", - "dark": "Dark", - "system": "System" - }, - "add_system": { - "add_new_system": "Add New System", - "binary": "Binary", - "dialog_des_1": "The agent must be running on the system to connect. Copy the", - "dialog_des_2": "for the agent below.", - "name": "Name", - "host_ip": "Host / IP", - "port": "Port", - "public_key": "Public Key", - "click_to_copy": "Click to copy", - "command": "command", - "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" - } -} \ No newline at end of file + "all_systems": "All Systems", + "filter": "Filter...", + "copy": "Copy", + "add": "Add", + "system": "System", + "systems": "Systems", + "cancel": "Cancel", + "continue": "Continue", + "home": { + "active_alerts": "Active Alerts", + "active_des": "Exceeds {{value}}{{unit}} average in last {{minutes}} min", + "subtitle_1": "Updated in real time. Click on a system to view information.", + "subtitle_2": "to open the command palette." + }, + "systems_table": { + "system": "System", + "memory": "Memory", + "cpu": "CPU", + "disk": "Disk", + "net": "Net", + "agent": "Agent", + "no_systems_found": "No systems found.", + "open_menu": "Open menu", + "resume": "Resume", + "pause": "Pause", + "copy_host": "Copy host", + "delete": "Delete", + "delete_confirm": "Are you sure you want to delete {{name}}?", + "delete_confirm_des_1": "This action cannot be undone. This will permanently delete all current records for", + "delete_confirm_des_2": "from the database." + }, + "alerts": { + "title": "Alerts", + "subtitle_1": "See", + "notification_settings": "notification settings", + "subtitle_2": "to configure how you receive 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", + "subtitle": "Manage display and notification preferences.", + "save_settings": "Save Settings", + "export_configuration": "Export configuration", + "general": { + "title": "General", + "subtitle": "Change general application options.", + "language": { + "title": "Language", + "subtitle_1": "Want to help us make our translations even better? Check out", + "subtitle_2": "for more details.", + "preferred_language": "Preferred Language" + }, + "chart_options": { + "title": "Chart options", + "subtitle": "Adjust display options for charts.", + "default_time_period": "Default time period", + "default_time_period_des": "Sets the default time range for charts when a system is viewed." + } + }, + "notifications": { + "title": "Notifications", + "subtitle_1": "Configure how you receive alert notifications.", + "subtitle_2": "Looking instead for where to create alerts? Click the bell", + "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" + }, + "user_dm": { + "users": "Users", + "logs": "Logs", + "backups": "Backups", + "auth_providers": "Auth Providers", + "log_out": "Log Out" + }, + "themes": { + "toggle_theme": "Toggle theme", + "light": "Light", + "dark": "Dark", + "system": "System" + }, + "add_system": { + "add_new_system": "Add New System", + "binary": "Binary", + "dialog_des_1": "The agent must be running on the system to connect. Copy the", + "dialog_des_2": "for the agent below.", + "name": "Name", + "host_ip": "Host / IP", + "port": "Port", + "public_key": "Public Key", + "click_to_copy": "Click to copy", + "command": "command", + "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" + } +} diff --git a/beszel/site/src/main.tsx b/beszel/site/src/main.tsx index 5dfb2fb..90e2797 100644 --- a/beszel/site/src/main.tsx +++ b/beszel/site/src/main.tsx @@ -11,50 +11,17 @@ import { $hubVersion, $copyContent, } from './lib/stores.ts' -import { LangToggle } from './components/lang-toggle.tsx' -import { ModeToggle } from './components/mode-toggle.tsx' -import { - cn, - updateUserSettings, - isAdmin, - isReadOnlyUser, - updateAlerts, - updateFavicon, - updateSystemList, -} from './lib/utils.ts' -import { buttonVariants } from './components/ui/button.tsx' -import { - DatabaseBackupIcon, - LockKeyholeIcon, - LogOutIcon, - LogsIcon, - ServerIcon, - SettingsIcon, - UserIcon, - UsersIcon, -} from 'lucide-react' +import { updateUserSettings, updateAlerts, updateFavicon, updateSystemList } from './lib/utils.ts' import { useStore } from '@nanostores/react' import { Toaster } from './components/ui/toaster.tsx' -import { Logo } from './components/logo.tsx' -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuGroup, - DropdownMenuItem, - DropdownMenuSeparator, - DropdownMenuTrigger, - DropdownMenuLabel, -} from './components/ui/dropdown-menu.tsx' -import { $router, Link } from './components/router.tsx' +import { $router } from './components/router.tsx' import SystemDetail from './components/routes/system.tsx' -import { AddSystemButton } from './components/add-system.tsx' import './lib/i18n.ts' import { useTranslation } from 'react-i18next' -import { TFunction } from 'i18next' +import Navbar from './components/navbar.tsx' // const ServerDetail = lazy(() => import('./components/routes/system.tsx')) -const CommandPalette = lazy(() => import('./components/command-palette.tsx')) const LoginPage = lazy(() => import('./components/login/login.tsx')) const CopyToClipboardDialog = lazy(() => import('./components/copy-to-clipboard.tsx')) const Settings = lazy(() => import('./components/routes/settings/layout.tsx')) @@ -115,84 +82,6 @@ const App = () => { } } -const Navbar = (t: TFunction<'translation', undefined>) => { - return ( -
- - - - -
- - - - - - - - - - - {pb.authStore.model?.email} - - - {isAdmin() && ( - <> - - - - {t('user_dm.users')} - - - - - - {t('systems')} - - - - - - {t('user_dm.logs')} - - - - - - {t('user_dm.backups')} - - - - - - {t('user_dm.auth_providers')} - - - - - )} - - pb.authStore.clear()}> - - {t('user_dm.log_out')} - - - - -
-
- ) -} - const Layout = () => { const { t } = useTranslation() @@ -212,9 +101,6 @@ const Layout = () => {
{Navbar(t)}
- - - {copyContent && (