teqo-backup/src/components
Francisco Ignácio Fontoura Solla 155f6492d9 B17: column picker on the seven CampaignTable list surfaces.
The picker shipped as a capability of CampaignTable rather than a municípios
feature, so every list that already uses the shared table got it: pass
`columnVisibility` and the table mounts the menu and filters the columns.

Persistence is a cookie, not localStorage, and the reason is a type rather
than a preference: CampaignTableColumn.cell is a function, so the column array
never crosses the server/client boundary and the client cannot rebuild the
table without it. The server filters, so a hidden column does not reach the RSC
payload either. `campaign_columns` carries a listId -> hidden ids map in a
compact form with no JSON and no percent-encoding, because document.cookie and
Next's cookies() disagree about decoding.

Closing the menu is the commit. The first cut debounced at 400 ms, which
batches a burst rather than a reading pace, so unchecking four columns while
reading their labels was four full-route refreshes — on /campanha/liderancas
each one re-pays the ~229 ms / 371-statement render already ledgered P1. The
timer survives at 3 s as a safety net for a menu left open; the price is that
the table behind the menu no longer updates per checkbox.

`defaultVisible` is gone: it was true on 10 columns and false on none, and
storing only the hidden set is what makes a newly shipped column visible to
everyone who never touched the picker. In exchange `label` is required, which
made `head` optional — 24 columns had a head that only restated the new label.
Each surface declares one mandatory column, re-filtered on the server so a
stale cookie cannot leave a row without its only linked cell.

The bug review caught is this codebase's recurring one: the RSC payload of
toggle A arrives inside the window of toggle B, and adopting the server there
undid B and then committed the set without it. Reconciliation now runs only
when no write is pending, pinned red against the previous code.

Municipality column ids are typed against MunicipalityListColumnId now, so the
id, the B22 description and the picker label are one key; the union member
`nivel` was renamed `level` to match the id and the ?level= filter. The
picker's own content comparison is sameIdSet, widened to string ids.
2026-07-28 08:25:16 -03:00
..
campaign B17: column picker on the seven CampaignTable list surfaces. 2026-07-28 08:25:16 -03:00
ui B34: editable município chips on the leaderships list. 2026-07-27 22:35:19 -03:00
CitySelect.tsx Replace state/city selects with type-to-filter comboboxes 2026-07-15 14:41:58 -03:00
EmailInput.tsx Improve Inputs 2026-03-20 12:36:16 -03:00
Footer.tsx Deliver Onda 0 MVP: provisional Consent, privacy policy, and /privacidade. 2026-07-19 03:38:21 -03:00
FormattedInput.tsx Ship /campanha nuclei MVP with RBAC, invites, and vote estimates. 2026-07-18 15:01:56 -03:00
FormCombobox.tsx Replace state/city selects with type-to-filter comboboxes 2026-07-15 14:41:58 -03:00
FormInput.tsx Ship /campanha nuclei MVP with RBAC, invites, and vote estimates. 2026-07-18 15:01:56 -03:00
MetaPixel.tsx Add the tooling gate: knip, CI, zero-warning lint, as-never ban 2026-07-23 23:06:12 -03:00
NameInput.tsx Improve NameInput 2026-03-20 15:44:11 -03:00
PetitionForm.tsx Tooling: prettier como autoridade de formatacao (organize-imports deterministico, scripts format/format:check, normalizacao mecanica de 312 arquivos; artefatos gerados e migrations excluidos via .prettierignore) 2026-07-25 17:22:20 -03:00
PetitionSuccessDialog.tsx Tooling: prettier como autoridade de formatacao (organize-imports deterministico, scripts format/format:check, normalizacao mecanica de 312 arquivos; artefatos gerados e migrations excluidos via .prettierignore) 2026-07-25 17:22:20 -03:00
PhoneInput.tsx Pass 2 W2: correcoes de fronteira lib/utilities e client boundary 2026-07-25 14:38:41 -03:00
PostalCodeInput.tsx fix zip code input field 2026-05-01 00:22:18 -03:00
PostCard.tsx Tooling: prettier como autoridade de formatacao (organize-imports deterministico, scripts format/format:check, normalizacao mecanica de 312 arquivos; artefatos gerados e migrations excluidos via .prettierignore) 2026-07-25 17:22:20 -03:00
RefreshRouteOnSave.tsx Break up the god modules into deep domain modules 2026-07-23 23:44:45 -03:00
SignatureCounter.tsx Tooling: prettier como autoridade de formatacao (organize-imports deterministico, scripts format/format:check, normalizacao mecanica de 312 arquivos; artefatos gerados e migrations excluidos via .prettierignore) 2026-07-25 17:22:20 -03:00
SiteHeader.tsx Guardas programaticas: fronteira lib/ (no-restricted-imports), ban de consent id hardcoded, codebaseConventions.unit.spec (server-only, copy Praca/Nucleo, listas legadas do eslint, wrappers de formActions), ciclo do payload.config quebrado (documents/globals divididos em tags+reads), timeout global do int suite, personName schema-valido, consent drafts Onda 0 p/ Municipio 2026-07-25 18:02:02 -03:00
socialIcons.tsx Add ThankStep 2026-03-18 23:55:28 -03:00
socialLinks.tsx Guardas programaticas: fronteira lib/ (no-restricted-imports), ban de consent id hardcoded, codebaseConventions.unit.spec (server-only, copy Praca/Nucleo, listas legadas do eslint, wrappers de formActions), ciclo do payload.config quebrado (documents/globals divididos em tags+reads), timeout global do int suite, personName schema-valido, consent drafts Onda 0 p/ Municipio 2026-07-25 18:02:02 -03:00
StateSelect.tsx Replace state/city selects with type-to-filter comboboxes 2026-07-15 14:41:58 -03:00
ThemeProvider.tsx Tooling: prettier como autoridade de formatacao (organize-imports deterministico, scripts format/format:check, normalizacao mecanica de 312 arquivos; artefatos gerados e migrations excluidos via .prettierignore) 2026-07-25 17:22:20 -03:00
WhatsappForm.tsx Tooling: prettier como autoridade de formatacao (organize-imports deterministico, scripts format/format:check, normalizacao mecanica de 312 arquivos; artefatos gerados e migrations excluidos via .prettierignore) 2026-07-25 17:22:20 -03:00