Jelajahi Sumber

P2-6: page-parameter + Custom Action fetchAlleHorecagelegenheden + Custom Function filterHorecagelegenheden gebouwd

- HorecagelegenheidoverzichtCall kreeg een page-parameter (Integer,
  default 0)
- Nieuwe Custom Action fetchAlleHorecagelegenheden: haalt alle
  pagina's op (loop tot <100 items, max 10 iteraties veiligheidslimiet)
- Nieuwe Custom Function filterHorecagelegenheden: naam- (diacritics-
  genormaliseerd) + categorie-filter. Kostte veel pogingen door een
  nieuw builder-quirk (lokale closure breekt Save Function-validatie),
  nu vastgelegd in CLAUDE.md, samen met een Ctrl+A/Delete-bug in de
  Custom Code-editor
- Widget-wiring (TextField, categorie-chips, Generate Dynamic
  Children herbinden) bewust aan Bob overgelaten: canvas-werk op een
  pagina waar hij actief zelf op zit, exacte stappen in TASKS.md

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
bob 2 minggu lalu
induk
melakukan
aa2929eb8a
2 mengubah file dengan 82 tambahan dan 0 penghapusan
  1. 39 0
      CLAUDE.md
  2. 43 0
      TASKS.md

+ 39 - 0
CLAUDE.md

@@ -473,6 +473,45 @@ dat al bevestigd werkt.
 
 ## FlutterFlow-builder: bekende problemen & patronen
 
+**Een Custom Function met een lokale geneste closure/functie in de body
+(`final x = (String input) { ... };` of `String x(String input) { ... }`
+binnen de functie zelf) laat "Save Function" mislukken met "The
+function is empty or cannot be parsed" — ook als de Dart-code zelf
+100% valide is.** Bevestigd 2026-08-25 (P2-6,
+`filterHorecagelegenheden`): een custom function die intern een kleine
+helper-closure declareerde (voor tekst-normalisatie, hergebruikt op 2
+plekken in de body) kreeg deze foutmelding bij elke opslagpoging,
+ondanks een correct geformatteerde, brace-gebalanceerde body. Pas na
+het volledig verwijderen van de geneste closure (logica in plaats
+daarvan inline uitgeschreven, 2x gedupliceerd i.p.v. 1x als helper)
+sloeg de functie wél op. FlutterFlow's eigen validator lijkt dus een
+lichte, niet-volledige parser te gebruiken die struikelt over een 2e
+`(params) { ... }`-patroon binnen de functie-body. **Vuistregel:**
+custom-function-bodies plat/zonder lokale closures schrijven; heb je
+gedeelde logica nodig, maak er een aparte top-level Custom Function
+van (die roep je dan gewoon aan vanuit de andere) i.p.v. een lokale
+helper te nesten.
+
+**De Custom Code-editor (Function/Action): tekst selecteren via
+toetsenbord (Ctrl+A, Home+Shift+Ctrl+End) en daarna Delete/Backspace
+drukken werkt structureel niet — de selectie is zichtbaar (blauw
+gemarkeerd) maar Delete/Backspace laat de tekst ongewijzigd staan.**
+Bevestigd 2026-08-25: herhaaldelijk getest (los Ctrl+A, los
+Home+Shift+Ctrl+End, beide gevolgd door zowel Delete als Backspace) —
+nooit een zichtbare wijziging, ondanks een overduidelijk gemarkeerde
+selectie. Losse toetsen als Ctrl+Z (undo) en gewoon typen werken wel
+gewoon. **Werkende omweg: typen ZONDER voorafgaande delete-actie**
+overschrijft de selectie namelijk ook niet (bevestigd, het getypte
+kwam ernaast/erin terecht i.p.v. de selectie te vervangen) — dus bij
+een foute/verouderde inhoud is er geen betrouwbare manier om gericht
+te muteren; de enige robuuste route is **Cancel → "Discard new custom
+code?" → Yes** en volledig opnieuw beginnen met één ononderbroken
+`type`-actie in een leeg codeveld. Een geslaagde eerste-keer-typing in
+een vers/leeg codeveld werkt wél betrouwbaar; het is specifiek
+achteraf-bewerken dat corrumpeert (waargenomen: oude en nieuwe tekst
+raken door elkaar gemengd, bv. `Strinal` uit een samengevoegde
+`String`/`final`).
+
 **Een Project Component naar een specifieke plek in de Widget Tree
 slepen (canvas-dropzone, zie het bestaande recept elders in dit
 bestand) kan structureel mislukken als een fixed-size kind-widget

+ 43 - 0
TASKS.md

@@ -2169,6 +2169,49 @@ dus ook een complete dataset vereist.
   beperking uit `CLAUDE.md` (geen Tooltip nodig, gewoon een losse
   `onTap` die `zoekterm` leegt).
 
+**Voortgang (2026-08-25, Claude, builder) — stappen 1, 2 en 5 volledig
+afgerond en bevestigd via verse export + `flutter analyze` (0
+errors):**
+- **Stap 1:** `page`-parameter (Integer, default `0`) toegevoegd aan
+  `HorecagelegenheidoverzichtCall` (Variables + Query Parameters,
+  gebonden via "From Variable").
+- **Stap 2:** Custom Action `fetchAlleHorecagelegenheden(String horcat,
+  String townid, String displayId) -> List<dynamic>` staat in
+  `lib/custom_code/actions/fetch_alle_horecagelegenheden.dart` — haalt
+  pagina's op tot een pagina <100 items teruggeeft (max 10 iteraties
+  als veiligheidslimiet).
+- **Stap 5:** Custom Function `filterHorecagelegenheden(...)` staat in
+  `lib/flutter_flow/custom_functions.dart` — combineert naam-match
+  (diacritics-genormaliseerd) met categorie-match. **Kostte
+  ongebruikelijk veel pogingen** door een nieuw ontdekt
+  builder-quirk: een lokale geneste helper-closure in de body brak de
+  "Save Function"-validatie structureel ("cannot be parsed", ondanks
+  valide Dart) — opgelost door de normalisatielogica plat/zonder
+  closure te schrijven (2x inline i.p.v. 1x als helper). Zie de nieuwe
+  `CLAUDE.md`-notitie voor het volledige patroon + een tweede
+  bijvangst-ontdekking (Ctrl+A/Delete werkt structureel niet in de
+  Custom Code-editor).
+- **Stappen 3, 4, 6 (widget-wiring: TextField, categorie-chips,
+  Generate Dynamic Children herbinden) nog te doen — dit is
+  builder-canvas-werk op een pagina waar Bob actief mee bezig is
+  (Sort/Datatype-experiment), dus bewust aan Bob overgelaten i.p.v.
+  door Claude gedaan.** Concreet, per tab van
+  `horecagelegenheden_overzicht_widget.dart` (en de provincie-variant):
+  1. `TextField` boven de `TabBar` invoegen, Local/Page State
+     `zoekterm` (String) via `onChanged` bijwerken.
+  2. Een manier om `categorieFilter` te kiezen (chips/dropdown) — opties
+     dynamisch uit de complete dataset, niet hardcoded.
+  3. Op page/tab-load: `fetchAlleHorecagelegenheden` aanroepen (met de
+     juiste `horcat`/`townid`/`displayId` voor die tab) → resultaat in
+     een Component State-variabele (bv. `alleItemsTabX`).
+  4. De tab's `Generate Dynamic Children`-"Value" ombouwen naar
+     `filterHorecagelegenheden(alleItemsTabX, zoekterm, categorieFilter,
+     '$.titel', '$.categorie')` (exacte JSON-paths per tab checken —
+     kunnen verschillen).
+  5. Verse export + `flutter analyze` om te bevestigen dat
+     `fetchAlleHorecagelegenheden`/`filterHorecagelegenheden` nu
+     daadwerkelijk aangeroepen worden.
+
 *(P2-14 volledig afgerond 2026-08-25 — Custom Function `googleMapsUrl`
 + Project Component `GoogleMapsIconButton` gebouwd door Claude, op
 beide pagina's (`horecagelegenheid_current_widget.dart`,