Files
kite/.planning/milestones/v0.2-phases/10-ux-interaction/10-12-PLAN.md
T
curo1305andClaude Sonnet 4.6 123ae5b29b chore: archive v0.2 phase directories to milestones/v0.2-phases/
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>
2026-06-17 14:34:52 +02:00

21 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 12 execute 5
10-01
10-06
10-07
10-08
10-09
10-10
10-11
frontend/src/components/storage/StorageBrowser.vue
frontend/src/components/layout/AppSidebar.vue
frontend/src/components/admin/AdminSidebar.vue
frontend/src/components/folders/FolderRow.vue
frontend/src/components/folders/FolderTreeItem.vue
frontend/src/components/folders/FolderDeleteModal.vue
frontend/src/components/documents/DocumentCard.vue
frontend/src/components/documents/DocumentPreviewModal.vue
frontend/src/components/documents/SearchBar.vue
frontend/src/components/sharing/ShareModal.vue
frontend/src/components/upload/DropZone.vue
frontend/src/components/upload/UploadProgress.vue
frontend/src/components/ui/TreeItem.vue
frontend/src/components/ui/SearchableModelSelect.vue
frontend/src/components/settings/SettingsCloudTab.vue
frontend/src/components/cloud/CloudFolderTreeItem.vue
frontend/src/components/cloud/CloudProviderTreeItem.vue
frontend/src/views/AccountView.vue
frontend/src/views/CloudStorageView.vue
frontend/src/views/SettingsView.vue
frontend/src/views/admin/AdminUsersView.vue
frontend/src/views/admin/AdminAuditView.vue
frontend/src/views/admin/AdminQuotasView.vue
frontend/src/views/admin/AdminAiView.vue
frontend/src/views/admin/AdminOverviewView.vue
true
CODE-05
truths artifacts key_links
All inline <svg> blocks (~66 instances across ~29 files) are replaced with <AppIcon name='...' class='...' /> calls
Each affected file imports AppIcon from the correct relative path
Visual rendering is unchanged - same classes carry through to the <svg> via $attrs.class
The full test suite continues to pass post-migration (no regression)
No inline `<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">` blocks remain (except in AppIcon.vue itself, AppSpinner.vue spinner, and UploadProgress.vue fill-based icons if they cannot be swapped)
path provides
frontend/src/**/*.vue Updated to use AppIcon
from to via pattern
Each modified .vue file AppIcon.vue import AppIcon from <relative-path>/components/ui/AppIcon.vue import AppIcon
Complete CODE-05 by replacing every inline `` block in the frontend with an `` call. This is the final wave of Phase 10 because every previous wave can freely modify its files without worrying about icon migration churn, and any new SVGs introduced earlier in the phase are caught here.

Per RESEARCH.md §Component Inventory §1, the audit found ~66 <svg> blocks across ~29 files mapping to ~30 named icons. The full Name -> d-attribute map lives in AppIcon.vue (from 10-01).

Output:

  • Every affected file imports AppIcon from the correct relative path
  • Every inline <svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="..." /></svg> block (or equivalent) is replaced with <AppIcon name="<assigned-name>" class="<original-classes>" />
  • AppSpinner.vue retains its inline spinner SVG (it is not an icon)
  • UploadProgress.vue fill-based icons are swapped for stroke equivalents (checkCircle / exclamationCircle from AppIcon)
  • FolderRow.vue's previously fill-based three-dot icon is replaced with <AppIcon name="dots" /> (stroke variant added in 10-01)

<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/components/ui/AppIcon.vue **Migration mapping (from RESEARCH.md §Component Inventory §1):**

For each file, identify each inline <svg> block by its d attribute, look up the icon name in the AppIcon ICON_PATHS map, then replace.

Example transformation:

<!-- BEFORE -->
<svg class="w-4 h-4 mr-2 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
    d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7..." />
</svg>

<!-- AFTER -->
<AppIcon name="tag" class="w-4 h-4 mr-2 shrink-0" />

Special cases:

  • Settings dual-path (cog + cogDot) in AppSidebar -> single <AppIcon name="cog" class="..." /> (AppIcon handles the array)
  • FolderRow dots (fill-based) -> <AppIcon name="dots" class="w-4 h-4" /> (stroke replacement; ICON_PATHS already includes the stroke version per 10-01)
  • UploadProgress fill-based check/error -> <AppIcon name="checkCircle" class="..." /> / <AppIcon name="exclamationCircle" class="..." />
  • BreadcrumbBar internal chevronRight (added in 10-03) is already AppIcon - no change needed
  • AppSpinner internal spinner SVG -> KEEP (it is a special animation, not an icon)
  • DocumentPreviewModal internal spinner SVG (if it uses <circle>) -> KEEP

Per-file inline SVG count (from RESEARCH.md):

File Approx SVG count Notes
frontend/src/components/storage/StorageBrowser.vue ~6 plus, folder (x2), folderMove, pencil, trash, share, document
frontend/src/components/layout/AppSidebar.vue ~10 tag, inbox, cloud, shield, cog (dual-path), logout, chevronRight (x2)
frontend/src/components/admin/AdminSidebar.vue ~6 home, users, chartBar, lightBulb, clipboardList, logout
frontend/src/components/folders/FolderRow.vue ~3 folder, dots, pencil, trash
frontend/src/components/folders/FolderTreeItem.vue ~2 folder, chevronRight
frontend/src/components/folders/FolderDeleteModal.vue 1 warning
frontend/src/components/documents/DocumentCard.vue ~3 document, folderMove, trash
frontend/src/components/documents/DocumentPreviewModal.vue 1 x (plus spinner kept)
frontend/src/components/sharing/ShareModal.vue 1 x
frontend/src/components/upload/DropZone.vue 1 upload
frontend/src/components/upload/UploadProgress.vue ~2 checkCircle, exclamationCircle (fill-swap)
frontend/src/components/ui/TreeItem.vue 1 chevronRight
frontend/src/components/ui/SearchableModelSelect.vue ~2 chevronDown, pencilEdit
frontend/src/components/settings/SettingsCloudTab.vue 1 warning
frontend/src/components/cloud/CloudFolderTreeItem.vue ~2 folder, fileDoc
frontend/src/components/cloud/CloudProviderTreeItem.vue 1 cloud
frontend/src/views/AccountView.vue 1 checkMark
frontend/src/views/CloudStorageView.vue 1 cloud (now handled in 10-08 via EmptyState; verify no other inline svg)
frontend/src/views/SettingsView.vue ~3 checkCircle, exclamationCircle, x (x2)
frontend/src/views/admin/AdminUsersView.vue ~3 copy, check, refresh
frontend/src/views/admin/AdminAuditView.vue possibly 0-1 after 10-08 changes
frontend/src/views/admin/AdminQuotasView.vue 0-1
frontend/src/views/admin/AdminAiView.vue 0-1
frontend/src/views/admin/AdminOverviewView.vue 0-1

The numbers are approximate; the actual count comes from grep -c "<svg" <file> at execution time.

Identification process: For each file:

  1. Read the file
  2. For each inline <svg> block, read the d attribute
  3. Look up the matching name in ICON_PATHS (from 10-01)
  4. Replace the whole <svg>...</svg> block with <AppIcon name="<name>" class="<original class attribute value>" />
  5. Ensure the file imports AppIcon

If an inline SVG's d attribute does NOT match any known icon, halt and report it - DO NOT invent a name. Either: (a) Add the missing name+d to ICON_PATHS in AppIcon.vue (and update the AppIcon test if necessary), OR (b) Leave that one inline SVG untouched and note it as an exception in the SUMMARY.

Import path patterns:

  • Files under frontend/src/components/storage/ -> import AppIcon from '../ui/AppIcon.vue'
  • Files under frontend/src/components/layout/ -> import AppIcon from '../ui/AppIcon.vue'
  • Files under frontend/src/components/folders/ -> import AppIcon from '../ui/AppIcon.vue'
  • Files under frontend/src/components/documents/ -> import AppIcon from '../ui/AppIcon.vue'
  • Files under frontend/src/components/cloud/ -> import AppIcon from '../ui/AppIcon.vue'
  • Files under frontend/src/components/sharing/ -> import AppIcon from '../ui/AppIcon.vue'
  • Files under frontend/src/components/upload/ -> import AppIcon from '../ui/AppIcon.vue'
  • Files under frontend/src/components/settings/ -> import AppIcon from '../ui/AppIcon.vue'
  • Files under frontend/src/components/admin/ -> import AppIcon from '../ui/AppIcon.vue'
  • Files under frontend/src/components/ui/ -> import AppIcon from './AppIcon.vue'
  • Files under frontend/src/views/ -> import AppIcon from '../components/ui/AppIcon.vue'
  • Files under frontend/src/views/admin/ -> import AppIcon from '../../components/ui/AppIcon.vue'

For Options API files, also register: components: { AppIcon, ... }. For <script setup> files, the import is enough.

Task 1: Migrate sidebar + top-level layout files (StorageBrowser, AppSidebar, AdminSidebar, TreeItem) frontend/src/components/storage/StorageBrowser.vue, frontend/src/components/layout/AppSidebar.vue, frontend/src/components/admin/AdminSidebar.vue, frontend/src/components/ui/TreeItem.vue - All four files (current state) - frontend/src/components/ui/AppIcon.vue (to know the available names and their d-values) - .planning/phases/10-ux-interaction/10-RESEARCH.md §"Component Inventory §1: SVG Audit" (file-to-icon map) For each file: add the AppIcon import (correct relative path). For Options API files (AppSidebar uses Options API, AdminSidebar likely the same, TreeItem may be either), register `AppIcon` in the `components: { ... }` map. For `<script setup>` files (StorageBrowser), only the import is needed.
Then, for each inline `<svg>` block, replace as described in <interfaces>:

**StorageBrowser.vue** (approx 6-7 SVGs):
- "New folder" button SVG (d=`M12 4v16m8-8H4`) -> `<AppIcon name="plus" class="w-4 h-4" />`
- Folder row icon (d starting `M3 7a2 2 0 012-2h4l2 2h8...`) -> `<AppIcon name="folder" class="w-4 h-4 text-amber-500" />`
- Inline new-folder row folder icon -> same as above
- File row pencil (rename) -> `<AppIcon name="pencil" class="..." />`
- File row trash (delete) -> `<AppIcon name="trash" class="..." />`
- File row share -> `<AppIcon name="share" class="..." />`
- File row document icon -> `<AppIcon name="document" class="..." />`
- File row folder-move (folderMove) -> `<AppIcon name="folderMove" class="..." />`

**AppSidebar.vue** (approx 10 SVGs):
- chevronRight x2 -> `<AppIcon name="chevronRight" class="..." />` each
- tag (All Topics) -> `<AppIcon name="tag" class="..." />`
- inbox (Shared with me) -> `<AppIcon name="inbox" class="..." />`
- cloud (Cloud section) -> `<AppIcon name="cloud" class="..." />`
- shield (Admin) -> `<AppIcon name="shield" class="..." />`
- cog dual-path (Settings) -> `<AppIcon name="cog" class="..." />` (single tag - AppIcon handles the array)
- logout (Sign out) -> `<AppIcon name="logout" class="..." />`

**AdminSidebar.vue** (approx 6 SVGs): home, users, chartBar, lightBulb, clipboardList, logout. Replace each with the matching AppIcon name preserving the original class attribute.

**TreeItem.vue** (1 SVG): chevronRight -> `<AppIcon name="chevronRight" class="..." />`.

Preserve all existing classes verbatim. Do not change SVG container element types (e.g., if the SVG was inside a `<button>`, the AppIcon stays inside the `<button>`).
cd frontend && npm run test -- --run; cd frontend && npm run build Expected: full test suite passes; build succeeds. - StorageBrowser.vue: `grep -c "` calls - Full test suite passes - npm run build exits 0 4 sidebar/storage files fully migrated; no inline SVGs remain in any of them. Task 2: Migrate folder + document + upload + sharing components frontend/src/components/folders/FolderRow.vue, frontend/src/components/folders/FolderTreeItem.vue, frontend/src/components/folders/FolderDeleteModal.vue, frontend/src/components/documents/DocumentCard.vue, frontend/src/components/documents/DocumentPreviewModal.vue, frontend/src/components/documents/SearchBar.vue, frontend/src/components/sharing/ShareModal.vue, frontend/src/components/upload/DropZone.vue, frontend/src/components/upload/UploadProgress.vue - All nine files (current state) - frontend/src/components/ui/AppIcon.vue - .planning/phases/10-ux-interaction/10-RESEARCH.md §"Component Inventory §1" (file/icon map) For each file, repeat the migration pattern: add `import AppIcon`, register in components if Options API, replace each inline `` with ``.
Specific notes:
- **FolderRow.vue**: the three-dot menu currently uses `fill="currentColor"` - replace with `<AppIcon name="dots" class="w-4 h-4" />` (stroke variant added in 10-01).
- **FolderDeleteModal.vue**: warning icon -> `<AppIcon name="warning" class="..." />`.
- **DocumentCard.vue**: document + folderMove + trash -> each with matching AppIcon name.
- **DocumentPreviewModal.vue**: close `x` button SVG -> `<AppIcon name="x" class="..." />`. KEEP the loading spinner SVG (it uses `<circle>` and is not in the icon map).
- **SearchBar.vue**: if SearchBar has a search icon inline, replace with `<AppIcon name="search" />`. If it does not have any inline SVG, this file is a no-op for migration (still add the import only if needed).
- **ShareModal.vue**: `x` close button -> `<AppIcon name="x" class="..." />`.
- **DropZone.vue**: upload icon -> `<AppIcon name="upload" class="..." />`.
- **UploadProgress.vue**: fill-based check + error icons -> `<AppIcon name="checkCircle" />` / `<AppIcon name="exclamationCircle" />`. Drop the `fill="currentColor"` styling - AppIcon uses stroke; visual difference at w-5 h-5 is minor and acceptable per RESEARCH.md Open Question 1.
cd frontend && npm run test -- --run; cd frontend && npm run build Expected: tests pass; build succeeds. - For each file: `grep -c "` returns 0 OR 1 (1 is acceptable only for DocumentPreviewModal.vue with the loading spinner) - Specifically: `grep -c "` returns 0 - Every file contains `import AppIcon` (except SearchBar if no SVGs existed there - confirm by reading) - Full test suite passes - npm run build exits 0 9 folder/document/upload/sharing files migrated. Task 3: Migrate cloud + settings + UI utility files frontend/src/components/cloud/CloudFolderTreeItem.vue, frontend/src/components/cloud/CloudProviderTreeItem.vue, frontend/src/components/settings/SettingsCloudTab.vue, frontend/src/components/ui/SearchableModelSelect.vue - All four files (current state) - frontend/src/components/ui/AppIcon.vue - .planning/phases/10-ux-interaction/10-RESEARCH.md §"Component Inventory §1" Apply the migration: - **CloudFolderTreeItem.vue**: folder + fileDoc -> `` / ``. - **CloudProviderTreeItem.vue**: cloud -> ``. - **SettingsCloudTab.vue**: warning -> ``. - **SearchableModelSelect.vue**: chevronDown + pencilEdit -> `` / ``. cd frontend && npm run test -- --run; cd frontend && npm run build Expected: tests pass; build succeeds. - Each file: `grep -c "` returns 0 - Each file imports AppIcon - Test suite + build pass 4 cloud/settings/UI files migrated. Task 4: Migrate view files (AccountView, CloudStorageView, SettingsView, all admin views) frontend/src/views/AccountView.vue, frontend/src/views/CloudStorageView.vue, frontend/src/views/SettingsView.vue, frontend/src/views/admin/AdminUsersView.vue, frontend/src/views/admin/AdminAuditView.vue, frontend/src/views/admin/AdminQuotasView.vue, frontend/src/views/admin/AdminAiView.vue, frontend/src/views/admin/AdminOverviewView.vue - All eight files (current state, after 10-08 modifications) - frontend/src/components/ui/AppIcon.vue - .planning/phases/10-ux-interaction/10-RESEARCH.md §"Component Inventory §1" Apply the migration: - **AccountView.vue**: checkMark -> ``. - **CloudStorageView.vue**: any remaining inline SVG (after 10-08 EmptyState wiring) -> matching AppIcon. - **SettingsView.vue**: checkCircle + exclamationCircle + x (x2) -> matching AppIcons. - **AdminUsersView.vue**: copy + check + refresh -> matching AppIcons. - **AdminAuditView.vue, AdminQuotasView.vue, AdminAiView.vue, AdminOverviewView.vue**: any remaining inline SVGs -> matching AppIcons. If none, this is a no-op (no import needed unless adding it).
For all views: register `AppIcon` in `components: { ... }` if Options API; or only add the import if `<script setup>`.
cd frontend && npm run test -- --run; cd frontend && npm run build; grep -rE " Expected: tests pass; build succeeds; grep count returns 0 (all stroke-based outline SVGs migrated). - Each view file: `grep -c "` returns 0 - `grep -rE "`). Both have already been validated NOT to use the stroke + viewBox 0 0 24 24 pattern; if either matches the grep above, halt and confirm with the user before proceeding. - npm run build exits 0 - Full test suite passes All view-level files migrated; CODE-05 verifiable by the single grep across the codebase returning 0. - Codebase-wide check: `grep -rE "

<success_criteria> The frontend bundle has a single source of truth for icon paths. Visually, the app renders identically to before migration. Adding a new icon requires editing ONE map in AppIcon.vue and using <AppIcon name="..." /> at consumer sites - no more copy-paste of <svg ...> blocks. The grep gate guarantees no future drift back to inline SVGs without violating CODE-05. </success_criteria>

Create `.planning/phases/10-ux-interaction/10-12-SUMMARY.md` when done. Include the final `grep -rc "