Moves phases 08–11 execution artifacts from .planning/phases/ to .planning/milestones/v0.2-phases/ to keep .planning/phases/ clean for the next milestone. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
17 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 10-ux-interaction | 08 | execute | 1 |
|
|
true |
|
|
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
<BreadcrumbBar>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
<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>
@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 <tbody> when loading. The existing loading spinner block is replaced.
EmptyState wiring (RESEARCH.md Component Inventory #3):
- AdminAuditView empty entries:
<EmptyState icon="clipboardList" headline="No entries found" subtext="Try adjusting your filters or date range.">with #cta buttonClear filters - SharedView empty shared docs:
<EmptyState icon="inbox" headline="Nothing shared with you yet" subtext="When someone shares a document with you, it will appear here." /> - CloudStorageView empty connections:
<EmptyState icon="cloud" headline="No cloud storage connected" subtext="Connect Google Drive, OneDrive, Nextcloud, or a WebDAV server in Settings.">with #cta router-link to /settings
AdminAuditView.skeleton.test.js (5 tests):
1. `renders 8 skeleton <tr> rows when loading=true` - mount AdminAuditView with loading mocked to true, find `<tbody>` and assert findAll('tr').length >= 8
2. `skeleton rows have exactly 5 <td> cells matching column count` - assert each skeleton row has 5 `<td>` children
3. `Loading audit log text is absent when loading=true` - assert wrapper.text() does NOT include 'Loading audit log'
4. `renders <EmptyState icon="clipboardList" headline="No entries found"> 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 <tr> rows when loading=true` - assert >= 5
2. `skeleton rows have exactly 6 <td> 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 }.
AdminUsersView.vue changes:
1. Add `import BreadcrumbBar from '../../components/ui/BreadcrumbBar.vue'`. Register if Options API.
2. Add `<BreadcrumbBar :segments="[{ label: 'Users' }]" :show-root="false" class="mb-4" />` at the top of the template root.
3. Replace the existing loading spinner block with skeleton table rows: 5 rows x 6 `<td>` cells per row, classes per <interfaces> section.
Preserve all other functionality (filters, action buttons, sort, pagination, modals).
AdminAiView.vue: Same pattern with segments `[{ label: 'AI Config' }]`.
AdminOverviewView.vue: Same pattern with `:segments="[]" :show-root="false"`. The empty segments block renders a `<nav>` with empty `<ol>` - acceptable. Alternatively keep the existing page heading and skip BreadcrumbBar if it would visually duplicate. Read the file: if there is already a clear `<h1>Admin Overview</h1>` heading, skip; otherwise add the BreadcrumbBar.
SettingsView.vue:
Read the file to find the `activeTab` state and its display labels. Add a computed `breadcrumbSegments` that returns `[{ label: 'Settings' }, { label: activeTabLabel }]` where `activeTabLabel` maps the current tab id to its user-facing label. Add `<BreadcrumbBar :segments="breadcrumbSegments" :show-root="false" class="mb-4" />` at the top of the template root.
SharedView.vue:
Add `import EmptyState from '../components/ui/EmptyState.vue'` and `import BreadcrumbBar from '../components/ui/BreadcrumbBar.vue'`. Register if Options API. At top of template add `<BreadcrumbBar :segments="[{ label: 'Shared with me' }]" :show-root="false" class="mb-4" />`. Replace the inline empty `<div v-else-if="sharedDocs.length === 0" class="text-center py-12 text-gray-400">...</div>` with:
```
<EmptyState
v-else-if="sharedDocs.length === 0"
icon="inbox"
headline="Nothing shared with you yet"
subtext="When someone shares a document with you, it will appear here."
/>
```
CloudStorageView.vue:
Add `import EmptyState` + `BreadcrumbBar`. Register if Options API. At top of template add `<BreadcrumbBar :segments="[{ label: 'Cloud Storage' }]" :show-root="false" class="mb-4" />`. Replace the inline empty div with:
```
<EmptyState
v-else-if="connections.length === 0"
icon="cloud"
headline="No cloud storage connected"
subtext="Connect Google Drive, OneDrive, Nextcloud, or a WebDAV server in Settings."
>
<template #cta>
<router-link to="/settings" class="mt-3 inline-block text-sm text-indigo-600 hover:underline">
Go to Settings
</router-link>
</template>
</EmptyState>
```
All six files: preserve existing functionality untouched aside from the additions above.
<success_criteria>
Every admin section + SettingsView shows a Section name breadcrumb at the top with no "Home" prefix. AdminAuditView + AdminUsersView display animated skeleton tables during load. AdminAuditView's "no entries" state renders the EmptyState with a Clear filters button. SharedView and CloudStorageView render proper EmptyState components with appropriate icons (inbox / cloud) and Settings link where applicable.
</success_criteria>