Skip to content

feat(representative-detail): display linked laws (representative_law M2M)

What it does

Replaces the "Refonte graphique en cours, cette section revient bientôt" placeholder in the representative-detail linked-laws section with a working component: <risefor-laws-grid> — the laws this representative is related to (the representative_law M2M), rendered with the same card family as the law listing (title, legislature/organe/procedure chips, last-act date, "Voir le détail" button navigating to law-detail).

  • Instances without the law-tracker (and reps without linked laws) render no block at all — no empty shells.
  • Cards match the listing family (own sheet per the shadow-DOM rule; grid: auto-fill minmax(280px,1fr), single column on mobile).

How the M2M is fetched (and why not the obvious way)

The naive path — adding representative_law with expand: true to the shared cherryPickedProperties — starves: the expand machinery re-applies every expand:true property to each nested resource, so each law's risefor_representative container (hundreds of reps per law) gets crawled. Measured: 412 _getProxyValue calls per page, task never settles.

Instead: _fetchRelatedLaws() fetches the container by URL (<rep>/representative_law/ — direct, reliable) and expands each law with a narrow 6-property list (name/legislature/dateDernierAct/organeReferent/procedureParlementaire/@id). ~6 calls total.

Bonus: fixes the infinite "Chargement en cours..." spinner (the bug Iris hit)

While testing, the stuck-loading bug (some reps hang forever on the spinner) reproduced 0/3 loads. Two root causes fixed here:

  1. Route guard zombie: the Task's early return when currentRoute is empty (router not ready at first run) leaves the Task PENDING forever — args stop changing, nothing re-runs it. Fix: empty currentRoute = router not ready = pass through (only block on a real mismatch).
  2. Pending watchdog: the Task can still enter never-settling states (sibStore memoizes per-resource pending promises internally — upstream startinblox behavior, ticket-worthy). New updated()-based watchdog: if still PENDING after 12s, bump _reloadTrigger by 2 (odd increments = always-fresh args tuple; a +1 re-hit the memoized zombie). Measured: 0/3 loads rendered before; 3/3 recover after (32–37s worst case, typically faster).

Also fixed the section typo: "Cet élu travail sur les lois" → "travaille".

Verification (local WebKit 26.5, iPhone UA, prod-like local data)

  • Rep 10988 (5 linked laws): 3/3 fresh loads → content + 5 cards + relatedLaws=5, consistent across loads.
  • tsc: zero new errors (802 total = pre-existing strict noise, stash-compare verified).
  • Cards aligned, chips/dates readable — same family as law listing (screenshot-verified).

Known follow-up (not in this MR)

  • The residual sibStore zombie (first pre-hydration getData for a URL can memoize a never-settling promise) makes first-load recovery slow on some navigations. Watchdog makes it deterministic but not instant. Root cause lives in upstream store internals — worth an upstream ticket + possibly a store-level cache-invalidation call. Filed separately.
  • Law cards could later reuse the status-pill treatment when law listing gets it.

⚠️ Deploy protocol as usual: merge → pull prod → purge Cloudflare.

Merge request reports