feat(vacaciones): add vacation range manager screen
Add the Vacaciones manager screen per design ADR-6: an active-range
hero (name, days-remaining countdown, determinate progress bar, and a
per-alarm pause-impact line), a "PROGRAMADOS" upcoming-ranges list, an
"Add range" CTA, and a "Rangos pasados" history section. This is the
real destination WU8's Alarmas-root summary row pushes to, replacing
WU8's own temporary placeholder (_PantallaVacacionesTemporal, now
deleted).
EstadoAlarmas gains 4 pure query methods (rangoVacacionesActivo,
vacacionesProximas, vacacionesPasadas, impactoDeRango) -- read-only
over _alarmas/_vacaciones, no writes, no rescheduling, no native
bridge calls. impactoDeRango mirrors ServicioProgramacionAlarmas's own
pause predicate exactly, so the screen never disagrees with the
scheduler about which alarms are paused. ImpactoVacaciones joins
RangoVacaciones in alarma_musical.dart.
The add-range form (_EditorVacacionesSheet, _PickerButton) moved
verbatim from pantalla_alarmas.dart to its one remaining consumer.
estado_alarmas.dart's scheduling/snooze paths and the ringing screen's
dismiss guard are untouched; both test files pass unmodified.
New ARB keys (en/es only; other 11 locales are WU18's job):
vacationImpact{Paused,Continues}Label, vacationUpcomingSectionTitle,
vacationPastSectionTitle, addVacationRangeCta,
vacationNoActiveRangeHint.
This commit is contained in:
@@ -553,23 +553,42 @@ Query, Past-Ranges History Query, Vacation Summary Row Replaces the Inline Panel
|
||||
**New tests**: `pantalla_vacaciones_test.dart`
|
||||
**Modified tests**: `estado_alarmas_test.dart` (additions only)
|
||||
|
||||
- [ ] 9.1 RED — with a **fixed `ahora`**: `rangoVacacionesActivo` returns the active range + days-remaining, or null
|
||||
- [x] 9.1 RED — with a **fixed `ahora`**: `rangoVacacionesActivo` returns the active range + days-remaining, or null
|
||||
when none matches; `vacacionesProximas` returns future ranges ascending by start; `vacacionesPasadas` returns
|
||||
ended ranges descending by end, disjoint from active/upcoming.
|
||||
- [ ] 9.2 RED — `impactoDeRango`: given 3 alarms (2 with `sonarEnVacaciones == false`, 1 with `true`) during an
|
||||
ended ranges descending by end, disjoint from active/upcoming. **Correction found at apply time**: `DateTime(...)`
|
||||
is NOT a const constructor in Dart (only literal-free `const` values are) — the first draft wrote `const
|
||||
RangoVacaciones(..., inicio: DateTime(...))` and failed to compile; fixed by dropping `const` on every
|
||||
`RangoVacaciones` fixture built from a `DateTime(...)` call, same non-const pattern the pre-existing
|
||||
`AlarmaMusical` fixtures in this file already use whenever they set a `DateTime` field.
|
||||
- [x] 9.2 RED — `impactoDeRango`: given 3 alarms (2 with `sonarEnVacaciones == false`, 1 with `true`) during an
|
||||
active range, assert exactly those 2 in `pausadas` and that 1 in `noAfectadas`, mirroring
|
||||
`servicio_programacion_alarmas.dart:150`'s predicate exactly.
|
||||
- [ ] 9.3 RED — `pantalla_vacaciones_test.dart`: active-range hero with progress + per-alarm impact line;
|
||||
"PROGRAMADOS" upcoming list; dashed "Añadir rango" CTA; "Rangos pasados" history row/screen.
|
||||
- [ ] 9.4 GREEN — add the 4 pure query members to `EstadoAlarmas` (`{DateTime? ahora}` defaulting to
|
||||
`servicio_programacion_alarmas.dart:150`'s predicate exactly. Added a 4th case (inactive alarm counts toward
|
||||
neither list) and a 5th purity guard (none of the 4 query methods call `android.programar`).
|
||||
- [x] 9.3 RED — `pantalla_vacaciones_test.dart`: active-range hero with progress + per-alarm impact line;
|
||||
"PROGRAMADOS" upcoming list; dashed "Añadir rango" CTA; "Rangos pasados" history row/screen. **Correction found
|
||||
at apply time**: `PantallaVacaciones` calls the new `EstadoAlarmas` query methods with NO `ahora` argument
|
||||
(production code always uses real `DateTime.now()` — the `{DateTime? ahora}` clock injection exists for STATE-
|
||||
layer tests only, per ADR-6's own explicit rejection of a testable Clock abstraction). The first draft used
|
||||
hardcoded calendar-literal vacation ranges assuming a fixed "today", which silently exercised the WRONG
|
||||
code path once real time didn't match; fixed by building every fixture's `RangoVacaciones` dates relative to
|
||||
the real `DateTime.now()` (e.g. `hoyDia.add(Duration(days: 5))`) instead.
|
||||
- [x] 9.4 GREEN — add the 4 pure query members to `EstadoAlarmas` (`{DateTime? ahora}` defaulting to
|
||||
`DateTime.now()`), delegating `rangoVacacionesActivo` to the existing `RangoVacaciones.contiene(fecha)`.
|
||||
- [ ] 9.5 GREEN — add `ImpactoVacaciones` beside `RangoVacaciones` in `lib/modelos/alarma_musical.dart`.
|
||||
- [ ] 9.6 GREEN — build `lib/pantallas/pantalla_vacaciones.dart` as a `PluriPushScaffold`; wire WU8's summary-row
|
||||
tap to it.
|
||||
- [ ] 9.7 REFACTOR — confirm none of the 4 new methods call `guardarVacaciones` or any reprogramming path
|
||||
(read-only over `_alarmas`/`_vacaciones`); confirm no ticker/periodic timer was added.
|
||||
- [ ] 9.8 Verify — `pantalla_alarma_sonando_dismiss_guard_test.dart` passes **unmodified** (hard rule — if a query
|
||||
addition appears to require touching it, STOP and escalate; do not edit the test).
|
||||
- [x] 9.5 GREEN — add `ImpactoVacaciones` beside `RangoVacaciones` in `lib/modelos/alarma_musical.dart`.
|
||||
- [x] 9.6 GREEN — build `lib/pantallas/pantalla_vacaciones.dart` as a `PluriPushScaffold`; wire WU8's summary-row
|
||||
tap to it. **Apply-time simplification, not spec-tested**: the "Añadir rango" CTA is a solid `OutlinedButton`,
|
||||
not a literally dashed border — no dashed-border utility exists in this codebase beyond WU4's own private
|
||||
one-off `_DashedBorderPainter` (`pantalla_favoritos.dart`), and duplicating a cosmetic `CustomPainter` for a
|
||||
detail no GIVEN/WHEN/THEN scenario actually tests isn't justified. The add-range form (`_EditorVacacionesSheet`,
|
||||
`_PickerButton`) was MOVED verbatim from `pantalla_alarmas.dart` (its only remaining consumer after WU8's
|
||||
placeholder is deleted below) rather than duplicated.
|
||||
- [x] 9.7 REFACTOR — confirm none of the 4 new methods call `guardarVacaciones` or any reprogramming path
|
||||
(read-only over `_alarmas`/`_vacaciones`); confirm no ticker/periodic timer was added. Also deleted WU8's own
|
||||
placeholder (`_PantallaVacacionesTemporal`) and the now-dead `_nombreVisibleVacaciones` wrapper from
|
||||
`pantalla_alarmas.dart`, and rewired the summary row's `onTap` to `PantallaVacaciones`.
|
||||
- [x] 9.8 Verify — `pantalla_alarma_sonando_dismiss_guard_test.dart` passes **unmodified** (hard rule — if a query
|
||||
addition appears to require touching it, STOP and escalate; do not edit the test). Confirmed via `git diff`
|
||||
(empty) and a full re-run (all 8 cases green) alongside the WU9 scoped suite.
|
||||
|
||||
## WU10 — Alarm editor sheet rewrite
|
||||
|
||||
|
||||
Reference in New Issue
Block a user