- Replaced @TIER: TRIVIAL with @COMPLEXITY: 1 - Replaced @TIER: STANDARD with @COMPLEXITY: 3 - Replaced @TIER: CRITICAL with @COMPLEXITY: 5 - Manually elevated specific critical/complex components to levels 2 and 4 - Ignored legacy, specs, and node_modules directories - Updated generated semantic map
82 lines
3.4 KiB
Svelte
82 lines
3.4 KiB
Svelte
<!-- [DEF:HealthMatrix:Component] -->
|
|
<!--
|
|
@COMPLEXITY: 3
|
|
@PURPOSE: Visual grid/matrix representing the health status of dashboards.
|
|
@LAYER: UI/Component
|
|
@UX_STATE: Idle -> Displays the health matrix grid.
|
|
@UX_STATE: Loading -> Displays a skeleton or spinner.
|
|
@UX_STATE: Error -> Displays an error message with a retry option.
|
|
@UX_REATIVITY: State: $state, Derived: $derived.
|
|
-->
|
|
<script>
|
|
import { t } from '$lib/i18n';
|
|
|
|
/** @type {{
|
|
* pass_count: number,
|
|
* warn_count: number,
|
|
* fail_count: number,
|
|
* unknown_count: number,
|
|
* loading: boolean,
|
|
* error: string | null
|
|
* }} */
|
|
let {
|
|
pass_count = 0,
|
|
warn_count = 0,
|
|
fail_count = 0,
|
|
unknown_count = 0,
|
|
loading = false,
|
|
error = null
|
|
} = $props();
|
|
|
|
// [REASON] We use derived state for total count to ensure consistency.
|
|
let total = $derived(pass_count + warn_count + fail_count + unknown_count);
|
|
</script>
|
|
|
|
<div class="health-matrix-summary mb-6">
|
|
{#if loading}
|
|
<div class="flex gap-4 animate-pulse">
|
|
<div class="h-24 w-32 bg-gray-200 dark:bg-gray-700 rounded-lg"></div>
|
|
<div class="h-24 w-32 bg-gray-200 dark:bg-gray-700 rounded-lg"></div>
|
|
<div class="h-24 w-32 bg-gray-200 dark:bg-gray-700 rounded-lg"></div>
|
|
</div>
|
|
{:else if error}
|
|
<div class="p-4 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg text-red-700 dark:text-red-400">
|
|
<p class="font-medium">{$t.health?.load_failed}</p>
|
|
<p class="text-sm">{error}</p>
|
|
</div>
|
|
{:else}
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
|
<div class="p-4 bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg text-center">
|
|
<div class="text-2xl font-bold text-green-700 dark:text-green-400">🟢 {pass_count}</div>
|
|
<div class="text-xs text-green-600 dark:text-green-500 uppercase tracking-wider font-semibold">{$t.health?.status_pass}</div>
|
|
</div>
|
|
|
|
<div class="p-4 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg text-center">
|
|
<div class="text-2xl font-bold text-yellow-700 dark:text-yellow-400">🟡 {warn_count}</div>
|
|
<div class="text-xs text-yellow-600 dark:text-yellow-500 uppercase tracking-wider font-semibold">{$t.health?.status_warn}</div>
|
|
</div>
|
|
|
|
<div class="p-4 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg text-center">
|
|
<div class="text-2xl font-bold text-red-700 dark:text-red-400">🔴 {fail_count}</div>
|
|
<div class="text-xs text-red-600 dark:text-red-500 uppercase tracking-wider font-semibold">{$t.health?.status_fail}</div>
|
|
</div>
|
|
|
|
<div class="p-4 bg-gray-50 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg text-center">
|
|
<div class="text-2xl font-bold text-gray-700 dark:text-gray-300">⚪ {unknown_count}</div>
|
|
<div class="text-xs text-gray-600 dark:text-gray-500 uppercase tracking-wider font-semibold">{$t.health?.status_unknown}</div>
|
|
</div>
|
|
</div>
|
|
|
|
{#if total === 0}
|
|
<div class="mt-4 p-8 text-center border-2 border-dashed border-gray-200 dark:border-gray-700 rounded-xl text-gray-500 dark:text-gray-400">
|
|
{$t.health?.no_records_for_environment}
|
|
</div>
|
|
{/if}
|
|
{/if}
|
|
</div>
|
|
|
|
<style>
|
|
/* Tailwind handles most styling, custom tweaks here if needed */
|
|
</style>
|
|
<!-- [/DEF:HealthMatrix:Component] -->
|