From fe009278cc05e082e6b73c0e032213f3ed563ca7 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 Jan 2025 22:35:23 +0100 Subject: [PATCH 01/17] allow passing headline and content string through manifest --- .../src/packages/core/entity-action/common/delete/types.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/types.ts index e01e50df2b..6d51bbecf5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/types.ts @@ -8,6 +8,10 @@ export interface ManifestEntityActionDeleteKind extends ManifestEntityAction Date: Thu, 30 Jan 2025 22:35:45 +0100 Subject: [PATCH 02/17] add clipboard translations --- src/Umbraco.Web.UI.Client/src/assets/lang/en.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts index 58885ade29..2b0411e609 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts @@ -2388,6 +2388,8 @@ export default { labelForRemoveAllEntries: 'Remove all items', labelForClearClipboard: 'Clear clipboard', labelForCopyToClipboard: 'Copy to clipboard', + confirmDeleteHeadline: 'Delete from clipboard', + confirmDeleteDescription: 'Are you sure you want to delete {0} from the clipboard?', }, propertyActions: { tooltipForPropertyActionsMenu: 'Open Property Actions', From 1872a9a139315adcbe7b476d6f19a5036cb1b022 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 Jan 2025 22:35:59 +0100 Subject: [PATCH 03/17] add keys to manifest --- .../packages/clipboard/clipboard-entry/detail/manifests.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/clipboard/clipboard-entry/detail/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/clipboard/clipboard-entry/detail/manifests.ts index f6a2cabd2a..5005ec5f48 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/clipboard/clipboard-entry/detail/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/clipboard/clipboard-entry/detail/manifests.ts @@ -19,11 +19,15 @@ export const manifests: Array = [ type: 'entityAction', kind: 'delete', alias: 'Umb.EntityAction.ClipboardEntry.Delete', - name: 'Delete Dictionary Entry Entity Action', + name: 'Delete Clipboard Entry Entity Action', forEntityTypes: [UMB_CLIPBOARD_ENTRY_ENTITY_TYPE], meta: { itemRepositoryAlias: UMB_CLIPBOARD_ENTRY_ITEM_REPOSITORY_ALIAS, detailRepositoryAlias: UMB_CLIPBOARD_ENTRY_DETAIL_REPOSITORY_ALIAS, + confirm: { + headline: '#clipboard_confirmDeleteHeadline', + content: '#clipboard_confirmDeleteDescription', + }, }, }, ]; From 25ca146eee9e41f793e6a32dcf5db933a9d8a4be Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 Jan 2025 22:36:39 +0100 Subject: [PATCH 04/17] handle strings with args in localize controller --- .../localization.controller.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.ts b/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.ts index 1c92265e91..5d14b7eb2d 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.ts @@ -191,9 +191,10 @@ export class UmbLocalizationController>} argsMap An object where the keys are the terms to translate and the values are arrays of arguments to pass to the term function. * @returns {string} The translated text. */ - string(text: unknown): string { + string(text: unknown, argsMap?: Record>): string { if (typeof text !== 'string') { return ''; } @@ -203,14 +204,26 @@ export class UmbLocalizationController { const key = match.slice(1); - // TODO: find solution to pass dynamic string to term + const args = argsMap?.[key] || []; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - const localized = this.term(key); + const localized = this.term(key, ...args); // we didn't find a localized string, so we return the original string with the # return localized === key ? match : localized; }); return localizedText; } + + /** + * Extracts all keys from a string that start with a `#` character. + * @param {string} text The text to parse. + * @returns {Array} An array of keys. + */ + getKeysFromString(text: string): Array { + const regex = /#\w+/g; + const keys = text.match(regex) || []; + return keys.map((key) => key.slice(1)); + } } From fe97cbeb7f2c9f5e77503861eddb448caaa9067c Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 Jan 2025 22:36:50 +0100 Subject: [PATCH 05/17] add tests --- .../localization.controller.test.ts | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.test.ts b/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.test.ts index 233bef12c9..b5eadaf6cf 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.test.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.test.ts @@ -302,6 +302,42 @@ describe('UmbLocalizeController', () => { expect(controller.string({})).to.equal(''); expect(controller.string(undefined)).to.equal(''); }); + + it('should return an empty string if the input is an empty string', async () => { + expect(controller.string('')).to.equal(''); + }); + + it('should return the input string if the input is not prefixed with a #', async () => { + const str = 'close'; + expect(controller.string(str)).to.equal('close'); + }); + + it('should replace tokens in each key with the provided values', async () => { + const str = '#withInlineToken #withInlineTokenLegacy'; + expect( + controller.string(str, { withInlineToken: ['value1', 'value2'], withInlineTokenLegacy: ['value3', 'value4'] }), + ).to.equal('value1 value2 value3 value4'); + }); + }); + + describe('getKeysFromString', () => { + it('should return an empty array if the input is not a string', async () => { + // @ts-expect-error + expect(controller.getKeysFromString(123)).to.deep.equal([]); + // @ts-expect-error + expect(controller.getKeysFromString({})).to.deep.equal([]); + // @ts-expect-error + expect(controller.getKeysFromString(undefined)).to.deep.equal([]); + }); + + it('should return an empty array if the input is an empty string', async () => { + expect(controller.getKeysFromString('')).to.deep.equal([]); + }); + + it('should return an array of keys', async () => { + const str = '#close #logout'; + expect(controller.getKeysFromString(str)).to.deep.equal(['close', 'logout']); + }); }); describe('host element', () => { From 4f3e4948a8bcc7cb6651bc742f3b527f8bc3af5c Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 Jan 2025 22:37:09 +0100 Subject: [PATCH 06/17] translate manifest strings --- .../entity-action/common/delete/delete.action.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts index e02b22e7f3..faa532f64e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts @@ -5,9 +5,13 @@ import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-reg import { umbConfirmModal } from '@umbraco-cms/backoffice/modal'; import type { UmbDetailRepository, UmbItemRepository } from '@umbraco-cms/backoffice/repository'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; +import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api'; + +type UmbLocalizeStringArgsMap = Record>; export class UmbDeleteEntityAction extends UmbEntityActionBase { // TODO: make base type for item and detail models + #localize = new UmbLocalizationController(this); override async execute() { if (!this.args.unique) throw new Error('Cannot delete an item without a unique identifier.'); @@ -21,10 +25,18 @@ export class UmbDeleteEntityAction extends UmbEntityActionBase { + acc[key] = [item.name]; + return acc; + }, {}); + // TODO: handle items with variants await umbConfirmModal(this._host, { - headline: `Delete`, - content: `Are you sure you want to delete ${item.name}?`, + headline: this.#localize.string(headline), + content: this.#localize.string(content, argsMap), color: 'danger', confirmLabel: 'Delete', }); From be61daebf55ce0df61a729363a80fd4ce371f16e Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 Jan 2025 22:37:15 +0100 Subject: [PATCH 07/17] export consts --- src/Umbraco.Web.UI.Client/utils/all-umb-consts/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/utils/all-umb-consts/index.ts b/src/Umbraco.Web.UI.Client/utils/all-umb-consts/index.ts index b13b2d8689..9e118cfd5e 100644 --- a/src/Umbraco.Web.UI.Client/utils/all-umb-consts/index.ts +++ b/src/Umbraco.Web.UI.Client/utils/all-umb-consts/index.ts @@ -404,7 +404,7 @@ export const foundConsts = [{ }, { path: '@umbraco-cms/backoffice/user', - consts: ["UMB_CREATE_USER_CLIENT_CREDENTIAL_MODAL","UMB_CREATE_USER_CLIENT_CREDENTIAL_MODAL_ALIAS","UMB_USER_CLIENT_CREDENTIAL_REPOSITORY_ALIAS","UMB_USER_COLLECTION_ALIAS","UMB_USER_COLLECTION_REPOSITORY_ALIAS","UMB_USER_COLLECTION_CONTEXT","UMB_COLLECTION_VIEW_USER_TABLE","UMB_COLLECTION_VIEW_USER_GRID","UMB_USER_ALLOW_CHANGE_PASSWORD_CONDITION_ALIAS","UMB_USER_ALLOW_DELETE_CONDITION_ALIAS","UMB_USER_ALLOW_DISABLE_CONDITION_ALIAS","UMB_USER_ALLOW_ENABLE_CONDITION_ALIAS","UMB_USER_ALLOW_EXTERNAL_LOGIN_CONDITION_ALIAS","UMB_USER_ALLOW_MFA_CONDITION_ALIAS","UMB_USER_ALLOW_UNLOCK_CONDITION_ALIAS","UMB_USER_IS_DEFAULT_KIND_CONDITION_ALIAS","UMB_CREATE_USER_MODAL","UMB_CREATE_USER_SUCCESS_MODAL","UMB_CREATE_USER_MODAL_ALIAS","UMB_USER_ENTITY_TYPE","UMB_USER_ROOT_ENTITY_TYPE","UMB_INVITE_USER_MODAL","UMB_RESEND_INVITE_TO_USER_MODAL","UMB_INVITE_USER_REPOSITORY_ALIAS","UMB_USER_MFA_MODAL","UMB_USER_PICKER_MODAL","UMB_USER_WORKSPACE_PATH","UMB_USER_ROOT_WORKSPACE_PATH","UMB_USER_AVATAR_REPOSITORY_ALIAS","UMB_CHANGE_USER_PASSWORD_REPOSITORY_ALIAS","UMB_USER_CONFIG_REPOSITORY_ALIAS","UMB_USER_CONFIG_STORE_ALIAS","UMB_USER_CONFIG_STORE_CONTEXT","UMB_CURRENT_USER_CONFIG_STORE_CONTEXT","UMB_USER_DETAIL_REPOSITORY_ALIAS","UMB_USER_DETAIL_STORE_ALIAS","UMB_USER_DETAIL_STORE_CONTEXT","UMB_DISABLE_USER_REPOSITORY_ALIAS","UMB_ENABLE_USER_REPOSITORY_ALIAS","UMB_USER_ITEM_REPOSITORY_ALIAS","UMB_USER_ITEM_STORE_ALIAS","UMB_USER_ITEM_STORE_CONTEXT","UMB_NEW_USER_PASSWORD_REPOSITORY_ALIAS","UMB_UNLOCK_USER_REPOSITORY_ALIAS","UMB_USER_WORKSPACE_ALIAS","UMB_USER_WORKSPACE_CONTEXT","UMB_USER_ROOT_WORKSPACE_ALIAS"] + consts: ["UMB_CREATE_USER_CLIENT_CREDENTIAL_MODAL","UMB_CREATE_USER_CLIENT_CREDENTIAL_MODAL_ALIAS","UMB_USER_CLIENT_CREDENTIAL_REPOSITORY_ALIAS","UMB_USER_COLLECTION_ALIAS","UMB_USER_COLLECTION_REPOSITORY_ALIAS","UMB_USER_COLLECTION_CONTEXT","UMB_COLLECTION_VIEW_USER_TABLE","UMB_COLLECTION_VIEW_USER_GRID","UMB_USER_ALLOW_CHANGE_PASSWORD_CONDITION_ALIAS","UMB_CURRENT_USER_ALLOW_CHANGE_PASSWORD_CONDITION_ALIAS","UMB_USER_ALLOW_DELETE_CONDITION_ALIAS","UMB_USER_ALLOW_DISABLE_CONDITION_ALIAS","UMB_USER_ALLOW_ENABLE_CONDITION_ALIAS","UMB_USER_ALLOW_EXTERNAL_LOGIN_CONDITION_ALIAS","UMB_USER_ALLOW_MFA_CONDITION_ALIAS","UMB_CURRENT_USER_ALLOW_MFA_CONDITION_ALIAS","UMB_USER_ALLOW_UNLOCK_CONDITION_ALIAS","UMB_USER_IS_DEFAULT_KIND_CONDITION_ALIAS","UMB_CREATE_USER_MODAL","UMB_CREATE_USER_SUCCESS_MODAL","UMB_CREATE_USER_MODAL_ALIAS","UMB_USER_ENTITY_TYPE","UMB_USER_ROOT_ENTITY_TYPE","UMB_INVITE_USER_MODAL","UMB_RESEND_INVITE_TO_USER_MODAL","UMB_INVITE_USER_REPOSITORY_ALIAS","UMB_USER_MFA_MODAL","UMB_USER_PICKER_MODAL","UMB_USER_WORKSPACE_PATH","UMB_USER_ROOT_WORKSPACE_PATH","UMB_USER_AVATAR_REPOSITORY_ALIAS","UMB_CHANGE_USER_PASSWORD_REPOSITORY_ALIAS","UMB_USER_CONFIG_REPOSITORY_ALIAS","UMB_USER_CONFIG_STORE_ALIAS","UMB_CURRENT_USER_CONFIG_REPOSITORY_ALIAS","UMB_CURRENT_USER_CONFIG_STORE_ALIAS","UMB_CURRENT_USER_CONFIG_STORE_CONTEXT","UMB_USER_CONFIG_STORE_CONTEXT","UMB_USER_DETAIL_REPOSITORY_ALIAS","UMB_USER_DETAIL_STORE_ALIAS","UMB_USER_DETAIL_STORE_CONTEXT","UMB_DISABLE_USER_REPOSITORY_ALIAS","UMB_ENABLE_USER_REPOSITORY_ALIAS","UMB_USER_ITEM_REPOSITORY_ALIAS","UMB_USER_ITEM_STORE_ALIAS","UMB_USER_ITEM_STORE_CONTEXT","UMB_NEW_USER_PASSWORD_REPOSITORY_ALIAS","UMB_UNLOCK_USER_REPOSITORY_ALIAS","UMB_USER_WORKSPACE_ALIAS","UMB_USER_WORKSPACE_CONTEXT","UMB_USER_ROOT_WORKSPACE_ALIAS"] }, { path: '@umbraco-cms/backoffice/utils', From c3d510dfe94ca0a9a34cfdaafc0e279c2acf5018 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 Jan 2025 22:44:19 +0100 Subject: [PATCH 08/17] add token --- src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts | 2 +- src/Umbraco.Web.UI.Client/src/assets/lang/en.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts index abee3dfad2..8ae9655a15 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts @@ -508,7 +508,7 @@ export default { anchorLinkPicker: 'Anchor or querystring', anchorInsert: 'Name', closeThisWindow: 'Close this window', - confirmdelete: 'Are you sure you want to delete', + confirmdelete: 'Are you sure you want to delete {0}?', confirmdeleteNumberOfItems: 'Are you sure you want to delete %0% of %1% items', confirmdisable: 'Are you sure you want to disable', confirmremove: 'Are you sure you want to remove', diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts index 2b0411e609..0e72bcfa7c 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts @@ -497,7 +497,7 @@ export default { anchorLinkPicker: 'Anchor or querystring', anchorInsert: 'Name', closeThisWindow: 'Close this window', - confirmdelete: 'Are you sure you want to delete', + confirmdelete: 'Are you sure you want to delete {0}?', confirmdeleteNumberOfItems: 'Are you sure you want to delete %0% of %1% items', confirmdisable: 'Are you sure you want to disable', confirmremove: 'Are you sure you want to remove', From 451810dc731192511167d51a3bc49a1a60b79215 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 Jan 2025 22:44:32 +0100 Subject: [PATCH 09/17] add danish translation --- src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts index e168fc2269..0270caafae 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts @@ -478,7 +478,7 @@ export default { anchorLinkPicker: 'Lokalt link / querystreng', anchorInsert: 'Navn på lokalt link', closeThisWindow: 'Luk denne dialog', - confirmdelete: 'Er du sikker på at du vil slette', + confirmdelete: 'Er du sikker på at du vil slette {0}?', confirmdisable: 'Er du sikker på du vil deaktivere', confirmremove: 'Er du sikker på at du vil fjerne', confirmremoveusageof: 'Er du sikker på du vil fjerne brugen af %0%', @@ -2249,6 +2249,8 @@ export default { labelForRemoveAllEntries: 'Fjern alle elementer', labelForClearClipboard: 'Ryd udklipsholder', labelForCopyToClipboard: 'Kopier til udklipsholder', + confirmDeleteHeadline: 'Slet fra udklipsholderen', + confirmDeleteDescription: 'Er du sikker på at du vil slette {0} fra udklipsholderen?', }, propertyActions: { tooltipForPropertyActionsMenu: 'Åben egenskabshandlinger', From 90c66f68c8e02f59f7a99b08d49154e9dd4d3b5e Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 Jan 2025 22:46:31 +0100 Subject: [PATCH 10/17] translate confirm label --- .../packages/core/entity-action/common/delete/delete.action.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts index faa532f64e..16de794404 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts @@ -38,7 +38,7 @@ export class UmbDeleteEntityAction extends UmbEntityActionBase>( From 9827cfd87ede5d0bc472466c1207b49f85e339d3 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 Jan 2025 23:12:17 +0100 Subject: [PATCH 11/17] Update localization.controller.ts --- .../src/libs/localization-api/localization.controller.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.ts b/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.ts index 5d14b7eb2d..0804a7029f 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.ts @@ -222,6 +222,10 @@ export class UmbLocalizationController} An array of keys. */ getKeysFromString(text: string): Array { + if (typeof text !== 'string') { + return []; + } + const regex = /#\w+/g; const keys = text.match(regex) || []; return keys.map((key) => key.slice(1)); From be7fe21099be45abdeae7bfe3e72ffe4ee0a5eb7 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 30 Jan 2025 23:15:47 +0100 Subject: [PATCH 12/17] add timeouts --- .../packages/core/sorter/sorter.controller.test.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/sorter/sorter.controller.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/sorter/sorter.controller.test.ts index 74242d6063..37cedaf4b8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/sorter/sorter.controller.test.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/sorter/sorter.controller.test.ts @@ -120,17 +120,19 @@ describe('UmbSorterController', () => { expect(items.length).to.equal(4); }); - it('sets all allowed draggable items to draggable', () => { + it('sets all allowed draggable items to draggable', async () => { const items = element.getSortableItems(); expect(items.length).to.equal(3); + await aTimeout(100); items.forEach((item) => { expect(item.draggable).to.be.true; }); }); - it('sets all disabled items non draggable', () => { + it('sets all disabled items non draggable', async () => { const items = element.getDisabledItems(); expect(items.length).to.equal(1); + await aTimeout(100); items.forEach((item) => { expect(item.draggable).to.be.false; }); @@ -138,9 +140,10 @@ describe('UmbSorterController', () => { }); describe('disable', () => { - it('sets all items to non draggable', () => { + it('sets all items to non draggable', async () => { element.sorter.disable(); const items = element.getAllItems(); + await aTimeout(100); items.forEach((item) => { expect(item.draggable).to.be.false; }); @@ -161,9 +164,10 @@ describe('UmbSorterController', () => { }); }); - it('sets all disabled items non draggable', () => { + it('sets all disabled items non draggable', async () => { const items = element.getDisabledItems(); expect(items.length).to.equal(1); + await aTimeout(100); items.forEach((item) => { expect(item.draggable).to.be.false; }); From 42dbfbe5c6a8e52df21786f7e79ce3d37467fbfc Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 31 Jan 2025 09:44:31 +0100 Subject: [PATCH 13/17] rename to message --- .../src/packages/clipboard/clipboard-entry/detail/manifests.ts | 2 +- .../packages/core/entity-action/common/delete/delete.action.ts | 2 +- .../src/packages/core/entity-action/common/delete/types.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/clipboard/clipboard-entry/detail/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/clipboard/clipboard-entry/detail/manifests.ts index 5005ec5f48..753a8c58de 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/clipboard/clipboard-entry/detail/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/clipboard/clipboard-entry/detail/manifests.ts @@ -26,7 +26,7 @@ export const manifests: Array = [ detailRepositoryAlias: UMB_CLIPBOARD_ENTRY_DETAIL_REPOSITORY_ALIAS, confirm: { headline: '#clipboard_confirmDeleteHeadline', - content: '#clipboard_confirmDeleteDescription', + message: '#clipboard_confirmDeleteDescription', }, }, }, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts index 16de794404..a06468f874 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts @@ -26,7 +26,7 @@ export class UmbDeleteEntityAction extends UmbEntityActionBase { acc[key] = [item.name]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/types.ts index 6d51bbecf5..840544de6f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/types.ts @@ -10,7 +10,7 @@ export interface MetaEntityActionDeleteKind extends MetaEntityActionDefaultKind itemRepositoryAlias: string; confirm?: { headline?: string; - content?: string; + message?: string; }; } From 0c6bef0e175f929148b7f86c07c0f47039831f01 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 31 Jan 2025 09:54:58 +0100 Subject: [PATCH 14/17] add comment --- .../entity-action/common/delete/delete.action.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts index a06468f874..4344e940c8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts @@ -26,9 +26,16 @@ export class UmbDeleteEntityAction extends UmbEntityActionBase { + const message = this.args.meta.confirm?.message ?? '#defaultdialogs_confirmdelete'; + + /* We need to replace the token in a translation with the item name. + A string can potentially consist of multiple translation keys. + First we find all the translation keys in message. */ + const keysFromMessageString = this.#localize.getKeysFromString(message); + + // Second we create a map of the translation keys found in the message and the arguments that should replace the tokens. + // This will enable the localize service to pass and replace the tokens in the all the translations with the item name. + const argsMap: UmbLocalizeStringArgsMap = keysFromMessageString.reduce((acc: UmbLocalizeStringArgsMap, key) => { acc[key] = [item.name]; return acc; }, {}); @@ -36,7 +43,7 @@ export class UmbDeleteEntityAction extends UmbEntityActionBase Date: Fri, 31 Jan 2025 10:14:22 +0100 Subject: [PATCH 15/17] simplify args --- .../localization.controller.test.ts | 26 ++----------------- .../localization.controller.ts | 20 ++------------ .../common/delete/delete.action.ts | 16 +----------- 3 files changed, 5 insertions(+), 57 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.test.ts b/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.test.ts index b5eadaf6cf..18ef72ea3e 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.test.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.test.ts @@ -312,31 +312,9 @@ describe('UmbLocalizeController', () => { expect(controller.string(str)).to.equal('close'); }); - it('should replace tokens in each key with the provided values', async () => { + it('should replace tokens in each key with the provided args', async () => { const str = '#withInlineToken #withInlineTokenLegacy'; - expect( - controller.string(str, { withInlineToken: ['value1', 'value2'], withInlineTokenLegacy: ['value3', 'value4'] }), - ).to.equal('value1 value2 value3 value4'); - }); - }); - - describe('getKeysFromString', () => { - it('should return an empty array if the input is not a string', async () => { - // @ts-expect-error - expect(controller.getKeysFromString(123)).to.deep.equal([]); - // @ts-expect-error - expect(controller.getKeysFromString({})).to.deep.equal([]); - // @ts-expect-error - expect(controller.getKeysFromString(undefined)).to.deep.equal([]); - }); - - it('should return an empty array if the input is an empty string', async () => { - expect(controller.getKeysFromString('')).to.deep.equal([]); - }); - - it('should return an array of keys', async () => { - const str = '#close #logout'; - expect(controller.getKeysFromString(str)).to.deep.equal(['close', 'logout']); + expect(controller.string(str, 'value1', 'value2')).to.equal('value1 value2 value1 value2'); }); }); diff --git a/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.ts b/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.ts index 0804a7029f..d37b958fa5 100644 --- a/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/libs/localization-api/localization.controller.ts @@ -191,10 +191,10 @@ export class UmbLocalizationController>} argsMap An object where the keys are the terms to translate and the values are arrays of arguments to pass to the term function. + * @param {...any} args The arguments to parse for this localization entry. * @returns {string} The translated text. */ - string(text: unknown, argsMap?: Record>): string { + string(text: unknown, ...args: any): string { if (typeof text !== 'string') { return ''; } @@ -204,7 +204,6 @@ export class UmbLocalizationController { const key = match.slice(1); - const args = argsMap?.[key] || []; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore @@ -215,19 +214,4 @@ export class UmbLocalizationController} An array of keys. - */ - getKeysFromString(text: string): Array { - if (typeof text !== 'string') { - return []; - } - - const regex = /#\w+/g; - const keys = text.match(regex) || []; - return keys.map((key) => key.slice(1)); - } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts index 4344e940c8..05d78fbbc2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts @@ -7,8 +7,6 @@ import type { UmbDetailRepository, UmbItemRepository } from '@umbraco-cms/backof import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api'; -type UmbLocalizeStringArgsMap = Record>; - export class UmbDeleteEntityAction extends UmbEntityActionBase { // TODO: make base type for item and detail models #localize = new UmbLocalizationController(this); @@ -28,22 +26,10 @@ export class UmbDeleteEntityAction extends UmbEntityActionBase { - acc[key] = [item.name]; - return acc; - }, {}); - // TODO: handle items with variants await umbConfirmModal(this._host, { headline: this.#localize.string(headline), - content: this.#localize.string(message, argsMap), + content: this.#localize.string(message, item.name), color: 'danger', confirmLabel: '#general_delete', }); From 415b1a2b43033020dc8d7130eb726f69d86170cc Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 31 Jan 2025 10:16:18 +0100 Subject: [PATCH 16/17] no need to localize headline here --- .../packages/core/entity-action/common/delete/delete.action.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts index 05d78fbbc2..0fadb1aa78 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.ts @@ -28,7 +28,7 @@ export class UmbDeleteEntityAction extends UmbEntityActionBase Date: Fri, 31 Jan 2025 10:47:18 +0100 Subject: [PATCH 17/17] format translations --- src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts | 4 ++-- src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts | 1 - src/Umbraco.Web.UI.Client/src/assets/lang/en.ts | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts index 0270caafae..b4ab6c71bc 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/da-dk.ts @@ -478,7 +478,7 @@ export default { anchorLinkPicker: 'Lokalt link / querystreng', anchorInsert: 'Navn på lokalt link', closeThisWindow: 'Luk denne dialog', - confirmdelete: 'Er du sikker på at du vil slette {0}?', + confirmdelete: (name: string) => `Er du sikker på at du vil slette${name ? ` ${name}` : ''}?`, confirmdisable: 'Er du sikker på du vil deaktivere', confirmremove: 'Er du sikker på at du vil fjerne', confirmremoveusageof: 'Er du sikker på du vil fjerne brugen af %0%', @@ -2250,7 +2250,7 @@ export default { labelForClearClipboard: 'Ryd udklipsholder', labelForCopyToClipboard: 'Kopier til udklipsholder', confirmDeleteHeadline: 'Slet fra udklipsholderen', - confirmDeleteDescription: 'Er du sikker på at du vil slette {0} fra udklipsholderen?', + confirmDeleteDescription: 'Er du sikker på at du vil slette {0} fra udklipsholderen?', }, propertyActions: { tooltipForPropertyActionsMenu: 'Åben egenskabshandlinger', diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts index 8ae9655a15..de31a6992a 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en-us.ts @@ -508,7 +508,6 @@ export default { anchorLinkPicker: 'Anchor or querystring', anchorInsert: 'Name', closeThisWindow: 'Close this window', - confirmdelete: 'Are you sure you want to delete {0}?', confirmdeleteNumberOfItems: 'Are you sure you want to delete %0% of %1% items', confirmdisable: 'Are you sure you want to disable', confirmremove: 'Are you sure you want to remove', diff --git a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts index 0e72bcfa7c..b6bdae3a3b 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts @@ -497,7 +497,7 @@ export default { anchorLinkPicker: 'Anchor or querystring', anchorInsert: 'Name', closeThisWindow: 'Close this window', - confirmdelete: 'Are you sure you want to delete {0}?', + confirmdelete: (name: string) => `Are you sure you want to delete${name ? ` ${name}` : ''}?`, confirmdeleteNumberOfItems: 'Are you sure you want to delete %0% of %1% items', confirmdisable: 'Are you sure you want to disable', confirmremove: 'Are you sure you want to remove', @@ -2389,7 +2389,7 @@ export default { labelForClearClipboard: 'Clear clipboard', labelForCopyToClipboard: 'Copy to clipboard', confirmDeleteHeadline: 'Delete from clipboard', - confirmDeleteDescription: 'Are you sure you want to delete {0} from the clipboard?', + confirmDeleteDescription: 'Are you sure you want to delete {0} from the clipboard?', }, propertyActions: { tooltipForPropertyActionsMenu: 'Open Property Actions',