Coluna "Dobradinhas" em /campanha/liderancas com chips clicáveis para /campanha/dobradinhas/<slug> e edição via Popover+Command (padrão B27, escrita via server action delta + lock, como B19). - LeadershipRowViewModel.stateDeputies (StateDeputySummary[]) via loadStateDeputySummaries, substituindo stateDeputyNames. - setLeadershipStateDeputyMembership(Record): delta com withPayloadTransaction + acquireTextAdvisoryLocks + revalidatePath. - nextStateDeputyIdsAfterMembership (lib/leadershipStateDeputyMembership.ts), espelha nextAdvisorIdsAfterMembership. - loadStateDeputyOptions estendido com plainName/party/slug. - Catálogo entregue uma vez por tabela via leadershipColumns(options) (columns factory, mesmo precedente de municipalityListColumns). /simplify (1ª rodada): corrige revert otimista por delta (não pelo snapshot inteiro), remove fallback silencioso na adição, extrai sameIdSet compartilhado com MunicipalityListAdvisorsControl (B27), e evita leitura+revalidação supérfluas no caminho no-op da action. /simplify (2ª rodada, pós-rebase): troca o StateDeputyOptionsProvider (Context) inicial pela columns factory acima — a 1ª rodada tinha validado o Context por falta da evidência de que MunicipalityList.tsx já resolve o mesmo problema sem Context; corrige revalidatePath para o id concreto em vez do template dinâmico '/campanha/liderancas/[id]' (que invalidava toda ficha a cada toggle); remove non-null assertion movendo a guarda para dentro do setCurrent updater. Gate verde: tsc, lint --max-warnings=0, format:check, unit 530/530, int 406/406 (incl. os 6 de campaignLeadershipStateDeputyMembership), build. Aikido: 0 achados nos arquivos novos/editados.
11 lines
518 B
TypeScript
11 lines
518 B
TypeScript
/**
|
|
* Order-independent equality for two id lists — the guard every list-cell
|
|
* optimistic-state hook uses to tell a genuine external prop change
|
|
* (navigation/RSC refresh) apart from a re-render carrying the same
|
|
* pre-edit content (which must not clobber in-flight optimistic state).
|
|
*/
|
|
export const sameIdSet = (left: readonly number[], right: readonly number[]): boolean => {
|
|
if (left.length !== right.length) return false
|
|
const rightSet = new Set(right)
|
|
return left.every((id) => rightSet.has(id))
|
|
}
|