docs(07-task-sorting): create phase plan
This commit is contained in:
214
.planning/phases/07-task-sorting/07-02-PLAN.md
Normal file
214
.planning/phases/07-task-sorting/07-02-PLAN.md
Normal file
@@ -0,0 +1,214 @@
|
||||
---
|
||||
phase: 07-task-sorting
|
||||
plan: 02
|
||||
type: execute
|
||||
wave: 2
|
||||
depends_on: ["07-01"]
|
||||
files_modified:
|
||||
- lib/features/tasks/presentation/sort_dropdown.dart
|
||||
- lib/features/home/presentation/home_screen.dart
|
||||
- lib/features/tasks/presentation/task_list_screen.dart
|
||||
- test/features/home/presentation/home_screen_test.dart
|
||||
autonomous: true
|
||||
requirements: [SORT-01, SORT-02, SORT-03]
|
||||
|
||||
must_haves:
|
||||
truths:
|
||||
- "A sort dropdown is visible in the HomeScreen AppBar showing the current sort label"
|
||||
- "A sort dropdown is visible in the TaskListScreen AppBar showing the current sort label"
|
||||
- "Tapping the dropdown shows three options: A-Z, Intervall, Aufwand"
|
||||
- "Selecting a sort option updates the task list order immediately"
|
||||
- "The sort preference persists across screen navigations and app restarts"
|
||||
artifacts:
|
||||
- path: "lib/features/tasks/presentation/sort_dropdown.dart"
|
||||
provides: "Reusable SortDropdown ConsumerWidget"
|
||||
exports: ["SortDropdown"]
|
||||
- path: "lib/features/home/presentation/home_screen.dart"
|
||||
provides: "HomeScreen with AppBar containing SortDropdown"
|
||||
contains: "SortDropdown"
|
||||
- path: "lib/features/tasks/presentation/task_list_screen.dart"
|
||||
provides: "TaskListScreen AppBar with SortDropdown alongside edit/delete"
|
||||
contains: "SortDropdown"
|
||||
key_links:
|
||||
- from: "lib/features/tasks/presentation/sort_dropdown.dart"
|
||||
to: "sortPreferenceProvider"
|
||||
via: "ref.watch for display, ref.read for mutation"
|
||||
pattern: "ref\\.watch\\(sortPreferenceProvider\\)"
|
||||
- from: "lib/features/home/presentation/home_screen.dart"
|
||||
to: "lib/features/tasks/presentation/sort_dropdown.dart"
|
||||
via: "SortDropdown widget in AppBar actions"
|
||||
pattern: "SortDropdown"
|
||||
- from: "lib/features/tasks/presentation/task_list_screen.dart"
|
||||
to: "lib/features/tasks/presentation/sort_dropdown.dart"
|
||||
via: "SortDropdown widget in AppBar actions"
|
||||
pattern: "SortDropdown"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Build the sort dropdown widget and wire it into both task list screens (HomeScreen and TaskListScreen), adding an AppBar to HomeScreen.
|
||||
|
||||
Purpose: Gives users visible access to the sort controls. The data layer from Plan 01 already sorts reactively; this plan adds the UI trigger.
|
||||
|
||||
Output: SortDropdown reusable widget, updated HomeScreen with AppBar, updated TaskListScreen with dropdown in existing AppBar, updated tests.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@/home/jlmak/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@/home/jlmak/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
@.planning/phases/07-task-sorting/07-CONTEXT.md
|
||||
@.planning/phases/07-task-sorting/07-01-SUMMARY.md
|
||||
|
||||
<interfaces>
|
||||
<!-- Interfaces from Plan 01 that this plan depends on -->
|
||||
|
||||
From lib/features/tasks/domain/task_sort_option.dart (created in 07-01):
|
||||
```dart
|
||||
enum TaskSortOption { alphabetical, interval, effort }
|
||||
```
|
||||
|
||||
From lib/features/tasks/presentation/sort_preference_notifier.dart (created in 07-01):
|
||||
```dart
|
||||
@riverpod
|
||||
class SortPreferenceNotifier extends _$SortPreferenceNotifier {
|
||||
TaskSortOption build(); // returns alphabetical by default
|
||||
Future<void> setSortOption(TaskSortOption option);
|
||||
}
|
||||
// Generated as: sortPreferenceProvider
|
||||
```
|
||||
|
||||
From lib/l10n/app_de.arb (strings added in 07-01):
|
||||
```
|
||||
sortAlphabetical: "A-Z"
|
||||
sortInterval: "Intervall"
|
||||
sortEffort: "Aufwand"
|
||||
sortLabel: "Sortierung"
|
||||
```
|
||||
|
||||
<!-- Existing interfaces being modified -->
|
||||
|
||||
From lib/features/home/presentation/home_screen.dart:
|
||||
```dart
|
||||
class HomeScreen extends ConsumerStatefulWidget {
|
||||
// Currently: Stack with CalendarStrip + CalendarDayList + floating Today FAB
|
||||
// No AppBar — body sits directly inside AppShell's Scaffold
|
||||
}
|
||||
```
|
||||
|
||||
From lib/features/tasks/presentation/task_list_screen.dart:
|
||||
```dart
|
||||
class TaskListScreen extends ConsumerWidget {
|
||||
// Has its own Scaffold with AppBar containing edit + delete IconButtons
|
||||
// AppBar actions: [edit, delete]
|
||||
}
|
||||
```
|
||||
|
||||
From lib/features/home/presentation/calendar_strip.dart:
|
||||
```dart
|
||||
class CalendarStrip extends StatefulWidget {
|
||||
const CalendarStrip({super.key, required this.controller, this.onTodayVisibilityChanged});
|
||||
final CalendarStripController controller;
|
||||
final ValueChanged<bool>? onTodayVisibilityChanged;
|
||||
}
|
||||
```
|
||||
</interfaces>
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Build SortDropdown widget and integrate into HomeScreen and TaskListScreen</name>
|
||||
<files>
|
||||
lib/features/tasks/presentation/sort_dropdown.dart,
|
||||
lib/features/home/presentation/home_screen.dart,
|
||||
lib/features/tasks/presentation/task_list_screen.dart
|
||||
</files>
|
||||
<action>
|
||||
1. Create `lib/features/tasks/presentation/sort_dropdown.dart`:
|
||||
- A `ConsumerWidget` named `SortDropdown`
|
||||
- Uses `PopupMenuButton<TaskSortOption>` (Material 3, better than DropdownButton for AppBar trailing actions — it opens a menu overlay rather than inline expansion)
|
||||
- `ref.watch(sortPreferenceProvider)` to get current sort option
|
||||
- The button child shows the current sort label as a Text widget using l10n strings:
|
||||
- `alphabetical` -> `l10n.sortAlphabetical` (A-Z)
|
||||
- `interval` -> `l10n.sortInterval` (Intervall)
|
||||
- `effort` -> `l10n.sortEffort` (Aufwand)
|
||||
- Style the button child as a Row with `Icon(Icons.sort)` + `SizedBox(width: 4)` + label Text. Use `theme.textTheme.labelLarge` for the text.
|
||||
- `itemBuilder` returns 3 `PopupMenuItem<TaskSortOption>` entries with check marks: for each option, show a Row with `Icon(Icons.check, size: 18)` (visible only when selected, invisible when not via `Opacity(opacity: isSelected ? 1 : 0)`) + `SizedBox(width: 8)` + label Text
|
||||
- `onSelected`: `ref.read(sortPreferenceProvider.notifier).setSortOption(value)`
|
||||
- Helper method `String _label(TaskSortOption option, AppLocalizations l10n)` that maps enum to l10n string
|
||||
|
||||
2. Edit `lib/features/home/presentation/home_screen.dart`:
|
||||
- HomeScreen currently returns a `Stack` with `Column(CalendarStrip, Expanded(CalendarDayList))` + optional floating Today button
|
||||
- Wrap the entire current Stack in a `Scaffold` with an `AppBar`:
|
||||
- `AppBar(title: Text(l10n.tabHome), actions: [const SortDropdown()])`
|
||||
- The `tabHome` l10n string already exists ("Ubersicht") — reuse it as the AppBar title for the home screen
|
||||
- body: the existing Stack content
|
||||
- Keep CalendarStrip, CalendarDayList, and floating Today FAB exactly as they are
|
||||
- Import `sort_dropdown.dart`
|
||||
- Note: HomeScreen is inside AppShell's Scaffold body. Adding a nested Scaffold is fine and standard for per-tab AppBars in StatefulShellRoute.indexedStack. The AppShell Scaffold provides the bottom nav; the inner Scaffold provides the AppBar.
|
||||
|
||||
3. Edit `lib/features/tasks/presentation/task_list_screen.dart`:
|
||||
- In the existing `AppBar.actions` list, add `const SortDropdown()` BEFORE the edit and delete IconButtons. Order: [SortDropdown, edit, delete].
|
||||
- Import `sort_dropdown.dart`
|
||||
- No other changes to TaskListScreen
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd /home/jlmak/Projects/jlmak/HouseHoldKeaper && flutter analyze --no-fatal-infos</automated>
|
||||
</verify>
|
||||
<done>SortDropdown widget exists showing current sort label with sort icon. HomeScreen has AppBar with title "Ubersicht" and SortDropdown. TaskListScreen AppBar has SortDropdown before edit/delete buttons. dart analyze clean.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Update tests for HomeScreen AppBar and sort dropdown</name>
|
||||
<files>
|
||||
test/features/home/presentation/home_screen_test.dart
|
||||
</files>
|
||||
<action>
|
||||
1. Edit `test/features/home/presentation/home_screen_test.dart`:
|
||||
- Add import for `sort_preference_notifier.dart` and `task_sort_option.dart`
|
||||
- In the `_buildApp` helper, add a provider override for `sortPreferenceProvider`:
|
||||
```dart
|
||||
sortPreferenceProvider.overrideWith(SortPreferenceNotifier.new),
|
||||
```
|
||||
This will use the real notifier with mock SharedPreferences (already set up in setUp).
|
||||
- Add a new test group `'HomeScreen sort dropdown'`:
|
||||
- Test: "shows sort dropdown in AppBar" — pump the app with tasks, verify `find.byType(PopupMenuButton<TaskSortOption>)` findsOneWidget
|
||||
- Test: "shows AppBar with title" — verify `find.text('Ubersicht')` findsOneWidget (the tabHome l10n string)
|
||||
- Verify all existing tests still pass. The addition of an AppBar wrapping the existing content should not break existing assertions since they look for specific widgets/text within the tree.
|
||||
|
||||
2. Run full test suite to confirm no regressions.
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd /home/jlmak/Projects/jlmak/HouseHoldKeaper && flutter test && flutter analyze --no-fatal-infos</automated>
|
||||
</verify>
|
||||
<done>Home screen tests verify AppBar with sort dropdown is present. All 108+ tests pass (106 existing + 2+ new). dart analyze clean.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
- `flutter test` — all tests pass including new sort dropdown tests
|
||||
- `flutter analyze --no-fatal-infos` — zero issues
|
||||
- HomeScreen has AppBar with SortDropdown visible
|
||||
- TaskListScreen has SortDropdown in AppBar actions
|
||||
- Tapping dropdown shows 3 options with check mark on current selection
|
||||
- Selecting a different sort option reorders the task list reactively
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- SortDropdown widget is reusable and shows current sort with icon
|
||||
- HomeScreen has AppBar titled "Ubersicht" with SortDropdown in trailing actions
|
||||
- TaskListScreen has SortDropdown before edit/delete buttons in AppBar
|
||||
- Sort selection updates task list order immediately (reactive via provider)
|
||||
- Sort preference persists (set in one screen, visible in another after navigation)
|
||||
- All tests pass, analyze clean
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/07-task-sorting/07-02-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user