forked from getarcaneapp/arcane
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathContainerLogStatMonitor.svelte
More file actions
81 lines (75 loc) · 2.93 KB
/
ContainerLogStatMonitor.svelte
File metadata and controls
81 lines (75 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<script lang="ts">
import * as ArcaneTooltip from '$lib/components/arcane-tooltip';
import type { IconType } from '$lib/icons';
import { Skeleton } from '$lib/components/ui/skeleton';
import { cn } from '$lib/utils';
interface Props {
icon: IconType;
label: string;
value: string;
detail: string;
history: Array<{ percent: number; tooltip: string }>;
tone?: 'cpu' | 'memory';
loading?: boolean;
disabled?: boolean;
testId?: string;
}
let { icon, label, value, detail, history, tone = 'cpu', loading = false, disabled = false, testId }: Props = $props();
const barColorClass = $derived(
tone === 'cpu' ? 'bg-sky-500/75 dark:bg-sky-400/75' : 'bg-emerald-500/75 dark:bg-emerald-400/75'
);
const iconColorClass = $derived(tone === 'cpu' ? 'text-sky-600 dark:text-sky-300' : 'text-emerald-600 dark:text-emerald-300');
const Icon = $derived(icon);
</script>
<section
class={cn(
'bg-card/35 border-border/70 grid min-w-0 gap-2 rounded-lg border px-3 py-2.5',
disabled && 'bg-muted/25 text-muted-foreground'
)}
data-testid={testId}
>
<div class="grid grid-cols-[minmax(0,1fr)_auto] items-start gap-x-3">
<div class="flex min-w-0 items-center gap-2">
<div class="bg-background/70 border-border/60 flex size-7 shrink-0 items-center justify-center rounded-md border">
<Icon class={cn('size-4', disabled ? 'text-muted-foreground' : iconColorClass)} />
</div>
<div class="min-w-0">
<div class="text-muted-foreground text-[11px] font-medium tracking-normal">{label}</div>
{#if loading}
<Skeleton class="mt-1 h-5 w-20" />
{:else}
<div class={cn('truncate text-sm font-semibold tabular-nums', disabled ? 'text-muted-foreground' : 'text-foreground')}>
{value}
</div>
{/if}
</div>
</div>
{#if loading}
<Skeleton class="mt-0.5 h-4 w-16 justify-self-end" />
{:else}
<div class="text-muted-foreground shrink-0 justify-self-end pl-2 text-right text-[11px] tabular-nums">{detail}</div>
{/if}
</div>
{#if loading}
<Skeleton class="h-8 w-full" />
{:else}
<div class="bg-background/60 border-border/60 flex h-8 items-end gap-[3px] overflow-hidden rounded-md border px-1.5 py-1">
{#each history as sample, index (`${tone}-${index}`)}
<ArcaneTooltip.Root>
<ArcaneTooltip.Trigger class="flex h-full min-w-0 flex-1 items-end self-stretch">
<div
class={cn('min-w-0 flex-1 rounded-[2px] transition-opacity', disabled ? 'bg-muted' : barColorClass)}
style={`height: ${Math.max(disabled ? 12 : Math.min(Math.max(sample.percent, 6), 100), 6)}%; opacity: ${disabled ? 0.35 : 0.45 + Math.min(sample.percent, 100) / 180};`}
></div>
</ArcaneTooltip.Trigger>
<ArcaneTooltip.Content side="top">
<div class="space-y-1">
<div class="text-xs font-medium">{label}</div>
<div class="text-muted-foreground text-xs tabular-nums">{sample.tooltip}</div>
</div>
</ArcaneTooltip.Content>
</ArcaneTooltip.Root>
{/each}
</div>
{/if}
</section>