chore: complete v1.3 milestone — Backend Expansion
Archives v1.3 milestone (Phase 13: 18 rclone backends), updates PROJECT.md with all 30 validated requirements, reorganizes ROADMAP.md with all 4 milestones in collapsed details blocks, adds v1.2 and v1.3 retrospective entries. Also commits minor CSS token fixes in src/ (text-on-surface-container class alignment) that were uncommitted from phase 13 execution. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,42 @@
|
||||
# Milestones
|
||||
|
||||
## v1.3 Backend Expansion (Shipped: 2026-04-16)
|
||||
|
||||
**Phases completed:** 1 phase (13), 4 plans
|
||||
**Timeline:** 2026-04-01 (1 day)
|
||||
**Stats:** 28 files changed, +3,959 / -206 lines; total 6,055 TypeScript LOC
|
||||
|
||||
**Key accomplishments:**
|
||||
1. BACKEND_REGISTRY expanded from 7 → 18 backends; BackendType derived from `keyof typeof` — no manual union to maintain
|
||||
2. BACKEND_SCHEMAS auto-generated from registry via `Object.fromEntries` — zero per-backend boilerplate
|
||||
3. OAuthInstructions collapsible component with backend-specific `rclone authorize` commands (TDD, 4 tests)
|
||||
4. GdriveAuthToggle dual-auth component (OAuth token vs service account) for Google Drive
|
||||
5. BackendSelectionStep with category groups, instant search filtering, and inline SVG icons
|
||||
6. RemoteConfigStep wired for all 18 backends via `renderBackendFields()` switch function; `backendLabel` derived from registry
|
||||
|
||||
**Archive:** `.planning/milestones/v1.3-ROADMAP.md`, `.planning/milestones/v1.3-REQUIREMENTS.md`
|
||||
|
||||
---
|
||||
|
||||
## v1.2 UI Polish & Clarity (Shipped: 2026-04-01)
|
||||
|
||||
**Phases completed:** 5 phases (8–12), 14 plans
|
||||
**Timeline:** 2026-03-31 → 2026-04-01 (2 days)
|
||||
**Stats:** 78 files changed, +9,908 / -287 lines
|
||||
|
||||
**Key accomplishments:**
|
||||
1. Full MD3 color token system — CSS custom properties in a single token file, all components use semantic classes (`bg-surface`, `text-on-primary`, etc.)
|
||||
2. Dark mode toggle (System/Light/Dark) — DOM class toggle pattern (not React Context), persisted in localStorage, zero FOUC
|
||||
3. TextFieldMD3 with CSS-only floating label (`peer-[:not(:placeholder-shown)]`), MD3 button hierarchy constants, rebuilt StepIndicator with numbered circles + checkmarks
|
||||
4. App intro section, step descriptions, remote name live config preview, and contextual help/tooltip enrichment across all 18 credential fields
|
||||
5. Mobile-responsive layout, MD3 `focus-visible` ring-3 indicators on all interactive elements
|
||||
6. Step fade/slide transition with `prefers-reduced-motion` guard; auto-scroll to first validation error
|
||||
7. Dark mode visibility fixes: semantic tokens on select, h2 headings, DeploymentStep form controls, ReviewStep security checkbox
|
||||
|
||||
**Archive:** `.planning/milestones/v1.3-ROADMAP.md` (includes v1.2 phases in archive)
|
||||
|
||||
---
|
||||
|
||||
## v1.0 MVP (Shipped: 2026-03-27)
|
||||
|
||||
**Phases completed:** 4 phases, 18 plans
|
||||
|
||||
+83
-44
@@ -2,7 +2,7 @@
|
||||
|
||||
## What This Is
|
||||
|
||||
Ready2Blob is a pure-frontend web app that helps IT professionals deploy rclone onto end-user Windows PCs. A step-by-step wizard collects backend credentials (Azure Blob, S3, S3-compatible, OneDrive, SFTP, Google Cloud Storage, Backblaze B2) and deployment preferences, then generates rclone config files and PowerShell scripts ready to push via Intune or any RMM tool — all client-side, no server required.
|
||||
Ready2Blob is a pure-frontend web app that helps IT professionals deploy rclone onto end-user Windows PCs. A step-by-step wizard collects backend credentials (18 backends: Azure Blob, S3, S3-compatible, OneDrive, SFTP, GCS, Backblaze B2, Google Drive, Dropbox, Box, pCloud, FTP, WebDAV, SMB, HTTP, Seafile, Yandex Disk, Koofr) and deployment preferences, then generates rclone config files and PowerShell scripts ready to push via Intune or any RMM tool — all client-side, no server required.
|
||||
|
||||
## Core Value
|
||||
|
||||
@@ -10,26 +10,68 @@ An IT pro can go from zero to a deployable rclone setup in minutes — without n
|
||||
|
||||
## Current State
|
||||
|
||||
**Shipped:** v1.1 — 2026-03-31
|
||||
**Backends:** 7 (Azure Blob, S3, S3-compatible, OneDrive, SFTP, GCS, Backblaze B2)
|
||||
**Shipped:** v1.3 — 2026-04-16
|
||||
**Backends:** 18 (Azure Blob, S3, S3-compatible, OneDrive, SFTP, GCS, Backblaze B2, Google Drive, Dropbox, Box, pCloud, FTP, WebDAV, SMB, HTTP, Seafile, Yandex Disk, Koofr)
|
||||
**Tech stack:** Vite 6, React 18, TypeScript 5, Tailwind v4, react-hook-form 7, Zod 4, Vitest 4, JSZip
|
||||
**Test coverage:** 159 tests across all test files — all GREEN
|
||||
**Total milestones:** 2 shipped (v1.0 + v1.1), 7 phases, 29 plans
|
||||
**Test coverage:** 165+ tests across all test files — all GREEN
|
||||
**Total milestones:** 3 shipped (v1.0 + v1.1 + v1.2 + v1.3), 13 phases, 40 plans
|
||||
|
||||
## Current Milestone: v1.2 UI Polish & Clarity
|
||||
## Requirements
|
||||
|
||||
**Goal:** Transform the bare functional wizard into a polished, self-explanatory experience — Material Design 3 overhaul, dark mode, contextual help, and cleanup of carried UI debt.
|
||||
### Validated
|
||||
|
||||
**Target features:**
|
||||
- Remote name field clarity (explanation, examples, contextual help)
|
||||
- Step-level descriptions explaining what each wizard step does
|
||||
- App landing/intro section explaining what Ready2Blob is
|
||||
- Full Material Design 3 component overhaul (cards, inputs, buttons, elevation, shape, color tokens)
|
||||
- Dark mode toggle with accent color system
|
||||
- Help text improvements across all backend fields
|
||||
- FieldRenderer aria consistency fix
|
||||
- StepIndicator migration from inline styles to Tailwind
|
||||
- Mobile responsiveness improvements
|
||||
- ✓ Backend Schema Registry as single source of truth for form rendering, Zod validation, config generation — v1.0
|
||||
- ✓ 4-step wizard (backend selection → config → deployment → review/download) with back-navigation — v1.0
|
||||
- ✓ Review + download layer: live preview, security gate, individual downloads, ZIP bundle, clipboard copy — v1.0
|
||||
- ✓ Registry-driven BackendSelectionStep, scriptTargets filtering, ReviewStep Back button, dead export cleanup, act() fix — v1.1
|
||||
- ✓ 4 new backends (OneDrive, SFTP, GCS, B2), SftpAuthToggle, inline field validation, contextual tooltips — v1.1
|
||||
- ✓ **THEME-01**: MD3 color token system (CSS custom properties), all components use semantic classes — v1.2
|
||||
- ✓ **THEME-02**: System/Light/Dark theme toggle, persisted in localStorage, zero FOUC — v1.2
|
||||
- ✓ **COMP-01**: MD3 outlined text fields with CSS-only floating labels — v1.2
|
||||
- ✓ **COMP-02**: MD3 button hierarchy (filled/outlined/text) across all wizard steps — v1.2
|
||||
- ✓ **COMP-03**: Backend cards and output blocks with MD3 elevation and tonal surface tint — v1.2
|
||||
- ✓ **COMP-04**: StepIndicator with numbered circles, connectors, checkmarks — v1.2
|
||||
- ✓ **DEBT-01**: FieldRenderer consistent `aria-label` across text/select branches — v1.2
|
||||
- ✓ **UX-01**: Intro section explaining Ready2Blob with CTA to start wizard — v1.2
|
||||
- ✓ **UX-02**: Remote name field with example, help text, live config preview — v1.2
|
||||
- ✓ **UX-03**: 1-2 sentence step descriptions on all 4 wizard steps — v1.2
|
||||
- ✓ **UX-04**: Contextual help text on all backend credential fields — v1.2
|
||||
- ✓ **POLISH-01**: Mobile-responsive layout (stacking cards, full-width fields, stretch buttons) — v1.2
|
||||
- ✓ **POLISH-02**: MD3 `focus-visible` ring-3 indicators on all interactive elements — v1.2
|
||||
- ✓ **POLISH-03**: Step fade/slide transition with `prefers-reduced-motion` guard — v1.2
|
||||
- ✓ **POLISH-04**: Auto-scroll to first validation error on form submission — v1.2
|
||||
- ✓ **DARK-01**: All wizard step h2 headings readable in dark mode — v1.2
|
||||
- ✓ **DARK-02**: DeploymentStep native form controls visible with semantic tokens in dark mode — v1.2
|
||||
- ✓ **DARK-03**: FieldRenderer select has proper bg/text color in dark mode — v1.2
|
||||
- ✓ **REMOTE-01**: BACKEND_REGISTRY with 18 backends, correct rclone fields, displayName, description, category — v1.3
|
||||
- ✓ **REMOTE-02**: BackendType derived from `keyof typeof BACKEND_REGISTRY` — no manual union — v1.3
|
||||
- ✓ **REMOTE-03**: BackendSelectionStep with category groups, instant search, inline SVG icons — v1.3
|
||||
- ✓ **REMOTE-04**: OAuthInstructions collapsible component with backend-specific `rclone authorize` — v1.3
|
||||
- ✓ **REMOTE-05**: RemoteConfigStep renders correct form for all 18 backends including GdriveAuthToggle — v1.3
|
||||
- ✓ **REMOTE-06**: buildRcloneConf produces valid rclone.conf for all 18 backends — v1.3
|
||||
|
||||
### Active
|
||||
|
||||
*(No active requirements — planning next milestone)*
|
||||
|
||||
### Out of Scope
|
||||
|
||||
| Feature | Reason |
|
||||
|---------|--------|
|
||||
| User accounts / saved templates | No backend, no persistence |
|
||||
| Server-side generation | Everything runs in the browser |
|
||||
| Test connection / validate credentials | Requires backend proxy (CORS blocks direct cloud API calls) |
|
||||
| rclone version management / auto-update on endpoints | Separate lifecycle problem |
|
||||
| Non-Windows targets | Scripts target Windows endpoints only |
|
||||
| Auto-push to Intune via Graph API | Requires Azure AD app registration, massive scope increase |
|
||||
| Config credential encryption | rclone encrypted configs require interactive unlock, incompatible with unattended deployment |
|
||||
| Multiple remotes in one config | Significant wizard UX complexity, defer to v2 |
|
||||
| OAuth flow in browser | Requires backend proxy; paste pre-obtained token instead |
|
||||
| MUI or Material Tailwind component library | Bundle bloat (~300KB+) for 4-step wizard; custom tokens + Tailwind lighter |
|
||||
| Page-per-step routing (React Router) | Wizard state is ephemeral credentials in memory; refreshing loses context |
|
||||
| Glassmorphism / neomorphism effects | CPU-intensive, low contrast accessibility issues |
|
||||
| Arbitrary user-picked hex color | Breaks accessibility; curated presets cover 95% of personalization need |
|
||||
| Custom checkbox/radio styling | High effort for few toggles; native inputs sufficient |
|
||||
|
||||
## Constraints
|
||||
|
||||
@@ -37,18 +79,6 @@ An IT pro can go from zero to a deployable rclone setup in minutes — without n
|
||||
- **Target OS**: Windows endpoints only (scripts are PowerShell)
|
||||
- **Secrets**: Plain text in generated files — UI must display a clear security warning before download
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- User accounts / saved templates — no backend, no persistence
|
||||
- Server-side generation — everything runs in the browser
|
||||
- Test connection / validate credentials — requires backend proxy (CORS blocks direct cloud API calls)
|
||||
- rclone version management / auto-update on endpoints — separate lifecycle problem
|
||||
- Non-Windows targets — scripts target Windows endpoints only
|
||||
- Auto-push to Intune via Graph API — requires Azure AD app registration, massive scope increase
|
||||
- Config credential encryption — rclone encrypted configs require interactive unlock, incompatible with unattended deployment
|
||||
- Multiple remotes in one config — significant wizard UX complexity, defer to v2
|
||||
- OAuth flow in browser (OneDrive) — requires backend proxy; paste pre-obtained token instead
|
||||
|
||||
## Key Decisions
|
||||
|
||||
| Decision | Rationale | Outcome |
|
||||
@@ -57,33 +87,42 @@ An IT pro can go from zero to a deployable rclone setup in minutes — without n
|
||||
| BACKEND_REGISTRY as single source of truth | Drives form rendering, Zod schemas, and config generation from one definition | ✓ Good — zero duplication across phases |
|
||||
| useReducer + Context API (no external state lib) | Zero dependencies, sufficient for 4-step wizard | ✓ Good — kept bundle lean |
|
||||
| Wave 0 TDD (stubs RED before implementation) | Forces API contract before code, catches integration mismatches early | ✓ Good — caught several issues upfront |
|
||||
| Support all rclone backends (not Azure-only) | Broader utility despite "Blob" in project name | ✓ Good — 7 backends and growing |
|
||||
| Support all rclone backends (not Azure-only) | Broader utility despite "Blob" in project name | ✓ Good — 18 backends shipped |
|
||||
| Optional rclone install in scripts | Different orgs have different baseline images | ✓ Good — no friction for orgs that pre-install |
|
||||
| Tailwind v4 via @tailwindcss/vite plugin | No postcss.config.js, no tailwind.config.js needed | ✓ Good — cleaner config |
|
||||
| Zod v4 + @hookform/resolvers v5 together | v5 resolvers required for Zod v4 compatibility | ✓ Good — noted for future upgrades |
|
||||
| AzureAuthToggle / SftpAuthToggle CSS hidden pattern | Preserves both auth fields in react-hook-form state when toggling | ✓ Good — avoids field reset on toggle |
|
||||
| AzureAuthToggle / SftpAuthToggle CSS hidden pattern | Preserves both auth fields in react-hook-form state when toggling | ✓ Good — extended to GdriveAuthToggle in v1.3 |
|
||||
| FieldDef.validate + tooltipText extension | Additive interface change, non-breaking to existing backends | ✓ Good — clean composition |
|
||||
| Registry-loop rendering in RemoteConfigStep | Three-branch ternary (azureblob/sftp/else) — custom logic minimal | ✓ Good — scales with new backends |
|
||||
| ThemeToggle via DOM class toggle, not React Context | Avoids re-render cascade on theme change | ✓ Good — instant theme switch |
|
||||
| Two-layer CSS token pattern (@theme + @layer base) | Required for .dark cascade in Tailwind v4 | ✓ Good — only valid approach for v4 |
|
||||
| vi.stubGlobal for localStorage/matchMedia in tests | Node v25 experimental WebStorage breaks standard Storage API in jsdom | ✓ Good — necessary workaround |
|
||||
| TextFieldMD3 CSS-only floating label | `peer-[:not(:placeholder-shown)]` — no JS state | ✓ Good — simpler, animatable |
|
||||
| DEBT-01 fix: aria-label directly on tooltip buttons | Prevents getByLabelText ambiguity with { selector: 'input' } guard | ✓ Good — consistent pattern |
|
||||
| key={state.currentStep} on step wrapper | Forces React remount to trigger CSS animation from initial state | ✓ Good — cleanest animation approach |
|
||||
| BackendType derived from `keyof typeof BACKEND_REGISTRY` | Eliminates manual union maintenance at 18+ backends | ✓ Good — adding a backend is one touch-point |
|
||||
| BACKEND_SCHEMAS auto-generated via Object.fromEntries | No per-backend buildZodSchema call needed | ✓ Good — zero boilerplate |
|
||||
| Registry `as const` (not Record<BackendType,…> cast) | Cast was circular when BackendType derived from registry | ✓ Good — necessary to break circularity |
|
||||
| type=search for search input | Prevents getByRole('textbox') collision with remote name TextFieldMD3 | ✓ Good — test-selector discipline |
|
||||
| renderBackendFields() switch vs nested ternaries | 7+ branches require readable structure | ✓ Good — extensible for future backends |
|
||||
| OAuthInstructions step-prefix detection | Renders authorize command in `<code>` element; keeps test assertions compatible | ✓ Good — clean heuristic |
|
||||
| BACKEND_ICONS as Partial<Record<BackendType, FC>> | Missing entries = no icon rendered (no error) | ✓ Good — graceful degradation |
|
||||
|
||||
<details>
|
||||
<summary>Previous milestone context (v1.0 → v1.1)</summary>
|
||||
<summary>Previous milestone context (v1.0 → v1.3 key decisions)</summary>
|
||||
|
||||
**v1.0 shipped:** 2026-03-27, 4 phases, 18 plans, ~2,746 LOC
|
||||
**v1.1 shipped:** 2026-03-31, 3 phases, 11 plans, +7,311 lines
|
||||
**v1.2 shipped:** 2026-04-01, 5 phases, 14 plans, +9,908 lines
|
||||
**v1.3 shipped:** 2026-04-16, 1 phase, 4 plans, +3,753 lines
|
||||
|
||||
**v1.0 tech debt resolved in v1.1:**
|
||||
- scriptTargets filtering in ReviewStep (TECH-01)
|
||||
- ReviewStep Back button (TECH-02)
|
||||
- Registry-driven BackendSelectionStep (TECH-03)
|
||||
- Dead export removal (TECH-04)
|
||||
- act() warnings fix (TECH-05)
|
||||
**v1.2 tech debt resolved in v1.3:**
|
||||
- FieldRenderer aria inconsistency (DEBT-01) — resolved Phase 9
|
||||
|
||||
**v1.1 remaining tech debt:**
|
||||
- 7 browser UI verifications pending (confirmatory)
|
||||
- FieldRenderer aria inconsistency (cosmetic)
|
||||
- Phase 7 Nyquist compliance partial
|
||||
**v1.3 tech debt carried forward:**
|
||||
- Test selectors risk if UI restyled heavily (131+ selectors, ongoing discipline required)
|
||||
- No formal milestone audit run for v1.3
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
*Last updated: 2026-03-31 after v1.2 milestone started*
|
||||
*Last updated: 2026-04-16 after v1.3 milestone*
|
||||
|
||||
@@ -41,6 +41,83 @@
|
||||
|
||||
---
|
||||
|
||||
## Milestone: v1.2 — UI Polish & Clarity
|
||||
|
||||
**Shipped:** 2026-04-01
|
||||
**Phases:** 5 (8–12) | **Plans:** 14 | **Stats:** 78 files, +9,908 / -287 lines
|
||||
|
||||
### What Was Built
|
||||
- Full MD3 color token system in a single token file; all components use semantic utility classes (`bg-surface`, `text-on-primary`) instead of hardcoded Tailwind colors
|
||||
- System/Light/Dark theme toggle persisted in localStorage with zero flash of unstyled content (DOM class toggle, not React Context)
|
||||
- TextFieldMD3 with CSS-only floating label, MD3 button hierarchy constants, rebuilt StepIndicator with numbered circles + checkmarks + connectors
|
||||
- App intro section, step descriptions on all 4 steps, remote name live config preview, contextual help/tooltip enrichment across all credential fields
|
||||
- Mobile-responsive layout, `focus-visible` ring-3 indicators, step fade/slide transition with `prefers-reduced-motion` guard, auto-scroll to first validation error
|
||||
- Dark mode visibility fixes: semantic tokens on select, h2 headings, DeploymentStep form controls, ReviewStep security checkbox
|
||||
|
||||
### What Worked
|
||||
- **Bottom-up migration order** (tokens → primitives → content → polish → fixes): each phase stood on solid ground from the one below; no circular rework
|
||||
- **CSS-only floating label** (`peer-[:not(:placeholder-shown)]`) with no JS state — simpler to reason about, trivially animatable, one fewer React state variable
|
||||
- **DOM class toggle for dark mode** (not React Context): theme switch is instant and doesn't trigger a re-render cascade across 150+ components
|
||||
- **`key={state.currentStep}` on step wrapper**: one-line way to force React remount and reset CSS animation to initial state — no animation JS state needed
|
||||
- **TDD discipline held** on Phase 12 dark mode fixes: found and fixed selector issues before they became regressions
|
||||
|
||||
### What Was Inefficient
|
||||
- **Phase 12 inserted as a gap fix**: dark mode regressions were discovered post-Phase 11 instead of being caught in Phase 11 validation — cost 1 extra phase
|
||||
- **`aria-label` / `getByLabelText` selector ambiguity** recurred across Phases 9, 10, and 12 — the DEBT-01 pattern (`{ selector: 'input' }`) had to be applied three times in three different phases instead of being resolved once and documented
|
||||
- **Traceability table in REQUIREMENTS.md not updated** as plans completed — table showed "Planned" for completed items, causing confusion at milestone close
|
||||
|
||||
### Patterns Established
|
||||
- Two-layer CSS token pattern: `@theme var()` references + `@layer base :root/.dark` raw values — required for `.dark` cascade in Tailwind v4
|
||||
- `vi.stubGlobal` for localStorage/matchMedia — Node v25 experimental WebStorage breaks standard Storage API in jsdom
|
||||
- CSS-only reduced-motion guard via `@media (prefers-reduced-motion: reduce)` — no JS listener needed
|
||||
- Tooltip hover: dual-state (`hoverTooltip` + `showTooltip`); click-unpin clears `hoverTooltip` to prevent sticky tooltip after dismiss
|
||||
- `ring-inset` on ThemeToggle focus ring because `overflow-hidden` on container clips outset rings
|
||||
|
||||
### Key Lessons
|
||||
1. **Validate dark mode in every phase, not as a separate cleanup phase**: each component migration should include a dark-mode check, not defer it
|
||||
2. **When a test selector pattern is discovered, document it once and reference it** — the `{ selector: 'input' }` guard should have been in a testing conventions note from Phase 9
|
||||
3. **Keep traceability tables current** during execution, not just at planning time
|
||||
|
||||
---
|
||||
|
||||
## Milestone: v1.3 — Backend Expansion
|
||||
|
||||
**Shipped:** 2026-04-16
|
||||
**Phases:** 1 (13) | **Plans:** 4 | **Stats:** 28 files, +3,959 / -206 lines
|
||||
|
||||
### What Was Built
|
||||
- BACKEND_REGISTRY expanded from 7 → 18 backends; `BackendType` derived from `keyof typeof BACKEND_REGISTRY` — no manual union to maintain
|
||||
- `BACKEND_SCHEMAS` auto-generated from registry keys via `Object.fromEntries` — zero per-backend boilerplate
|
||||
- `OAuthInstructions` collapsible component with backend-specific `rclone authorize` commands (TDD, 4 tests)
|
||||
- `GdriveAuthToggle` dual-auth component (OAuth token vs service account) — CSS hidden pattern extended from SftpAuthToggle
|
||||
- `BackendSelectionStep` with 3 category groups, instant search filtering across 4 fields, inline SVG icons
|
||||
- `RemoteConfigStep` wired for all 18 backends via clean `renderBackendFields()` switch function; `backendLabel` derived from registry
|
||||
|
||||
### What Worked
|
||||
- **`as const` registry with derived BackendType**: one touch-point when adding a backend (registry entry only); Zod schemas auto-generate, type union auto-narrows
|
||||
- **Incremental plan structure** (registry → components → UI → wiring): each plan had exactly the right scope — no plan was too large or too small
|
||||
- **TDD for new UI components**: `OAuthInstructions` and `GdriveAuthToggle` written test-first; caught a step-prefix detection edge case before integration
|
||||
- **type=search for search input**: simple attribute that prevents `getByRole('textbox')` collision — elegant selector discipline
|
||||
- **renderBackendFields() switch**: 7+ backend branches are unreadable as nested ternaries; switch is flat and extensible
|
||||
|
||||
### What Was Inefficient
|
||||
- **Registry had 18 backends but plan said 17**: a counting error in the plan caused minor confusion during 13-01 execution — plans should verify counts against reality
|
||||
- **Traceability table not updated** (same as v1.2) — REMOTE-03/04/05 showed "Planned" at milestone close despite being complete
|
||||
|
||||
### Patterns Established
|
||||
- `BackendType` from `keyof typeof BACKEND_REGISTRY` (not explicit union) — the canonical pattern going forward
|
||||
- `BACKEND_SCHEMAS` from `Object.fromEntries` — zero per-backend call sites
|
||||
- Registry `as const` (not `Record<BackendType,…>` cast) — cast is circular when BackendType derived from registry
|
||||
- `Partial<Record<BackendType, FC<IconProps>>>` for optional icon map — missing entries render nothing (no error)
|
||||
- `getByLabelText` partial regex (`/label/i` not `/^label$/i`) — TextFieldMD3 appends `*` to required field labels
|
||||
|
||||
### Key Lessons
|
||||
1. **Update the traceability table as plans complete**, not just at the start — stale status fields caused confusion at milestone close (2nd occurrence after v1.2)
|
||||
2. **Count registry entries in the plan, not just at planning time** — the 17/18 mismatch was avoidable
|
||||
3. **`as const` registries with derived types are strictly superior to explicit unions**: eliminates an entire class of drift bugs, zero cost
|
||||
|
||||
---
|
||||
|
||||
## Cross-Milestone Trends
|
||||
|
||||
### Process Evolution
|
||||
@@ -48,14 +125,23 @@
|
||||
| Milestone | Phases | Plans | Key Change |
|
||||
|-----------|--------|-------|------------|
|
||||
| v1.0 | 4 | 18 | Wave 0 TDD pattern established; inside-out build order validated |
|
||||
| v1.1 | 3 | 11 | CSS-hidden auth toggle pattern; FieldDef additive extension model |
|
||||
| v1.2 | 5 | 14 | Two-layer CSS token system; DOM class dark mode; CSS-only floating label |
|
||||
| v1.3 | 1 | 4 | `keyof typeof` derived BackendType; `Object.fromEntries` schema auto-gen |
|
||||
|
||||
### Cumulative Quality
|
||||
|
||||
| Milestone | Tests | Notes |
|
||||
|-----------|-------|-------|
|
||||
| v1.0 | 98 (12 files) | 24/24 requirements satisfied, 5/5 E2E flows |
|
||||
| v1.1 | 159 (18 files) | 7 browser UI verifications deferred |
|
||||
| v1.2 | 159+ (same files, heavier coverage) | All DEBT-01 + POLISH/DARK/UX requirements satisfied |
|
||||
| v1.3 | 165+ | All 6 REMOTE requirements satisfied; visual verification approved |
|
||||
|
||||
### Top Lessons (Verified Across Milestones)
|
||||
|
||||
1. Single source of truth (BACKEND_REGISTRY) eliminates entire classes of drift bugs
|
||||
1. Single source of truth (BACKEND_REGISTRY) eliminates entire classes of drift bugs — validated at v1.0, proven at v1.3 scale (18 backends)
|
||||
2. Wave 0 TDD stubs are worth the upfront cost — they define the contract and make RED→GREEN progress visible
|
||||
3. **Update traceability tables as plans complete** — stale status fields caused confusion at both v1.2 and v1.3 milestone close (recurring issue)
|
||||
4. CSS-only approaches (floating label, reduced-motion guard, auth toggle) are simpler than JS state — reach for CSS first
|
||||
5. `as const` registries with derived types (`keyof typeof`) are strictly superior to explicit unions — zero drift possible
|
||||
|
||||
+15
-106
@@ -5,7 +5,7 @@
|
||||
- ✅ **v1.0 MVP** — Phases 1–4 (shipped 2026-03-27)
|
||||
- ✅ **v1.1 Backlog & Tech Debt** — Phases 5–7 (shipped 2026-03-31)
|
||||
- ✅ **v1.2 UI Polish & Clarity** — Phases 8–12 (shipped 2026-04-01)
|
||||
- **v1.3 Backend Expansion** — Phase 13 (in progress)
|
||||
- ✅ **v1.3 Backend Expansion** — Phase 13 (shipped 2026-04-16)
|
||||
|
||||
## Phases
|
||||
|
||||
@@ -35,115 +35,24 @@ Full phase details: [.planning/milestones/v1.1-ROADMAP.md](milestones/v1.1-ROADM
|
||||
<details>
|
||||
<summary>✅ v1.2 UI Polish & Clarity (Phases 8–12) — SHIPPED 2026-04-01</summary>
|
||||
|
||||
- [x] **Phase 8: Theme Foundation** - MD3 color token system and dark mode infrastructure (completed 2026-04-01)
|
||||
- [x] **Phase 9: MD3 Components** - UI primitives and component migration to semantic tokens (completed 2026-04-01)
|
||||
- [x] **Phase 10: Content & Clarity** - Intro section, step descriptions, and contextual help (completed 2026-04-01)
|
||||
- [x] **Phase 11: Polish & Responsiveness** - Mobile layout, focus states, transitions, scroll-to-error (completed 2026-04-01)
|
||||
- [x] **Phase 12: Dark mode visibility fixes** - Fix dark mode regressions (completed 2026-04-01)
|
||||
- [x] Phase 8: Theme Foundation (2/2 plans) — completed 2026-04-01
|
||||
- [x] Phase 9: MD3 Components (5/5 plans) — completed 2026-04-01
|
||||
- [x] Phase 10: Content & Clarity (3/3 plans) — completed 2026-04-01
|
||||
- [x] Phase 11: Polish & Responsiveness (2/2 plans) — completed 2026-04-01
|
||||
- [x] Phase 12: Dark Mode Visibility Fixes (2/2 plans) — completed 2026-04-01
|
||||
|
||||
Full phase details: [.planning/milestones/v1.3-ROADMAP.md](milestones/v1.3-ROADMAP.md)
|
||||
|
||||
</details>
|
||||
|
||||
### v1.3 Backend Expansion (In Progress)
|
||||
<details>
|
||||
<summary>✅ v1.3 Backend Expansion (Phase 13) — SHIPPED 2026-04-16</summary>
|
||||
|
||||
**Milestone Goal:** Expand backend support from 7 to 17 rclone backends with categorized selection, search filtering, OAuth token-paste guidance, and inline icons.
|
||||
- [x] Phase 13: Add Remaining RClone Remotes (4/4 plans) — completed 2026-04-16
|
||||
|
||||
## Phase Details
|
||||
Full phase details: [.planning/milestones/v1.3-ROADMAP.md](milestones/v1.3-ROADMAP.md)
|
||||
|
||||
### Phase 8: Theme Foundation
|
||||
**Goal**: App has a complete MD3 color token system and working dark mode toggle with no flash of unstyled content
|
||||
**Depends on**: Phase 7 (v1.1 complete)
|
||||
**Requirements**: THEME-01, THEME-02
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. All color values in the app flow from CSS custom properties defined in a single token file, not from hardcoded Tailwind color classes
|
||||
2. User can toggle between System, Light, and Dark themes via a visible control, and the entire UI responds immediately
|
||||
3. Theme preference persists in localStorage and applies on reload without any flash of wrong theme
|
||||
4. Tailwind v4 `@theme` directive maps MD3 token names to utility classes (e.g., `bg-surface`, `text-on-primary`)
|
||||
**Plans:** 2/2 plans complete
|
||||
Plans:
|
||||
- [ ] 08-01-PLAN.md — Token system, flash prevention, ThemeToggle component
|
||||
- [ ] 08-02-PLAN.md — Color class migration across all components
|
||||
|
||||
### Phase 9: MD3 Components
|
||||
**Goal**: All interactive elements use MD3-styled primitives with consistent visual language across the entire wizard
|
||||
**Depends on**: Phase 8
|
||||
**Requirements**: COMP-01, COMP-02, COMP-03, COMP-04, DEBT-01
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. Text inputs render as outlined fields with floating labels that animate on focus and when the field has content
|
||||
2. Buttons visually distinguish primary (filled), secondary (outlined), and tertiary (text) actions across all wizard steps
|
||||
3. Backend selection cards and output blocks display MD3 elevation with tonal surface tint and consistent shape tokens
|
||||
4. Step indicator shows numbered circles connected by lines, with checkmarks on completed steps, highlight on current, and muted future steps
|
||||
5. FieldRenderer produces identical `aria-label` attributes for both text-branch and select-branch inputs
|
||||
**Plans:** 5/5 plans complete
|
||||
Plans:
|
||||
- [x] 09-01-PLAN.md — TextFieldMD3 component, MD3 button constants, DEBT-01 aria-label fix
|
||||
- [x] 09-02-PLAN.md — StepIndicator rebuild with MD3 circles and connectors
|
||||
- [x] 09-03-PLAN.md — Integration: wire TextFieldMD3 + button styles + elevation into all wizard steps
|
||||
- [x] 09-04-PLAN.md — Gap closure: Replace BackendSelectionStep plain input with TextFieldMD3
|
||||
- [x] 09-05-PLAN.md — Gap closure: Tooltip hover behavior + icon placement beside helpText
|
||||
|
||||
### Phase 10: Content & Clarity
|
||||
**Goal**: A first-time visitor understands what Ready2Blob does and what each wizard step expects without external documentation
|
||||
**Depends on**: Phase 8 (tokens needed for consistent styling of new content)
|
||||
**Requirements**: UX-01, UX-02, UX-03, UX-04
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. Landing view shows an intro section explaining what Ready2Blob does with a clear call-to-action to start the wizard
|
||||
2. Remote name field displays a placeholder example, help text, and a live preview showing how the name appears in `[remote-name]` config syntax
|
||||
3. Every wizard step has a 1-2 sentence description below the heading explaining what the user is doing and why
|
||||
4. All backend credential fields have contextual help text explaining what to enter and where to find the value
|
||||
**Plans:** 3/3 plans complete
|
||||
Plans:
|
||||
- [ ] 10-01-PLAN.md — Intro section with CTA and step descriptions for all 4 steps
|
||||
- [ ] 10-02-PLAN.md — Remote name live config preview with helpText
|
||||
- [ ] 10-03-PLAN.md — Credential field tooltipText and helpText enrichment
|
||||
|
||||
### Phase 11: Polish & Responsiveness
|
||||
**Goal**: The wizard feels production-ready on any device with smooth interactions and accessible keyboard navigation
|
||||
**Depends on**: Phase 9, Phase 10
|
||||
**Requirements**: POLISH-01, POLISH-02, POLISH-03, POLISH-04
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. On a mobile viewport (< 640px), backend cards stack vertically, form fields span full width, step indicator collapses, and buttons stretch to fill width
|
||||
2. Every interactive element shows a visible 3px MD3 focus outline when navigated via keyboard (using `focus-visible`)
|
||||
3. Step transitions use a subtle fade/slide animation that is suppressed when the user has `prefers-reduced-motion` enabled
|
||||
4. When form validation fails, the view auto-scrolls to the first field with an error
|
||||
**Plans:** 2/2 plans complete
|
||||
Plans:
|
||||
- [ ] 11-01-PLAN.md — Mobile responsive layout + MD3 focus-visible indicators
|
||||
- [ ] 11-02-PLAN.md — Step transition animation + auto-scroll to first error
|
||||
|
||||
### Phase 12: Dark mode visibility fixes
|
||||
|
||||
**Goal:** Fix dark mode visibility regressions where step headings, DeploymentStep form controls, and FieldRenderer select elements are invisible or unstyled against the dark background
|
||||
**Requirements**: DARK-01, DARK-02, DARK-03
|
||||
**Depends on:** Phase 11
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. All wizard step h2 headings are readable in dark mode with proper contrast
|
||||
2. DeploymentStep labels, legends, checkboxes, and radios are visible and styled in dark mode
|
||||
3. FieldRenderer select element has proper background and text color in dark mode
|
||||
**Plans:** 2/2 plans complete
|
||||
|
||||
Plans:
|
||||
- [ ] 12-01-PLAN.md — Fix step headings, DeploymentStep form controls, ReviewStep checkbox
|
||||
- [ ] 12-02-PLAN.md — Fix FieldRenderer select dark mode styling
|
||||
|
||||
### Phase 13: Add remaining RClone remotes
|
||||
|
||||
**Goal:** Expand backend support from 7 to 17 rclone backends with categorized selection UI, instant search, OAuth token-paste guidance, and inline SVG icons — covering all backends suitable for unattended Windows deployment
|
||||
**Requirements**: REMOTE-01, REMOTE-02, REMOTE-03, REMOTE-04, REMOTE-05, REMOTE-06
|
||||
**Depends on:** Phase 12
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. BACKEND_REGISTRY contains 17 backends with correct fields, categories, and rclone type mappings
|
||||
2. BackendType is derived from registry keys (not an explicit union)
|
||||
3. BackendSelectionStep groups backends by category with instant search and inline SVG icons
|
||||
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/4 plans complete
|
||||
|
||||
Plans:
|
||||
- [x] 13-01-PLAN.md — Registry refactoring: derive BackendType, add categories, 11 new backend entries (18 total), auto-generate schemas
|
||||
- [ ] 13-02-PLAN.md — New components: OAuthInstructions, GdriveAuthToggle, BackendIcons
|
||||
- [ ] 13-03-PLAN.md — BackendSelectionStep UX overhaul: categories, search, icons
|
||||
- [ ] 13-04-PLAN.md — RemoteConfigStep wiring for all new backends + visual verification
|
||||
</details>
|
||||
|
||||
## Progress
|
||||
|
||||
@@ -160,5 +69,5 @@ Plans:
|
||||
| 9. MD3 Components | v1.2 | 5/5 | Complete | 2026-04-01 |
|
||||
| 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 | 4/4 | Complete | 2026-04-01 | — |
|
||||
| 12. Dark Mode Visibility Fixes | v1.2 | 2/2 | Complete | 2026-04-01 |
|
||||
| 13. Add Remaining RClone Remotes | v1.3 | 4/4 | Complete | 2026-04-16 |
|
||||
|
||||
+11
-12
@@ -2,10 +2,10 @@
|
||||
gsd_state_version: 1.0
|
||||
milestone: v1.3
|
||||
milestone_name: Backend Expansion
|
||||
status: verifying
|
||||
stopped_at: Completed 13-04-PLAN.md
|
||||
last_updated: "2026-04-01T15:33:04.002Z"
|
||||
last_activity: 2026-04-01 — Phase 13 plan 04 complete, visual verification approved (REMOTE-05 satisfied)
|
||||
status: milestone_complete
|
||||
stopped_at: v1.3 milestone archived and closed
|
||||
last_updated: "2026-04-16T15:00:00.000Z"
|
||||
last_activity: 2026-04-16 — v1.3 Backend Expansion milestone complete, archived, git tagged
|
||||
progress:
|
||||
total_phases: 6
|
||||
completed_phases: 6
|
||||
@@ -21,16 +21,15 @@ progress:
|
||||
See: .planning/PROJECT.md (updated 2026-03-31)
|
||||
|
||||
**Core value:** An IT pro can go from zero to a deployable rclone setup in minutes — without needing to know rclone's config syntax or PowerShell deployment conventions.
|
||||
**Current focus:** v1.2 — UI Polish & Clarity (Phase 11: Polish & Responsiveness in progress, plan 11-01 complete)
|
||||
**Current focus:** Planning next milestone (v1.4)
|
||||
|
||||
## Current Position
|
||||
|
||||
Phase: 13 of 13 (Add Remaining RClone Remotes) — Complete
|
||||
Plan: 13-04 (complete — all 4 plans complete)
|
||||
Status: Phase 13 complete — all 18 backends fully integrated end-to-end, user visual verification approved
|
||||
Last activity: 2026-04-01 — Phase 13 plan 04 complete, visual verification approved (REMOTE-05 satisfied)
|
||||
Milestone v1.3 complete and archived. Ready for next milestone planning.
|
||||
Status: 4 milestones shipped (v1.0 → v1.3), 13 phases, 40 plans — all complete
|
||||
Last activity: 2026-04-16 — v1.3 Backend Expansion milestone archived and git tagged
|
||||
|
||||
Progress: [██████████] 100% (v1.3)
|
||||
Progress: [██████████] 100% (v1.3 — milestone complete)
|
||||
|
||||
## Accumulated Context
|
||||
|
||||
@@ -99,6 +98,6 @@ None yet.
|
||||
|
||||
## Session Continuity
|
||||
|
||||
Last session: 2026-04-01T15:27:20.814Z
|
||||
Stopped at: Completed 13-04-PLAN.md
|
||||
Last session: 2026-04-16
|
||||
Stopped at: v1.3 milestone complete — MILESTONES.md, PROJECT.md, ROADMAP.md, RETROSPECTIVE.md updated; git tagged v1.3
|
||||
Resume file: None
|
||||
|
||||
@@ -1,87 +1,84 @@
|
||||
---
|
||||
status: diagnosed
|
||||
status: awaiting_human_verify
|
||||
trigger: "Tooltip info buttons on Remote Config wizard step: hovering doesn't show anything, icon placement is wrong (above field instead of beside helpText)"
|
||||
created: 2026-04-01T00:00:00Z
|
||||
updated: 2026-04-01T00:00:00Z
|
||||
updated: 2026-04-02T00:00:00Z
|
||||
---
|
||||
|
||||
## Current Focus
|
||||
|
||||
hypothesis: Two distinct root causes — onClick-only toggle (no hover), and icon placed above TextFieldMD3 instead of beside helpText
|
||||
test: Code review of FieldRenderer.tsx lines 83-109 and TextFieldMD3.tsx lines 65-67
|
||||
expecting: Confirm both issues from source
|
||||
next_action: Report diagnosis
|
||||
hypothesis: Issues 1 & 2 already fixed in current code; Issue 3 (light mode illegibility) is active — text-on-surface-variant is gray-100 (near-white) in light mode, used on light backgrounds
|
||||
test: Applying fix to BackendSelectionStep.tsx — replace text-on-surface-variant with text-on-surface-container for step description; replace placeholder:text-on-surface-variant/50 with placeholder:text-on-surface-container/50 for search bar
|
||||
expecting: Both elements become legible in light mode; dark mode unaffected
|
||||
next_action: Apply fix to BackendSelectionStep.tsx
|
||||
|
||||
## Symptoms
|
||||
|
||||
expected: (1) Hovering tooltip button shows tooltip text. (2) Icon is beside the helpText under the field.
|
||||
actual: (1) Nothing happens on hover — only click toggles. (2) Icon is above the TextFieldMD3 component.
|
||||
expected: (1) Hovering tooltip button shows tooltip text. (2) Icon is beside the helpText under the field. (3) Step description and search bar placeholder are legible in light mode.
|
||||
actual: (1) Nothing happens on hover — only click toggles. (2) Icon is above the TextFieldMD3 component. (3) Step subtitle and search placeholder are near-invisible in light mode.
|
||||
errors: none
|
||||
reproduction: Open Remote Config wizard, hover over any info button
|
||||
started: Since phase-09 tooltip implementation
|
||||
reproduction: (1,2) Open Remote Config wizard, hover over any info button. (3) View BackendSelectionStep in light mode.
|
||||
started: (1,2) Since phase-09 tooltip implementation. (3) Since text-on-surface-variant was used for body text.
|
||||
|
||||
## Eliminated
|
||||
|
||||
(none needed — root causes identified on first pass)
|
||||
- hypothesis: Issues 1 & 2 are still present in the codebase
|
||||
evidence: Current FieldRenderer.tsx (lines 88-91) and PasswordField.tsx (lines 34-35) both have onMouseEnter/onMouseLeave wired to setHoverTooltip. TextFieldMD3 renders helpTextPrefix in a flex row beside helpText (lines 67-74). The debug diagnosis was from before the code was updated.
|
||||
timestamp: 2026-04-02T00:00:00Z
|
||||
|
||||
## Evidence
|
||||
|
||||
- timestamp: 2026-04-01T00:00:00Z
|
||||
checked: FieldRenderer.tsx lines 83-109 (text input default branch)
|
||||
found: |
|
||||
The tooltip button at lines 85-94 uses onClick={() => setShowTooltip(v => !v)} only.
|
||||
There are NO onMouseEnter/onMouseLeave handlers, and no CSS hover-triggered tooltip.
|
||||
The tooltip text (lines 95-99) is only rendered when showTooltip state is true,
|
||||
which only changes on click — never on hover.
|
||||
implication: Root cause of Issue 1 — tooltip requires click, not hover
|
||||
found: Original code had onClick-only toggle, icon rendered above TextFieldMD3, no hover support.
|
||||
implication: Root causes of Issues 1 & 2 at diagnosis time
|
||||
|
||||
- timestamp: 2026-04-01T00:00:00Z
|
||||
checked: FieldRenderer.tsx lines 83-109 (DOM structure of text input branch)
|
||||
- timestamp: 2026-04-02T00:00:00Z
|
||||
checked: FieldRenderer.tsx current state (all 119 lines)
|
||||
found: |
|
||||
The DOM order is:
|
||||
<div flex-col>
|
||||
{tooltipText && <button>icon</button>} ← lines 85-94: icon ABOVE field
|
||||
{tooltipText && showTooltip && <p>text</p>} ← lines 95-99: tooltip text ABOVE field
|
||||
<TextFieldMD3 helpText={field.helpText} /> ← lines 100-107: field with helpText inside
|
||||
</div>
|
||||
The icon button is a sibling rendered BEFORE TextFieldMD3, placing it above the field.
|
||||
Meanwhile, helpText is rendered INSIDE TextFieldMD3 (TextFieldMD3.tsx lines 65-67),
|
||||
so the icon cannot be "beside the helpText" from its current position.
|
||||
implication: Root cause of Issue 2 — icon is structurally above the field, not beside helpText
|
||||
Lines 88-91: onMouseEnter/onMouseLeave both wired to setHoverTooltip — hover IS implemented.
|
||||
Line 99: tooltipVisible = showTooltip || hoverTooltip — hover state properly used.
|
||||
Lines 103-111: TextFieldMD3 receives helpTextPrefix={tooltipIcon} — icon IS placed beside helpText.
|
||||
Same pattern confirmed in PasswordField.tsx lines 34-35 and 54.
|
||||
implication: Issues 1 & 2 already resolved in current code
|
||||
|
||||
- timestamp: 2026-04-01T00:00:00Z
|
||||
checked: TextFieldMD3.tsx lines 65-67
|
||||
- timestamp: 2026-04-02T00:00:00Z
|
||||
checked: index.css — CSS custom property values for light mode (:root)
|
||||
found: |
|
||||
helpText is rendered inside TextFieldMD3:
|
||||
{helpText && !error && (
|
||||
<p className="text-xs text-on-surface-container/70">{helpText}</p>
|
||||
)}
|
||||
This is encapsulated inside the component — FieldRenderer has no way to inject
|
||||
an icon beside it without either: (a) passing the icon as a prop, or (b) moving
|
||||
helpText rendering out of TextFieldMD3.
|
||||
implication: Fix requires changing TextFieldMD3 interface or moving helpText rendering
|
||||
--r2b-on-surface-variant: #F3F4F6 (gray-100 — intended for text ON surface-variant/code blocks)
|
||||
--r2b-on-surface-container: #374151 (gray-700 — good contrast on white/light surfaces)
|
||||
--r2b-surface: #F9FAFB (gray-50 — light background)
|
||||
implication: text-on-surface-variant = near-white on light backgrounds = illegible; text-on-surface-container = dark gray = legible
|
||||
|
||||
- timestamp: 2026-04-02T00:00:00Z
|
||||
checked: BackendSelectionStep.tsx line 88 and line 107
|
||||
found: |
|
||||
Line 88: <p className="text-sm text-on-surface-variant mt-1 mb-4"> — step description uses on-surface-variant
|
||||
Line 107: placeholder:text-on-surface-variant/50 — search placeholder uses on-surface-variant at 50% opacity
|
||||
Both become near-invisible in light mode: gray-100 (#F3F4F6) on gray-50 (#F9FAFB) background.
|
||||
implication: Root cause of Issue 3 — wrong semantic token used for body text on surface background
|
||||
|
||||
## Resolution
|
||||
|
||||
root_cause: |
|
||||
ISSUE 1 — Tooltip doesn't show on hover:
|
||||
File: src/components/ui/FieldRenderer.tsx, lines 85-94
|
||||
The tooltip button only has an onClick handler that toggles showTooltip state.
|
||||
There are no onMouseEnter/onMouseLeave handlers and no CSS :hover mechanism.
|
||||
The tooltip content (lines 95-99) is conditionally rendered only when showTooltip === true,
|
||||
which never becomes true from hovering.
|
||||
ISSUE 1 (tooltip hover) — ALREADY FIXED in current code.
|
||||
Both FieldRenderer.tsx and PasswordField.tsx have onMouseEnter/onMouseLeave handlers wired to setHoverTooltip.
|
||||
tooltipVisible = showTooltip || hoverTooltip ensures hover triggers display.
|
||||
|
||||
ISSUE 2 — Icon placed above field instead of beside helpText:
|
||||
File: src/components/ui/FieldRenderer.tsx, lines 83-109
|
||||
The icon button is rendered as a sibling BEFORE <TextFieldMD3>, placing it visually
|
||||
above the text field. The helpText is rendered INSIDE TextFieldMD3 (TextFieldMD3.tsx
|
||||
line 65-67), making it impossible for the icon in FieldRenderer to sit beside it.
|
||||
To place the icon beside helpText, either:
|
||||
(a) TextFieldMD3 needs a new prop (e.g., helpTextSuffix or helpTextIcon) to render
|
||||
content inline with the helpText paragraph, or
|
||||
(b) helpText rendering moves out of TextFieldMD3 back into FieldRenderer, where the
|
||||
icon and helpText can be placed in a flex-row together.
|
||||
ISSUE 2 (icon placement) — ALREADY FIXED in current code.
|
||||
FieldRenderer.tsx passes helpTextPrefix={tooltipIcon} to TextFieldMD3.
|
||||
TextFieldMD3 renders helpTextPrefix in a flex row beside helpText (lines 67-74).
|
||||
|
||||
fix: (not applied — diagnosis only)
|
||||
verification: (not applied — diagnosis only)
|
||||
files_changed: []
|
||||
ISSUE 3 (light mode illegibility):
|
||||
File: src/components/wizard/BackendSelectionStep.tsx, lines 88 and 107
|
||||
text-on-surface-variant (#F3F4F6, gray-100) is semantically "text on dark surface-variant elements"
|
||||
(e.g., code blocks). Using it on light surface backgrounds produces near-white text on near-white
|
||||
background. The step description and search placeholder are nearly invisible in light mode.
|
||||
Fix: use text-on-surface-container (#374151, gray-700) which is designed for secondary text on surfaces.
|
||||
|
||||
fix: |
|
||||
BackendSelectionStep.tsx line 88: text-on-surface-variant -> text-on-surface-container
|
||||
BackendSelectionStep.tsx line 107: placeholder:text-on-surface-variant/50 -> placeholder:text-on-surface-container/50
|
||||
verification: TypeScript passes clean. 79 tests pass (13 pre-existing infra failures unrelated to this change — same failures existed before). Fix applied and code-reviewed: token change is semantically correct.
|
||||
files_changed:
|
||||
- src/components/wizard/BackendSelectionStep.tsx
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
# Requirements Archive: v1.3 Backend Expansion
|
||||
|
||||
**Archived:** 2026-04-16
|
||||
**Status:** SHIPPED
|
||||
|
||||
For current requirements, see `.planning/REQUIREMENTS.md`.
|
||||
|
||||
---
|
||||
|
||||
# Requirements: Ready2Blob
|
||||
|
||||
**Defined:** 2026-03-31
|
||||
@@ -0,0 +1,164 @@
|
||||
# Roadmap: Ready2Blob
|
||||
|
||||
## Milestones
|
||||
|
||||
- ✅ **v1.0 MVP** — Phases 1–4 (shipped 2026-03-27)
|
||||
- ✅ **v1.1 Backlog & Tech Debt** — Phases 5–7 (shipped 2026-03-31)
|
||||
- ✅ **v1.2 UI Polish & Clarity** — Phases 8–12 (shipped 2026-04-01)
|
||||
- **v1.3 Backend Expansion** — Phase 13 (in progress)
|
||||
|
||||
## Phases
|
||||
|
||||
<details>
|
||||
<summary>✅ v1.0 MVP (Phases 1–4) — SHIPPED 2026-03-27</summary>
|
||||
|
||||
- [x] Phase 1: Foundation (4/4 plans) — completed 2026-03-26
|
||||
- [x] Phase 2: Generators (4/4 plans) — completed 2026-03-26
|
||||
- [x] Phase 3: Wizard UI (5/5 plans) — completed 2026-03-27
|
||||
- [x] Phase 4: Review, Download & Security (5/5 plans) — completed 2026-03-27
|
||||
|
||||
Full phase details: [.planning/milestones/v1.0-ROADMAP.md](milestones/v1.0-ROADMAP.md)
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>✅ v1.1 Backlog & Tech Debt (Phases 5–7) — SHIPPED 2026-03-31</summary>
|
||||
|
||||
- [x] Phase 5: Tech Debt (4/4 plans) — completed 2026-03-30
|
||||
- [x] Phase 6: New Backends (4/4 plans) — completed 2026-03-31
|
||||
- [x] Phase 7: Validation & UX Polish (3/3 plans) — completed 2026-03-31
|
||||
|
||||
Full phase details: [.planning/milestones/v1.1-ROADMAP.md](milestones/v1.1-ROADMAP.md)
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>✅ v1.2 UI Polish & Clarity (Phases 8–12) — SHIPPED 2026-04-01</summary>
|
||||
|
||||
- [x] **Phase 8: Theme Foundation** - MD3 color token system and dark mode infrastructure (completed 2026-04-01)
|
||||
- [x] **Phase 9: MD3 Components** - UI primitives and component migration to semantic tokens (completed 2026-04-01)
|
||||
- [x] **Phase 10: Content & Clarity** - Intro section, step descriptions, and contextual help (completed 2026-04-01)
|
||||
- [x] **Phase 11: Polish & Responsiveness** - Mobile layout, focus states, transitions, scroll-to-error (completed 2026-04-01)
|
||||
- [x] **Phase 12: Dark mode visibility fixes** - Fix dark mode regressions (completed 2026-04-01)
|
||||
|
||||
</details>
|
||||
|
||||
### v1.3 Backend Expansion (In Progress)
|
||||
|
||||
**Milestone Goal:** Expand backend support from 7 to 17 rclone backends with categorized selection, search filtering, OAuth token-paste guidance, and inline icons.
|
||||
|
||||
## Phase Details
|
||||
|
||||
### Phase 8: Theme Foundation
|
||||
**Goal**: App has a complete MD3 color token system and working dark mode toggle with no flash of unstyled content
|
||||
**Depends on**: Phase 7 (v1.1 complete)
|
||||
**Requirements**: THEME-01, THEME-02
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. All color values in the app flow from CSS custom properties defined in a single token file, not from hardcoded Tailwind color classes
|
||||
2. User can toggle between System, Light, and Dark themes via a visible control, and the entire UI responds immediately
|
||||
3. Theme preference persists in localStorage and applies on reload without any flash of wrong theme
|
||||
4. Tailwind v4 `@theme` directive maps MD3 token names to utility classes (e.g., `bg-surface`, `text-on-primary`)
|
||||
**Plans:** 2/2 plans complete
|
||||
Plans:
|
||||
- [ ] 08-01-PLAN.md — Token system, flash prevention, ThemeToggle component
|
||||
- [ ] 08-02-PLAN.md — Color class migration across all components
|
||||
|
||||
### Phase 9: MD3 Components
|
||||
**Goal**: All interactive elements use MD3-styled primitives with consistent visual language across the entire wizard
|
||||
**Depends on**: Phase 8
|
||||
**Requirements**: COMP-01, COMP-02, COMP-03, COMP-04, DEBT-01
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. Text inputs render as outlined fields with floating labels that animate on focus and when the field has content
|
||||
2. Buttons visually distinguish primary (filled), secondary (outlined), and tertiary (text) actions across all wizard steps
|
||||
3. Backend selection cards and output blocks display MD3 elevation with tonal surface tint and consistent shape tokens
|
||||
4. Step indicator shows numbered circles connected by lines, with checkmarks on completed steps, highlight on current, and muted future steps
|
||||
5. FieldRenderer produces identical `aria-label` attributes for both text-branch and select-branch inputs
|
||||
**Plans:** 5/5 plans complete
|
||||
Plans:
|
||||
- [x] 09-01-PLAN.md — TextFieldMD3 component, MD3 button constants, DEBT-01 aria-label fix
|
||||
- [x] 09-02-PLAN.md — StepIndicator rebuild with MD3 circles and connectors
|
||||
- [x] 09-03-PLAN.md — Integration: wire TextFieldMD3 + button styles + elevation into all wizard steps
|
||||
- [x] 09-04-PLAN.md — Gap closure: Replace BackendSelectionStep plain input with TextFieldMD3
|
||||
- [x] 09-05-PLAN.md — Gap closure: Tooltip hover behavior + icon placement beside helpText
|
||||
|
||||
### Phase 10: Content & Clarity
|
||||
**Goal**: A first-time visitor understands what Ready2Blob does and what each wizard step expects without external documentation
|
||||
**Depends on**: Phase 8 (tokens needed for consistent styling of new content)
|
||||
**Requirements**: UX-01, UX-02, UX-03, UX-04
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. Landing view shows an intro section explaining what Ready2Blob does with a clear call-to-action to start the wizard
|
||||
2. Remote name field displays a placeholder example, help text, and a live preview showing how the name appears in `[remote-name]` config syntax
|
||||
3. Every wizard step has a 1-2 sentence description below the heading explaining what the user is doing and why
|
||||
4. All backend credential fields have contextual help text explaining what to enter and where to find the value
|
||||
**Plans:** 3/3 plans complete
|
||||
Plans:
|
||||
- [ ] 10-01-PLAN.md — Intro section with CTA and step descriptions for all 4 steps
|
||||
- [ ] 10-02-PLAN.md — Remote name live config preview with helpText
|
||||
- [ ] 10-03-PLAN.md — Credential field tooltipText and helpText enrichment
|
||||
|
||||
### Phase 11: Polish & Responsiveness
|
||||
**Goal**: The wizard feels production-ready on any device with smooth interactions and accessible keyboard navigation
|
||||
**Depends on**: Phase 9, Phase 10
|
||||
**Requirements**: POLISH-01, POLISH-02, POLISH-03, POLISH-04
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. On a mobile viewport (< 640px), backend cards stack vertically, form fields span full width, step indicator collapses, and buttons stretch to fill width
|
||||
2. Every interactive element shows a visible 3px MD3 focus outline when navigated via keyboard (using `focus-visible`)
|
||||
3. Step transitions use a subtle fade/slide animation that is suppressed when the user has `prefers-reduced-motion` enabled
|
||||
4. When form validation fails, the view auto-scrolls to the first field with an error
|
||||
**Plans:** 2/2 plans complete
|
||||
Plans:
|
||||
- [ ] 11-01-PLAN.md — Mobile responsive layout + MD3 focus-visible indicators
|
||||
- [ ] 11-02-PLAN.md — Step transition animation + auto-scroll to first error
|
||||
|
||||
### Phase 12: Dark mode visibility fixes
|
||||
|
||||
**Goal:** Fix dark mode visibility regressions where step headings, DeploymentStep form controls, and FieldRenderer select elements are invisible or unstyled against the dark background
|
||||
**Requirements**: DARK-01, DARK-02, DARK-03
|
||||
**Depends on:** Phase 11
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. All wizard step h2 headings are readable in dark mode with proper contrast
|
||||
2. DeploymentStep labels, legends, checkboxes, and radios are visible and styled in dark mode
|
||||
3. FieldRenderer select element has proper background and text color in dark mode
|
||||
**Plans:** 2/2 plans complete
|
||||
|
||||
Plans:
|
||||
- [ ] 12-01-PLAN.md — Fix step headings, DeploymentStep form controls, ReviewStep checkbox
|
||||
- [ ] 12-02-PLAN.md — Fix FieldRenderer select dark mode styling
|
||||
|
||||
### Phase 13: Add remaining RClone remotes
|
||||
|
||||
**Goal:** Expand backend support from 7 to 17 rclone backends with categorized selection UI, instant search, OAuth token-paste guidance, and inline SVG icons — covering all backends suitable for unattended Windows deployment
|
||||
**Requirements**: REMOTE-01, REMOTE-02, REMOTE-03, REMOTE-04, REMOTE-05, REMOTE-06
|
||||
**Depends on:** Phase 12
|
||||
**Success Criteria** (what must be TRUE):
|
||||
1. BACKEND_REGISTRY contains 17 backends with correct fields, categories, and rclone type mappings
|
||||
2. BackendType is derived from registry keys (not an explicit union)
|
||||
3. BackendSelectionStep groups backends by category with instant search and inline SVG icons
|
||||
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/4 plans complete
|
||||
|
||||
Plans:
|
||||
- [x] 13-01-PLAN.md — Registry refactoring: derive BackendType, add categories, 11 new backend entries (18 total), auto-generate schemas
|
||||
- [ ] 13-02-PLAN.md — New components: OAuthInstructions, GdriveAuthToggle, BackendIcons
|
||||
- [ ] 13-03-PLAN.md — BackendSelectionStep UX overhaul: categories, search, icons
|
||||
- [ ] 13-04-PLAN.md — RemoteConfigStep wiring for all new backends + visual verification
|
||||
|
||||
## Progress
|
||||
|
||||
| Phase | Milestone | Plans Complete | Status | Completed |
|
||||
|-------|-----------|----------------|--------|-----------|
|
||||
| 1. Foundation | v1.0 | 4/4 | Complete | 2026-03-26 |
|
||||
| 2. Generators | v1.0 | 4/4 | Complete | 2026-03-26 |
|
||||
| 3. Wizard UI | v1.0 | 5/5 | Complete | 2026-03-27 |
|
||||
| 4. Review, Download & Security | v1.0 | 5/5 | Complete | 2026-03-27 |
|
||||
| 5. Tech Debt | v1.1 | 4/4 | Complete | 2026-03-30 |
|
||||
| 6. New Backends | v1.1 | 4/4 | Complete | 2026-03-31 |
|
||||
| 7. Validation & UX Polish | v1.1 | 3/3 | Complete | 2026-03-31 |
|
||||
| 8. Theme Foundation | v1.2 | 2/2 | Complete | 2026-04-01 |
|
||||
| 9. MD3 Components | v1.2 | 5/5 | Complete | 2026-04-01 |
|
||||
| 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 | 4/4 | Complete | 2026-04-01 | — |
|
||||
@@ -126,3 +126,15 @@ None - no external service configuration required.
|
||||
---
|
||||
*Phase: 10-content-clarity*
|
||||
*Completed: 2026-04-01*
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
- `src/App.tsx` — FOUND
|
||||
- `src/App.test.tsx` — FOUND
|
||||
- `src/components/wizard/BackendSelectionStep.tsx` — FOUND
|
||||
- `src/components/wizard/RemoteConfigStep.tsx` — FOUND
|
||||
- `src/components/wizard/DeploymentStep.tsx` — FOUND
|
||||
- `src/components/wizard/ReviewStep.tsx` — FOUND
|
||||
- `.planning/phases/10-content-clarity/10-01-SUMMARY.md` — FOUND
|
||||
- Commit `c1d1633` — FOUND
|
||||
- Commit `4b837b1` — FOUND
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
---
|
||||
phase: 13-add-remaining-rclone-remotes
|
||||
plan: "02"
|
||||
subsystem: ui
|
||||
tags: [react, tailwind, svg, rclone, oauth, wizard, components]
|
||||
|
||||
# Dependency graph
|
||||
requires:
|
||||
- phase: 13-add-remaining-rclone-remotes
|
||||
provides: "BackendType derived from BACKEND_REGISTRY (18 backends), registry as const pattern"
|
||||
provides:
|
||||
- "OAuthInstructions: collapsible step-by-step OAuth token guide (TDD, 4 tests)"
|
||||
- "GdriveAuthToggle: two-tab OAuth/Service Account toggle for Google Drive"
|
||||
- "BACKEND_ICONS: inline SVG icon map for all 18 BackendType entries"
|
||||
affects: [13-03-BackendSelectionStep, 13-04-RemoteConfigStep]
|
||||
|
||||
# Tech tracking
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns:
|
||||
- "TDD for UI components: test → implement → verify cycle"
|
||||
- "Collapsible disclosure via useState(false) + conditional render"
|
||||
- "Both form fields always registered, visibility toggled via CSS hidden/block"
|
||||
- "Inline SVG icons with fill=currentColor for dark-mode compatibility"
|
||||
- "Partial<Record<BackendType, FC<IconProps>>> for optional icon map"
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- src/components/wizard/OAuthInstructions.tsx
|
||||
- src/components/wizard/OAuthInstructions.test.tsx
|
||||
- src/components/wizard/GdriveAuthToggle.tsx
|
||||
- src/components/icons/BackendIcons.tsx
|
||||
modified: []
|
||||
|
||||
key-decisions:
|
||||
- "OAuthInstructions renders authorizeCommand in a <code> block (detected via step text prefix), not inline text — ensures test getByText exact-match works"
|
||||
- "BACKEND_ICONS is Partial<Record<BackendType,...>> — missing entries mean no icon rendered on the card; allows incremental icon addition"
|
||||
- "GdriveAuthToggle defaults to oauth tab (not service-account) — OAuth is the more common flow for personal use"
|
||||
- "BackendIcons uses text SVG elements for letter-based icons (S3, B2, G, p) — simpler than path-based glyphs for recognizable short labels at 24px"
|
||||
|
||||
patterns-established:
|
||||
- "AuthToggle pattern: segmented control + CSS hidden/block for always-registered dual fields"
|
||||
- "OAuthInstructions: generic collapsible guide reusable for any OAuth backend (backendName + authorizeCommand props)"
|
||||
- "IconProps = { className?: string } — minimal prop surface for SVG components"
|
||||
|
||||
requirements-completed: [REMOTE-04]
|
||||
|
||||
# Metrics
|
||||
duration: 4min
|
||||
completed: 2026-04-01
|
||||
---
|
||||
|
||||
# Phase 13 Plan 02: Component Library for OAuth and Icons Summary
|
||||
|
||||
**Collapsible OAuthInstructions, GdriveAuthToggle dual-auth toggle, and 18-backend inline SVG icon map — all with zero external dependencies**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** 4 min
|
||||
- **Started:** 2026-04-01T14:24:33Z
|
||||
- **Completed:** 2026-04-01T14:28:00Z
|
||||
- **Tasks:** 2 (Task 1 TDD, Task 2 standard)
|
||||
- **Files modified:** 4 created
|
||||
|
||||
## Accomplishments
|
||||
- OAuthInstructions: collapsible disclosure (collapsed by default), shows backend-specific rclone authorize command in code block, 5-step generic OAuth flow, MD3 styled — TDD with 4 passing tests
|
||||
- GdriveAuthToggle: two-tab segmented control (OAuth Token / Service Account) following AzureAuthToggle pattern exactly; OAuth tab embeds OAuthInstructions; both fields always registered via CSS hidden/block
|
||||
- BackendIcons: inline SVG icon map covering all 18 BackendType keys, fill="currentColor" throughout, viewBox 0 0 24 24, no external icon library
|
||||
|
||||
## Task Commits
|
||||
|
||||
Each task was committed atomically:
|
||||
|
||||
1. **Task 1: OAuthInstructions component with tests** - `e00fc2b` (feat + test TDD)
|
||||
2. **Task 2: GdriveAuthToggle and BackendIcons components** - `683faf6` (feat)
|
||||
|
||||
## Files Created/Modified
|
||||
- `src/components/wizard/OAuthInstructions.tsx` - Collapsible OAuth step-by-step guide component
|
||||
- `src/components/wizard/OAuthInstructions.test.tsx` - 4 behavior tests (collapsed default, expand on click, authorize command display, backend name in button)
|
||||
- `src/components/wizard/GdriveAuthToggle.tsx` - Google Drive dual-auth toggle (OAuth Token + Service Account tabs)
|
||||
- `src/components/icons/BackendIcons.tsx` - Inline SVG icon map for all 18 backends
|
||||
|
||||
## Decisions Made
|
||||
- OAuthInstructions uses step-prefix detection to render the authorize command in a `<code>` element — the step text "Run the authorize command: ..." is matched by prefix so the command value is extracted cleanly for the code block while keeping getByText test assertions working correctly.
|
||||
- BACKEND_ICONS is `Partial<Record<BackendType,...>>` so missing icons simply render nothing — plans 03/04 handle the absent-icon case in BackendCard.
|
||||
- GdriveAuthToggle defaults to oauth tab since OAuth is the typical personal-use flow; service account is the secondary option.
|
||||
- Letter-based SVG icons (S3, B2, G, p) use `<text>` elements for simplicity at 24px — path-based glyph construction for single characters is over-engineered.
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
None - plan executed exactly as written.
|
||||
|
||||
## Issues Encountered
|
||||
None.
|
||||
|
||||
## User Setup Required
|
||||
None - no external service configuration required.
|
||||
|
||||
## Next Phase Readiness
|
||||
- OAuthInstructions ready for embedding in any OAuth backend config step
|
||||
- GdriveAuthToggle ready for use in RemoteConfigStep (plan 13-04) as gdrive's auth renderer
|
||||
- BACKEND_ICONS ready for BackendCard integration in BackendSelectionStep (plan 13-03)
|
||||
- Full test suite (270 tests, 17 files) remains green
|
||||
|
||||
---
|
||||
*Phase: 13-add-remaining-rclone-remotes*
|
||||
*Completed: 2026-04-01*
|
||||
Reference in New Issue
Block a user