From 0c63c0b6ab8186c07d10407d45486cb3bd3967fd Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Tue, 7 Apr 2026 13:52:24 +0900 Subject: [PATCH] =?UTF-8?q?feat(ui):=20Phase=20B=20=E2=80=94=20sidebar=20d?= =?UTF-8?q?rawer=20+=20SystemStatusDot=20+=20=ED=82=A4=EB=B3=B4=EB=93=9C?= =?UTF-8?q?=20nav?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - +layout.svelte: 햄버거 → IconButton, 우측 nav → Button ghost, sidebar overlay → Drawer (uiState 단일 slot), Esc 글로벌 핸들러 ui.handleEscape() 위임 (5대 원칙 #2) - lib/stores/system.ts (신규): dashboardSummary writable + 60s 폴링, 단일 fetch를 SystemStatusDot(B)와 dashboard(C)가 공유 - SystemStatusDot.svelte (신규): 8px 도트 + tooltip, failed > 0 → error / pending > 10 → warning / 그 외 → success - Sidebar.svelte: 트리에 ArrowUp/Down 키보드 nav, 활성 도메인 row에 aria-current="page" --- frontend/src/lib/components/Sidebar.svelte | 22 ++++- .../src/lib/components/SystemStatusDot.svelte | 89 +++++++++++++++++++ frontend/src/lib/stores/system.ts | 79 ++++++++++++++++ frontend/src/routes/+layout.svelte | 69 ++++++-------- 4 files changed, 214 insertions(+), 45 deletions(-) create mode 100644 frontend/src/lib/components/SystemStatusDot.svelte create mode 100644 frontend/src/lib/stores/system.ts diff --git a/frontend/src/lib/components/Sidebar.svelte b/frontend/src/lib/components/Sidebar.svelte index 60dddc2..d5c6c88 100644 --- a/frontend/src/lib/components/Sidebar.svelte +++ b/frontend/src/lib/components/Sidebar.svelte @@ -66,6 +66,24 @@ }); let totalCount = $derived(tree.reduce((sum, n) => sum + n.count, 0)); + + // ArrowUp/Down 키보드 nav — 현재 펼쳐진 tree-row만 traverse + function handleTreeKeydown(e) { + if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') return; + const root = e.currentTarget; + const rows = Array.from(root.querySelectorAll('[data-tree-row]')); + if (rows.length === 0) return; + const active = document.activeElement; + const idx = active ? rows.indexOf(active) : -1; + let next; + if (e.key === 'ArrowDown') { + next = idx < 0 ? 0 : Math.min(idx + 1, rows.length - 1); + } else { + next = idx <= 0 ? 0 : idx - 1; + } + e.preventDefault(); + rows[next].focus(); + }