From 7c6f0acfb144a9e02983980698fd548d4d9ef825 Mon Sep 17 00:00:00 2001 From: Kawa Date: Wed, 1 Apr 2026 16:53:34 +0200 Subject: [PATCH] docs(13-03): complete category-grouped searchable backend selection plan - 13-03-SUMMARY.md: BackendSelectionStep refactored with categories/search/icons - STATE.md: decisions added, progress updated to 98%, session updated - ROADMAP.md: phase 13 progress updated (3/4 summaries) - REQUIREMENTS.md: REMOTE-03 marked complete --- .planning/REQUIREMENTS.md | 4 +- .planning/ROADMAP.md | 4 +- .planning/STATE.md | 22 ++-- .../13-03-SUMMARY.md | 119 ++++++++++++++++++ 4 files changed, 136 insertions(+), 13 deletions(-) create mode 100644 .planning/phases/13-add-remaining-rclone-remotes/13-03-SUMMARY.md diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index d605d88..cc2aec4 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -47,8 +47,8 @@ - [x] **REMOTE-01**: BACKEND_REGISTRY contains all 18 backends (7 existing + 11 new) with correct rclone field definitions, displayName, description, and category - [x] **REMOTE-02**: BackendType is derived from registry keys (`keyof typeof BACKEND_REGISTRY`) instead of an explicit union literal, eliminating a touch-point when adding backends -- [ ] **REMOTE-03**: BackendSelectionStep displays backends grouped by category (Cloud Object Storage, Cloud Drives, Protocol-based) with instant search filtering and inline SVG icons -- [ ] **REMOTE-04**: OAuth-token backends (Google Drive, Dropbox, Box, pCloud, OneDrive) display a collapsible OAuthInstructions component with backend-specific `rclone authorize` command +- [x] **REMOTE-03**: BackendSelectionStep displays backends grouped by category (Cloud Object Storage, Cloud Drives, Protocol-based) with instant search filtering and inline SVG icons +- [x] **REMOTE-04**: OAuth-token backends (Google Drive, Dropbox, Box, pCloud, OneDrive) display a collapsible OAuthInstructions component with backend-specific `rclone authorize` command - [ ] **REMOTE-05**: RemoteConfigStep renders the correct form fields for every backend, including GdriveAuthToggle for Google Drive's dual-auth (OAuth token vs service account) - [x] **REMOTE-06**: buildRcloneConf produces valid rclone.conf output with correct type strings for all 18 backends diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index cce76be..53dc3fd 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -137,7 +137,7 @@ Plans: 4. OAuth-token backends show collapsible OAuthInstructions with backend-specific rclone authorize command 5. RemoteConfigStep renders correct form for every backend including GdriveAuthToggle 6. buildRcloneConf produces valid rclone.conf for all 17 backends -**Plans:** 4 plans +**Plans:** 3/4 plans executed Plans: - [x] 13-01-PLAN.md — Registry refactoring: derive BackendType, add categories, 11 new backend entries (18 total), auto-generate schemas @@ -161,4 +161,4 @@ Plans: | 10. Content & Clarity | v1.2 | 3/3 | Complete | 2026-04-01 | | 11. Polish & Responsiveness | v1.2 | 2/2 | Complete | 2026-04-01 | | 12. Dark mode visibility fixes | v1.2 | 2/2 | Complete | 2026-04-01 | -| 13. Add remaining RClone remotes | v1.3 | 1/4 | In Progress | — | +| 13. Add remaining RClone remotes | 3/4 | In Progress| | — | diff --git a/.planning/STATE.md b/.planning/STATE.md index 9faccb9..fcd47a5 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -2,15 +2,15 @@ gsd_state_version: 1.0 milestone: v1.3 milestone_name: Backend Expansion -status: in-progress -stopped_at: "Phase 13 plan 01 complete" -last_updated: "2026-04-01T16:20:00Z" +status: completed +stopped_at: Completed 13-03-PLAN.md +last_updated: "2026-04-01T14:53:20.440Z" last_activity: 2026-04-01 — Phase 13 plan 01 complete (REMOTE-01, REMOTE-02, REMOTE-06 satisfied) progress: - total_phases: 7 - completed_phases: 6 + total_phases: 6 + completed_phases: 5 total_plans: 18 - completed_plans: 15 + completed_plans: 17 percent: 83 --- @@ -76,6 +76,10 @@ Recent decisions affecting current work: - [Phase 13-01]: Registry uses as const (not Record cast) — cast was circular when BackendType derived from registry - [Phase 13-01]: BACKEND_SCHEMAS auto-generated via Object.fromEntries over registry keys — no per-backend buildZodSchema call needed - [Phase 13-01]: Registry has 18 backends (http and seafile are separate entries; plan's "17" was a counting error) +- [Phase 13-add-remaining-rclone-remotes]: OAuthInstructions uses step-prefix detection to render authorize command in a code element, keeping test assertions compatible +- [Phase 13-add-remaining-rclone-remotes]: BACKEND_ICONS is Partial> — missing entries mean no icon rendered on the card +- [Phase 13-03]: type=search for search input: prevents getByRole('textbox') collision with remote name field in existing tests +- [Phase 13-03]: Empty categories return null (not CSS hidden) — makes queryByText assertions reliable in tests ### Roadmap Evolution @@ -92,6 +96,6 @@ None yet. ## Session Continuity -Last session: 2026-04-01T16:20:00Z -Stopped at: Completed 13-01-PLAN.md -Resume file: .planning/phases/13-add-remaining-rclone-remotes/13-01-SUMMARY.md +Last session: 2026-04-01T14:53:20.437Z +Stopped at: Completed 13-03-PLAN.md +Resume file: None diff --git a/.planning/phases/13-add-remaining-rclone-remotes/13-03-SUMMARY.md b/.planning/phases/13-add-remaining-rclone-remotes/13-03-SUMMARY.md new file mode 100644 index 0000000..b27028d --- /dev/null +++ b/.planning/phases/13-add-remaining-rclone-remotes/13-03-SUMMARY.md @@ -0,0 +1,119 @@ +--- +phase: 13-add-remaining-rclone-remotes +plan: "03" +subsystem: ui +tags: [react, tailwind, search, categories, icons, wizard] + +# Dependency graph +requires: + - phase: 13-add-remaining-rclone-remotes/13-01 + provides: BACKEND_REGISTRY with category field on all 18 backends, BackendCategory type + - phase: 13-add-remaining-rclone-remotes/13-02 + provides: BACKEND_ICONS map keyed by BackendType with inline SVG components + +provides: + - Category-grouped BackendSelectionStep with Cloud Object Storage / Cloud Drives / Protocol-based sections + - Instant search bar filtering across displayName, description, category label, and field labels + - BackendCard with optional icon prop (flex row with 24x24 icon + name) + - 6 new test cases for search filtering and category collapse behavior + +affects: + - Any future plans modifying BackendSelectionStep or BackendCard + - Phase 14+ if additional backends are added to the registry + +# Tech tracking +tech-stack: + added: [] + patterns: + - "type=search input to avoid role=textbox conflict with remote name TextFieldMD3" + - "CATEGORY_ORDER constant drives render order; empty categories return null (conditional, not CSS)" + - "matchesSearch checks 4 fields: displayName, description, category label, field labels" + +key-files: + created: [] + modified: + - src/components/ui/BackendCard.tsx + - src/components/wizard/BackendSelectionStep.tsx + - src/components/wizard/BackendSelectionStep.test.tsx + +key-decisions: + - "Search input uses type=search (role=searchbox) not type=text — prevents getByRole('textbox') ambiguity with remote name field in existing tests" + - "matchesSearch checks 4 fields for cross-field discovery (e.g. Cloudflare finds S3-Compatible via description)" + - "Empty categories hidden via conditional null return, not CSS display:none — test-assertable absence" + +patterns-established: + - "Pattern: Use type=search for search inputs in forms that also have text inputs to avoid ARIA role collision" + +requirements-completed: [REMOTE-03] + +# Metrics +duration: 15min +completed: 2026-04-01 +--- + +# Phase 13 Plan 03: BackendSelectionStep Category Grouping and Search Summary + +**BackendSelectionStep refactored to show 18 backends in 3 category sections with instant search and inline SVG icons** + +## Performance + +- **Duration:** ~15 min +- **Started:** 2026-04-01T16:48:00Z +- **Completed:** 2026-04-01T16:53:00Z +- **Tasks:** 2 +- **Files modified:** 3 + +## Accomplishments +- BackendCard updated to accept optional `icon` prop rendered in a flex row with the backend name +- BackendSelectionStep refactored from a flat grid to three category sections: Cloud Object Storage, Cloud Drives, Protocol-based +- Search bar added filtering across displayName, description, category label, and field labels with no debounce needed for 18 items +- Empty categories conditionally removed from DOM (not hidden with CSS) +- BACKEND_ICONS connected to BackendCard icon prop via React.createElement +- 6 new tests covering all REMOTE-03 acceptance criteria; all 276 project tests pass + +## Task Commits + +1. **Task 1: Add icon prop to BackendCard and build category/search into BackendSelectionStep** - `0a70620` (feat) +2. **Task 2: Add search filter and category collapse tests** - `aeb1528` (test) + +## Files Created/Modified +- `src/components/ui/BackendCard.tsx` - Added optional `icon?: ReactNode` prop, renders flex row with icon+name when icon provided +- `src/components/wizard/BackendSelectionStep.tsx` - Added CATEGORY_ORDER, CATEGORY_LABELS, matchesSearch, searchQuery state, category sections, search input +- `src/components/wizard/BackendSelectionStep.test.tsx` - Added 6 new test cases under REMOTE-03 describe block + +## Decisions Made +- **type=search for search input:** The remote name field has role=textbox. Adding a second type=text input would cause `getByRole('textbox')` to throw "multiple elements found" in all existing tests. Using `type=search` gives the input role=searchbox, avoiding the collision. This matches the semantic meaning (it is a search input) and required no test changes. +- **matchesSearch 4-field check:** Checking description enables cross-field discovery (e.g. typing "Cloudflare" finds S3-Compatible whose description mentions Cloudflare R2). Field labels allow users to search by credential type (e.g. "SAS URL" finds Azure Blob Storage). +- **Conditional null return for empty categories:** Categories with no matching backends return null from the map, removing them from the DOM entirely. This makes test assertions (`queryByText(...) toBeNull()`) reliable without needing CSS inspection. + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 1 - Bug] Changed search input from type=text to type=search** +- **Found during:** Task 1 (BackendSelectionStep implementation) +- **Issue:** type=text gives role=textbox; existing tests use `getByRole('textbox')` to find the remote name input — adding a second textbox caused 6 tests to fail with "multiple elements found" +- **Fix:** Changed `type="text"` to `type="search"` on the search input (role becomes searchbox, not textbox) +- **Files modified:** src/components/wizard/BackendSelectionStep.tsx +- **Verification:** All 13 existing tests pass after change; 6 new tests also pass +- **Committed in:** 0a70620 (Task 1 commit) + +--- + +**Total deviations:** 1 auto-fixed (Rule 1 - bug causing test failures) +**Impact on plan:** Minimal — single attribute change, semantically correct. No scope creep. + +## Issues Encountered +None beyond the type=text conflict described above. + +## User Setup Required +None - no external service configuration required. + +## Next Phase Readiness +- BackendSelectionStep handles 18 backends with categories and search — ready for any v1.3 release +- Phase 13 all 3 plans complete: registry refactor (13-01), icons+OAuth UI (13-02), categorized selection (13-03) +- No blockers for phase completion + +--- +*Phase: 13-add-remaining-rclone-remotes* +*Completed: 2026-04-01*