fix(housekeeping): link only reachable preview routes
This commit is contained in:
1 parent
543607a80e
commit
d8fb8edff6
6 files changed
+216
-162
No files matched your search
@@ -3,37 +3,63 @@ import { satisfiesCapability } from "./capability-context";
|
||||
import type {
|
||||
HousekeepingCapabilityContext,
|
||||
HousekeepingDomainManifest,
|
||||
HousekeepingPreviewHref,
|
||||
} from "./contracts";
|
||||
import type { HousekeepingRegistry } from "./registry";
|
||||
import type { HousekeepingRouteRuntime } from "./routing/runtime";
|
||||
|
||||
export interface HousekeepingNavigationDomain {
|
||||
id: HousekeepingDomainId;
|
||||
href: string;
|
||||
href: HousekeepingPreviewHref;
|
||||
iconId: HousekeepingDomainManifest["iconId"];
|
||||
label: string;
|
||||
description: string;
|
||||
items: readonly { id: string; href: string; label: string }[];
|
||||
items: readonly {
|
||||
id: string;
|
||||
href: HousekeepingPreviewHref;
|
||||
label: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
export function buildHousekeepingNavigation(
|
||||
registry: HousekeepingRegistry,
|
||||
runtime: HousekeepingRouteRuntime,
|
||||
context: HousekeepingCapabilityContext,
|
||||
translate: (key: string) => string,
|
||||
): readonly HousekeepingNavigationDomain[] {
|
||||
return registry.domains
|
||||
.filter((domain) => satisfiesCapability(context, domain.capability))
|
||||
.map((domain) => ({
|
||||
id: domain.id,
|
||||
href: domain.previewHref,
|
||||
iconId: domain.iconId,
|
||||
label: translate(domain.labelKey),
|
||||
description: translate(domain.descriptionKey),
|
||||
items: domain.routes
|
||||
.filter((route) => satisfiesCapability(context, route.capability))
|
||||
.map((route) => ({
|
||||
id: route.id,
|
||||
href: route.href,
|
||||
label: translate(route.labelKey),
|
||||
})),
|
||||
}));
|
||||
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),
|
||||
}));
|
||||
|
||||
if (items.length === 0) return [];
|
||||
|
||||
const landing =
|
||||
items.find((item) => item.id === domain.landingRouteId) ?? 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: HousekeepingPreviewHref): boolean {
|
||||
return !href.split("/").some((segment) => segment.startsWith(":"));
|
||||
}
|
||||
Reference in new issue
Block a user