Przeglądaj źródła

132-B + 132-N AF: zoekterm en datumchip reizen nu zichtbaar mee

Twee bindingen in FilterBalkComponent (gedeeld door Home en PUitgaanPage):
- TextField Initial Value -> App State zoekterm
  export: TextEditingController(text: FFAppState().zoekterm)
- ChoiceChips Initial Option -> App State datumFilter
  export: FormFieldController<List<String>>([FFAppState().datumFilter])

Op emulator-5556 bewezen: Home zoeken op 'jazz' + chip Vandaag -> menu ->
Gemeente -> Uitgaan toont nu 'jazz' in het veld en Vandaag opgelicht, in
plaats van een leeg veld bij een gefilterde lijst. Veld wissen laat de lijst
weer vollopen met de datumfilter intact. dart analyze: 0 errors.

Bijwerking zoals voorzien: bij een koude start licht geen enkele chip op tot
je iets kiest (datumFilter is dan leeg en matcht geen optielabel). Geen
crashrisico - FlutterFlowChoiceChips doet een contains() op het label.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bob 1 dzień temu
rodzic
commit
6e3881b225
1 zmienionych plików z 1 dodań i 148 usunięć
  1. 1 148
      TASKS.md

+ 1 - 148
TASKS.md

@@ -401,153 +401,6 @@ eronder mee te schuiven.
 Fix: de Column van elke tab scrollbaar maken (let op het recept in `CLAUDE.md`:
 eerst elke `Expanded` eruit, anders weigert FlutterFlow het).
 
-### 132-B · Zoekterm lekt van Home naar `PUitgaanPage`, met een leeg zoekveld
-
-`FFAppState().zoekterm` is globaal, maar `FilterBalkComponent` maakt zijn
-`TextEditingController` in `initState` **leeg** aan
-(`_model.textController ??= TextEditingController()`, geen `..text = …`).
-Reproductie: op Home zoeken op `jazz` → menu → Gemeente → Uitgaan. De lijst
-toont dan exact de 3 jazz-treffers van Amsterdam (nagemeten tegen
-`flutterflowmobiel1?zoek=jazz`), terwijl het zoekveld *Zoek op titel* als
-placeholder toont. De gebruiker ziet een vrijwel lege pagina zonder oorzaak.
-
-#### De keten (nagelopen in een verse export, 2026-09-22)
-
-1. Tik op het vergrootglas → `FFAppState().zoekOpen = !zoekOpen`, de controller
-   wordt gewist, `zoekterm = ''`, dan `herlaadLijsten()`.
-2. Het veld verschijnt (`if (FFAppState().zoekOpen)`) en op Home én `PUitgaanPage`
-   verdwijnt tegelijk de slider (`if (!FFAppState().zoekOpen)`).
-3. Typen → `EasyDebounce` 2000 ms → `FFAppState().zoekterm = controller.text` →
-   `herlaadLijsten()`.
-4. De pagina's geven `zoekterm: FFAppState().zoekterm` door aan hun
-   kaartcomponenten (Home 5×, één per tab; `PUitgaanPage` 1×), en die zetten hem
-   in hun Backend Query als query-parameter `zoek`.
-
-Alles hierin is App State — behalve de `TextEditingController`, en díe zit in het
-**component-model**. Bij een paginawissel wordt dat model vers aangemaakt
-(`_model.textController ??= TextEditingController()`, zonder `text:`), terwijl
-`zoekterm` én `zoekOpen` blijven staan. Vandaar: veld open en leeg, filter actief.
-
-⚠️ Tweede symptoom van dezelfde oorzaak: omdat `zoekOpen` ook meegaat, is op de
-nieuwe pagina óók de **slider verborgen**. Dat maakt het beeld nog verwarrender.
-
-`zoekterm` is **niet** persisted, dus een herstart van de app lost het vanzelf op
-— wat verklaart waarom dit niet eerder opviel.
-
-#### Plan van aanpak — één binding, in het gedeelde component
-
-Zet op `FilterBalkComponent` → het `TextField` → **Initial Value** een binding
-naar App State **`zoekterm`**. Dat is alles: het component wordt door beide
-pagina's gedeeld, dus één wijziging dekt Home en `PUitgaanPage`.
-
-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** —
-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.
-2. Eigenschap **Initial Value** → klik het kleine **⚏-icoontje naast het label**.
-   ⚠️ Níét het icoontje rechts in die rij — dat is de vertaal-globe, die vervangt
-   het hele rechterpaneel door "Setting Translations" (onschadelijk, klik *Back*).
-3. Set from Variable → zoekveld: typ **`zoek`** (levert `zoekterm`, `zoekActief`
-   en `zoekOpen` op — bewust een term die meer dan één bron overhoudt, anders
-   rendert de optielijst leeg) → App State → **`zoekterm`**. Rendert de rij leeg:
-   hover er eerst vanaf een andere positie naartoe, in dezelfde tool-aanroep.
-4. Confirm.
-
-Verwachte export:
-`_model.textController ??= TextEditingController(text: FFAppState().zoekterm)`.
-
-Testen op een toestel: Home → vergrootglas → zoek `jazz` → menu → Gemeente →
-Uitgaan. Het veld moet nu **`jazz`** tonen bij dezelfde drie treffers. Wis het
-veld → lijst loopt weer vol (reken op de 2 s debounce).
-
-#### Wat deze fix NIET oplost — één randgeval op de terugweg
-
-De controller wordt met `??=` aangemaakt, dus de binding grijpt alleen op een
-**verse** pagina. Ga je van Home naar `PUitgaanPage` (veld toont `jazz` ✅), wis je
-het daar, en navigeer je terug, dan leeft Home nog op de stack: `initState` draait
-niet opnieuw, dus het veld toont nog `jazz` terwijl `zoekterm` inmiddels leeg is —
-de spiegel van deze bug. Wel milder: je ziet een vólle lijst, dus het leest als
-"het filter doet niets" in plaats van "de app is stuk", en één aanraking van het
-veld zet het recht.
-
-Niet te repareren met een `ValueKey` op de component-instantie: die vervangt de
-`State`, maar het model — en dus de `TextEditingController` — komt via de Provider
-uit het paginamodel en overleeft (zie het `pagingController`-verhaal in
-`CLAUDE.md`). Volledig sluitend zou custom code vergen die de controller bij elke
-rebuild synct; besloten 2026-09-23 dat dat te veel machinerie is voor dit symptoom.
-
-#### ⚠️ 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)
 
 **Bob 2026-09-22: "als iemand stadsrechten heeft, mag de activiteit direct
@@ -850,7 +703,7 @@ 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 —
+- **Drie dode restanten rond de filterbalk** (gevonden 2026-09-22 bij het zoeklek
   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