diff --git a/site/index.html b/site/index.html
index 22e3fed..800e4d6 100644
--- a/site/index.html
+++ b/site/index.html
@@ -2,7 +2,7 @@
-
+
Home
diff --git a/site/public/favicon.svg b/site/public/favicon.svg
new file mode 100644
index 0000000..3d846cb
--- /dev/null
+++ b/site/public/favicon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/site/public/ubik-reiswar.svg b/site/public/ubik-reiswar.svg
new file mode 100644
index 0000000..6e17d50
--- /dev/null
+++ b/site/public/ubik-reiswar.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/site/public/vite.svg b/site/public/vite.svg
deleted file mode 100644
index e7b8dfb..0000000
--- a/site/public/vite.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 550defc..f8cb8d2 100644
--- a/site/src/components/add-server.tsx
+++ b/site/src/components/add-server.tsx
@@ -26,8 +26,8 @@ export function AddServerButton() {
function copyDockerCompose(port: string) {
copyToClipboard(`services:
agent:
- image: 'henrygd/monitor-agent'
- container_name: 'monitor-agent'
+ image: 'henrygd/ubik-agent'
+ container_name: 'ubik-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 9a0162f..d39b136 100644
--- a/site/src/components/charts/container-cpu-chart.tsx
+++ b/site/src/components/charts/container-cpu-chart.tsx
@@ -4,19 +4,21 @@ import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts'
import {
ChartConfig,
ChartContainer,
- ChartLegend,
- ChartLegendContent,
ChartTooltip,
ChartTooltipContent,
} from '@/components/ui/chart'
-import { useMemo, useState } from 'react'
+import { useMemo } from 'react'
import { formatShortDate, formatShortTime } from '@/lib/utils'
+import Spinner from '../spinner'
-export default function ({ chartData }: { chartData: Record[] }) {
- const [containerNames, setContainerNames] = useState([] as string[])
-
+export default function ({
+ chartData,
+ max,
+}: {
+ chartData: Record[]
+ max: number
+}) {
const chartConfig = useMemo(() => {
- console.log('chartData', chartData)
let config = {} as Record<
string,
{
@@ -24,13 +26,21 @@ export default function ({ chartData }: { chartData: Record
- const lastRecord = chartData.at(-1)
- // @ts-ignore
- let allKeys = new Set(Object.keys(lastRecord))
- allKeys.delete('time')
- const keys = Array.from(allKeys)
- keys.sort((a, b) => (lastRecord![b] as number) - (lastRecord![a] as number))
- setContainerNames(keys)
+ const totalUsage = {} as Record
+ for (let stats of chartData) {
+ for (let key in stats) {
+ if (key === 'time') {
+ continue
+ }
+ if (!(key in totalUsage)) {
+ totalUsage[key] = 0
+ }
+ // @ts-ignore
+ totalUsage[key] += stats[key]
+ }
+ }
+ let keys = Object.keys(totalUsage)
+ keys.sort((a, b) => (totalUsage[a] > totalUsage[b] ? -1 : 1))
const length = keys.length
for (let i = 0; i < length; i++) {
const key = keys[i]
@@ -40,12 +50,11 @@ export default function ({ chartData }: { chartData: Record
}
return (
@@ -53,20 +62,23 @@ export default function ({ chartData }: { chartData: Record
- {/* */}
- `${v}%`}
+ />
+
{
- // console.log('itemSorter', item)
- // return -item.value
- // }}
- indicator="line"
- />
- }
+ content={}
/>
- {containerNames.map((key) => (
+ {Object.keys(chartConfig).map((key) => (
))}
- {/* */}
- {/* } className="flex-wrap gap-y-2 mb-2" /> */}
)
diff --git a/site/src/components/charts/cpu-chart.tsx b/site/src/components/charts/cpu-chart.tsx
index b5e3e9c..d4c3ba9 100644
--- a/site/src/components/charts/cpu-chart.tsx
+++ b/site/src/components/charts/cpu-chart.tsx
@@ -7,6 +7,8 @@ import {
ChartTooltipContent,
} from '@/components/ui/chart'
import { formatShortDate, formatShortTime } from '@/lib/utils'
+import { useEffect } from 'react'
+import Spinner from '../spinner'
// for (const data of chartData) {
// data.month = formatDateShort(data.month)
// }
@@ -18,26 +20,26 @@ const chartConfig = {
},
} satisfies ChartConfig
-export default function ({ chartData }: { chartData: { time: string; cpu: number }[] }) {
+export default function ({
+ chartData,
+ max,
+}: {
+ chartData: { time: string; cpu: number }[]
+ max: number
+}) {
+ if (!chartData?.length) {
+ return
+ }
+
return (
-
+
`${v}%`}
/>
{/* todo: short time if first date is same day, otherwise short date */}
diff --git a/site/src/components/charts/disk-chart.tsx b/site/src/components/charts/disk-chart.tsx
index bf405d7..b4023b9 100644
--- a/site/src/components/charts/disk-chart.tsx
+++ b/site/src/components/charts/disk-chart.tsx
@@ -8,6 +8,7 @@ import {
} from '@/components/ui/chart'
import { formatShortDate, formatShortTime } from '@/lib/utils'
import { useMemo } from 'react'
+import Spinner from '../spinner'
// for (const data of chartData) {
// data.month = formatDateShort(data.month)
// }
@@ -37,6 +38,10 @@ export default function ({
// return ticks
// }, [diskSize])
+ if (!chartData.length) {
+ return
+ }
+
return (
+ }
+
return (
diff --git a/site/src/components/logo.tsx b/site/src/components/logo.tsx
new file mode 100644
index 0000000..3a2681f
--- /dev/null
+++ b/site/src/components/logo.tsx
@@ -0,0 +1,18 @@
+export function Logo({ className }: { className?: string }) {
+ return (
+
+ )
+}
+
+export function Can({ className }: { className?: string }) {
+ return (
+
+ )
+}
diff --git a/site/src/components/mode-toggle.tsx b/site/src/components/mode-toggle.tsx
index 90e1157..8ce1f1b 100644
--- a/site/src/components/mode-toggle.tsx
+++ b/site/src/components/mode-toggle.tsx
@@ -1,4 +1,4 @@
-import { Moon, Sun } from 'lucide-react'
+import { MoonStarIcon, Sun } from 'lucide-react'
import { Button } from '@/components/ui/button'
import {
@@ -17,7 +17,7 @@ export function ModeToggle() {
diff --git a/site/src/components/routes/server.tsx b/site/src/components/routes/server.tsx
index 82bb280..61a1d6e 100644
--- a/site/src/components/routes/server.tsx
+++ b/site/src/components/routes/server.tsx
@@ -1,5 +1,5 @@
import { $servers, pb } from '@/lib/stores'
-import { ContainerStatsRecord, SystemRecord, SystemStats, SystemStatsRecord } from '@/types'
+import { ContainerStatsRecord, SystemRecord, SystemStatsRecord } from '@/types'
import { Suspense, lazy, useEffect, useState } from 'react'
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '../ui/card'
import { useStore } from '@nanostores/react'
@@ -8,6 +8,7 @@ import CpuChart from '../charts/cpu-chart'
import MemChart from '../charts/mem-chart'
import DiskChart from '../charts/disk-chart'
import ContainerCpuChart from '../charts/container-cpu-chart'
+import { CpuIcon } from 'lucide-react'
// const CpuChart = lazy(() => import('../cpu-chart'))
@@ -29,7 +30,9 @@ export default function ServerDetail({ name }: { name: string }) {
const [containers, setContainers] = useState([] as ContainerStatsRecord[])
const [serverStats, setServerStats] = useState([] as SystemStatsRecord[])
- const [cpuChartData, setCpuChartData] = useState({} as { time: string; cpu: number }[])
+ const [cpuChartData, setCpuChartData] = useState(
+ {} as { max: number; data: { time: string; cpu: number }[] }
+ )
const [memChartData, setMemChartData] = useState(
{} as { time: string; mem: number; memUsed: number }[]
)
@@ -40,6 +43,16 @@ export default function ServerDetail({ name }: { name: string }) {
[] as Record[]
)
+ useEffect(() => {
+ document.title = name
+ return () => {
+ setContainerCpuChartData([])
+ setCpuChartData({} as { max: number; data: { time: string; cpu: number }[] })
+ setMemChartData([] as { time: string; mem: number; memUsed: number }[])
+ setDiskChartData([] as { time: string; disk: number; diskUsed: number }[])
+ }
+ }, [name])
+
// get stats
useEffect(() => {
if (!('name' in server)) {
@@ -71,15 +84,14 @@ export default function ServerDetail({ name }: { name: string }) {
memData.push({ time: created, mem: stats.mem, memUsed: stats.memUsed })
diskData.push({ time: created, disk: stats.disk, diskUsed: stats.diskUsed })
}
- setCpuChartData(cpuData.reverse())
+ setCpuChartData({
+ max: Math.ceil(Math.max(...cpuData.map((d) => d.cpu))),
+ data: cpuData.reverse(),
+ })
setMemChartData(memData.reverse())
setDiskChartData(diskData.reverse())
}, [serverStats])
- useEffect(() => {
- document.title = name
- }, [name])
-
useEffect(() => {
if ($servers.get().length === 0) {
console.log('skipping')
@@ -117,28 +129,44 @@ export default function ServerDetail({ name }: { name: string }) {
for (let { created, stats } of containers) {
let obj = { time: created } as Record
for (let { name, cpu } of stats) {
- obj[name] = cpu * 10
+ obj[name] = cpu
}
containerCpuData.push(obj)
}
setContainerCpuChartData(containerCpuData.reverse())
- console.log('containerCpuData', containerCpuData)
}, [containers])
return (
<>
-
-
+
+
- CPU Usage
+
+ CPU Usage
+
+
Average usage of the one minute preceding the recorded time
- {/* }> */}
-
- {/* */}
+ }>
+
+
+
+
+
+
+
+ Docker CPU Usage
+
+ {' '}
+ CPU usage of docker containers
+
+
+ }>
+
+
@@ -163,21 +191,6 @@ export default function ServerDetail({ name }: { name: string }) {
{/* */}
-
-
- Container CPU Usage
-
- Average usage of the one minute preceding the recorded time
-
-
-
- {/* }> */}
- {containerCpuChartData.length > 0 && (
-
- )}
- {/* */}
-
-
diff --git a/site/src/components/server-table/data-table.tsx b/site/src/components/server-table/data-table.tsx
index 2c65265..26d00fd 100644
--- a/site/src/components/server-table/data-table.tsx
+++ b/site/src/components/server-table/data-table.tsx
@@ -106,7 +106,7 @@ export default function () {
// size: 70,
accessorKey: 'name',
cell: (info) => (
-
+