220 lines
5.7 KiB
TypeScript
220 lines
5.7 KiB
TypeScript
import { PERMS } from "@/lib/permission-slugs";
|
|
import {
|
|
anyCapability,
|
|
type CanonicalHousekeepingHref,
|
|
type HousekeepingRouteDefinition,
|
|
} from "../../foundation/contracts";
|
|
|
|
export const CONTENT_ROUTE_GROUPS = [
|
|
"editorial",
|
|
"media",
|
|
"engagement",
|
|
"help",
|
|
"brand",
|
|
"localization",
|
|
] as const;
|
|
|
|
export type ContentRouteGroup = (typeof CONTENT_ROUTE_GROUPS)[number];
|
|
|
|
export const CONTENT_ROUTE_IDS = [
|
|
"content.editorial.articles",
|
|
"content.editorial.article-create",
|
|
"content.editorial.article-detail",
|
|
"content.media.photos",
|
|
"content.media.library",
|
|
"content.media.banners",
|
|
"content.media.ads",
|
|
"content.media.ad-create",
|
|
"content.media.ad-detail",
|
|
"content.engagement.events",
|
|
"content.engagement.event-create",
|
|
"content.engagement.event-types",
|
|
"content.engagement.event-detail",
|
|
"content.engagement.polls",
|
|
"content.engagement.poll-create",
|
|
"content.engagement.poll-detail",
|
|
"content.help.questions",
|
|
"content.help.question-create",
|
|
"content.help.question-detail",
|
|
"content.editorial.tags",
|
|
"content.engagement.prefixes",
|
|
"content.editorial.writeable-boxes",
|
|
"content.help.email-templates",
|
|
"content.brand.theme",
|
|
"content.brand.theme-builder",
|
|
"content.brand.favicon",
|
|
"content.localization.overview",
|
|
"content.localization.client",
|
|
"content.localization.cms",
|
|
"content.localization.emulator",
|
|
] as const;
|
|
|
|
export type ContentRouteId = (typeof CONTENT_ROUTE_IDS)[number];
|
|
|
|
function contentRoute(
|
|
id: ContentRouteId,
|
|
href: CanonicalHousekeepingHref,
|
|
capabilities: readonly string[],
|
|
): HousekeepingRouteDefinition {
|
|
return {
|
|
id,
|
|
labelKey: `pages.housekeeping.routes.${id}`,
|
|
href,
|
|
capability: anyCapability(...capabilities),
|
|
};
|
|
}
|
|
|
|
export const CONTENT_ROUTES = [
|
|
contentRoute(
|
|
"content.editorial.articles",
|
|
"/ase-next/content/editorial/articles",
|
|
[PERMS.NEWS_VIEW],
|
|
),
|
|
contentRoute(
|
|
"content.editorial.article-create",
|
|
"/ase-next/content/editorial/articles/new",
|
|
[PERMS.NEWS_EDIT],
|
|
),
|
|
contentRoute(
|
|
"content.editorial.article-detail",
|
|
"/ase-next/content/editorial/articles/:id",
|
|
[PERMS.NEWS_VIEW],
|
|
),
|
|
contentRoute("content.media.photos", "/ase-next/content/media/photos", [
|
|
PERMS.PAGES_VIEW,
|
|
]),
|
|
contentRoute("content.media.library", "/ase-next/content/media/library", [
|
|
PERMS.PAGES_VIEW,
|
|
]),
|
|
contentRoute("content.media.banners", "/ase-next/content/media/banners", [
|
|
PERMS.BANNERS_VIEW,
|
|
]),
|
|
contentRoute("content.media.ads", "/ase-next/content/media/ads", [
|
|
PERMS.PAGES_VIEW,
|
|
]),
|
|
contentRoute("content.media.ad-create", "/ase-next/content/media/ads/new", [
|
|
PERMS.PAGES_EDIT,
|
|
]),
|
|
contentRoute("content.media.ad-detail", "/ase-next/content/media/ads/:id", [
|
|
PERMS.PAGES_VIEW,
|
|
]),
|
|
contentRoute(
|
|
"content.engagement.events",
|
|
"/ase-next/content/engagement/events",
|
|
[PERMS.EVENTS_VIEW],
|
|
),
|
|
contentRoute(
|
|
"content.engagement.event-create",
|
|
"/ase-next/content/engagement/events/create",
|
|
[PERMS.EVENTS_EDIT],
|
|
),
|
|
contentRoute(
|
|
"content.engagement.event-types",
|
|
"/ase-next/content/engagement/events/types",
|
|
[PERMS.EVENTS_EDIT],
|
|
),
|
|
contentRoute(
|
|
"content.engagement.event-detail",
|
|
"/ase-next/content/engagement/events/:id",
|
|
[PERMS.EVENTS_EDIT],
|
|
),
|
|
contentRoute(
|
|
"content.engagement.polls",
|
|
"/ase-next/content/engagement/polls",
|
|
[PERMS.POLLS_VIEW],
|
|
),
|
|
contentRoute(
|
|
"content.engagement.poll-create",
|
|
"/ase-next/content/engagement/polls/create",
|
|
[PERMS.POLLS_EDIT],
|
|
),
|
|
contentRoute(
|
|
"content.engagement.poll-detail",
|
|
"/ase-next/content/engagement/polls/:id",
|
|
[PERMS.POLLS_EDIT],
|
|
),
|
|
contentRoute("content.help.questions", "/ase-next/content/help/questions", [
|
|
PERMS.PAGES_VIEW,
|
|
]),
|
|
contentRoute(
|
|
"content.help.question-create",
|
|
"/ase-next/content/help/questions/new",
|
|
[PERMS.PAGES_EDIT],
|
|
),
|
|
contentRoute(
|
|
"content.help.question-detail",
|
|
"/ase-next/content/help/questions/:id",
|
|
[PERMS.PAGES_VIEW],
|
|
),
|
|
contentRoute("content.editorial.tags", "/ase-next/content/editorial/tags", [
|
|
PERMS.PAGES_VIEW,
|
|
]),
|
|
contentRoute(
|
|
"content.engagement.prefixes",
|
|
"/ase-next/content/engagement/prefixes",
|
|
[PERMS.PREFIXES_VIEW],
|
|
),
|
|
contentRoute(
|
|
"content.editorial.writeable-boxes",
|
|
"/ase-next/content/editorial/writeable-boxes",
|
|
[PERMS.PAGES_VIEW],
|
|
),
|
|
contentRoute(
|
|
"content.help.email-templates",
|
|
"/ase-next/content/help/email-templates",
|
|
[PERMS.PAGES_VIEW],
|
|
),
|
|
contentRoute("content.brand.theme", "/ase-next/content/brand/theme", [
|
|
PERMS.SETTINGS_VIEW,
|
|
]),
|
|
contentRoute(
|
|
"content.brand.theme-builder",
|
|
"/ase-next/content/brand/theme-builder",
|
|
[PERMS.SETTINGS_VIEW],
|
|
),
|
|
contentRoute("content.brand.favicon", "/ase-next/content/brand/favicon", [
|
|
PERMS.SETTINGS_VIEW,
|
|
]),
|
|
contentRoute(
|
|
"content.localization.overview",
|
|
"/ase-next/content/localization",
|
|
[PERMS.SETTINGS_VIEW],
|
|
),
|
|
contentRoute(
|
|
"content.localization.client",
|
|
"/ase-next/content/localization/client",
|
|
[PERMS.SETTINGS_VIEW],
|
|
),
|
|
contentRoute(
|
|
"content.localization.cms",
|
|
"/ase-next/content/localization/cms",
|
|
[PERMS.SETTINGS_VIEW],
|
|
),
|
|
contentRoute(
|
|
"content.localization.emulator",
|
|
"/ase-next/content/localization/emulator",
|
|
[PERMS.SETTINGS_VIEW],
|
|
),
|
|
] as const satisfies readonly HousekeepingRouteDefinition[];
|
|
|
|
const routeGroups = new Map<ContentRouteId, ContentRouteGroup>(
|
|
CONTENT_ROUTE_IDS.map((routeId) => [
|
|
routeId,
|
|
routeId.split(".")[1] as ContentRouteGroup,
|
|
]),
|
|
);
|
|
|
|
export function contentRouteGroup(routeId: ContentRouteId): ContentRouteGroup {
|
|
const group = routeGroups.get(routeId);
|
|
if (!group) throw new Error(`unknown Content route: ${routeId}`);
|
|
return group;
|
|
}
|
|
|
|
export function contentRouteById(
|
|
routeId: ContentRouteId,
|
|
): (typeof CONTENT_ROUTES)[number] {
|
|
const route = CONTENT_ROUTES.find((candidate) => candidate.id === routeId);
|
|
if (!route) throw new Error(`unknown Content route: ${routeId}`);
|
|
return route;
|
|
}
|