diff --git a/src/lib/campaignHomeActions.ts b/src/lib/campaignHomeActions.ts index 40da5fc4..cd04fe35 100644 --- a/src/lib/campaignHomeActions.ts +++ b/src/lib/campaignHomeActions.ts @@ -124,6 +124,18 @@ export type ResolvedCampaignHomeAction = CampaignHomeAction & { href?: string } +/** Mirrors Início `buildMunicipalityListHref({ coverage: 'sem_assessor', sort: 'votos' }, 1)`. */ +export const UNCOVERED_MUNICIPALITIES_LIST_HREF = + '/campanha/municipios?coverage=sem_assessor&sort=votos' as const + +/** Staff Início catalog with hrefs — shared by quick-action registries (B81+). */ +export const resolveStaffHomeQuickActions = ( + role: CampaignRole, +): readonly ResolvedCampaignHomeAction[] => { + if (!isStaffCampaignRole(role)) return [] + return toHomeActionButtonProps(homeActionsForRole(role), UNCOVERED_MUNICIPALITIES_LIST_HREF) +} + export const toHomeActionButtonProps = ( actions: readonly CampaignHomeAction[], uncoveredMunicipalitiesHref?: string, diff --git a/src/lib/campaignQuickActionRegistry.ts b/src/lib/campaignQuickActionRegistry.ts index ff2f3eec..d3960cd9 100644 --- a/src/lib/campaignQuickActionRegistry.ts +++ b/src/lib/campaignQuickActionRegistry.ts @@ -1,14 +1,25 @@ -import type { ResolvedCampaignHomeAction } from '@/lib/campaignHomeActions' +import { + resolveStaffHomeQuickActions, + type ResolvedCampaignHomeAction, +} from '@/lib/campaignHomeActions' import type { CampaignQuickActionContext } from '@/lib/campaignQuickActionContext' import type { CampaignRole } from '@/lib/campaignRoles' +const isTerritoriesListPath = (pathname: string): boolean => + pathname === '/campanha/territorios' || pathname.startsWith('/campanha/territorios/') + /** * Pathname + role + page context → contextual quick actions. * Catalogs per vertical land in B80–B90; the B79 chassis renders whatever * this helper returns (empty until those items register providers). */ export const resolveQuickActionsForPath = ( - _pathname: string, - _role: CampaignRole, + pathname: string, + role: CampaignRole, _context: CampaignQuickActionContext, -): readonly ResolvedCampaignHomeAction[] => [] +): readonly ResolvedCampaignHomeAction[] => { + if (isTerritoriesListPath(pathname)) { + return resolveStaffHomeQuickActions(role) + } + return [] +} diff --git a/tests/unit/campaignQuickAction.unit.spec.ts b/tests/unit/campaignQuickAction.unit.spec.ts index 9447fcaa..5322d5e2 100644 --- a/tests/unit/campaignQuickAction.unit.spec.ts +++ b/tests/unit/campaignQuickAction.unit.spec.ts @@ -12,6 +12,10 @@ import { QUICK_ACTIONS_SNAP_EXPANDED, quickActionsSnapIsExpanded, } from '@/lib/campaignQuickActionSnap' +import { + UNCOVERED_MUNICIPALITIES_LIST_HREF, + homeActionsForRole, +} from '@/lib/campaignHomeActions' describe('campaignQuickActionMount', () => { it('treats Início as exact match only', () => { @@ -34,6 +38,7 @@ describe('campaignQuickActionMount', () => { it('mounts for staff outside Início and acoes', () => { expect(shouldMountQuickActionsDrawer('/campanha/municipios', 'coordinator')).toBe(true) + expect(shouldMountQuickActionsDrawer('/campanha/territorios', 'coordinator')).toBe(true) expect(shouldMountQuickActionsDrawer('/campanha', 'coordinator')).toBe(false) expect(shouldMountQuickActionsDrawer('/campanha/acoes/registrar-sinal', 'advisor')).toBe(false) }) @@ -45,13 +50,33 @@ describe('campaignQuickActionMount', () => { }) describe('campaignQuickActionRegistry', () => { - it('returns empty catalog until B80+ register providers', () => { + const staffActionIds = homeActionsForRole('coordinator').map((action) => action.id) + + it('returns empty catalog for unregistered paths', () => { expect( resolveQuickActionsForPath('/campanha/municipios/foo', 'coordinator', { municipalitySlug: 'foo', }), ).toEqual([]) }) + + it('returns staff Início catalog on territorios without municipality prefill (B81)', () => { + const actions = resolveQuickActionsForPath('/campanha/territorios', 'coordinator', {}) + expect(actions.map((action) => action.id)).toEqual(staffActionIds) + expect(actions.find((action) => action.id === 'update-votes')?.href).toBe( + '/campanha/acoes/atualizar-votos', + ) + expect(actions.find((action) => action.id === 'uncovered-municipalities')?.href).toBe( + UNCOVERED_MUNICIPALITIES_LIST_HREF, + ) + for (const action of actions) { + expect(action.href).not.toContain('municipio=') + } + }) + + it('returns empty catalog on territorios for leader lockdown', () => { + expect(resolveQuickActionsForPath('/campanha/territorios', 'leader', {})).toEqual([]) + }) }) describe('campaignQuickActionSnap', () => {