Merge pull request #18183 from umbraco/15.2/hotfix/clipboard-delete-confirm-dialog

Hotfix: Clipboard confirm delete labels
This commit is contained in:
Niels Lyngsø
2025-01-31 11:21:04 +01:00
committed by GitHub
10 changed files with 50 additions and 15 deletions

View File

@@ -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: (name: string) => `Er du sikker på at du vil slette${name ? ` <strong>${name}</strong>` : ''}?`,
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 <strong>%0%</strong>',
@@ -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 <strong>{0}</strong> fra udklipsholderen?',
},
propertyActions: {
tooltipForPropertyActionsMenu: 'Åben egenskabshandlinger',

View File

@@ -508,7 +508,6 @@ export default {
anchorLinkPicker: 'Anchor or querystring',
anchorInsert: 'Name',
closeThisWindow: 'Close this window',
confirmdelete: 'Are you sure you want to delete',
confirmdeleteNumberOfItems: 'Are you sure you want to delete <strong>%0%</strong> of <strong>%1%</strong> items',
confirmdisable: 'Are you sure you want to disable',
confirmremove: 'Are you sure you want to remove',

View File

@@ -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: (name: string) => `Are you sure you want to delete${name ? ` <strong>${name}</strong>` : ''}?`,
confirmdeleteNumberOfItems: 'Are you sure you want to delete <strong>%0%</strong> of <strong>%1%</strong> items',
confirmdisable: 'Are you sure you want to disable',
confirmremove: 'Are you sure you want to remove',
@@ -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 <strong>{0}</strong> from the clipboard?',
},
propertyActions: {
tooltipForPropertyActionsMenu: 'Open Property Actions',

View File

@@ -302,6 +302,20 @@ 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 args', async () => {
const str = '#withInlineToken #withInlineTokenLegacy';
expect(controller.string(str, 'value1', 'value2')).to.equal('value1 value2 value1 value2');
});
});
describe('host element', () => {

View File

@@ -191,9 +191,10 @@ export class UmbLocalizationController<LocalizationSetType extends UmbLocalizati
* If the term is found in the localization set, it will be replaced with the localized term.
* If the term is not found, the original term will be returned.
* @param {string} text The text to translate.
* @param {...any} args The arguments to parse for this localization entry.
* @returns {string} The translated text.
*/
string(text: unknown): string {
string(text: unknown, ...args: any): string {
if (typeof text !== 'string') {
return '';
}
@@ -203,10 +204,10 @@ export class UmbLocalizationController<LocalizationSetType extends UmbLocalizati
const localizedText = text.replace(regex, (match: string) => {
const key = match.slice(1);
// TODO: find solution to pass dynamic string to term
// 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;
});

View File

@@ -19,11 +19,15 @@ export const manifests: Array<UmbExtensionManifest> = [
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',
message: '#clipboard_confirmDeleteDescription',
},
},
},
];

View File

@@ -5,9 +5,11 @@ 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';
export class UmbDeleteEntityAction extends UmbEntityActionBase<MetaEntityActionDeleteKind> {
// 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,12 +23,15 @@ export class UmbDeleteEntityAction extends UmbEntityActionBase<MetaEntityActionD
const item = data?.[0];
if (!item) throw new Error('Item not found.');
const headline = this.args.meta.confirm?.headline ?? '#actions_delete';
const message = this.args.meta.confirm?.message ?? '#defaultdialogs_confirmdelete';
// TODO: handle items with variants
await umbConfirmModal(this._host, {
headline: `Delete`,
content: `Are you sure you want to delete ${item.name}?`,
headline,
content: this.#localize.string(message, item.name),
color: 'danger',
confirmLabel: 'Delete',
confirmLabel: '#general_delete',
});
const detailRepository = await createExtensionApiByAlias<UmbDetailRepository<any>>(

View File

@@ -8,6 +8,10 @@ export interface ManifestEntityActionDeleteKind extends ManifestEntityAction<Met
export interface MetaEntityActionDeleteKind extends MetaEntityActionDefaultKind {
detailRepositoryAlias: string;
itemRepositoryAlias: string;
confirm?: {
headline?: string;
message?: string;
};
}
declare global {

View File

@@ -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;
});

View File

@@ -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',