feat(webui): expose stable product destinations
Module Package Release / publish-packages (push) Successful in 13s
Module Package Release / publish-packages (push) Successful in 13s
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useMemo, useState } from "react";
|
||||
import { FileText, GitBranch, Inbox, Search, ShieldCheck } from "lucide-react";
|
||||
import { CalendarDays, FileText, Folder, GitBranch, Inbox, ListChecks, Mail, Search, ShieldCheck } from "lucide-react";
|
||||
import { useLocation } from "react-router";
|
||||
import FormInstancePage from "../../../govoplan-forms-runtime/webui/src/features/forms/FormInstancePage";
|
||||
import FormsRuntimePage from "../../../govoplan-forms-runtime/webui/src/features/forms/FormsRuntimePage";
|
||||
@@ -30,12 +30,23 @@ import WorkspaceLayout from "../src/components/WorkspaceLayout";
|
||||
import WorkspaceActionBar from "../src/components/WorkspaceActionBar";
|
||||
import BreadcrumbBar from "../src/layout/BreadcrumbBar";
|
||||
import HelpMenu from "../src/layout/HelpMenu";
|
||||
import IconRail from "../src/layout/IconRail";
|
||||
import { useGuardedNavigate } from "../src/components/UnsavedChangesGuard";
|
||||
import {
|
||||
createQuickAccessLaunchContext,
|
||||
quickAccessLaunchState
|
||||
} from "../src/platform/launchContext";
|
||||
import type { ApiSettings, AuthInfo, EffectiveViewProjection, QuickAccessToolMetadata } from "../src/types";
|
||||
import { projectProductNavigation } from "../src/platform/productSurfaces";
|
||||
import type {
|
||||
ApiSettings,
|
||||
AuthInfo,
|
||||
EffectiveViewProjection,
|
||||
PlatformNavItem,
|
||||
PlatformWebModule,
|
||||
ProductAreaContribution,
|
||||
ProductSurfaceContribution,
|
||||
QuickAccessToolMetadata
|
||||
} from "../src/types";
|
||||
|
||||
export default function ConformanceApp() {
|
||||
const location = useLocation();
|
||||
@@ -43,6 +54,10 @@ export default function ConformanceApp() {
|
||||
const [editorDirty, setEditorDirty] = useState(true);
|
||||
const [metricDrilldown, setMetricDrilldown] = useState("");
|
||||
|
||||
if (new URLSearchParams(location.search).has("product-navigation")) {
|
||||
return <ProductNavigationScenario />;
|
||||
}
|
||||
|
||||
if (location.pathname.startsWith("/forms/public/")) {
|
||||
return <PublicFormPage settings={CONFORMANCE_SETTINGS} auth={FORMS_RUNTIME_AUTH} />;
|
||||
}
|
||||
@@ -185,6 +200,39 @@ export default function ConformanceApp() {
|
||||
);
|
||||
}
|
||||
|
||||
function ProductNavigationScenario() {
|
||||
const projection = useMemo(
|
||||
() => projectProductNavigation(
|
||||
PRODUCT_NAV_ITEMS,
|
||||
PRODUCT_NAV_MODULES,
|
||||
PRODUCT_NAV_AUTH
|
||||
),
|
||||
[]
|
||||
);
|
||||
return (
|
||||
<div className="app-shell" data-conformance-id="product-navigation">
|
||||
<IconRail
|
||||
navItems={projection.primaryItems}
|
||||
allToolItems={projection.allToolItems}
|
||||
productAreas={PRODUCT_NAV_AREAS}
|
||||
/>
|
||||
<main className="main-area">
|
||||
<PageLayout
|
||||
archetype="overview"
|
||||
mode="embedded"
|
||||
title="Anwohnerparkausweis bearbeiten"
|
||||
description="Die Navigation beschreibt Arbeit und Ergebnisse; technische Eigentümer bleiben nachvollziehbar erreichbar."
|
||||
>
|
||||
<StatePanel
|
||||
title="Vorgang ist bereit"
|
||||
description="Nutzen Sie Arbeit, Kalender, Nachrichten oder Dateien für den nächsten Schritt."
|
||||
/>
|
||||
</PageLayout>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function HelpConformanceScenario() {
|
||||
return (
|
||||
<section className="conformance-section" aria-labelledby="help-heading">
|
||||
@@ -303,6 +351,122 @@ const CONFORMANCE_AUTH = {
|
||||
groups_loaded: true
|
||||
} satisfies AuthInfo;
|
||||
|
||||
const PRODUCT_NAV_AUTH = {
|
||||
...CONFORMANCE_AUTH,
|
||||
scopes: [
|
||||
"tasks:item:read",
|
||||
"calendar:event:read",
|
||||
"mail:mailbox:read",
|
||||
"postbox:message:read",
|
||||
"files:file:read"
|
||||
]
|
||||
} satisfies AuthInfo;
|
||||
|
||||
const PRODUCT_NAV_ITEMS: PlatformNavItem[] = [
|
||||
{ to: "/tasks", label: "Tasks", icon: ListChecks, surfaceId: "tasks.nav.tasks", anyOf: ["tasks:item:read"], order: 30 },
|
||||
{ to: "/files", label: "Files", icon: Folder, surfaceId: "files.nav.files", anyOf: ["files:file:read"], order: 40 },
|
||||
{ to: "/mail", label: "Mail", icon: Mail, surfaceId: "mail.nav.mail", anyOf: ["mail:mailbox:read"], order: 50 },
|
||||
{ to: "/postbox", label: "Postbox", icon: Inbox, surfaceId: "postbox.nav.postbox", anyOf: ["postbox:message:read"], order: 51 },
|
||||
{ to: "/calendar", label: "Calendar", icon: CalendarDays, surfaceId: "calendar.nav.calendar", anyOf: ["calendar:event:read"], order: 55 }
|
||||
];
|
||||
|
||||
const PRODUCT_NAV_AREAS: ProductAreaContribution[] = [
|
||||
{ id: "work", moduleId: "tasks", label: "i18n:govoplan-core.product_area.work", iconName: "list-checks", surfaceIds: ["tasks.nav.tasks"], order: 10 },
|
||||
{ id: "records-documents", moduleId: "files", label: "i18n:govoplan-core.product_area.records_documents", iconName: "folder", surfaceIds: ["files.nav.files"], order: 30 },
|
||||
{ id: "communication", moduleId: "mail", label: "i18n:govoplan-core.product_area.communication", iconName: "mail", surfaceIds: ["mail.nav.mail", "postbox.nav.postbox"], order: 40 },
|
||||
{ id: "meetings-decisions", moduleId: "calendar", label: "i18n:govoplan-core.product_area.meetings_decisions", iconName: "calendar", surfaceIds: ["calendar.nav.calendar"], order: 50 }
|
||||
];
|
||||
|
||||
const PRODUCT_NAV_MODULES: PlatformWebModule[] = [
|
||||
productModule("tasks", productSurface({
|
||||
id: "work.items",
|
||||
moduleId: "tasks",
|
||||
label: "i18n:govoplan-core.product_surface.work",
|
||||
description: "i18n:govoplan-core.product_surface.work_description",
|
||||
iconName: "list-checks",
|
||||
entryPath: "/work",
|
||||
routePath: "/tasks",
|
||||
surfaceIds: ["tasks.nav.tasks"],
|
||||
anyOf: ["tasks:item:read"]
|
||||
})),
|
||||
productModule("files", productSurface({
|
||||
id: "records.files",
|
||||
moduleId: "files",
|
||||
label: "i18n:govoplan-core.product_surface.files",
|
||||
description: "i18n:govoplan-core.product_surface.files_description",
|
||||
iconName: "folder",
|
||||
entryPath: "/documents",
|
||||
routePath: "/files",
|
||||
surfaceIds: ["files.nav.files"],
|
||||
anyOf: ["files:file:read"]
|
||||
})),
|
||||
productModule("mail", productSurface({
|
||||
id: "communication.messages",
|
||||
moduleId: "mail",
|
||||
label: "i18n:govoplan-core.product_surface.messages",
|
||||
description: "i18n:govoplan-core.product_surface.messages_description",
|
||||
iconName: "mail",
|
||||
entryPath: "/messages",
|
||||
routePath: "/mail",
|
||||
surfaceIds: ["mail.nav.mail"],
|
||||
anyOf: ["mail:mailbox:read"],
|
||||
aliases: ["/inbox"]
|
||||
})),
|
||||
productModule("postbox", productSurface({
|
||||
id: "communication.messages",
|
||||
moduleId: "postbox",
|
||||
label: "i18n:govoplan-core.product_surface.messages",
|
||||
description: "i18n:govoplan-core.product_surface.messages_description",
|
||||
iconName: "mail",
|
||||
entryPath: "/messages",
|
||||
routePath: "/postbox",
|
||||
surfaceIds: ["postbox.nav.postbox"],
|
||||
anyOf: ["postbox:message:read"],
|
||||
aliases: ["/inbox"],
|
||||
order: 20
|
||||
})),
|
||||
productModule("calendar", productSurface({
|
||||
id: "meetings.calendar",
|
||||
moduleId: "calendar",
|
||||
label: "i18n:govoplan-core.product_surface.calendar",
|
||||
description: "i18n:govoplan-core.product_surface.calendar_description",
|
||||
iconName: "calendar",
|
||||
entryPath: "/agenda",
|
||||
routePath: "/calendar",
|
||||
surfaceIds: ["calendar.nav.calendar"],
|
||||
anyOf: ["calendar:event:read"]
|
||||
}))
|
||||
];
|
||||
|
||||
function productModule(id: string, surface: ProductSurfaceContribution): PlatformWebModule {
|
||||
return { id, label: id, version: "test", productSurfaces: [surface] };
|
||||
}
|
||||
|
||||
function productSurface(
|
||||
partial: Pick<ProductSurfaceContribution,
|
||||
"id" | "moduleId" | "label" | "description" | "iconName" | "entryPath" |
|
||||
"routePath" | "surfaceIds" | "anyOf"> & Partial<ProductSurfaceContribution>
|
||||
): ProductSurfaceContribution {
|
||||
return {
|
||||
contractVersion: "1",
|
||||
presentations: ["task", "reader"],
|
||||
capabilityIds: [],
|
||||
searchSourceIds: [],
|
||||
helpContextIds: [],
|
||||
documentationTopicIds: [],
|
||||
allOf: [],
|
||||
aliases: [],
|
||||
order: 10,
|
||||
unavailable: {
|
||||
reason: "authorization",
|
||||
title: "Not available",
|
||||
description: "The destination is not available for this responsibility.",
|
||||
resolution: "Ask the access administrator to review the assignment."
|
||||
},
|
||||
...partial
|
||||
};
|
||||
}
|
||||
|
||||
const FORMS_RUNTIME_AUTH = {
|
||||
...CONFORMANCE_AUTH,
|
||||
scopes: [
|
||||
|
||||
Reference in New Issue
Block a user