140 lines
5.3 KiB
TypeScript
140 lines
5.3 KiB
TypeScript
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;
|