瀏覽代碼

132-B uitgezocht: oorzaak bevestigd, alternatief afgevallen, chips-lek als 132-N

- 132-B: redenering over de Initial-Value-valkuil gecorrigeerd (de controller
  wordt in initState van het component aangemaakt, ongeacht de zoekOpen-conditie;
  wat het veilig maakt is dat de bron App State is).
- 132-B: het alternatief "per scherm wissen via On Page Load" geschrapt — de
  drawer gebruikt pushNamed, dus Home blijft op de stack met een gevulde
  controller en zou na een back-navigatie 'jazz' tonen zonder actief filter.
- 132-N toegevoegd: de datumfilter-chips hebben exact hetzelfde lek
  (hardcoded FormFieldController(['Alles'])), plus een sync-probleem binnen
  één pagina na gebruik van de datumprikker. Drie oplossingsroutes beschreven.
- 132-I: drie dode restanten rond de filterbalk genoteerd (zoekActief,
  parameter1, page state zoekOpen op Home).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bob 1 天之前
父節點
當前提交
0625dd39fb
共有 1 個文件被更改,包括 76 次插入8 次删除
  1. 76 8
      TASKS.md

+ 76 - 8
TASKS.md

@@ -444,9 +444,12 @@ Waarom dit de juiste richting is: het ontwerp is al "de filterbalk is globaal"
 (`zoekOpen` reist immers ook mee). Dan hoort het veld te tónen waarop gefilterd
 wordt, in plaats van de filter stilletjes te verbergen.
 
-De bekende "Initial Value wordt te vroeg gelezen"-valkuil speelt hier **niet**:
-het veld staat achter `if (FFAppState().zoekOpen)` en bestaat dus pas nadat de
-gebruiker het zoeken heeft geopend — op dat moment is de App State al gevuld.
+De bekende "Initial Value wordt te vroeg gelezen"-valkuil speelt hier **niet** —
+maar niet om de reden die je zou denken. De controller wordt aangemaakt in
+`initState` van het *component*, dus ongeacht de `if (FFAppState().zoekOpen)`
+eromheen (alleen het `TextFormField` zelf is conditioneel). Wat het veilig maakt
+is de **bron**: App State is al gevuld vóórdat er genavigeerd werd, anders dan
+een page state die pas in een On-Page-Load-actie gezet wordt.
 
 Builder-stappen:
 1. `FilterBalkComponent` openen, het `TextField` in de tree selecteren.
@@ -466,11 +469,68 @@ Testen op een toestel: Home → vergrootglas → zoek `jazz` → menu → Gemeen
 Uitgaan. Het veld moet nu **`jazz`** tonen bij dezelfde drie treffers. Wis het
 veld → lijst loopt weer vol (reken op de 2 s debounce).
 
-**Alternatief als je liever hebt dat zoeken per scherm is:** zet in plaats
-daarvan op beide pagina's een On-Page-Load-actie die `zoekterm` én `zoekOpen`
-reset. Dat is meer werk (twee pagina's) en je verliest de zoekterm bij elke
-navigatie — maar het is verdedigbaar, want het aanbod verschilt per scherm. Kies
-er één; de combinatie van beide is zinloos.
+#### ⚠️ Het alternatief "per scherm wissen" is GEEN gelijkwaardige keuze — afgevallen
+
+Eerder stond hier dat je in plaats hiervan op beide pagina's een On-Page-Load-actie
+kon zetten die `zoekterm` + `zoekOpen` reset. Nagelopen 2026-09-22: **dat maakt het
+beeld omgekeerd kapot.** De drawer navigeert met `context.pushNamed(...)`
+(`drawer_component_widget.dart`), dus Home blijft gewoon op de stack staan mét zijn
+paginamodel en zijn controller waar `jazz` in staat. Wist `PUitgaanPage` bij het
+openen de App State, dan toont Home ná een back-navigatie het woord `jazz` in het
+veld terwijl er niets meer gefilterd wordt — dezelfde verwarring, andere kant op.
+En dat is niet te repareren met nóg een actie, want bij een pop draait On Page Load
+niet.
+
+De Initial-Value-binding heeft dat probleem niet: een pagina die blijft bestaan
+houdt zowel zijn controller als de App State, en die twee blijven dus in sync.
+
+### 132-N · Datumfilter-chips lekken óók — zelfde component, zelfde oorzaak (pak samen met 132-B)
+
+Gevonden 2026-09-22 tijdens het uitzoeken van 132-B, in dezelfde
+`FilterBalkComponent`. De chips hangen aan een **hardcoded** controller:
+
+```dart
+controller: _model.choiceChipsValueController ??=
+    FormFieldController<List<String>>([ getText('u4ve4egb' /* Alles */) ]),
+```
+
+`FFAppState().datumFilter` reist dus mee naar de volgende pagina, maar de chipbalk
+begint daar altijd weer op **Alles**. Twee gevolgen:
+
+1. **Bij een paginawissel** (Home → Uitgaan): lijst gefilterd op `Vandaag`, chip
+   zegt `Alles`. Nóg onzichtbaarder dan het zoekveld, want het `Text`-label naast
+   de kalenderknop toont `datumKnopLabel('Vandaag')` → dat geeft `''` (de functie
+   accepteert alleen een `JJJJ-MM-DD`-string), dus `valueOrDefault` maakt er
+   `Datum` van. Er staat dan letterlijk nergens op het scherm dat er een
+   datumfilter actief is.
+2. **Binnen één pagina al**, na gebruik van de datumprikker: `datumFilter` wordt
+   `2026-09-25`, maar de eerder gekozen chip blijft geselecteerd. Twee filters
+   lijken aan te staan terwijl er één geldt.
+
+#### Waarom dit niet dezelfde one-liner is als 132-B
+
+De chips hebben wél een **Initial Option**-slot, maar de gekozen waarde is
+tegelijk het zichtbare *label* — en dat label is vertaald (`Alles`/`All`,
+`Deze week`/`This week`). Een rechtstreekse binding aan `datumFilter` werkt voor
+`Vandaag`/`Weekend`/`Deze week` en laat bij een prikkerdatum netjes niets
+geselecteerd (correct), maar valt om op de **startwaarde `''`**: dan matcht geen
+enkele optie en staat er helemaal geen chip aan, terwijl `Alles` hoort. Een
+custom function die bij `''` het woord `Alles` teruggeeft, breekt in het Engels.
+
+Drie routes, oplopend in netheid:
+- **a.** Initial Option binden aan `datumFilter` en accepteren dat er bij een
+  verse start geen chip oplicht. Eén binding, geen nieuwe code.
+- **b.** Idem, plus een custom function die `''` vertaalt naar het juiste label op
+  basis van de taalcode (Global Properties → Language Code).
+- **c.** Structureel: `datumFilter` niet meer met labels vullen maar met sleutels
+  (`alles`/`vandaag`/`weekend`/`week`/een datum), en de chips daar los van zetten.
+  Dan is de i18n-koppeling helemaal weg. Raakt wel `filterDatumVan`/`filterDatumTot`
+  (die matchen nu op substring, dus die blijven gewoon werken) en de `onChanged`
+  van de chips.
+
+Let bij a en b op de valkuil uit `CLAUDE.md`: **een chiplabel is tegelijk de
+waarde**, en een lege `en`-vertaling levert een lege string op — niet een
+terugval op het Nederlands.
 
 ### 132-C · Stadsrechten publiceren NIET direct — backend moet mee · Eigenaar: Bob (Drupal)
 
@@ -601,6 +661,14 @@ eerste tab naar die knop (of toon `LegeLijstComponent` met die tekst).
 
 ### 132-I · Kleine punten
 
+- **Drie dode restanten rond de filterbalk** (gevonden bij 132-B, 2026-09-22 —
+  alleen opruimen, geen gedragswijziging; **Claude raakt dit niet aan**):
+  App State **`zoekActief`** wordt nergens gelezen of gezet; de
+  component-parameter **`parameter1`** van `FilterBalkComponent` wordt nergens
+  in dat component gebruikt (Home geeft er `_model.zoekOpen` aan mee,
+  `PUitgaanPage` letterlijk `false`); en de page state **`zoekOpen` op Home**
+  wordt nergens meer geschreven — dat is een restant van vóór de verhuizing naar
+  App State.
 - **Build-stempel zichtbaar voor eindgebruikers.** `functions.buildStempel()`
   staat onderaan de **drawer** én op **Favorieten** en toont `onbekend` zolang er
   geen `--dart-define=BUILD_TS=…` meegaat. Weghalen vóór livegang, of vullen.