--- phase: 10-ux-interaction plan: 08 type: execute wave: 1 depends_on: [10-02, 10-03, 10-05] files_modified: - frontend/src/views/admin/AdminAuditView.vue - frontend/src/views/admin/AdminUsersView.vue - frontend/src/views/admin/AdminQuotasView.vue - frontend/src/views/admin/AdminAiView.vue - frontend/src/views/admin/AdminOverviewView.vue - frontend/src/views/SettingsView.vue - frontend/src/views/SharedView.vue - frontend/src/views/CloudStorageView.vue - frontend/src/views/admin/__tests__/AdminAuditView.skeleton.test.js - frontend/src/views/admin/__tests__/AdminUsersView.skeleton.test.js autonomous: true requirements: [UX-04, UX-01, UX-12] must_haves: truths: - "AdminAuditView shows >=5 skeleton rows during loading" - "AdminUsersView shows >=5 skeleton rows during loading" - "AdminAuditView empty state uses EmptyState icon=clipboardList with a Clear filters CTA" - "SharedView empty state uses EmptyState icon=inbox" - "CloudStorageView empty state uses EmptyState icon=cloud with a Settings router-link CTA" - "Each admin view + SettingsView renders a BreadcrumbBar with the static segments per the wiring table (D-13)" artifacts: - path: "frontend/src/views/admin/AdminAuditView.vue" provides: "Audit view with skeleton + EmptyState + BreadcrumbBar" - path: "frontend/src/views/admin/AdminUsersView.vue" provides: "Users view with skeleton + BreadcrumbBar" - path: "frontend/src/views/SettingsView.vue" provides: "Settings view with BreadcrumbBar reflecting active tab" key_links: - from: "Each admin view" to: "BreadcrumbBar.vue" via: "static segments computed" pattern: " Wire UX-04 (skeleton table rows in admin tables), the remaining UX-01 (EmptyState in SharedView, CloudStorageView, AdminAuditView), and the admin/settings parts of UX-12 (BreadcrumbBar static segments) across the admin views, SettingsView, SharedView, and CloudStorageView. Per D-13: each view computes its own segments array. Admin/settings/topics views use `showRoot=false` so they do NOT show a "Home" button. Output: - AdminUsersView, AdminAuditView, AdminQuotasView, AdminAiView, AdminOverviewView: each gains a `` block at the top - AdminUsersView + AdminAuditView: skeleton table rows replace loading spinner - AdminAuditView empty state replaced with EmptyState - SettingsView: BreadcrumbBar with `Settings > {activeTab}` static segments - SharedView: EmptyState replaces inline empty div + BreadcrumbBar - CloudStorageView: EmptyState replaces inline empty div with Settings #cta + BreadcrumbBar - Two admin skeleton stub files promoted to real tests @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md @CLAUDE.md @.planning/phases/10-ux-interaction/10-CONTEXT.md @.planning/phases/10-ux-interaction/10-RESEARCH.md @.planning/phases/10-ux-interaction/10-PATTERNS.md @frontend/src/views/admin/AdminAuditView.vue @frontend/src/views/admin/AdminUsersView.vue @frontend/src/views/admin/AdminQuotasView.vue @frontend/src/views/admin/AdminAiView.vue @frontend/src/views/admin/AdminOverviewView.vue @frontend/src/views/SettingsView.vue @frontend/src/views/SharedView.vue @frontend/src/views/CloudStorageView.vue @frontend/src/components/ui/BreadcrumbBar.vue @frontend/src/components/ui/EmptyState.vue BreadcrumbBar per-view wiring table (from RESEARCH.md): | View | segments | showRoot | |------|----------|----------| | AdminOverviewView | `[]` | false | | AdminUsersView | `[{ label: 'Users' }]` | false | | AdminQuotasView | `[{ label: 'Quotas' }]` | false | | AdminAiView | `[{ label: 'AI Config' }]` | false | | AdminAuditView | `[{ label: 'Audit Log' }]` | false | | SettingsView | `[{ label: 'Settings' }, { label: activeTabLabel }]` | false | | SharedView | `[{ label: 'Shared with me' }]` | false | | CloudStorageView | `[{ label: 'Cloud Storage' }]` | false | SettingsView active tab labels: map tab id to display label (existing tabs in SettingsView.vue - read the file to find the mapping; typical tabs: 'Account', 'Cloud Storage', 'Preferences'). Skeleton table row pattern (RESEARCH.md Pitfall 7 admin variant): AdminAuditView (5 cols: Timestamp | User | Email | Action | IP) - 8 rows. AdminUsersView (6 cols: Email | Handle | Role | Status | Created | Actions) - 5 rows. Skeleton rows render inside the existing `` when loading. The existing loading spinner block is replaced. EmptyState wiring (RESEARCH.md Component Inventory #3): - AdminAuditView empty entries: `` with #cta button `Clear filters` - SharedView empty shared docs: `` - CloudStorageView empty connections: `` with #cta router-link to /settings Task 1: Promote AdminAuditView + AdminUsersView skeleton test stubs frontend/src/views/admin/__tests__/AdminAuditView.skeleton.test.js, frontend/src/views/admin/__tests__/AdminUsersView.skeleton.test.js - The two stub files (Wave 0 outputs) - frontend/src/views/admin/AdminAuditView.vue + AdminUsersView.vue (current state) Replace the `.todo` entries with real assertions: AdminAuditView.skeleton.test.js (5 tests): 1. `renders 8 skeleton rows when loading=true` - mount AdminAuditView with loading mocked to true, find `` and assert findAll('tr').length >= 8 2. `skeleton rows have exactly 5 cells matching column count` - assert each skeleton row has 5 `` children 3. `Loading audit log text is absent when loading=true` - assert wrapper.text() does NOT include 'Loading audit log' 4. `renders when entries empty and not loading` - assert EmptyState stub is found with those props 5. `EmptyState includes a Clear filters CTA button` - assert the rendered EmptyState slot contains 'Clear filters' AdminUsersView.skeleton.test.js (3 tests): 1. `renders 5 skeleton rows when loading=true` - assert >= 5 2. `skeleton rows have exactly 6 cells` - assert each row has 6 cells 3. `Loading users text is absent when loading=true` - assert wrapper.text() excludes 'Loading users' Use setActivePinia(createPinia()) and override store state. Stub child components via global.stubs: { BreadcrumbBar: true, EmptyState: true, AppIcon: true }. Replace `it.todo(...)` entries in both files with the real tests defined above. Tests fail until Task 2-3 update the views. cd frontend && npm run test -- --run AdminAuditView.skeleton; cd frontend && npm run test -- --run AdminUsersView.skeleton Expected: 5 + 3 = 8 tests RED. - AdminAuditView.skeleton.test.js contains 5 real `it(...)` blocks (no `.todo`) - AdminUsersView.skeleton.test.js contains 3 real `it(...)` blocks - All 8 tests are RED before Task 2 8 RED skeleton tests in place. Task 2: Update AdminAuditView.vue and AdminUsersView.vue frontend/src/views/admin/AdminAuditView.vue, frontend/src/views/admin/AdminUsersView.vue - Both view files (current state - read in full to learn the loading block + table structure + filter state) - The two failing test files from Task 1 - frontend/src/components/ui/BreadcrumbBar.vue - frontend/src/components/ui/EmptyState.vue - .planning/phases/10-ux-interaction/10-PATTERNS.md sections for AdminAuditView.vue and AdminUsersView.vue AdminAuditView.vue changes: 1. Add imports: `import BreadcrumbBar from '../../components/ui/BreadcrumbBar.vue'` and `import EmptyState from '../../components/ui/EmptyState.vue'`. Register both in `components: { ... }` (Options API) or rely on import resolution (script setup). 2. At the very top of the `