feat(ui): ship policy decisioning studio

This commit is contained in:
master
2026-03-08 01:35:18 +02:00
parent 8ee40b56e9
commit 6e00a48e00
57 changed files with 3637 additions and 333 deletions

View File

@@ -17,7 +17,32 @@
* until SPRINT_20260218_016 cutover; this file owns the /administration/* canonical paths.
*/
import { Routes } from '@angular/router';
import { inject } from '@angular/core';
import { Router, Routes } from '@angular/router';
function redirectToDecisioning(path: string) {
return ({
params,
queryParams,
fragment,
}: {
params: Record<string, string>;
queryParams: Record<string, string>;
fragment?: string | null;
}) => {
const router = inject(Router);
let targetPath = path;
for (const [name, value] of Object.entries(params ?? {})) {
targetPath = targetPath.replaceAll(`:${name}`, encodeURIComponent(value));
}
const target = router.parseUrl(targetPath);
target.queryParams = { ...queryParams };
target.fragment = fragment ?? null;
return target;
};
}
export const ADMINISTRATION_ROUTES: Routes = [
// A0 — Administration overview
@@ -117,73 +142,106 @@ export const ADMINISTRATION_ROUTES: Routes = [
path: 'policy-governance',
title: 'Policy Governance',
data: { breadcrumb: 'Policy Governance' },
loadChildren: () =>
import('../features/policy-governance/policy-governance.routes').then(
(m) => m.policyGovernanceRoutes
),
redirectTo: redirectToDecisioning('/ops/policy/governance'),
pathMatch: 'full',
},
{
path: 'policy-governance/exceptions',
title: 'Exceptions',
data: { breadcrumb: 'Exceptions' },
redirectTo: redirectToDecisioning('/ops/policy/vex/exceptions'),
pathMatch: 'full',
},
{
path: 'policy-governance/exceptions/:id',
title: 'Exception Detail',
data: { breadcrumb: 'Exception Detail' },
redirectTo: redirectToDecisioning('/ops/policy/vex/exceptions/:id'),
pathMatch: 'full',
},
{
path: 'policy-governance/:page',
title: 'Policy Governance',
data: { breadcrumb: 'Policy Governance' },
redirectTo: redirectToDecisioning('/ops/policy/governance/:page'),
pathMatch: 'full',
},
{
path: 'policy-governance/:page/:child',
title: 'Policy Governance',
data: { breadcrumb: 'Policy Governance' },
redirectTo: redirectToDecisioning('/ops/policy/governance/:page/:child'),
pathMatch: 'full',
},
{
path: 'policy',
title: 'Policy Governance',
data: { breadcrumb: 'Policy Governance' },
loadComponent: () =>
import('../features/settings/policy/policy-governance-settings-page.component').then(
(m) => m.PolicyGovernanceSettingsPageComponent
),
redirectTo: redirectToDecisioning('/ops/policy/governance'),
pathMatch: 'full',
},
{
path: 'policy/packs',
title: 'Policy Packs',
data: { breadcrumb: 'Policy Packs' },
loadComponent: () =>
import('../features/policy-studio/workspace/policy-workspace.component').then(
(m) => m.PolicyWorkspaceComponent
),
redirectTo: redirectToDecisioning('/ops/policy/packs'),
pathMatch: 'full',
},
{
path: 'policy/exceptions',
title: 'Exceptions',
data: { breadcrumb: 'Exceptions' },
loadComponent: () =>
import('../features/triage/triage-artifacts.component').then(
(m) => m.TriageArtifactsComponent
),
redirectTo: redirectToDecisioning('/ops/policy/vex/exceptions'),
pathMatch: 'full',
},
{
path: 'policy/exceptions/:id',
title: 'Exception Detail',
data: { breadcrumb: 'Exception Detail' },
loadComponent: () =>
import('../features/triage/triage-workspace.component').then(
(m) => m.TriageWorkspaceComponent
),
redirectTo: redirectToDecisioning('/ops/policy/vex/exceptions/:id'),
pathMatch: 'full',
},
{
path: 'policy/packs/:packId',
title: 'Policy Pack',
data: { breadcrumb: 'Policy Pack' },
loadComponent: () =>
import('../features/policy-studio/workspace/policy-workspace.component').then(
(m) => m.PolicyWorkspaceComponent
),
redirectTo: redirectToDecisioning('/ops/policy/packs/:packId'),
pathMatch: 'full',
},
{
path: 'policy/packs/:packId/:page',
title: 'Policy Pack',
data: { breadcrumb: 'Policy Pack' },
loadComponent: () =>
import('../features/policy-studio/workspace/policy-workspace.component').then(
(m) => m.PolicyWorkspaceComponent
),
redirectTo: redirectToDecisioning('/ops/policy/packs/:packId/:page'),
pathMatch: 'full',
},
{
path: 'policy/packs/:packId/explain/:runId',
title: 'Policy Explain',
data: { breadcrumb: 'Policy Explain' },
redirectTo: redirectToDecisioning('/ops/policy/packs/:packId/explain/:runId'),
pathMatch: 'full',
},
{
path: 'policy/governance',
title: 'Policy Governance',
data: { breadcrumb: 'Policy Governance' },
loadChildren: () =>
import('../features/policy-governance/policy-governance.routes').then(
(m) => m.policyGovernanceRoutes
),
redirectTo: redirectToDecisioning('/ops/policy/governance'),
pathMatch: 'full',
},
{
path: 'policy/governance/:page',
title: 'Policy Governance',
data: { breadcrumb: 'Policy Governance' },
redirectTo: redirectToDecisioning('/ops/policy/governance/:page'),
pathMatch: 'full',
},
{
path: 'policy/governance/:page/:child',
title: 'Policy Governance',
data: { breadcrumb: 'Policy Governance' },
redirectTo: redirectToDecisioning('/ops/policy/governance/:page/:child'),
pathMatch: 'full',
},
// A6 — Trust & Signing