feat(service-integrations): phase 2 — integration widget & app form UI
- Add 6 renderer components: StatCard, Gauge, List, Progress, AlertBanner, Chart - Add IntegrationWidget container with auto-refresh, loading, error states - Add IntegrationAlertOverlay for layout-level critical alerts - Add IntegrationConfigFields for dynamic form generation from Zod schemas - Register integration type in WidgetRenderer - Extend WidgetCreationForm with integration app/endpoint pickers - Extend AppForm with integration config section and test connection button - Add /api/integrations/alerts endpoint
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
<script lang="ts">
|
||||
import type { GaugeData } from '$lib/server/integrations/types.js';
|
||||
|
||||
interface Props {
|
||||
data: GaugeData;
|
||||
}
|
||||
|
||||
let { data }: Props = $props();
|
||||
|
||||
const percentage = $derived(data.max > 0 ? Math.min((data.value / data.max) * 100, 100) : 0);
|
||||
|
||||
const color = $derived.by(() => {
|
||||
const warn = data.thresholds?.warning ?? 60;
|
||||
const crit = data.thresholds?.critical ?? 85;
|
||||
if (percentage >= crit) return '#ef4444'; // red
|
||||
if (percentage >= warn) return '#eab308'; // yellow
|
||||
return '#22c55e'; // green
|
||||
});
|
||||
|
||||
// SVG circle math
|
||||
const radius = 40;
|
||||
const circumference = 2 * Math.PI * radius;
|
||||
const strokeDashoffset = $derived(circumference - (percentage / 100) * circumference);
|
||||
</script>
|
||||
|
||||
<div class="flex flex-col items-center justify-center gap-2 p-3">
|
||||
<div class="relative h-24 w-24">
|
||||
<svg viewBox="0 0 100 100" class="h-full w-full -rotate-90">
|
||||
<circle cx="50" cy="50" r={radius} fill="none" stroke="currentColor" stroke-width="8" class="text-muted/20" />
|
||||
<circle
|
||||
cx="50" cy="50" r={radius} fill="none"
|
||||
stroke={color} stroke-width="8"
|
||||
stroke-linecap="round"
|
||||
stroke-dasharray={circumference}
|
||||
stroke-dashoffset={strokeDashoffset}
|
||||
class="transition-all duration-700 ease-out"
|
||||
/>
|
||||
</svg>
|
||||
<div class="absolute inset-0 flex flex-col items-center justify-center">
|
||||
<span class="text-lg font-bold text-foreground">{Math.round(percentage)}%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
<span class="text-sm font-medium text-muted-foreground">{data.label}</span>
|
||||
<span class="block text-xs text-muted-foreground/70">{data.value}{data.unit} / {data.max}{data.unit}</span>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user