From 1c769a4e1294f7cbf3b8b92a7fa692f4aa2c1351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 6 Mar 2024 19:21:31 +0100 Subject: [PATCH 1/7] move to repository folder --- .../src/packages/core/content-type/index.ts | 4 ++-- .../content-type-structure-data-source.interface.ts | 0 .../content-type-structure-repository-base.ts | 0 .../content-type-structure-repository.interface.ts | 0 .../content-type-structure-server-data-source-base.ts | 0 .../core/content-type/{structure => repository}/index.ts | 0 6 files changed, 2 insertions(+), 2 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/core/content-type/{structure => repository}/content-type-structure-data-source.interface.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/core/content-type/{structure => repository}/content-type-structure-repository-base.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/core/content-type/{structure => repository}/content-type-structure-repository.interface.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/core/content-type/{structure => repository}/content-type-structure-server-data-source-base.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/core/content-type/{structure => repository}/index.ts (100%) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/index.ts index f2eddad99c..944a60f9d3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/index.ts @@ -1,6 +1,6 @@ +export * from './components/index.js'; export * from './content-type-container-structure-helper.class.js'; export * from './content-type-property-structure-helper.class.js'; export * from './content-type-structure-manager.class.js'; +export * from './repository/index.js'; export * from './types.js'; -export * from './components/index.js'; -export * from './structure/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-data-source.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/repository/content-type-structure-data-source.interface.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-data-source.interface.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/content-type/repository/content-type-structure-data-source.interface.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-repository-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/repository/content-type-structure-repository-base.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-repository-base.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/content-type/repository/content-type-structure-repository-base.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-repository.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/repository/content-type-structure-repository.interface.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-repository.interface.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/content-type/repository/content-type-structure-repository.interface.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-server-data-source-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/repository/content-type-structure-server-data-source-base.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/content-type-structure-server-data-source-base.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/content-type/repository/content-type-structure-server-data-source-base.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/repository/index.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/core/content-type/structure/index.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/content-type/repository/index.ts From 2a3ed74402bee1247fca09f735f5b3cc4f047c29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 8 Mar 2024 11:43:30 +0100 Subject: [PATCH 2/7] level up methods --- .../src/packages/core/router/route.context.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/route.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/route.context.ts index 70a2198629..c72a5b1bd4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/router/route.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/route.context.ts @@ -31,6 +31,19 @@ export class UmbRouteContext extends UmbControllerBase { }); } + public navigateLevelUp() { + const path = this.getLevelUpPath(); + if (path) { + window.history.pushState({}, '', path); + } + } + public getLevelUpPath() { + if (this.#routerBasePath) { + return this.#routerBasePath.endsWith('/') ? this.#routerBasePath : this.#routerBasePath + '/'; + } + return; + } + public registerModal(registration: UmbModalRouteRegistration) { this.#modalRegistrations.push(registration); this.#createNewUrlBuilder(registration); From 9724a4479650686cc0a51de65a9c02e95aa8952b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Fri, 8 Mar 2024 13:21:48 +0100 Subject: [PATCH 3/7] _constructLocalRouterPath --- .../src/packages/core/router/route.context.ts | 14 -------------- .../packages/core/router/router-slot.element.ts | 17 ++++++++++++----- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/route.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/route.context.ts index c72a5b1bd4..d7f41278b7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/router/route.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/route.context.ts @@ -31,19 +31,6 @@ export class UmbRouteContext extends UmbControllerBase { }); } - public navigateLevelUp() { - const path = this.getLevelUpPath(); - if (path) { - window.history.pushState({}, '', path); - } - } - public getLevelUpPath() { - if (this.#routerBasePath) { - return this.#routerBasePath.endsWith('/') ? this.#routerBasePath : this.#routerBasePath + '/'; - } - return; - } - public registerModal(registration: UmbModalRouteRegistration) { this.#modalRegistrations.push(registration); this.#createNewUrlBuilder(registration); @@ -162,7 +149,6 @@ export class UmbRouteContext extends UmbControllerBase { : this.#routerActiveLocalPath + '/' : ''; const localPath = routeBasePath + routeActiveLocalPath + modalRegistration.generateModalPath(); - const urlBuilder = createRoutePathBuilder(localPath); modalRegistration._internal_setRouteBuilder(urlBuilder); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/router-slot.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/router-slot.element.ts index 50e54d418f..7ec328256a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/router/router-slot.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/router-slot.element.ts @@ -70,6 +70,10 @@ export class UmbRouterSlotElement extends UmbLitElement { return this.#router.constructAbsolutePath('') || ''; } + protected _constructLocalRouterPath() { + return this.#router.match?.fragments.consumed ?? ''; + } + connectedCallback() { super.connectedCallback(); // Currently we have to set this every time as RouteSlot looks for its parent every-time it is connected. Aka it has not way to explicitly set the parent. @@ -101,7 +105,7 @@ export class UmbRouterSlotElement extends UmbLitElement { this.#routeContext._internal_routerGotBasePath(this._routerPath); this.dispatchEvent(new UmbRouterSlotInitEvent()); - const newActiveLocalPath = this.#router.match?.route.path; + const newActiveLocalPath = this._constructLocalRouterPath(); if (this._activeLocalPath !== newActiveLocalPath) { this._activeLocalPath = newActiveLocalPath; this.#routeContext._internal_routerGotActiveLocalPath(this._activeLocalPath); @@ -112,11 +116,14 @@ export class UmbRouterSlotElement extends UmbLitElement { private _onNavigationChanged = (event?: any) => { if (event.detail.slot === this.#router) { - this._activeLocalPath = event.detail.match.route.path; - this.#routeContext._internal_routerGotActiveLocalPath(this._activeLocalPath); - this.dispatchEvent(new UmbRouterSlotChangeEvent()); + const newActiveLocalPath = this._constructLocalRouterPath(); + if (this._activeLocalPath !== newActiveLocalPath) { + this._activeLocalPath = newActiveLocalPath; + this.#routeContext._internal_routerGotActiveLocalPath(newActiveLocalPath); + this.dispatchEvent(new UmbRouterSlotChangeEvent()); + } } else if (event.detail.slot === this.#modalRouter) { - const newActiveModalLocalPath = event.detail.match.route.path; + const newActiveModalLocalPath = this.#modalRouter.match?.fragments.consumed ?? ''; this.#routeContext._internal_modalRouterChanged(newActiveModalLocalPath); } }; From d7d1c7925e6f1f5c9f5e4f02301cef87e981a2b5 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Mon, 11 Mar 2024 15:13:46 +0100 Subject: [PATCH 4/7] add support for having paramater-like segments of a url that shouldn't be replaced + tests --- ...nerate-route-path-builder.function.test.ts | 39 +++++++++++++++++++ .../generate-route-path-builder.function.ts | 11 +++--- 2 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts new file mode 100644 index 0000000000..efacc1ea44 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts @@ -0,0 +1,39 @@ +import { expect } from '@open-wc/testing'; +import { createRoutePathBuilder } from './generate-route-path-builder.function.js'; + +describe('createRoutePathBuilder', () => { + it('should return a function that builds a route path without parameters', () => { + const buildPath = createRoutePathBuilder('test/path'); + expect(buildPath(null)).to.eq('/test/path/'); + }); + + it('should return a function that builds a route path with parameters', () => { + const buildPath = createRoutePathBuilder('test/:param1/path/:param2'); + expect(buildPath({ param1: 'value1', param2: 'value2' })).to.eq('/test/value1/path/value2/'); + }); + + it('should convert number parameters to strings', () => { + const buildPath = createRoutePathBuilder('test/:param1/path/:param2'); + expect(buildPath({ param1: 123, param2: 456 })).to.eq('/test/123/path/456/'); + }); + + it('should not consider route segments that resembles parameters as parameters', () => { + const buildPath = createRoutePathBuilder('test/uc:store/path'); + expect(buildPath({ someOtherParam: 'test' })).to.eq('/test/uc:store/path/'); + }); + + it('should support multiple parameters with the same name', () => { + const buildPath = createRoutePathBuilder('test/:param1/path/:param1'); + expect(buildPath({ param1: 'value1' })).to.eq('/test/value1/path/value1/'); + }); + + it('should support complex objects as parameters with a custom toString method', () => { + const buildPath = createRoutePathBuilder('test/:param1/path/:param2'); + const obj = { + toString() { + return 'value1'; + }, + }; + expect(buildPath({ param1: obj, param2: 'value2' })).to.eq('/test/value1/path/value2/'); + }); +}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.ts index b2fbf53067..162f8514dc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.ts @@ -1,17 +1,18 @@ /* eslint-disable */ import { stripSlash } from '@umbraco-cms/backoffice/external/router-slot'; // This must only include the util to avoid side effects of registering the route element. -const PARAM_IDENTIFIER = /:([^\\/]+)/g; +const PARAM_IDENTIFIER = /\/:([^\/]+)/g; export function createRoutePathBuilder(path: string) { - return (params: { [key: string]: string | number } | null) => { + return (params: { [key: string]: string | number | { toString: () => string } } | null) => { return ( '/' + stripSlash( params - ? path.replace(PARAM_IDENTIFIER, (substring: string, ...args: string[]) => { - return params[args[0]].toString(); - }) + ? path.replace(PARAM_IDENTIFIER, (_substring: string, ...args: string[]) => { + // Replace the parameter with the value from the params object or the parameter name if it doesn't exist (args[0] is the parameter name without the colon) + return '/' + (typeof params[args[0]] !== 'undefined' ? params[args[0]].toString() : `:${args[0]}`); + }) : path, ) + '/' From 638c1139f97388ad3f5b704e39bd284aadd1841f Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Mon, 11 Mar 2024 16:12:55 +0100 Subject: [PATCH 5/7] add support for URLs without a leading slash --- .../router/generate-route-path-builder.function.test.ts | 6 ++++-- .../core/router/generate-route-path-builder.function.ts | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts index efacc1ea44..6efbf1845f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts @@ -8,8 +8,10 @@ describe('createRoutePathBuilder', () => { }); it('should return a function that builds a route path with parameters', () => { - const buildPath = createRoutePathBuilder('test/:param1/path/:param2'); - expect(buildPath({ param1: 'value1', param2: 'value2' })).to.eq('/test/value1/path/value2/'); + const buildPath = createRoutePathBuilder(':param0/test/:param1/path/:param2'); + expect(buildPath({ param0: 'value0', param1: 'value1', param2: 'value2' })).to.eq( + '/value0/test/value1/path/value2/', + ); }); it('should convert number parameters to strings', () => { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.ts index 162f8514dc..115a6c3f91 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.ts @@ -1,7 +1,7 @@ /* eslint-disable */ import { stripSlash } from '@umbraco-cms/backoffice/external/router-slot'; // This must only include the util to avoid side effects of registering the route element. -const PARAM_IDENTIFIER = /\/:([^\/]+)/g; +const PARAM_IDENTIFIER = /:([^\/]+)/g; export function createRoutePathBuilder(path: string) { return (params: { [key: string]: string | number | { toString: () => string } } | null) => { @@ -11,7 +11,7 @@ export function createRoutePathBuilder(path: string) { params ? path.replace(PARAM_IDENTIFIER, (_substring: string, ...args: string[]) => { // Replace the parameter with the value from the params object or the parameter name if it doesn't exist (args[0] is the parameter name without the colon) - return '/' + (typeof params[args[0]] !== 'undefined' ? params[args[0]].toString() : `:${args[0]}`); + return typeof params[args[0]] !== 'undefined' ? params[args[0]].toString() : `:${args[0]}`; }) : path, ) + From 586758dd4e7fdb0cc98ab431c8267bbb4690cced Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Mon, 11 Mar 2024 16:14:19 +0100 Subject: [PATCH 6/7] test if only known parameters are replaced --- .../core/router/generate-route-path-builder.function.test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts index 6efbf1845f..f6de7d9f86 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts @@ -29,6 +29,11 @@ describe('createRoutePathBuilder', () => { expect(buildPath({ param1: 'value1' })).to.eq('/test/value1/path/value1/'); }); + it('should not consider parameters that are not in the params object', () => { + const buildPath = createRoutePathBuilder('test/:param1/path/:param2'); + expect(buildPath({ param1: 'value1' })).to.eq('/test/value1/path/:param2/'); + }); + it('should support complex objects as parameters with a custom toString method', () => { const buildPath = createRoutePathBuilder('test/:param1/path/:param2'); const obj = { From b6897771e24bafc029dafbf2af8f81730c62aa12 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 11 Mar 2024 15:20:38 +0100 Subject: [PATCH 7/7] don't allow reload of data type children --- .../data-type/tree/reload-tree-item-children/manifests.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/tree/reload-tree-item-children/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/tree/reload-tree-item-children/manifests.ts index e5f14fc8cb..cf276f7dc6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/data-type/tree/reload-tree-item-children/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/tree/reload-tree-item-children/manifests.ts @@ -1,8 +1,4 @@ -import { - UMB_DATA_TYPE_ENTITY_TYPE, - UMB_DATA_TYPE_FOLDER_ENTITY_TYPE, - UMB_DATA_TYPE_ROOT_ENTITY_TYPE, -} from '../../entity.js'; +import { UMB_DATA_TYPE_FOLDER_ENTITY_TYPE, UMB_DATA_TYPE_ROOT_ENTITY_TYPE } from '../../entity.js'; import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; export const manifests: Array = [ @@ -11,7 +7,7 @@ export const manifests: Array = [ kind: 'reloadTreeItemChildren', alias: 'Umb.EntityAction.DataType.Tree.ReloadChildrenOf', name: 'Reload Data Type Tree Item Children Entity Action', - forEntityTypes: [UMB_DATA_TYPE_ENTITY_TYPE, UMB_DATA_TYPE_ROOT_ENTITY_TYPE, UMB_DATA_TYPE_FOLDER_ENTITY_TYPE], + forEntityTypes: [UMB_DATA_TYPE_ROOT_ENTITY_TYPE, UMB_DATA_TYPE_FOLDER_ENTITY_TYPE], meta: {}, }, ];