From 9c5373fffda7629068db5a2ebd39f486d165388a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 24 May 2024 18:37:57 +0200 Subject: [PATCH 1/8] add route entry interface --- .../src/packages/core/router/index.ts | 1 + .../src/packages/core/router/types.ts | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/router/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/index.ts index 181854001c..fc2663470f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/router/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/index.ts @@ -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'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/types.ts new file mode 100644 index 0000000000..6fcea8d459 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/types.ts @@ -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; +} From 1473e2f5ff7442ca41e060c8ecef0ac1e4292d9f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 24 May 2024 18:38:10 +0200 Subject: [PATCH 2/8] add new section route extension type --- .../packages/core/extension-registry/models/index.ts | 2 ++ .../extension-registry/models/section-route.model.ts | 12 ++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/section-route.model.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/index.ts index c81ff73f7f..b0aa5d38f4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/index.ts @@ -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 diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/section-route.model.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/section-route.model.ts new file mode 100644 index 0000000000..fc57b62471 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/models/section-route.model.ts @@ -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 { + type: 'sectionRoute'; + meta: MetaSectionRoute; +} + +export interface MetaSectionRoute { + path?: string; +} From 404400d205ef4cfae465ab35686d36dab7881545 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 24 May 2024 18:38:38 +0200 Subject: [PATCH 3/8] add util to encode alias to path --- .../src/packages/core/utils/path/path-encode.function.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/path-encode.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/path-encode.function.ts index ef3e8b0a2b..7b7567cf74 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/path-encode.function.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/path/path-encode.function.ts @@ -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); From 7af2271b6f4ba46391037f019be8906936deb727 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 24 May 2024 18:39:05 +0200 Subject: [PATCH 4/8] handle section routes in default section element --- .../core/section/section-default.element.ts | 62 +++++++++++++++---- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/section/section-default.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/section/section-default.element.ts index bfb1103f32..fca5c4c6df 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/section/section-default.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/section/section-default.element.ts @@ -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 + | 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 = 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) { + this._routes = [ + ...routes, { path: '**', component: () => import('./section-main-views/section-main-views.element.js'), From e873487da9b753083a6a5f5bf0438e1d327a129d Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 24 May 2024 18:39:28 +0200 Subject: [PATCH 5/8] register workspace as a section route --- .../src/packages/core/workspace/manifests.ts | 14 ++++++++------ .../core/workspace/section-routes/manifests.ts | 11 +++++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/workspace/section-routes/manifests.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/manifests.ts index 95204a41c6..7e64360c26 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/manifests.ts @@ -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 = [ - ...workspaceConditions, - ...workspaceKinds, ...componentManifests, - ...workspaceModals, + ...sectionRouteManifests, + ...workspaceConditionManifests, + ...workspaceKindManifest, + ...workspaceModalManifest, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/section-routes/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/section-routes/manifests.ts new file mode 100644 index 0000000000..566b1b5e31 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/section-routes/manifests.ts @@ -0,0 +1,11 @@ +import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + { + type: 'sectionRoute', + alias: 'Umb.SectionRoute.Workspace', + name: 'Section Workspace Route', + element: () => import('../workspace.element.js'), + api: () => import('./workspace-section-route.api.js'), + }, +]; From 338032d98fb2f35c2fe19909bac2daf4043fceb4 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 24 May 2024 18:40:13 +0200 Subject: [PATCH 6/8] add api class --- .../workspace-section-route.route-entry.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/workspace/section-routes/workspace-section-route.route-entry.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/section-routes/workspace-section-route.route-entry.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/section-routes/workspace-section-route.route-entry.ts new file mode 100644 index 0000000000..eae555fb26 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/section-routes/workspace-section-route.route-entry.ts @@ -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 }; From acd22889069f274333dfecc82ecc01985ee601a6 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 24 May 2024 18:50:52 +0200 Subject: [PATCH 7/8] change type --- .../src/packages/core/workspace/section-routes/manifests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/section-routes/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/section-routes/manifests.ts index 566b1b5e31..804f7dc284 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/section-routes/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/section-routes/manifests.ts @@ -6,6 +6,6 @@ export const manifests: Array = [ alias: 'Umb.SectionRoute.Workspace', name: 'Section Workspace Route', element: () => import('../workspace.element.js'), - api: () => import('./workspace-section-route.api.js'), + api: () => import('./workspace-section-route.route-entry.js'), }, ]; From d87d3930db232985bf5ebdb54b51e53aa677b3dc Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 24 May 2024 18:58:09 +0200 Subject: [PATCH 8/8] Better name --- .../src/packages/core/workspace/section-routes/manifests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/section-routes/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/section-routes/manifests.ts index 804f7dc284..e5d441f3fc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/section-routes/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/section-routes/manifests.ts @@ -4,7 +4,7 @@ export const manifests: Array = [ { type: 'sectionRoute', alias: 'Umb.SectionRoute.Workspace', - name: 'Section Workspace Route', + name: 'Workspace Section Route', element: () => import('../workspace.element.js'), api: () => import('./workspace-section-route.route-entry.js'), },