Merge pull request #1897 from umbraco/feature/extendable-section-routes
Feature: Extendable section routes
This commit is contained in:
@@ -69,6 +69,7 @@ import type { ManifestAppEntryPoint } from './app-entry-point.model.js';
|
||||
import type { ManifestBackofficeEntryPoint } from './backoffice-entry-point.model.js';
|
||||
import type { ManifestEntryPoint } from './entry-point.model.js';
|
||||
import type { ManifestMonacoMarkdownEditorAction } from './monaco-markdown-editor-action.model.js';
|
||||
import type { ManifestSectionRoute } from './section-route.model.js';
|
||||
import type { ManifestBase, ManifestBundle, ManifestCondition } from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
export type * from './app-entry-point.model.js';
|
||||
@@ -196,6 +197,7 @@ export type ManifestTypes =
|
||||
| ManifestSectionSidebarApp
|
||||
| ManifestSectionSidebarAppMenuKind
|
||||
| ManifestSectionView
|
||||
| ManifestSectionRoute
|
||||
| ManifestStore
|
||||
| ManifestTheme
|
||||
| ManifestTinyMcePlugin
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import type { UmbRouteEntry } from '../../router/types.js';
|
||||
import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api';
|
||||
import type { ManifestElementAndApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
export interface ManifestSectionRoute extends ManifestElementAndApi<UmbControllerHostElement, UmbRouteEntry> {
|
||||
type: 'sectionRoute';
|
||||
meta: MetaSectionRoute;
|
||||
}
|
||||
|
||||
export interface MetaSectionRoute {
|
||||
path?: string;
|
||||
}
|
||||
@@ -8,3 +8,4 @@ export * from './router-slot.element.js';
|
||||
export * from './path-pattern.class.js';
|
||||
export * from './modal-registration/modal-route-registration.interface.js';
|
||||
export * from './modal-registration/modal-route-registration.controller.js';
|
||||
export * from './types.js';
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import type { IRoutingInfo, PageComponent } from '@umbraco-cms/backoffice/external/router-slot';
|
||||
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
export interface UmbRouteEntry extends UmbApi {
|
||||
getPath?(): string;
|
||||
setup?(element: PageComponent, info: IRoutingInfo): void;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { UmbWorkspaceElement } from '../workspace/workspace.element.js';
|
||||
import type { ManifestSectionRoute } from '../extension-registry/models/section-route.model.js';
|
||||
import type { UmbSectionMainViewElement } from './section-main-views/section-main-views.element.js';
|
||||
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
|
||||
import { css, html, nothing, customElement, property, state, repeat } from '@umbraco-cms/backoffice/external/lit';
|
||||
@@ -9,11 +9,14 @@ import type {
|
||||
UmbSectionElement,
|
||||
} from '@umbraco-cms/backoffice/extension-registry';
|
||||
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
|
||||
import type { UmbRoute } from '@umbraco-cms/backoffice/router';
|
||||
import type { IRoute, IRoutingInfo, PageComponent, UmbRoute } from '@umbraco-cms/backoffice/router';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import type { UmbExtensionElementInitializer } from '@umbraco-cms/backoffice/extension-api';
|
||||
import { UmbExtensionsElementInitializer } from '@umbraco-cms/backoffice/extension-api';
|
||||
import { UMB_WORKSPACE_PATH_PATTERN } from '@umbraco-cms/backoffice/workspace';
|
||||
import {
|
||||
UmbExtensionsElementAndApiInitializer,
|
||||
UmbExtensionsElementInitializer,
|
||||
} from '@umbraco-cms/backoffice/extension-api';
|
||||
import { aliasToPath, debounce } from '@umbraco-cms/backoffice/utils';
|
||||
|
||||
/**
|
||||
* @export
|
||||
@@ -47,6 +50,10 @@ export class UmbSectionDefaultElement extends UmbLitElement implements UmbSectio
|
||||
@state()
|
||||
_splitPanelPosition = '300px';
|
||||
|
||||
#routeExtensionsController:
|
||||
| UmbExtensionsElementAndApiInitializer<ManifestSectionRoute, 'sectionRoute', ManifestSectionRoute>
|
||||
| undefined;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
@@ -56,7 +63,7 @@ export class UmbSectionDefaultElement extends UmbLitElement implements UmbSectio
|
||||
this.requestUpdate('_sidebarApps', oldValue);
|
||||
});
|
||||
|
||||
this.#createRoutes();
|
||||
this.#observeRoutes();
|
||||
|
||||
const splitPanelPosition = localStorage.getItem('umb-split-panel-position');
|
||||
if (splitPanelPosition) {
|
||||
@@ -64,15 +71,44 @@ export class UmbSectionDefaultElement extends UmbLitElement implements UmbSectio
|
||||
}
|
||||
}
|
||||
|
||||
#createRoutes() {
|
||||
this._routes = [
|
||||
{
|
||||
path: UMB_WORKSPACE_PATH_PATTERN.toString(),
|
||||
component: () => import('../workspace/workspace.element.js'),
|
||||
setup: (element, info) => {
|
||||
(element as UmbWorkspaceElement).entityType = info.match.params.entityType;
|
||||
},
|
||||
#observeRoutes(): void {
|
||||
this.#routeExtensionsController?.destroy();
|
||||
|
||||
this.#routeExtensionsController = new UmbExtensionsElementAndApiInitializer<
|
||||
ManifestSectionRoute,
|
||||
'sectionRoute',
|
||||
ManifestSectionRoute
|
||||
>(
|
||||
this,
|
||||
umbExtensionsRegistry,
|
||||
'sectionRoute',
|
||||
undefined,
|
||||
undefined,
|
||||
(sectionRouteExtensions) => {
|
||||
const routes: Array<IRoute> = sectionRouteExtensions.map((extensionController) => {
|
||||
return {
|
||||
path:
|
||||
extensionController.api?.getPath?.() ||
|
||||
extensionController.manifest.meta?.path ||
|
||||
aliasToPath(extensionController.manifest.alias),
|
||||
component: extensionController.component,
|
||||
setup: (element: PageComponent, info: IRoutingInfo) => {
|
||||
extensionController.api?.setup?.(element, info);
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
this.#debouncedCreateRoutes(routes);
|
||||
},
|
||||
undefined, // We can leave the alias to undefined, as we destroy this our selfs.
|
||||
);
|
||||
}
|
||||
|
||||
#debouncedCreateRoutes = debounce(this.#createRoutes, 50);
|
||||
|
||||
#createRoutes(routes: Array<IRoute>) {
|
||||
this._routes = [
|
||||
...routes,
|
||||
{
|
||||
path: '**',
|
||||
component: () => import('./section-main-views/section-main-views.element.js'),
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
export const encodeFilePath = (path: string) => encodeURIComponent(path).replace('.', '-');
|
||||
export const encodeFilePath = (path: string) => encodeURIComponent(path).replaceAll('.', '-');
|
||||
|
||||
export const aliasToPath = (path: string) => encodeFilePath(path);
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { manifests as componentManifests } from './components/manifests.js';
|
||||
import { manifests as workspaceKinds } from './kinds/manifests.js';
|
||||
import { manifests as workspaceModals } from './modals/manifests.js';
|
||||
import { manifests as workspaceConditions } from './conditions/manifests.js';
|
||||
import { manifests as sectionRouteManifests } from './section-routes/manifests.js';
|
||||
import { manifests as workspaceConditionManifests } from './conditions/manifests.js';
|
||||
import { manifests as workspaceKindManifest } from './kinds/manifests.js';
|
||||
import { manifests as workspaceModalManifest } from './modals/manifests.js';
|
||||
import type { ManifestTypes, UmbBackofficeManifestKind } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const manifests: Array<ManifestTypes | UmbBackofficeManifestKind> = [
|
||||
...workspaceConditions,
|
||||
...workspaceKinds,
|
||||
...componentManifests,
|
||||
...workspaceModals,
|
||||
...sectionRouteManifests,
|
||||
...workspaceConditionManifests,
|
||||
...workspaceKindManifest,
|
||||
...workspaceModalManifest,
|
||||
];
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry';
|
||||
|
||||
export const manifests: Array<ManifestTypes> = [
|
||||
{
|
||||
type: 'sectionRoute',
|
||||
alias: 'Umb.SectionRoute.Workspace',
|
||||
name: 'Workspace Section Route',
|
||||
element: () => import('../workspace.element.js'),
|
||||
api: () => import('./workspace-section-route.route-entry.js'),
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,18 @@
|
||||
import { UMB_WORKSPACE_PATH_PATTERN } from '../paths.js';
|
||||
import type { UmbWorkspaceElement } from '../workspace.element.js';
|
||||
import type { IRoutingInfo, PageComponent, UmbRouteEntry } from '@umbraco-cms/backoffice/router';
|
||||
import type { UmbApi } from '@umbraco-cms/backoffice/extension-api';
|
||||
|
||||
export class UmbWorkspaceSectionRouteEntry implements UmbApi, UmbRouteEntry {
|
||||
getPath(): string {
|
||||
return UMB_WORKSPACE_PATH_PATTERN.toString();
|
||||
}
|
||||
|
||||
setup(element: PageComponent, info: IRoutingInfo) {
|
||||
(element as UmbWorkspaceElement).entityType = info.match.params.entityType;
|
||||
}
|
||||
|
||||
destroy(): void {}
|
||||
}
|
||||
|
||||
export { UmbWorkspaceSectionRouteEntry as api };
|
||||
Reference in New Issue
Block a user