mirror of
https://github.com/fankes/beszel.git
synced 2025-10-19 09:49:28 +08:00
use grid layout for charts
This commit is contained in:
@@ -74,6 +74,7 @@ export default function ContainerCpuChart({
|
|||||||
>
|
>
|
||||||
<AreaChart
|
<AreaChart
|
||||||
accessibilityLayer
|
accessibilityLayer
|
||||||
|
// syncId={'cpu'}
|
||||||
data={chartData}
|
data={chartData}
|
||||||
margin={{
|
margin={{
|
||||||
top: 10,
|
top: 10,
|
||||||
|
@@ -29,7 +29,12 @@ export default function CpuChart({
|
|||||||
'opacity-100': yAxisSet,
|
'opacity-100': yAxisSet,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<AreaChart accessibilityLayer data={systemData} margin={{ top: 10 }}>
|
<AreaChart
|
||||||
|
accessibilityLayer
|
||||||
|
data={systemData}
|
||||||
|
margin={{ top: 10 }}
|
||||||
|
// syncId={'cpu'}
|
||||||
|
>
|
||||||
<CartesianGrid vertical={false} />
|
<CartesianGrid vertical={false} />
|
||||||
<YAxis
|
<YAxis
|
||||||
className="tracking-tighter"
|
className="tracking-tighter"
|
||||||
|
@@ -116,7 +116,6 @@ export default function TemperatureChart({
|
|||||||
type="monotoneX"
|
type="monotoneX"
|
||||||
dot={false}
|
dot={false}
|
||||||
strokeWidth={1.5}
|
strokeWidth={1.5}
|
||||||
fill="hsl(360, 60%, 55%)"
|
|
||||||
stroke={newChartData.colors[key]}
|
stroke={newChartData.colors[key]}
|
||||||
isAnimationActive={false}
|
isAnimationActive={false}
|
||||||
/>
|
/>
|
||||||
|
@@ -15,7 +15,7 @@ export function ModeToggle() {
|
|||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button className="max-sm:w-9" variant={'ghost'} size="icon">
|
<Button variant={'ghost'} size="icon">
|
||||||
<Sun className="h-[1.2rem] w-[1.2rem] dark:opacity-0" />
|
<Sun className="h-[1.2rem] w-[1.2rem] dark:opacity-0" />
|
||||||
<MoonStarIcon className="absolute h-[1.2rem] w-[1.2rem] opacity-0 dark:opacity-100" />
|
<MoonStarIcon className="absolute h-[1.2rem] w-[1.2rem] opacity-0 dark:opacity-100" />
|
||||||
<span className="sr-only">Toggle theme</span>
|
<span className="sr-only">Toggle theme</span>
|
||||||
|
@@ -191,58 +191,60 @@ export default function SystemDetail({ name }: { name: string }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid gap-4 mb-10">
|
<div className="grid lg:grid-cols-2 gap-4 mb-10">
|
||||||
<Card>
|
<Card className="col-span-full">
|
||||||
<div className="grid gap-2 px-4 sm:px-6 pt-3 sm:pt-4 pb-5">
|
<div className="grid lg:flex items-center gap-4 px-4 sm:px-6 pt-3 sm:pt-4 pb-5">
|
||||||
<h1 className="text-[1.6rem] font-semibold">{system.name}</h1>
|
<div>
|
||||||
<div className="flex flex-wrap items-center gap-3 gap-y-2 text-sm opacity-90">
|
<h1 className="text-[1.6rem] font-semibold mb-1.5">{system.name}</h1>
|
||||||
<div className="capitalize flex gap-2 items-center">
|
<div className="flex flex-wrap items-center gap-3 gap-y-2 text-sm opacity-90">
|
||||||
<span className={cn('relative flex h-3 w-3')}>
|
<div className="capitalize flex gap-2 items-center">
|
||||||
{system.status === 'up' && (
|
<span className={cn('relative flex h-3 w-3')}>
|
||||||
|
{system.status === 'up' && (
|
||||||
|
<span
|
||||||
|
className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"
|
||||||
|
style={{ animationDuration: '1.5s' }}
|
||||||
|
></span>
|
||||||
|
)}
|
||||||
<span
|
<span
|
||||||
className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"
|
className={cn('relative inline-flex rounded-full h-3 w-3', {
|
||||||
style={{ animationDuration: '1.5s' }}
|
'bg-green-500': system.status === 'up',
|
||||||
|
'bg-red-500': system.status === 'down',
|
||||||
|
'bg-primary/40': system.status === 'paused',
|
||||||
|
'bg-yellow-500': system.status === 'pending',
|
||||||
|
})}
|
||||||
></span>
|
></span>
|
||||||
)}
|
</span>
|
||||||
<span
|
{system.status}
|
||||||
className={cn('relative inline-flex rounded-full h-3 w-3', {
|
</div>
|
||||||
'bg-green-500': system.status === 'up',
|
<Separator orientation="vertical" className="h-4 bg-primary/30" />
|
||||||
'bg-red-500': system.status === 'down',
|
<div className="flex gap-1.5">
|
||||||
'bg-primary/40': system.status === 'paused',
|
<GlobeIcon className="h-4 w-4 mt-[1px]" /> {system.host}
|
||||||
'bg-yellow-500': system.status === 'pending',
|
</div>
|
||||||
})}
|
{system.info?.u && (
|
||||||
></span>
|
<TooltipProvider>
|
||||||
</span>
|
<Tooltip>
|
||||||
{system.status}
|
<Separator orientation="vertical" className="h-4 bg-primary/30" />
|
||||||
</div>
|
<TooltipTrigger asChild>
|
||||||
<Separator orientation="vertical" className="h-4 bg-primary/30" />
|
<div className="flex gap-1.5">
|
||||||
<div className="flex gap-1.5">
|
<ClockArrowUp className="h-4 w-4 mt-[1px]" /> {uptime}
|
||||||
<GlobeIcon className="h-4 w-4 mt-[1px]" /> {system.host}
|
</div>
|
||||||
</div>
|
</TooltipTrigger>
|
||||||
{system.info?.u && (
|
<TooltipContent>Uptime</TooltipContent>
|
||||||
<TooltipProvider>
|
</Tooltip>
|
||||||
<Tooltip>
|
</TooltipProvider>
|
||||||
|
)}
|
||||||
|
{system.info?.m && (
|
||||||
|
<>
|
||||||
<Separator orientation="vertical" className="h-4 bg-primary/30" />
|
<Separator orientation="vertical" className="h-4 bg-primary/30" />
|
||||||
<TooltipTrigger asChild>
|
<div className="flex gap-1.5">
|
||||||
<div className="flex gap-1.5">
|
<CpuIcon className="h-4 w-4 mt-[1px]" />
|
||||||
<ClockArrowUp className="h-4 w-4 mt-[1px]" /> {uptime}
|
{system.info.m} ({system.info.c}c / {system.info.t}t)
|
||||||
</div>
|
</div>
|
||||||
</TooltipTrigger>
|
</>
|
||||||
<TooltipContent>Uptime</TooltipContent>
|
)}
|
||||||
</Tooltip>
|
</div>
|
||||||
</TooltipProvider>
|
|
||||||
)}
|
|
||||||
{system.info?.m && (
|
|
||||||
<>
|
|
||||||
<Separator orientation="vertical" className="h-4 bg-primary/30" />
|
|
||||||
<div className="flex gap-1.5">
|
|
||||||
<CpuIcon className="h-4 w-4 mt-[1px]" />
|
|
||||||
{system.info.m} ({system.info.c}c / {system.info.t}t)
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<ChartTimeSelect className="mt-2 -ml-1 sm:hidden" />
|
<ChartTimeSelect className="w-full lg:w-40 xl:w-52 ml-auto max-sm:-mb-1" />
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
@@ -273,15 +275,12 @@ export default function SystemDetail({ name }: { name: string }) {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{systemStats.at(-1)?.stats.t && (
|
{systemStats.at(-1)?.stats.t && (
|
||||||
<ChartCard title="Temperature" description="Temperature of system components">
|
<ChartCard title="Temperature" description="Temperatures of system sensors">
|
||||||
<TemperatureChart ticks={ticks} systemData={systemStats} />
|
<TemperatureChart ticks={ticks} systemData={systemStats} />
|
||||||
</ChartCard>
|
</ChartCard>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<ChartCard
|
<ChartCard title="Disk Usage" description="Space usage of root partition">
|
||||||
title="Disk Usage"
|
|
||||||
description="Usage of partition where the root filesystem is mounted"
|
|
||||||
>
|
|
||||||
<DiskChart ticks={ticks} systemData={systemStats} />
|
<DiskChart ticks={ticks} systemData={systemStats} />
|
||||||
</ChartCard>
|
</ChartCard>
|
||||||
|
|
||||||
@@ -303,7 +302,8 @@ export default function SystemDetail({ name }: { name: string }) {
|
|||||||
</ChartCard>
|
</ChartCard>
|
||||||
{/* add space for tooltip if more than 12 containers */}
|
{/* add space for tooltip if more than 12 containers */}
|
||||||
{Object.keys(dockerNetChartData[0]).length > 12 && (
|
{Object.keys(dockerNetChartData[0]).length > 12 && (
|
||||||
<div
|
<span
|
||||||
|
className="block"
|
||||||
style={{
|
style={{
|
||||||
height: (Object.keys(dockerNetChartData[0]).length - 13) * 18,
|
height: (Object.keys(dockerNetChartData[0]).length - 13) * 18,
|
||||||
}}
|
}}
|
||||||
@@ -327,15 +327,15 @@ function ChartCard({
|
|||||||
const target = useRef<HTMLDivElement>(null)
|
const target = useRef<HTMLDivElement>(null)
|
||||||
const [isInViewport, wrappedTargetRef] = useClampedIsInViewport({ target: target })
|
const [isInViewport, wrappedTargetRef] = useClampedIsInViewport({ target: target })
|
||||||
return (
|
return (
|
||||||
<Card className="pb-2 sm:pb-4 col-span-full" ref={wrappedTargetRef}>
|
<Card className="pb-2 sm:pb-4 even:last-of-type:col-span-full" ref={wrappedTargetRef}>
|
||||||
<CardHeader className="pb-5 pt-4 relative space-y-1 max-sm:py-3 max-sm:px-4">
|
<CardHeader className="pb-5 pt-4 relative space-y-1 max-sm:py-3 max-sm:px-4">
|
||||||
<CardTitle className="text-xl sm:text-2xl">{title}</CardTitle>
|
<CardTitle className="text-xl sm:text-2xl">{title}</CardTitle>
|
||||||
<CardDescription>{description}</CardDescription>
|
<CardDescription>{description}</CardDescription>
|
||||||
<div className="w-full pt-1 sm:w-40 hidden sm:block absolute top-1.5 right-3.5">
|
{/* <div className="w-full pt-1 sm:w-40 hidden sm:block absolute top-1.5 right-3.5">
|
||||||
<ChartTimeSelect />
|
<ChartTimeSelect />
|
||||||
</div>
|
</div> */}
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="pl-1 w-[calc(100%-1.6em)] h-52 relative">
|
<CardContent className="pl-0 w-[calc(100%-1.6em)] h-52 relative">
|
||||||
{<Spinner />}
|
{<Spinner />}
|
||||||
{isInViewport && <Suspense>{children}</Suspense>}
|
{isInViewport && <Suspense>{children}</Suspense>}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
@@ -208,7 +208,7 @@ export function useYaxisWidth(chartRef: React.RefObject<HTMLDivElement>) {
|
|||||||
if (yAxisElement) {
|
if (yAxisElement) {
|
||||||
// console.log('yAxisElement', yAxisElement)
|
// console.log('yAxisElement', yAxisElement)
|
||||||
clearInterval(interval)
|
clearInterval(interval)
|
||||||
setYAxisWidth(yAxisElement.getBoundingClientRect().width + 22)
|
setYAxisWidth(yAxisElement.getBoundingClientRect().width + 24)
|
||||||
}
|
}
|
||||||
}, 16)
|
}, 16)
|
||||||
return () => clearInterval(interval)
|
return () => clearInterval(interval)
|
||||||
|
@@ -120,7 +120,7 @@ const Layout = () => {
|
|||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<button
|
<button
|
||||||
aria-label="User Actions"
|
aria-label="User Actions"
|
||||||
className={cn('max-sm:w-9', buttonVariants({ variant: 'ghost', size: 'icon' }))}
|
className={cn('', buttonVariants({ variant: 'ghost', size: 'icon' }))}
|
||||||
>
|
>
|
||||||
<UserIcon className="h-[1.2rem] w-[1.2rem]" />
|
<UserIcon className="h-[1.2rem] w-[1.2rem]" />
|
||||||
</button>
|
</button>
|
||||||
|
Reference in New Issue
Block a user