Files
EpicNext-Cms/src/features/housekeeping/foundation/navigation.ts
T
Simo b413e62085
CI / runtime-diagnostics (pull_request) Skipped
CI / check (pull_request) Successful in 58s
CI / release (pull_request) Skipped
CI / deploy (pull_request) Skipped
chore: satisfy upgraded biome checks
2026-09-01 19:14:09 +02:00

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(":"));
}