58 lines
1.5 KiB
TypeScript
58 lines
1.5 KiB
TypeScript
import type { HousekeepingDomainId } from "../migration/types";
|
|
import { satisfiesCapability } from "./capability-context";
|
|
import type {
|
|
HousekeepingCapabilityContext,
|
|
HousekeepingDomainManifest,
|
|
} from "./contracts";
|
|
import type { HousekeepingRouteRuntime } from "./routing/runtime";
|
|
|
|
export interface HousekeepingNavigationDomain {
|
|
id: HousekeepingDomainId;
|
|
href: string;
|
|
iconId: HousekeepingDomainManifest["iconId"];
|
|
label: string;
|
|
description: string;
|
|
items: readonly { id: string; href: string; label: string }[];
|
|
}
|
|
|
|
export function buildHousekeepingNavigation(
|
|
runtime: HousekeepingRouteRuntime,
|
|
context: HousekeepingCapabilityContext,
|
|
translate: (key: string) => string,
|
|
): readonly HousekeepingNavigationDomain[] {
|
|
return runtime.registry.domains.flatMap((domain) => {
|
|
if (!satisfiesCapability(context, domain.capability)) return [];
|
|
|
|
const items = domain.routes
|
|
.filter(
|
|
(route) =>
|
|
runtime.handlers.has(route.id) &&
|
|
isConcreteNavigationHref(route.href) &&
|
|
satisfiesCapability(context, route.capability),
|
|
)
|
|
.map((route) => ({
|
|
id: route.id,
|
|
href: route.href,
|
|
label: translate(route.labelKey),
|
|
}));
|
|
|
|
const landing = items[0];
|
|
if (!landing) return [];
|
|
|
|
return [
|
|
{
|
|
id: domain.id,
|
|
href: landing.href,
|
|
iconId: domain.iconId,
|
|
label: translate(domain.labelKey),
|
|
description: translate(domain.descriptionKey),
|
|
items,
|
|
},
|
|
];
|
|
});
|
|
}
|
|
|
|
function isConcreteNavigationHref(href: string): boolean {
|
|
return !href.split("/").some((segment) => segment.startsWith(":"));
|
|
}
|