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..f6de7d9f86 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/router/generate-route-path-builder.function.test.ts @@ -0,0 +1,46 @@ +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(':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', () => { + 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 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 = { + 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..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,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, ) + '/' 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: {}, }, ];