Matt ef379013e6 feat(uat-batch): U66 — EOI berth-scope picker inside generate dialog
Closes plan item 66 part (c). Parts (a)+(b) shipped earlier (05e727f
defaults flip + linked-berths-list rename); this is the
picker-inside-generate-dialog that the rep sees at the moment the
"which berths does this EOI cover?" question is actually live in their
head, instead of relying on them having visited LinkedBerthsList
toggles upstream.

EoiGenerateDialog gains:
- A new useQuery against /api/v1/interests/[id]/berths returning every
  linked berth + its current isInEoiBundle / isSpecificInterest flags.
- A local Map<berthId, {isInEoiBundle, isSpecificInterest}> seeded
  once from the server snapshot and isolated from subsequent refetches
  (so a background refetch doesn't wipe pending checks). Resets when
  the dialog closes.
- A new "EOI scope" section in the body listing every linked berth
  with two checkboxes ("In EOI" / "Public map"), primary-marked
  visually, plus a one-line legend explaining the bundle-vs-public
  distinction (matters more post-(a) since the two flags routinely
  diverge).
- handleGenerate diffs the picker state against the server snapshot
  before kicking off the envelope; only changed berths get PATCHed,
  and we wait for all PATCHes to settle (so a 5xx surfaces before the
  EOI fires). Cache invalidation extended to bounce the new
  ['interests', id, 'berths'] queryKey so the LinkedBerthsList tab
  picks up the new state on navigation.

The "Manage linked berths" cross-link below is preserved — the picker
is the in-dialog fast path, not a replacement for the full management
surface.

1454/1454 vitest, tsc clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 13:07:29 +02:00
Description
No description provided
25 MiB
Languages
TypeScript 98.7%
HTML 1%
CSS 0.1%
Shell 0.1%