docs(05-08): complete cloud sidebar tree plan — awaiting human checkpoint
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
---
|
||||
phase: 05-cloud-storage-backends
|
||||
plan: 08
|
||||
subsystem: ui
|
||||
tags: [cloud-storage, vue3, sidebar, tree-view, lazy-load, tailwind]
|
||||
|
||||
# Dependency graph
|
||||
requires:
|
||||
- phase: 05-cloud-storage-backends
|
||||
plan: 07
|
||||
provides: "useCloudConnectionsStore with connections/loading state and fetchConnections action; CloudCredentialModal.vue; SettingsCloudTab.vue"
|
||||
|
||||
provides:
|
||||
- "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"
|
||||
affects: []
|
||||
|
||||
# Tech tracking
|
||||
tech-stack:
|
||||
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"
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- frontend/src/components/cloud/CloudProviderTreeItem.vue
|
||||
- frontend/src/components/cloud/CloudFolderTreeItem.vue
|
||||
modified:
|
||||
- frontend/src/api/client.js
|
||||
- frontend/src/components/layout/AppSidebar.vue
|
||||
|
||||
key-decisions:
|
||||
- "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"
|
||||
|
||||
# Metrics
|
||||
duration: 7min
|
||||
completed: 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*
|
||||
Reference in New Issue
Block a user