Documentation
Entity manifest example
Declare a list/detail entity with lazy facet loaders and detail pages.
Use manifests to keep entity-level routing and facet loading explicit. Lazy facet loaders let large backoffice entities split list, picker, layout, and detail-page code into separate chunks.
import {
createListDetailManifest,
type BackofficeDetailPageManifestItem,
type BackofficeListDetailFacetLoaderMap,
} from '@plumile/backoffice-core';
export const projectDetailPages = [
{
: 'overview',
: 'overview',
label: (t) => t('project.detail.overview'),
: true,
},
{
: 'activity',
: 'activity',
label: (t) => t('project.detail.activity'),
},
] as const satisfies readonly BackofficeDetailPageManifestItem[];
export const projectFacetLoaders: BackofficeListDetailFacetLoaderMap = {
list: async () => {
const module = await import'./facets/list.js';
return module.loadedProjectListFacetModule;
},
picker: async () => {
const module = await import'./facets/picker.js';
return module.loadedProjectPickerFacetModule;
},
detailLayout: async () => {
const module = await import'./facets/detail-layout.js';
return module.loadedProjectDetailLayoutFacetModule;
},
detailPage: async (pageId) => {
ifpageId === 'overview' {
const module = await import'./facets/detail-pages/overview.js';
return module.loadedProjectOverviewDetailPageFacetModule;
}
throw new Error`Unknown project detail page: ${pageId}`;
},
};
export const projectManifest = createListDetailManifest({
: 'projects',
label: (t) => t('project.entity.plural'),
: projectDetailPages,
: projectFacetLoaders,
});Prefer one folder per entity when the entity has multiple facets. Keep the manifest small and move list/detail logic into facet modules.