Files

6.3 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, duration, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions duration completed
05-cloud-storage-backends 08 ui
cloud-storage
vue3
sidebar
tree-view
lazy-load
tailwind
phase plan provides
05-cloud-storage-backends 07 useCloudConnectionsStore with connections/loading state and fetchConnections action; CloudCredentialModal.vue; SettingsCloudTab.vue
frontend/src/components/cloud/CloudProviderTreeItem.vue: sidebar tree root node per ACTIVE cloud connection with lazy-load folder expansion
frontend/src/components/cloud/CloudFolderTreeItem.vue: recursive cloud sub-folder tree node with lazy-load and depth padding
frontend/src/api/client.js: getCloudFolders(provider, folderId) function
frontend/src/components/layout/AppSidebar.vue: Cloud Storage collapsible section between Folders and Topics
added patterns
Lazy-load tree pattern (script setup Composition API): childrenLoaded ref guards re-fetch; toggleExpand loads then flips expanded
Recursive component self-reference: CloudFolderTreeItem renders CloudFolderTreeItem for nested children
Computed activeCloudConnections filtered to status === 'ACTIVE' — REQUIRES_REAUTH and ERROR hidden from sidebar
created modified
frontend/src/components/cloud/CloudProviderTreeItem.vue
frontend/src/components/cloud/CloudFolderTreeItem.vue
frontend/src/api/client.js
frontend/src/components/layout/AppSidebar.vue
CloudFolderTreeItem self-references itself for recursive nested children (Vue SFC default export is self-referencing by component name; works out of the box with script setup)
AppSidebar fetchConnections() called without await in onMounted to avoid blocking the folder/shared-with-me loads — connections load async in background
Cloud Storage label uses plain <a href='/settings'> matching UI-SPEC Surface 5 exactly (not router-link) to avoid active-class styling collision with the existing Settings nav-link
7min 2026-05-29

Phase 5 Plan 08: Cloud Storage Sidebar Tree Summary

CloudProviderTreeItem and CloudFolderTreeItem components plus AppSidebar Cloud Storage section wiring active connections to a collapsible lazy-load folder tree

Performance

  • Duration: 7 min
  • Started: 2026-05-29T06:26:41Z
  • Completed: 2026-05-29T06:33:41Z
  • Tasks: 2 (automated) + 1 (human checkpoint — pending)
  • Files modified: 4

Accomplishments

  • Added getCloudFolders(provider, folderId) export to frontend/src/api/client.js — calls GET /api/cloud/folders/{provider}/{folderId}
  • Created CloudProviderTreeItem.vue using Composition API (script setup): expand/collapse arrow, provider cloud icon with per-provider color (google_drive→blue, onedrive→sky, nextcloud→orange, webdav→gray), lazy-loads children via getCloudFolders(provider, 'root') on first expand, loading state ("Loading…") and error state ("Failed to load — tap to retry") per UI-SPEC Surface 5
  • Created CloudFolderTreeItem.vue: recursively renders itself for nested sub-folders; expand arrow only shown when folder.is_dir === true; lazy-loads children on expand; navigates to /cloud/{provider}/{folder.id} on click; depth padding via depth * 12 px
  • Extended AppSidebar.vue with Cloud Storage collapsible section between Folders and Topics: imports useCloudConnectionsStore, CloudProviderTreeItem; adds cloudExpanded ref (default true), activeCloudConnections computed (filter status === 'ACTIVE'), loadingCloudConnections computed; calls cloudConnectionsStore.fetchConnections() on mount; renders empty state "No cloud storage connected" or one CloudProviderTreeItem per ACTIVE connection

Task Commits

  1. Task 1: Cloud tree components + API function - 34b0593 (feat)
  2. Task 2: AppSidebar Cloud Storage section - 98576ac (feat)

Files Created/Modified

  • frontend/src/components/cloud/CloudProviderTreeItem.vue — Provider root node in sidebar tree (created)
  • frontend/src/components/cloud/CloudFolderTreeItem.vue — Cloud sub-folder recursive node (created)
  • frontend/src/api/client.js — Added getCloudFolders function
  • frontend/src/components/layout/AppSidebar.vue — Added Cloud Storage section; imported CloudProviderTreeItem and useCloudConnectionsStore

Decisions Made

  • @pinia/testing not used — store access via useCloudConnectionsStore() in the component; same composition pattern as all other stores in the project
  • cloudConnectionsStore.fetchConnections() is called without await in onMounted to avoid serializing with folder/shared-with-me loads; connections appear as soon as the API responds in the background
  • Cloud Storage label uses <a href="/settings"> (plain anchor) rather than <router-link> to prevent the router-link nav-link-active class from activating when on /settings

Deviations from Plan

None — plan executed exactly as written.

Known Stubs

None. All components are wired to live data via useCloudConnectionsStore and getCloudFolders. The "No cloud storage connected" state is correct zero-state when no connections exist.

Threat Surface Scan

No new network endpoints introduced. Frontend-only changes. Threat T-05-08-04 (only ACTIVE connections shown in sidebar) is implemented correctly — activeCloudConnections filters to status === 'ACTIVE'.

Self-Check: PASSED

Files verified present:

  • frontend/src/components/cloud/CloudProviderTreeItem.vue: FOUND
  • frontend/src/components/cloud/CloudFolderTreeItem.vue: FOUND
  • frontend/src/api/client.js: FOUND (with getCloudFolders)
  • frontend/src/components/layout/AppSidebar.vue: FOUND (with CloudProviderTreeItem, cloudExpanded, useCloudConnectionsStore, Cloud Storage section)

Commits verified:

  • 34b0593: feat(05-08): add cloud tree components and getCloudFolders API function — FOUND
  • 98576ac: feat(05-08): add Cloud Storage collapsible section to AppSidebar — FOUND

Build verification: npm run build → exit 0, 191 kB bundle


Human Checkpoint Pending

Plan 05-08 contains a checkpoint:human-verify task (gate="blocking"). The automated tasks are complete. The checkpoint details are presented to the user below.


Phase: 05-cloud-storage-backends Completed (automated tasks): 2026-05-29