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>
AdminAuditView.vue — The top-level loading spinner (Loading audit log… text + animate-spin div) has been replaced. The <tbody> now renders 8 skeleton rows (5 <td> cells each, all animate-pulse) when loading=true. When loading is false and entries is empty, an EmptyState renders in a colspan=5 cell. When entries exist, the real rows render.
AdminUsersView.vue — Same pattern: 5 skeleton rows x 6 <td> cells each. The v-if="loading" spinner div is gone. The existing empty/real rendering is now inside a single always-visible table.
1. [Rule 1 - Bug] CTA slot test required EmptyState not to be stubbed
Found during: Task 2 (GREEN verification)
Issue: The test EmptyState includes a Clear filters CTA button used EmptyState: true (full stub). When an EmptyState is stubbed as true, Vue Test Utils renders the component as <emptystate-stub/> — named slots are discarded. The #cta slot content (the Clear filters button) never rendered, so wrapper.text() did not contain 'Clear filters'.
Fix: The CTA test mounts AdminAuditView with EmptyState NOT stubbed (only BreadcrumbBar and AppIcon are stubbed). The real EmptyState renders, which renders the slot content.
Issue: CloudStorageView has a sticky toolbar div with a static <span>Cloud Storage</span> label. Adding BreadcrumbBar as a separate element would create visual duplication with the existing toolbar.
Fix: Replaced the <span class="text-sm font-medium text-gray-700">Cloud Storage</span> with <BreadcrumbBar :segments="[{ label: 'Cloud Storage' }]" :show-root="false" /> directly in the toolbar, preserving the sticky header layout.
None. All EmptyState usages are fully wired with real data conditions. The BreadcrumbBar segments are static strings derived from the view's own label — no async data needed.
Threat Flags
None. All changes are presentational — no new network endpoints, no auth paths, no file access. The EmptyState components display static strings.