import { createElement, lazy, useCallback } from "react"; import { Navigate, useParams } from "react-router"; import { ResourceAccessBoundary, hasAnyScope, type ApiSettings, type AuthInfo, type DashboardWidgetsUiCapability, type PlatformWebModule, type QuickAccessToolsUiCapability } from "@govoplan/core-webui"; import { getCampaign } from "./api/campaigns"; import CampaignActivityWidget from "./features/campaigns/CampaignActivityWidget"; import CampaignQuickAccess from "./features/campaigns/CampaignQuickAccess"; import { OPERATOR_QUEUE_ROUTE_SCOPES } from "./features/operator/operatorQueueAccess"; import { generatedTranslations } from "./i18n/generatedTranslations"; import { campaignWizardDirectories } from "./features/campaigns/wizard/directory"; import "./styles/campaign-workspace.css"; const CampaignModulePage = lazy(() => import("./features/campaigns/CampaignModulePage")); const CampaignWorkspace = lazy(() => import("./features/campaigns/CampaignWorkspace")); const campaignRead = ["campaigns:campaign:read"]; const reportRead = ["campaigns:report:read"]; const campaignModuleRead = [...campaignRead, ...reportRead]; // Preserve the former /operator route identity for saved View projections. const operatorQueueSurface = "campaigns.route.operator"; const reportsSurface = "campaigns.route.reports"; const translations = { en: generatedTranslations.en, de: generatedTranslations.de }; const campaignDashboardWidgets: DashboardWidgetsUiCapability = { widgets: [ { id: "campaigns.activity", surfaceId: "campaigns.widget.activity", title: "Campaign activity", description: "Recently changed campaigns and delivery state.", moduleId: "campaigns", category: "Communication", order: 50, defaultVisible: false, defaultSize: "medium", supportedSizes: ["medium", "wide"], anyOf: campaignRead, refreshIntervalMs: 30_000, defaultConfiguration: { maxItems: 5, showCompleted: false }, configurationFields: [ { id: "maxItems", label: "Maximum campaigns", kind: "number", min: 1, max: 12, step: 1, required: true }, { id: "showCompleted", label: "Include completed campaigns", kind: "boolean" } ], render: ({ settings, refreshKey, configuration }) => createElement(CampaignActivityWidget, { settings, refreshKey, configuration }) } ] }; const campaignQuickAccessTools: QuickAccessToolsUiCapability = { tools: [ { id: "campaigns.select", render: (context) => createElement(CampaignQuickAccess, context) } ] }; export const campaignModule: PlatformWebModule = { id: "campaigns", label: "i18n:govoplan-campaign.campaigns.01a23a28", version: "1.0.0", dependencies: ["access"], optionalDependencies: ["files", "mail"], translations, viewSurfaces: [ { id: "campaigns.widget.activity", moduleId: "campaigns", kind: "section", label: "Campaign activity widget", order: 50 } ], navItems: [ { to: "/campaigns", label: "i18n:govoplan-campaign.campaigns.01a23a28", iconName: "campaign", anyOf: campaignModuleRead, order: 20 }], routes: [ { path: "/campaigns", anyOf: campaignModuleRead, order: 20, render: ({ settings, auth }) => createElement(CampaignModuleLandingRoute, { settings, auth }) }, { path: "/operator", anyOf: OPERATOR_QUEUE_ROUTE_SCOPES, allOf: campaignRead, order: 21, surfaceId: operatorQueueSurface, render: () => createElement(Navigate, { to: "/campaigns/queue", replace: true }) }, { path: "/campaigns/queue", anyOf: OPERATOR_QUEUE_ROUTE_SCOPES, allOf: campaignRead, order: 21, surfaceId: operatorQueueSurface, render: ({ settings, auth }) => createElement(CampaignModulePage, { active: "queue", settings, auth }) }, { path: "/campaigns/reports", anyOf: reportRead, order: 22, surfaceId: reportsSurface, render: ({ settings, auth }) => createElement(CampaignModulePage, { active: "reports", settings, auth }) }, { path: "/campaigns/:campaignId/*", anyOf: campaignRead, order: 22, render: ({ settings, auth }) => createElement(CampaignResourceRoute, { settings, auth }) }], uiCapabilities: { "dashboard.widgets": campaignDashboardWidgets, "quickAccess.tools": campaignQuickAccessTools, "wizard.directories": campaignWizardDirectories } }; function CampaignModuleLandingRoute({ settings, auth }: {settings: ApiSettings;auth: AuthInfo;}) { if (!hasAnyScope(auth, campaignRead)) { return createElement(Navigate, { to: "/campaigns/reports", replace: true }); } return createElement(CampaignModulePage, { active: "campaigns", settings, auth }); } function CampaignResourceRoute({ settings, auth }: {settings: ApiSettings;auth: AuthInfo;}) { const { campaignId = "" } = useParams(); const tenantId = (auth.active_tenant ?? auth.tenant).id; const probe = useCallback(() => getCampaign(settings, campaignId), [settings.apiBaseUrl, settings.apiKey, settings.accessToken, campaignId, tenantId]); return createElement(ResourceAccessBoundary, { probe, resetKey: `${tenantId}:${campaignId}`, fallback: "/campaigns", children: createElement(CampaignWorkspace, { settings, auth }) }); } export default campaignModule;