diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index a7796cc..39e91fa 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -34,7 +34,7 @@ See `milestones/v1.1-ROADMAP.md` for full phase details. **v1.2 Polish & Task Management (Phases 8-10):** - [x] **Phase 8: Task Delete** - Add smart delete action to tasks — hard delete if never completed, soft delete (deactivate) if completed at least once (completed 2026-03-18) -- [ ] **Phase 9: Task Creation UX** - Rework the frequency picker from flat preset chips to an intuitive "Every N units" interface with quick-select shortcuts +- [x] **Phase 9: Task Creation UX** - Rework the frequency picker from flat preset chips to an intuitive "Every N units" interface with quick-select shortcuts (completed 2026-03-18) - [ ] **Phase 10: Dead Code Cleanup** - Remove orphaned v1.0 daily plan files and verify no regressions ## Phase Details @@ -58,7 +58,7 @@ Plans: **Goal**: Users can set any recurring frequency intuitively without hunting through a grid of preset chips — common frequencies are one tap away, custom intervals are freeform **Depends on**: Phase 8 **Requirements**: TCX-01, TCX-02, TCX-03, TCX-04 -**Plans:** 1 plan +**Plans:** 1/1 plans complete Plans: - [ ] 09-01-PLAN.md — Rework frequency picker: 4 shortcut chips + freeform "Every N units" picker **Success Criteria** (what must be TRUE): @@ -90,5 +90,5 @@ Plans: | 6. Task History | v1.1 | 1/1 | Complete | 2026-03-16 | | 7. Task Sorting | v1.1 | 2/2 | Complete | 2026-03-16 | | 8. Task Delete | 2/2 | Complete | 2026-03-18 | - | -| 9. Task Creation UX | v1.2 | 0/1 | Planned | - | +| 9. Task Creation UX | 1/1 | Complete | 2026-03-18 | - | | 10. Dead Code Cleanup | v1.2 | - | Planned | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index b2c3d81..550e351 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,14 +3,14 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone status: "Ready for /gsd:plan-phase 8" -stopped_at: Completed 08-task-delete 08-02-PLAN.md -last_updated: "2026-03-18T20:08:14.841Z" +stopped_at: Completed 09-task-creation-ux 09-01-PLAN.md +last_updated: "2026-03-18T21:46:51.068Z" last_activity: 2026-03-18 — Created v1.2 milestone progress: total_phases: 3 - completed_phases: 1 - total_plans: 2 - completed_plans: 2 + completed_phases: 2 + total_plans: 3 + completed_plans: 3 percent: 0 --- @@ -44,6 +44,7 @@ Progress: [░░░░░░░░░░] 0% (0/3 phases) | Tests | 89 | 108 | TBD | | Phase 08-task-delete P01 | 9 | 2 tasks | 11 files | | Phase 08-task-delete P02 | 2 | 2 tasks | 3 files | +| Phase 09-task-creation-ux P01 | 2 | 1 tasks | 4 files | ## Accumulated Context @@ -55,6 +56,7 @@ Decisions archived to PROJECT.md Key Decisions table. - [Phase 08-task-delete]: Migration tests updated to only test v1->v3 and v2->v3 paths since AppDatabase.schemaVersion=3 always migrates to v3 - [Phase 08-task-delete]: smartDeleteTask kept separate from deleteTask to preserve existing hard-delete path for cascade/other uses - [Phase 08-task-delete]: Delete button placed after history section with divider, visible only in edit mode +- [Phase 09-task-creation-ux]: Picker is single source of truth: _resolveFrequency() reads from picker always; _ShortcutFrequency enum handles bidirectional sync via toPickerValues()/fromPickerValues() ### Pending Todos @@ -66,7 +68,7 @@ None. ## Session Continuity -Last session: 2026-03-18T20:03:07.081Z -Stopped at: Completed 08-task-delete 08-02-PLAN.md +Last session: 2026-03-18T21:46:51.066Z +Stopped at: Completed 09-task-creation-ux 09-01-PLAN.md Resume file: None Next action: /gsd:plan-phase 8 diff --git a/.planning/phases/09-task-creation-ux/09-01-SUMMARY.md b/.planning/phases/09-task-creation-ux/09-01-SUMMARY.md new file mode 100644 index 0000000..b1efe70 --- /dev/null +++ b/.planning/phases/09-task-creation-ux/09-01-SUMMARY.md @@ -0,0 +1,105 @@ +--- +phase: 09-task-creation-ux +plan: 01 +subsystem: ui +tags: [flutter, dart, l10n, frequency-picker, choice-chip, segmented-button] + +# Dependency graph +requires: [] +provides: + - Reworked frequency picker with 4 shortcut chips (Täglich, Wöchentlich, Alle 2 Wochen, Monatlich) + - Always-visible freeform "Alle [N] [unit]" picker replacing hidden Custom mode + - Bidirectional chip/picker sync via _ShortcutFrequency enum + - Unified _resolveFrequency() reading exclusively from picker (single source of truth) + - Edit mode loading for all 8 IntervalType values including quarterly and yearly +affects: [] + +# Tech tracking +tech-stack: + added: [] + patterns: + - "Shortcut chip + freeform picker: ChoiceChip row above always-visible SegmentedButton picker" + - "Bidirectional sync: chip tapped populates picker; picker edited recalculates chip highlight via fromPickerValues()" + - "Single source of truth: _resolveFrequency() always reads from picker, never from a preset reference" + +key-files: + created: [] + modified: + - lib/features/tasks/presentation/task_form_screen.dart + - lib/l10n/app_de.arb + - lib/l10n/app_localizations.dart + - lib/l10n/app_localizations_de.dart + +key-decisions: + - "Picker is single source of truth: _resolveFrequency() reads from _customIntervalController + _customUnit always" + - "_ShortcutFrequency enum with toPickerValues() and fromPickerValues() handles bidirectional sync without manual mapping" + - "Named IntervalTypes (daily/weekly/biweekly/monthly) used for canonical values; only everyNDays for 3+ weeks" + - "Quarterly (3 months) and yearly (12 months) displayed correctly in picker with no chip highlighted" + +patterns-established: + - "Shortcut chip pattern: enum with toPickerValues() / fromPickerValues() for bidirectional picker sync" + +requirements-completed: [TCX-01, TCX-02, TCX-03, TCX-04] + +# Metrics +duration: 2min +completed: 2026-03-18 +--- + +# Phase 9 Plan 01: Task Creation UX — Frequency Picker Rework Summary + +**4 shortcut chips (Täglich/Wöchentlich/Alle 2 Wochen/Monatlich) + always-visible freeform picker replacing the 10-chip grid with hidden Custom mode** + +## Performance + +- **Duration:** 2 min +- **Started:** 2026-03-18T21:43:24Z +- **Completed:** 2026-03-18T21:45:30Z +- **Tasks:** 1 (+ 1 auto-approved checkpoint) +- **Files modified:** 4 + +## Accomplishments +- Replaced 10-chip preset grid and hidden "Benutzerdefiniert" mode with 4 shortcut chips + always-visible freeform picker +- Implemented bidirectional sync: tapping a chip populates the picker; editing the picker recalculates chip highlight +- Simplified _resolveFrequency() to read exclusively from the picker (single source of truth), using named IntervalTypes for canonical values +- Edit mode correctly loads all 8 IntervalType values (daily, everyNDays, weekly, biweekly, monthly, everyNMonths, quarterly, yearly) into the picker and highlights the matching shortcut chip where applicable + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Rework frequency picker — shortcut chips + freeform picker** - `8a0b69b` (feat) +2. **Task 2: Verify frequency picker UX** - auto-approved (checkpoint:human-verify, auto_advance=true) + +**Plan metadata:** (docs commit follows) + +## Files Created/Modified +- `lib/features/tasks/presentation/task_form_screen.dart` - Reworked frequency picker: removed _selectedPreset and _isCustomFrequency fields; added _ShortcutFrequency enum and _activeShortcut state; replaced _buildFrequencySelector() with shortcut chips + always-visible picker; renamed _buildCustomFrequencyInput to _buildFrequencyPickerRow with bidirectional sync; simplified _resolveFrequency() to picker-only +- `lib/l10n/app_de.arb` - Added frequencyShortcutDaily/Weekly/Biweekly/Monthly keys +- `lib/l10n/app_localizations.dart` - Regenerated to include new shortcut string getters +- `lib/l10n/app_localizations_de.dart` - Regenerated with German translations (Täglich, Wöchentlich, Alle 2 Wochen, Monatlich) + +## Decisions Made +- Picker is single source of truth: _resolveFrequency() reads from _customIntervalController + _customUnit always, regardless of which chip is highlighted +- _ShortcutFrequency enum with toPickerValues() and static fromPickerValues() cleanly handles bidirectional sync without manual if-chain mapping in each callback +- Named IntervalTypes (daily/weekly/biweekly/monthly) used for canonical values (e.g., weekly has days=1, biweekly has days=14) matching existing DB records; only everyNDays used for 3+ weeks +- Quarterly (3 months) and yearly (12 months) round-trip correctly: loaded as "3 Monate" / "12 Monate" in picker with no chip highlighted + +## Deviations from Plan + +None - plan executed exactly as written. + +## Issues Encountered +None. + +## User Setup Required +None - no external service configuration required. + +## Next Phase Readiness +- Frequency picker rework complete; TaskFormScreen is ready for further UX improvements +- All 144 existing tests pass, dart analyze is clean +- No changes to frequency.dart, no DB migration, no new screens + +--- +*Phase: 09-task-creation-ux* +*Completed: 2026-03-18*