teqo-backup/src/app/(campaign)/campanha/(app)/liderancas/[id]/formActions.ts
Francisco Ignácio Fontoura Solla 812e3a0bee B34: editable município chips on the leaderships list.
The "Municípios" column was dead text; it is now chips that navigate to the
município, with a territory chip when a leadership covers a whole TI, and it is
editable in place. What picks inline vs. Drawer is the `pointer:` media query,
not viewport width: on a fine pointer the editor is always mounted (the "×" sits
at the chip's corner, revealed on hover/focus) and on a coarse pointer a tap
anywhere in the cell opens a Drawer with 44 px targets.

`AdvisorMunicipalityCell` is promoted to `shared/MunicipalityPortfolioCell` and
/campanha/assessores migrates onto it in the same change, so the second call site
is born with the first. One batch action only; the single-id advisor twin is
deleted with its int tests migrated. The anti-goal on always-mounted list inputs
is amended for chip-based relations on fine pointers, not reopened.

Also fixes a latent bug: `CampaignTableHead`'s `description` seam broke any RSC
caller, because its two helpers lived in a 'use client' module.
2026-07-27 22:35:19 -03:00

58 lines
2.2 KiB
TypeScript

'use server'
import { revalidatePath } from 'next/cache'
import { leadershipStaffEditSafeMessages } from '@/app/(campaign)/campanha/(app)/liderancas/leadershipStaffEditMessages'
import { updateLeadershipInternal } from '@/app/(campaign)/campanha/actions/leadership'
import {
nullableFormText,
optionalFormText,
repeatedRelationshipFormValues,
requiredRelationshipFormValue,
} from '@/lib/formData'
import {
LEADERSHIP_MUNICIPALITY_SCOPE_MESSAGE,
leadershipSectors,
leadershipSupportStatuses,
} from '@/lib/schemas/leadership'
import {
runCampaignFormAction,
type CampaignFormActionState,
} from '@/utilities/campaignFormActionError'
const safeMessages = [
LEADERSHIP_MUNICIPALITY_SCOPE_MESSAGE,
...leadershipStaffEditSafeMessages,
] as const
export const updateLeadershipInternalFormAction = async (
_state: CampaignFormActionState,
formData: FormData,
): Promise<CampaignFormActionState> =>
runCampaignFormAction({
execute: async () => {
const sector = optionalFormText(formData, 'sector')
const supportStatus = optionalFormText(formData, 'supportStatus')
await updateLeadershipInternal({
id: requiredRelationshipFormValue(formData, 'leadershipId'),
municipalities: repeatedRelationshipFormValues(formData, 'municipalities'),
organizations: repeatedRelationshipFormValues(formData, 'organizations'),
stateDeputies: repeatedRelationshipFormValues(formData, 'stateDeputies'),
sector: leadershipSectors.includes(sector as (typeof leadershipSectors)[number])
? (sector as (typeof leadershipSectors)[number])
: null,
supportStatus: leadershipSupportStatuses.includes(
supportStatus as (typeof leadershipSupportStatuses)[number],
)
? (supportStatus as (typeof leadershipSupportStatuses)[number])
: undefined,
notes: nullableFormText(formData, 'notes'),
consentNote: nullableFormText(formData, 'consentNote'),
})
revalidatePath('/campanha/liderancas/[id]', 'page')
return { message: 'Ficha da liderança atualizada.' }
},
safeMessages,
genericMessage: 'Não foi possível salvar a ficha. Verifique seu acesso e tente novamente.',
})