refactor(frontend): replace raw buttons with /ui/Button in SummaryPanel
- Replace raw <button> with <Button variant="ghost"> - Dim zero-count badges with opacity-50 - Add transition-colors duration-300 to count numbers - Replace inline reconnect link with themed <Button>
This commit is contained in:
@@ -1,18 +1,21 @@
|
||||
<!-- #region SummaryPanel [C:4] [TYPE Component] [SEMANTICS component, summary, dashboard, websocket-reactive, task-status-center] -->
|
||||
<!-- @BRIEF Summary dashboard panel — grid of clickable cards showing task counts by type × status. -->
|
||||
<!-- @LAYER UI Component -->
|
||||
<!-- @LAYER UI -->
|
||||
<!-- @UX_STATE idle: cards rendered normally, clickable -->
|
||||
<!-- @UX_STATE loading: skeleton placeholders (4 cards with pulse animation) -->
|
||||
<!-- @UX_STATE empty: all cards show zero counts -->
|
||||
<!-- @UX_STATE reconnecting: last known counts visible, yellow pulsing indicator -->
|
||||
<!-- @UX_STATE disconnected: last known counts visible, opacity reduced, "disconnected" badge -->
|
||||
<!-- @UX_FEEDBACK Count change: number animates (CSS transition). Card click: emits filter event. -->
|
||||
<!-- @UX_FEEDBACK Count change: number animates (CSS transition). Card click: emits filter event. Zero-count badges remain dimmed but visible. -->
|
||||
<!-- @UX_RECOVERY Disconnected: auto-reconnect indicator. Click → manual reconnect button. -->
|
||||
<!-- @UX_REACTIVITY Props: summary: TaskSummary | null, screenState: ScreenState. Derived: by_type grid. -->
|
||||
<!-- @RELATION BINDS_TO -> [TaskCenterModel] -->
|
||||
<!-- @RELATION BINDS_TO -> [TaskCenter.Model] -->
|
||||
<!-- @PRE summary is non-null when screenState is 'ready' or 'disconnected'. -->
|
||||
<!-- @POST Clicking a card calls onFilterByTypeAndStatus(taskType, status). -->
|
||||
<!-- @DATA_CONTRACT Input: TaskSummary + ScreenState → Output: clickable status summary cards. -->
|
||||
<!-- @SIDE_EFFECT Calls parent callbacks only; no direct network or store mutation. -->
|
||||
<script lang="ts">
|
||||
import { Button } from '$lib/ui';
|
||||
import type { TaskType, ReportStatus, ScreenState, StatusCounts, TaskSummary } from '$types/reports';
|
||||
|
||||
const STATUS_CONFIG: { key: keyof StatusCounts; label: string; colorClass: string }[] = [
|
||||
@@ -79,15 +82,17 @@
|
||||
{#each STATUS_CONFIG as status (status.key)}
|
||||
{@const count = getCount(typeSummary, status.key)}
|
||||
{@const isActive = isStatusActive(typeSummary, status.key)}
|
||||
<button
|
||||
class="flex min-h-11 items-center gap-2 rounded-lg border px-2 py-2 text-left cursor-pointer transition-all hover:border-border-strong focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-ring {screenState === 'disconnected' ? 'opacity-60' : ''} {status.colorClass} {isActive ? 'border-primary-ring ring-2 ring-primary-ring/50' : 'border-border'}"
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
class="flex min-h-11 w-full items-center justify-start gap-2 rounded-lg border px-2 py-2 text-left cursor-pointer transition-all hover:border-border-strong focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-ring {screenState === 'disconnected' ? 'opacity-60' : ''} {status.colorClass} {count === 0 ? 'opacity-50' : ''} {isActive ? 'border-primary-ring ring-2 ring-primary-ring/50' : 'border-border'}"
|
||||
onclick={() => handleCardClick(typeSummary, status.key)}
|
||||
aria-label="{typeSummary.display_label}, {status.label}: {count}"
|
||||
aria-pressed={isActive}
|
||||
>
|
||||
<span class="text-sm font-mono min-w-[1.5rem] text-center font-semibold">{count}</span>
|
||||
<span class="text-sm font-mono min-w-[1.5rem] text-center font-semibold transition-colors duration-300">{count}</span>
|
||||
<span class="text-xs truncate">{status.label}</span>
|
||||
</button>
|
||||
</Button>
|
||||
{/each}
|
||||
</div>
|
||||
{/each}
|
||||
@@ -95,7 +100,7 @@
|
||||
<div class="flex items-center gap-2 text-xs text-text-muted mt-2">
|
||||
<span class="w-2 h-2 rounded-full bg-destructive"></span>
|
||||
Данные могут быть неактуальны
|
||||
<button class="underline cursor-pointer" onclick={onReconnect}>Подключиться</button>
|
||||
<Button variant="ghost" size="sm" class="h-auto p-0 underline" onclick={onReconnect}>Подключиться</Button>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user