mirror of
https://github.com/fankes/beszel.git
synced 2025-10-19 17:59:28 +08:00
updates
This commit is contained in:
@@ -17,6 +17,7 @@ import { Copy, Plus } from 'lucide-react'
|
|||||||
import { useState, useRef, MutableRefObject, useEffect } from 'react'
|
import { useState, useRef, MutableRefObject, useEffect } from 'react'
|
||||||
import { useStore } from '@nanostores/react'
|
import { useStore } from '@nanostores/react'
|
||||||
import { copyToClipboard } from '@/lib/utils'
|
import { copyToClipboard } from '@/lib/utils'
|
||||||
|
import { SystemStats } from '@/types'
|
||||||
|
|
||||||
export function AddServerButton() {
|
export function AddServerButton() {
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
@@ -53,14 +54,14 @@ export function AddServerButton() {
|
|||||||
const formData = new FormData(e.target as HTMLFormElement)
|
const formData = new FormData(e.target as HTMLFormElement)
|
||||||
const data = Object.fromEntries(formData) as Record<string, any>
|
const data = Object.fromEntries(formData) as Record<string, any>
|
||||||
data.stats = {
|
data.stats = {
|
||||||
cpu: 0,
|
c: 0,
|
||||||
mem: 0,
|
d: 0,
|
||||||
memUsed: 0,
|
dp: 0,
|
||||||
memPct: 0,
|
du: 0,
|
||||||
disk: 0,
|
m: 0,
|
||||||
diskUsed: 0,
|
mp: 0,
|
||||||
diskPct: 0,
|
mu: 0,
|
||||||
}
|
} as SystemStats
|
||||||
try {
|
try {
|
||||||
setOpen(false)
|
setOpen(false)
|
||||||
await pb.collection('systems').create(data)
|
await pb.collection('systems').create(data)
|
||||||
@@ -97,7 +98,7 @@ export function AddServerButton() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-4 items-center gap-4">
|
<div className="grid grid-cols-4 items-center gap-4">
|
||||||
<Label htmlFor="ip" className="text-right">
|
<Label htmlFor="ip" className="text-right">
|
||||||
IP Address
|
Host / IP
|
||||||
</Label>
|
</Label>
|
||||||
<Input id="ip" name="ip" className="col-span-3" required />
|
<Input id="ip" name="ip" className="col-span-3" required />
|
||||||
</div>
|
</div>
|
||||||
|
@@ -62,16 +62,20 @@ export default function ({
|
|||||||
<AreaChart
|
<AreaChart
|
||||||
accessibilityLayer
|
accessibilityLayer
|
||||||
data={chartData}
|
data={chartData}
|
||||||
|
margin={{
|
||||||
|
top: 10,
|
||||||
|
}}
|
||||||
|
|
||||||
// reverseStackOrder={true}
|
// reverseStackOrder={true}
|
||||||
>
|
>
|
||||||
<CartesianGrid vertical={false} />
|
<CartesianGrid vertical={false} />
|
||||||
<YAxis
|
<YAxis
|
||||||
domain={[0, max]}
|
domain={[0, (max: number) => Math.ceil(max)]}
|
||||||
tickCount={5}
|
// tickCount={5}
|
||||||
tickLine={false}
|
tickLine={false}
|
||||||
axisLine={false}
|
axisLine={false}
|
||||||
tickFormatter={(v) => `${v}%`}
|
unit={'%'}
|
||||||
|
tickFormatter={(x) => (x % 1 === 0 ? x : x.toFixed(1))}
|
||||||
/>
|
/>
|
||||||
<XAxis
|
<XAxis
|
||||||
dataKey="time"
|
dataKey="time"
|
||||||
@@ -88,7 +92,7 @@ export default function ({
|
|||||||
// console.log('itemSorter', item)
|
// console.log('itemSorter', item)
|
||||||
// return -item.value
|
// return -item.value
|
||||||
// }}
|
// }}
|
||||||
content={<ChartTooltipContent indicator="line" />}
|
content={<ChartTooltipContent unit="%" indicator="line" />}
|
||||||
/>
|
/>
|
||||||
{Object.keys(chartConfig).map((key) => (
|
{Object.keys(chartConfig).map((key) => (
|
||||||
<Area
|
<Area
|
||||||
@@ -96,7 +100,7 @@ export default function ({
|
|||||||
// isAnimationActive={false}
|
// isAnimationActive={false}
|
||||||
animateNewValues={false}
|
animateNewValues={false}
|
||||||
dataKey={key}
|
dataKey={key}
|
||||||
type="natural"
|
type="bump"
|
||||||
fill={chartConfig[key].color}
|
fill={chartConfig[key].color}
|
||||||
fillOpacity={0.4}
|
fillOpacity={0.4}
|
||||||
stroke={chartConfig[key].color}
|
stroke={chartConfig[key].color}
|
||||||
|
@@ -63,6 +63,9 @@ export default function ({
|
|||||||
<AreaChart
|
<AreaChart
|
||||||
accessibilityLayer
|
accessibilityLayer
|
||||||
data={chartData}
|
data={chartData}
|
||||||
|
margin={{
|
||||||
|
top: 10,
|
||||||
|
}}
|
||||||
|
|
||||||
// reverseStackOrder={true}
|
// reverseStackOrder={true}
|
||||||
>
|
>
|
||||||
@@ -70,6 +73,7 @@ export default function ({
|
|||||||
<YAxis
|
<YAxis
|
||||||
domain={[0, max]}
|
domain={[0, max]}
|
||||||
tickCount={9}
|
tickCount={9}
|
||||||
|
allowDecimals={false}
|
||||||
tickLine={false}
|
tickLine={false}
|
||||||
axisLine={false}
|
axisLine={false}
|
||||||
tickFormatter={(v) => `${Math.ceil(v / 1024)} GiB`}
|
tickFormatter={(v) => `${Math.ceil(v / 1024)} GiB`}
|
||||||
@@ -89,7 +93,7 @@ export default function ({
|
|||||||
// console.log('itemSorter', item)
|
// console.log('itemSorter', item)
|
||||||
// return -item.value
|
// return -item.value
|
||||||
// }}
|
// }}
|
||||||
content={<ChartTooltipContent indicator="line" />}
|
content={<ChartTooltipContent unit=" MiB" indicator="line" />}
|
||||||
/>
|
/>
|
||||||
{Object.keys(chartConfig).map((key) => (
|
{Object.keys(chartConfig).map((key) => (
|
||||||
<Area
|
<Area
|
||||||
|
@@ -7,7 +7,6 @@ import {
|
|||||||
ChartTooltipContent,
|
ChartTooltipContent,
|
||||||
} from '@/components/ui/chart'
|
} from '@/components/ui/chart'
|
||||||
import { formatShortDate, formatShortTime } from '@/lib/utils'
|
import { formatShortDate, formatShortTime } from '@/lib/utils'
|
||||||
import { useEffect } from 'react'
|
|
||||||
import Spinner from '../spinner'
|
import Spinner from '../spinner'
|
||||||
// for (const data of chartData) {
|
// for (const data of chartData) {
|
||||||
// data.month = formatDateShort(data.month)
|
// data.month = formatDateShort(data.month)
|
||||||
@@ -33,14 +32,16 @@ export default function ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ChartContainer config={chartConfig} className="h-full w-full absolute aspect-auto">
|
<ChartContainer config={chartConfig} className="h-full w-full absolute aspect-auto">
|
||||||
<AreaChart accessibilityLayer data={chartData}>
|
<AreaChart accessibilityLayer data={chartData} margin={{ top: 10 }}>
|
||||||
<CartesianGrid vertical={false} />
|
<CartesianGrid vertical={false} />
|
||||||
<YAxis
|
<YAxis
|
||||||
domain={[0, max]}
|
domain={[0, max]}
|
||||||
tickCount={5}
|
width={47}
|
||||||
|
// tickCount={5}
|
||||||
tickLine={false}
|
tickLine={false}
|
||||||
axisLine={false}
|
axisLine={false}
|
||||||
tickFormatter={(v) => `${v}%`}
|
unit={'%'}
|
||||||
|
// tickFormatter={(v) => `${v}%`}
|
||||||
/>
|
/>
|
||||||
{/* todo: short time if first date is same day, otherwise short date */}
|
{/* todo: short time if first date is same day, otherwise short date */}
|
||||||
<XAxis
|
<XAxis
|
||||||
@@ -54,16 +55,12 @@ export default function ({
|
|||||||
<ChartTooltip
|
<ChartTooltip
|
||||||
cursor={false}
|
cursor={false}
|
||||||
content={
|
content={
|
||||||
<ChartTooltipContent
|
<ChartTooltipContent unit="%" labelFormatter={formatShortDate} indicator="line" />
|
||||||
labelFormatter={formatShortDate}
|
|
||||||
defaultValue={'%'}
|
|
||||||
indicator="line"
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Area
|
<Area
|
||||||
dataKey="cpu"
|
dataKey="cpu"
|
||||||
type="natural"
|
type="monotone"
|
||||||
fill="var(--color-cpu)"
|
fill="var(--color-cpu)"
|
||||||
fillOpacity={0.4}
|
fillOpacity={0.4}
|
||||||
stroke="var(--color-cpu)"
|
stroke="var(--color-cpu)"
|
||||||
|
@@ -50,17 +50,20 @@ export default function ({
|
|||||||
margin={{
|
margin={{
|
||||||
left: 0,
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
top: 0,
|
top: 10,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CartesianGrid vertical={false} />
|
<CartesianGrid vertical={false} />
|
||||||
<YAxis
|
<YAxis
|
||||||
|
width={75}
|
||||||
domain={[0, diskSize]}
|
domain={[0, diskSize]}
|
||||||
// ticks={ticks}
|
// ticks={ticks}
|
||||||
|
tickCount={9}
|
||||||
|
minTickGap={8}
|
||||||
tickLine={false}
|
tickLine={false}
|
||||||
axisLine={false}
|
axisLine={false}
|
||||||
tickFormatter={(v) => `${v} GiB`}
|
unit={' GiB'}
|
||||||
/>
|
/>
|
||||||
{/* todo: short time if first date is same day, otherwise short date */}
|
{/* todo: short time if first date is same day, otherwise short date */}
|
||||||
<XAxis
|
<XAxis
|
||||||
@@ -73,11 +76,13 @@ export default function ({
|
|||||||
/>
|
/>
|
||||||
<ChartTooltip
|
<ChartTooltip
|
||||||
cursor={false}
|
cursor={false}
|
||||||
content={<ChartTooltipContent labelFormatter={formatShortDate} indicator="line" />}
|
content={
|
||||||
|
<ChartTooltipContent unit=" GiB" labelFormatter={formatShortDate} indicator="line" />
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<Area
|
<Area
|
||||||
dataKey="diskUsed"
|
dataKey="diskUsed"
|
||||||
type="natural"
|
type="bump"
|
||||||
fill="var(--color-diskUsed)"
|
fill="var(--color-diskUsed)"
|
||||||
fillOpacity={0.4}
|
fillOpacity={0.4}
|
||||||
stroke="var(--color-diskUsed)"
|
stroke="var(--color-diskUsed)"
|
||||||
|
@@ -36,10 +36,7 @@ export default function ({
|
|||||||
accessibilityLayer
|
accessibilityLayer
|
||||||
data={chartData}
|
data={chartData}
|
||||||
margin={{
|
margin={{
|
||||||
left: 0,
|
top: 10,
|
||||||
right: 0,
|
|
||||||
top: 0,
|
|
||||||
bottom: 0,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CartesianGrid vertical={false} />
|
<CartesianGrid vertical={false} />
|
||||||
@@ -48,6 +45,7 @@ export default function ({
|
|||||||
domain={[0, totalMem]}
|
domain={[0, totalMem]}
|
||||||
tickCount={9}
|
tickCount={9}
|
||||||
tickLine={false}
|
tickLine={false}
|
||||||
|
allowDecimals={false}
|
||||||
axisLine={false}
|
axisLine={false}
|
||||||
tickFormatter={(v) => `${v} GiB`}
|
tickFormatter={(v) => `${v} GiB`}
|
||||||
/>
|
/>
|
||||||
@@ -62,11 +60,13 @@ export default function ({
|
|||||||
/>
|
/>
|
||||||
<ChartTooltip
|
<ChartTooltip
|
||||||
cursor={false}
|
cursor={false}
|
||||||
content={<ChartTooltipContent labelFormatter={formatShortDate} indicator="line" />}
|
content={
|
||||||
|
<ChartTooltipContent unit=" GiB" labelFormatter={formatShortDate} indicator="line" />
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<Area
|
<Area
|
||||||
dataKey="memUsed"
|
dataKey="memUsed"
|
||||||
type="natural"
|
type="bump"
|
||||||
fill="var(--color-memUsed)"
|
fill="var(--color-memUsed)"
|
||||||
fillOpacity={0.4}
|
fillOpacity={0.4}
|
||||||
stroke="var(--color-memUsed)"
|
stroke="var(--color-memUsed)"
|
||||||
|
@@ -85,10 +85,10 @@ export default function ServerDetail({ name }: { name: string }) {
|
|||||||
const memData = [] as { time: string; mem: number; memUsed: number }[]
|
const memData = [] as { time: string; mem: number; memUsed: number }[]
|
||||||
const diskData = [] as { time: string; disk: number; diskUsed: number }[]
|
const diskData = [] as { time: string; disk: number; diskUsed: number }[]
|
||||||
for (let { created, stats } of serverStats) {
|
for (let { created, stats } of serverStats) {
|
||||||
cpuData.push({ time: created, cpu: stats.cpu })
|
cpuData.push({ time: created, cpu: stats.c })
|
||||||
maxCpu = Math.max(maxCpu, stats.cpu)
|
maxCpu = Math.max(maxCpu, stats.c)
|
||||||
memData.push({ time: created, mem: stats.mem, memUsed: stats.memUsed })
|
memData.push({ time: created, mem: stats.m, memUsed: stats.mu })
|
||||||
diskData.push({ time: created, disk: stats.disk, diskUsed: stats.diskUsed })
|
diskData.push({ time: created, disk: stats.d, diskUsed: stats.du })
|
||||||
}
|
}
|
||||||
setCpuChartData({
|
setCpuChartData({
|
||||||
max: Math.ceil(maxCpu),
|
max: Math.ceil(maxCpu),
|
||||||
@@ -137,8 +137,8 @@ export default function ServerDetail({ name }: { name: string }) {
|
|||||||
let cpuData = { time: created } as Record<string, number | string>
|
let cpuData = { time: created } as Record<string, number | string>
|
||||||
let memData = { time: created } as Record<string, number | string>
|
let memData = { time: created } as Record<string, number | string>
|
||||||
for (let container of stats) {
|
for (let container of stats) {
|
||||||
cpuData[container.name] = container.cpu
|
cpuData[container.n] = container.c
|
||||||
memData[container.name] = container.mem
|
memData[container.n] = container.m
|
||||||
}
|
}
|
||||||
containerCpuData.push(cpuData)
|
containerCpuData.push(cpuData)
|
||||||
containerMemData.push(memData)
|
containerMemData.push(memData)
|
||||||
@@ -157,7 +157,7 @@ export default function ServerDetail({ name }: { name: string }) {
|
|||||||
<CpuIcon className="opacity-70" />
|
<CpuIcon className="opacity-70" />
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
<CardDescription>
|
<CardDescription>
|
||||||
Average usage of the one minute preceding the recorded time
|
System-wide CPU utilization of the preceding one minute as a percentage
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className={'pl-1 w-[calc(100%-2em)] h-52 relative'}>
|
<CardContent className={'pl-1 w-[calc(100%-2em)] h-52 relative'}>
|
||||||
@@ -166,20 +166,22 @@ export default function ServerDetail({ name }: { name: string }) {
|
|||||||
</Suspense>
|
</Suspense>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
<Card className="pb-2">
|
{containerCpuChartData.length > 0 && (
|
||||||
<CardHeader>
|
<Card className="pb-2">
|
||||||
<CardTitle className="flex gap-2 justify-between">
|
<CardHeader>
|
||||||
<span>Docker CPU Usage</span>
|
<CardTitle className="flex gap-2 justify-between">
|
||||||
<CpuIcon className="opacity-70" />
|
<span>Docker CPU Usage</span>
|
||||||
</CardTitle>{' '}
|
<CpuIcon className="opacity-70" />
|
||||||
<CardDescription>CPU usage of docker containers</CardDescription>
|
</CardTitle>{' '}
|
||||||
</CardHeader>
|
<CardDescription>CPU utilization of docker containers</CardDescription>
|
||||||
<CardContent className={'pl-1 w-[calc(100%-2em)] h-52 relative'}>
|
</CardHeader>
|
||||||
<Suspense fallback={<Spinner />}>
|
<CardContent className={'pl-1 w-[calc(100%-2em)] h-52 relative'}>
|
||||||
<ContainerCpuChart chartData={containerCpuChartData} max={cpuChartData.max} />
|
<Suspense fallback={<Spinner />}>
|
||||||
</Suspense>
|
<ContainerCpuChart chartData={containerCpuChartData} max={cpuChartData.max} />
|
||||||
</CardContent>
|
</Suspense>
|
||||||
</Card>
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
<Card className="pb-2">
|
<Card className="pb-2">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>Memory Usage</CardTitle>
|
<CardTitle>Memory Usage</CardTitle>
|
||||||
@@ -191,25 +193,27 @@ export default function ServerDetail({ name }: { name: string }) {
|
|||||||
</Suspense>
|
</Suspense>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
<Card className="pb-2">
|
{containerMemChartData.length > 0 && (
|
||||||
<CardHeader>
|
<Card className="pb-2">
|
||||||
<CardTitle className="flex gap-2 justify-between">
|
<CardHeader>
|
||||||
<span>Docker Memory Usage</span>
|
<CardTitle className="flex gap-2 justify-between">
|
||||||
<MemoryStickIcon className="opacity-70" />
|
<span>Docker Memory Usage</span>
|
||||||
</CardTitle>{' '}
|
<MemoryStickIcon className="opacity-70" />
|
||||||
<CardDescription>Memory usage of docker containers</CardDescription>
|
</CardTitle>{' '}
|
||||||
</CardHeader>
|
<CardDescription>Memory usage of docker containers</CardDescription>
|
||||||
<CardContent className={'pl-1 w-[calc(100%-2em)] h-52 relative'}>
|
</CardHeader>
|
||||||
<Suspense fallback={<Spinner />}>
|
<CardContent className={'pl-1 w-[calc(100%-2em)] h-52 relative'}>
|
||||||
{server?.stats?.mem && (
|
<Suspense fallback={<Spinner />}>
|
||||||
<ContainerMemChart
|
{server?.stats?.m && (
|
||||||
chartData={containerMemChartData}
|
<ContainerMemChart
|
||||||
max={server.stats.mem * 1024}
|
chartData={containerMemChartData}
|
||||||
/>
|
max={server.stats.m * 1024}
|
||||||
)}
|
/>
|
||||||
</Suspense>
|
)}
|
||||||
</CardContent>
|
</Suspense>
|
||||||
</Card>
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
<Card className="pb-2">
|
<Card className="pb-2">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>Disk Usage</CardTitle>
|
<CardTitle>Disk Usage</CardTitle>
|
||||||
|
@@ -52,6 +52,8 @@ import {
|
|||||||
Cpu,
|
Cpu,
|
||||||
MemoryStick,
|
MemoryStick,
|
||||||
HardDrive,
|
HardDrive,
|
||||||
|
PauseIcon,
|
||||||
|
CopyIcon,
|
||||||
} from 'lucide-react'
|
} from 'lucide-react'
|
||||||
import { useMemo, useState } from 'react'
|
import { useMemo, useState } from 'react'
|
||||||
import { $servers, pb, navigate } from '@/lib/stores'
|
import { $servers, pb, navigate } from '@/lib/stores'
|
||||||
@@ -109,7 +111,7 @@ export default function () {
|
|||||||
<span className="flex gap-0.5 items-center text-base">
|
<span className="flex gap-0.5 items-center text-base">
|
||||||
<span
|
<span
|
||||||
className={cn(
|
className={cn(
|
||||||
'w-2.5 h-2.5 left-0 rounded-full',
|
'w-2 h-2 left-0 rounded-full',
|
||||||
info.row.original.active ? 'bg-green-500' : 'bg-red-500'
|
info.row.original.active ? 'bg-green-500' : 'bg-red-500'
|
||||||
)}
|
)}
|
||||||
style={{ marginBottom: '-1px' }}
|
style={{ marginBottom: '-1px' }}
|
||||||
@@ -120,24 +122,24 @@ export default function () {
|
|||||||
onClick={() => copyToClipboard(info.getValue() as string)}
|
onClick={() => copyToClipboard(info.getValue() as string)}
|
||||||
>
|
>
|
||||||
{info.getValue() as string}
|
{info.getValue() as string}
|
||||||
<Copy className="h-3.5 w-3.5 opacity-70" />
|
<CopyIcon className="h-3 w-3" />
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
header: ({ column }) => sortableHeader(column, 'Server', Server),
|
header: ({ column }) => sortableHeader(column, 'Server', Server),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'stats.cpu',
|
accessorKey: 'stats.c',
|
||||||
cell: CellFormatter,
|
cell: CellFormatter,
|
||||||
header: ({ column }) => sortableHeader(column, 'CPU', Cpu),
|
header: ({ column }) => sortableHeader(column, 'CPU', Cpu),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'stats.memPct',
|
accessorKey: 'stats.mp',
|
||||||
cell: CellFormatter,
|
cell: CellFormatter,
|
||||||
header: ({ column }) => sortableHeader(column, 'Memory', MemoryStick),
|
header: ({ column }) => sortableHeader(column, 'Memory', MemoryStick),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'stats.diskPct',
|
accessorKey: 'stats.dp',
|
||||||
cell: CellFormatter,
|
cell: CellFormatter,
|
||||||
header: ({ column }) => sortableHeader(column, 'Disk', HardDrive),
|
header: ({ column }) => sortableHeader(column, 'Disk', HardDrive),
|
||||||
},
|
},
|
||||||
@@ -169,8 +171,8 @@ export default function () {
|
|||||||
<DropdownMenuItem onClick={() => console.log('pause server')}>
|
<DropdownMenuItem onClick={() => console.log('pause server')}>
|
||||||
Pause
|
Pause
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuItem onClick={() => navigator.clipboard.writeText(system.ip)}>
|
<DropdownMenuItem onClick={() => copyToClipboard(system.ip)}>
|
||||||
Copy IP address
|
Copy host
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
|
@@ -58,21 +58,30 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.recharts-tooltip-wrapper {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* charts */
|
/* charts */
|
||||||
@layer base {
|
@layer base {
|
||||||
:root {
|
:root {
|
||||||
--chart-1: 12 76% 61%;
|
/* --chart-1: 12 76% 61%;
|
||||||
--chart-2: 173 58% 39%;
|
--chart-2: 173 58% 39%;
|
||||||
--chart-3: 197 37% 24%;
|
--chart-3: 197 37% 24%;
|
||||||
--chart-4: 43 74% 66%;
|
--chart-4: 43 74% 66%;
|
||||||
--chart-5: 27 87% 67%;
|
--chart-5: 27 87% 67%; */
|
||||||
}
|
|
||||||
|
|
||||||
.dark {
|
|
||||||
--chart-1: 220 70% 50%;
|
--chart-1: 220 70% 50%;
|
||||||
--chart-2: 160 60% 45%;
|
--chart-2: 160 60% 45%;
|
||||||
--chart-3: 30 80% 55%;
|
--chart-3: 30 80% 55%;
|
||||||
--chart-4: 280 65% 60%;
|
--chart-4: 280 65% 60%;
|
||||||
--chart-5: 340 75% 55%;
|
--chart-5: 340 75% 55%;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
.dark {
|
||||||
|
--chart-1: 220 70% 50%;
|
||||||
|
--chart-2: 160 60% 45%;
|
||||||
|
--chart-3: 30 80% 55%;
|
||||||
|
--chart-4: 280 65% 60%;
|
||||||
|
--chart-5: 340 75% 55%;
|
||||||
|
} */
|
||||||
}
|
}
|
||||||
|
@@ -52,26 +52,18 @@ const Layout = () => {
|
|||||||
<>
|
<>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="flex items-center h-16 bg-card px-6 border bt-0 rounded-md my-5">
|
<div className="flex items-center h-16 bg-card px-6 border bt-0 rounded-md my-5">
|
||||||
<TooltipProvider delayDuration={300}>
|
<a
|
||||||
<Tooltip>
|
href="/"
|
||||||
<TooltipTrigger asChild>
|
aria-label="Home"
|
||||||
<a
|
className={'p-2 pl-0 -mb-1'}
|
||||||
href="/"
|
onClick={(e) => {
|
||||||
aria-label="Home"
|
e.preventDefault()
|
||||||
className={'p-2 pl-0 -mb-1'}
|
navigate('/')
|
||||||
onClick={(e) => {
|
}}
|
||||||
e.preventDefault()
|
>
|
||||||
navigate('/')
|
<Logo className="h-[1.1em] fill-foreground" />
|
||||||
}}
|
</a>
|
||||||
>
|
|
||||||
<Logo className="h-[1.1em] fill-foreground" />
|
|
||||||
</a>
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent>
|
|
||||||
<p>Home</p>
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
<div className={'flex gap-1 ml-auto'}>
|
<div className={'flex gap-1 ml-auto'}>
|
||||||
<TooltipProvider delayDuration={300}>
|
<TooltipProvider delayDuration={300}>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
|
31
site/src/types.d.ts
vendored
31
site/src/types.d.ts
vendored
@@ -9,13 +9,20 @@ export interface SystemRecord extends RecordModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface SystemStats {
|
export interface SystemStats {
|
||||||
cpu: number
|
/** cpu percent */
|
||||||
disk: number
|
c: number
|
||||||
diskPct: number
|
/** disk size (gb) */
|
||||||
diskUsed: number
|
d: number
|
||||||
mem: number
|
/** disk percent */
|
||||||
memPct: number
|
dp: number
|
||||||
memUsed: number
|
/** disk used (gb) */
|
||||||
|
du: number
|
||||||
|
/** total memory (gb) */
|
||||||
|
m: number
|
||||||
|
/** memory percent */
|
||||||
|
mp: number
|
||||||
|
/** memory used (gb) */
|
||||||
|
mu: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ContainerStatsRecord extends RecordModel {
|
export interface ContainerStatsRecord extends RecordModel {
|
||||||
@@ -24,10 +31,12 @@ export interface ContainerStatsRecord extends RecordModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ContainerStats {
|
interface ContainerStats {
|
||||||
name: string
|
/** name */
|
||||||
cpu: number
|
n: string
|
||||||
mem: number
|
/** cpu percent */
|
||||||
memPct: number
|
c: number
|
||||||
|
/** memory used (gb) */
|
||||||
|
m: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SystemStatsRecord extends RecordModel {
|
export interface SystemStatsRecord extends RecordModel {
|
||||||
|
23
types.go
23
types.go
@@ -16,18 +16,19 @@ type SystemData struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SystemStats struct {
|
type SystemStats struct {
|
||||||
Cpu float64 `json:"cpu"`
|
Cpu float64 `json:"c"`
|
||||||
Mem float64 `json:"mem"`
|
Mem float64 `json:"m"`
|
||||||
MemUsed float64 `json:"memUsed"`
|
MemUsed float64 `json:"mu"`
|
||||||
MemPct float64 `json:"memPct"`
|
MemPct float64 `json:"mp"`
|
||||||
Disk float64 `json:"disk"`
|
MemBuf float64 `json:"mb"`
|
||||||
DiskUsed float64 `json:"diskUsed"`
|
Disk float64 `json:"d"`
|
||||||
DiskPct float64 `json:"diskPct"`
|
DiskUsed float64 `json:"du"`
|
||||||
|
DiskPct float64 `json:"dp"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ContainerStats struct {
|
type ContainerStats struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"n"`
|
||||||
Cpu float64 `json:"cpu"`
|
Cpu float64 `json:"c"`
|
||||||
Mem float64 `json:"mem"`
|
Mem float64 `json:"m"`
|
||||||
MemPct float64 `json:"memPct"`
|
// MemPct float64 `json:"mp"`
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user