diff --git a/scripts/lib/e2e-affected-manifest.mjs b/scripts/lib/e2e-affected-manifest.mjs index 66ba5233..7ebc2db3 100644 --- a/scripts/lib/e2e-affected-manifest.mjs +++ b/scripts/lib/e2e-affected-manifest.mjs @@ -86,6 +86,8 @@ export const E2E_AFFECTED_MANIFEST = [ `${CAMPAIGN_APP}/layout.tsx`, 'src/utilities/campaignPwa', 'src/lib/campaignQuickAction', + 'src/lib/campaignReferenceQuickActions', + 'src/lib/campaignPaths.ts', ], specs: ['campaign-pwa', 'campaignWizardChrome'], }, diff --git a/src/components/campaign/shell/CampaignQuickActionsDrawer.tsx b/src/components/campaign/shell/CampaignQuickActionsDrawer.tsx index c5af7831..784818cf 100644 --- a/src/components/campaign/shell/CampaignQuickActionsDrawer.tsx +++ b/src/components/campaign/shell/CampaignQuickActionsDrawer.tsx @@ -101,9 +101,7 @@ export const CampaignQuickActionsDrawer = ({ }))} className="w-full" /> - ) : ( -

Nenhuma ação rápida nesta página.

- )} + ) : null} {expanded ? : null} diff --git a/src/lib/campaignPaths.ts b/src/lib/campaignPaths.ts index 3500430d..56c0bf02 100644 --- a/src/lib/campaignPaths.ts +++ b/src/lib/campaignPaths.ts @@ -8,3 +8,5 @@ export const CAMPAIGN_DEMANDS_HOME = '/campanha/demandas' as const export const CAMPAIGN_ADVISORS_HOME = '/campanha/assessores' as const export const LEADER_CONTACTS_HOME = '/campanha/contatos' as const + +export const CAMPAIGN_PROFILE_HOME = '/campanha/perfil' as const diff --git a/src/lib/campaignQuickActionRegistry.ts b/src/lib/campaignQuickActionRegistry.ts index da907a50..b35ab409 100644 --- a/src/lib/campaignQuickActionRegistry.ts +++ b/src/lib/campaignQuickActionRegistry.ts @@ -21,6 +21,10 @@ import { parseOrganizationQuickActionSurface, } from '@/lib/campaignQuickActionPaths' import type { CampaignQuickAction } from '@/lib/campaignQuickActionTypes' +import { + isReferenceQuickActionPath, + resolveReferenceQuickActionsForPath, +} from '@/lib/campaignReferenceQuickActions' import type { CampaignRole } from '@/lib/campaignRoles' import { resolveLeaderContactsQuickActions } from '@/lib/leaderContactsQuickActions' import { resolveOrganizationQuickActions } from '@/lib/organizationQuickActions' @@ -77,5 +81,9 @@ export const resolveQuickActionsForPath = ( if (isTerritoriesListPath(pathname)) { return resolveStaffHomeQuickActions(role) } + + const referenceActions = resolveReferenceQuickActionsForPath(pathname, role, context) + if (isReferenceQuickActionPath(pathname)) return referenceActions + return [] } diff --git a/src/lib/campaignReferenceQuickActions.ts b/src/lib/campaignReferenceQuickActions.ts new file mode 100644 index 00000000..f14f0d5e --- /dev/null +++ b/src/lib/campaignReferenceQuickActions.ts @@ -0,0 +1,25 @@ +import { CAMPAIGN_CONCEPTS_PATH } from '@/lib/campaignIntelligenceConcepts' +import { CAMPAIGN_PROFILE_HOME } from '@/lib/campaignPaths' +import type { CampaignQuickActionContext } from '@/lib/campaignQuickActionContext' +import type { CampaignQuickAction } from '@/lib/campaignQuickActionTypes' +import { isStaffCampaignRole, type CampaignRole } from '@/lib/campaignRoles' + +export const isConceptsPath = (pathname: string): boolean => + pathname === CAMPAIGN_CONCEPTS_PATH || pathname === `${CAMPAIGN_CONCEPTS_PATH}/` + +export const isProfilePath = (pathname: string): boolean => + pathname === CAMPAIGN_PROFILE_HOME || pathname === `${CAMPAIGN_PROFILE_HOME}/` + +/** B90 — reference/account surfaces with search-only drawer (no action catalog). */ +export const isReferenceQuickActionPath = (pathname: string): boolean => + isConceptsPath(pathname) || isProfilePath(pathname) + +export const resolveReferenceQuickActionsForPath = ( + pathname: string, + role: CampaignRole, + _context: CampaignQuickActionContext, +): readonly CampaignQuickAction[] => { + if (!isStaffCampaignRole(role)) return [] + if (!isReferenceQuickActionPath(pathname)) return [] + return [] +} diff --git a/tests/unit/campaignQuickAction.unit.spec.ts b/tests/unit/campaignQuickAction.unit.spec.ts index babf3a54..d00212ef 100644 --- a/tests/unit/campaignQuickAction.unit.spec.ts +++ b/tests/unit/campaignQuickAction.unit.spec.ts @@ -4,6 +4,8 @@ import { resolveActivityQuickActions } from '@/lib/activityQuickActions' import { CAMPAIGN_WIZARD_ACTION_SLUGS } from '@/lib/campaignActionRoutes' import { advisorQuickCreateHref } from '@/lib/campaignAdvisorQuickActions' import { UNCOVERED_MUNICIPALITIES_LIST_HREF, homeActionsForRole } from '@/lib/campaignHomeActions' +import { CAMPAIGN_CONCEPTS_PATH } from '@/lib/campaignIntelligenceConcepts' +import { CAMPAIGN_PROFILE_HOME } from '@/lib/campaignPaths' import { CAMPAIGN_DEMANDS_CREATE_HREF, demandCreateHref, @@ -90,6 +92,10 @@ describe('campaignQuickActionMount', () => { expect(shouldMountQuickActionsDrawer('/campanha/dobradinhas', 'coordinator')).toBe(true) expect(shouldMountQuickActionsDrawer('/campanha/dobradinhas/foo', 'advisor')).toBe(true) }) + + it('omits drawer on perfil for leader (B90)', () => { + expect(shouldMountQuickActionsDrawer(CAMPAIGN_PROFILE_HOME, 'leader')).toBe(false) + }) }) describe('campaignQuickActionPaths (activities)', () => { @@ -259,6 +265,11 @@ describe('campaignQuickActionRegistry', () => { expect(resolveQuickActionsForPath('/campanha/apoiadores', 'coordinator', {})).toEqual([]) }) + it('returns empty catalog on conceitos and perfil for staff (B90)', () => { + expect(resolveQuickActionsForPath(CAMPAIGN_CONCEPTS_PATH, 'coordinator', {})).toEqual([]) + expect(resolveQuickActionsForPath(CAMPAIGN_PROFILE_HOME, 'candidate', {})).toEqual([]) + }) + it('delegates municipality list and detail catalogs (B80)', () => { const list = resolveQuickActionsForPath('/campanha/municipios', 'coordinator', {}) expect(list).toHaveLength(6) diff --git a/tests/unit/campaignReferenceQuickActions.unit.spec.ts b/tests/unit/campaignReferenceQuickActions.unit.spec.ts new file mode 100644 index 00000000..3697f4e0 --- /dev/null +++ b/tests/unit/campaignReferenceQuickActions.unit.spec.ts @@ -0,0 +1,43 @@ +import { describe, expect, it } from 'vitest' + +import { CAMPAIGN_CONCEPTS_PATH } from '@/lib/campaignIntelligenceConcepts' +import { CAMPAIGN_PROFILE_HOME } from '@/lib/campaignPaths' +import { + isConceptsPath, + isProfilePath, + isReferenceQuickActionPath, + resolveReferenceQuickActionsForPath, +} from '@/lib/campaignReferenceQuickActions' + +describe('campaignReferenceQuickActions paths', () => { + it('matches conceitos exactly', () => { + expect(isConceptsPath(CAMPAIGN_CONCEPTS_PATH)).toBe(true) + expect(isConceptsPath(`${CAMPAIGN_CONCEPTS_PATH}/`)).toBe(true) + expect(isConceptsPath(`${CAMPAIGN_CONCEPTS_PATH}/foo`)).toBe(false) + }) + + it('matches perfil exactly', () => { + expect(isProfilePath(CAMPAIGN_PROFILE_HOME)).toBe(true) + expect(isProfilePath(`${CAMPAIGN_PROFILE_HOME}/`)).toBe(true) + expect(isProfilePath(`${CAMPAIGN_PROFILE_HOME}/editar`)).toBe(false) + }) + + it('groups reference surfaces', () => { + expect(isReferenceQuickActionPath(CAMPAIGN_CONCEPTS_PATH)).toBe(true) + expect(isReferenceQuickActionPath(CAMPAIGN_PROFILE_HOME)).toBe(true) + expect(isReferenceQuickActionPath('/campanha/municipios')).toBe(false) + }) +}) + +describe('resolveReferenceQuickActionsForPath (B90)', () => { + it('returns empty catalog for staff on conceitos and perfil', () => { + expect(resolveReferenceQuickActionsForPath(CAMPAIGN_CONCEPTS_PATH, 'coordinator', {})).toEqual( + [], + ) + expect(resolveReferenceQuickActionsForPath(CAMPAIGN_PROFILE_HOME, 'advisor', {})).toEqual([]) + }) + + it('returns empty catalog for leader lockdown', () => { + expect(resolveReferenceQuickActionsForPath(CAMPAIGN_PROFILE_HOME, 'leader', {})).toEqual([]) + }) +})