From aacaf2f04f7cd40a8bdb81a3251bdc48c630fa28 Mon Sep 17 00:00:00 2001 From: Henry Dollman Date: Fri, 12 Jul 2024 20:12:50 -0400 Subject: [PATCH] updates --- main.go | 4 +- site/index.html | 2 +- site/public/favicon-green.svg | 1 + site/public/favicon-red.svg | 1 + site/public/favicon.svg | 2 +- site/public/ubik-reiswar.svg | 1 - site/src/components/add-server.tsx | 4 +- .../components/charts/container-cpu-chart.tsx | 2 +- site/src/components/charts/disk-chart.tsx | 2 +- site/src/components/charts/mem-chart.tsx | 41 +++++++++++++++---- site/src/components/logo.tsx | 4 +- site/src/components/routes/home.tsx | 4 +- site/src/components/routes/server.tsx | 8 ++-- site/src/index.css | 4 ++ site/src/lib/utils.ts | 3 ++ site/src/main.tsx | 20 +++++++-- site/src/types.d.ts | 2 + 17 files changed, 77 insertions(+), 28 deletions(-) create mode 100644 site/public/favicon-green.svg create mode 100644 site/public/favicon-red.svg delete mode 100644 site/public/ubik-reiswar.svg diff --git a/main.go b/main.go index 7c44f8a..e5ba1cd 100644 --- a/main.go +++ b/main.go @@ -94,8 +94,10 @@ func main() { return nil }) - // create ssh key if it doesn't exist app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + // create ssh key if it doesn't exist + getSSHKey() + // api route to return public key e.Router.GET("/getkey", func(c echo.Context) error { requestData := apis.RequestInfo(c) if requestData.Admin == nil { diff --git a/site/index.html b/site/index.html index 800e4d6..e3e71c6 100644 --- a/site/index.html +++ b/site/index.html @@ -4,7 +4,7 @@ - Home + Qoma \ No newline at end of file diff --git a/site/public/favicon-red.svg b/site/public/favicon-red.svg new file mode 100644 index 0000000..34daf83 --- /dev/null +++ b/site/public/favicon-red.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/site/public/favicon.svg b/site/public/favicon.svg index 3d846cb..d5f3cac 100644 --- a/site/public/favicon.svg +++ b/site/public/favicon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/site/public/ubik-reiswar.svg b/site/public/ubik-reiswar.svg deleted file mode 100644 index 6e17d50..0000000 --- a/site/public/ubik-reiswar.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/src/components/add-server.tsx b/site/src/components/add-server.tsx index 0c9a8cb..6aa0b93 100644 --- a/site/src/components/add-server.tsx +++ b/site/src/components/add-server.tsx @@ -27,8 +27,8 @@ export function AddServerButton() { function copyDockerCompose(port: string) { copyToClipboard(`services: agent: - image: 'henrygd/quoma-agent' - container_name: 'quoma-agent' + image: 'henrygd/qoma-agent' + container_name: 'qoma-agent' restart: unless-stopped ports: - '${port}:45876' diff --git a/site/src/components/charts/container-cpu-chart.tsx b/site/src/components/charts/container-cpu-chart.tsx index 92d3734..1f6878e 100644 --- a/site/src/components/charts/container-cpu-chart.tsx +++ b/site/src/components/charts/container-cpu-chart.tsx @@ -63,7 +63,7 @@ export default function ({ chartData }: { chartData: Record Math.ceil(max)]} + domain={[0, (max: number) => Math.max(Math.ceil(max), 0.4)]} // tickCount={5} tickLine={false} axisLine={false} diff --git a/site/src/components/charts/disk-chart.tsx b/site/src/components/charts/disk-chart.tsx index 736e0fa..61cc404 100644 --- a/site/src/components/charts/disk-chart.tsx +++ b/site/src/components/charts/disk-chart.tsx @@ -15,7 +15,7 @@ import Spinner from '../spinner' const chartConfig = { diskUsed: { - label: 'Disk Use', + label: 'Disk Usage', color: 'hsl(var(--chart-3))', }, } satisfies ChartConfig diff --git a/site/src/components/charts/mem-chart.tsx b/site/src/components/charts/mem-chart.tsx index a3dc2dc..e4f663b 100644 --- a/site/src/components/charts/mem-chart.tsx +++ b/site/src/components/charts/mem-chart.tsx @@ -10,22 +10,29 @@ import { formatShortDate, formatShortTime } from '@/lib/utils' import { useMemo } from 'react' import Spinner from '../spinner' -const chartConfig = { - memUsed: { - label: 'Memory Use', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - export default function ({ chartData, }: { - chartData: { time: string; mem: number; memUsed: number }[] + chartData: { time: string; mem: number; memUsed: number; memCache: number }[] }) { const totalMem = useMemo(() => { return Math.ceil(chartData[0]?.mem) }, [chartData]) + const chartConfig = useMemo( + () => ({ + memCache: { + label: 'Cache / Buffers', + color: 'hsl(var(--chart-2))', + }, + memUsed: { + label: 'Used', + color: 'hsl(var(--chart-2))', + }, + }), + [] + ) satisfies ChartConfig + if (!chartData.length) { return } @@ -61,7 +68,13 @@ export default function ({ + a.name.localeCompare(b.name)} + labelFormatter={formatShortDate} + indicator="line" + /> } /> + diff --git a/site/src/components/logo.tsx b/site/src/components/logo.tsx index af017ed..5715bdc 100644 --- a/site/src/components/logo.tsx +++ b/site/src/components/logo.tsx @@ -1,8 +1,8 @@ export function Logo({ className }: { className?: string }) { return ( // audiowide - - + + ) } diff --git a/site/src/components/routes/home.tsx b/site/src/components/routes/home.tsx index 3a9a46c..0f9bdb3 100644 --- a/site/src/components/routes/home.tsx +++ b/site/src/components/routes/home.tsx @@ -9,7 +9,7 @@ const DataTable = lazy(() => import('../server-table/data-table')) export default function () { useEffect(() => { - document.title = 'Home' + document.title = 'Qoma Dashboard' }, []) useEffect(updateServerList, []) @@ -49,7 +49,7 @@ export default function () { <> - All Servers + All Systems Updated in real time. Press{' '} diff --git a/site/src/components/routes/server.tsx b/site/src/components/routes/server.tsx index f137862..5c3fe78 100644 --- a/site/src/components/routes/server.tsx +++ b/site/src/components/routes/server.tsx @@ -33,7 +33,7 @@ export default function ServerDetail({ name }: { name: string }) { const [serverStats, setServerStats] = useState([] as SystemStatsRecord[]) const [cpuChartData, setCpuChartData] = useState([] as { time: string; cpu: number }[]) const [memChartData, setMemChartData] = useState( - [] as { time: string; mem: number; memUsed: number }[] + [] as { time: string; mem: number; memUsed: number; memCache: number }[] ) const [diskChartData, setDiskChartData] = useState( [] as { time: string; disk: number; diskUsed: number }[] @@ -46,7 +46,7 @@ export default function ServerDetail({ name }: { name: string }) { ) useEffect(() => { - document.title = name + document.title = `${name} / Qoma` return () => { setContainerCpuChartData([]) setCpuChartData([]) @@ -80,12 +80,12 @@ export default function ServerDetail({ name }: { name: string }) { } // let maxCpu = 0 const cpuData = [] as { time: string; cpu: number }[] - const memData = [] as { time: string; mem: number; memUsed: number }[] + const memData = [] as { time: string; mem: number; memUsed: number; memCache: number }[] const diskData = [] as { time: string; disk: number; diskUsed: number }[] for (let { created, stats } of serverStats) { cpuData.push({ time: created, cpu: stats.c }) // maxCpu = Math.max(maxCpu, stats.c) - memData.push({ time: created, mem: stats.m, memUsed: stats.mu }) + memData.push({ time: created, mem: stats.m, memUsed: stats.mu, memCache: stats.mb }) diskData.push({ time: created, disk: stats.d, diskUsed: stats.du }) } setCpuChartData(cpuData.reverse()) diff --git a/site/src/index.css b/site/src/index.css index 92b0133..922d8ed 100644 --- a/site/src/index.css +++ b/site/src/index.css @@ -62,6 +62,10 @@ z-index: 1; } +.recharts-yAxis { + font-variant-numeric: tabular-nums; +} + /* charts */ @layer base { :root { diff --git a/site/src/lib/utils.ts b/site/src/lib/utils.ts index ce378f5..cf11fda 100644 --- a/site/src/lib/utils.ts +++ b/site/src/lib/utils.ts @@ -51,3 +51,6 @@ const shortDateFormatter = new Intl.DateTimeFormat(undefined, { minute: 'numeric', }) export const formatShortDate = (timestamp: string) => shortDateFormatter.format(new Date(timestamp)) + +export const updateFavicon = (newIconUrl: string) => + ((document.querySelector("link[rel='icon']") as HTMLLinkElement).href = newIconUrl) diff --git a/site/src/main.tsx b/site/src/main.tsx index e21fffc..668f8b3 100644 --- a/site/src/main.tsx +++ b/site/src/main.tsx @@ -3,9 +3,9 @@ import React, { Suspense, lazy, useEffect } from 'react' import ReactDOM from 'react-dom/client' import Home from './components/routes/home.tsx' import { ThemeProvider } from './components/theme-provider.tsx' -import { $authenticated, $router, navigate } from './lib/stores.ts' +import { $authenticated, $router, $servers, navigate } from './lib/stores.ts' import { ModeToggle } from './components/mode-toggle.tsx' -import { cn, updateServerList } from './lib/utils.ts' +import { cn, updateFavicon, updateServerList } from './lib/utils.ts' import { buttonVariants } from './components/ui/button.tsx' import { Github } from 'lucide-react' import { useStore } from '@nanostores/react' @@ -24,10 +24,24 @@ const LoginPage = lazy(() => import('./components/login.tsx')) const App = () => { const page = useStore($router) + const authenticated = useStore($authenticated) + const servers = useStore($servers) // get servers useEffect(updateServerList, []) + // update favicon + useEffect(() => { + if (!authenticated || !servers.length) { + updateFavicon('/favicon.svg') + } else if (servers.find((server) => !server.active)) { + updateFavicon('/favicon-red.svg') + } else { + // all servers good + updateFavicon('/favicon-green.svg') + } + }, [authenticated, servers]) + if (!page) { return

404

} else if (page.path === '/') { @@ -61,7 +75,7 @@ const Layout = () => { navigate('/') }} > - +
diff --git a/site/src/types.d.ts b/site/src/types.d.ts index 8f5610f..45e0bb6 100644 --- a/site/src/types.d.ts +++ b/site/src/types.d.ts @@ -21,6 +21,8 @@ export interface SystemStats { m: number /** memory percent */ mp: number + /** memory buffer + cache (gb) */ + mb: number /** memory used (gb) */ mu: number }