From 01516bb142b438f97b9373fb292d312d2c9ba59c Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 6 Feb 2025 10:34:17 +0100 Subject: [PATCH 001/145] add trash confirm modal --- .../entity-action/trash/manifests.ts | 4 +- .../entity-action/trash/modal/constants.ts | 1 + .../entity-action/trash/modal/manifests.ts | 8 ++ .../modal/trash-confirm-modal.element.ts | 112 ++++++++++++++++++ .../trash/modal/trash-confirm-modal.token.ts | 19 +++ .../entity-action/trash/trash.action.ts | 28 ++--- .../recycle-bin/entity-action/manifests.ts | 2 + 7 files changed, 158 insertions(+), 16 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.token.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/manifests.ts index 46ec59d132b6..5900880a6091 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/manifests.ts @@ -1,4 +1,6 @@ import { manifest as trashKindManifest } from './trash.action.kind.js'; +import { manifests as modalManifests } from './modal/manifests.js'; + import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; -export const manifests: Array = [trashKindManifest]; +export const manifests: Array = [trashKindManifest, ...modalManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/constants.ts new file mode 100644 index 000000000000..759ff7efcf8e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/constants.ts @@ -0,0 +1 @@ +export * from './trash-confirm-modal.token.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/manifests.ts new file mode 100644 index 000000000000..c96a19c65955 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/manifests.ts @@ -0,0 +1,8 @@ +export const manifests: Array = [ + { + type: 'modal', + alias: 'Umb.Modal.Trash.Confirm', + name: 'Trash Confirm Modal', + element: () => import('./trash-confirm-modal.element.js'), + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts new file mode 100644 index 000000000000..5cb9f9261610 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts @@ -0,0 +1,112 @@ +import type { UmbTrashConfirmModalData, UmbTrashConfirmModalValue } from './trash-confirm-modal.token.js'; +import { html, customElement, property, css, state } from '@umbraco-cms/backoffice/external/lit'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import type { UmbModalContext } from '@umbraco-cms/backoffice/modal'; +import { UmbLitElement, umbFocus } from '@umbraco-cms/backoffice/lit-element'; +import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; +import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; + +@customElement('umb-trash-confirm-modal') +export class UmbTrashConfirmModalElement extends UmbLitElement { + @property({ attribute: false }) + modalContext?: UmbModalContext; + + @property({ type: Object, attribute: false }) + private _data?: UmbTrashConfirmModalData | undefined; + public get data(): UmbTrashConfirmModalData | undefined { + return this._data; + } + public set data(value: UmbTrashConfirmModalData | undefined) { + this._data = value; + this.#initData(); + } + + private _handleConfirm() { + this.modalContext?.submit(); + } + + private _handleCancel() { + this.modalContext?.reject(); + } + + @state() + referencedBy: any[] = []; + + @state() + _item: any; + + #itemRepository?: UmbItemRepository; + #referenceRepository?: any; + + constructor() { + super(); + this.#initData(); + } + + async #initData() { + if (!this._data) { + this.#itemRepository?.destroy(); + this.#referenceRepository?.destroy(); + return; + } + + this.#itemRepository = await createExtensionApiByAlias>( + this, + this._data.itemRepositoryAlias, + ); + + const { data } = await this.#itemRepository.requestItems([this._data.unique]); + const item = data?.[0]; + if (!item) throw new Error('Item not found.'); + + this._item = item.name; + + this.#referenceRepository = await createExtensionApiByAlias(this, this._data.referenceRepositoryAlias); + + const { data: referencesData } = await this.#referenceRepository.requestReferencedBy(this._data.unique); + + if (referencesData) { + this.referencedBy = [...referencesData.items]; + } + } + + override render() { + return html` + +

Are you sure you want to move ${this._item} to the recycle bin?

+ + + ${this.referencedBy.map((reference) => html` `)} + + + + + +
+ `; + } + + static override styles = [ + UmbTextStyles, + css` + uui-dialog-layout { + max-inline-size: 60ch; + } + `, + ]; +} + +export { UmbTrashConfirmModalElement as element }; + +declare global { + interface HTMLElementTagNameMap { + 'umb-trash-confirm-modal': UmbTrashConfirmModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.token.ts new file mode 100644 index 000000000000..ac6b816437c5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.token.ts @@ -0,0 +1,19 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbTrashConfirmModalData { + unique: string; + entityType: string; + itemRepositoryAlias: string; + referenceRepositoryAlias: string; +} + +export type UmbTrashConfirmModalValue = undefined; + +export const UMB_TRASH_CONFIRM_MODAL = new UmbModalToken( + 'Umb.Modal.Trash.Confirm', + { + modal: { + type: 'dialog', + }, + }, +); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts index 6896d26586cc..62770d8151f9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts @@ -3,8 +3,9 @@ import { UmbRequestReloadStructureForEntityEvent } from '../../../entity-action/ import type { UmbRecycleBinRepository } from '../../recycle-bin-repository.interface.js'; import type { MetaEntityActionTrashKind } from './types.js'; import { UmbEntityTrashedEvent } from './trash.event.js'; +import { UMB_TRASH_CONFIRM_MODAL } from './modal/constants.js'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; -import { umbConfirmModal } from '@umbraco-cms/backoffice/modal'; +import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; @@ -21,27 +22,24 @@ export class UmbTrashEntityAction extends UmbEntityActionBase>( - this, - this.args.meta.itemRepositoryAlias, - ); - - const { data } = await itemRepository.requestItems([this.args.unique]); - const item = data?.[0]; - if (!item) throw new Error('Item not found.'); + const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); - // TODO: handle items with variants - await umbConfirmModal(this._host, { - headline: `Trash`, - content: `Are you sure you want to move ${item.name} to the recycle bin?`, - color: 'danger', - confirmLabel: 'Trash', + const modal = modalManager.open(this, UMB_TRASH_CONFIRM_MODAL, { + data: { + unique: this.args.unique, + entityType: this.args.entityType, + itemRepositoryAlias: this.args.meta.itemRepositoryAlias, + referenceRepositoryAlias: this.args.meta.referenceRepositoryAlias, + }, }); + await modal.onSubmit(); + const recycleBinRepository = await createExtensionApiByAlias( this, this.args.meta.recycleBinRepositoryAlias, ); + await recycleBinRepository.requestTrash({ unique: this.args.unique }); this.#notify(); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/manifests.ts index f4d9b410dee9..270014cf66c5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/manifests.ts @@ -6,6 +6,7 @@ import { UMB_USER_PERMISSION_DOCUMENT_MOVE, } from '../../constants.js'; import { UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS } from '../../repository/constants.js'; +import { UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS } from '../../reference/constants.js'; import { UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS, UMB_ENTITY_IS_TRASHED_CONDITION_ALIAS, @@ -21,6 +22,7 @@ export const manifests: Array = [ meta: { itemRepositoryAlias: UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS, recycleBinRepositoryAlias: UMB_DOCUMENT_RECYCLE_BIN_REPOSITORY_ALIAS, + referenceRepositoryAlias: UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS, }, conditions: [ { From 9ccb58acca19d7950a3a19873db9c8a13dba988c Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 6 Feb 2025 12:51:29 +0100 Subject: [PATCH 002/145] make referenceRepo optional + adjust styling --- .../components/ref-item/ref-item.element.ts | 12 +++-- .../modal/trash-confirm-modal.element.ts | 48 +++++++++++++++---- .../trash/modal/trash-confirm-modal.token.ts | 2 +- .../entity-action/trash/trash.action.ts | 1 - .../recycle-bin/entity-action/trash/types.ts | 1 + 5 files changed, 48 insertions(+), 16 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/ref-item/ref-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/ref-item/ref-item.element.ts index 1bda4e17bce8..9db1a3a2cc93 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/ref-item/ref-item.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/ref-item/ref-item.element.ts @@ -5,17 +5,19 @@ import { UUIRefNodeElement } from '@umbraco-cms/backoffice/external/uui'; @customElement('umb-ref-item') export class UmbRefItemElement extends UmbElementMixin(UUIRefNodeElement) { @property({ type: String }) - icon = ''; + icon? = ''; #iconElement = document.createElement('umb-icon'); protected override firstUpdated(_changedProperties: PropertyValues): void { super.firstUpdated(_changedProperties); - // Temporary fix for the icon appending, this could in the future be changed to override a renderIcon method, or other ways to make this happen without appending children. - this.#iconElement.setAttribute('slot', 'icon'); - this.#iconElement.setAttribute('name', this.icon); - this.appendChild(this.#iconElement); + if (this.icon) { + // Temporary fix for the icon appending, this could in the future be changed to override a renderIcon method, or other ways to make this happen without appending children. + this.#iconElement.setAttribute('slot', 'icon'); + this.#iconElement.setAttribute('name', this.icon); + this.appendChild(this.#iconElement); + } } static override styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts index 5cb9f9261610..943465a01f81 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts @@ -1,5 +1,5 @@ import type { UmbTrashConfirmModalData, UmbTrashConfirmModalValue } from './trash-confirm-modal.token.js'; -import { html, customElement, property, css, state } from '@umbraco-cms/backoffice/external/lit'; +import { html, customElement, property, css, state, nothing } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import type { UmbModalContext } from '@umbraco-cms/backoffice/modal'; import { UmbLitElement, umbFocus } from '@umbraco-cms/backoffice/lit-element'; @@ -30,10 +30,13 @@ export class UmbTrashConfirmModalElement extends UmbLitElement { } @state() - referencedBy: any[] = []; + _item: any; @state() - _item: any; + _referencedBy: any[] = []; + + @state() + _totalReferencedBy: number = 0; #itemRepository?: UmbItemRepository; #referenceRepository?: any; @@ -61,12 +64,20 @@ export class UmbTrashConfirmModalElement extends UmbLitElement { this._item = item.name; + this.#loadReferencedBy(); + } + + async #loadReferencedBy() { + // Skip if there is no reference repository + if (!this._data?.referenceRepositoryAlias) return; + this.#referenceRepository = await createExtensionApiByAlias(this, this._data.referenceRepositoryAlias); - const { data: referencesData } = await this.#referenceRepository.requestReferencedBy(this._data.unique); + const { data: referencesData } = await this.#referenceRepository.requestReferencedBy(this._data.unique, 0, 5); if (referencesData) { - this.referencedBy = [...referencesData.items]; + this._referencedBy = [...referencesData.items]; + this._totalReferencedBy = referencesData.total; } } @@ -74,10 +85,7 @@ export class UmbTrashConfirmModalElement extends UmbLitElement { return html`

Are you sure you want to move ${this._item} to the recycle bin?

- - - ${this.referencedBy.map((reference) => html` `)} - + ${this.#renderReferencedBy()} @@ -93,12 +101,34 @@ export class UmbTrashConfirmModalElement extends UmbLitElement { `; } + #renderReferencedBy() { + if (this._totalReferencedBy === 0) return nothing; + + return html` +
${this.localize.term('references_labelDependsOnThis')}
+ + ${this._referencedBy.map((reference) => html` `)} + + ${this._totalReferencedBy > 5 + ? html`${this.localize.term('references_labelMoreReferences', this._totalReferencedBy - 5)}` + : nothing} + `; + } + static override styles = [ UmbTextStyles, css` uui-dialog-layout { max-inline-size: 60ch; } + + #reference-headline { + margin-bottom: var(--uui-size-3); + } + + uui-ref-list { + margin-bottom: var(--uui-size-2); + } `, ]; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.token.ts index ac6b816437c5..1c1ae7bc5d05 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.token.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.token.ts @@ -4,7 +4,7 @@ export interface UmbTrashConfirmModalData { unique: string; entityType: string; itemRepositoryAlias: string; - referenceRepositoryAlias: string; + referenceRepositoryAlias?: string; } export type UmbTrashConfirmModalValue = undefined; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts index 62770d8151f9..91429cae2f38 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts @@ -6,7 +6,6 @@ import { UmbEntityTrashedEvent } from './trash.event.js'; import { UMB_TRASH_CONFIRM_MODAL } from './modal/constants.js'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; -import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; /** diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/types.ts index d587158fec6c..d535badb23bc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/types.ts @@ -8,6 +8,7 @@ export interface ManifestEntityActionTrashKind extends ManifestEntityAction Date: Thu, 6 Feb 2025 12:54:46 +0100 Subject: [PATCH 003/145] add referenceRepository to media trash action --- .../packages/media/media/recycle-bin/entity-action/manifests.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/manifests.ts index b78ea50e0fb7..549cd5617731 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/manifests.ts @@ -4,6 +4,7 @@ import { UMB_MEDIA_ENTITY_TYPE, } from '../../constants.js'; import { UMB_MEDIA_RECYCLE_BIN_ROOT_ENTITY_TYPE, UMB_MEDIA_RECYCLE_BIN_REPOSITORY_ALIAS } from '../constants.js'; +import { UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS } from '../../reference/constants.js'; import { UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS, UMB_ENTITY_IS_TRASHED_CONDITION_ALIAS, @@ -19,6 +20,7 @@ export const manifests: Array = [ meta: { itemRepositoryAlias: UMB_MEDIA_ITEM_REPOSITORY_ALIAS, recycleBinRepositoryAlias: UMB_MEDIA_RECYCLE_BIN_REPOSITORY_ALIAS, + referenceRepositoryAlias: UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS, }, conditions: [ { From edb6a7c40f40fa5bb933982a330823651171c201 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 6 Feb 2025 22:10:47 +0100 Subject: [PATCH 004/145] wip entity-item-ref extension point --- .../entity-item-ref.element.ts | 72 ++++++++++++ .../entity-item-ref.extension.ts | 18 +++ .../core/entity/entity-item-ref/index.ts | 3 + .../core/entity/entity-item-ref/types.ts | 1 + .../src/packages/core/entity/index.ts | 1 + .../src/packages/core/picker-input/index.ts | 1 + .../picker-input.context-token.ts | 4 + .../core/picker-input/picker-input.context.ts | 7 +- .../input-document/input-document.element.ts | 78 ++----------- .../item/document-item-ref.element.ts | 104 ++++++++++++++++++ .../documents/documents/item/manifests.ts | 11 ++ .../packages/documents/documents/manifests.ts | 2 + 12 files changed, 231 insertions(+), 71 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.extension.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/types.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context-token.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/manifests.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts new file mode 100644 index 000000000000..a263af033bef --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts @@ -0,0 +1,72 @@ +import type { UmbEntityModel } from '../types.js'; +import type { ManifestEntityItemRef } from './entity-item-ref.extension.js'; +import { customElement, property, type PropertyValueMap, state, css, html } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbExtensionsElementInitializer } from '@umbraco-cms/backoffice/extension-api'; +import { UMB_MARK_ATTRIBUTE_NAME } from '@umbraco-cms/backoffice/const'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; + +@customElement('umb-entity-item-ref') +export class UmbEntityItemRefElement extends UmbLitElement { + #extensionsController?: UmbExtensionsElementInitializer; + #item?: UmbEntityModel; + + @state() + _component?: HTMLElement; + + @property({ type: Object, attribute: false }) + public get item(): UmbEntityModel | undefined { + return this.#item; + } + public set item(value: UmbEntityModel | undefined) { + if (value === this.#item || !value) return; + this.#item = value; + this.#createController(value.entityType); + } + + protected override firstUpdated(_changedProperties: PropertyValueMap | Map): void { + super.firstUpdated(_changedProperties); + this.setAttribute(UMB_MARK_ATTRIBUTE_NAME, 'entity-item-ref'); + } + + #createController(entityType: string) { + if (this.#extensionsController) { + this.#extensionsController.destroy(); + } + + this.#extensionsController = new UmbExtensionsElementInitializer( + this, + umbExtensionsRegistry, + 'entityItemRef', + (manifest: ManifestEntityItemRef) => manifest.forEntityTypes.includes(entityType), + (extensionControllers) => { + const component = extensionControllers[0]?.component; + component.item = this.#item; + this._component = component; + }, + undefined, // We can leave the alias to undefined, as we destroy this our selfs. + undefined, + { single: true }, + ); + } + + override render() { + return html`${this._component}`; + } + + static override styles = [ + css` + :host { + display: contents; + } + `, + ]; +} + +export { UmbEntityItemRefElement as element }; + +declare global { + interface HTMLElementTagNameMap { + 'umb-entity-item-ref': UmbEntityItemRefElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.extension.ts new file mode 100644 index 000000000000..9b4d9d43daea --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.extension.ts @@ -0,0 +1,18 @@ +import type { ManifestElement, ManifestWithDynamicConditions } from '@umbraco-cms/backoffice/extension-api'; + +export interface ManifestEntityItemRef + extends ManifestElement, + ManifestWithDynamicConditions { + type: 'entityItemRef'; + meta: MetaType; + forEntityTypes: Array; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +export interface MetaEntityItemRef {} + +declare global { + interface UmbExtensionManifestMap { + umbManifestEntityItemRef: ManifestEntityItemRef; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/index.ts new file mode 100644 index 000000000000..338849e06997 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/index.ts @@ -0,0 +1,3 @@ +import './entity-item-ref.element.js'; + +export * from './entity-item-ref.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/types.ts new file mode 100644 index 000000000000..06c33f562f4e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/types.ts @@ -0,0 +1 @@ +export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/index.ts index 737d7bf4828c..7fbfc9d7f634 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/index.ts @@ -1,3 +1,4 @@ export { UMB_ENTITY_CONTEXT } from './entity.context-token.js'; export { UmbEntityContext } from './entity.context.js'; +export * from './entity-item-ref/index.js'; export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/index.ts index 5aee89bb955f..66eb8d0b6067 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/index.ts @@ -1 +1,2 @@ export * from './picker-input.context.js'; +export * from './picker-input.context-token.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context-token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context-token.ts new file mode 100644 index 000000000000..e208597b4770 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context-token.ts @@ -0,0 +1,4 @@ +import type { UmbPickerInputContext } from './picker-input.context.js'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; + +export const UMB_PICKER_INPUT_CONTEXT = new UmbContextToken('UmbPickerInputContext'); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context.ts index 1a597bf8af68..385671b75d89 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context.ts @@ -1,11 +1,12 @@ import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; -import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; import { UmbRepositoryItemsManager } from '@umbraco-cms/backoffice/repository'; import { UMB_MODAL_MANAGER_CONTEXT, umbConfirmModal } from '@umbraco-cms/backoffice/modal'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; import type { UmbModalToken, UmbPickerModalData, UmbPickerModalValue } from '@umbraco-cms/backoffice/modal'; import { UmbDeprecation } from '@umbraco-cms/backoffice/utils'; +import { UMB_PICKER_INPUT_CONTEXT } from './picker-input.context-token'; type PickerItemBaseType = { name: string; unique: string }; export class UmbPickerInputContext< @@ -13,7 +14,7 @@ export class UmbPickerInputContext< PickerItemType extends PickerItemBaseType = PickedItemType, PickerModalConfigType extends UmbPickerModalData = UmbPickerModalData, PickerModalValueType extends UmbPickerModalValue = UmbPickerModalValue, -> extends UmbControllerBase { +> extends UmbContextBase { modalAlias: string | UmbModalToken, PickerModalValueType>; repository?: UmbItemRepository; #getUnique: (entry: PickedItemType) => string | undefined; @@ -59,7 +60,7 @@ export class UmbPickerInputContext< modalAlias: string | UmbModalToken, PickerModalValueType>, getUniqueMethod?: (entry: PickedItemType) => string | undefined, ) { - super(host); + super(host, UMB_PICKER_INPUT_CONTEXT); this.modalAlias = modalAlias; this.#getUnique = getUniqueMethod || ((entry) => entry.unique); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts index c16b2c675968..70998fe293d8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts @@ -136,9 +136,6 @@ export class UmbInputDocumentElement extends UmbFormControlMixin; @@ -147,15 +144,6 @@ export class UmbInputDocumentElement extends UmbFormControlMixin { - return { data: { entityType: 'document', preset: {} } }; - }) - .observeRouteBuilder((routeBuilder) => { - this._editDocumentPath = routeBuilder({}); - }); - this.addValidator( 'rangeUnderflow', () => this.minMessage, @@ -172,10 +160,6 @@ export class UmbInputDocumentElement extends UmbFormControlMixin (this._items = selectedItems), '_observerItems'); } - #isDraft(item: UmbDocumentItemModel) { - return item.variants[0]?.state === 'Draft'; - } - #openPicker() { this.#pickerContext.openPicker( { @@ -191,10 +175,6 @@ export class UmbInputDocumentElement extends UmbFormControlMixin - ${repeat( - this._items, - (item) => item.unique, - (item) => this.#renderItem(item), - )} - + ${repeat( + this._items, + (item) => item.unique, + (item) => + html``, + )} `; } - #renderItem(item: UmbDocumentItemModel) { - if (!item.unique) return; - const href = !this.readonly && this.showOpenButton ? `${this._editDocumentPath}edit/${item.unique}` : undefined; - return html` - - ${this.#renderIcon(item)} ${this.#renderIsTrashed(item)} - ${when( - !this.readonly, - () => html` - - this.#onRemove(item)}> - - `, - )} - - `; - } - - #renderIcon(item: UmbDocumentItemModel) { - if (!item.documentType.icon) return; - return html``; - } - - #renderIsTrashed(item: UmbDocumentItemModel) { - if (!item.isTrashed) return; - return html`Trashed`; - } - static override styles = [ css` #btn-add { display: block; } - uui-ref-node[drag-placeholder] { + umb-entity-item-ref[drag-placeholder] { opacity: 0.2; } - - .draft { - opacity: 0.6; - } `, ]; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts new file mode 100644 index 000000000000..87f8cc770419 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -0,0 +1,104 @@ +import type { UmbDocumentItemModel } from '../repository/types.js'; +import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; +import { + classMap, + customElement, + html, + ifDefined, + nothing, + property, + when, +} from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; +import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; +import { UMB_PICKER_INPUT_CONTEXT } from '@umbraco-cms/backoffice/picker-input'; + +@customElement('umb-document-item-ref') +export class UmbDocumentItemRefElement extends UmbLitElement { + @property({ type: Object }) + item?: UmbDocumentItemModel; + + @property({ type: Boolean }) + readonly = false; + + @property({ type: Boolean }) + standalone = false; + + _editDocumentPath = ''; + + #pickerInputContext?: typeof UMB_PICKER_INPUT_CONTEXT.TYPE; + + constructor() { + super(); + + this.consumeContext(UMB_PICKER_INPUT_CONTEXT, (context) => { + this.#pickerInputContext = context; + }); + + new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath(UMB_DOCUMENT_ENTITY_TYPE) + .onSetup(() => { + return { data: { entityType: UMB_DOCUMENT_ENTITY_TYPE, preset: {} } }; + }) + .observeRouteBuilder((routeBuilder) => { + this._editDocumentPath = routeBuilder({}); + }); + } + + #isDraft(item: UmbDocumentItemModel) { + return item.variants[0]?.state === 'Draft'; + } + + #getHref(item: UmbDocumentItemModel) { + return `${this._editDocumentPath}/edit/${item.unique}`; + } + + #onRemove(item: UmbDocumentItemModel) { + this.#pickerInputContext?.requestRemoveItem(item.unique); + } + + override render() { + if (!this.item) return nothing; + + return html` + + ${this.#renderIcon(this.item)} ${this.#renderIsTrashed(this.item)} + ${when( + !this.readonly, + () => html` + + this.#onRemove(this.item)}> + + `, + )} + + `; + } + + #renderIcon(item: UmbDocumentItemModel) { + if (!item.documentType.icon) return; + return html``; + } + + #renderIsTrashed(item: UmbDocumentItemModel) { + if (!item.isTrashed) return; + return html`Trashed`; + } +} + +export { UmbDocumentItemRefElement as element }; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-item-ref': UmbDocumentItemRefElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/manifests.ts new file mode 100644 index 000000000000..522b66ae3fd6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/manifests.ts @@ -0,0 +1,11 @@ +import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; + +export const manifests: Array = [ + { + type: 'entityItemRef', + alias: 'Umb.EntityItemRef.Document', + name: 'Document Entity Item Reference', + element: () => import('./document-item-ref.element.js'), + forEntityTypes: [UMB_DOCUMENT_ENTITY_TYPE], + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/manifests.ts index e744094a3c84..c7910bc1b5c3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/manifests.ts @@ -3,6 +3,7 @@ import { manifests as collectionManifests } from './collection/manifests.js'; import { manifests as entityActionManifests } from './entity-actions/manifests.js'; import { manifests as entityBulkActionManifests } from './entity-bulk-actions/manifests.js'; import { manifests as globalContextManifests } from './global-contexts/manifests.js'; +import { manifests as itemManifests } from './item/manifests.js'; import { manifests as menuManifests } from './menu/manifests.js'; import { manifests as modalManifests } from './modals/manifests.js'; import { manifests as pickerManifests } from './picker/manifests.js'; @@ -26,6 +27,7 @@ export const manifests: Array = ...entityActionManifests, ...entityBulkActionManifests, ...globalContextManifests, + ...itemManifests, ...menuManifests, ...modalManifests, ...pickerManifests, From 62f1bd7d43fe7ef79d749921e6ff4f0523804eb2 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 6 Feb 2025 22:23:47 +0100 Subject: [PATCH 005/145] clean up --- .../input-document/input-document.element.ts | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts index 70998fe293d8..ae38bcf92440 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts @@ -1,30 +1,15 @@ import { UmbDocumentPickerInputContext } from './input-document.context.js'; -import { - classMap, - css, - customElement, - html, - ifDefined, - nothing, - property, - repeat, - state, - when, -} from '@umbraco-cms/backoffice/external/lit'; +import { css, customElement, html, nothing, property, repeat, state } from '@umbraco-cms/backoffice/external/lit'; import { splitStringToArray } from '@umbraco-cms/backoffice/utils'; import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbSorterController } from '@umbraco-cms/backoffice/sorter'; -import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; -import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import type { UmbDocumentItemModel } from '@umbraco-cms/backoffice/document'; import type { UmbTreeStartNode } from '@umbraco-cms/backoffice/tree'; import { UMB_DOCUMENT_TYPE_ENTITY_TYPE } from '@umbraco-cms/backoffice/document-type'; -const elementName = 'umb-input-document'; - -@customElement(elementName) +@customElement('umb-input-document') export class UmbInputDocumentElement extends UmbFormControlMixin( UmbLitElement, ) { @@ -227,6 +212,6 @@ export { UmbInputDocumentElement as element }; declare global { interface HTMLElementTagNameMap { - [elementName]: UmbInputDocumentElement; + 'umb-input-document': UmbInputDocumentElement; } } From fd06887aa19dd6318ba7d886c2c47bf57a57ef01 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 6 Feb 2025 22:27:54 +0100 Subject: [PATCH 006/145] add ref list element --- .../input-document/input-document.element.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts index ae38bcf92440..e7fd4be8eb54 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts @@ -183,15 +183,18 @@ export class UmbInputDocumentElement extends UmbFormControlMixin item.unique, - (item) => - html` + ${repeat( + this._items, + (item) => item.unique, + (item) => + html``, - )} + ?standalone=${this.max === 1}> + `, + )} + `; } From 977b047d8e41e80795258d0286d5eed6d5605943 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 6 Feb 2025 22:27:59 +0100 Subject: [PATCH 007/145] fix styling --- .../core/entity/entity-item-ref/entity-item-ref.element.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts index a263af033bef..66eda864473d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts @@ -57,7 +57,8 @@ export class UmbEntityItemRefElement extends UmbLitElement { static override styles = [ css` :host { - display: contents; + display: block; + position: relative; } `, ]; From 0731f66f668651fbd3a972d515e5da8a53ad8eb1 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 6 Feb 2025 22:36:08 +0100 Subject: [PATCH 008/145] Update document-item-ref.element.ts --- .../item/document-item-ref.element.ts | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index 87f8cc770419..be5b948ae6a2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -7,6 +7,7 @@ import { ifDefined, nothing, property, + state, when, } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @@ -25,6 +26,9 @@ export class UmbDocumentItemRefElement extends UmbLitElement { @property({ type: Boolean }) standalone = false; + @state() + _isPickerInput = false; + _editDocumentPath = ''; #pickerInputContext?: typeof UMB_PICKER_INPUT_CONTEXT.TYPE; @@ -34,6 +38,7 @@ export class UmbDocumentItemRefElement extends UmbLitElement { this.consumeContext(UMB_PICKER_INPUT_CONTEXT, (context) => { this.#pickerInputContext = context; + this._isPickerInput = context !== undefined; }); new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) @@ -54,8 +59,9 @@ export class UmbDocumentItemRefElement extends UmbLitElement { return `${this._editDocumentPath}/edit/${item.unique}`; } - #onRemove(item: UmbDocumentItemModel) { - this.#pickerInputContext?.requestRemoveItem(item.unique); + #onRemove() { + if (!this.item) return; + this.#pickerInputContext?.requestRemoveItem(this.item.unique); } override render() { @@ -69,21 +75,23 @@ export class UmbDocumentItemRefElement extends UmbLitElement { href=${ifDefined(this.#getHref(this.item))} ?readonly=${this.readonly} ?standalone=${this.standalone}> - ${this.#renderIcon(this.item)} ${this.#renderIsTrashed(this.item)} - ${when( - !this.readonly, - () => html` - - this.#onRemove(this.item)}> - - `, - )} + ${this.#renderIcon(this.item)} ${this.#renderIsTrashed(this.item)} ${this.#renderActions()} `; } + #renderActions() { + if (this.readonly) return; + if (!this.item) return; + if (!this._isPickerInput) return; + + return html` + + + + `; + } + #renderIcon(item: UmbDocumentItemModel) { if (!item.documentType.icon) return; return html``; From 5901d4a156701b423cfd804fc41c6e9e254659f6 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 6 Feb 2025 23:03:38 +0100 Subject: [PATCH 009/145] move item repo --- .../components/input-document/input-document.context.ts | 9 +++------ .../src/packages/documents/documents/constants.ts | 1 + .../documents/entity-actions/create/create.action.ts | 2 +- .../create/document-create-options-modal.element.ts | 2 +- .../documents/documents/entity-actions/manifests.ts | 3 ++- .../modal/document-notifications-modal.element.ts | 2 +- .../public-access/modal/public-access-modal.element.ts | 2 +- .../entity-actions/sort-children-of/manifests.ts | 2 +- .../src/packages/documents/documents/index.ts | 3 ++- .../src/packages/documents/documents/item/constants.ts | 1 + .../documents/item/document-item-ref.element.ts | 3 +-- .../src/packages/documents/documents/item/index.ts | 1 + .../src/packages/documents/documents/item/manifests.ts | 2 ++ .../{repository/item => item/repository}/constants.ts | 0 .../item => item/repository}/document-item.repository.ts | 0 .../repository}/document-item.server.data-source.ts | 0 .../repository}/document-item.store.context-token.ts | 0 .../item => item/repository}/document-item.store.ts | 0 .../{repository/item => item/repository}/index.ts | 0 .../{repository/item => item/repository}/manifests.ts | 0 .../{repository/item => item/repository}/types.ts | 0 .../src/packages/documents/documents/item/types.ts | 1 + .../documents/recycle-bin/entity-action/manifests.ts | 2 +- .../packages/documents/documents/repository/constants.ts | 1 - .../src/packages/documents/documents/repository/index.ts | 2 -- .../packages/documents/documents/repository/manifests.ts | 3 +-- .../src/packages/documents/documents/repository/types.ts | 1 - .../search/document-search-result-item.element.ts | 2 +- .../src/packages/documents/documents/search/types.ts | 2 +- .../src/packages/documents/documents/types.ts | 8 ++++---- .../input-document-granular-user-permission.element.ts | 3 ++- 31 files changed, 29 insertions(+), 29 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/index.ts rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/{repository/item => item/repository}/constants.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/{repository/item => item/repository}/document-item.repository.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/{repository/item => item/repository}/document-item.server.data-source.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/{repository/item => item/repository}/document-item.store.context-token.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/{repository/item => item/repository}/document-item.store.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/{repository/item => item/repository}/index.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/{repository/item => item/repository}/manifests.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/{repository/item => item/repository}/types.ts (100%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/types.ts delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.context.ts index 75b2b2c42a90..6d9f07bc551a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.context.ts @@ -1,10 +1,7 @@ import type { UmbDocumentPickerModalData, UmbDocumentPickerModalValue } from '../../modals/types.js'; -import { - UMB_DOCUMENT_PICKER_MODAL, - UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS, - UMB_DOCUMENT_SEARCH_PROVIDER_ALIAS, -} from '../../constants.js'; -import type { UmbDocumentItemModel } from '../../repository/index.js'; +import { UMB_DOCUMENT_PICKER_MODAL, UMB_DOCUMENT_SEARCH_PROVIDER_ALIAS } from '../../constants.js'; +import type { UmbDocumentItemModel } from '../../item/types.js'; +import { UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS } from '../../item/constants.js'; import type { UmbDocumentTreeItemModel } from '../../tree/types.js'; import { UmbPickerInputContext } from '@umbraco-cms/backoffice/picker-input'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/constants.ts index 456994bdd613..b0cd03a572f1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/constants.ts @@ -3,6 +3,7 @@ export { UMB_DOCUMENT_ENTITY_TYPE, UMB_DOCUMENT_ROOT_ENTITY_TYPE } from './entit export * from './collection/constants.js'; export * from './entity-actions/constants.js'; export * from './entity-bulk-actions/constants.js'; +export * from './item/constants.js'; export * from './modals/constants.js'; export * from './paths.js'; export * from './property-dataset-context/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/create/create.action.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/create/create.action.ts index 2bcc382622f7..af2adec3bef7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/create/create.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/create/create.action.ts @@ -1,4 +1,4 @@ -import { UmbDocumentItemRepository } from '../../repository/index.js'; +import { UmbDocumentItemRepository } from '../../item/index.js'; import { UMB_DOCUMENT_CREATE_OPTIONS_MODAL } from './document-create-options-modal.token.js'; import type { UmbEntityActionArgs } from '@umbraco-cms/backoffice/entity-action'; import { UmbEntityActionBase } from '@umbraco-cms/backoffice/entity-action'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/create/document-create-options-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/create/document-create-options-modal.element.ts index 419bd85a626f..1dbf684c995d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/create/document-create-options-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/create/document-create-options-modal.element.ts @@ -1,4 +1,4 @@ -import { UmbDocumentItemRepository } from '../../repository/index.js'; +import { UmbDocumentItemRepository } from '../../item/index.js'; import type { UmbDocumentCreateOptionsModalData, UmbDocumentCreateOptionsModalValue, diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/manifests.ts index 8caa4a29f5c1..3c1a1fcd1be2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/manifests.ts @@ -1,4 +1,5 @@ -import { UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS, UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS } from '../repository/index.js'; +import { UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS } from '../repository/index.js'; +import { UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS } from '../item/constants.js'; import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; import { UMB_USER_PERMISSION_DOCUMENT_DELETE } from '../user-permissions/constants.js'; import { manifests as createBlueprintManifests } from './create-blueprint/manifests.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/notifications/modal/document-notifications-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/notifications/modal/document-notifications-modal.element.ts index b1d9683fc1f8..061c60669c1a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/notifications/modal/document-notifications-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/notifications/modal/document-notifications-modal.element.ts @@ -1,4 +1,4 @@ -import { UmbDocumentItemRepository } from '../../../repository/index.js'; +import { UmbDocumentItemRepository } from '../../../item/index.js'; import { UmbDocumentNotificationsRepository } from '../repository/document-notifications.repository.js'; import type { UmbDocumentNotificationsModalData } from './document-notifications-modal.token.js'; import type { UmbEntityUnique } from '@umbraco-cms/backoffice/entity'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/public-access/modal/public-access-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/public-access/modal/public-access-modal.element.ts index e246b11ae21e..90d08daedc48 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/public-access/modal/public-access-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/public-access/modal/public-access-modal.element.ts @@ -1,5 +1,5 @@ import { UmbDocumentPublicAccessRepository } from '../repository/public-access.repository.js'; -import { UmbDocumentItemRepository } from '../../../repository/index.js'; +import { UmbDocumentItemRepository } from '../../../item/index.js'; import type { UmbInputDocumentElement } from '../../../components/index.js'; import type { UmbPublicAccessModalData, UmbPublicAccessModalValue } from './public-access-modal.token.js'; import { css, customElement, html, nothing, state } from '@umbraco-cms/backoffice/external/lit'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/sort-children-of/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/sort-children-of/manifests.ts index 41a9ecade2f0..39f00ca0f828 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/sort-children-of/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/sort-children-of/manifests.ts @@ -1,5 +1,5 @@ import { UMB_DOCUMENT_ENTITY_TYPE, UMB_DOCUMENT_ROOT_ENTITY_TYPE } from '../../entity.js'; -import { UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS } from '../../repository/index.js'; +import { UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS } from '../../item/constants.js'; import { UMB_DOCUMENT_TREE_REPOSITORY_ALIAS } from '../../tree/index.js'; import { UMB_USER_PERMISSION_DOCUMENT_SORT } from '../../user-permissions/index.js'; import { UMB_SORT_CHILDREN_OF_DOCUMENT_REPOSITORY_ALIAS } from './repository/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/index.ts index fcc6565ced8d..a14bf00b99e1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/index.ts @@ -5,16 +5,17 @@ export * from './components/index.js'; export * from './constants.js'; export * from './entity-actions/index.js'; export * from './global-contexts/index.js'; +export * from './item/index.js'; export * from './modals/index.js'; export * from './paths.js'; export * from './publishing/index.js'; export * from './recycle-bin/index.js'; export * from './reference/index.js'; export * from './repository/index.js'; +export * from './tree/index.js'; export * from './url/index.js'; export * from './user-permissions/index.js'; -export * from './tree/index.js'; export { UMB_CONTENT_MENU_ALIAS } from './menu/manifests.js'; export { UMB_DOCUMENT_COLLECTION_ALIAS } from './collection/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/constants.ts new file mode 100644 index 000000000000..41a409dec1f0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/constants.ts @@ -0,0 +1 @@ +export * from './repository/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index be5b948ae6a2..c271f30f0318 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -1,5 +1,5 @@ -import type { UmbDocumentItemModel } from '../repository/types.js'; import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; +import type { UmbDocumentItemModel } from './types.js'; import { classMap, customElement, @@ -8,7 +8,6 @@ import { nothing, property, state, - when, } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/index.ts new file mode 100644 index 000000000000..f6365499927d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/index.ts @@ -0,0 +1 @@ +export { UmbDocumentItemRepository } from './repository/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/manifests.ts index 522b66ae3fd6..16a6e20374f2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/manifests.ts @@ -1,4 +1,5 @@ import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; +import { manifests as repositoryManifests } from './repository/manifests.js'; export const manifests: Array = [ { @@ -8,4 +9,5 @@ export const manifests: Array = [ element: () => import('./document-item-ref.element.js'), forEntityTypes: [UMB_DOCUMENT_ENTITY_TYPE], }, + ...repositoryManifests, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/item/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/constants.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/item/constants.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/constants.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/item/document-item.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/document-item.repository.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/item/document-item.repository.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/document-item.repository.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/item/document-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/document-item.server.data-source.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/item/document-item.server.data-source.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/document-item.server.data-source.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/item/document-item.store.context-token.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/document-item.store.context-token.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/item/document-item.store.context-token.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/document-item.store.context-token.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/item/document-item.store.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/document-item.store.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/item/document-item.store.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/document-item.store.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/item/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/index.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/item/index.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/item/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/manifests.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/item/manifests.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/manifests.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/item/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/types.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/item/types.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/types.ts new file mode 100644 index 000000000000..281be3f829a9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/types.ts @@ -0,0 +1 @@ +export type { UmbDocumentItemModel } from './repository/types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/manifests.ts index f4d9b410dee9..bf4f63f5d34a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/manifests.ts @@ -5,7 +5,7 @@ import { UMB_USER_PERMISSION_DOCUMENT_DELETE, UMB_USER_PERMISSION_DOCUMENT_MOVE, } from '../../constants.js'; -import { UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS } from '../../repository/constants.js'; +import { UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS } from '../../item/constants.js'; import { UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS, UMB_ENTITY_IS_TRASHED_CONDITION_ALIAS, diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/constants.ts index 7a6c4a9d9c73..7846cdeb9a47 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/constants.ts @@ -1,3 +1,2 @@ export * from './detail/constants.js'; -export * from './item/constants.js'; export * from './validation/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/index.ts index 8059abd30dde..6025dec443a4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/index.ts @@ -1,6 +1,4 @@ export { UmbDocumentDetailRepository } from './detail/index.js'; -export { UmbDocumentItemRepository } from './item/index.js'; export { UmbDocumentPreviewRepository } from './preview/index.js'; export * from './constants.js'; -export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/manifests.ts index 4dfb0c911f4e..3c7f8d7aaf69 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/manifests.ts @@ -1,4 +1,3 @@ import { manifests as detailManifests } from './detail/manifests.js'; -import { manifests as itemManifests } from './item/manifests.js'; -export const manifests: Array = [...detailManifests, ...itemManifests]; +export const manifests: Array = [...detailManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/types.ts deleted file mode 100644 index 204e345ff932..000000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/types.ts +++ /dev/null @@ -1 +0,0 @@ -export type { UmbDocumentItemModel } from './item/types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts index f7907e593572..4cd8d71a5944 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/document-search-result-item.element.ts @@ -1,4 +1,4 @@ -import type { UmbDocumentItemModel, UmbDocumentItemVariantModel } from '../repository/item/types.js'; +import type { UmbDocumentItemModel, UmbDocumentItemVariantModel } from '../item/repository/types.js'; import type { UmbSearchResultItemModel } from '@umbraco-cms/backoffice/search'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { css, customElement, html, nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/types.ts index a63f89853bd7..3b12d8b51a97 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/search/types.ts @@ -1,4 +1,4 @@ -import type { UmbDocumentItemModel } from '../repository/index.js'; +import type { UmbDocumentItemModel } from '../item/types.js'; import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search'; import type { UmbDocumentTypeEntityType } from '@umbraco-cms/backoffice/document-type'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/types.ts index a3407cf5aa4a..c6bd94ae241d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/types.ts @@ -10,15 +10,15 @@ import type { UmbContentDetailModel, UmbElementValueModel } from '@umbraco-cms/b export { UmbDocumentVariantState }; export type * from './audit-log/types.js'; -export type * from './recycle-bin/types.js'; export type * from './collection/types.js'; +export type * from './entity.js'; +export type * from './item/types.js'; export type * from './modals/types.js'; -export type * from './repository/types.js'; +export type * from './publishing/types.js'; +export type * from './recycle-bin/types.js'; export type * from './tree/types.js'; export type * from './user-permissions/types.js'; -export type * from './entity.js'; export type * from './workspace/types.js'; -export type * from './publishing/types.js'; export interface UmbDocumentDetailModel extends UmbContentDetailModel { documentType: { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/input-document-granular-user-permission/input-document-granular-user-permission.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/input-document-granular-user-permission/input-document-granular-user-permission.element.ts index c83a9975d1d2..512fc7af2a04 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/input-document-granular-user-permission/input-document-granular-user-permission.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/user-permissions/input-document-granular-user-permission/input-document-granular-user-permission.element.ts @@ -1,5 +1,6 @@ import type { UmbDocumentUserPermissionModel } from '../types.js'; -import { UmbDocumentItemRepository, type UmbDocumentItemModel } from '../../repository/index.js'; +import { UmbDocumentItemRepository } from '../../item/index.js'; +import type { UmbDocumentItemModel } from '../../item/types.js'; import { UMB_DOCUMENT_PICKER_MODAL } from '../../constants.js'; import { css, customElement, html, repeat, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; From 5b0444ffa20a397c7b429a27c4bff9ebee86b910 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 6 Feb 2025 23:15:58 +0100 Subject: [PATCH 010/145] implement for input member --- .../input-member/input-member.element.ts | 51 +--------- .../packages/members/member/item/manifests.ts | 11 +++ .../member/item/member-item-ref.element.ts | 93 +++++++++++++++++++ .../src/packages/members/member/manifests.ts | 2 + 4 files changed, 111 insertions(+), 46 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member/item/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts index fd594ad89884..985dfb0417ab 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts @@ -5,10 +5,8 @@ import { splitStringToArray } from '@umbraco-cms/backoffice/utils'; import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UmbSorterController } from '@umbraco-cms/backoffice/sorter'; import { UMB_MEMBER_TYPE_ENTITY_TYPE } from '@umbraco-cms/backoffice/member-type'; -import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; @customElement('umb-input-member') export class UmbInputMemberElement extends UmbFormControlMixin( @@ -133,15 +131,6 @@ export class UmbInputMemberElement extends UmbFormControlMixin { - return { data: { entityType: 'member', preset: {} } }; - }) - .observeRouteBuilder((routeBuilder) => { - this._editMemberPath = routeBuilder({}); - }); - this.addValidator( 'rangeUnderflow', () => this.minMessage, @@ -172,10 +161,6 @@ export class UmbInputMemberElement extends UmbFormControlMixin item.unique, - (item) => this.#renderItem(item), + (item) => + html``, )} `; @@ -209,36 +198,6 @@ export class UmbInputMemberElement extends UmbFormControlMixin - ${when(item.memberType.icon, (icon) => html``)} - - ${this.#renderOpenButton(item)} ${this.#renderRemoveButton(item)} - - - `; - } - - #renderOpenButton(item: UmbMemberItemModel) { - if (!this.showOpenButton) return nothing; - return html` - - - - `; - } - - #renderRemoveButton(item: UmbMemberItemModel) { - if (this.readonly) return nothing; - return html` - this.#onRemove(item)} label=${this.localize.term('general_remove')}> - `; - } - static override styles = [ css` #btn-add { diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/manifests.ts new file mode 100644 index 000000000000..70b6e157699d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/manifests.ts @@ -0,0 +1,11 @@ +import { UMB_MEMBER_ENTITY_TYPE } from '../entity.js'; + +export const manifests: Array = [ + { + type: 'entityItemRef', + alias: 'Umb.EntityItemRef.Member', + name: 'Member Entity Item Reference', + element: () => import('./member-item-ref.element.js'), + forEntityTypes: [UMB_MEMBER_ENTITY_TYPE], + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts new file mode 100644 index 000000000000..69482bc4cb3d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts @@ -0,0 +1,93 @@ +import { UMB_MEMBER_ENTITY_TYPE } from '../entity.js'; +import type { UmbMemberItemModel } from '../repository/index.js'; +import { customElement, html, ifDefined, nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; +import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; +import { UMB_PICKER_INPUT_CONTEXT } from '@umbraco-cms/backoffice/picker-input'; + +@customElement('umb-member-item-ref') +export class UmbMemberItemRefElement extends UmbLitElement { + @property({ type: Object }) + item?: UmbMemberItemModel; + + @property({ type: Boolean }) + readonly = false; + + @property({ type: Boolean }) + standalone = false; + + @state() + _isPickerInput = false; + + _editDocumentPath = ''; + + #pickerInputContext?: typeof UMB_PICKER_INPUT_CONTEXT.TYPE; + + constructor() { + super(); + + this.consumeContext(UMB_PICKER_INPUT_CONTEXT, (context) => { + this.#pickerInputContext = context; + this._isPickerInput = context !== undefined; + }); + + new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath(UMB_MEMBER_ENTITY_TYPE) + .onSetup(() => { + return { data: { entityType: UMB_MEMBER_ENTITY_TYPE, preset: {} } }; + }) + .observeRouteBuilder((routeBuilder) => { + this._editDocumentPath = routeBuilder({}); + }); + } + + #getHref(item: UmbMemberItemModel) { + return `${this._editDocumentPath}/edit/${item.unique}`; + } + + #onRemove() { + if (!this.item) return; + this.#pickerInputContext?.requestRemoveItem(this.item.unique); + } + + override render() { + if (!this.item) return nothing; + + return html` + + ${this.#renderIcon(this.item)} ${this.#renderActions()} + + `; + } + + #renderActions() { + if (this.readonly) return; + if (!this.item) return; + if (!this._isPickerInput) return; + + return html` + + + + `; + } + + #renderIcon(item: UmbMemberItemModel) { + if (!item.memberType.icon) return; + return html``; + } +} + +export { UmbMemberItemRefElement as element }; + +declare global { + interface HTMLElementTagNameMap { + 'umb-member-item-ref': UmbMemberItemRefElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/manifests.ts index 84682bbb25be..470f6503b329 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/manifests.ts @@ -1,5 +1,6 @@ import { manifests as collectionManifests } from './collection/manifests.js'; import { manifests as entityActionManifests } from './entity-actions/manifests.js'; +import { manifests as itemManifests } from './item/manifests.js'; import { manifests as memberPickerModalManifests } from './components/member-picker-modal/manifests.js'; import { manifests as menuItemManifests } from './menu-item/manifests.js'; import { manifests as pickerManifests } from './picker/manifests.js'; @@ -13,6 +14,7 @@ import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension export const manifests: Array = [ ...collectionManifests, ...entityActionManifests, + ...itemManifests, ...memberPickerModalManifests, ...menuItemManifests, ...pickerManifests, From d073ab50edad38767c2001b2fdd6b2cea635d9d9 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 7 Feb 2025 12:43:42 +0100 Subject: [PATCH 011/145] enable action slot --- .../entity-item-ref.element.ts | 9 ++++ .../input-document/input-document.element.ts | 23 ++++++++--- .../item/document-item-ref.element.ts | 28 +------------ .../input-member/input-member.element.ts | 41 ++++++++++++++++--- .../member/item/member-item-ref.element.ts | 36 +++------------- 5 files changed, 68 insertions(+), 69 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts index 66eda864473d..3fc9b80d0e85 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts @@ -41,7 +41,16 @@ export class UmbEntityItemRefElement extends UmbLitElement { (manifest: ManifestEntityItemRef) => manifest.forEntityTypes.includes(entityType), (extensionControllers) => { const component = extensionControllers[0]?.component; + + // assign the item to the component component.item = this.#item; + + // Proxy the actions slot to the component + const slotElement = document.createElement('slot'); + slotElement.name = 'actions'; + slotElement.setAttribute('slot', 'actions'); + component.appendChild(slotElement); + this._component = component; }, undefined, // We can leave the alias to undefined, as we destroy this our selfs. diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts index e7fd4be8eb54..60e698d72eff 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts @@ -1,5 +1,5 @@ import { UmbDocumentPickerInputContext } from './input-document.context.js'; -import { css, customElement, html, nothing, property, repeat, state } from '@umbraco-cms/backoffice/external/lit'; +import { css, customElement, html, nothing, property, repeat, state, when } from '@umbraco-cms/backoffice/external/lit'; import { splitStringToArray } from '@umbraco-cms/backoffice/utils'; import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; @@ -160,6 +160,10 @@ export class UmbInputDocumentElement extends UmbFormControlMixin item.unique, (item) => - html` - `, + html` + ${when( + !this.readonly, + () => html` + + this.#onRemove(item)}> + + `, + )} + `, )} `; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index c271f30f0318..ca3a2e85b9af 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -12,7 +12,6 @@ import { import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; -import { UMB_PICKER_INPUT_CONTEXT } from '@umbraco-cms/backoffice/picker-input'; @customElement('umb-document-item-ref') export class UmbDocumentItemRefElement extends UmbLitElement { @@ -30,16 +29,9 @@ export class UmbDocumentItemRefElement extends UmbLitElement { _editDocumentPath = ''; - #pickerInputContext?: typeof UMB_PICKER_INPUT_CONTEXT.TYPE; - constructor() { super(); - this.consumeContext(UMB_PICKER_INPUT_CONTEXT, (context) => { - this.#pickerInputContext = context; - this._isPickerInput = context !== undefined; - }); - new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) .addAdditionalPath(UMB_DOCUMENT_ENTITY_TYPE) .onSetup(() => { @@ -58,11 +50,6 @@ export class UmbDocumentItemRefElement extends UmbLitElement { return `${this._editDocumentPath}/edit/${item.unique}`; } - #onRemove() { - if (!this.item) return; - this.#pickerInputContext?.requestRemoveItem(this.item.unique); - } - override render() { if (!this.item) return nothing; @@ -74,23 +61,12 @@ export class UmbDocumentItemRefElement extends UmbLitElement { href=${ifDefined(this.#getHref(this.item))} ?readonly=${this.readonly} ?standalone=${this.standalone}> - ${this.#renderIcon(this.item)} ${this.#renderIsTrashed(this.item)} ${this.#renderActions()} + + ${this.#renderIcon(this.item)} ${this.#renderIsTrashed(this.item)} `; } - #renderActions() { - if (this.readonly) return; - if (!this.item) return; - if (!this._isPickerInput) return; - - return html` - - - - `; - } - #renderIcon(item: UmbDocumentItemModel) { if (!item.documentType.icon) return; return html``; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts index 985dfb0417ab..82b74de0c09d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts @@ -161,6 +161,10 @@ export class UmbInputMemberElement extends UmbFormControlMixin item.unique, - (item) => - html``, + (item) => this.#renderItem(item), )} `; } + #renderItem(item: UmbMemberItemModel) { + if (!item.unique) return nothing; + return html` + + + ${this.#renderOpenButton(item)} ${this.#renderRemoveButton(item)} + + + `; + } + #renderAddButton() { if (this.selection.length >= this.max) return nothing; if (this.readonly && this.selection.length > 0) { @@ -198,13 +209,31 @@ export class UmbInputMemberElement extends UmbFormControlMixin + ${this.localize.term('general_open')} + + `; + } + + #renderRemoveButton(item: UmbMemberItemModel) { + if (this.readonly) return nothing; + return html` + this.#onRemove(item)} label=${this.localize.term('general_remove')}> + `; + } + static override styles = [ css` #btn-add { display: block; } - uui-ref-node[drag-placeholder] { + umb-entity-item-ref[drag-placeholder] { opacity: 0.2; } `, diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts index 69482bc4cb3d..96b413ff8113 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts @@ -17,38 +17,23 @@ export class UmbMemberItemRefElement extends UmbLitElement { @property({ type: Boolean }) standalone = false; - @state() - _isPickerInput = false; - - _editDocumentPath = ''; - - #pickerInputContext?: typeof UMB_PICKER_INPUT_CONTEXT.TYPE; + _editPath = ''; constructor() { super(); - this.consumeContext(UMB_PICKER_INPUT_CONTEXT, (context) => { - this.#pickerInputContext = context; - this._isPickerInput = context !== undefined; - }); - new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) .addAdditionalPath(UMB_MEMBER_ENTITY_TYPE) .onSetup(() => { return { data: { entityType: UMB_MEMBER_ENTITY_TYPE, preset: {} } }; }) .observeRouteBuilder((routeBuilder) => { - this._editDocumentPath = routeBuilder({}); + this._editPath = routeBuilder({}); }); } #getHref(item: UmbMemberItemModel) { - return `${this._editDocumentPath}/edit/${item.unique}`; - } - - #onRemove() { - if (!this.item) return; - this.#pickerInputContext?.requestRemoveItem(this.item.unique); + return `${this._editPath}/edit/${item.unique}`; } override render() { @@ -61,23 +46,12 @@ export class UmbMemberItemRefElement extends UmbLitElement { href=${ifDefined(this.#getHref(this.item))} ?readonly=${this.readonly} ?standalone=${this.standalone}> - ${this.#renderIcon(this.item)} ${this.#renderActions()} + + ${this.#renderIcon(this.item)} `; } - #renderActions() { - if (this.readonly) return; - if (!this.item) return; - if (!this._isPickerInput) return; - - return html` - - - - `; - } - #renderIcon(item: UmbMemberItemModel) { if (!item.memberType.icon) return; return html``; From 964e86ca77b3bccbb8a113d8bff3e66328f985f2 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 7 Feb 2025 12:53:04 +0100 Subject: [PATCH 012/145] add null check --- .../core/entity/entity-item-ref/entity-item-ref.element.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts index 3fc9b80d0e85..bd2befeae60d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts @@ -42,6 +42,11 @@ export class UmbEntityItemRefElement extends UmbLitElement { (extensionControllers) => { const component = extensionControllers[0]?.component; + if (!component) { + this._component?.remove(); + return; + } + // assign the item to the component component.item = this.#item; From e1cbf73887e30902055d5734b1643ea0e4b30041 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 7 Feb 2025 12:53:13 +0100 Subject: [PATCH 013/145] fix sorting again --- .../components/input-document/input-document.element.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts index 60e698d72eff..1f8b902c4521 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/components/input-document/input-document.element.ts @@ -21,7 +21,7 @@ export class UmbInputDocumentElement extends UmbFormControlMixin { this.selection = model; @@ -192,7 +192,11 @@ export class UmbInputDocumentElement extends UmbFormControlMixin item.unique, (item) => - html` + html` ${when( !this.readonly, () => html` From b986ebd618a931015de40ebcf71a6544409013db Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 7 Feb 2025 12:53:31 +0100 Subject: [PATCH 014/145] fix sorting again --- .../member/components/input-member/input-member.element.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts index 82b74de0c09d..b8296f2cd446 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts @@ -20,7 +20,7 @@ export class UmbInputMemberElement extends UmbFormControlMixin { this.selection = model; @@ -185,7 +185,7 @@ export class UmbInputMemberElement extends UmbFormControlMixin + ${this.#renderOpenButton(item)} ${this.#renderRemoveButton(item)} From a98e3db4f0cd28e0e16db799a4c468e11d551ea2 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 7 Feb 2025 13:34:21 +0100 Subject: [PATCH 015/145] use member element --- .../members/member/item/member-item-ref.element.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts index 96b413ff8113..48485a30c956 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts @@ -1,10 +1,9 @@ import { UMB_MEMBER_ENTITY_TYPE } from '../entity.js'; import type { UmbMemberItemModel } from '../repository/index.js'; -import { customElement, html, ifDefined, nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; +import { customElement, html, ifDefined, nothing, property } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; -import { UMB_PICKER_INPUT_CONTEXT } from '@umbraco-cms/backoffice/picker-input'; @customElement('umb-member-item-ref') export class UmbMemberItemRefElement extends UmbLitElement { @@ -40,7 +39,7 @@ export class UmbMemberItemRefElement extends UmbLitElement { if (!this.item) return nothing; return html` - ${this.#renderIcon(this.item)} - + `; } From 3aba5686cb182c6df6364ebf9d14cdc098823841 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 7 Feb 2025 13:34:31 +0100 Subject: [PATCH 016/145] add draft styling back --- .../item/document-item-ref.element.ts | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index ca3a2e85b9af..94eff8be1227 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -1,14 +1,6 @@ import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; import type { UmbDocumentItemModel } from './types.js'; -import { - classMap, - customElement, - html, - ifDefined, - nothing, - property, - state, -} from '@umbraco-cms/backoffice/external/lit'; +import { classMap, css, customElement, html, ifDefined, nothing, property } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; @@ -24,10 +16,7 @@ export class UmbDocumentItemRefElement extends UmbLitElement { @property({ type: Boolean }) standalone = false; - @state() - _isPickerInput = false; - - _editDocumentPath = ''; + _editPath = ''; constructor() { super(); @@ -38,7 +27,7 @@ export class UmbDocumentItemRefElement extends UmbLitElement { return { data: { entityType: UMB_DOCUMENT_ENTITY_TYPE, preset: {} } }; }) .observeRouteBuilder((routeBuilder) => { - this._editDocumentPath = routeBuilder({}); + this._editPath = routeBuilder({}); }); } @@ -47,7 +36,7 @@ export class UmbDocumentItemRefElement extends UmbLitElement { } #getHref(item: UmbDocumentItemModel) { - return `${this._editDocumentPath}/edit/${item.unique}`; + return `${this._editPath}/edit/${item.unique}`; } override render() { @@ -76,6 +65,14 @@ export class UmbDocumentItemRefElement extends UmbLitElement { if (!item.isTrashed) return; return html`Trashed`; } + + static override styles = [ + css` + .draft { + opacity: 0.6; + } + `, + ]; } export { UmbDocumentItemRefElement as element }; From f4547b5d3f82ba2fb74155c59dd6fc77c28608fc Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 7 Feb 2025 13:44:13 +0100 Subject: [PATCH 017/145] move item repository --- .../member/components/input-member/input-member.context.ts | 2 +- .../member/components/input-member/input-member.element.ts | 4 ++-- .../member-picker-modal/member-picker-modal.element.ts | 2 +- .../member-picker-modal/member-picker-modal.token.ts | 2 +- .../src/packages/members/member/constants.ts | 2 ++ .../src/packages/members/member/entity-actions/manifests.ts | 2 +- .../src/packages/members/member/index.ts | 2 ++ .../src/packages/members/member/item/constants.ts | 1 + .../src/packages/members/member/item/index.ts | 3 +++ .../src/packages/members/member/item/manifests.ts | 2 ++ .../packages/members/member/item/member-item-ref.element.ts | 2 +- .../member/{repository/item => item/repository}/constants.ts | 0 .../member/{repository/item => item/repository}/index.ts | 0 .../member/{repository/item => item/repository}/manifests.ts | 0 .../item => item/repository}/member-item.repository.ts | 0 .../repository}/member-item.server.data-source.ts | 0 .../repository}/member-item.store.context-token.ts | 0 .../{repository/item => item/repository}/member-item.store.ts | 0 .../member/{repository/item => item/repository}/types.ts | 0 .../src/packages/members/member/item/types.ts | 1 + .../src/packages/members/member/repository/constants.ts | 1 - .../src/packages/members/member/repository/index.ts | 1 - .../src/packages/members/member/repository/manifests.ts | 3 +-- .../members/member/repository/member-repository-base.ts | 4 ++-- .../src/packages/members/member/search/types.ts | 2 +- .../src/packages/members/member/types.ts | 4 +++- 26 files changed, 25 insertions(+), 15 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member/item/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member/item/index.ts rename src/Umbraco.Web.UI.Client/src/packages/members/member/{repository/item => item/repository}/constants.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/members/member/{repository/item => item/repository}/index.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/members/member/{repository/item => item/repository}/manifests.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/members/member/{repository/item => item/repository}/member-item.repository.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/members/member/{repository/item => item/repository}/member-item.server.data-source.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/members/member/{repository/item => item/repository}/member-item.store.context-token.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/members/member/{repository/item => item/repository}/member-item.store.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/members/member/{repository/item => item/repository}/types.ts (100%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/members/member/item/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.context.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.context.ts index b8c77827b967..350e9b1ae4aa 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.context.ts @@ -1,4 +1,4 @@ -import type { UmbMemberItemModel } from '../../repository/index.js'; +import type { UmbMemberItemModel } from '../../item/types.js'; import { UMB_MEMBER_PICKER_MODAL, type UmbMemberPickerModalData, diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts index b8296f2cd446..d01b47536409 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts @@ -1,6 +1,6 @@ -import type { UmbMemberItemModel } from '../../repository/index.js'; +import type { UmbMemberItemModel } from '../../item/types.js'; import { UmbMemberPickerInputContext } from './input-member.context.js'; -import { css, customElement, html, nothing, property, repeat, state, when } from '@umbraco-cms/backoffice/external/lit'; +import { css, customElement, html, nothing, property, repeat, state } from '@umbraco-cms/backoffice/external/lit'; import { splitStringToArray } from '@umbraco-cms/backoffice/utils'; import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/member-picker-modal/member-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/member-picker-modal/member-picker-modal.element.ts index db9349b93243..f2bba35ef91d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/member-picker-modal/member-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/member-picker-modal/member-picker-modal.element.ts @@ -1,6 +1,6 @@ import { UmbMemberCollectionRepository } from '../../collection/index.js'; import type { UmbMemberDetailModel } from '../../types.js'; -import type { UmbMemberItemModel } from '../../repository/index.js'; +import type { UmbMemberItemModel } from '../../item/types.js'; import type { UmbMemberPickerModalValue, UmbMemberPickerModalData } from './member-picker-modal.token.js'; import type { PropertyValueMap } from '@umbraco-cms/backoffice/external/lit'; import { customElement, html, nothing, repeat, state } from '@umbraco-cms/backoffice/external/lit'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/member-picker-modal/member-picker-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/member-picker-modal/member-picker-modal.token.ts index a49bce2f6180..845b6b5643af 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/member-picker-modal/member-picker-modal.token.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/member-picker-modal/member-picker-modal.token.ts @@ -1,4 +1,4 @@ -import type { UmbMemberItemModel } from '../../repository/index.js'; +import type { UmbMemberItemModel } from '../../item/types.js'; import { UMB_MEMBER_SEARCH_PROVIDER_ALIAS } from '../../search/constants.js'; import type { UmbPickerModalData, UmbPickerModalValue } from '@umbraco-cms/backoffice/modal'; import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/constants.ts index 9e63926414c6..c2e40ebfe7fd 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/constants.ts @@ -1,7 +1,9 @@ export { UMB_MEMBER_ENTITY_TYPE, UMB_MEMBER_ROOT_ENTITY_TYPE } from './entity.js'; export { UMB_MEMBER_VARIANT_CONTEXT } from './property-dataset-context/member-property-dataset.context-token.js'; + export * from './collection/constants.js'; export * from './entity-actions/constants.js'; +export * from './item/constants.js'; export * from './repository/constants.js'; export * from './search/constants.js'; export * from './workspace/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/manifests.ts index 51167999f0e2..933d3a563b28 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/entity-actions/manifests.ts @@ -1,4 +1,4 @@ -import { UMB_MEMBER_ITEM_REPOSITORY_ALIAS } from '../repository/constants.js'; +import { UMB_MEMBER_ITEM_REPOSITORY_ALIAS } from '../item/constants.js'; import { UMB_MEMBER_ENTITY_TYPE } from '../entity.js'; import { UMB_MEMBER_DETAIL_REPOSITORY_ALIAS } from '../repository/detail/manifests.js'; import { manifests as createManifests } from './create/manifests.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/index.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/index.ts index 6c56c5810dc3..05d76cee3ae5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/index.ts @@ -3,6 +3,8 @@ import './components/index.js'; export * from './collection/index.js'; export * from './components/index.js'; export * from './constants.js'; +export * from './item/index.js'; export * from './paths.js'; export * from './repository/index.js'; + export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/constants.ts new file mode 100644 index 000000000000..41a409dec1f0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/constants.ts @@ -0,0 +1 @@ +export * from './repository/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/index.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/index.ts new file mode 100644 index 000000000000..a9562032ae63 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/index.ts @@ -0,0 +1,3 @@ +export { UmbMemberItemRepository } from './repository/index.js'; + +export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/manifests.ts index 70b6e157699d..637a3ebcc33e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/manifests.ts @@ -1,4 +1,5 @@ import { UMB_MEMBER_ENTITY_TYPE } from '../entity.js'; +import { manifests as repositoryManifests } from './repository/manifests.js'; export const manifests: Array = [ { @@ -8,4 +9,5 @@ export const manifests: Array = [ element: () => import('./member-item-ref.element.js'), forEntityTypes: [UMB_MEMBER_ENTITY_TYPE], }, + ...repositoryManifests, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts index 48485a30c956..766c52cb4258 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts @@ -1,5 +1,5 @@ import { UMB_MEMBER_ENTITY_TYPE } from '../entity.js'; -import type { UmbMemberItemModel } from '../repository/index.js'; +import type { UmbMemberItemModel } from './repository/types.js'; import { customElement, html, ifDefined, nothing, property } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/constants.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/constants.ts rename to src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/constants.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/index.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/index.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/index.ts rename to src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/manifests.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/manifests.ts rename to src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/manifests.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/member-item.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/member-item.repository.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/member-item.repository.ts rename to src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/member-item.repository.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/member-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/member-item.server.data-source.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/member-item.server.data-source.ts rename to src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/member-item.server.data-source.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/member-item.store.context-token.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/member-item.store.context-token.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/member-item.store.context-token.ts rename to src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/member-item.store.context-token.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/member-item.store.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/member-item.store.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/member-item.store.ts rename to src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/member-item.store.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/types.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/types.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/members/member/repository/item/types.ts rename to src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/types.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/types.ts new file mode 100644 index 000000000000..e32ac4b889fe --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/types.ts @@ -0,0 +1 @@ +export type * from './repository/types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/constants.ts index 5409d1b6b838..0f60420161b0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/constants.ts @@ -1,2 +1 @@ export * from './detail/constants.js'; -export * from './item/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/index.ts index d54682b8ca73..f54e601fc57e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/index.ts @@ -1,3 +1,2 @@ export { UmbMemberDetailRepository } from './detail/index.js'; -export { UmbMemberItemRepository, type UmbMemberItemModel } from './item/index.js'; export * from './validation/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/manifests.ts index 74a3121896bb..b4c5404d8422 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/manifests.ts @@ -1,5 +1,4 @@ import { manifests as detailManifests } from './detail/manifests.js'; -import { manifests as itemManifests } from './item/manifests.js'; import { manifests as validationManifests } from './validation/manifests.js'; -export const manifests: Array = [...detailManifests, ...itemManifests, ...validationManifests]; +export const manifests: Array = [...detailManifests, ...validationManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/member-repository-base.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/member-repository-base.ts index c8a0464f7a2f..74257955e161 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/member-repository-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/member-repository-base.ts @@ -1,7 +1,7 @@ import type { UmbMemberDetailStore } from './detail/member-detail.store.js'; import { UMB_MEMBER_DETAIL_STORE_CONTEXT } from './detail/member-detail.store.context-token.js'; -import type { UmbMemberItemStore } from './item/member-item.store.js'; -import { UMB_MEMBER_ITEM_STORE_CONTEXT } from './item/member-item.store.context-token.js'; +import type { UmbMemberItemStore } from '../item/repository/member-item.store.js'; +import { UMB_MEMBER_ITEM_STORE_CONTEXT } from '../item/repository/member-item.store.context-token.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbNotificationContext } from '@umbraco-cms/backoffice/notification'; import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/search/types.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/types.ts index 6ee8fceef593..1970d6108500 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/search/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/search/types.ts @@ -1,4 +1,4 @@ -import type { UmbMemberItemModel } from '../repository/index.js'; +import type { UmbMemberItemModel } from '../item/types.js'; import type { UmbMemberTypeEntityType } from '@umbraco-cms/backoffice/member-type'; import type { UmbSearchRequestArgs } from '@umbraco-cms/backoffice/search'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/types.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/types.ts index 44fb8d298cfc..cb8c9c153dcc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/types.ts @@ -5,6 +5,8 @@ import type { UmbContentDetailModel, UmbElementValueModel } from '@umbraco-cms/b export type * from './entity.js'; export type * from './collection/types.js'; +export type * from './item/types.js'; + export interface UmbMemberDetailModel extends UmbContentDetailModel { email: string; entityType: UmbMemberEntityType; @@ -19,7 +21,7 @@ export interface UmbMemberDetailModel extends UmbContentDetailModel { lastPasswordChangeDate: string | null; memberType: { unique: string; - icon: string; + icon: string; }; newPassword?: string; oldPassword?: string; From 1adf436e5c037390d06310965286b5e339630597 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 7 Feb 2025 14:06:31 +0100 Subject: [PATCH 018/145] implement for user input --- .../user-input/user-input.element.ts | 15 +--- .../src/packages/user/user/item/manifests.ts | 11 +++ .../user/user/item/user-item-ref.element.ts | 68 +++++++++++++++++++ .../src/packages/user/user/manifests.ts | 7 +- 4 files changed, 87 insertions(+), 14 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/user/user/item/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/components/user-input/user-input.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/components/user-input/user-input.element.ts index 118cdc4a3677..f5621924100a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/components/user-input/user-input.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/components/user-input/user-input.element.ts @@ -18,7 +18,7 @@ export class UmbUserInputElement extends UUIFormControlMixin(UmbLitElement, '') return modelEntry; }, identifier: 'Umb.SorterIdentifier.InputUser', - itemSelector: 'uui-ref-node-user', + itemSelector: 'umb-entity-item-ref', containerSelector: 'uui-ref-list', onChange: ({ model }) => { this.selection = model; @@ -156,16 +156,11 @@ export class UmbUserInputElement extends UUIFormControlMixin(UmbLitElement, '') #renderItem(item: UmbUserItemModel) { if (!item.unique) return nothing; return html` - - + this.#removeItem(item)}> - + `; } @@ -174,10 +169,6 @@ export class UmbUserInputElement extends UUIFormControlMixin(UmbLitElement, '') #btn-add { width: 100%; } - - umb-user-avatar { - font-size: var(--uui-size-4); - } `, ]; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/item/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/item/manifests.ts new file mode 100644 index 000000000000..460383ab2103 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/item/manifests.ts @@ -0,0 +1,11 @@ +import { UMB_USER_ENTITY_TYPE } from '../entity.js'; + +export const manifests: Array = [ + { + type: 'entityItemRef', + alias: 'Umb.EntityItemRef.User', + name: 'User Entity Item Reference', + element: () => import('./user-item-ref.element.js'), + forEntityTypes: [UMB_USER_ENTITY_TYPE], + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts new file mode 100644 index 000000000000..2310f1fbe5bd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts @@ -0,0 +1,68 @@ +import { UMB_USER_ENTITY_TYPE } from '../entity.js'; +import type { UmbUserItemModel } from '../repository/index.js'; +import { css, customElement, html, nothing, property } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; +import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; + +@customElement('umb-user-item-ref') +export class UmbDocumentItemRefElement extends UmbLitElement { + @property({ type: Object }) + item?: UmbUserItemModel; + + @property({ type: Boolean }) + readonly = false; + + @property({ type: Boolean }) + standalone = false; + + _editPath = ''; + + constructor() { + super(); + + new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath(UMB_USER_ENTITY_TYPE) + .onSetup(() => { + return { data: { entityType: UMB_USER_ENTITY_TYPE, preset: {} } }; + }) + .observeRouteBuilder((routeBuilder) => { + this._editPath = routeBuilder({}); + }); + } + + #getHref(item: UmbUserItemModel) { + return `${this._editPath}/edit/${item.unique}`; + } + + override render() { + if (!this.item) return nothing; + + return html` + + + + + `; + } + + static override styles = [ + css` + umb-user-avatar { + font-size: var(--uui-size-4); + } + `, + ]; +} + +export { UmbDocumentItemRefElement as element }; + +declare global { + interface HTMLElementTagNameMap { + 'umb-document-item-ref': UmbDocumentItemRefElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/manifests.ts index 29df08be7c9e..d3f0e2d96ee1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/manifests.ts @@ -4,11 +4,13 @@ import { manifests as conditionsManifests } from './conditions/manifests.js'; import { manifests as entityActionsManifests } from './entity-actions/manifests.js'; import { manifests as entityBulkActionManifests } from './entity-bulk-actions/manifests.js'; import { manifests as inviteManifests } from './invite/manifests.js'; +import { manifests as itemManifests } from './item/manifests.js'; +import { manifests as menuItemManifests } from './menu-item/manifests.js'; import { manifests as modalManifests } from './modals/manifests.js'; import { manifests as propertyEditorManifests } from './property-editor/manifests.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; import { manifests as workspaceManifests } from './workspace/manifests.js'; -import { manifests as menuItemManifests } from './menu-item/manifests.js'; + import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; export const manifests: Array = [ @@ -18,9 +20,10 @@ export const manifests: Array = ...entityActionsManifests, ...entityBulkActionManifests, ...inviteManifests, + ...itemManifests, + ...menuItemManifests, ...modalManifests, ...propertyEditorManifests, ...repositoryManifests, ...workspaceManifests, - ...menuItemManifests, ]; From db9b9d344156a8cf5f6a75b6438e5eba74033939 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 7 Feb 2025 14:19:24 +0100 Subject: [PATCH 019/145] pass readonly and standalone props --- .../entity-item-ref.element.ts | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts index bd2befeae60d..08ab638191eb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts @@ -12,7 +12,7 @@ export class UmbEntityItemRefElement extends UmbLitElement { #item?: UmbEntityModel; @state() - _component?: HTMLElement; + _component?: any; // TODO: Add type @property({ type: Object, attribute: false }) public get item(): UmbEntityModel | undefined { @@ -24,6 +24,32 @@ export class UmbEntityItemRefElement extends UmbLitElement { this.#createController(value.entityType); } + #readonly = false; + @property({ type: Boolean, attribute: 'readonly' }) + public get readonly() { + return this.#readonly; + } + public set readonly(value) { + this.#readonly = value; + + if (this._component) { + this._component.readonly = this.#readonly; + } + } + + #standalone = false; + @property({ type: Boolean, attribute: 'standalone' }) + public get standalone() { + return this.#standalone; + } + public set standalone(value) { + this.#standalone = value; + + if (this._component) { + this._component.standalone = this.#standalone; + } + } + protected override firstUpdated(_changedProperties: PropertyValueMap | Map): void { super.firstUpdated(_changedProperties); this.setAttribute(UMB_MARK_ATTRIBUTE_NAME, 'entity-item-ref'); @@ -47,8 +73,10 @@ export class UmbEntityItemRefElement extends UmbLitElement { return; } - // assign the item to the component + // assign the properties to the component component.item = this.#item; + component.readonly = this.readonly; + component.standalone = this.standalone; // Proxy the actions slot to the component const slotElement = document.createElement('slot'); From 1088b04948102b3405263e2eeef610933592afca Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 7 Feb 2025 14:32:48 +0100 Subject: [PATCH 020/145] make editPath a state --- .../documents/item/document-item-ref.element.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index 94eff8be1227..4cf8c09e0323 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -1,6 +1,15 @@ import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; import type { UmbDocumentItemModel } from './types.js'; -import { classMap, css, customElement, html, ifDefined, nothing, property } from '@umbraco-cms/backoffice/external/lit'; +import { + classMap, + css, + customElement, + html, + ifDefined, + nothing, + property, + state, +} from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; @@ -16,6 +25,7 @@ export class UmbDocumentItemRefElement extends UmbLitElement { @property({ type: Boolean }) standalone = false; + @state() _editPath = ''; constructor() { From d70fb9581ae659b1bc08a349ca4e208ec5981067 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 7 Feb 2025 14:33:59 +0100 Subject: [PATCH 021/145] Update member-item-ref.element.ts --- .../packages/members/member/item/member-item-ref.element.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts index 766c52cb4258..06b371d38b21 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts @@ -1,6 +1,6 @@ import { UMB_MEMBER_ENTITY_TYPE } from '../entity.js'; import type { UmbMemberItemModel } from './repository/types.js'; -import { customElement, html, ifDefined, nothing, property } from '@umbraco-cms/backoffice/external/lit'; +import { customElement, html, ifDefined, nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; @@ -16,6 +16,7 @@ export class UmbMemberItemRefElement extends UmbLitElement { @property({ type: Boolean }) standalone = false; + @state() _editPath = ''; constructor() { From 914953b3ee0f3a64cb78e7c53f9cb713af99166e Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 7 Feb 2025 14:54:48 +0100 Subject: [PATCH 022/145] Fix user item ref --- .../core/picker-input/picker-input.context.ts | 2 +- .../user/user/item/user-item-ref.element.ts | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context.ts index 385671b75d89..7660af190cc4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context.ts @@ -1,3 +1,4 @@ +import { UMB_PICKER_INPUT_CONTEXT } from './picker-input.context-token.js'; import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; import { UmbRepositoryItemsManager } from '@umbraco-cms/backoffice/repository'; @@ -6,7 +7,6 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; import type { UmbModalToken, UmbPickerModalData, UmbPickerModalValue } from '@umbraco-cms/backoffice/modal'; import { UmbDeprecation } from '@umbraco-cms/backoffice/utils'; -import { UMB_PICKER_INPUT_CONTEXT } from './picker-input.context-token'; type PickerItemBaseType = { name: string; unique: string }; export class UmbPickerInputContext< diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts index 2310f1fbe5bd..cdc15ce43263 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts @@ -1,12 +1,12 @@ import { UMB_USER_ENTITY_TYPE } from '../entity.js'; import type { UmbUserItemModel } from '../repository/index.js'; -import { css, customElement, html, nothing, property } from '@umbraco-cms/backoffice/external/lit'; +import { css, customElement, html, nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; @customElement('umb-user-item-ref') -export class UmbDocumentItemRefElement extends UmbLitElement { +export class UmbUserItemRefElement extends UmbLitElement { @property({ type: Object }) item?: UmbUserItemModel; @@ -16,6 +16,7 @@ export class UmbDocumentItemRefElement extends UmbLitElement { @property({ type: Boolean }) standalone = false; + @state() _editPath = ''; constructor() { @@ -39,7 +40,11 @@ export class UmbDocumentItemRefElement extends UmbLitElement { if (!this.item) return nothing; return html` - + Date: Fri, 7 Feb 2025 14:57:04 +0100 Subject: [PATCH 023/145] remove open button --- .../input-member/input-member.element.ts | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts index d01b47536409..ba3d18dc69b4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts @@ -82,9 +82,6 @@ export class UmbInputMemberElement extends UmbFormControlMixin - - ${this.#renderOpenButton(item)} ${this.#renderRemoveButton(item)} - + ${this.#renderRemoveButton(item)} `; } @@ -209,17 +204,6 @@ export class UmbInputMemberElement extends UmbFormControlMixin - ${this.localize.term('general_open')} - - `; - } - #renderRemoveButton(item: UmbMemberItemModel) { if (this.readonly) return nothing; return html` From efe75be3d7ce008512a024e45ba4a76c3957e3ca Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 7 Feb 2025 21:48:38 +0100 Subject: [PATCH 024/145] remove unused --- .../member/components/input-member/input-member.element.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts index ba3d18dc69b4..f1a29cb80bf2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts @@ -7,6 +7,10 @@ import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbSorterController } from '@umbraco-cms/backoffice/sorter'; import { UMB_MEMBER_TYPE_ENTITY_TYPE } from '@umbraco-cms/backoffice/member-type'; +import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user'; +import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; +import { UMB_SECTION_USER_PERMISSION_CONDITION_ALIAS } from '@umbraco-cms/backoffice/section'; +import { UMB_MEMBER_MANAGEMENT_SECTION_ALIAS } from 'src/packages/members/section/constants.js'; @customElement('umb-input-member') export class UmbInputMemberElement extends UmbFormControlMixin( @@ -117,9 +121,6 @@ export class UmbInputMemberElement extends UmbFormControlMixin; From 33f37591d88d5500d1ddb87d804ffd4a967919f6 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sat, 8 Feb 2025 19:32:45 +0100 Subject: [PATCH 025/145] remove unused --- .../member/components/input-member/input-member.element.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts index f1a29cb80bf2..0d903b5dee7c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/components/input-member/input-member.element.ts @@ -7,10 +7,6 @@ import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbSorterController } from '@umbraco-cms/backoffice/sorter'; import { UMB_MEMBER_TYPE_ENTITY_TYPE } from '@umbraco-cms/backoffice/member-type'; -import { UMB_CURRENT_USER_CONTEXT } from '@umbraco-cms/backoffice/current-user'; -import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; -import { UMB_SECTION_USER_PERMISSION_CONDITION_ALIAS } from '@umbraco-cms/backoffice/section'; -import { UMB_MEMBER_MANAGEMENT_SECTION_ALIAS } from 'src/packages/members/section/constants.js'; @customElement('umb-input-member') export class UmbInputMemberElement extends UmbFormControlMixin( From 95c12ec778f48749bc3188ff32a76dee7361d879 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sat, 8 Feb 2025 19:33:06 +0100 Subject: [PATCH 026/145] check for section permission --- .../member/item/member-item-ref.element.ts | 19 ++++++++++++++++++- .../user/user/item/user-item-ref.element.ts | 19 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts index 06b371d38b21..86820fe1d950 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts @@ -1,8 +1,11 @@ import { UMB_MEMBER_ENTITY_TYPE } from '../entity.js'; +import { UMB_MEMBER_MANAGEMENT_SECTION_ALIAS } from '../../section/constants.js'; import type { UmbMemberItemModel } from './repository/types.js'; +import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; import { customElement, html, ifDefined, nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; +import { UMB_SECTION_USER_PERMISSION_CONDITION_ALIAS } from '@umbraco-cms/backoffice/section'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; @customElement('umb-member-item-ref') @@ -19,9 +22,23 @@ export class UmbMemberItemRefElement extends UmbLitElement { @state() _editPath = ''; + @state() + _userHasSectionAccess = false; + constructor() { super(); + createExtensionApiByAlias(this, UMB_SECTION_USER_PERMISSION_CONDITION_ALIAS, [ + { + config: { + match: UMB_MEMBER_MANAGEMENT_SECTION_ALIAS, + }, + onChange: (permitted: boolean) => { + this._userHasSectionAccess = permitted; + }, + }, + ]); + new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) .addAdditionalPath(UMB_MEMBER_ENTITY_TYPE) .onSetup(() => { @@ -44,7 +61,7 @@ export class UmbMemberItemRefElement extends UmbLitElement { id=${this.item.unique} name=${this.item.name} href=${ifDefined(this.#getHref(this.item))} - ?readonly=${this.readonly} + ?readonly=${this.readonly || !this._userHasSectionAccess} ?standalone=${this.standalone}> ${this.#renderIcon(this.item)} diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts index cdc15ce43263..3001d17fc85f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts @@ -3,7 +3,10 @@ import type { UmbUserItemModel } from '../repository/index.js'; import { css, customElement, html, nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; +import { UMB_SECTION_USER_PERMISSION_CONDITION_ALIAS } from '@umbraco-cms/backoffice/section'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; +import { UMB_USER_MANAGEMENT_SECTION_ALIAS } from '../../section/constants.js'; +import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; @customElement('umb-user-item-ref') export class UmbUserItemRefElement extends UmbLitElement { @@ -19,9 +22,23 @@ export class UmbUserItemRefElement extends UmbLitElement { @state() _editPath = ''; + @state() + _userHasSectionAccess = false; + constructor() { super(); + createExtensionApiByAlias(this, UMB_SECTION_USER_PERMISSION_CONDITION_ALIAS, [ + { + config: { + match: UMB_USER_MANAGEMENT_SECTION_ALIAS, + }, + onChange: (permitted: boolean) => { + this._userHasSectionAccess = permitted; + }, + }, + ]); + new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) .addAdditionalPath(UMB_USER_ENTITY_TYPE) .onSetup(() => { @@ -43,7 +60,7 @@ export class UmbUserItemRefElement extends UmbLitElement { Date: Sun, 9 Feb 2025 19:54:24 +0100 Subject: [PATCH 027/145] add null check --- .../documents/documents/item/document-item-ref.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index 4cf8c09e0323..af740cfac30c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -42,7 +42,7 @@ export class UmbDocumentItemRefElement extends UmbLitElement { } #isDraft(item: UmbDocumentItemModel) { - return item.variants[0]?.state === 'Draft'; + return item.variants?.[0]?.state === 'Draft'; } #getHref(item: UmbDocumentItemModel) { From 93aa0ea16f8209dbf8a438ff8a5d697d9aa92c07 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 9 Feb 2025 19:54:54 +0100 Subject: [PATCH 028/145] change to use entity-item-ref element --- .../entity-action/trash/modal/trash-confirm-modal.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts index 943465a01f81..79196b7be4de 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts @@ -107,7 +107,7 @@ export class UmbTrashConfirmModalElement extends UmbLitElement { return html`
${this.localize.term('references_labelDependsOnThis')}
- ${this._referencedBy.map((reference) => html` `)} + ${this._referencedBy.map((reference) => html` `)} ${this._totalReferencedBy > 5 ? html`${this.localize.term('references_labelMoreReferences', this._totalReferencedBy - 5)}` From dbd27cc0b64b9d359f1306bbf095db2fddbad220 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 9 Feb 2025 19:55:21 +0100 Subject: [PATCH 029/145] register media item ref --- .../packages/media/media/item/manifests.ts | 11 +++ .../media/item/media-item-ref.element.ts | 74 +++++++++++++++++++ .../src/packages/media/media/manifests.ts | 2 + 3 files changed, 87 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/media/media/item/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/manifests.ts new file mode 100644 index 000000000000..fe40fdf4416d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/manifests.ts @@ -0,0 +1,11 @@ +import { UMB_MEDIA_ENTITY_TYPE } from '../entity.js'; + +export const manifests: Array = [ + { + type: 'entityItemRef', + alias: 'Umb.EntityItemRef.Media', + name: 'Media Entity Item Reference', + element: () => import('./media-item-ref.element.js'), + forEntityTypes: [UMB_MEDIA_ENTITY_TYPE], + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts new file mode 100644 index 000000000000..a3b85e52d062 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts @@ -0,0 +1,74 @@ +import { UMB_MEDIA_ENTITY_TYPE } from '../entity.js'; +import type { UmbMediaItemModel } from '../types.js'; +import { customElement, html, ifDefined, nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; +import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; + +@customElement('umb-media-item-ref') +export class UmbMediaItemRefElement extends UmbLitElement { + @property({ type: Object }) + item?: UmbMediaItemModel; + + @property({ type: Boolean }) + readonly = false; + + @property({ type: Boolean }) + standalone = false; + + @state() + _editPath = ''; + + constructor() { + super(); + + new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath(UMB_MEDIA_ENTITY_TYPE) + .onSetup(() => { + return { data: { entityType: UMB_MEDIA_ENTITY_TYPE, preset: {} } }; + }) + .observeRouteBuilder((routeBuilder) => { + this._editPath = routeBuilder({}); + }); + } + + #getHref(item: UmbMediaItemModel) { + return `${this._editPath}/edit/${item.unique}`; + } + + override render() { + if (!this.item) return nothing; + + return html` + + + ${this.#renderIcon(this.item)} ${this.#renderIsTrashed(this.item)} + + `; + } + + #renderIcon(item: UmbMediaItemModel) { + if (!item.mediaType.icon) return; + return html``; + } + + #renderIsTrashed(item: UmbMediaItemModel) { + if (!item.isTrashed) return; + return html`Trashed`; + } + + static override styles = []; +} + +export { UmbMediaItemRefElement as element }; + +declare global { + interface HTMLElementTagNameMap { + 'umb-media-item-ref': UmbMediaItemRefElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/manifests.ts index 1b61cda60755..69738473e5f2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/manifests.ts @@ -4,6 +4,7 @@ import { manifests as dropzoneManifests } from './dropzone/manifests.js'; import { manifests as entityActionsManifests } from './entity-actions/manifests.js'; import { manifests as entityBulkActionsManifests } from './entity-bulk-actions/manifests.js'; import { manifests as fileUploadPreviewManifests } from './components/input-upload-field/manifests.js'; +import { manifests as itemManifests } from './item/manifests.js'; import { manifests as menuManifests } from './menu/manifests.js'; import { manifests as modalManifests } from './modals/manifests.js'; import { manifests as propertyEditorsManifests } from './property-editors/manifests.js'; @@ -23,6 +24,7 @@ export const manifests: Array = [ ...entityActionsManifests, ...entityBulkActionsManifests, ...fileUploadPreviewManifests, + ...itemManifests, ...menuManifests, ...modalManifests, ...propertyEditorsManifests, From 0afe46c04db159340b5c8f947edaeb84c00a9ff6 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 10 Feb 2025 10:51:20 +0100 Subject: [PATCH 030/145] add fallback element --- .../default-item-ref.element.ts | 37 +++++++++++++++++++ .../entity-item-ref.element.ts | 10 ++--- .../src/packages/core/entity/types.ts | 4 ++ 3 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/default-item-ref.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/default-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/default-item-ref.element.ts new file mode 100644 index 000000000000..25c32cafd65a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/default-item-ref.element.ts @@ -0,0 +1,37 @@ +import type { UmbDefaultItemModel } from '../types.js'; +import { customElement, html, nothing, property } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; + +@customElement('umb-default-item-ref') +export class UmbDefaultItemRefElement extends UmbLitElement { + @property({ type: Object }) + item?: UmbDefaultItemModel; + + @property({ type: Boolean }) + readonly = false; + + @property({ type: Boolean }) + standalone = false; + + override render() { + if (!this.item) return nothing; + + return html` + + + ${this.#renderIcon(this.item)} + + `; + } + + #renderIcon(item: UmbDefaultItemModel) { + if (!item.icon) return; + return html``; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'umb-default-item-ref': UmbDefaultItemRefElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts index 08ab638191eb..f78da6baa2f6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts @@ -6,6 +6,8 @@ import { UmbExtensionsElementInitializer } from '@umbraco-cms/backoffice/extensi import { UMB_MARK_ATTRIBUTE_NAME } from '@umbraco-cms/backoffice/const'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; +import './default-item-ref.element.js'; + @customElement('umb-entity-item-ref') export class UmbEntityItemRefElement extends UmbLitElement { #extensionsController?: UmbExtensionsElementInitializer; @@ -66,12 +68,8 @@ export class UmbEntityItemRefElement extends UmbLitElement { 'entityItemRef', (manifest: ManifestEntityItemRef) => manifest.forEntityTypes.includes(entityType), (extensionControllers) => { - const component = extensionControllers[0]?.component; - - if (!component) { - this._component?.remove(); - return; - } + this._component?.remove(); + const component = extensionControllers[0]?.component || document.createElement('umb-default-item-ref'); // assign the properties to the component component.item = this.#item; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/types.ts index f2fcb7dde994..09ec5529e207 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/types.ts @@ -8,3 +8,7 @@ export interface UmbEntityModel { export interface UmbNamedEntityModel extends UmbEntityModel { name: string; } + +export interface UmbDefaultItemModel extends UmbNamedEntityModel { + icon?: string; +} From 4394db3cce7b3c58aaaef3494ccd1b600fb45541 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 10 Feb 2025 11:31:58 +0100 Subject: [PATCH 031/145] show 3 references --- .../modal/trash-confirm-modal.element.ts | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts index 79196b7be4de..83382c3fdf38 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts @@ -41,6 +41,8 @@ export class UmbTrashConfirmModalElement extends UmbLitElement { #itemRepository?: UmbItemRepository; #referenceRepository?: any; + #limitReferencedBy = 3; + constructor() { super(); this.#initData(); @@ -73,7 +75,11 @@ export class UmbTrashConfirmModalElement extends UmbLitElement { this.#referenceRepository = await createExtensionApiByAlias(this, this._data.referenceRepositoryAlias); - const { data: referencesData } = await this.#referenceRepository.requestReferencedBy(this._data.unique, 0, 5); + const { data: referencesData } = await this.#referenceRepository.requestReferencedBy( + this._data.unique, + 0, + this.#limitReferencedBy, + ); if (referencesData) { this._referencedBy = [...referencesData.items]; @@ -107,10 +113,17 @@ export class UmbTrashConfirmModalElement extends UmbLitElement { return html`
${this.localize.term('references_labelDependsOnThis')}
- ${this._referencedBy.map((reference) => html` `)} + ${this._referencedBy.map( + (reference) => html` `, + )} - ${this._totalReferencedBy > 5 - ? html`${this.localize.term('references_labelMoreReferences', this._totalReferencedBy - 5)}` + ${this._totalReferencedBy > this.#limitReferencedBy + ? html`${this.localize.term( + 'references_labelMoreReferences', + this._totalReferencedBy - this.#limitReferencedBy, + )}` : nothing} `; } From 4ffa3d6130dd161122877dd66c1ef5ede176984f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 10 Feb 2025 15:00:34 +0100 Subject: [PATCH 032/145] wip data mapper concept --- .../data-mapper/data-mapper-resolver.ts | 59 +++++++++++++++++++ .../data-mapper/data-mapper.extension.ts | 19 ++++++ .../core/repository/data-mapper/index.ts | 1 + .../core/repository/data-mapper/types.ts | 13 ++++ .../src/packages/core/repository/index.ts | 1 + .../src/packages/core/repository/types.ts | 2 + ...ocument-reference-response-model.mapper.ts | 27 +++++++++ .../document-reference.server.data.ts | 30 ++++++++-- .../reference/repository/manifests.ts | 7 +++ .../documents/documents/reference/types.ts | 26 ++++++++ .../media/reference/repository/manifests.ts | 7 +++ .../media-reference-response-model.mapper.ts | 26 ++++++++ .../media/media/reference/repository/types.ts | 26 ++++++++ 13 files changed, 238 insertions(+), 6 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper-resolver.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.extension.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/types.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response-model.mapper.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/types.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response-model.mapper.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper-resolver.ts new file mode 100644 index 000000000000..50ffcfc95d9c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper-resolver.ts @@ -0,0 +1,59 @@ +import type { UmbDataMapper } from './types.js'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import { createExtensionApi, type ManifestBase } from '@umbraco-cms/backoffice/extension-api'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; + +export class UmbDataMapperResolver extends UmbControllerBase { + #apiCache = new Map(); + + async resolve($type: string): Promise { + if (!$type) { + throw new Error('data is required'); + } + + const manifest = this.#getManifestWithBestFit($type); + + if (!manifest) { + return undefined; + } + + // Check the cache before creating a new instance + if (this.#apiCache.has(manifest.alias)) { + return this.#apiCache.get(manifest.alias)!; + } + + const dataMapper = await createExtensionApi(this, manifest); + + if (!dataMapper) { + return undefined; + } + + if (!dataMapper.map) { + throw new Error('Data Mapper does not have a map method.'); + } + + // Cache the api instance for future use + this.#apiCache.set(manifest.alias, dataMapper); + + return dataMapper; + } + + #getManifestWithBestFit($type: string) { + const supportedManifests = this.#getSupportedManifests($type); + + if (!supportedManifests.length) { + return undefined; + } + + // Pick the manifest with the highest priority + return supportedManifests.sort((a: ManifestBase, b: ManifestBase): number => (b.weight || 0) - (a.weight || 0))[0]; + } + + #getSupportedManifests($type: string) { + const supportedManifests = umbExtensionsRegistry.getByTypeAndFilter('$typeDataMapper', (manifest) => { + return manifest.from$type === $type; + }); + + return supportedManifests; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.extension.ts new file mode 100644 index 000000000000..0db57c414642 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.extension.ts @@ -0,0 +1,19 @@ +import type { UmbDataMapper } from './types.js'; +import type { ManifestApi, ManifestWithDynamicConditions } from '@umbraco-cms/backoffice/extension-api'; + +export interface Manifest$TypeDataMapper + extends ManifestApi, + ManifestWithDynamicConditions { + type: '$typeDataMapper'; + meta: MetaType; + from$type: string; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +export interface MetaDataMapper {} + +declare global { + interface UmbExtensionManifestMap { + umbManifest$TypeDataMapper: Manifest$TypeDataMapper; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts new file mode 100644 index 000000000000..843267ab4e42 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts @@ -0,0 +1 @@ +export * from './data-mapper-resolver.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/types.ts new file mode 100644 index 000000000000..ce10076c8472 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/types.ts @@ -0,0 +1,13 @@ +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; + +export interface UmbServerResponseModel { + $type: string; +} + +export interface UmbDataMapper< + ServerModelType extends UmbServerResponseModel = UmbServerResponseModel, + ClientModelType extends UmbEntityModel = UmbEntityModel, +> extends UmbApi { + map: (data: ServerModelType) => Promise; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/index.ts index 3d2bf2606a84..10f104e3c0a0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/index.ts @@ -3,6 +3,7 @@ export * from './repository-base.js'; export * from './item/index.js'; export * from './detail/index.js'; +export * from './data-mapper/index.js'; export type { UmbDataSourceResponse, UmbDataSourceErrorResponse } from './data-source-response.interface.js'; export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/types.ts index 958077f2aa01..5fb70c396d95 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/types.ts @@ -14,3 +14,5 @@ export interface UmbRepositoryErrorResponse extends UmbDataSourceErrorResponse { export interface UmbRepositoryResponseWithAsObservable extends UmbRepositoryResponse { asObservable: () => Observable; } + +export type * from './data-mapper/types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response-model.mapper.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response-model.mapper.ts new file mode 100644 index 000000000000..c81010b443e8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response-model.mapper.ts @@ -0,0 +1,27 @@ +import type { UmbDocumentReferenceModel } from '../types.js'; +import { UMB_DOCUMENT_ENTITY_TYPE } from '../../entity.js'; +import type { DocumentReferenceResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbDataMapper } from '@umbraco-cms/backoffice/repository'; + +export class UmbDocumentReferenceResponseModelMapper + extends UmbControllerBase + implements UmbDataMapper +{ + async map(data: DocumentReferenceResponseModel): Promise { + return { + documentType: { + alias: data.documentType.alias, + icon: data.documentType.icon, + name: data.documentType.name, + }, + entityType: UMB_DOCUMENT_ENTITY_TYPE, + id: data.id, + name: data.name, + published: data.published, + unique: data.id, + }; + } +} + +export { UmbDocumentReferenceResponseModelMapper as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts index 13a7b725a5fe..795de9f54ecd 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts @@ -1,13 +1,15 @@ import { DocumentService } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import { UmbDataMapperResolver } from '@umbraco-cms/backoffice/repository'; /** * @class UmbDocumentReferenceServerDataSource * @implements {RepositoryDetailDataSource} */ -export class UmbDocumentReferenceServerDataSource { - #host: UmbControllerHost; +export class UmbDocumentReferenceServerDataSource extends UmbControllerBase { + #dataMapperResolver = new UmbDataMapperResolver(this); /** * Creates an instance of UmbDocumentReferenceServerDataSource. @@ -15,16 +17,32 @@ export class UmbDocumentReferenceServerDataSource { * @memberof UmbDocumentReferenceServerDataSource */ constructor(host: UmbControllerHost) { - this.#host = host; + super(host); } /** * Fetches the item for the given unique from the server - * @param {string} id + * @param {string} unique * @returns {*} * @memberof UmbDocumentReferenceServerDataSource */ - async getReferencedBy(id: string, skip = 0, take = 20) { - return await tryExecuteAndNotify(this.#host, DocumentService.getDocumentByIdReferencedBy({ id, skip, take })); + async getReferencedBy(unique: string, skip = 0, take = 20) { + const { data, error } = await tryExecuteAndNotify( + this, + DocumentService.getDocumentByIdReferencedBy({ id: unique, skip, take }), + ); + + if (data) { + const promises = data.items.map(async (item) => { + const mapper = await this.#dataMapperResolver.resolve(item.$type); + return mapper ? mapper.map(item) : item; + }); + + const items = await Promise.all(promises); + + return { data: { items, total: data.total } }; + } + + return { data, error }; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts index 0527cc53bcc8..5fab41096a80 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts @@ -7,4 +7,11 @@ export const manifests: Array = [ name: 'Document Reference Repository', api: () => import('./document-reference.repository.js'), }, + { + type: '$typeDataMapper', + alias: 'Umb.$typeDataMapper.DocumentReferenceResponseModel', + name: 'Document Reference Response Model to Client Model Data Mapper', + api: () => import('./document-reference-response-model.mapper.js'), + from$type: 'DocumentReferenceResponseModel', + }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/types.ts new file mode 100644 index 000000000000..dde29a3f23bb --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/types.ts @@ -0,0 +1,26 @@ +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import type { TrackedReferenceDocumentTypeModel } from '@umbraco-cms/backoffice/external/backend-api'; + +export interface UmbDocumentReferenceModel extends UmbEntityModel { + /** + * @deprecated use unique instead + * @type {string} + * @memberof UmbDocumentReferenceModel + */ + id: string; + + /** + * @deprecated use name on the variant array instead + * @type {(string | null)} + * @memberof UmbDocumentReferenceModel + */ + name?: string | null; + + /** + * @deprecated use state on variant array instead + * @type {boolean} + * @memberof UmbDocumentReferenceModel + */ + published?: boolean | null; + documentType: TrackedReferenceDocumentTypeModel; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts index 6981b551522d..e53d4bebb6dc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts @@ -7,4 +7,11 @@ export const manifests: Array = [ name: 'Media Reference Repository', api: () => import('./media-reference.repository.js'), }, + { + type: '$typeDataMapper', + alias: 'Umb.$typeDataMapper.MediaReferenceResponseModel', + name: 'Media Reference Response Model to Client Model Data Mapper', + api: () => import('./media-reference-response-model.mapper.js'), + from$type: 'MediaReferenceResponseModel', + }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response-model.mapper.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response-model.mapper.ts new file mode 100644 index 000000000000..2fe4c99adc33 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response-model.mapper.ts @@ -0,0 +1,26 @@ +import { UMB_MEDIA_ENTITY_TYPE } from '../../entity.js'; +import type { UmbMediaReferenceModel } from './types.js'; +import type { MediaReferenceResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbDataMapper } from '@umbraco-cms/backoffice/repository'; + +export class UmbMediaReferenceResponseModelMapper + extends UmbControllerBase + implements UmbDataMapper +{ + async map(data: MediaReferenceResponseModel): Promise { + return { + entityType: UMB_MEDIA_ENTITY_TYPE, + id: data.id, + mediaType: { + alias: data.mediaType.alias, + icon: data.mediaType.icon, + name: data.mediaType.name, + }, + name: data.name, + unique: data.id, + }; + } +} + +export { UmbMediaReferenceResponseModelMapper as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/types.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/types.ts new file mode 100644 index 000000000000..02ae250ed881 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/types.ts @@ -0,0 +1,26 @@ +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import type { TrackedReferenceMediaTypeModel } from '@umbraco-cms/backoffice/external/backend-api'; + +export interface UmbMediaReferenceModel extends UmbEntityModel { + /** + * @deprecated use unique instead + * @type {string} + * @memberof UmbMediaReferenceModel + */ + id: string; + + /** + * @deprecated use name on the variant array instead + * @type {(string | null)} + * @memberof UmbMediaReferenceModel + */ + name?: string | null; + + /** + * @deprecated use state on variant array instead + * @type {boolean} + * @memberof UmbMediaReferenceModel + */ + published?: boolean | null; + mediaType: TrackedReferenceMediaTypeModel; +} From fa491109f1eb0191885ebf7b1992016a386f086d Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 09:36:55 +0100 Subject: [PATCH 033/145] add unique to modal route registration --- .../item/document-item-ref.element.ts | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index 4cf8c09e0323..fb887e6ee225 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -16,8 +16,29 @@ import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; @customElement('umb-document-item-ref') export class UmbDocumentItemRefElement extends UmbLitElement { + #item?: UmbDocumentItemModel | undefined; + @property({ type: Object }) - item?: UmbDocumentItemModel; + public get item(): UmbDocumentItemModel | undefined { + return this.#item; + } + public set item(value: UmbDocumentItemModel | undefined) { + this.#item = value; + + if (!this.#item) { + this.#modalRoute?.destroy(); + return; + } + + this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath(UMB_DOCUMENT_ENTITY_TYPE + '/' + this.#item.unique) + .onSetup(() => { + return { data: { entityType: UMB_DOCUMENT_ENTITY_TYPE, preset: {} } }; + }) + .observeRouteBuilder((routeBuilder) => { + this._editPath = routeBuilder({}); + }); + } @property({ type: Boolean }) readonly = false; @@ -28,18 +49,7 @@ export class UmbDocumentItemRefElement extends UmbLitElement { @state() _editPath = ''; - constructor() { - super(); - - new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath(UMB_DOCUMENT_ENTITY_TYPE) - .onSetup(() => { - return { data: { entityType: UMB_DOCUMENT_ENTITY_TYPE, preset: {} } }; - }) - .observeRouteBuilder((routeBuilder) => { - this._editPath = routeBuilder({}); - }); - } + #modalRoute?: any; #isDraft(item: UmbDocumentItemModel) { return item.variants[0]?.state === 'Draft'; From a76b30a93a31ff5814a1a7606f1dd5195bc4c6d6 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 09:53:09 +0100 Subject: [PATCH 034/145] add unique to modal router --- .../member/item/member-item-ref.element.ts | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts index 86820fe1d950..4a4d6a3e0ec3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts @@ -10,8 +10,29 @@ import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; @customElement('umb-member-item-ref') export class UmbMemberItemRefElement extends UmbLitElement { + #item?: UmbMemberItemModel | undefined; + @property({ type: Object }) - item?: UmbMemberItemModel; + public get item(): UmbMemberItemModel | undefined { + return this.#item; + } + public set item(value: UmbMemberItemModel | undefined) { + this.#item = value; + + if (!this.#item) { + this.#modalRoute?.destroy(); + return; + } + + this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath(UMB_MEMBER_ENTITY_TYPE + '/' + this.#item.unique) + .onSetup(() => { + return { data: { entityType: UMB_MEMBER_ENTITY_TYPE, preset: {} } }; + }) + .observeRouteBuilder((routeBuilder) => { + this._editPath = routeBuilder({}); + }); + } @property({ type: Boolean }) readonly = false; @@ -25,6 +46,8 @@ export class UmbMemberItemRefElement extends UmbLitElement { @state() _userHasSectionAccess = false; + #modalRoute?: any; + constructor() { super(); @@ -58,7 +81,6 @@ export class UmbMemberItemRefElement extends UmbLitElement { return html` Date: Tue, 11 Feb 2025 09:53:20 +0100 Subject: [PATCH 035/145] remove unused id --- .../documents/documents/item/document-item-ref.element.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index fb887e6ee225..92a3b407d3c3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -64,7 +64,6 @@ export class UmbDocumentItemRefElement extends UmbLitElement { return html` Date: Tue, 11 Feb 2025 09:54:02 +0100 Subject: [PATCH 036/145] Update member-item-ref.element.ts --- .../members/member/item/member-item-ref.element.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts index 4a4d6a3e0ec3..e78166e64c1a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts @@ -61,15 +61,6 @@ export class UmbMemberItemRefElement extends UmbLitElement { }, }, ]); - - new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath(UMB_MEMBER_ENTITY_TYPE) - .onSetup(() => { - return { data: { entityType: UMB_MEMBER_ENTITY_TYPE, preset: {} } }; - }) - .observeRouteBuilder((routeBuilder) => { - this._editPath = routeBuilder({}); - }); } #getHref(item: UmbMemberItemModel) { From 13d5feaf3092d2e811027eeafad015ec2ec4c391 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 10:03:15 +0100 Subject: [PATCH 037/145] append unique --- .../user/user/item/user-item-ref.element.ts | 39 +++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts index 3001d17fc85f..6e3aa9be9436 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts @@ -1,17 +1,41 @@ import { UMB_USER_ENTITY_TYPE } from '../entity.js'; import type { UmbUserItemModel } from '../repository/index.js'; +import { UMB_USER_MANAGEMENT_SECTION_ALIAS } from '../../section/constants.js'; import { css, customElement, html, nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UMB_SECTION_USER_PERMISSION_CONDITION_ALIAS } from '@umbraco-cms/backoffice/section'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; -import { UMB_USER_MANAGEMENT_SECTION_ALIAS } from '../../section/constants.js'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; @customElement('umb-user-item-ref') export class UmbUserItemRefElement extends UmbLitElement { + #item?: UmbUserItemModel | undefined; + @property({ type: Object }) - item?: UmbUserItemModel; + public get item(): UmbUserItemModel | undefined { + return this.#item; + } + public set item(value: UmbUserItemModel | undefined) { + const oldValue = this.#item; + this.#item = value; + + if (!this.#item) { + this.#modalRoute?.destroy(); + return; + } + + if (oldValue?.unique !== this.#item.unique) { + this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath(UMB_USER_ENTITY_TYPE + '/' + this.#item.unique) + .onSetup(() => { + return { data: { entityType: UMB_USER_ENTITY_TYPE, preset: {} } }; + }) + .observeRouteBuilder((routeBuilder) => { + this._editPath = routeBuilder({}); + }); + } + } @property({ type: Boolean }) readonly = false; @@ -25,6 +49,8 @@ export class UmbUserItemRefElement extends UmbLitElement { @state() _userHasSectionAccess = false; + #modalRoute?: any; + constructor() { super(); @@ -38,15 +64,6 @@ export class UmbUserItemRefElement extends UmbLitElement { }, }, ]); - - new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath(UMB_USER_ENTITY_TYPE) - .onSetup(() => { - return { data: { entityType: UMB_USER_ENTITY_TYPE, preset: {} } }; - }) - .observeRouteBuilder((routeBuilder) => { - this._editPath = routeBuilder({}); - }); } #getHref(item: UmbUserItemModel) { From 494fcbe025bc00ed76f06263806d881e94806b55 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 10:03:26 +0100 Subject: [PATCH 038/145] compare with old value --- .../item/document-item-ref.element.ts | 19 ++++++++++-------- .../member/item/member-item-ref.element.ts | 20 ++++++++++--------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index 92a3b407d3c3..85ffa9c94dbb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -23,6 +23,7 @@ export class UmbDocumentItemRefElement extends UmbLitElement { return this.#item; } public set item(value: UmbDocumentItemModel | undefined) { + const oldValue = this.#item; this.#item = value; if (!this.#item) { @@ -30,14 +31,16 @@ export class UmbDocumentItemRefElement extends UmbLitElement { return; } - this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath(UMB_DOCUMENT_ENTITY_TYPE + '/' + this.#item.unique) - .onSetup(() => { - return { data: { entityType: UMB_DOCUMENT_ENTITY_TYPE, preset: {} } }; - }) - .observeRouteBuilder((routeBuilder) => { - this._editPath = routeBuilder({}); - }); + if (oldValue?.unique !== this.#item.unique) { + this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath(UMB_DOCUMENT_ENTITY_TYPE + '/' + this.#item.unique) + .onSetup(() => { + return { data: { entityType: UMB_DOCUMENT_ENTITY_TYPE, preset: {} } }; + }) + .observeRouteBuilder((routeBuilder) => { + this._editPath = routeBuilder({}); + }); + } } @property({ type: Boolean }) diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts index e78166e64c1a..08d2d8c940b9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts @@ -17,21 +17,23 @@ export class UmbMemberItemRefElement extends UmbLitElement { return this.#item; } public set item(value: UmbMemberItemModel | undefined) { + const oldValue = this.#item; this.#item = value; if (!this.#item) { this.#modalRoute?.destroy(); return; } - - this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath(UMB_MEMBER_ENTITY_TYPE + '/' + this.#item.unique) - .onSetup(() => { - return { data: { entityType: UMB_MEMBER_ENTITY_TYPE, preset: {} } }; - }) - .observeRouteBuilder((routeBuilder) => { - this._editPath = routeBuilder({}); - }); + if (oldValue?.unique !== this.#item.unique) { + this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath(UMB_MEMBER_ENTITY_TYPE + '/' + this.#item.unique) + .onSetup(() => { + return { data: { entityType: UMB_MEMBER_ENTITY_TYPE, preset: {} } }; + }) + .observeRouteBuilder((routeBuilder) => { + this._editPath = routeBuilder({}); + }); + } } @property({ type: Boolean }) From 3c67f0044876b51c12fb1339a61b6b3a588cc665 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 10:15:20 +0100 Subject: [PATCH 039/145] only recreate the controller if the entity type changes --- .../entity-item-ref/entity-item-ref.element.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts index f78da6baa2f6..a76e1c36c062 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts @@ -21,8 +21,19 @@ export class UmbEntityItemRefElement extends UmbLitElement { return this.#item; } public set item(value: UmbEntityModel | undefined) { - if (value === this.#item || !value) return; + const oldValue = this.#item; this.#item = value; + + if (value === oldValue) return; + if (!value) return; + + // If the component is already created and the entity type is the same, we can just update the item. + if (this._component && value.entityType === oldValue?.entityType) { + this._component.item = value; + return; + } + + // If the component is already created, but the entity type is different, we need to destroy the component. this.#createController(value.entityType); } From b52175078f4270d400f81a1f27607656bd5baa9c Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 10:46:52 +0100 Subject: [PATCH 040/145] fix console warning --- .../src/packages/core/picker-input/picker-input.context.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context.ts index 7660af190cc4..057ba23d72b9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/picker-input/picker-input.context.ts @@ -62,7 +62,6 @@ export class UmbPickerInputContext< ) { super(host, UMB_PICKER_INPUT_CONTEXT); this.modalAlias = modalAlias; - this.#getUnique = getUniqueMethod || ((entry) => entry.unique); this.#getUnique = getUniqueMethod ? (entry: PickedItemType) => { @@ -75,7 +74,7 @@ export class UmbPickerInputContext< } : (entry) => entry.unique; - this.#itemManager = new UmbRepositoryItemsManager(this, repositoryAlias, this.#getUnique); + this.#itemManager = new UmbRepositoryItemsManager(this, repositoryAlias, getUniqueMethod); this.selection = this.#itemManager.uniques; this.selectedItems = this.#itemManager.items; From 80b144ea0f2a7430c6be24d45e909f381d2a2efd Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 11:23:39 +0100 Subject: [PATCH 041/145] implement for document item ref --- .../item/document-item-ref.element.ts | 61 +++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index 85ffa9c94dbb..628e7d044631 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -1,5 +1,6 @@ import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; import type { UmbDocumentItemModel } from './types.js'; +import { UMB_APP_LANGUAGE_CONTEXT } from '@umbraco-cms/backoffice/language'; import { classMap, css, @@ -11,8 +12,10 @@ import { state, } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; +import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; @customElement('umb-document-item-ref') export class UmbDocumentItemRefElement extends UmbLitElement { @@ -52,10 +55,60 @@ export class UmbDocumentItemRefElement extends UmbLitElement { @state() _editPath = ''; + @state() + _defaultCulture?: string; + + @state() + _appCulture?: string; + + @state() + _propertyDataSetCulture?: UmbVariantId; + #modalRoute?: any; - #isDraft(item: UmbDocumentItemModel) { - return item.variants[0]?.state === 'Draft'; + constructor() { + super(); + + this.consumeContext(UMB_APP_LANGUAGE_CONTEXT, (context) => { + this.observe(context.appLanguageCulture, (culture) => (this._appCulture = culture)); + this.observe(context.appDefaultLanguage, (value) => { + this._defaultCulture = value?.unique; + }); + }); + + this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, (context) => { + this._propertyDataSetCulture = context.getVariantId(); + }); + } + + #findVariant(culture: string | undefined) { + return this.item?.variants.find((x) => x.culture === culture); + } + + #getCurrentVariant() { + if (this.#isInvariant()) { + return this.item?.variants?.[0]; + } + + const culture = this._propertyDataSetCulture?.culture || this._appCulture; + return this.#findVariant(culture); + } + + #isInvariant() { + const firstVariant = this.item?.variants?.[0]; + return firstVariant?.culture === null; + } + + #getName() { + const variant = this.#getCurrentVariant(); + const fallbackName = this.#findVariant(this._defaultCulture)?.name; + + return variant?.name ?? `(${fallbackName})`; + } + + #isDraft() { + const variant = this.#getCurrentVariant(); + return variant?.state === 'Draft'; } #getHref(item: UmbDocumentItemModel) { @@ -67,8 +120,8 @@ export class UmbDocumentItemRefElement extends UmbLitElement { return html` From 08d3add9aff5cae9fbace497a9afd470f88beaae Mon Sep 17 00:00:00 2001 From: Sven Geusens Date: Tue, 11 Feb 2025 12:59:38 +0100 Subject: [PATCH 042/145] Added $type to ReferenceResponseModels --- .../ViewModels/TrackedReferences/IReferenceResponseModel.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/IReferenceResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/IReferenceResponseModel.cs index 83edaf05bea1..e16fb0c29e65 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/IReferenceResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/IReferenceResponseModel.cs @@ -1,6 +1,8 @@ -namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences; +using Umbraco.Cms.Api.Common.OpenApi; -public interface IReferenceResponseModel +namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences; + +public interface IReferenceResponseModel : IOpenApiDiscriminator { public Guid Id { get; } From 2cb20c8f1025b15e1e66e9e992809add045c6998 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 13:14:43 +0100 Subject: [PATCH 043/145] move logic to item data resolver --- .../item/document-item-data-resolver.ts | 118 ++++++++++++++++++ .../item/document-item-ref.element.ts | 87 ++++--------- 2 files changed, 141 insertions(+), 64 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts new file mode 100644 index 000000000000..336883acc749 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts @@ -0,0 +1,118 @@ +import type { UmbDocumentItemModel } from './types.js'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import type { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api'; +import { UMB_APP_LANGUAGE_CONTEXT } from '@umbraco-cms/backoffice/language'; +import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property'; +import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; + +/** + * A controller for resolving data for a document item + * @exports + * @class UmbDocumentItemDataResolver + * @augments {UmbControllerBase} + */ +export class UmbDocumentItemDataResolver extends UmbControllerBase { + #defaultCulture?: string; + #appCulture?: string; + #propertyDataSetCulture?: UmbVariantId; + #item?: UmbDocumentItemModel | undefined; + + constructor(host: UmbControllerHost) { + super(host); + + this.consumeContext(UMB_APP_LANGUAGE_CONTEXT, (context) => { + this.observe(context.appLanguageCulture, (culture) => (this.#appCulture = culture)); + this.observe(context.appDefaultLanguage, (value) => { + this.#defaultCulture = value?.unique; + }); + }); + + this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, (context) => { + this.#propertyDataSetCulture = context.getVariantId(); + }); + } + + /** + * Get the current item + * @returns {UmbDocumentItemModel | undefined} The current item + * @memberof UmbDocumentItemDataResolver + */ + getItem(): UmbDocumentItemModel | undefined { + return this.#item; + } + + /** + * Set the current item + * @param {UmbDocumentItemModel | undefined} item The current item + * @memberof UmbDocumentItemDataResolver + */ + setItem(item: UmbDocumentItemModel | undefined) { + this.#item = item; + } + + /** + * Get the unique of the item + * @returns {string | undefined} The unique of the item + * @memberof UmbDocumentItemDataResolver + */ + getUnique(): string | undefined { + return this.#item?.unique; + } + + /** + * Get the name of the item + * @returns {string} The name of the item + * @memberof UmbDocumentItemDataResolver + */ + getName(): string { + const variant = this.#getCurrentVariant(); + const fallbackName = this.#findVariant(this.#defaultCulture)?.name; + + return variant?.name ?? `(${fallbackName})`; + } + + /** + * Get the icon of the item + * @returns {string | undefined} The icon of the item + * @memberof UmbDocumentItemDataResolver + */ + getIcon(): string | undefined { + return this.#item?.documentType.icon; + } + + /** + * Get the state of the item + * @returns {string | undefined} The state of the item + * @memberof UmbDocumentItemDataResolver + */ + getState(): DocumentVariantStateModel | null | undefined { + return this.#getCurrentVariant()?.state; + } + + /** + * Get the isTrashed of the item + * @returns {boolean | undefined} The isTrashed of the item + * @memberof UmbDocumentItemDataResolver + */ + isTrashed(): boolean { + return this.#item?.isTrashed ?? false; + } + + #findVariant(culture: string | undefined) { + return this.#item?.variants.find((x) => x.culture === culture); + } + + #getCurrentVariant() { + if (this.#isInvariant()) { + return this.#item?.variants?.[0]; + } + + const culture = this.#propertyDataSetCulture?.culture || this.#appCulture; + return this.#findVariant(culture); + } + + #isInvariant() { + return this.#item?.variants?.[0]?.culture === null; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index 628e7d044631..e3227280eb35 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -1,6 +1,6 @@ import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; import type { UmbDocumentItemModel } from './types.js'; -import { UMB_APP_LANGUAGE_CONTEXT } from '@umbraco-cms/backoffice/language'; +import { UmbDocumentItemDataResolver } from './document-item-data-resolver.js'; import { classMap, css, @@ -12,31 +12,30 @@ import { state, } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; @customElement('umb-document-item-ref') export class UmbDocumentItemRefElement extends UmbLitElement { - #item?: UmbDocumentItemModel | undefined; + #item = new UmbDocumentItemDataResolver(this); @property({ type: Object }) public get item(): UmbDocumentItemModel | undefined { - return this.#item; + return this.#item.getItem(); } public set item(value: UmbDocumentItemModel | undefined) { - const oldValue = this.#item; - this.#item = value; + const oldValue = this.#item.getItem(); + this.#item.setItem(value); - if (!this.#item) { + if (!value) { this.#modalRoute?.destroy(); return; } - if (oldValue?.unique !== this.#item.unique) { + if (oldValue?.unique !== value.unique) { this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath(UMB_DOCUMENT_ENTITY_TYPE + '/' + this.#item.unique) + .addAdditionalPath(UMB_DOCUMENT_ENTITY_TYPE + '/' + value.unique) .onSetup(() => { return { data: { entityType: UMB_DOCUMENT_ENTITY_TYPE, preset: {} } }; }) @@ -66,53 +65,8 @@ export class UmbDocumentItemRefElement extends UmbLitElement { #modalRoute?: any; - constructor() { - super(); - - this.consumeContext(UMB_APP_LANGUAGE_CONTEXT, (context) => { - this.observe(context.appLanguageCulture, (culture) => (this._appCulture = culture)); - this.observe(context.appDefaultLanguage, (value) => { - this._defaultCulture = value?.unique; - }); - }); - - this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, (context) => { - this._propertyDataSetCulture = context.getVariantId(); - }); - } - - #findVariant(culture: string | undefined) { - return this.item?.variants.find((x) => x.culture === culture); - } - - #getCurrentVariant() { - if (this.#isInvariant()) { - return this.item?.variants?.[0]; - } - - const culture = this._propertyDataSetCulture?.culture || this._appCulture; - return this.#findVariant(culture); - } - - #isInvariant() { - const firstVariant = this.item?.variants?.[0]; - return firstVariant?.culture === null; - } - - #getName() { - const variant = this.#getCurrentVariant(); - const fallbackName = this.#findVariant(this._defaultCulture)?.name; - - return variant?.name ?? `(${fallbackName})`; - } - - #isDraft() { - const variant = this.#getCurrentVariant(); - return variant?.state === 'Draft'; - } - - #getHref(item: UmbDocumentItemModel) { - return `${this._editPath}/edit/${item.unique}`; + #getHref() { + return `${this._editPath}/edit/${this.#item.getUnique()}`; } override render() { @@ -121,23 +75,28 @@ export class UmbDocumentItemRefElement extends UmbLitElement { return html` - ${this.#renderIcon(this.item)} ${this.#renderIsTrashed(this.item)} + ${this.#renderIcon()} ${this.#renderIsTrashed()} `; } - #renderIcon(item: UmbDocumentItemModel) { - if (!item.documentType.icon) return; - return html``; + #isDraft() { + return this.#item.getState() === 'Draft'; + } + + #renderIcon() { + const icon = this.#item.getIcon(); + if (!icon) return nothing; + return html``; } - #renderIsTrashed(item: UmbDocumentItemModel) { - if (!item.isTrashed) return; + #renderIsTrashed() { + if (!this.#item.isTrashed()) return nothing; return html`Trashed`; } From 0c15b411bef08ce69e4ea6bf263ee8b090d4a4a3 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 13:18:02 +0100 Subject: [PATCH 044/145] render draft as a tag --- .../documents/item/document-item-ref.element.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index e3227280eb35..b9c58d3ac69c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -3,7 +3,6 @@ import type { UmbDocumentItemModel } from './types.js'; import { UmbDocumentItemDataResolver } from './document-item-data-resolver.js'; import { classMap, - css, customElement, html, ifDefined, @@ -80,7 +79,7 @@ export class UmbDocumentItemRefElement extends UmbLitElement { ?readonly=${this.readonly} ?standalone=${this.standalone}> - ${this.#renderIcon()} ${this.#renderIsTrashed()} + ${this.#renderIcon()}${this.#renderIsDraft()} ${this.#renderIsTrashed()} `; } @@ -100,13 +99,10 @@ export class UmbDocumentItemRefElement extends UmbLitElement { return html`Trashed`; } - static override styles = [ - css` - .draft { - opacity: 0.6; - } - `, - ]; + #renderIsDraft() { + if (!this.#isDraft()) return nothing; + return html`Draft`; + } } export { UmbDocumentItemRefElement as element }; From 7fe30d7c7530dcf748bd545408521ddd552ff3a2 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 13:18:45 +0100 Subject: [PATCH 045/145] Update document-item-ref.element.ts --- .../documents/documents/item/document-item-ref.element.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index b9c58d3ac69c..10cd6f1a0b97 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -14,6 +14,7 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; +import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api'; @customElement('umb-document-item-ref') export class UmbDocumentItemRefElement extends UmbLitElement { @@ -85,7 +86,7 @@ export class UmbDocumentItemRefElement extends UmbLitElement { } #isDraft() { - return this.#item.getState() === 'Draft'; + return this.#item.getState() === DocumentVariantStateModel.DRAFT; } #renderIcon() { From 9be6d8196cf29ffd3af65d902caf83601934a64f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 14:13:33 +0100 Subject: [PATCH 046/145] generate server models --- .../src/external/backend-api/src/types.gen.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/types.gen.ts b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/types.gen.ts index 41a57432eabc..9fb5dbd8129b 100644 --- a/src/Umbraco.Web.UI.Client/src/external/backend-api/src/types.gen.ts +++ b/src/Umbraco.Web.UI.Client/src/external/backend-api/src/types.gen.ts @@ -565,6 +565,7 @@ export type DataTypeTreeItemResponseModel = { }; export type DefaultReferenceResponseModel = { + $type: string; id: string; name?: (string) | null; type?: (string) | null; @@ -686,6 +687,7 @@ export type DocumentRecycleBinItemResponseModel = { }; export type DocumentReferenceResponseModel = { + $type: string; id: string; name?: (string) | null; published?: (boolean) | null; @@ -1213,6 +1215,7 @@ export type MediaRecycleBinItemResponseModel = { }; export type MediaReferenceResponseModel = { + $type: string; id: string; name?: (string) | null; mediaType: (TrackedReferenceMediaTypeModel); From e47217e25c7647ea8e8d263878213c6d034d543f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 15:47:44 +0100 Subject: [PATCH 047/145] add more helpers to data resolver --- .../item/document-item-data-resolver.ts | 12 ++++++++++- .../item/document-item-ref.element.ts | 20 +++---------------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts index 336883acc749..73b5559ea9cc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts @@ -1,3 +1,4 @@ +import { UmbDocumentVariantState } from '../types.js'; import type { UmbDocumentItemModel } from './types.js'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; @@ -90,12 +91,21 @@ export class UmbDocumentItemDataResolver extends UmbControllerBase { return this.#getCurrentVariant()?.state; } + /** + * Get the isDraft of the item + * @returns {boolean} The isDraft of the item + * @memberof UmbDocumentItemDataResolver + */ + getIsDraft(): boolean { + return this.getState() === UmbDocumentVariantState.DRAFT || false; + } + /** * Get the isTrashed of the item * @returns {boolean | undefined} The isTrashed of the item * @memberof UmbDocumentItemDataResolver */ - isTrashed(): boolean { + getIsTrashed(): boolean { return this.#item?.isTrashed ?? false; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index 10cd6f1a0b97..46d1b75a25fb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -1,20 +1,11 @@ import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; import type { UmbDocumentItemModel } from './types.js'; import { UmbDocumentItemDataResolver } from './document-item-data-resolver.js'; -import { - classMap, - customElement, - html, - ifDefined, - nothing, - property, - state, -} from '@umbraco-cms/backoffice/external/lit'; +import { customElement, html, ifDefined, nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; -import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api'; @customElement('umb-document-item-ref') export class UmbDocumentItemRefElement extends UmbLitElement { @@ -74,7 +65,6 @@ export class UmbDocumentItemRefElement extends UmbLitElement { return html` Trashed`; } #renderIsDraft() { - if (!this.#isDraft()) return nothing; + if (!this.#item.getIsDraft()) return nothing; return html`Draft`; } } From f45ae29d258ee236ec601234924b1c47f4872c9a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 15:47:56 +0100 Subject: [PATCH 048/145] export resolver --- .../src/packages/documents/documents/item/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/index.ts index f6365499927d..3b64c9668a2b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/index.ts @@ -1 +1,2 @@ export { UmbDocumentItemRepository } from './repository/index.js'; +export * from './document-item-data-resolver.js'; From 2b0ae998e126e4209139e382a386eaded9549a88 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 19:13:39 +0100 Subject: [PATCH 049/145] add observables --- .../item/document-item-data-resolver.ts | 110 ++++++++++++++---- 1 file changed, 85 insertions(+), 25 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts index 73b5559ea9cc..7608c2d9aaef 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts @@ -3,7 +3,9 @@ import type { UmbDocumentItemModel } from './types.js'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api'; +import type { UmbAppLanguageContext } from '@umbraco-cms/backoffice/language'; import { UMB_APP_LANGUAGE_CONTEXT } from '@umbraco-cms/backoffice/language'; +import { UmbBooleanState, UmbStringState } from '@umbraco-cms/backoffice/observable-api'; import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property'; import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; @@ -19,19 +21,48 @@ export class UmbDocumentItemDataResolver extends UmbControllerBase { #propertyDataSetCulture?: UmbVariantId; #item?: UmbDocumentItemModel | undefined; + #init: Promise<[UmbAppLanguageContext]>; + + #unique = new UmbStringState(undefined); + public readonly unique = this.#unique.asObservable(); + + #name = new UmbStringState(undefined); + public readonly name = this.#name.asObservable(); + + #icon = new UmbStringState(undefined); + public readonly icon = this.#icon.asObservable(); + + #isTrashed = new UmbBooleanState(undefined); + public readonly isTrashed = this.#isTrashed.asObservable(); + + #isDraft = new UmbBooleanState(undefined); + public readonly isDraft = this.#isDraft.asObservable(); + constructor(host: UmbControllerHost) { super(host); - this.consumeContext(UMB_APP_LANGUAGE_CONTEXT, (context) => { - this.observe(context.appLanguageCulture, (culture) => (this.#appCulture = culture)); - this.observe(context.appDefaultLanguage, (value) => { - this.#defaultCulture = value?.unique; - }); - }); - + // We do not depend on this context because we know is it only available in some cases this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, (context) => { this.#propertyDataSetCulture = context.getVariantId(); + this.#setName(); + this.#setIsDraft(); }); + + this.#init = Promise.all([ + this.consumeContext(UMB_APP_LANGUAGE_CONTEXT, (context) => { + this.observe(context.appLanguageCulture, (culture) => { + this.#appCulture = culture; + this.#setName(); + this.#setIsDraft(); + }); + + this.observe(context.appDefaultLanguage, (value) => { + this.#defaultCulture = value?.unique; + this.#setName(); + this.#setIsDraft(); + }); + }).asPromise(), + ]); } /** @@ -50,65 +81,94 @@ export class UmbDocumentItemDataResolver extends UmbControllerBase { */ setItem(item: UmbDocumentItemModel | undefined) { this.#item = item; + + if (!this.#item) { + this.#unique.setValue(undefined); + this.#name.setValue(undefined); + this.#icon.setValue(undefined); + this.#isTrashed.setValue(undefined); + this.#isDraft.setValue(undefined); + return; + } + + this.#unique.setValue(this.#item.unique); + this.#icon.setValue(this.#item.documentType.icon); + this.#isTrashed.setValue(this.#item.isTrashed); } /** * Get the unique of the item - * @returns {string | undefined} The unique of the item + * @returns {Promise} The unique of the item * @memberof UmbDocumentItemDataResolver */ - getUnique(): string | undefined { - return this.#item?.unique; + async getUnique(): Promise { + await this.#init; + return this.#unique.getValue(); } /** * Get the name of the item - * @returns {string} The name of the item + * @returns {Promise} The name of the item * @memberof UmbDocumentItemDataResolver */ - getName(): string { - const variant = this.#getCurrentVariant(); - const fallbackName = this.#findVariant(this.#defaultCulture)?.name; - - return variant?.name ?? `(${fallbackName})`; + async getName(): Promise { + await this.#init; + return this.#name.getValue() || ''; } /** * Get the icon of the item - * @returns {string | undefined} The icon of the item + * @returns {Promise} The icon of the item * @memberof UmbDocumentItemDataResolver */ - getIcon(): string | undefined { + async getIcon(): Promise { + await this.#init; return this.#item?.documentType.icon; } /** * Get the state of the item - * @returns {string | undefined} The state of the item + * @returns {Promise} The state of the item * @memberof UmbDocumentItemDataResolver */ - getState(): DocumentVariantStateModel | null | undefined { + async getState(): Promise { + await this.#init; return this.#getCurrentVariant()?.state; } /** * Get the isDraft of the item - * @returns {boolean} The isDraft of the item + * @returns {Promise} The isDraft of the item * @memberof UmbDocumentItemDataResolver */ - getIsDraft(): boolean { - return this.getState() === UmbDocumentVariantState.DRAFT || false; + async getIsDraft(): Promise { + await this.#init; + return this.#isDraft.getValue() ?? false; } /** * Get the isTrashed of the item - * @returns {boolean | undefined} The isTrashed of the item + * @returns {Promise} The isTrashed of the item * @memberof UmbDocumentItemDataResolver */ - getIsTrashed(): boolean { + async getIsTrashed(): Promise { + await this.#init; return this.#item?.isTrashed ?? false; } + #setName() { + const variant = this.#getCurrentVariant(); + const fallbackName = this.#findVariant(this.#defaultCulture)?.name; + const name = variant?.name ?? `(${fallbackName})`; + this.#name.setValue(name); + } + + #setIsDraft() { + const variant = this.#getCurrentVariant(); + const isDraft = variant?.state === UmbDocumentVariantState.DRAFT || false; + this.#isDraft.setValue(isDraft); + } + #findVariant(culture: string | undefined) { return this.#item?.variants.find((x) => x.culture === culture); } From 0ae2420efa21c3d14384ac35ca4307fdb62a177f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 19:13:55 +0100 Subject: [PATCH 050/145] use observables in document item ref --- .../item/document-item-ref.element.ts | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index 46d1b75a25fb..c09ea737fe61 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -42,6 +42,21 @@ export class UmbDocumentItemRefElement extends UmbLitElement { @property({ type: Boolean }) standalone = false; + @state() + _unique = ''; + + @state() + _name = ''; + + @state() + _icon = ''; + + @state() + _isTrashed = false; + + @state() + _isDraft = false; + @state() _editPath = ''; @@ -57,7 +72,16 @@ export class UmbDocumentItemRefElement extends UmbLitElement { #modalRoute?: any; #getHref() { - return `${this._editPath}/edit/${this.#item.getUnique()}`; + return `${this._editPath}/edit/${this._unique}`; + } + + constructor() { + super(); + this.#item.observe(this.#item.unique, (unique) => (this._unique = unique ?? '')); + this.#item.observe(this.#item.name, (name) => (this._name = name ?? '')); + this.#item.observe(this.#item.icon, (icon) => (this._icon = icon ?? '')); + this.#item.observe(this.#item.isTrashed, (isTrashed) => (this._isTrashed = isTrashed ?? false)); + this.#item.observe(this.#item.isDraft, (isDraft) => (this._isDraft = isDraft ?? false)); } override render() { @@ -65,7 +89,7 @@ export class UmbDocumentItemRefElement extends UmbLitElement { return html` @@ -76,18 +100,17 @@ export class UmbDocumentItemRefElement extends UmbLitElement { } #renderIcon() { - const icon = this.#item.getIcon(); - if (!icon) return nothing; - return html``; + if (!this._icon) return nothing; + return html``; } #renderIsTrashed() { - if (!this.#item.getIsTrashed()) return nothing; + if (!this._isTrashed) return nothing; return html`Trashed`; } #renderIsDraft() { - if (!this.#item.getIsDraft()) return nothing; + if (!this._isDraft) return nothing; return html`Draft`; } } From 6f7cc8e7c01decb33de31c8773f28af7b26540fc Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 19:16:12 +0100 Subject: [PATCH 051/145] add data resolver to tree item --- .../tree-item/document-tree-item.context.ts | 11 +++ .../tree-item/document-tree-item.element.ts | 79 +++---------------- 2 files changed, 24 insertions(+), 66 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.context.ts index af7b4f65886e..673203bb8ef7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.context.ts @@ -1,4 +1,5 @@ import type { UmbDocumentTreeItemModel, UmbDocumentTreeRootModel } from '../types.js'; +import { UmbDocumentItemDataResolver } from '../../item/index.js'; import { UmbDefaultTreeItemContext } from '@umbraco-cms/backoffice/tree'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbIsTrashedEntityContext } from '@umbraco-cms/backoffice/recycle-bin'; @@ -9,6 +10,11 @@ export class UmbDocumentTreeItemContext extends UmbDefaultTreeItemContext< > { // TODO: Provide this together with the EntityContext, ideally this takes part via a extension-type [NL] #isTrashedContext = new UmbIsTrashedEntityContext(this); + #item = new UmbDocumentItemDataResolver(this); + + readonly name = this.#item.name; + readonly icon = this.#item.icon; + readonly isDraft = this.#item.isDraft; readonly isTrashed = this._treeItem.asObservablePart((item) => item?.isTrashed ?? false); @@ -19,6 +25,11 @@ export class UmbDocumentTreeItemContext extends UmbDefaultTreeItemContext< this.#isTrashedContext.setIsTrashed(isTrashed); }); } + + public override setTreeItem(treeItem: UmbDocumentTreeItemModel | undefined) { + super.setTreeItem(treeItem); + this.#item.setItem(treeItem); + } } export { UmbDocumentTreeItemContext as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.element.ts index bd122660bfb6..018e1c8d00bf 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.element.ts @@ -1,86 +1,35 @@ -import type { UmbDocumentTreeItemModel, UmbDocumentTreeItemVariantModel } from '../types.js'; -import { DocumentVariantStateModel } from '@umbraco-cms/backoffice/external/backend-api'; -import { css, html, nothing, customElement, state, classMap } from '@umbraco-cms/backoffice/external/lit'; -import type { UmbAppLanguageContext } from '@umbraco-cms/backoffice/language'; -import { UMB_APP_LANGUAGE_CONTEXT } from '@umbraco-cms/backoffice/language'; +import type { UmbDocumentTreeItemModel } from '../types.js'; +import { css, html, nothing, customElement, classMap, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { UmbTreeItemElementBase } from '@umbraco-cms/backoffice/tree'; +import { UMB_TREE_ITEM_CONTEXT, UmbTreeItemElementBase } from '@umbraco-cms/backoffice/tree'; @customElement('umb-document-tree-item') export class UmbDocumentTreeItemElement extends UmbTreeItemElementBase { - #appLanguageContext?: UmbAppLanguageContext; - @state() - _currentCulture?: string; + private _name = ''; @state() - _defaultCulture?: string; + private _isDraft = false; @state() - _variant?: UmbDocumentTreeItemVariantModel; + private _icon = ''; constructor() { super(); - this.consumeContext(UMB_APP_LANGUAGE_CONTEXT, (instance) => { - this.#appLanguageContext = instance; - this.#observeAppCulture(); - this.#observeDefaultCulture(); - }); - } - - #observeAppCulture() { - this.observe(this.#appLanguageContext!.appLanguageCulture, (value) => { - this._currentCulture = value; - this._variant = this.#findVariant(value); + this.consumeContext(UMB_TREE_ITEM_CONTEXT, (context) => { + this.observe(context.name, (name) => (this._name = name)); + this.observe(context.isDraft, (isDraft) => (this._isDraft = isDraft)); + this.observe(context.icon, (icon) => (this._icon = icon)); }); } - #observeDefaultCulture() { - this.observe(this.#appLanguageContext!.appDefaultLanguage, (value) => { - this._defaultCulture = value?.unique; - }); - } - - #findVariant(culture: string | undefined) { - return this.item?.variants.find((x) => x.culture === culture); - } - - #isInvariant() { - const firstVariant = this.item?.variants[0]; - return firstVariant?.culture === null && firstVariant?.segment === null; - } - - // TODO: we should move the fallback name logic to a helper class. It will be used in multiple places - #getLabel() { - if (this.#isInvariant()) { - return this._item?.variants[0].name; - } - - // ensure we always have the correct variant data - this._variant = this.#findVariant(this._currentCulture); - - const fallbackName = this.#findVariant(this._defaultCulture)?.name ?? this._item?.variants[0].name ?? 'Unknown'; - return this._variant?.name ?? `(${fallbackName})`; - } - - #isDraft() { - if (this.#isInvariant()) { - return this._item?.variants[0].state === DocumentVariantStateModel.DRAFT; - } - - // ensure we always have the correct variant data - this._variant = this.#findVariant(this._currentCulture); - - return this._variant?.state === DocumentVariantStateModel.DRAFT; - } - override renderIconContainer() { - const icon = this.item?.documentType.icon; + const icon = this._icon; const iconWithoutColor = icon?.split(' ')[0]; return html` - + ${icon && iconWithoutColor ? html` @@ -92,9 +41,7 @@ export class UmbDocumentTreeItemElement extends UmbTreeItemElementBase${this.#getLabel()} `; + return html`${this._name} `; } #renderStateIcon() { From ef1638b853880887594bcb0f3bb23ebdeeabbba7 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 20:43:52 +0100 Subject: [PATCH 052/145] add observable state --- .../item/document-item-data-resolver.ts | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts index 7608c2d9aaef..c285249fa3ef 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts @@ -32,6 +32,9 @@ export class UmbDocumentItemDataResolver extends UmbControllerBase { #icon = new UmbStringState(undefined); public readonly icon = this.#icon.asObservable(); + #state = new UmbStringState(undefined); + public readonly state = this.#state.asObservable(); + #isTrashed = new UmbBooleanState(undefined); public readonly isTrashed = this.#isTrashed.asObservable(); @@ -44,22 +47,19 @@ export class UmbDocumentItemDataResolver extends UmbControllerBase { // We do not depend on this context because we know is it only available in some cases this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, (context) => { this.#propertyDataSetCulture = context.getVariantId(); - this.#setName(); - this.#setIsDraft(); + this.#setObservableValues(); }); this.#init = Promise.all([ this.consumeContext(UMB_APP_LANGUAGE_CONTEXT, (context) => { this.observe(context.appLanguageCulture, (culture) => { this.#appCulture = culture; - this.#setName(); - this.#setIsDraft(); + this.#setObservableValues(); }); this.observe(context.appDefaultLanguage, (value) => { this.#defaultCulture = value?.unique; - this.#setName(); - this.#setIsDraft(); + this.#setObservableValues(); }); }).asPromise(), ]); @@ -156,6 +156,12 @@ export class UmbDocumentItemDataResolver extends UmbControllerBase { return this.#item?.isTrashed ?? false; } + #setObservableValues() { + this.#setName(); + this.#setIsDraft(); + this.#setState(); + } + #setName() { const variant = this.#getCurrentVariant(); const fallbackName = this.#findVariant(this.#defaultCulture)?.name; @@ -169,6 +175,12 @@ export class UmbDocumentItemDataResolver extends UmbControllerBase { this.#isDraft.setValue(isDraft); } + #setState() { + const variant = this.#getCurrentVariant(); + const state = variant?.state || UmbDocumentVariantState.NOT_CREATED; + this.#state.setValue(state); + } + #findVariant(culture: string | undefined) { return this.#item?.variants.find((x) => x.culture === culture); } From 029cc3cfa61c36f9b761ddfd26273ef31e972c05 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 20:44:10 +0100 Subject: [PATCH 053/145] use const --- .../views/table/document-table-collection-view.element.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts index 679bb81783ef..b86d271b3bf2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts @@ -3,6 +3,7 @@ import { UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN } from '../../../paths.js'; import type { UmbDocumentCollectionItemModel } from '../../types.js'; import type { UmbDocumentCollectionContext } from '../../document-collection.context.js'; import { UMB_DOCUMENT_COLLECTION_CONTEXT } from '../../document-collection.context-token.js'; +import { UMB_DOCUMENT_ENTITY_TYPE } from '../../../entity.js'; import type { UmbCollectionColumnConfiguration } from '@umbraco-cms/backoffice/collection'; import { css, customElement, html, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @@ -167,7 +168,7 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement { return { id: item.unique, icon: item.icon, - entityType: 'document', + entityType: UMB_DOCUMENT_ENTITY_TYPE, data: data, }; }); From cdcbf3197d2d9f630d8c425baa97449d6857d245 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 21:44:15 +0100 Subject: [PATCH 054/145] align models --- .../document-collection.server.data-source.ts | 17 +++++++- .../documents/documents/collection/types.ts | 43 ++++++++++++++++--- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts index 99091d6d97a6..30f2050121f5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts @@ -1,4 +1,5 @@ import type { UmbDocumentCollectionFilterModel, UmbDocumentCollectionItemModel } from '../types.js'; +import { UMB_DOCUMENT_ENTITY_TYPE } from '../../entity.js'; import { DirectionModel, DocumentService } from '@umbraco-cms/backoffice/external/backend-api'; import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; import type { DocumentCollectionResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; @@ -32,12 +33,12 @@ export class UmbDocumentCollectionServerDataSource implements UmbCollectionDataS if (data) { const items = data.items.map((item: DocumentCollectionResponseModel) => { - // TODO: [LK] Temp solution, review how to get the name from the corresponding variant. + // TODO: remove in v17.0.0 const variant = item.variants[0]; const model: UmbDocumentCollectionItemModel = { unique: item.id, - entityType: 'document', + entityType: UMB_DOCUMENT_ENTITY_TYPE, contentTypeAlias: item.documentType.alias, createDate: new Date(variant.createDate), creator: item.creator, @@ -50,6 +51,18 @@ export class UmbDocumentCollectionServerDataSource implements UmbCollectionDataS values: item.values.map((item) => { return { alias: item.alias, value: item.value as string }; }), + documentType: { + unique: item.documentType.id, + icon: item.documentType.icon, + alias: item.documentType.alias, + }, + variants: item.variants.map((item) => { + return { + name: item.name, + culture: item.culture ?? null, + state: item.state, + }; + }), }; return model; }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/types.ts index c3a7b165170e..3629ce58a45c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/types.ts @@ -1,3 +1,4 @@ +import type { UmbDocumentItemVariantModel } from '../item/repository/types.js'; import type { UmbCollectionFilterModel } from '@umbraco-cms/backoffice/collection'; export interface UmbDocumentCollectionFilterModel extends UmbCollectionFilterModel { @@ -12,16 +13,46 @@ export interface UmbDocumentCollectionFilterModel extends UmbCollectionFilterMod export interface UmbDocumentCollectionItemModel { unique: string; entityType: string; - contentTypeAlias: string; - createDate: Date; creator?: string | null; - icon: string; - name: string; sortOrder: number; - state: string; - updateDate: Date; updater?: string | null; values: Array<{ alias: string; value: string }>; + documentType: { + unique: string; + icon: string; + alias: string; + }; + variants: Array; + + /** + * @deprecated From 15.3.0. Will be removed in 17.0.0. Use state in variants array instead. + */ + state: string; + + /** + * @deprecated From 15.3.0. Will be removed in 17.0.0. Use name in variants array instead. + */ + name: string; + + /** + * @deprecated From 15.3.0. Will be removed in 17.0.0. Use updateDate in variants array instead. + */ + updateDate: Date; + + /** + * @deprecated From 15.3.0. Will be removed in 17.0.0. Use createDate in variants array instead. + */ + createDate: Date; + + /** + * @deprecated From 15.3.0. Will be removed in 17.0.0. Use alias on documentType instead. + */ + contentTypeAlias: string; + + /** + * @deprecated From 15.3.0. Will be removed in 17.0.0. Use icon on documentType instead. + */ + icon: string; } export interface UmbEditableDocumentCollectionItemModel { From f6ac0e45ac93c4bbe524c67c3f55e29d5267f21a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 22:16:41 +0100 Subject: [PATCH 055/145] get icon from document type object --- .../views/table/document-table-collection-view.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts index b86d271b3bf2..3ce823efc37e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/document-table-collection-view.element.ts @@ -167,7 +167,7 @@ export class UmbDocumentTableCollectionViewElement extends UmbLitElement { return { id: item.unique, - icon: item.icon, + icon: item.documentType.icon, entityType: UMB_DOCUMENT_ENTITY_TYPE, data: data, }; From ff164c7235b43aa70c6374443c5aa5a937ae207a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 11 Feb 2025 22:20:47 +0100 Subject: [PATCH 056/145] observe name and state --- .../document-table-column-name.element.ts | 36 +++++++++++-------- .../document-table-column-state.element.ts | 27 ++++++++++++-- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-name.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-name.element.ts index cc084caa0190..5bfca08aebf2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-name.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-name.element.ts @@ -1,32 +1,40 @@ import type { UmbEditableDocumentCollectionItemModel } from '../../../types.js'; -import { css, customElement, html, nothing, property } from '@umbraco-cms/backoffice/external/lit'; +import { UmbDocumentItemDataResolver } from '../../../../item/index.js'; +import { css, customElement, html, nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { UmbTableColumn, UmbTableColumnLayoutElement, UmbTableItem } from '@umbraco-cms/backoffice/components'; -import type { UUIButtonElement } from '@umbraco-cms/backoffice/external/uui'; @customElement('umb-document-table-column-name') export class UmbDocumentTableColumnNameElement extends UmbLitElement implements UmbTableColumnLayoutElement { column!: UmbTableColumn; item!: UmbTableItem; + #value!: UmbEditableDocumentCollectionItemModel; @property({ attribute: false }) - value!: UmbEditableDocumentCollectionItemModel; + public get value(): UmbEditableDocumentCollectionItemModel { + return this.#value; + } + public set value(value: UmbEditableDocumentCollectionItemModel) { + this.#value = value; + + if (value.item) { + this.#item.setItem(value.item); + } + } + + @state() + _name = ''; + + #item = new UmbDocumentItemDataResolver(this); - #onClick(event: Event & { target: UUIButtonElement }) { - event.preventDefault(); - event.stopPropagation(); - window.history.pushState(null, '', event.target.href); + constructor() { + super(); + this.#item.observe(this.#item.name, (name) => (this._name = name || '')); } override render() { if (!this.value) return nothing; - return html` - - `; + return html` `; } static override styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts index f986920e750e..f239a6e3f896 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts @@ -1,5 +1,6 @@ import type { UmbEditableDocumentCollectionItemModel } from '../../../types.js'; -import { customElement, html, property } from '@umbraco-cms/backoffice/external/lit'; +import { UmbDocumentItemDataResolver } from '../../../../item/index.js'; +import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; import { fromCamelCase } from '@umbraco-cms/backoffice/utils'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import type { UmbTableColumn, UmbTableColumnLayoutElement, UmbTableItem } from '@umbraco-cms/backoffice/components'; @@ -9,11 +10,31 @@ export class UmbDocumentTableColumnStateElement extends UmbLitElement implements column!: UmbTableColumn; item!: UmbTableItem; + #value!: UmbEditableDocumentCollectionItemModel; @property({ attribute: false }) - value!: UmbEditableDocumentCollectionItemModel; + public get value(): UmbEditableDocumentCollectionItemModel { + return this.#value; + } + public set value(value: UmbEditableDocumentCollectionItemModel) { + this.#value = value; + + if (value.item) { + this.#item.setItem(value.item); + } + } + + @state() + _state = ''; + + #item = new UmbDocumentItemDataResolver(this); + + constructor() { + super(); + this.#item.observe(this.#item.state, (state) => (this._state = state)); + } override render() { - switch (this.value.item.state) { + switch (this._state) { case 'Published': return html`${this.localize.term('content_published')}`; case 'PublishedPendingChanges': From 9b478241eed4ff637cccd829957a8a1981307ea9 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 12 Feb 2025 16:49:38 +0100 Subject: [PATCH 057/145] update observed value when a new item is set --- .../documents/documents/item/document-item-data-resolver.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts index c285249fa3ef..323e5a81633d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts @@ -94,6 +94,7 @@ export class UmbDocumentItemDataResolver extends UmbControllerBase { this.#unique.setValue(this.#item.unique); this.#icon.setValue(this.#item.documentType.icon); this.#isTrashed.setValue(this.#item.isTrashed); + this.#setObservableValues(); } /** From f218486ca649cf7a139273694546bbfe954510fb Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 12 Feb 2025 16:59:22 +0100 Subject: [PATCH 058/145] update method name --- .../documents/item/document-item-data-resolver.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts index 323e5a81633d..26089a3d08e3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts @@ -47,19 +47,19 @@ export class UmbDocumentItemDataResolver extends UmbControllerBase { // We do not depend on this context because we know is it only available in some cases this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, (context) => { this.#propertyDataSetCulture = context.getVariantId(); - this.#setObservableValues(); + this.#setVariantAwareValues(); }); this.#init = Promise.all([ this.consumeContext(UMB_APP_LANGUAGE_CONTEXT, (context) => { this.observe(context.appLanguageCulture, (culture) => { this.#appCulture = culture; - this.#setObservableValues(); + this.#setVariantAwareValues(); }); this.observe(context.appDefaultLanguage, (value) => { this.#defaultCulture = value?.unique; - this.#setObservableValues(); + this.#setVariantAwareValues(); }); }).asPromise(), ]); @@ -94,7 +94,7 @@ export class UmbDocumentItemDataResolver extends UmbControllerBase { this.#unique.setValue(this.#item.unique); this.#icon.setValue(this.#item.documentType.icon); this.#isTrashed.setValue(this.#item.isTrashed); - this.#setObservableValues(); + this.#setVariantAwareValues(); } /** @@ -157,7 +157,7 @@ export class UmbDocumentItemDataResolver extends UmbControllerBase { return this.#item?.isTrashed ?? false; } - #setObservableValues() { + #setVariantAwareValues() { this.#setName(); this.#setIsDraft(); this.#setState(); From dc1b5ce93082f4d7fa5e4958765b2e39e575a03e Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 12 Feb 2025 20:25:29 +0100 Subject: [PATCH 059/145] update method names --- .../document-table-column-name.element.ts | 2 +- .../document-table-column-state.element.ts | 2 +- .../item/document-item-data-resolver.ts | 36 ++++++++++--------- .../item/document-item-ref.element.ts | 6 ++-- .../tree-item/document-tree-item.context.ts | 2 +- 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-name.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-name.element.ts index 5bfca08aebf2..660c27db90d8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-name.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-name.element.ts @@ -18,7 +18,7 @@ export class UmbDocumentTableColumnNameElement extends UmbLitElement implements this.#value = value; if (value.item) { - this.#item.setItem(value.item); + this.#item.setData(value.item); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts index f239a6e3f896..bf5e166df4d5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts @@ -19,7 +19,7 @@ export class UmbDocumentTableColumnStateElement extends UmbLitElement implements this.#value = value; if (value.item) { - this.#item.setItem(value.item); + this.#item.setData(value.item); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts index 26089a3d08e3..0243acff1472 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts @@ -9,17 +9,19 @@ import { UmbBooleanState, UmbStringState } from '@umbraco-cms/backoffice/observa import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property'; import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; +type UmbDocumentItemDataResolverModel = Omit; + /** * A controller for resolving data for a document item * @exports * @class UmbDocumentItemDataResolver * @augments {UmbControllerBase} */ -export class UmbDocumentItemDataResolver extends UmbControllerBase { +export class UmbDocumentItemDataResolver extends UmbControllerBase { #defaultCulture?: string; #appCulture?: string; #propertyDataSetCulture?: UmbVariantId; - #item?: UmbDocumentItemModel | undefined; + #data?: UmbDocumentItemDataResolverModel | undefined; #init: Promise<[UmbAppLanguageContext]>; @@ -67,22 +69,22 @@ export class UmbDocumentItemDataResolver extends UmbControllerBase { /** * Get the current item - * @returns {UmbDocumentItemModel | undefined} The current item + * @returns {DataType | undefined} The current item * @memberof UmbDocumentItemDataResolver */ - getItem(): UmbDocumentItemModel | undefined { - return this.#item; + getData(): DataType | undefined { + return this.#data as DataType; } /** * Set the current item - * @param {UmbDocumentItemModel | undefined} item The current item + * @param {DataType | undefined} data The current item * @memberof UmbDocumentItemDataResolver */ - setItem(item: UmbDocumentItemModel | undefined) { - this.#item = item; + setData(data: DataType | undefined) { + this.#data = data; - if (!this.#item) { + if (!this.#data) { this.#unique.setValue(undefined); this.#name.setValue(undefined); this.#icon.setValue(undefined); @@ -91,9 +93,9 @@ export class UmbDocumentItemDataResolver extends UmbControllerBase { return; } - this.#unique.setValue(this.#item.unique); - this.#icon.setValue(this.#item.documentType.icon); - this.#isTrashed.setValue(this.#item.isTrashed); + this.#unique.setValue(this.#data.unique); + this.#icon.setValue(this.#data.documentType.icon); + this.#isTrashed.setValue(this.#data.isTrashed); this.#setVariantAwareValues(); } @@ -124,7 +126,7 @@ export class UmbDocumentItemDataResolver extends UmbControllerBase { */ async getIcon(): Promise { await this.#init; - return this.#item?.documentType.icon; + return this.#data?.documentType.icon; } /** @@ -154,7 +156,7 @@ export class UmbDocumentItemDataResolver extends UmbControllerBase { */ async getIsTrashed(): Promise { await this.#init; - return this.#item?.isTrashed ?? false; + return this.#data?.isTrashed ?? false; } #setVariantAwareValues() { @@ -183,12 +185,12 @@ export class UmbDocumentItemDataResolver extends UmbControllerBase { } #findVariant(culture: string | undefined) { - return this.#item?.variants.find((x) => x.culture === culture); + return this.#data?.variants.find((x) => x.culture === culture); } #getCurrentVariant() { if (this.#isInvariant()) { - return this.#item?.variants?.[0]; + return this.#data?.variants?.[0]; } const culture = this.#propertyDataSetCulture?.culture || this.#appCulture; @@ -196,6 +198,6 @@ export class UmbDocumentItemDataResolver extends UmbControllerBase { } #isInvariant() { - return this.#item?.variants?.[0]?.culture === null; + return this.#data?.variants?.[0]?.culture === null; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index c09ea737fe61..71f9d4e67be9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -13,11 +13,11 @@ export class UmbDocumentItemRefElement extends UmbLitElement { @property({ type: Object }) public get item(): UmbDocumentItemModel | undefined { - return this.#item.getItem(); + return this.#item.getData(); } public set item(value: UmbDocumentItemModel | undefined) { - const oldValue = this.#item.getItem(); - this.#item.setItem(value); + const oldValue = this.#item.getData(); + this.#item.setData(value); if (!value) { this.#modalRoute?.destroy(); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.context.ts index 673203bb8ef7..ee3b089159d5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.context.ts @@ -28,7 +28,7 @@ export class UmbDocumentTreeItemContext extends UmbDefaultTreeItemContext< public override setTreeItem(treeItem: UmbDocumentTreeItemModel | undefined) { super.setTreeItem(treeItem); - this.#item.setItem(treeItem); + this.#item.setData(treeItem); } } From a1444b5b2e8d70e1ec05d47a45bca62afe20b4a6 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 12 Feb 2025 20:29:56 +0100 Subject: [PATCH 060/145] pass model type --- .../column-layouts/document-table-column-state.element.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts index bf5e166df4d5..34f1085ecd0c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts @@ -1,4 +1,4 @@ -import type { UmbEditableDocumentCollectionItemModel } from '../../../types.js'; +import type { UmbDocumentCollectionItemModel, UmbEditableDocumentCollectionItemModel } from '../../../types.js'; import { UmbDocumentItemDataResolver } from '../../../../item/index.js'; import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; import { fromCamelCase } from '@umbraco-cms/backoffice/utils'; @@ -26,11 +26,11 @@ export class UmbDocumentTableColumnStateElement extends UmbLitElement implements @state() _state = ''; - #item = new UmbDocumentItemDataResolver(this); + #item = new UmbDocumentItemDataResolver(this); constructor() { super(); - this.#item.observe(this.#item.state, (state) => (this._state = state)); + this.#item.observe(this.#item.state, (state) => (this._state = state || '')); } override render() { From 41a0c112857fc1058e7ab587e497e9e1c9abfea0 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 12 Feb 2025 20:31:27 +0100 Subject: [PATCH 061/145] pass context type --- .../tree-item/tree-item-base/tree-item-element-base.ts | 9 ++++++--- .../tree/tree-item/document-tree-item.element.ts | 6 +++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item-base/tree-item-element-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item-base/tree-item-element-base.ts index b6f13bf61d6b..afce2cc3b2e9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item-base/tree-item-element-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item-base/tree-item-element-base.ts @@ -4,7 +4,10 @@ import { UMB_TREE_ITEM_CONTEXT } from './tree-item-context-base.js'; import { html, nothing, state, ifDefined, repeat, property } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -export abstract class UmbTreeItemElementBase extends UmbLitElement { +export abstract class UmbTreeItemElementBase< + TreeItemModelType extends UmbTreeItemModel, + TreeItemContextType extends UmbTreeItemContext = UmbTreeItemContext, +> extends UmbLitElement { _item?: TreeItemModelType; @property({ type: Object, attribute: false }) get item(): TreeItemModelType | undefined { @@ -51,14 +54,14 @@ export abstract class UmbTreeItemElementBase; + #treeItemContext?: TreeItemContextType; constructor() { super(); // TODO: Notice this can be retrieve via a api property. [NL] this.consumeContext(UMB_TREE_ITEM_CONTEXT, (instance) => { - this.#treeItemContext = instance; + this.#treeItemContext = instance as TreeItemContextType; if (!this.#treeItemContext) return; this.#initTreeItem(); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.element.ts index 018e1c8d00bf..e386dbd5fe78 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.element.ts @@ -1,10 +1,14 @@ import type { UmbDocumentTreeItemModel } from '../types.js'; +import type { UmbDocumentTreeItemContext } from './document-tree-item.context.js'; import { css, html, nothing, customElement, classMap, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UMB_TREE_ITEM_CONTEXT, UmbTreeItemElementBase } from '@umbraco-cms/backoffice/tree'; @customElement('umb-document-tree-item') -export class UmbDocumentTreeItemElement extends UmbTreeItemElementBase { +export class UmbDocumentTreeItemElement extends UmbTreeItemElementBase< + UmbDocumentTreeItemModel, + UmbDocumentTreeItemContext +> { @state() private _name = ''; From 9b3f45d65afa83e114bf4bb4dea33dff84da91b1 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 12 Feb 2025 20:47:09 +0100 Subject: [PATCH 062/145] use api prop instead of context --- .../tree-item-base/tree-item-element-base.ts | 76 +++++++++---------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item-base/tree-item-element-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item-base/tree-item-element-base.ts index afce2cc3b2e9..8cee44081d73 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item-base/tree-item-element-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/tree/tree-item/tree-item-base/tree-item-element-base.ts @@ -1,6 +1,5 @@ import type { UmbTreeItemContext } from '../index.js'; import type { UmbTreeItemModel } from '../../types.js'; -import { UMB_TREE_ITEM_CONTEXT } from './tree-item-context-base.js'; import { html, nothing, state, ifDefined, repeat, property } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; @@ -8,14 +7,40 @@ export abstract class UmbTreeItemElementBase< TreeItemModelType extends UmbTreeItemModel, TreeItemContextType extends UmbTreeItemContext = UmbTreeItemContext, > extends UmbLitElement { - _item?: TreeItemModelType; + protected _item?: TreeItemModelType; @property({ type: Object, attribute: false }) get item(): TreeItemModelType | undefined { return this._item; } set item(newVal: TreeItemModelType) { this._item = newVal; - this.#initTreeItem(); + + if (this._item) { + this.#initTreeItem(); + } + } + + #api: TreeItemContextType | undefined; + @property({ type: Object, attribute: false }) + public get api(): TreeItemContextType | undefined { + return this.#api; + } + public set api(value: TreeItemContextType | undefined) { + this.#api = value; + + if (this.#api) { + this.observe(this.#api.childItems, (value) => (this._childItems = value)); + this.observe(this.#api.hasChildren, (value) => (this._hasChildren = value)); + this.observe(this.#api.isActive, (value) => (this._isActive = value)); + this.observe(this.#api.isLoading, (value) => (this._isLoading = value)); + this.observe(this.#api.isSelectableContext, (value) => (this._isSelectableContext = value)); + this.observe(this.#api.isSelectable, (value) => (this._isSelectable = value)); + this.observe(this.#api.isSelected, (value) => (this._isSelected = value)); + this.observe(this.#api.path, (value) => (this._href = value)); + this.observe(this.#api.pagination.currentPage, (value) => (this._currentPage = value)); + this.observe(this.#api.pagination.totalPages, (value) => (this._totalPages = value)); + this.#initTreeItem(); + } } @property({ type: Boolean, attribute: false }) @@ -54,58 +79,31 @@ export abstract class UmbTreeItemElementBase< @state() private _currentPage = 1; - #treeItemContext?: TreeItemContextType; - - constructor() { - super(); - - // TODO: Notice this can be retrieve via a api property. [NL] - this.consumeContext(UMB_TREE_ITEM_CONTEXT, (instance) => { - this.#treeItemContext = instance as TreeItemContextType; - if (!this.#treeItemContext) return; - - this.#initTreeItem(); - - // TODO: investigate if we can make an observe decorator - this.observe(this.#treeItemContext.treeItem, (value) => (this._item = value)); - this.observe(this.#treeItemContext.childItems, (value) => (this._childItems = value)); - this.observe(this.#treeItemContext.hasChildren, (value) => (this._hasChildren = value)); - this.observe(this.#treeItemContext.isActive, (value) => (this._isActive = value)); - this.observe(this.#treeItemContext.isLoading, (value) => (this._isLoading = value)); - this.observe(this.#treeItemContext.isSelectableContext, (value) => (this._isSelectableContext = value)); - this.observe(this.#treeItemContext.isSelectable, (value) => (this._isSelectable = value)); - this.observe(this.#treeItemContext.isSelected, (value) => (this._isSelected = value)); - this.observe(this.#treeItemContext.path, (value) => (this._href = value)); - this.observe(this.#treeItemContext.pagination.currentPage, (value) => (this._currentPage = value)); - this.observe(this.#treeItemContext.pagination.totalPages, (value) => (this._totalPages = value)); - }); - } - #initTreeItem() { - if (!this.#treeItemContext) return; + if (!this.#api) return; if (!this._item) return; - this.#treeItemContext.setTreeItem(this._item); + this.#api.setTreeItem(this._item); } private _handleSelectedItem(event: Event) { event.stopPropagation(); - this.#treeItemContext?.select(); + this.#api?.select(); } private _handleDeselectedItem(event: Event) { event.stopPropagation(); - this.#treeItemContext?.deselect(); + this.#api?.deselect(); } // TODO: do we want to catch and emit a backoffice event here? private _onShowChildren() { - this.#treeItemContext?.loadChildren(); + this.#api?.loadChildren(); } #onLoadMoreClick = (event: any) => { event.stopPropagation(); const next = (this._currentPage = this._currentPage + 1); - this.#treeItemContext?.pagination.setCurrentPageNumber(next); + this.#api?.pagination.setCurrentPageNumber(next); }; // Note: Currently we want to prevent opening when the item is in a selectable context, but this might change in the future. @@ -171,11 +169,11 @@ export abstract class UmbTreeItemElementBase< #renderActions() { if (this.hideActions) return; - return this.#treeItemContext && this._item + return this.#api && this._item ? html` ` : ''; From c075debaa807494c80d996c8b2d2aa04793c2590 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 12 Feb 2025 20:55:11 +0100 Subject: [PATCH 063/145] use api prop instead of context --- .../tree-item/document-tree-item.element.ts | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.element.ts index e386dbd5fe78..eea98ba21a57 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/tree-item/document-tree-item.element.ts @@ -1,14 +1,31 @@ import type { UmbDocumentTreeItemModel } from '../types.js'; import type { UmbDocumentTreeItemContext } from './document-tree-item.context.js'; -import { css, html, nothing, customElement, classMap, state } from '@umbraco-cms/backoffice/external/lit'; +import { css, html, nothing, customElement, classMap, state, property } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { UMB_TREE_ITEM_CONTEXT, UmbTreeItemElementBase } from '@umbraco-cms/backoffice/tree'; +import { UmbTreeItemElementBase } from '@umbraco-cms/backoffice/tree'; @customElement('umb-document-tree-item') export class UmbDocumentTreeItemElement extends UmbTreeItemElementBase< UmbDocumentTreeItemModel, UmbDocumentTreeItemContext > { + #api: UmbDocumentTreeItemContext | undefined; + @property({ type: Object, attribute: false }) + public override get api(): UmbDocumentTreeItemContext | undefined { + return this.#api; + } + public override set api(value: UmbDocumentTreeItemContext | undefined) { + this.#api = value; + + if (this.#api) { + this.observe(this.#api.name, (name) => (this._name = name || '')); + this.observe(this.#api.isDraft, (isDraft) => (this._isDraft = isDraft || false)); + this.observe(this.#api.icon, (icon) => (this._icon = icon || '')); + } + + super.api = value; + } + @state() private _name = ''; @@ -18,16 +35,6 @@ export class UmbDocumentTreeItemElement extends UmbTreeItemElementBase< @state() private _icon = ''; - constructor() { - super(); - - this.consumeContext(UMB_TREE_ITEM_CONTEXT, (context) => { - this.observe(context.name, (name) => (this._name = name)); - this.observe(context.isDraft, (isDraft) => (this._isDraft = isDraft)); - this.observe(context.icon, (icon) => (this._icon = icon)); - }); - } - override renderIconContainer() { const icon = this._icon; const iconWithoutColor = icon?.split(' ')[0]; From cf34d1972f1a6a2fbdd5d3490565e1fd8449e783 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 12 Feb 2025 21:30:04 +0100 Subject: [PATCH 064/145] fix types --- .../column-layouts/document-table-column-state.element.ts | 2 +- .../documents/documents/item/document-item-data-resolver.ts | 4 ++-- .../documents/documents/item/document-item-ref.element.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts index 34f1085ecd0c..17b17dd9367e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts @@ -26,7 +26,7 @@ export class UmbDocumentTableColumnStateElement extends UmbLitElement implements @state() _state = ''; - #item = new UmbDocumentItemDataResolver(this); + #item = new UmbDocumentItemDataResolver(this); constructor() { super(); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts index 0243acff1472..6b790025a410 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts @@ -21,7 +21,7 @@ export class UmbDocumentItemDataResolver; @@ -73,7 +73,7 @@ export class UmbDocumentItemDataResolver(this); @property({ type: Object }) public get item(): UmbDocumentItemModel | undefined { From 1b04ec779d3cb6796d54f85a8d075d4427a9cc7a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 10:18:14 +0100 Subject: [PATCH 065/145] use addUniquePaths for modal registration --- .../item/document-item-ref.element.ts | 27 ++++++++++++------- .../member/item/member-item-ref.element.ts | 23 +++++++++------- .../user/user/item/user-item-ref.element.ts | 23 +++++++++------- 3 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index 85ffa9c94dbb..3b57e75ca9bd 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -31,16 +31,11 @@ export class UmbDocumentItemRefElement extends UmbLitElement { return; } - if (oldValue?.unique !== this.#item.unique) { - this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath(UMB_DOCUMENT_ENTITY_TYPE + '/' + this.#item.unique) - .onSetup(() => { - return { data: { entityType: UMB_DOCUMENT_ENTITY_TYPE, preset: {} } }; - }) - .observeRouteBuilder((routeBuilder) => { - this._editPath = routeBuilder({}); - }); + if (oldValue?.unique === this.#item.unique) { + return; } + + this.#modalRoute?.setUniquePathValue('unique', this.#item.unique); } @property({ type: Boolean }) @@ -54,6 +49,20 @@ export class UmbDocumentItemRefElement extends UmbLitElement { #modalRoute?: any; + constructor() { + super(); + + this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath(UMB_DOCUMENT_ENTITY_TYPE) + .addUniquePaths(['unique']) + .onSetup(() => { + return { data: { entityType: UMB_DOCUMENT_ENTITY_TYPE, preset: {} } }; + }) + .observeRouteBuilder((routeBuilder) => { + this._editPath = routeBuilder({}); + }); + } + #isDraft(item: UmbDocumentItemModel) { return item.variants[0]?.state === 'Draft'; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts index 08d2d8c940b9..2dbfb4848b5a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts @@ -24,16 +24,11 @@ export class UmbMemberItemRefElement extends UmbLitElement { this.#modalRoute?.destroy(); return; } - if (oldValue?.unique !== this.#item.unique) { - this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath(UMB_MEMBER_ENTITY_TYPE + '/' + this.#item.unique) - .onSetup(() => { - return { data: { entityType: UMB_MEMBER_ENTITY_TYPE, preset: {} } }; - }) - .observeRouteBuilder((routeBuilder) => { - this._editPath = routeBuilder({}); - }); + if (oldValue?.unique === this.#item.unique) { + return; } + + this.#modalRoute?.setUniquePathValue('unique', this.#item.unique); } @property({ type: Boolean }) @@ -63,6 +58,16 @@ export class UmbMemberItemRefElement extends UmbLitElement { }, }, ]); + + this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath(UMB_MEMBER_ENTITY_TYPE) + .addUniquePaths(['unique']) + .onSetup(() => { + return { data: { entityType: UMB_MEMBER_ENTITY_TYPE, preset: {} } }; + }) + .observeRouteBuilder((routeBuilder) => { + this._editPath = routeBuilder({}); + }); } #getHref(item: UmbMemberItemModel) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts index 6e3aa9be9436..f910931ba47c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts @@ -25,16 +25,11 @@ export class UmbUserItemRefElement extends UmbLitElement { return; } - if (oldValue?.unique !== this.#item.unique) { - this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath(UMB_USER_ENTITY_TYPE + '/' + this.#item.unique) - .onSetup(() => { - return { data: { entityType: UMB_USER_ENTITY_TYPE, preset: {} } }; - }) - .observeRouteBuilder((routeBuilder) => { - this._editPath = routeBuilder({}); - }); + if (oldValue?.unique === this.#item.unique) { + return; } + + this.#modalRoute?.setUniquePathValue('unique', this.#item.unique); } @property({ type: Boolean }) @@ -64,6 +59,16 @@ export class UmbUserItemRefElement extends UmbLitElement { }, }, ]); + + this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath(UMB_USER_ENTITY_TYPE) + .addUniquePaths(['unique']) + .onSetup(() => { + return { data: { entityType: UMB_USER_ENTITY_TYPE, preset: {} } }; + }) + .observeRouteBuilder((routeBuilder) => { + this._editPath = routeBuilder({}); + }); } #getHref(item: UmbUserItemModel) { From 1c8432ae4b81eddb74e93cb2898916ff80e5c27a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 10:57:05 +0100 Subject: [PATCH 066/145] add fallback --- .../repository/document-reference.server.data.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts index 795de9f54ecd..55de0de55f0b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts @@ -35,7 +35,13 @@ export class UmbDocumentReferenceServerDataSource extends UmbControllerBase { if (data) { const promises = data.items.map(async (item) => { const mapper = await this.#dataMapperResolver.resolve(item.$type); - return mapper ? mapper.map(item) : item; + return mapper + ? mapper.map(item) + : { + ...item, + unique: item.id, + entityType: 'unknown', + }; }); const items = await Promise.all(promises); From bafd96bd939754774c9e56eefc5eb292e3d532a2 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 11:13:19 +0100 Subject: [PATCH 067/145] use ref list --- ...-references-workspace-view-info.element.ts | 119 +++--------------- .../src/packages/relations/relations/types.ts | 4 + 2 files changed, 21 insertions(+), 102 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/info-app/document-references-workspace-view-info.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/info-app/document-references-workspace-view-info.element.ts index def6b92a8060..61910918bbdc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/info-app/document-references-workspace-view-info.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/info-app/document-references-workspace-view-info.element.ts @@ -1,20 +1,14 @@ import { UmbDocumentReferenceRepository } from '../repository/index.js'; import { UMB_DOCUMENT_WORKSPACE_CONTEXT } from '../../constants.js'; -import { css, customElement, html, nothing, repeat, state, when } from '@umbraco-cms/backoffice/external/lit'; -import { isDefaultReference, isDocumentReference, isMediaReference } from '@umbraco-cms/backoffice/relations'; +import { css, customElement, html, nothing, repeat, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; -import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; -import type { UmbReferenceModel } from '@umbraco-cms/backoffice/relations'; +import type { UmbReferenceItemModel } from '@umbraco-cms/backoffice/relations'; import type { UUIPaginationEvent } from '@umbraco-cms/backoffice/external/uui'; import type { UmbEntityUnique } from '@umbraco-cms/backoffice/entity'; @customElement('umb-document-references-workspace-info-app') export class UmbDocumentReferencesWorkspaceInfoAppElement extends UmbLitElement { - @state() - private _editDocumentPath = ''; - @state() private _currentPage = 1; @@ -22,7 +16,7 @@ export class UmbDocumentReferencesWorkspaceInfoAppElement extends UmbLitElement private _total = 0; @state() - private _items?: Array = []; + private _items?: Array = []; #itemsPerPage = 10; #referenceRepository = new UmbDocumentReferenceRepository(this); @@ -32,15 +26,6 @@ export class UmbDocumentReferencesWorkspaceInfoAppElement extends UmbLitElement constructor() { super(); - new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath('document') - .onSetup(() => { - return { data: { entityType: 'document', preset: {} } }; - }) - .observeRouteBuilder((routeBuilder) => { - this._editDocumentPath = routeBuilder({}); - }); - this.consumeContext(UMB_DOCUMENT_WORKSPACE_CONTEXT, (context) => { this.#workspaceContext = context; this.#observeDocumentUnique(); @@ -91,98 +76,28 @@ export class UmbDocumentReferencesWorkspaceInfoAppElement extends UmbLitElement this.#getReferences(); } - #getIcon(item: UmbReferenceModel) { - if (isDocumentReference(item)) { - return item.documentType.icon ?? 'icon-document'; - } - if (isMediaReference(item)) { - return item.mediaType.icon ?? 'icon-picture'; - } - if (isDefaultReference(item)) { - return item.icon ?? 'icon-document'; - } - return 'icon-document'; - } - - #getPublishedStatus(item: UmbReferenceModel) { - return isDocumentReference(item) ? item.published : true; - } - - #getContentTypeName(item: UmbReferenceModel) { - if (isDocumentReference(item)) { - return item.documentType.name; - } - if (isMediaReference(item)) { - return item.mediaType.name; - } - if (isDefaultReference(item)) { - return item.type; - } - return ''; - } - - #getContentType(item: UmbReferenceModel) { - if (isDocumentReference(item)) { - return item.documentType.alias; - } - if (isMediaReference(item)) { - return item.mediaType.alias; - } - if (isDefaultReference(item)) { - return item.type; - } - return ''; - } - override render() { if (!this._items?.length) return nothing; return html` - - - - Name - Status - Type Name - Type - - ${repeat( - this._items, - (item) => item.id, - (item) => html` - - - - - - ${when( - isDocumentReference(item), - () => html` - - ${item.name} - - `, - () => item.name, - )} - - - ${this.#getPublishedStatus(item) - ? this.localize.term('content_published') - : this.localize.term('content_unpublished')} - - ${this.#getContentTypeName(item)} - ${this.#getContentType(item)} - - `, - )} - - ${this.#renderReferencePagination()} + ${this.#renderItems()} ${this.#renderReferencePagination()} `; } + #renderItems() { + if (!this._items) return; + return html` + + ${repeat( + this._items, + (item) => item.unique, + (item) => html``, + )} + + `; + } + #renderReferencePagination() { if (!this._total) return nothing; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/types.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/types.ts index 08536e1a3f76..cf7867b4dc33 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/types.ts @@ -1,4 +1,5 @@ import type { UmbRelationEntityType } from './entity.js'; +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; import type { DefaultReferenceResponseModel, DocumentReferenceResponseModel, @@ -23,6 +24,9 @@ export interface UmbRelationDetailModel { comment: string | null; } +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +export interface UmbReferenceItemModel extends UmbEntityModel {} + export type UmbReferenceModel = | DefaultReferenceResponseModel | DocumentReferenceResponseModel From 870cd86788e291d82965b6059eed64508f07a8a8 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 11:28:16 +0100 Subject: [PATCH 068/145] use reference items for media --- .../document-reference.server.data.ts | 12 +- ...a-references-workspace-info-app.element.ts | 106 ++---------------- .../repository/media-reference.server.data.ts | 44 +++++--- 3 files changed, 37 insertions(+), 125 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts index 55de0de55f0b..234c2317177a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts @@ -1,5 +1,4 @@ import { DocumentService } from '@umbraco-cms/backoffice/external/backend-api'; -import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import { UmbDataMapperResolver } from '@umbraco-cms/backoffice/repository'; @@ -11,18 +10,9 @@ import { UmbDataMapperResolver } from '@umbraco-cms/backoffice/repository'; export class UmbDocumentReferenceServerDataSource extends UmbControllerBase { #dataMapperResolver = new UmbDataMapperResolver(this); - /** - * Creates an instance of UmbDocumentReferenceServerDataSource. - * @param {UmbControllerHost} host - The controller host for this controller to be appended to - * @memberof UmbDocumentReferenceServerDataSource - */ - constructor(host: UmbControllerHost) { - super(host); - } - /** * Fetches the item for the given unique from the server - * @param {string} unique + * @param {string} unique - The unique identifier of the item to fetch * @returns {*} * @memberof UmbDocumentReferenceServerDataSource */ diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/info-app/media-references-workspace-info-app.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/info-app/media-references-workspace-info-app.element.ts index e552b8554071..f65a8c83c3c1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/info-app/media-references-workspace-info-app.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/info-app/media-references-workspace-info-app.element.ts @@ -1,13 +1,9 @@ import { UmbMediaReferenceRepository } from '../repository/index.js'; import { UMB_MEDIA_WORKSPACE_CONTEXT } from '../../workspace/constants.js'; import { css, customElement, html, nothing, repeat, state, when } from '@umbraco-cms/backoffice/external/lit'; -import { isDefaultReference, isDocumentReference, isMediaReference } from '@umbraco-cms/backoffice/relations'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; -import type { UmbReferenceModel } from '@umbraco-cms/backoffice/relations'; -import type { UmbModalRouteBuilder } from '@umbraco-cms/backoffice/router'; +import type { UmbReferenceItemModel, UmbReferenceModel } from '@umbraco-cms/backoffice/relations'; import type { UUIPaginationEvent } from '@umbraco-cms/backoffice/external/uui'; import type { UmbEntityUnique } from '@umbraco-cms/backoffice/entity'; @@ -17,8 +13,6 @@ export class UmbMediaReferencesWorkspaceInfoAppElement extends UmbLitElement { #referenceRepository; - #routeBuilder?: UmbModalRouteBuilder; - @state() private _currentPage = 1; @@ -26,7 +20,7 @@ export class UmbMediaReferencesWorkspaceInfoAppElement extends UmbLitElement { private _total = 0; @state() - private _items?: Array = []; + private _items?: Array = []; @state() private _loading = true; @@ -38,15 +32,6 @@ export class UmbMediaReferencesWorkspaceInfoAppElement extends UmbLitElement { super(); this.#referenceRepository = new UmbMediaReferenceRepository(this); - new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath(':entityType') - .onSetup((params) => { - return { data: { entityType: params.entityType, preset: {} } }; - }) - .observeRouteBuilder((routeBuilder) => { - this.#routeBuilder = routeBuilder; - }); - this.consumeContext(UMB_MEDIA_WORKSPACE_CONTEXT, (context) => { this.#workspaceContext = context; this.#observeMediaUnique(); @@ -106,54 +91,6 @@ export class UmbMediaReferencesWorkspaceInfoAppElement extends UmbLitElement { this.#getReferences(); } - #getEditPath(item: UmbReferenceModel) { - const entityType = this.#getEntityType(item); - return this.#routeBuilder && entityType ? `${this.#routeBuilder({ entityType })}edit/${item.id}` : '#'; - } - - #getIcon(item: UmbReferenceModel) { - if (isDocumentReference(item)) { - return item.documentType.icon ?? 'icon-document'; - } - if (isMediaReference(item)) { - return item.mediaType.icon ?? 'icon-picture'; - } - if (isDefaultReference(item)) { - return item.icon ?? 'icon-document'; - } - return 'icon-document'; - } - - #getPublishedStatus(item: UmbReferenceModel) { - return isDocumentReference(item) ? item.published : true; - } - - #getContentTypeName(item: UmbReferenceModel) { - if (isDocumentReference(item)) { - return item.documentType.name; - } - if (isMediaReference(item)) { - return item.mediaType.name; - } - if (isDefaultReference(item)) { - return item.type; - } - return null; - } - - #getEntityType(item: UmbReferenceModel) { - if (isDocumentReference(item)) { - return 'document'; - } - if (isMediaReference(item)) { - return 'media'; - } - if (isDefaultReference(item)) { - return item.type; - } - return null; - } - override render() { if (!this._items?.length) return nothing; return html` @@ -168,44 +105,15 @@ export class UmbMediaReferencesWorkspaceInfoAppElement extends UmbLitElement { } #renderItems() { - if (!this._items?.length) return nothing; + if (!this._items) return; return html` - - - Name - Status - Type Name - Type - + ${repeat( this._items, - (item) => item.id, - (item) => html` - - - - - - - - ${when( - this.#getPublishedStatus(item), - () => - html`${this.localize.term('content_published')}`, - () => - html`${this.localize.term('content_unpublished')}`, - )} - - ${this.#getContentTypeName(item)} - ${this.#getEntityType(item)} - - `, + (item) => item.unique, + (item) => html``, )} - + `; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts index 5ff12c10e5d6..c3355f19fcb7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts @@ -1,30 +1,44 @@ -import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import { MediaService } from '@umbraco-cms/backoffice/external/backend-api'; +import { UmbDataMapperResolver } from '@umbraco-cms/backoffice/repository'; import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** * @class UmbMediaReferenceServerDataSource * @implements {RepositoryDetailDataSource} */ -export class UmbMediaReferenceServerDataSource { - #host: UmbControllerHost; - - /** - * Creates an instance of UmbMediaReferenceServerDataSource. - * @param {UmbControllerHost} host - The controller host for this controller to be appended to - * @memberof UmbMediaReferenceServerDataSource - */ - constructor(host: UmbControllerHost) { - this.#host = host; - } +export class UmbMediaReferenceServerDataSource extends UmbControllerBase { + #dataMapperResolver = new UmbDataMapperResolver(this); /** * Fetches the item for the given id from the server - * @param {Array} ids + * @param {string} unique - The unique identifier of the item to fetch * @returns {*} * @memberof UmbMediaReferenceServerDataSource */ - async getReferencedBy(id: string, skip = 0, take = 20) { - return await tryExecuteAndNotify(this.#host, MediaService.getMediaByIdReferencedBy({ id, skip, take })); + async getReferencedBy(unique: string, skip = 0, take = 20) { + const { data, error } = await tryExecuteAndNotify( + this, + MediaService.getMediaByIdReferencedBy({ id: unique, skip, take }), + ); + + if (data) { + const promises = data.items.map(async (item) => { + const mapper = await this.#dataMapperResolver.resolve(item.$type); + return mapper + ? mapper.map(item) + : { + ...item, + unique: item.id, + entityType: 'unknown', + }; + }); + + const items = await Promise.all(promises); + + return { data: { items, total: data.total } }; + } + + return { data, error }; } } From f43e32e59aead98432fc21c4e22926897c958715 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 12:54:34 +0100 Subject: [PATCH 069/145] make mapper name more generic --- .../data-mapper/data-mapper-resolver.ts | 16 ++++++++-------- .../data-mapper/data-mapper.extension.ts | 8 ++++---- .../core/repository/data-mapper/types.ts | 12 ++---------- .../documents/reference/repository/manifests.ts | 6 +++--- .../media/reference/repository/manifests.ts | 6 +++--- 5 files changed, 20 insertions(+), 28 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper-resolver.ts index 50ffcfc95d9c..2ce30bc3753d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper-resolver.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper-resolver.ts @@ -6,12 +6,12 @@ import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registr export class UmbDataMapperResolver extends UmbControllerBase { #apiCache = new Map(); - async resolve($type: string): Promise { - if (!$type) { + async resolve(identifier: string): Promise { + if (!identifier) { throw new Error('data is required'); } - const manifest = this.#getManifestWithBestFit($type); + const manifest = this.#getManifestWithBestFit(identifier); if (!manifest) { return undefined; @@ -38,8 +38,8 @@ export class UmbDataMapperResolver extends UmbControllerBase { return dataMapper; } - #getManifestWithBestFit($type: string) { - const supportedManifests = this.#getSupportedManifests($type); + #getManifestWithBestFit(identifier: string) { + const supportedManifests = this.#getSupportedManifests(identifier); if (!supportedManifests.length) { return undefined; @@ -49,9 +49,9 @@ export class UmbDataMapperResolver extends UmbControllerBase { return supportedManifests.sort((a: ManifestBase, b: ManifestBase): number => (b.weight || 0) - (a.weight || 0))[0]; } - #getSupportedManifests($type: string) { - const supportedManifests = umbExtensionsRegistry.getByTypeAndFilter('$typeDataMapper', (manifest) => { - return manifest.from$type === $type; + #getSupportedManifests(identifier: string) { + const supportedManifests = umbExtensionsRegistry.getByTypeAndFilter('dataMapper', (manifest) => { + return manifest.identifier === identifier; }); return supportedManifests; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.extension.ts index 0db57c414642..40c4946a56e3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.extension.ts @@ -1,12 +1,12 @@ import type { UmbDataMapper } from './types.js'; import type { ManifestApi, ManifestWithDynamicConditions } from '@umbraco-cms/backoffice/extension-api'; -export interface Manifest$TypeDataMapper +export interface ManifestDataMapper extends ManifestApi, ManifestWithDynamicConditions { - type: '$typeDataMapper'; + type: 'dataMapper'; meta: MetaType; - from$type: string; + identifier: string; } // eslint-disable-next-line @typescript-eslint/no-empty-object-type @@ -14,6 +14,6 @@ export interface MetaDataMapper {} declare global { interface UmbExtensionManifestMap { - umbManifest$TypeDataMapper: Manifest$TypeDataMapper; + umbManifestDataMapper: ManifestDataMapper; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/types.ts index ce10076c8472..2b7ac0ac88fb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/types.ts @@ -1,13 +1,5 @@ -import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; -export interface UmbServerResponseModel { - $type: string; -} - -export interface UmbDataMapper< - ServerModelType extends UmbServerResponseModel = UmbServerResponseModel, - ClientModelType extends UmbEntityModel = UmbEntityModel, -> extends UmbApi { - map: (data: ServerModelType) => Promise; +export interface UmbDataMapper extends UmbApi { + map: (data: fromModelType) => Promise; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts index 5fab41096a80..d354816f91df 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts @@ -8,10 +8,10 @@ export const manifests: Array = [ api: () => import('./document-reference.repository.js'), }, { - type: '$typeDataMapper', - alias: 'Umb.$typeDataMapper.DocumentReferenceResponseModel', + type: 'dataMapper', + alias: 'Umb.DataMapper.DocumentReferenceResponseModel', name: 'Document Reference Response Model to Client Model Data Mapper', api: () => import('./document-reference-response-model.mapper.js'), - from$type: 'DocumentReferenceResponseModel', + identifier: 'DocumentReferenceResponseModel', }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts index e53d4bebb6dc..c7bbb8af2b5c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts @@ -8,10 +8,10 @@ export const manifests: Array = [ api: () => import('./media-reference.repository.js'), }, { - type: '$typeDataMapper', - alias: 'Umb.$typeDataMapper.MediaReferenceResponseModel', + type: 'dataMapper', + alias: 'Umb.DataMapper.MediaReferenceResponseModel', name: 'Media Reference Response Model to Client Model Data Mapper', api: () => import('./media-reference-response-model.mapper.js'), - from$type: 'MediaReferenceResponseModel', + identifier: 'MediaReferenceResponseModel', }, ]; From bb039685f2fbe91c58191b0b0ec38b23acb398ed Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 12:55:03 +0100 Subject: [PATCH 070/145] make default ref item always readonly --- .../core/entity/entity-item-ref/default-item-ref.element.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/default-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/default-item-ref.element.ts index 25c32cafd65a..44c750fe70d6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/default-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/default-item-ref.element.ts @@ -7,9 +7,6 @@ export class UmbDefaultItemRefElement extends UmbLitElement { @property({ type: Object }) item?: UmbDefaultItemModel; - @property({ type: Boolean }) - readonly = false; - @property({ type: Boolean }) standalone = false; @@ -17,7 +14,7 @@ export class UmbDefaultItemRefElement extends UmbLitElement { if (!this.item) return nothing; return html` - + ${this.#renderIcon(this.item)} From fbf9f2f867ec0d0780d97d49e5815c1b7b8e54fe Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 12:55:15 +0100 Subject: [PATCH 071/145] export types --- .../src/packages/documents/documents/item/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/types.ts index 281be3f829a9..e32ac4b889fe 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/types.ts @@ -1 +1 @@ -export type { UmbDocumentItemModel } from './repository/types.js'; +export type * from './repository/types.js'; From 75face7e78ca5f0639c1af180ac60f6a0b581120 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 12:55:39 +0100 Subject: [PATCH 072/145] temp fake variants array --- .../document-reference-response-model.mapper.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response-model.mapper.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response-model.mapper.ts index c81010b443e8..8ec38b1a2226 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response-model.mapper.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response-model.mapper.ts @@ -1,6 +1,9 @@ import type { UmbDocumentReferenceModel } from '../types.js'; import { UMB_DOCUMENT_ENTITY_TYPE } from '../../entity.js'; -import type { DocumentReferenceResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; +import { + DocumentVariantStateModel, + type DocumentReferenceResponseModel, +} from '@umbraco-cms/backoffice/external/backend-api'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbDataMapper } from '@umbraco-cms/backoffice/repository'; @@ -19,6 +22,14 @@ export class UmbDocumentReferenceResponseModelMapper id: data.id, name: data.name, published: data.published, + // TODO: this is a hardcoded array until the server can return the correct variants array + variants: [ + { + culture: null, + name: data.name ?? '', + state: data.published ? DocumentVariantStateModel.PUBLISHED : null, + }, + ], unique: data.id, }; } From 63e03ace30ddd92b8009c00906b6d8e7f5fb7f66 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 12:55:50 +0100 Subject: [PATCH 073/145] add variants array to model --- .../src/packages/documents/documents/reference/types.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/types.ts index dde29a3f23bb..90496f5d8778 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/types.ts @@ -1,3 +1,4 @@ +import type { UmbDocumentItemVariantModel } from '../item/types.js'; import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; import type { TrackedReferenceDocumentTypeModel } from '@umbraco-cms/backoffice/external/backend-api'; @@ -23,4 +24,5 @@ export interface UmbDocumentReferenceModel extends UmbEntityModel { */ published?: boolean | null; documentType: TrackedReferenceDocumentTypeModel; + variants: Array; } From 575f3b22c11054fb2637ff8369c852fccb8055f2 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 12:56:27 +0100 Subject: [PATCH 074/145] Update media-references-workspace-info-app.element.ts --- .../info-app/media-references-workspace-info-app.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/info-app/media-references-workspace-info-app.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/info-app/media-references-workspace-info-app.element.ts index f65a8c83c3c1..b1f46e6fd9f8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/info-app/media-references-workspace-info-app.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/info-app/media-references-workspace-info-app.element.ts @@ -3,7 +3,7 @@ import { UMB_MEDIA_WORKSPACE_CONTEXT } from '../../workspace/constants.js'; import { css, customElement, html, nothing, repeat, state, when } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import type { UmbReferenceItemModel, UmbReferenceModel } from '@umbraco-cms/backoffice/relations'; +import type { UmbReferenceItemModel } from '@umbraco-cms/backoffice/relations'; import type { UUIPaginationEvent } from '@umbraco-cms/backoffice/external/uui'; import type { UmbEntityUnique } from '@umbraco-cms/backoffice/entity'; From 81a0805e92251d80bf0bf967ea1dd9a47fc136a2 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 13:07:38 +0100 Subject: [PATCH 075/145] add variants to model --- .../src/packages/media/media/reference/repository/types.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/types.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/types.ts index 02ae250ed881..69220e630167 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/types.ts @@ -1,3 +1,4 @@ +import type { UmbMediaItemVariantModel } from '../../repository/item/types.js'; import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; import type { TrackedReferenceMediaTypeModel } from '@umbraco-cms/backoffice/external/backend-api'; @@ -23,4 +24,5 @@ export interface UmbMediaReferenceModel extends UmbEntityModel { */ published?: boolean | null; mediaType: TrackedReferenceMediaTypeModel; + variants: Array; } From 934e03b345546e7ed9b759b57411444b936d5673 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 13:07:53 +0100 Subject: [PATCH 076/145] hardcode fake array --- .../repository/media-reference-response-model.mapper.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response-model.mapper.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response-model.mapper.ts index 2fe4c99adc33..61c6ccf2ae29 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response-model.mapper.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response-model.mapper.ts @@ -18,6 +18,13 @@ export class UmbMediaReferenceResponseModelMapper name: data.mediaType.name, }, name: data.name, + // TODO: this is a hardcoded array until the server can return the correct variants array + variants: [ + { + culture: null, + name: data.name ?? '', + }, + ], unique: data.id, }; } From 54814c19bf18aecc0955f5896aa128d0d7e19be0 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 13:53:57 +0100 Subject: [PATCH 077/145] register media ref item --- .../packages/media/media/item/manifests.ts | 11 ++ .../media/item/media-item-ref.element.ts | 104 ++++++++++++++++++ .../src/packages/media/media/manifests.ts | 2 + 3 files changed, 117 insertions(+) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/media/media/item/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/manifests.ts new file mode 100644 index 000000000000..ceb7c57fb02c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/manifests.ts @@ -0,0 +1,11 @@ +import { UMB_MEDIA_ENTITY_TYPE } from '../entity.js'; + +export const manifests: Array = [ + { + type: 'entityItemRef', + alias: 'Umb.EntityItemRef.Media', + name: 'Member Entity Item Reference', + element: () => import('./media-item-ref.element.js'), + forEntityTypes: [UMB_MEDIA_ENTITY_TYPE], + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts new file mode 100644 index 000000000000..5a0e9bc695a9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts @@ -0,0 +1,104 @@ +import type { UmbMediaItemModel } from '../repository/types.js'; +import { UMB_MEDIA_SECTION_ALIAS } from '../../media-section/constants.js'; +import { UMB_MEDIA_ENTITY_TYPE } from '../entity.js'; +import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; +import { customElement, html, ifDefined, nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; +import { UMB_SECTION_USER_PERMISSION_CONDITION_ALIAS } from '@umbraco-cms/backoffice/section'; +import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; + +@customElement('umb-media-item-ref') +export class UmbMediaItemRefElement extends UmbLitElement { + #item?: UmbMediaItemModel | undefined; + + @property({ type: Object }) + public get item(): UmbMediaItemModel | undefined { + return this.#item; + } + public set item(value: UmbMediaItemModel | undefined) { + const oldValue = this.#item; + this.#item = value; + + if (!this.#item) { + this.#modalRoute?.destroy(); + return; + } + if (oldValue?.unique === this.#item.unique) { + return; + } + + this.#modalRoute?.setUniquePathValue('unique', this.#item.unique); + } + + @property({ type: Boolean }) + readonly = false; + + @property({ type: Boolean }) + standalone = false; + + @state() + _editPath = ''; + + @state() + _userHasSectionAccess = false; + + #modalRoute?: any; + + constructor() { + super(); + + createExtensionApiByAlias(this, UMB_SECTION_USER_PERMISSION_CONDITION_ALIAS, [ + { + config: { + match: UMB_MEDIA_SECTION_ALIAS, + }, + onChange: (permitted: boolean) => { + this._userHasSectionAccess = permitted; + }, + }, + ]); + + this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addAdditionalPath(UMB_MEDIA_ENTITY_TYPE) + .addUniquePaths(['unique']) + .onSetup(() => { + return { data: { entityType: UMB_MEDIA_ENTITY_TYPE, preset: {} } }; + }) + .observeRouteBuilder((routeBuilder) => { + this._editPath = routeBuilder({}); + }); + } + + #getHref(item: UmbMediaItemModel) { + return `${this._editPath}/edit/${item.unique}`; + } + + override render() { + if (!this.item) return nothing; + + return html` + + + ${this.#renderIcon(this.item)} + + `; + } + + #renderIcon(item: UmbMediaItemModel) { + if (!item.mediaType.icon) return; + return html``; + } +} + +export { UmbMediaItemRefElement as element }; + +declare global { + interface HTMLElementTagNameMap { + 'umb-media-item-ref': UmbMediaItemRefElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/manifests.ts index 1b61cda60755..69738473e5f2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/manifests.ts @@ -4,6 +4,7 @@ import { manifests as dropzoneManifests } from './dropzone/manifests.js'; import { manifests as entityActionsManifests } from './entity-actions/manifests.js'; import { manifests as entityBulkActionsManifests } from './entity-bulk-actions/manifests.js'; import { manifests as fileUploadPreviewManifests } from './components/input-upload-field/manifests.js'; +import { manifests as itemManifests } from './item/manifests.js'; import { manifests as menuManifests } from './menu/manifests.js'; import { manifests as modalManifests } from './modals/manifests.js'; import { manifests as propertyEditorsManifests } from './property-editors/manifests.js'; @@ -23,6 +24,7 @@ export const manifests: Array = [ ...entityActionsManifests, ...entityBulkActionsManifests, ...fileUploadPreviewManifests, + ...itemManifests, ...menuManifests, ...modalManifests, ...propertyEditorsManifests, From bbc5fee737a86ed9ffa8e5e226f2ecbdf97402d1 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 13:56:19 +0100 Subject: [PATCH 078/145] update mock data --- .../src/mocks/data/tracked-reference.data.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/mocks/data/tracked-reference.data.ts b/src/Umbraco.Web.UI.Client/src/mocks/data/tracked-reference.data.ts index 868f48c3e720..ef12fcc0cbc8 100644 --- a/src/Umbraco.Web.UI.Client/src/mocks/data/tracked-reference.data.ts +++ b/src/Umbraco.Web.UI.Client/src/mocks/data/tracked-reference.data.ts @@ -8,6 +8,7 @@ export const items: Array< DefaultReferenceResponseModel | DocumentReferenceResponseModel | MediaReferenceResponseModel > = [ { + $type: 'DocumentReferenceResponseModel', id: 'simple-document-id', name: 'Simple Document', published: true, @@ -18,6 +19,7 @@ export const items: Array< }, } satisfies DocumentReferenceResponseModel, { + $type: 'MediaReferenceResponseModel', id: '1234', name: 'Image Block', published: true, @@ -28,6 +30,7 @@ export const items: Array< }, } satisfies DocumentReferenceResponseModel, { + $type: 'MediaReferenceResponseModel', id: 'media-id', name: 'Simple Media', mediaType: { @@ -37,6 +40,7 @@ export const items: Array< }, } satisfies MediaReferenceResponseModel, { + $type: 'DefaultReferenceResponseModel', id: 'default-id', name: 'Some other reference', type: 'Default', From 193d93a41b5c71703f98a001538cb4fb3032a6e6 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 14:14:21 +0100 Subject: [PATCH 079/145] dot not allow conditions for data mappers --- .../core/repository/data-mapper/data-mapper.extension.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.extension.ts index 40c4946a56e3..1269562f3f6b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.extension.ts @@ -1,12 +1,11 @@ import type { UmbDataMapper } from './types.js'; -import type { ManifestApi, ManifestWithDynamicConditions } from '@umbraco-cms/backoffice/extension-api'; +import type { ManifestApi } from '@umbraco-cms/backoffice/extension-api'; export interface ManifestDataMapper - extends ManifestApi, - ManifestWithDynamicConditions { + extends ManifestApi { type: 'dataMapper'; - meta: MetaType; identifier: string; + meta: MetaType; } // eslint-disable-next-line @typescript-eslint/no-empty-object-type From 57b11457e19a049f2fc2275725e139333b1ea24f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 14:57:46 +0100 Subject: [PATCH 080/145] add data mapper --- .../repository/data-mapper/data-mapper.ts | 38 +++++++++++++++++++ .../core/repository/data-mapper/index.ts | 1 + .../document-reference.server.data.ts | 15 +++++--- .../repository/media-reference.server.data.ts | 15 +++++--- 4 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.ts new file mode 100644 index 000000000000..08c9e9f6c032 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.ts @@ -0,0 +1,38 @@ +import { UmbDataMapperResolver } from './data-mapper-resolver.js'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; + +export interface UmbDataMapperMapArgs { + identifier: string; + data: fromModelType; + fallback?: (data: fromModelType) => Promise; +} + +export class UmbDataMapper extends UmbControllerBase { + #dataMapperResolver = new UmbDataMapperResolver(this); + + async map(args: UmbDataMapperMapArgs) { + if (!args.identifier) { + throw new Error('identifier is required'); + } + + if (!args.data) { + throw new Error('data is required'); + } + + const mapper = await this.#dataMapperResolver.resolve(args.identifier); + + if (!mapper && !args.fallback) { + throw new Error('Data Mapper not found and no fallback provided.'); + } + + if (!mapper && args.fallback) { + return args.fallback(args.data); + } + + if (!mapper?.map) { + throw new Error('Data Mapper does not have a map method.'); + } + + return mapper.map(args.data); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts index 843267ab4e42..acfa9fb37064 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts @@ -1 +1,2 @@ export * from './data-mapper-resolver.js'; +export * from './data-mapper.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts index 234c2317177a..e9ff572164ff 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts @@ -1,14 +1,14 @@ import { DocumentService } from '@umbraco-cms/backoffice/external/backend-api'; import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; -import { UmbDataMapperResolver } from '@umbraco-cms/backoffice/repository'; +import { UmbDataMapper } from '@umbraco-cms/backoffice/repository'; /** * @class UmbDocumentReferenceServerDataSource * @implements {RepositoryDetailDataSource} */ export class UmbDocumentReferenceServerDataSource extends UmbControllerBase { - #dataMapperResolver = new UmbDataMapperResolver(this); + #dataMapper = new UmbDataMapper(this); /** * Fetches the item for the given unique from the server @@ -24,14 +24,17 @@ export class UmbDocumentReferenceServerDataSource extends UmbControllerBase { if (data) { const promises = data.items.map(async (item) => { - const mapper = await this.#dataMapperResolver.resolve(item.$type); - return mapper - ? mapper.map(item) - : { + return this.#dataMapper.map({ + identifier: item.$type, + data: item, + fallback: async () => { + return { ...item, unique: item.id, entityType: 'unknown', }; + }, + }); }); const items = await Promise.all(promises); diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts index c3355f19fcb7..7384c9d75fce 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts @@ -1,6 +1,6 @@ import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import { MediaService } from '@umbraco-cms/backoffice/external/backend-api'; -import { UmbDataMapperResolver } from '@umbraco-cms/backoffice/repository'; +import { UmbDataMapper } from '@umbraco-cms/backoffice/repository'; import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** @@ -8,7 +8,7 @@ import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; * @implements {RepositoryDetailDataSource} */ export class UmbMediaReferenceServerDataSource extends UmbControllerBase { - #dataMapperResolver = new UmbDataMapperResolver(this); + #dataMapper = new UmbDataMapper(this); /** * Fetches the item for the given id from the server @@ -24,14 +24,17 @@ export class UmbMediaReferenceServerDataSource extends UmbControllerBase { if (data) { const promises = data.items.map(async (item) => { - const mapper = await this.#dataMapperResolver.resolve(item.$type); - return mapper - ? mapper.map(item) - : { + return this.#dataMapper.map({ + identifier: item.$type, + data: item, + fallback: async () => { + return { ...item, unique: item.id, entityType: 'unknown', }; + }, + }); }); const items = await Promise.all(promises); From 5f9d9d41da98396c857f94e324a54d649c97b10a Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 16:58:38 +0100 Subject: [PATCH 081/145] prefix info routes --- .../views/info/document-workspace-view-info.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/info/document-workspace-view-info.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/info/document-workspace-view-info.element.ts index d21a6a2fcd3c..88babb91daf0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/info/document-workspace-view-info.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/views/info/document-workspace-view-info.element.ts @@ -60,7 +60,7 @@ export class UmbDocumentWorkspaceViewInfoElement extends UmbLitElement { super(); new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath(':entityType') + .addAdditionalPath('general/:entityType') .onSetup((params) => { return { data: { entityType: params.entityType, preset: {} } }; }) From a73116021cb27a33a6c511e8645e8e7af2998cde Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 16:59:37 +0100 Subject: [PATCH 082/145] prefix all ref routes --- .../core/entity/entity-item-ref/entity-item-ref.element.ts | 5 +++++ .../documents/documents/item/document-item-ref.element.ts | 4 ---- .../src/packages/media/media/item/media-item-ref.element.ts | 4 ---- .../packages/members/member/item/member-item-ref.element.ts | 4 ---- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts index a76e1c36c062..de07c6a3d5f1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts @@ -7,6 +7,7 @@ import { UMB_MARK_ATTRIBUTE_NAME } from '@umbraco-cms/backoffice/const'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import './default-item-ref.element.js'; +import { UmbRoutePathAddendumContext } from '@umbraco-cms/backoffice/router'; @customElement('umb-entity-item-ref') export class UmbEntityItemRefElement extends UmbLitElement { @@ -33,6 +34,8 @@ export class UmbEntityItemRefElement extends UmbLitElement { return; } + this.#pathAddendum.setAddendum('ref/' + value.entityType + '/' + value.unique); + // If the component is already created, but the entity type is different, we need to destroy the component. this.#createController(value.entityType); } @@ -63,6 +66,8 @@ export class UmbEntityItemRefElement extends UmbLitElement { } } + #pathAddendum = new UmbRoutePathAddendumContext(this); + protected override firstUpdated(_changedProperties: PropertyValueMap | Map): void { super.firstUpdated(_changedProperties); this.setAttribute(UMB_MARK_ATTRIBUTE_NAME, 'entity-item-ref'); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index c83c1ed167a2..288a9d793360 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -27,8 +27,6 @@ export class UmbDocumentItemRefElement extends UmbLitElement { if (oldValue?.unique === value.unique) { return; } - - this.#modalRoute?.setUniquePathValue('unique', value.unique); } @property({ type: Boolean }) @@ -70,8 +68,6 @@ export class UmbDocumentItemRefElement extends UmbLitElement { super(); this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath(UMB_DOCUMENT_ENTITY_TYPE) - .addUniquePaths(['unique']) .onSetup(() => { return { data: { entityType: UMB_DOCUMENT_ENTITY_TYPE, preset: {} } }; }) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts index 5a0e9bc695a9..1350af9e7e6c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts @@ -27,8 +27,6 @@ export class UmbMediaItemRefElement extends UmbLitElement { if (oldValue?.unique === this.#item.unique) { return; } - - this.#modalRoute?.setUniquePathValue('unique', this.#item.unique); } @property({ type: Boolean }) @@ -60,8 +58,6 @@ export class UmbMediaItemRefElement extends UmbLitElement { ]); this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath(UMB_MEDIA_ENTITY_TYPE) - .addUniquePaths(['unique']) .onSetup(() => { return { data: { entityType: UMB_MEDIA_ENTITY_TYPE, preset: {} } }; }) diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts index 2dbfb4848b5a..769fdf015042 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts @@ -27,8 +27,6 @@ export class UmbMemberItemRefElement extends UmbLitElement { if (oldValue?.unique === this.#item.unique) { return; } - - this.#modalRoute?.setUniquePathValue('unique', this.#item.unique); } @property({ type: Boolean }) @@ -60,8 +58,6 @@ export class UmbMemberItemRefElement extends UmbLitElement { ]); this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath(UMB_MEMBER_ENTITY_TYPE) - .addUniquePaths(['unique']) .onSetup(() => { return { data: { entityType: UMB_MEMBER_ENTITY_TYPE, preset: {} } }; }) From ddbec2a14acffcdf68282fa6dcf93baec7a68559 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 13 Feb 2025 21:06:45 +0100 Subject: [PATCH 083/145] return undefined if there is not edit path --- .../documents/documents/item/document-item-ref.element.ts | 1 + .../src/packages/media/media/item/media-item-ref.element.ts | 1 + .../src/packages/members/member/item/member-item-ref.element.ts | 1 + 3 files changed, 3 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index 288a9d793360..65b8cdb3787a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -83,6 +83,7 @@ export class UmbDocumentItemRefElement extends UmbLitElement { } #getHref() { + if (!this._editPath) return; return `${this._editPath}/edit/${this._unique}`; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts index 1350af9e7e6c..2b7aade2c369 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts @@ -67,6 +67,7 @@ export class UmbMediaItemRefElement extends UmbLitElement { } #getHref(item: UmbMediaItemModel) { + if (!this._editPath) return; return `${this._editPath}/edit/${item.unique}`; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts index 769fdf015042..5ed664278a0e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts @@ -67,6 +67,7 @@ export class UmbMemberItemRefElement extends UmbLitElement { } #getHref(item: UmbMemberItemModel) { + if (!this._editPath) return; return `${this._editPath}/edit/${item.unique}`; } From b518e789a72868f55cca4ea032f39350a984bb0d Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 14 Feb 2025 13:37:23 +0100 Subject: [PATCH 084/145] add types for reference data source + repository --- .../document-reference.repository.ts | 8 +++- .../document-reference.server.data.ts | 48 +++++++++++++++++-- .../relations/relations/reference/types.ts | 41 ++++++++++++++++ .../src/packages/relations/relations/types.ts | 15 +----- 4 files changed, 94 insertions(+), 18 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.repository.ts index 628592c62c18..5a62fedc6a6d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.repository.ts @@ -1,8 +1,9 @@ import { UmbDocumentReferenceServerDataSource } from './document-reference.server.data.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbEntityReferenceRepository } from '@umbraco-cms/backoffice/relations'; -export class UmbDocumentReferenceRepository extends UmbControllerBase { +export class UmbDocumentReferenceRepository extends UmbControllerBase implements UmbEntityReferenceRepository { #referenceSource: UmbDocumentReferenceServerDataSource; constructor(host: UmbControllerHost) { @@ -14,6 +15,11 @@ export class UmbDocumentReferenceRepository extends UmbControllerBase { if (!unique) throw new Error(`unique is required`); return this.#referenceSource.getReferencedBy(unique, skip, take); } + + async requestReferencedDescendants(unique: string, skip = 0, take = 20) { + if (!unique) throw new Error(`unique is required`); + return this.#referenceSource.getReferencedDescendants(unique, skip, take); + } } export default UmbDocumentReferenceRepository; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts index e9ff572164ff..021abdbf50f0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts @@ -1,22 +1,32 @@ +import { UMB_DOCUMENT_ENTITY_TYPE } from '../../entity.js'; import { DocumentService } from '@umbraco-cms/backoffice/external/backend-api'; import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import { UmbDataMapper } from '@umbraco-cms/backoffice/repository'; +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import type { UmbEntityReferenceDataSource, UmbReferenceItemModel } from '@umbraco-cms/backoffice/relations'; +import type { UmbPagedModel, UmbDataSourceResponse } from '@umbraco-cms/backoffice/repository'; /** * @class UmbDocumentReferenceServerDataSource * @implements {RepositoryDetailDataSource} */ -export class UmbDocumentReferenceServerDataSource extends UmbControllerBase { +export class UmbDocumentReferenceServerDataSource extends UmbControllerBase implements UmbEntityReferenceDataSource { #dataMapper = new UmbDataMapper(this); /** * Fetches the item for the given unique from the server * @param {string} unique - The unique identifier of the item to fetch - * @returns {*} + * @param {number} skip - The number of items to skip + * @param {number} take - The number of items to take + * @returns {Promise>>} - Items that are referenced by the given unique * @memberof UmbDocumentReferenceServerDataSource */ - async getReferencedBy(unique: string, skip = 0, take = 20) { + async getReferencedBy( + unique: string, + skip: number = 0, + take: number = 20, + ): Promise>> { const { data, error } = await tryExecuteAndNotify( this, DocumentService.getDocumentByIdReferencedBy({ id: unique, skip, take }), @@ -44,4 +54,36 @@ export class UmbDocumentReferenceServerDataSource extends UmbControllerBase { return { data, error }; } + + /** + * Returns any descendants of the given unique that is referenced by other items + * @param {string} unique - The unique identifier of the item to fetch descendants for + * @param {number} skip - The number of items to skip + * @param {number} take - The number of items to take + * @returns {Promise>>} - Any descendants of the given unique that is referenced by other items + * @memberof UmbDocumentReferenceServerDataSource + */ + async getReferencedDescendants( + unique: string, + skip: number = 0, + take: number = 20, + ): Promise>> { + const { data, error } = await tryExecuteAndNotify( + this, + DocumentService.getDocumentByIdReferencedDescendants({ id: unique, skip, take }), + ); + + if (data) { + const items: Array = data.items.map((item) => { + return { + unique: item.id, + entityType: UMB_DOCUMENT_ENTITY_TYPE, + }; + }); + + return { data: { items, total: data.total } }; + } + + return { data, error }; + } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts new file mode 100644 index 000000000000..86339368b75a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts @@ -0,0 +1,41 @@ +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import type { + DefaultReferenceResponseModel, + DocumentReferenceResponseModel, + MediaReferenceResponseModel, +} from '@umbraco-cms/backoffice/external/backend-api'; +import type { UmbDataSourceResponse, UmbPagedModel, UmbRepositoryResponse } from '@umbraco-cms/backoffice/repository'; + +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +export interface UmbReferenceItemModel extends UmbEntityModel {} + +export type UmbReferenceModel = + | DefaultReferenceResponseModel + | DocumentReferenceResponseModel + | MediaReferenceResponseModel; + +export interface UmbEntityReferenceRepository { + requestReferencedBy( + unique: string, + skip?: number, + take?: number, + ): Promise>>; + requestReferencedDescendants?( + unique: string, + skip?: number, + take?: number, + ): Promise>>; +} + +export interface UmbEntityReferenceDataSource { + getReferencedBy( + unique: string, + skip?: number, + take?: number, + ): Promise>>; + getReferencedDescendants?( + unique: string, + skip?: number, + take?: number, + ): Promise>>; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/types.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/types.ts index cf7867b4dc33..f82c4baafe95 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/types.ts @@ -1,10 +1,5 @@ import type { UmbRelationEntityType } from './entity.js'; -import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; -import type { - DefaultReferenceResponseModel, - DocumentReferenceResponseModel, - MediaReferenceResponseModel, -} from '@umbraco-cms/backoffice/external/backend-api'; +export type * from './reference/types.js'; export interface UmbRelationDetailModel { unique: string; @@ -23,11 +18,3 @@ export interface UmbRelationDetailModel { createDate: string; comment: string | null; } - -// eslint-disable-next-line @typescript-eslint/no-empty-object-type -export interface UmbReferenceItemModel extends UmbEntityModel {} - -export type UmbReferenceModel = - | DefaultReferenceResponseModel - | DocumentReferenceResponseModel - | MediaReferenceResponseModel; From 161c9d5ef57ccdcd737e9104ddd9eefc8b40880f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 14 Feb 2025 15:00:54 +0100 Subject: [PATCH 085/145] split trash with relation into its own action --- .../recycle-bin/entity-action/constants.ts | 1 + .../entity-action/trash/constants.ts | 1 + .../entity-action/trash/manifests.ts | 4 +- .../entity-action/trash/modal/constants.ts | 1 - .../entity-action/trash/modal/manifests.ts | 8 -- .../trash/modal/trash-confirm-modal.token.ts | 19 ----- .../entity-action/trash/trash.action.kind.ts | 7 +- .../entity-action/trash/trash.action.ts | 31 ++++--- .../recycle-bin/entity-action/trash/types.ts | 1 - .../recycle-bin/entity-action/manifests.ts | 2 +- .../packages/relations/relations/manifests.ts | 7 +- .../relations/relations/reference/types.ts | 3 +- .../relations/relations/trash/index.ts | 2 + .../relations/relations/trash/manifests.ts | 6 ++ .../relations/trash/modal/constants.ts | 1 + .../relations/trash/modal/manifests.ts | 8 ++ .../trash-with-relation-modal.element.ts} | 85 +++++++++---------- .../modal/trash-with-relation-modal.token.ts | 19 +++++ .../trash/trash-with-relation.action.kind.ts | 15 ++++ .../trash/trash-with-relation.action.ts | 64 ++++++++++++++ .../relations/relations/trash/types.ts | 18 ++++ 21 files changed, 203 insertions(+), 100 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/constants.ts delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/constants.ts delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/manifests.ts delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.token.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/manifests.ts rename src/Umbraco.Web.UI.Client/src/packages/{core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts => relations/relations/trash/modal/trash-with-relation-modal.element.ts} (56%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.token.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/trash-with-relation.action.kind.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/trash-with-relation.action.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/constants.ts index 962fe58d3c34..55b3a7405c7c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/constants.ts @@ -1 +1,2 @@ export * from './restore-from-recycle-bin/constants.js'; +export * from './trash/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/constants.ts new file mode 100644 index 000000000000..45dc319a2e66 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/constants.ts @@ -0,0 +1 @@ +export { UMB_ENTITY_ACTION_TRASH_KIND_MANIFEST } from './trash.action.kind.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/manifests.ts index 5900880a6091..46ec59d132b6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/manifests.ts @@ -1,6 +1,4 @@ import { manifest as trashKindManifest } from './trash.action.kind.js'; -import { manifests as modalManifests } from './modal/manifests.js'; - import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; -export const manifests: Array = [trashKindManifest, ...modalManifests]; +export const manifests: Array = [trashKindManifest]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/constants.ts deleted file mode 100644 index 759ff7efcf8e..000000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/constants.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './trash-confirm-modal.token.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/manifests.ts deleted file mode 100644 index c96a19c65955..000000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/manifests.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const manifests: Array = [ - { - type: 'modal', - alias: 'Umb.Modal.Trash.Confirm', - name: 'Trash Confirm Modal', - element: () => import('./trash-confirm-modal.element.js'), - }, -]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.token.ts deleted file mode 100644 index 1c1ae7bc5d05..000000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.token.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; - -export interface UmbTrashConfirmModalData { - unique: string; - entityType: string; - itemRepositoryAlias: string; - referenceRepositoryAlias?: string; -} - -export type UmbTrashConfirmModalValue = undefined; - -export const UMB_TRASH_CONFIRM_MODAL = new UmbModalToken( - 'Umb.Modal.Trash.Confirm', - { - modal: { - type: 'dialog', - }, - }, -); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.kind.ts index a5b8770a452d..f9155f4fbab1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.kind.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.kind.ts @@ -1,7 +1,7 @@ import { UMB_ENTITY_ACTION_DEFAULT_KIND_MANIFEST } from '../../../entity-action/default/default.action.kind.js'; import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; -export const manifest: UmbExtensionManifestKind = { +export const UMB_ENTITY_ACTION_TRASH_KIND_MANIFEST: UmbExtensionManifestKind = { type: 'kind', alias: 'Umb.Kind.EntityAction.Trash', matchKind: 'trash', @@ -12,13 +12,12 @@ export const manifest: UmbExtensionManifestKind = { kind: 'trash', api: () => import('./trash.action.js'), weight: 1150, - forEntityTypes: [], meta: { icon: 'icon-trash', label: '#actions_trash', - itemRepositoryAlias: '', - recycleBinRepositoryAlias: '', additionalOptions: true, }, }, }; + +export const manifest = UMB_ENTITY_ACTION_TRASH_KIND_MANIFEST; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts index 91429cae2f38..999b1fe0fb88 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts @@ -1,12 +1,11 @@ -import { UmbEntityActionBase } from '../../../entity-action/entity-action-base.js'; -import { UmbRequestReloadStructureForEntityEvent } from '../../../entity-action/request-reload-structure-for-entity.event.js'; import type { UmbRecycleBinRepository } from '../../recycle-bin-repository.interface.js'; import type { MetaEntityActionTrashKind } from './types.js'; import { UmbEntityTrashedEvent } from './trash.event.js'; -import { UMB_TRASH_CONFIRM_MODAL } from './modal/constants.js'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; -import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; +import { umbConfirmModal } from '@umbraco-cms/backoffice/modal'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; +import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; +import { UmbEntityActionBase, UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/entity-action'; /** * Entity action for trashing an item. @@ -21,18 +20,22 @@ export class UmbTrashEntityAction extends UmbEntityActionBase>( + this, + this.args.meta.itemRepositoryAlias, + ); - const modal = modalManager.open(this, UMB_TRASH_CONFIRM_MODAL, { - data: { - unique: this.args.unique, - entityType: this.args.entityType, - itemRepositoryAlias: this.args.meta.itemRepositoryAlias, - referenceRepositoryAlias: this.args.meta.referenceRepositoryAlias, - }, - }); + const { data } = await itemRepository.requestItems([this.args.unique]); + const item = data?.[0]; + if (!item) throw new Error('Item not found.'); - await modal.onSubmit(); + // TODO: handle items with variants + await umbConfirmModal(this._host, { + headline: `Trash`, + content: `Are you sure you want to move ${item.name} to the recycle bin?`, + color: 'danger', + confirmLabel: 'Trash', + }); const recycleBinRepository = await createExtensionApiByAlias( this, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/types.ts index d535badb23bc..d587158fec6c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/types.ts @@ -8,7 +8,6 @@ export interface ManifestEntityActionTrashKind extends ManifestEntityAction = [ { type: 'entityAction', - kind: 'trash', + kind: 'trashWithRelation', alias: 'Umb.EntityAction.Document.RecycleBin.Trash', name: 'Trash Document Entity Action', forEntityTypes: [UMB_DOCUMENT_ENTITY_TYPE], diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts index bfab902d3c4e..e57a37198d6f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts @@ -1,3 +1,8 @@ import { manifests as collectionManifests } from './collection/manifests.js'; +import { manifests as trashManifests } from './trash/manifests.js'; +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; -export const manifests: Array = [...collectionManifests]; +export const manifests: Array = [ + ...collectionManifests, + ...trashManifests, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts index 86339368b75a..09abb1f860c3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts @@ -1,4 +1,5 @@ import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; import type { DefaultReferenceResponseModel, DocumentReferenceResponseModel, @@ -14,7 +15,7 @@ export type UmbReferenceModel = | DocumentReferenceResponseModel | MediaReferenceResponseModel; -export interface UmbEntityReferenceRepository { +export interface UmbEntityReferenceRepository extends UmbApi { requestReferencedBy( unique: string, skip?: number, diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/index.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/index.ts new file mode 100644 index 000000000000..cca1fbe202bf --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/index.ts @@ -0,0 +1,2 @@ +export * from './trash-with-relation.action.js'; +export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/manifests.ts new file mode 100644 index 000000000000..607b77322dee --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/manifests.ts @@ -0,0 +1,6 @@ +import { manifest as trashKindManifest } from './trash-with-relation.action.kind.js'; +import { manifests as modalManifests } from './modal/manifests.js'; + +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [trashKindManifest, ...modalManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/constants.ts new file mode 100644 index 000000000000..4f885f7678f0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/constants.ts @@ -0,0 +1 @@ +export * from './trash-with-relation-modal.token.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/manifests.ts new file mode 100644 index 000000000000..4b310dd31ef5 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/manifests.ts @@ -0,0 +1,8 @@ +export const manifests: Array = [ + { + type: 'modal', + alias: 'Umb.Modal.TrashWithRelation', + name: 'Trash With Relation Modal', + element: () => import('./trash-with-relation-modal.element.js'), + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts similarity index 56% rename from src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts index 83382c3fdf38..df8684844967 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/modal/trash-confirm-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts @@ -1,82 +1,73 @@ -import type { UmbTrashConfirmModalData, UmbTrashConfirmModalValue } from './trash-confirm-modal.token.js'; -import { html, customElement, property, css, state, nothing } from '@umbraco-cms/backoffice/external/lit'; +import type { UmbEntityReferenceRepository, UmbReferenceItemModel } from '../../types.js'; +import type { + UmbTrashWithRelationConfirmModalData, + UmbTrashWithRelationConfirmModalValue, +} from './trash-with-relation-modal.token.js'; +import { html, customElement, css, state, nothing, type PropertyValues } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import type { UmbModalContext } from '@umbraco-cms/backoffice/modal'; -import { UmbLitElement, umbFocus } from '@umbraco-cms/backoffice/lit-element'; +import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; +import { umbFocus } from '@umbraco-cms/backoffice/lit-element'; import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; +import type { UmbNamedEntityModel } from '@umbraco-cms/backoffice/entity'; -@customElement('umb-trash-confirm-modal') -export class UmbTrashConfirmModalElement extends UmbLitElement { - @property({ attribute: false }) - modalContext?: UmbModalContext; - - @property({ type: Object, attribute: false }) - private _data?: UmbTrashConfirmModalData | undefined; - public get data(): UmbTrashConfirmModalData | undefined { - return this._data; - } - public set data(value: UmbTrashConfirmModalData | undefined) { - this._data = value; - this.#initData(); - } - - private _handleConfirm() { - this.modalContext?.submit(); - } - - private _handleCancel() { - this.modalContext?.reject(); - } - +@customElement('umb-trash-with-relation-confirm-modal') +export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement< + UmbTrashWithRelationConfirmModalData, + UmbTrashWithRelationConfirmModalValue +> { @state() - _item: any; + _name?: string; @state() - _referencedBy: any[] = []; + _referencedBy: Array = []; @state() _totalReferencedBy: number = 0; - #itemRepository?: UmbItemRepository; - #referenceRepository?: any; + #itemRepository?: UmbItemRepository; + #referenceRepository?: UmbEntityReferenceRepository; #limitReferencedBy = 3; - constructor() { - super(); + protected override firstUpdated(_changedProperties: PropertyValues): void { + super.firstUpdated(_changedProperties); this.#initData(); } async #initData() { - if (!this._data) { + if (!this.data) { this.#itemRepository?.destroy(); this.#referenceRepository?.destroy(); return; } - this.#itemRepository = await createExtensionApiByAlias>( + this.#itemRepository = await createExtensionApiByAlias>( this, - this._data.itemRepositoryAlias, + this.data.itemRepositoryAlias, ); - const { data } = await this.#itemRepository.requestItems([this._data.unique]); + const { data } = await this.#itemRepository.requestItems([this.data.unique]); const item = data?.[0]; if (!item) throw new Error('Item not found.'); - this._item = item.name; + this._name = item.name; this.#loadReferencedBy(); } async #loadReferencedBy() { - // Skip if there is no reference repository - if (!this._data?.referenceRepositoryAlias) return; + if (!this.data?.referenceRepositoryAlias) { + throw new Error('Missing referenceRepositoryAlias in data.'); + } - this.#referenceRepository = await createExtensionApiByAlias(this, this._data.referenceRepositoryAlias); + this.#referenceRepository = await createExtensionApiByAlias( + this, + this.data?.referenceRepositoryAlias, + ); const { data: referencesData } = await this.#referenceRepository.requestReferencedBy( - this._data.unique, + this.data.unique, 0, this.#limitReferencedBy, ); @@ -90,10 +81,10 @@ export class UmbTrashConfirmModalElement extends UmbLitElement { override render() { return html` -

Are you sure you want to move ${this._item} to the recycle bin?

+

Are you sure you want to move ${this._name} to the recycle bin?

${this.#renderReferencedBy()} - +
`; @@ -146,10 +137,10 @@ export class UmbTrashConfirmModalElement extends UmbLitElement { ]; } -export { UmbTrashConfirmModalElement as element }; +export { UmbTrashWithRelationConfirmModalElement as element }; declare global { interface HTMLElementTagNameMap { - 'umb-trash-confirm-modal': UmbTrashConfirmModalElement; + 'umb-trash-with-relation-confirm-modal': UmbTrashWithRelationConfirmModalElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.token.ts new file mode 100644 index 000000000000..6e67d47f1a3b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.token.ts @@ -0,0 +1,19 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbTrashWithRelationConfirmModalData { + unique: string; + entityType: string; + itemRepositoryAlias: string; + referenceRepositoryAlias: string; +} + +export type UmbTrashWithRelationConfirmModalValue = undefined; + +export const UMB_TRASH_WITH_RELATION_CONFIRM_MODAL = new UmbModalToken< + UmbTrashWithRelationConfirmModalData, + UmbTrashWithRelationConfirmModalValue +>('Umb.Modal.TrashWithRelation', { + modal: { + type: 'dialog', + }, +}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/trash-with-relation.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/trash-with-relation.action.kind.ts new file mode 100644 index 000000000000..e2ceee56ad09 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/trash-with-relation.action.kind.ts @@ -0,0 +1,15 @@ +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; +import { UMB_ENTITY_ACTION_TRASH_KIND_MANIFEST } from '@umbraco-cms/backoffice/recycle-bin'; + +export const manifest: UmbExtensionManifestKind = { + type: 'kind', + alias: 'Umb.Kind.EntityAction.TrashWithRelation', + matchKind: 'trashWithRelation', + matchType: 'entityAction', + manifest: { + ...UMB_ENTITY_ACTION_TRASH_KIND_MANIFEST.manifest, + type: 'entityAction', + kind: 'trashWithRelation', + api: () => import('./trash-with-relation.action.js'), + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/trash-with-relation.action.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/trash-with-relation.action.ts new file mode 100644 index 000000000000..444b2341ed4f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/trash-with-relation.action.ts @@ -0,0 +1,64 @@ +import type { MetaEntityActionTrashWithRelationKind } from './types.js'; +import { UMB_TRASH_WITH_RELATION_CONFIRM_MODAL } from './modal/constants.js'; +import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; +import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; +import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; +import { UmbEntityActionBase, UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/entity-action'; +import { UmbEntityTrashedEvent } from '@umbraco-cms/backoffice/recycle-bin'; + +/** + * Entity action for trashing an item with relations. + * @class UmbTrashWithRelationEntityAction + * @augments {UmbEntityActionBase} + */ +export class UmbTrashWithRelationEntityAction extends UmbEntityActionBase { + /** + * Executes the action. + * @memberof UmbTrashWithRelationEntityAction + */ + override async execute() { + if (!this.args.unique) throw new Error('Cannot trash an item without a unique identifier.'); + + const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); + + const modal = modalManager.open(this, UMB_TRASH_WITH_RELATION_CONFIRM_MODAL, { + data: { + unique: this.args.unique, + entityType: this.args.entityType, + itemRepositoryAlias: this.args.meta.itemRepositoryAlias, + referenceRepositoryAlias: this.args.meta.referenceRepositoryAlias, + }, + }); + + await modal.onSubmit(); + + const recycleBinRepository = await createExtensionApiByAlias( + this, + this.args.meta.recycleBinRepositoryAlias, + ); + + await recycleBinRepository.requestTrash({ unique: this.args.unique }); + + this.#notify(); + } + + async #notify() { + const actionEventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); + + const event = new UmbRequestReloadStructureForEntityEvent({ + unique: this.args.unique, + entityType: this.args.entityType, + }); + + actionEventContext.dispatchEvent(event); + + const trashedEvent = new UmbEntityTrashedEvent({ + unique: this.args.unique, + entityType: this.args.entityType, + }); + + actionEventContext.dispatchEvent(trashedEvent); + } +} + +export { UmbTrashWithRelationEntityAction as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/types.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/types.ts new file mode 100644 index 000000000000..a02b000e8bcd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/types.ts @@ -0,0 +1,18 @@ +import type { ManifestEntityAction } from '@umbraco-cms/backoffice/entity-action'; +import type { MetaEntityActionTrashKind } from '@umbraco-cms/backoffice/recycle-bin'; + +export interface ManifestEntityActionTrashWithRelationKind + extends ManifestEntityAction { + type: 'entityAction'; + kind: 'trashWithRelation'; +} + +export interface MetaEntityActionTrashWithRelationKind extends MetaEntityActionTrashKind { + referenceRepositoryAlias: string; +} + +declare global { + interface UmbExtensionManifestMap { + umbManifestEntityActionTrashWithRelationKind: ManifestEntityActionTrashWithRelationKind; + } +} From a8324b6ba561b668cfbb80d34807b5d4cf758715 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 14 Feb 2025 15:57:36 +0100 Subject: [PATCH 086/145] render descendants with references --- .../document-reference.repository.ts | 2 +- .../relations/relations/reference/types.ts | 2 +- .../trash-with-relation-modal.element.ts | 99 +++++++++++++------ 3 files changed, 69 insertions(+), 34 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.repository.ts index 5a62fedc6a6d..fa3b1f6dbe3a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.repository.ts @@ -16,7 +16,7 @@ export class UmbDocumentReferenceRepository extends UmbControllerBase implements return this.#referenceSource.getReferencedBy(unique, skip, take); } - async requestReferencedDescendants(unique: string, skip = 0, take = 20) { + async requestDescendantsWithReferences(unique: string, skip = 0, take = 20) { if (!unique) throw new Error(`unique is required`); return this.#referenceSource.getReferencedDescendants(unique, skip, take); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts index 09abb1f860c3..a84034a6421b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts @@ -21,7 +21,7 @@ export interface UmbEntityReferenceRepository extends UmbApi { skip?: number, take?: number, ): Promise>>; - requestReferencedDescendants?( + requestDescendantsWithReferences?( unique: string, skip?: number, take?: number, diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts index df8684844967..a20530352ee2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts @@ -9,7 +9,6 @@ import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; import { umbFocus } from '@umbraco-cms/backoffice/lit-element'; import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; -import type { UmbNamedEntityModel } from '@umbraco-cms/backoffice/entity'; @customElement('umb-trash-with-relation-confirm-modal') export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement< @@ -20,15 +19,21 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement _name?: string; @state() - _referencedBy: Array = []; + _referencedByItems: Array = []; @state() - _totalReferencedBy: number = 0; + _totalReferencedByItems: number = 0; - #itemRepository?: UmbItemRepository; + @state() + _totalDescendantsWithReferences: number = 0; + + @state() + _descendantsWithReferences: Array = []; + + #itemRepository?: UmbItemRepository; #referenceRepository?: UmbEntityReferenceRepository; - #limitReferencedBy = 3; + #limitItems = 3; protected override firstUpdated(_changedProperties: PropertyValues): void { super.firstUpdated(_changedProperties); @@ -42,10 +47,7 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement return; } - this.#itemRepository = await createExtensionApiByAlias>( - this, - this.data.itemRepositoryAlias, - ); + this.#itemRepository = await createExtensionApiByAlias>(this, this.data.itemRepositoryAlias); const { data } = await this.#itemRepository.requestItems([this.data.unique]); const item = data?.[0]; @@ -53,10 +55,6 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement this._name = item.name; - this.#loadReferencedBy(); - } - - async #loadReferencedBy() { if (!this.data?.referenceRepositoryAlias) { throw new Error('Missing referenceRepositoryAlias in data.'); } @@ -66,15 +64,54 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement this.data?.referenceRepositoryAlias, ); - const { data: referencesData } = await this.#referenceRepository.requestReferencedBy( + this.#loadReferencedBy(); + this.#loadDescendantsWithReferences(); + } + + async #loadReferencedBy() { + if (!this.#referenceRepository) { + throw new Error('Failed to create reference repository.'); + } + + if (!this.data?.unique) { + throw new Error('Missing unique in data.'); + } + + const { data } = await this.#referenceRepository.requestReferencedBy(this.data.unique, 0, this.#limitItems); + + if (data) { + this._referencedByItems = [...data.items]; + this._totalReferencedByItems = data.total; + } + } + + async #loadDescendantsWithReferences() { + if (!this.#referenceRepository) { + throw new Error('Failed to create reference repository.'); + } + + if (!this.#itemRepository) { + throw new Error('Failed to create item repository.'); + } + + // If the repository does not have the method, we don't need to load the referenced descendants. + if (!this.#referenceRepository.requestDescendantsWithReferences) return; + + if (!this.data?.unique) { + throw new Error('Missing unique in data.'); + } + + const { data } = await this.#referenceRepository.requestDescendantsWithReferences( this.data.unique, 0, - this.#limitReferencedBy, + this.#limitItems, ); - if (referencesData) { - this._referencedBy = [...referencesData.items]; - this._totalReferencedBy = referencesData.total; + if (data) { + this._totalDescendantsWithReferences = data.total; + const uniques = data.items.map((item) => item.unique).filter((unique) => unique) as Array; + const { data: items } = await this.#itemRepository.requestItems(uniques); + this._descendantsWithReferences = items ?? []; } } @@ -82,7 +119,12 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement return html`

Are you sure you want to move ${this._name} to the recycle bin?

- ${this.#renderReferencedBy()} + ${this.#renderItems('references_labelDependsOnThis', this._referencedByItems, this._totalReferencedByItems)} + ${this.#renderItems( + 'references_labelDependentDescendants', + this._descendantsWithReferences, + this._totalDescendantsWithReferences, + )} @@ -98,23 +140,16 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement `; } - #renderReferencedBy() { - if (this._totalReferencedBy === 0) return nothing; + #renderItems(headline: string, items: Array, total: number) { + if (!items) return nothing; return html` -
${this.localize.term('references_labelDependsOnThis')}
+
${this.localize.term(headline)}
- ${this._referencedBy.map( - (reference) => html` `, - )} + ${items.map((item) => html` `)} - ${this._totalReferencedBy > this.#limitReferencedBy - ? html`${this.localize.term( - 'references_labelMoreReferences', - this._totalReferencedBy - this.#limitReferencedBy, - )}` + ${total > this.#limitItems + ? html`${this.localize.term('references_labelMoreReferences', total - this.#limitItems)}` : nothing} `; } From 541753c9e4c6d9fee494f917f0111367257c8249 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 14 Feb 2025 16:07:26 +0100 Subject: [PATCH 087/145] fix length check --- .../relations/trash/modal/trash-with-relation-modal.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts index a20530352ee2..88f0d7ded4ce 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts @@ -141,7 +141,7 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement } #renderItems(headline: string, items: Array, total: number) { - if (!items) return nothing; + if (total === 0) return nothing; return html`
${this.localize.term(headline)}
From dcc9b3d6e9aa87e2c1abfe1bfd7abfb7cd35049b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 14 Feb 2025 16:20:46 +0100 Subject: [PATCH 088/145] set standalone attribute --- .../trash/modal/trash-with-relation-modal.element.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts index 88f0d7ded4ce..473aca5e7ac9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts @@ -146,7 +146,10 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement return html`
${this.localize.term(headline)}
- ${items.map((item) => html` `)} + ${items.map( + (item) => + html` `, + )} ${total > this.#limitItems ? html`${this.localize.term('references_labelMoreReferences', total - this.#limitItems)}` From d3e2db58596b8e626516dfe12e084f245e2aa3fd Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 14 Feb 2025 16:24:02 +0100 Subject: [PATCH 089/145] implement for media --- .../recycle-bin/entity-action/manifests.ts | 2 +- .../repository/media-reference.repository.ts | 8 ++- .../repository/media-reference.server.data.ts | 54 ++++++++++++++++--- 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/manifests.ts index 549cd5617731..cf87461c8924 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/manifests.ts @@ -13,7 +13,7 @@ import { export const manifests: Array = [ { type: 'entityAction', - kind: 'trash', + kind: 'trashWithRelation', alias: 'Umb.EntityAction.Media.RecycleBin.Trash', name: 'Trash Media Entity Action', forEntityTypes: [UMB_MEDIA_ENTITY_TYPE], diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.repository.ts index dd7bb49c50de..ab5ac83a5fc7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.repository.ts @@ -1,8 +1,9 @@ import { UmbMediaReferenceServerDataSource } from './media-reference.server.data.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbEntityReferenceRepository } from '@umbraco-cms/backoffice/relations'; -export class UmbMediaReferenceRepository extends UmbControllerBase { +export class UmbMediaReferenceRepository extends UmbControllerBase implements UmbEntityReferenceRepository { #referenceSource: UmbMediaReferenceServerDataSource; constructor(host: UmbControllerHost) { @@ -14,6 +15,11 @@ export class UmbMediaReferenceRepository extends UmbControllerBase { if (!unique) throw new Error(`unique is required`); return this.#referenceSource.getReferencedBy(unique, skip, take); } + + async requestDescendantsWithReferences(unique: string, skip = 0, take = 20) { + if (!unique) throw new Error(`unique is required`); + return this.#referenceSource.getReferencedDescendants(unique, skip, take); + } } export default UmbMediaReferenceRepository; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts index 7384c9d75fce..396c92205592 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts @@ -1,22 +1,32 @@ -import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import { UMB_MEDIA_ENTITY_TYPE } from '../../entity.js'; import { MediaService } from '@umbraco-cms/backoffice/external/backend-api'; -import { UmbDataMapper } from '@umbraco-cms/backoffice/repository'; import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import { UmbDataMapper } from '@umbraco-cms/backoffice/repository'; +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import type { UmbEntityReferenceDataSource, UmbReferenceItemModel } from '@umbraco-cms/backoffice/relations'; +import type { UmbPagedModel, UmbDataSourceResponse } from '@umbraco-cms/backoffice/repository'; /** * @class UmbMediaReferenceServerDataSource * @implements {RepositoryDetailDataSource} */ -export class UmbMediaReferenceServerDataSource extends UmbControllerBase { +export class UmbMediaReferenceServerDataSource extends UmbControllerBase implements UmbEntityReferenceDataSource { #dataMapper = new UmbDataMapper(this); /** - * Fetches the item for the given id from the server + * Fetches the item for the given unique from the server * @param {string} unique - The unique identifier of the item to fetch - * @returns {*} + * @param {number} skip - The number of items to skip + * @param {number} take - The number of items to take + * @returns {Promise>>} - Items that are referenced by the given unique * @memberof UmbMediaReferenceServerDataSource */ - async getReferencedBy(unique: string, skip = 0, take = 20) { + async getReferencedBy( + unique: string, + skip: number = 0, + take: number = 20, + ): Promise>> { const { data, error } = await tryExecuteAndNotify( this, MediaService.getMediaByIdReferencedBy({ id: unique, skip, take }), @@ -44,4 +54,36 @@ export class UmbMediaReferenceServerDataSource extends UmbControllerBase { return { data, error }; } + + /** + * Returns any descendants of the given unique that is referenced by other items + * @param {string} unique - The unique identifier of the item to fetch descendants for + * @param {number} skip - The number of items to skip + * @param {number} take - The number of items to take + * @returns {Promise>>} - Any descendants of the given unique that is referenced by other items + * @memberof UmbMediaReferenceServerDataSource + */ + async getReferencedDescendants( + unique: string, + skip: number = 0, + take: number = 20, + ): Promise>> { + const { data, error } = await tryExecuteAndNotify( + this, + MediaService.getMediaByIdReferencedDescendants({ id: unique, skip, take }), + ); + + if (data) { + const items: Array = data.items.map((item) => { + return { + unique: item.id, + entityType: UMB_MEDIA_ENTITY_TYPE, + }; + }); + + return { data: { items, total: data.total } }; + } + + return { data, error }; + } } From e31186772e6a108228bd9d59447ff5185e6b608f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 16 Feb 2025 19:29:55 +0100 Subject: [PATCH 090/145] move trash --- .../relations/relations/{ => entity-actions}/trash/index.ts | 0 .../relations/relations/{ => entity-actions}/trash/manifests.ts | 0 .../relations/{ => entity-actions}/trash/modal/constants.ts | 0 .../relations/{ => entity-actions}/trash/modal/manifests.ts | 0 .../trash/modal/trash-with-relation-modal.element.ts | 2 +- .../trash/modal/trash-with-relation-modal.token.ts | 0 .../trash/trash-with-relation.action.kind.ts | 0 .../{ => entity-actions}/trash/trash-with-relation.action.ts | 0 .../relations/relations/{ => entity-actions}/trash/types.ts | 0 .../src/packages/relations/relations/manifests.ts | 2 +- 10 files changed, 2 insertions(+), 2 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/relations/relations/{ => entity-actions}/trash/index.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/relations/relations/{ => entity-actions}/trash/manifests.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/relations/relations/{ => entity-actions}/trash/modal/constants.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/relations/relations/{ => entity-actions}/trash/modal/manifests.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/relations/relations/{ => entity-actions}/trash/modal/trash-with-relation-modal.element.ts (99%) rename src/Umbraco.Web.UI.Client/src/packages/relations/relations/{ => entity-actions}/trash/modal/trash-with-relation-modal.token.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/relations/relations/{ => entity-actions}/trash/trash-with-relation.action.kind.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/relations/relations/{ => entity-actions}/trash/trash-with-relation.action.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/relations/relations/{ => entity-actions}/trash/types.ts (100%) diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/index.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/index.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/index.ts rename to src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/manifests.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/manifests.ts rename to src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/manifests.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/constants.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/constants.ts rename to src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/constants.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/manifests.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/manifests.ts rename to src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/manifests.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts similarity index 99% rename from src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts index 473aca5e7ac9..02d8d828c0e2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts @@ -1,4 +1,4 @@ -import type { UmbEntityReferenceRepository, UmbReferenceItemModel } from '../../types.js'; +import type { UmbEntityReferenceRepository, UmbReferenceItemModel } from '../../../types.js'; import type { UmbTrashWithRelationConfirmModalData, UmbTrashWithRelationConfirmModalValue, diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.token.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/modal/trash-with-relation-modal.token.ts rename to src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.token.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/trash-with-relation.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/trash-with-relation.action.kind.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/trash-with-relation.action.kind.ts rename to src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/trash-with-relation.action.kind.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/trash-with-relation.action.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/trash-with-relation.action.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/trash-with-relation.action.ts rename to src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/trash-with-relation.action.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/types.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/types.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/relations/relations/trash/types.ts rename to src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts index e57a37198d6f..30dd3979a3f1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts @@ -1,5 +1,5 @@ import { manifests as collectionManifests } from './collection/manifests.js'; -import { manifests as trashManifests } from './trash/manifests.js'; +import { manifests as trashManifests } from './entity-actions/trash/manifests.js'; import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; export const manifests: Array = [ From 1e084b4d157f65974c6698a9aad4d49c4cca26ab Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 16 Feb 2025 19:40:54 +0100 Subject: [PATCH 091/145] wip delete with relation --- .../core/entity-action/common/constants.ts | 1 + .../entity-action/common/delete/constants.ts | 1 + .../common/delete/delete.action.kind.ts | 4 +- .../core/entity-action/common/types.ts | 1 + .../src/packages/core/entity-action/types.ts | 1 + .../delete-with-relation.action.kind.ts | 15 ++ .../delete/delete-with-relation.action.ts | 48 +++++ .../relations/entity-actions/delete/index.ts | 2 + .../entity-actions/delete/manifests.ts | 9 + .../entity-actions/delete/modal/constants.ts | 1 + .../delete-with-relation-modal.element.ts | 184 ++++++++++++++++++ .../modal/delete-with-relation-modal.token.ts | 19 ++ .../entity-actions/delete/modal/manifests.ts | 8 + .../relations/entity-actions/delete/types.ts | 17 ++ 14 files changed, 310 insertions(+), 1 deletion(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/types.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/delete-with-relation.action.kind.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/delete-with-relation.action.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.token.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/constants.ts index f8cd69a673b3..7dcb65f74574 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/constants.ts @@ -1 +1,2 @@ export * from './create/constants.js'; +export * from './delete/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/constants.ts new file mode 100644 index 000000000000..14e2c4886c60 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/constants.ts @@ -0,0 +1 @@ +export { UMB_ENTITY_ACTION_DELETE_KIND_MANIFEST } from './delete.action.kind.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.kind.ts index 07995746e6fe..e0474309fa8a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.kind.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/delete/delete.action.kind.ts @@ -1,7 +1,7 @@ import { UMB_ENTITY_ACTION_DEFAULT_KIND_MANIFEST } from '../../default/default.action.kind.js'; import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; -export const manifest: UmbExtensionManifestKind = { +export const UMB_ENTITY_ACTION_DELETE_KIND_MANIFEST: UmbExtensionManifestKind = { type: 'kind', alias: 'Umb.Kind.EntityAction.Delete', matchKind: 'delete', @@ -22,3 +22,5 @@ export const manifest: UmbExtensionManifestKind = { }, }, }; + +export const manifest = UMB_ENTITY_ACTION_DELETE_KIND_MANIFEST; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/types.ts new file mode 100644 index 000000000000..b493efd74dfb --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/common/types.ts @@ -0,0 +1 @@ +export type * from './delete/types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/types.ts index 5fc6da73803d..35d2e26e19e3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/types.ts @@ -1,5 +1,6 @@ import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +export type * from './common/types.js'; export type * from './default/types.js'; export type * from './entity-action-element.interface.js'; export type * from './entity-action.extension.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/delete-with-relation.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/delete-with-relation.action.kind.ts new file mode 100644 index 000000000000..cc1b0a57cc9e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/delete-with-relation.action.kind.ts @@ -0,0 +1,15 @@ +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; +import { UMB_ENTITY_ACTION_DELETE_KIND_MANIFEST } from '@umbraco-cms/backoffice/entity-action'; + +export const manifest: UmbExtensionManifestKind = { + type: 'kind', + alias: 'Umb.Kind.EntityAction.DeleteWithRelation', + matchKind: 'deleteWithRelation', + matchType: 'entityAction', + manifest: { + ...UMB_ENTITY_ACTION_DELETE_KIND_MANIFEST.manifest, + type: 'entityAction', + kind: 'deleteWithRelation', + api: () => import('./delete-with-relation.action.js'), + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/delete-with-relation.action.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/delete-with-relation.action.ts new file mode 100644 index 000000000000..c580b3895655 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/delete-with-relation.action.ts @@ -0,0 +1,48 @@ +import type { MetaEntityActionDeleteWithRelationKind } from './types.js'; +import { UMB_DELETE_WITH_RELATION_CONFIRM_MODAL } from './modal/constants.js'; +import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; +import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; +import { UmbEntityActionBase, UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/entity-action'; + +/** + * Entity action for deleting an item with relations. + * @class UmbDeleteWithRelationEntityAction + * @augments {UmbEntityActionBase} + */ +export class UmbDeleteWithRelationEntityAction extends UmbEntityActionBase { + /** + * Executes the action. + * @memberof UmbDeleteWithRelationEntityAction + */ + override async execute() { + if (!this.args.unique) throw new Error('Cannot delete an item without a unique identifier.'); + + const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); + + const modal = modalManager.open(this, UMB_DELETE_WITH_RELATION_CONFIRM_MODAL, { + data: { + unique: this.args.unique, + entityType: this.args.entityType, + itemRepositoryAlias: this.args.meta.itemRepositoryAlias, + referenceRepositoryAlias: this.args.meta.referenceRepositoryAlias, + }, + }); + + await modal.onSubmit(); + + this.#notify(); + } + + async #notify() { + const actionEventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); + + const event = new UmbRequestReloadStructureForEntityEvent({ + unique: this.args.unique, + entityType: this.args.entityType, + }); + + actionEventContext.dispatchEvent(event); + } +} + +export { UmbDeleteWithRelationEntityAction as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/index.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/index.ts new file mode 100644 index 000000000000..a609dad289f9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/index.ts @@ -0,0 +1,2 @@ +export * from './delete-with-relation.action.js'; +export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/manifests.ts new file mode 100644 index 000000000000..81aff4a3cf03 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/manifests.ts @@ -0,0 +1,9 @@ +import { manifest as deleteKindManifest } from './delete-with-relation.action.kind.js'; +import { manifests as modalManifests } from './modal/manifests.js'; + +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + deleteKindManifest, + ...modalManifests, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/constants.ts new file mode 100644 index 000000000000..1081167efe8a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/constants.ts @@ -0,0 +1 @@ +export * from './delete-with-relation-modal.token.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts new file mode 100644 index 000000000000..524a90a680be --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts @@ -0,0 +1,184 @@ +import type { UmbEntityReferenceRepository, UmbReferenceItemModel } from '../../../types.js'; +import type { + UmbDeleteWithRelationConfirmModalData, + UmbDeleteWithRelationConfirmModalValue, +} from './delete-with-relation-modal.token.js'; +import { html, customElement, css, state, nothing, type PropertyValues } from '@umbraco-cms/backoffice/external/lit'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; +import { umbFocus } from '@umbraco-cms/backoffice/lit-element'; +import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; +import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; + +@customElement('umb-delete-with-relation-confirm-modal') +export class UmbDeleteWithRelationConfirmModalElement extends UmbModalBaseElement< + UmbDeleteWithRelationConfirmModalData, + UmbDeleteWithRelationConfirmModalValue +> { + @state() + _name?: string; + + @state() + _referencedByItems: Array = []; + + @state() + _totalReferencedByItems: number = 0; + + @state() + _totalDescendantsWithReferences: number = 0; + + @state() + _descendantsWithReferences: Array = []; + + #itemRepository?: UmbItemRepository; + #referenceRepository?: UmbEntityReferenceRepository; + + #limitItems = 3; + + protected override firstUpdated(_changedProperties: PropertyValues): void { + super.firstUpdated(_changedProperties); + this.#initData(); + } + + async #initData() { + if (!this.data) { + this.#itemRepository?.destroy(); + this.#referenceRepository?.destroy(); + return; + } + + this.#itemRepository = await createExtensionApiByAlias>(this, this.data.itemRepositoryAlias); + + const { data } = await this.#itemRepository.requestItems([this.data.unique]); + const item = data?.[0]; + if (!item) throw new Error('Item not found.'); + + this._name = item.name; + + if (!this.data?.referenceRepositoryAlias) { + throw new Error('Missing referenceRepositoryAlias in data.'); + } + + this.#referenceRepository = await createExtensionApiByAlias( + this, + this.data?.referenceRepositoryAlias, + ); + + this.#loadReferencedBy(); + this.#loadDescendantsWithReferences(); + } + + async #loadReferencedBy() { + if (!this.#referenceRepository) { + throw new Error('Failed to create reference repository.'); + } + + if (!this.data?.unique) { + throw new Error('Missing unique in data.'); + } + + const { data } = await this.#referenceRepository.requestReferencedBy(this.data.unique, 0, this.#limitItems); + + if (data) { + this._referencedByItems = [...data.items]; + this._totalReferencedByItems = data.total; + } + } + + async #loadDescendantsWithReferences() { + if (!this.#referenceRepository) { + throw new Error('Failed to create reference repository.'); + } + + if (!this.#itemRepository) { + throw new Error('Failed to create item repository.'); + } + + // If the repository does not have the method, we don't need to load the referenced descendants. + if (!this.#referenceRepository.requestDescendantsWithReferences) return; + + if (!this.data?.unique) { + throw new Error('Missing unique in data.'); + } + + const { data } = await this.#referenceRepository.requestDescendantsWithReferences( + this.data.unique, + 0, + this.#limitItems, + ); + + if (data) { + this._totalDescendantsWithReferences = data.total; + const uniques = data.items.map((item) => item.unique).filter((unique) => unique) as Array; + const { data: items } = await this.#itemRepository.requestItems(uniques); + this._descendantsWithReferences = items ?? []; + } + } + + override render() { + return html` + +

Are you sure you want to move ${this._name} to the recycle bin?

+ ${this.#renderItems('references_labelDependsOnThis', this._referencedByItems, this._totalReferencedByItems)} + ${this.#renderItems( + 'references_labelDependentDescendants', + this._descendantsWithReferences, + this._totalDescendantsWithReferences, + )} + + + + +
+ `; + } + + #renderItems(headline: string, items: Array, total: number) { + if (total === 0) return nothing; + + return html` +
${this.localize.term(headline)}
+ + ${items.map( + (item) => + html` `, + )} + + ${total > this.#limitItems + ? html`${this.localize.term('references_labelMoreReferences', total - this.#limitItems)}` + : nothing} + `; + } + + static override styles = [ + UmbTextStyles, + css` + uui-dialog-layout { + max-inline-size: 60ch; + } + + #reference-headline { + margin-bottom: var(--uui-size-3); + } + + uui-ref-list { + margin-bottom: var(--uui-size-2); + } + `, + ]; +} + +export { UmbDeleteWithRelationConfirmModalElement as element }; + +declare global { + interface HTMLElementTagNameMap { + 'umb-delete-with-relation-confirm-modal': UmbDeleteWithRelationConfirmModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.token.ts new file mode 100644 index 000000000000..c3ba603bb5ba --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.token.ts @@ -0,0 +1,19 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbDeleteWithRelationConfirmModalData { + unique: string; + entityType: string; + itemRepositoryAlias: string; + referenceRepositoryAlias: string; +} + +export type UmbDeleteWithRelationConfirmModalValue = undefined; + +export const UMB_DELETE_WITH_RELATION_CONFIRM_MODAL = new UmbModalToken< + UmbDeleteWithRelationConfirmModalData, + UmbDeleteWithRelationConfirmModalValue +>('Umb.Modal.DeleteWithRelation', { + modal: { + type: 'dialog', + }, +}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/manifests.ts new file mode 100644 index 000000000000..8689b6d7837c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/manifests.ts @@ -0,0 +1,8 @@ +export const manifests: Array = [ + { + type: 'modal', + alias: 'Umb.Modal.DeleteWithRelation', + name: 'Delete With Relation Modal', + element: () => import('./delete-with-relation-modal.element.js'), + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/types.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/types.ts new file mode 100644 index 000000000000..d53ef50d1fcc --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/types.ts @@ -0,0 +1,17 @@ +import type { ManifestEntityAction, MetaEntityActionDeleteKind } from '@umbraco-cms/backoffice/entity-action'; + +export interface ManifestEntityActionDeleteWithRelationKind + extends ManifestEntityAction { + type: 'entityAction'; + kind: 'deleteWithRelation'; +} + +export interface MetaEntityActionDeleteWithRelationKind extends MetaEntityActionDeleteKind { + referenceRepositoryAlias: string; +} + +declare global { + interface UmbExtensionManifestMap { + umbManifestEntityActionDeleteWithRelationKind: ManifestEntityActionDeleteWithRelationKind; + } +} From 9e273f9c4cbe43d5ced391222ccb64ca9b2107ec Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Sun, 16 Feb 2025 20:03:23 +0100 Subject: [PATCH 092/145] move to element --- ...onfirm-action-entity-references.element.ts | 163 ++++++++++++++++++ .../trash-with-relation-modal.element.ts | 120 ++----------- 2 files changed, 178 insertions(+), 105 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts new file mode 100644 index 000000000000..8fc56fc2306f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts @@ -0,0 +1,163 @@ +import type { UmbEntityReferenceRepository, UmbReferenceItemModel } from '../../reference/types.js'; +import { + html, + customElement, + css, + state, + nothing, + type PropertyValues, + property, +} from '@umbraco-cms/backoffice/external/lit'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; +import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; + +@customElement('umb-confirm-action-entity-references') +export class UmbConfirmActionEntityReferencesElement extends UmbLitElement { + @property({ type: Object, attribute: false }) + config?: { + itemRepositoryAlias: string; + referenceRepositoryAlias: string; + entityType: string; + unique: string; + }; + + @state() + _referencedByItems: Array = []; + + @state() + _totalReferencedByItems: number = 0; + + @state() + _totalDescendantsWithReferences: number = 0; + + @state() + _descendantsWithReferences: Array = []; + + #itemRepository?: UmbItemRepository; + #referenceRepository?: UmbEntityReferenceRepository; + + #limitItems = 3; + + protected override firstUpdated(_changedProperties: PropertyValues): void { + super.firstUpdated(_changedProperties); + this.#initData(); + } + + async #initData() { + if (!this.config) { + this.#itemRepository?.destroy(); + this.#referenceRepository?.destroy(); + return; + } + + if (!this.config?.referenceRepositoryAlias) { + throw new Error('Missing referenceRepositoryAlias in config.'); + } + + this.#referenceRepository = await createExtensionApiByAlias( + this, + this.config?.referenceRepositoryAlias, + ); + + this.#loadReferencedBy(); + this.#loadDescendantsWithReferences(); + } + + async #loadReferencedBy() { + if (!this.#referenceRepository) { + throw new Error('Failed to create reference repository.'); + } + + if (!this.config?.unique) { + throw new Error('Missing unique in data.'); + } + + const { data } = await this.#referenceRepository.requestReferencedBy(this.config.unique, 0, this.#limitItems); + + if (data) { + this._referencedByItems = [...data.items]; + this._totalReferencedByItems = data.total; + } + } + + async #loadDescendantsWithReferences() { + if (!this.#referenceRepository) { + throw new Error('Failed to create reference repository.'); + } + + if (!this.#itemRepository) { + throw new Error('Failed to create item repository.'); + } + + // If the repository does not have the method, we don't need to load the referenced descendants. + if (!this.#referenceRepository.requestDescendantsWithReferences) return; + + if (!this.config?.unique) { + throw new Error('Missing unique in data.'); + } + + const { data } = await this.#referenceRepository.requestDescendantsWithReferences( + this.config.unique, + 0, + this.#limitItems, + ); + + if (data) { + this._totalDescendantsWithReferences = data.total; + const uniques = data.items.map((item) => item.unique).filter((unique) => unique) as Array; + const { data: items } = await this.#itemRepository.requestItems(uniques); + this._descendantsWithReferences = items ?? []; + } + } + + override render() { + return html` + ${this.#renderItems('references_labelDependsOnThis', this._referencedByItems, this._totalReferencedByItems)} + ${this.#renderItems( + 'references_labelDependentDescendants', + this._descendantsWithReferences, + this._totalDescendantsWithReferences, + )} + `; + } + + #renderItems(headline: string, items: Array, total: number) { + if (total === 0) return nothing; + + return html` +
${this.localize.term(headline)}
+ + ${items.map( + (item) => + html` `, + )} + + ${total > this.#limitItems + ? html`${this.localize.term('references_labelMoreReferences', total - this.#limitItems)}` + : nothing} + `; + } + + static override styles = [ + UmbTextStyles, + css` + #reference-headline { + margin-bottom: var(--uui-size-3); + } + + uui-ref-list { + margin-bottom: var(--uui-size-2); + } + `, + ]; +} + +export { UmbConfirmActionEntityReferencesElement as element }; + +declare global { + interface HTMLElementTagNameMap { + 'umb-confirm-action-entity-references': UmbConfirmActionEntityReferencesElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts index 02d8d828c0e2..cdfc9d0639d8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts @@ -1,15 +1,17 @@ -import type { UmbEntityReferenceRepository, UmbReferenceItemModel } from '../../../types.js'; import type { UmbTrashWithRelationConfirmModalData, UmbTrashWithRelationConfirmModalValue, } from './trash-with-relation-modal.token.js'; -import { html, customElement, css, state, nothing, type PropertyValues } from '@umbraco-cms/backoffice/external/lit'; +import { html, customElement, css, state, type PropertyValues, nothing } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; import { umbFocus } from '@umbraco-cms/backoffice/lit-element'; import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; +// import of local component +import '../../local-components/confirm-action-entity-references.element.js'; + @customElement('umb-trash-with-relation-confirm-modal') export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement< UmbTrashWithRelationConfirmModalData, @@ -19,21 +21,9 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement _name?: string; @state() - _referencedByItems: Array = []; - - @state() - _totalReferencedByItems: number = 0; - - @state() - _totalDescendantsWithReferences: number = 0; - - @state() - _descendantsWithReferences: Array = []; + _referencesConfig?: any; #itemRepository?: UmbItemRepository; - #referenceRepository?: UmbEntityReferenceRepository; - - #limitItems = 3; protected override firstUpdated(_changedProperties: PropertyValues): void { super.firstUpdated(_changedProperties); @@ -43,7 +33,6 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement async #initData() { if (!this.data) { this.#itemRepository?.destroy(); - this.#referenceRepository?.destroy(); return; } @@ -55,76 +44,22 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement this._name = item.name; - if (!this.data?.referenceRepositoryAlias) { - throw new Error('Missing referenceRepositoryAlias in data.'); - } - - this.#referenceRepository = await createExtensionApiByAlias( - this, - this.data?.referenceRepositoryAlias, - ); - - this.#loadReferencedBy(); - this.#loadDescendantsWithReferences(); - } - - async #loadReferencedBy() { - if (!this.#referenceRepository) { - throw new Error('Failed to create reference repository.'); - } - - if (!this.data?.unique) { - throw new Error('Missing unique in data.'); - } - - const { data } = await this.#referenceRepository.requestReferencedBy(this.data.unique, 0, this.#limitItems); - - if (data) { - this._referencedByItems = [...data.items]; - this._totalReferencedByItems = data.total; - } - } - - async #loadDescendantsWithReferences() { - if (!this.#referenceRepository) { - throw new Error('Failed to create reference repository.'); - } - - if (!this.#itemRepository) { - throw new Error('Failed to create item repository.'); - } - - // If the repository does not have the method, we don't need to load the referenced descendants. - if (!this.#referenceRepository.requestDescendantsWithReferences) return; - - if (!this.data?.unique) { - throw new Error('Missing unique in data.'); - } - - const { data } = await this.#referenceRepository.requestDescendantsWithReferences( - this.data.unique, - 0, - this.#limitItems, - ); - - if (data) { - this._totalDescendantsWithReferences = data.total; - const uniques = data.items.map((item) => item.unique).filter((unique) => unique) as Array; - const { data: items } = await this.#itemRepository.requestItems(uniques); - this._descendantsWithReferences = items ?? []; - } + this._referencesConfig = { + unique: this.data.unique, + itemRepositoryAlias: this.data.itemRepositoryAlias, + referenceRepositoryAlias: this.data.referenceRepositoryAlias, + }; } override render() { return html`

Are you sure you want to move ${this._name} to the recycle bin?

- ${this.#renderItems('references_labelDependsOnThis', this._referencedByItems, this._totalReferencedByItems)} - ${this.#renderItems( - 'references_labelDependentDescendants', - this._descendantsWithReferences, - this._totalDescendantsWithReferences, - )} + + ${this._referencesConfig + ? html`` + : nothing} @@ -140,37 +75,12 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement `; } - #renderItems(headline: string, items: Array, total: number) { - if (total === 0) return nothing; - - return html` -
${this.localize.term(headline)}
- - ${items.map( - (item) => - html` `, - )} - - ${total > this.#limitItems - ? html`${this.localize.term('references_labelMoreReferences', total - this.#limitItems)}` - : nothing} - `; - } - static override styles = [ UmbTextStyles, css` uui-dialog-layout { max-inline-size: 60ch; } - - #reference-headline { - margin-bottom: var(--uui-size-3); - } - - uui-ref-list { - margin-bottom: var(--uui-size-2); - } `, ]; } From 46b050a05b29df2dea1136e6ac21e7a52c9fa473 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Feb 2025 10:52:20 +0100 Subject: [PATCH 093/145] fix name collision --- .../data-mapper/data-mapper.extension.ts | 18 --------------- .../repository/data-mapper/data-mapper.ts | 14 ++++++------ .../core/repository/data-mapper/index.ts | 2 +- .../data-mapping-resolver.ts} | 22 +++++++++---------- .../mapping/data-mapping.extension.ts | 18 +++++++++++++++ .../repository/data-mapper/mapping/index.ts | 1 + .../repository/data-mapper/mapping/types.ts | 5 +++++ .../core/repository/data-mapper/types.ts | 6 +---- .../src/packages/core/repository/types.ts | 2 +- ...ument-reference-response-model.mapping.ts} | 8 +++---- .../reference/repository/manifests.ts | 8 +++---- .../media/reference/repository/manifests.ts | 8 +++---- ...media-reference-response-model.mapping.ts} | 8 +++---- 13 files changed, 61 insertions(+), 59 deletions(-) delete mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.extension.ts rename src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/{data-mapper-resolver.ts => mapping/data-mapping-resolver.ts} (69%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping.extension.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/types.ts rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/{document-reference-response-model.mapper.ts => document-reference-response-model.mapping.ts} (77%) rename src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/{media-reference-response-model.mapper.ts => media-reference-response-model.mapping.ts} (74%) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.extension.ts deleted file mode 100644 index 1269562f3f6b..000000000000 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.extension.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { UmbDataMapper } from './types.js'; -import type { ManifestApi } from '@umbraco-cms/backoffice/extension-api'; - -export interface ManifestDataMapper - extends ManifestApi { - type: 'dataMapper'; - identifier: string; - meta: MetaType; -} - -// eslint-disable-next-line @typescript-eslint/no-empty-object-type -export interface MetaDataMapper {} - -declare global { - interface UmbExtensionManifestMap { - umbManifestDataMapper: ManifestDataMapper; - } -} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.ts index 08c9e9f6c032..c451a943266b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.ts @@ -1,4 +1,4 @@ -import { UmbDataMapperResolver } from './data-mapper-resolver.js'; +import { UmbDataMappingResolver } from './mapping/data-mapping-resolver.js'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; export interface UmbDataMapperMapArgs { @@ -8,7 +8,7 @@ export interface UmbDataMapperMapArgs extends UmbControllerBase { - #dataMapperResolver = new UmbDataMapperResolver(this); + #dataMappingResolver = new UmbDataMappingResolver(this); async map(args: UmbDataMapperMapArgs) { if (!args.identifier) { @@ -19,20 +19,20 @@ export class UmbDataMapper exten throw new Error('data is required'); } - const mapper = await this.#dataMapperResolver.resolve(args.identifier); + const dataMapping = await this.#dataMappingResolver.resolve(args.identifier); - if (!mapper && !args.fallback) { + if (!dataMapping && !args.fallback) { throw new Error('Data Mapper not found and no fallback provided.'); } - if (!mapper && args.fallback) { + if (!dataMapping && args.fallback) { return args.fallback(args.data); } - if (!mapper?.map) { + if (!dataMapping?.map) { throw new Error('Data Mapper does not have a map method.'); } - return mapper.map(args.data); + return dataMapping.map(args.data); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts index acfa9fb37064..4a99513c8583 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts @@ -1,2 +1,2 @@ -export * from './data-mapper-resolver.js'; export * from './data-mapper.js'; +export * from './mapping/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping-resolver.ts similarity index 69% rename from src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper-resolver.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping-resolver.ts index 2ce30bc3753d..187a28d9dbfc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper-resolver.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping-resolver.ts @@ -1,12 +1,12 @@ -import type { UmbDataMapper } from './types.js'; +import type { UmbDataMapping } from './types.js'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import { createExtensionApi, type ManifestBase } from '@umbraco-cms/backoffice/extension-api'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; -export class UmbDataMapperResolver extends UmbControllerBase { - #apiCache = new Map(); +export class UmbDataMappingResolver extends UmbControllerBase { + #apiCache = new Map(); - async resolve(identifier: string): Promise { + async resolve(identifier: string): Promise { if (!identifier) { throw new Error('data is required'); } @@ -22,20 +22,20 @@ export class UmbDataMapperResolver extends UmbControllerBase { return this.#apiCache.get(manifest.alias)!; } - const dataMapper = await createExtensionApi(this, manifest); + const dataMapping = await createExtensionApi(this, manifest); - if (!dataMapper) { + if (!dataMapping) { return undefined; } - if (!dataMapper.map) { - throw new Error('Data Mapper does not have a map method.'); + if (!dataMapping.map) { + throw new Error('Data Mapping does not have a map method.'); } // Cache the api instance for future use - this.#apiCache.set(manifest.alias, dataMapper); + this.#apiCache.set(manifest.alias, dataMapping); - return dataMapper; + return dataMapping; } #getManifestWithBestFit(identifier: string) { @@ -50,7 +50,7 @@ export class UmbDataMapperResolver extends UmbControllerBase { } #getSupportedManifests(identifier: string) { - const supportedManifests = umbExtensionsRegistry.getByTypeAndFilter('dataMapper', (manifest) => { + const supportedManifests = umbExtensionsRegistry.getByTypeAndFilter('dataMapping', (manifest) => { return manifest.identifier === identifier; }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping.extension.ts new file mode 100644 index 000000000000..1c32e0e6aa69 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping.extension.ts @@ -0,0 +1,18 @@ +import type { UmbDataMapping } from './types.js'; +import type { ManifestApi } from '@umbraco-cms/backoffice/extension-api'; + +export interface ManifestDataMapping + extends ManifestApi { + type: 'dataMapping'; + identifier: string; + meta: MetaType; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +export interface MetaDataMapping {} + +declare global { + interface UmbExtensionManifestMap { + umbManifestDataMapping: ManifestDataMapping; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/index.ts new file mode 100644 index 000000000000..2a1055c6f2ed --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/index.ts @@ -0,0 +1 @@ +export * from './data-mapping-resolver.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/types.ts new file mode 100644 index 000000000000..a9cb7efdde94 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/types.ts @@ -0,0 +1,5 @@ +import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; + +export interface UmbDataMapping extends UmbApi { + map: (data: fromModelType) => Promise; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/types.ts index 2b7ac0ac88fb..bb05f6a27dd8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/types.ts @@ -1,5 +1 @@ -import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; - -export interface UmbDataMapper extends UmbApi { - map: (data: fromModelType) => Promise; -} +export type * from './mapping/types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/types.ts index 5fb70c396d95..c75d42253864 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/types.ts @@ -15,4 +15,4 @@ export interface UmbRepositoryResponseWithAsObservable extends UmbRepositoryR asObservable: () => Observable; } -export type * from './data-mapper/types.js'; +export type * from './data-mapper/mapping/types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response-model.mapper.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response-model.mapping.ts similarity index 77% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response-model.mapper.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response-model.mapping.ts index 8ec38b1a2226..91addf082985 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response-model.mapper.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response-model.mapping.ts @@ -5,11 +5,11 @@ import { type DocumentReferenceResponseModel, } from '@umbraco-cms/backoffice/external/backend-api'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; -import type { UmbDataMapper } from '@umbraco-cms/backoffice/repository'; +import type { UmbDataMapping } from '@umbraco-cms/backoffice/repository'; -export class UmbDocumentReferenceResponseModelMapper +export class UmbDocumentReferenceResponseModelDataMapping extends UmbControllerBase - implements UmbDataMapper + implements UmbDataMapping { async map(data: DocumentReferenceResponseModel): Promise { return { @@ -35,4 +35,4 @@ export class UmbDocumentReferenceResponseModelMapper } } -export { UmbDocumentReferenceResponseModelMapper as api }; +export { UmbDocumentReferenceResponseModelDataMapping as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts index d354816f91df..abb84771a81f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts @@ -8,10 +8,10 @@ export const manifests: Array = [ api: () => import('./document-reference.repository.js'), }, { - type: 'dataMapper', - alias: 'Umb.DataMapper.DocumentReferenceResponseModel', - name: 'Document Reference Response Model to Client Model Data Mapper', - api: () => import('./document-reference-response-model.mapper.js'), + type: 'dataMapping', + alias: 'Umb.DataMapping.DocumentReferenceResponseModel', + name: 'Document Reference Response Model to Client Model Data Mapping', + api: () => import('./document-reference-response-model.mapping.js'), identifier: 'DocumentReferenceResponseModel', }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts index c7bbb8af2b5c..c6a94804ee59 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts @@ -8,10 +8,10 @@ export const manifests: Array = [ api: () => import('./media-reference.repository.js'), }, { - type: 'dataMapper', - alias: 'Umb.DataMapper.MediaReferenceResponseModel', - name: 'Media Reference Response Model to Client Model Data Mapper', - api: () => import('./media-reference-response-model.mapper.js'), + type: 'dataMapping', + alias: 'Umb.DataMapping.MediaReferenceResponseModel', + name: 'Media Reference Response Model to Client Model Data Mapping', + api: () => import('./media-reference-response-model.mapping.js'), identifier: 'MediaReferenceResponseModel', }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response-model.mapper.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response-model.mapping.ts similarity index 74% rename from src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response-model.mapper.ts rename to src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response-model.mapping.ts index 61c6ccf2ae29..0cadae7acf0e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response-model.mapper.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response-model.mapping.ts @@ -2,11 +2,11 @@ import { UMB_MEDIA_ENTITY_TYPE } from '../../entity.js'; import type { UmbMediaReferenceModel } from './types.js'; import type { MediaReferenceResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; -import type { UmbDataMapper } from '@umbraco-cms/backoffice/repository'; +import type { UmbDataMapping } from '@umbraco-cms/backoffice/repository'; -export class UmbMediaReferenceResponseModelMapper +export class UmbMediaReferenceResponseModelDataMapping extends UmbControllerBase - implements UmbDataMapper + implements UmbDataMapping { async map(data: MediaReferenceResponseModel): Promise { return { @@ -30,4 +30,4 @@ export class UmbMediaReferenceResponseModelMapper } } -export { UmbMediaReferenceResponseModelMapper as api }; +export { UmbMediaReferenceResponseModelDataMapping as api }; From 11b3e04501f5debab53e46ab1cc30aad4eeaffa9 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Feb 2025 12:27:41 +0100 Subject: [PATCH 094/145] require data source identifier --- .../repository/data-mapper/data-mapper.ts | 17 +++++++++----- .../mapping/data-mapping-resolver.ts | 22 ++++++++++++------- .../mapping/data-mapping.extension.ts | 3 ++- .../document-reference.server.data.ts | 3 ++- .../reference/repository/manifests.ts | 3 ++- .../media/reference/repository/manifests.ts | 3 ++- .../repository/media-reference.server.data.ts | 3 ++- 7 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.ts index c451a943266b..0c192046a423 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.ts @@ -2,7 +2,8 @@ import { UmbDataMappingResolver } from './mapping/data-mapping-resolver.js'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; export interface UmbDataMapperMapArgs { - identifier: string; + dataModelIdentifier: string; + dataSourceIdentifier: string; data: fromModelType; fallback?: (data: fromModelType) => Promise; } @@ -11,18 +12,22 @@ export class UmbDataMapper exten #dataMappingResolver = new UmbDataMappingResolver(this); async map(args: UmbDataMapperMapArgs) { - if (!args.identifier) { - throw new Error('identifier is required'); + if (!args.dataSourceIdentifier) { + throw new Error('data source identifier is required'); + } + + if (!args.dataModelIdentifier) { + throw new Error('data identifier is required'); } if (!args.data) { throw new Error('data is required'); } - const dataMapping = await this.#dataMappingResolver.resolve(args.identifier); + const dataMapping = await this.#dataMappingResolver.resolve(args.dataSourceIdentifier, args.dataModelIdentifier); if (!dataMapping && !args.fallback) { - throw new Error('Data Mapper not found and no fallback provided.'); + throw new Error('Data mapping not found and no fallback provided.'); } if (!dataMapping && args.fallback) { @@ -30,7 +35,7 @@ export class UmbDataMapper exten } if (!dataMapping?.map) { - throw new Error('Data Mapper does not have a map method.'); + throw new Error('Data mapping does not have a map method.'); } return dataMapping.map(args.data); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping-resolver.ts index 187a28d9dbfc..29a415e68ac0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping-resolver.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping-resolver.ts @@ -6,12 +6,16 @@ import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registr export class UmbDataMappingResolver extends UmbControllerBase { #apiCache = new Map(); - async resolve(identifier: string): Promise { - if (!identifier) { - throw new Error('data is required'); + async resolve(dataSourceIdentifier: string, dataModelIdentifier: string): Promise { + if (!dataSourceIdentifier) { + throw new Error('data source identifier is required'); } - const manifest = this.#getManifestWithBestFit(identifier); + if (!dataModelIdentifier) { + throw new Error('data identifier is required'); + } + + const manifest = this.#getManifestWithBestFit(dataSourceIdentifier, dataModelIdentifier); if (!manifest) { return undefined; @@ -38,8 +42,8 @@ export class UmbDataMappingResolver extends UmbControllerBase { return dataMapping; } - #getManifestWithBestFit(identifier: string) { - const supportedManifests = this.#getSupportedManifests(identifier); + #getManifestWithBestFit(dataSourceIdentifier: string, dataModelIdentifier: string) { + const supportedManifests = this.#getSupportedManifests(dataSourceIdentifier, dataModelIdentifier); if (!supportedManifests.length) { return undefined; @@ -49,9 +53,11 @@ export class UmbDataMappingResolver extends UmbControllerBase { return supportedManifests.sort((a: ManifestBase, b: ManifestBase): number => (b.weight || 0) - (a.weight || 0))[0]; } - #getSupportedManifests(identifier: string) { + #getSupportedManifests(dataSourceIdentifier: string, dataModelIdentifier: string) { const supportedManifests = umbExtensionsRegistry.getByTypeAndFilter('dataMapping', (manifest) => { - return manifest.identifier === identifier; + return ( + manifest.dataSourceIdentifier === dataSourceIdentifier && manifest.dataModelIdentifier === dataModelIdentifier + ); }); return supportedManifests; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping.extension.ts index 1c32e0e6aa69..47505a748a1f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping.extension.ts @@ -4,7 +4,8 @@ import type { ManifestApi } from '@umbraco-cms/backoffice/extension-api'; export interface ManifestDataMapping extends ManifestApi { type: 'dataMapping'; - identifier: string; + dataSourceIdentifier: string; + dataModelIdentifier: string; meta: MetaType; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts index e9ff572164ff..9526277c384b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts @@ -25,7 +25,8 @@ export class UmbDocumentReferenceServerDataSource extends UmbControllerBase { if (data) { const promises = data.items.map(async (item) => { return this.#dataMapper.map({ - identifier: item.$type, + dataSourceIdentifier: 'Umb.ManagementApi', + dataModelIdentifier: item.$type, data: item, fallback: async () => { return { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts index abb84771a81f..c5541c9fcc85 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts @@ -12,6 +12,7 @@ export const manifests: Array = [ alias: 'Umb.DataMapping.DocumentReferenceResponseModel', name: 'Document Reference Response Model to Client Model Data Mapping', api: () => import('./document-reference-response-model.mapping.js'), - identifier: 'DocumentReferenceResponseModel', + dataSourceIdentifier: 'Umb.ManagementApi', + dataModelIdentifier: 'DocumentReferenceResponseModel', }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts index c6a94804ee59..7fe0d3f1191d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts @@ -12,6 +12,7 @@ export const manifests: Array = [ alias: 'Umb.DataMapping.MediaReferenceResponseModel', name: 'Media Reference Response Model to Client Model Data Mapping', api: () => import('./media-reference-response-model.mapping.js'), - identifier: 'MediaReferenceResponseModel', + dataSourceIdentifier: 'Umb.ManagementApi', + dataModelIdentifier: 'MediaReferenceResponseModel', }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts index 7384c9d75fce..dd3666681c28 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts @@ -25,7 +25,8 @@ export class UmbMediaReferenceServerDataSource extends UmbControllerBase { if (data) { const promises = data.items.map(async (item) => { return this.#dataMapper.map({ - identifier: item.$type, + dataSourceIdentifier: 'Umb.ManagementApi', + dataModelIdentifier: item.$type, data: item, fallback: async () => { return { From 2d3ca2928d5cb555cdb6482a99759e51056bd091 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Feb 2025 12:31:26 +0100 Subject: [PATCH 095/145] use management api mapper --- .../src/packages/core/repository/data-mapper/index.ts | 1 + .../reference/repository/document-reference.server.data.ts | 5 ++--- .../reference/repository/media-reference.server.data.ts | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts index 4a99513c8583..488ca6933a2f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts @@ -1,2 +1,3 @@ export * from './data-mapper.js'; export * from './mapping/index.js'; +export * from './management-api-data-mapper.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts index 9526277c384b..322ce6fe150c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts @@ -1,14 +1,14 @@ import { DocumentService } from '@umbraco-cms/backoffice/external/backend-api'; import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; -import { UmbDataMapper } from '@umbraco-cms/backoffice/repository'; +import { UmbManagementApiDataMapper } from '@umbraco-cms/backoffice/repository'; /** * @class UmbDocumentReferenceServerDataSource * @implements {RepositoryDetailDataSource} */ export class UmbDocumentReferenceServerDataSource extends UmbControllerBase { - #dataMapper = new UmbDataMapper(this); + #dataMapper = new UmbManagementApiDataMapper(this); /** * Fetches the item for the given unique from the server @@ -25,7 +25,6 @@ export class UmbDocumentReferenceServerDataSource extends UmbControllerBase { if (data) { const promises = data.items.map(async (item) => { return this.#dataMapper.map({ - dataSourceIdentifier: 'Umb.ManagementApi', dataModelIdentifier: item.$type, data: item, fallback: async () => { diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts index dd3666681c28..e05b48fab9c0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts @@ -1,6 +1,6 @@ import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import { MediaService } from '@umbraco-cms/backoffice/external/backend-api'; -import { UmbDataMapper } from '@umbraco-cms/backoffice/repository'; +import { UmbManagementApiDataMapper } from '@umbraco-cms/backoffice/repository'; import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; /** @@ -8,7 +8,7 @@ import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; * @implements {RepositoryDetailDataSource} */ export class UmbMediaReferenceServerDataSource extends UmbControllerBase { - #dataMapper = new UmbDataMapper(this); + #dataMapper = new UmbManagementApiDataMapper(this); /** * Fetches the item for the given id from the server @@ -25,7 +25,6 @@ export class UmbMediaReferenceServerDataSource extends UmbControllerBase { if (data) { const promises = data.items.map(async (item) => { return this.#dataMapper.map({ - dataSourceIdentifier: 'Umb.ManagementApi', dataModelIdentifier: item.$type, data: item, fallback: async () => { From 1c5aedfc73056be879e9988c0d9f2e5c9f6affad Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Feb 2025 13:06:24 +0100 Subject: [PATCH 096/145] add management api mapper --- .../src/packages/core/repository/constants.ts | 1 + .../core/repository/data-mapper/constants.ts | 1 + .../core/repository/data-mapper/index.ts | 2 +- .../data-mapper/management-api/constants.ts | 1 + .../management-api-data-mapper.ts | 19 +++++++++++++++++++ .../src/packages/core/repository/index.ts | 10 +++++----- .../reference/repository/manifests.ts | 3 ++- .../media/reference/repository/manifests.ts | 3 ++- 8 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/repository/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/management-api-data-mapper.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/constants.ts new file mode 100644 index 000000000000..72ec3b021af2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/constants.ts @@ -0,0 +1 @@ +export * from './data-mapper/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/constants.ts new file mode 100644 index 000000000000..7b9ccdc34562 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/constants.ts @@ -0,0 +1 @@ +export * from './management-api/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts index 488ca6933a2f..f709dce8599f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/index.ts @@ -1,3 +1,3 @@ export * from './data-mapper.js'; export * from './mapping/index.js'; -export * from './management-api-data-mapper.js'; +export * from './management-api/management-api-data-mapper.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/constants.ts new file mode 100644 index 000000000000..25d3b5812fab --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/constants.ts @@ -0,0 +1 @@ +export const UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER = 'Umb.ManagementApi'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/management-api-data-mapper.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/management-api-data-mapper.ts new file mode 100644 index 000000000000..747b1bcff980 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/management-api-data-mapper.ts @@ -0,0 +1,19 @@ +import { UmbDataMapper, type UmbDataMapperMapArgs } from '../data-mapper.js'; +import { UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER } from './constants.js'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; + +export class UmbManagementApiDataMapper extends UmbControllerBase { + #dataMapper = new UmbDataMapper(this); + + constructor(host: UmbControllerHost) { + super(host); + } + + map(args: Omit) { + return this.#dataMapper.map({ + ...args, + dataSourceIdentifier: UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER, + }); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/index.ts index 10f104e3c0a0..a344a151a986 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/index.ts @@ -1,9 +1,9 @@ -export * from './repository-items.manager.js'; -export * from './repository-base.js'; - -export * from './item/index.js'; -export * from './detail/index.js'; +export * from './constants.js'; export * from './data-mapper/index.js'; +export * from './detail/index.js'; +export * from './item/index.js'; +export * from './repository-base.js'; +export * from './repository-items.manager.js'; export type { UmbDataSourceResponse, UmbDataSourceErrorResponse } from './data-source-response.interface.js'; export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts index c5541c9fcc85..82bc4d2f3d9d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts @@ -1,4 +1,5 @@ import { UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS } from './constants.js'; +import { UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER } from '@umbraco-cms/backoffice/repository'; export const manifests: Array = [ { @@ -12,7 +13,7 @@ export const manifests: Array = [ alias: 'Umb.DataMapping.DocumentReferenceResponseModel', name: 'Document Reference Response Model to Client Model Data Mapping', api: () => import('./document-reference-response-model.mapping.js'), - dataSourceIdentifier: 'Umb.ManagementApi', + dataSourceIdentifier: UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER, dataModelIdentifier: 'DocumentReferenceResponseModel', }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts index 7fe0d3f1191d..087e23ed6316 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts @@ -1,4 +1,5 @@ import { UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS } from './constants.js'; +import { UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER } from '@umbraco-cms/backoffice/repository'; export const manifests: Array = [ { @@ -12,7 +13,7 @@ export const manifests: Array = [ alias: 'Umb.DataMapping.MediaReferenceResponseModel', name: 'Media Reference Response Model to Client Model Data Mapping', api: () => import('./media-reference-response-model.mapping.js'), - dataSourceIdentifier: 'Umb.ManagementApi', + dataSourceIdentifier: UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER, dataModelIdentifier: 'MediaReferenceResponseModel', }, ]; From ac8955e84df7d133842fb3e4c287174c571c76a7 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Feb 2025 13:56:52 +0100 Subject: [PATCH 097/145] fix type errors --- .../repository/document-collection.server.data-source.ts | 2 ++ .../src/packages/documents/documents/collection/types.ts | 5 ++++- .../column-layouts/document-table-column-state.element.ts | 2 +- .../documents/documents/item/document-item-data-resolver.ts | 2 +- .../packages/documents/documents/item/repository/types.ts | 2 +- 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts index 30f2050121f5..04977651d4a7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/repository/document-collection.server.data-source.ts @@ -43,6 +43,8 @@ export class UmbDocumentCollectionServerDataSource implements UmbCollectionDataS createDate: new Date(variant.createDate), creator: item.creator, icon: item.documentType.icon, + isProtected: item.isProtected, + isTrashed: item.isTrashed, name: variant.name, sortOrder: item.sortOrder, state: variant.state, diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/types.ts index 3629ce58a45c..55107999fc7f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/types.ts @@ -1,3 +1,4 @@ +import type { UmbDocumentEntityType } from '../entity.js'; import type { UmbDocumentItemVariantModel } from '../item/repository/types.js'; import type { UmbCollectionFilterModel } from '@umbraco-cms/backoffice/collection'; @@ -12,11 +13,13 @@ export interface UmbDocumentCollectionFilterModel extends UmbCollectionFilterMod export interface UmbDocumentCollectionItemModel { unique: string; - entityType: string; + entityType: UmbDocumentEntityType; creator?: string | null; sortOrder: number; updater?: string | null; values: Array<{ alias: string; value: string }>; + isProtected: boolean; + isTrashed: boolean; documentType: { unique: string; icon: string; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts index 17b17dd9367e..37bde5b831f0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/collection/views/table/column-layouts/document-table-column-state.element.ts @@ -1,4 +1,4 @@ -import type { UmbDocumentCollectionItemModel, UmbEditableDocumentCollectionItemModel } from '../../../types.js'; +import type { UmbEditableDocumentCollectionItemModel } from '../../../types.js'; import { UmbDocumentItemDataResolver } from '../../../../item/index.js'; import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; import { fromCamelCase } from '@umbraco-cms/backoffice/utils'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts index 6b790025a410..0fc145e928ab 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-data-resolver.ts @@ -9,7 +9,7 @@ import { UmbBooleanState, UmbStringState } from '@umbraco-cms/backoffice/observa import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property'; import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; -type UmbDocumentItemDataResolverModel = Omit; +type UmbDocumentItemDataResolverModel = Omit; /** * A controller for resolving data for a document item diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/types.ts index f1077ccaf85f..142d9e2951d7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/types.ts @@ -7,7 +7,7 @@ export interface UmbDocumentItemModel { documentType: { unique: string; icon: string; - collection: UmbReferenceByUnique | null; + collection?: UmbReferenceByUnique | null; }; entityType: UmbDocumentEntityType; hasChildren: boolean; From 2cbe1efecd03d5672917389e62efa8e9d58d8d8e Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Feb 2025 13:59:15 +0100 Subject: [PATCH 098/145] Update index.ts --- .../utils/all-umb-consts/index.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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 66fb3000df72..60c23df656c7 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 @@ -140,7 +140,7 @@ export const foundConsts = [{ }, { path: '@umbraco-cms/backoffice/document', - consts: ["UMB_DOCUMENT_COLLECTION_ALIAS","UMB_DOCUMENT_COLLECTION_CONTEXT","UMB_DOCUMENT_COLLECTION_REPOSITORY_ALIAS","UMB_DOCUMENT_GRID_COLLECTION_VIEW_ALIAS","UMB_DOCUMENT_TABLE_COLLECTION_VIEW_ALIAS","UMB_DOCUMENT_CREATE_OPTIONS_MODAL","UMB_CREATE_BLUEPRINT_MODAL","UMB_DOCUMENT_CREATE_BLUEPRINT_REPOSITORY_ALIAS","UMB_CULTURE_AND_HOSTNAMES_MODAL","UMB_DOCUMENT_CULTURE_AND_HOSTNAMES_REPOSITORY_ALIAS","UMB_DUPLICATE_DOCUMENT_MODAL","UMB_DUPLICATE_DOCUMENT_MODAL_ALIAS","UMB_DUPLICATE_DOCUMENT_REPOSITORY_ALIAS","UMB_MOVE_DOCUMENT_REPOSITORY_ALIAS","UMB_DOCUMENT_NOTIFICATIONS_MODAL","UMB_DOCUMENT_NOTIFICATIONS_MODAL_ALIAS","UMB_DOCUMENT_NOTIFICATIONS_REPOSITORY_ALIAS","UMB_PUBLIC_ACCESS_MODAL","UMB_DOCUMENT_PUBLIC_ACCESS_REPOSITORY_ALIAS","UMB_SORT_CHILDREN_OF_DOCUMENT_REPOSITORY_ALIAS","UMB_BULK_DUPLICATE_DOCUMENT_REPOSITORY_ALIAS","UMB_BULK_MOVE_DOCUMENT_REPOSITORY_ALIAS","UMB_BULK_TRASH_DOCUMENT_REPOSITORY_ALIAS","UMB_DOCUMENT_ENTITY_TYPE","UMB_DOCUMENT_ROOT_ENTITY_TYPE","UMB_DOCUMENT_CONFIGURATION_CONTEXT","UMB_CONTENT_MENU_ALIAS","UMB_DOCUMENT_PICKER_MODAL","UMB_DOCUMENT_SAVE_MODAL","UMB_DOCUMENT_SAVE_MODAL_ALIAS","UMB_DOCUMENT_WORKSPACE_PATH","UMB_CREATE_FROM_BLUEPRINT_DOCUMENT_WORKSPACE_PATH_PATTERN","UMB_CREATE_DOCUMENT_WORKSPACE_PATH_PATTERN","UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN","UMB_DOCUMENT_PROPERTY_DATASET_CONTEXT","UMB_DOCUMENT_PUBLISH_MODAL_ALIAS","UMB_DOCUMENT_PUBLISH_MODAL","UMB_DOCUMENT_PUBLISH_WITH_DESCENDANTS_MODAL_ALIAS","UMB_DOCUMENT_PUBLISH_WITH_DESCENDANTS_MODAL","UMB_DOCUMENT_PUBLISHING_REPOSITORY_ALIAS","UMB_DOCUMENT_SCHEDULE_MODAL_ALIAS","UMB_DOCUMENT_SCHEDULE_MODAL","UMB_DOCUMENT_UNPUBLISH_MODAL_ALIAS","UMB_DOCUMENT_UNPUBLISH_MODAL","UMB_DOCUMENT_PUBLISHING_WORKSPACE_CONTEXT","UMB_DOCUMENT_RECYCLE_BIN_ROOT_ENTITY_TYPE","UMB_DOCUMENT_RECYCLE_BIN_REPOSITORY_ALIAS","UMB_DOCUMENT_RECYCLE_BIN_TREE_REPOSITORY_ALIAS","UMB_DOCUMENT_RECYCLE_BIN_TREE_STORE_ALIAS","UMB_DOCUMENT_RECYCLE_BIN_TREE_ALIAS","UMB_DOCUMENT_RECYCLE_BIN_TREE_STORE_CONTEXT","UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS","UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS","UMB_DOCUMENT_DETAIL_STORE_ALIAS","UMB_DOCUMENT_DETAIL_STORE_CONTEXT","UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS","UMB_DOCUMENT_STORE_ALIAS","UMB_DOCUMENT_ITEM_STORE_CONTEXT","UMB_DOCUMENT_VALIDATION_REPOSITORY_ALIAS","UMB_ROLLBACK_MODAL_ALIAS","UMB_ROLLBACK_MODAL","UMB_ROLLBACK_REPOSITORY_ALIAS","UMB_DOCUMENT_SEARCH_PROVIDER_ALIAS","UMB_DOCUMENT_TREE_STORE_CONTEXT","UMB_DOCUMENT_TREE_REPOSITORY_ALIAS","UMB_DOCUMENT_TREE_STORE_ALIAS","UMB_DOCUMENT_TREE_ALIAS","UMB_DOCUMENT_URL_REPOSITORY_ALIAS","UMB_DOCUMENT_URL_STORE_ALIAS","UMB_DOCUMENT_URL_STORE_CONTEXT","UMB_DOCUMENT_USER_PERMISSION_CONDITION_ALIAS","UMB_USER_PERMISSION_DOCUMENT_CREATE","UMB_USER_PERMISSION_DOCUMENT_READ","UMB_USER_PERMISSION_DOCUMENT_UPDATE","UMB_USER_PERMISSION_DOCUMENT_DELETE","UMB_USER_PERMISSION_DOCUMENT_CREATE_BLUEPRINT","UMB_USER_PERMISSION_DOCUMENT_NOTIFICATIONS","UMB_USER_PERMISSION_DOCUMENT_PUBLISH","UMB_USER_PERMISSION_DOCUMENT_PERMISSIONS","UMB_USER_PERMISSION_DOCUMENT_UNPUBLISH","UMB_USER_PERMISSION_DOCUMENT_DUPLICATE","UMB_USER_PERMISSION_DOCUMENT_MOVE","UMB_USER_PERMISSION_DOCUMENT_SORT","UMB_USER_PERMISSION_DOCUMENT_CULTURE_AND_HOSTNAMES","UMB_USER_PERMISSION_DOCUMENT_PUBLIC_ACCESS","UMB_USER_PERMISSION_DOCUMENT_ROLLBACK","UMB_DOCUMENT_PERMISSION_REPOSITORY_ALIAS","UMB_DOCUMENT_IS_NOT_TRASHED_CONDITION_ALIAS","UMB_DOCUMENT_IS_TRASHED_CONDITION_ALIAS","UMB_DOCUMENT_WORKSPACE_ALIAS","UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD","UMB_DOCUMENT_WORKSPACE_CONTEXT"] + consts: ["UMB_DOCUMENT_COLLECTION_ALIAS","UMB_DOCUMENT_COLLECTION_CONTEXT","UMB_DOCUMENT_COLLECTION_REPOSITORY_ALIAS","UMB_DOCUMENT_GRID_COLLECTION_VIEW_ALIAS","UMB_DOCUMENT_TABLE_COLLECTION_VIEW_ALIAS","UMB_DOCUMENT_CREATE_OPTIONS_MODAL","UMB_CREATE_BLUEPRINT_MODAL","UMB_DOCUMENT_CREATE_BLUEPRINT_REPOSITORY_ALIAS","UMB_CULTURE_AND_HOSTNAMES_MODAL","UMB_DOCUMENT_CULTURE_AND_HOSTNAMES_REPOSITORY_ALIAS","UMB_DUPLICATE_DOCUMENT_MODAL","UMB_DUPLICATE_DOCUMENT_MODAL_ALIAS","UMB_DUPLICATE_DOCUMENT_REPOSITORY_ALIAS","UMB_MOVE_DOCUMENT_REPOSITORY_ALIAS","UMB_DOCUMENT_NOTIFICATIONS_MODAL","UMB_DOCUMENT_NOTIFICATIONS_MODAL_ALIAS","UMB_DOCUMENT_NOTIFICATIONS_REPOSITORY_ALIAS","UMB_PUBLIC_ACCESS_MODAL","UMB_DOCUMENT_PUBLIC_ACCESS_REPOSITORY_ALIAS","UMB_SORT_CHILDREN_OF_DOCUMENT_REPOSITORY_ALIAS","UMB_BULK_DUPLICATE_DOCUMENT_REPOSITORY_ALIAS","UMB_BULK_MOVE_DOCUMENT_REPOSITORY_ALIAS","UMB_BULK_TRASH_DOCUMENT_REPOSITORY_ALIAS","UMB_DOCUMENT_ENTITY_TYPE","UMB_DOCUMENT_ROOT_ENTITY_TYPE","UMB_DOCUMENT_CONFIGURATION_CONTEXT","UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS","UMB_DOCUMENT_STORE_ALIAS","UMB_DOCUMENT_ITEM_STORE_CONTEXT","UMB_CONTENT_MENU_ALIAS","UMB_DOCUMENT_PICKER_MODAL","UMB_DOCUMENT_SAVE_MODAL","UMB_DOCUMENT_SAVE_MODAL_ALIAS","UMB_DOCUMENT_WORKSPACE_PATH","UMB_CREATE_FROM_BLUEPRINT_DOCUMENT_WORKSPACE_PATH_PATTERN","UMB_CREATE_DOCUMENT_WORKSPACE_PATH_PATTERN","UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN","UMB_DOCUMENT_PROPERTY_DATASET_CONTEXT","UMB_DOCUMENT_PUBLISH_MODAL_ALIAS","UMB_DOCUMENT_PUBLISH_MODAL","UMB_DOCUMENT_PUBLISH_WITH_DESCENDANTS_MODAL_ALIAS","UMB_DOCUMENT_PUBLISH_WITH_DESCENDANTS_MODAL","UMB_DOCUMENT_PUBLISHING_REPOSITORY_ALIAS","UMB_DOCUMENT_SCHEDULE_MODAL_ALIAS","UMB_DOCUMENT_SCHEDULE_MODAL","UMB_DOCUMENT_UNPUBLISH_MODAL_ALIAS","UMB_DOCUMENT_UNPUBLISH_MODAL","UMB_DOCUMENT_PUBLISHING_WORKSPACE_CONTEXT","UMB_DOCUMENT_RECYCLE_BIN_ROOT_ENTITY_TYPE","UMB_DOCUMENT_RECYCLE_BIN_REPOSITORY_ALIAS","UMB_DOCUMENT_RECYCLE_BIN_TREE_REPOSITORY_ALIAS","UMB_DOCUMENT_RECYCLE_BIN_TREE_STORE_ALIAS","UMB_DOCUMENT_RECYCLE_BIN_TREE_ALIAS","UMB_DOCUMENT_RECYCLE_BIN_TREE_STORE_CONTEXT","UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS","UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS","UMB_DOCUMENT_DETAIL_STORE_ALIAS","UMB_DOCUMENT_DETAIL_STORE_CONTEXT","UMB_DOCUMENT_VALIDATION_REPOSITORY_ALIAS","UMB_ROLLBACK_MODAL_ALIAS","UMB_ROLLBACK_MODAL","UMB_ROLLBACK_REPOSITORY_ALIAS","UMB_DOCUMENT_SEARCH_PROVIDER_ALIAS","UMB_DOCUMENT_TREE_STORE_CONTEXT","UMB_DOCUMENT_TREE_REPOSITORY_ALIAS","UMB_DOCUMENT_TREE_STORE_ALIAS","UMB_DOCUMENT_TREE_ALIAS","UMB_DOCUMENT_URL_REPOSITORY_ALIAS","UMB_DOCUMENT_URL_STORE_ALIAS","UMB_DOCUMENT_URL_STORE_CONTEXT","UMB_DOCUMENT_USER_PERMISSION_CONDITION_ALIAS","UMB_USER_PERMISSION_DOCUMENT_CREATE","UMB_USER_PERMISSION_DOCUMENT_READ","UMB_USER_PERMISSION_DOCUMENT_UPDATE","UMB_USER_PERMISSION_DOCUMENT_DELETE","UMB_USER_PERMISSION_DOCUMENT_CREATE_BLUEPRINT","UMB_USER_PERMISSION_DOCUMENT_NOTIFICATIONS","UMB_USER_PERMISSION_DOCUMENT_PUBLISH","UMB_USER_PERMISSION_DOCUMENT_PERMISSIONS","UMB_USER_PERMISSION_DOCUMENT_UNPUBLISH","UMB_USER_PERMISSION_DOCUMENT_DUPLICATE","UMB_USER_PERMISSION_DOCUMENT_MOVE","UMB_USER_PERMISSION_DOCUMENT_SORT","UMB_USER_PERMISSION_DOCUMENT_CULTURE_AND_HOSTNAMES","UMB_USER_PERMISSION_DOCUMENT_PUBLIC_ACCESS","UMB_USER_PERMISSION_DOCUMENT_ROLLBACK","UMB_DOCUMENT_PERMISSION_REPOSITORY_ALIAS","UMB_DOCUMENT_IS_NOT_TRASHED_CONDITION_ALIAS","UMB_DOCUMENT_IS_TRASHED_CONDITION_ALIAS","UMB_DOCUMENT_WORKSPACE_ALIAS","UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD","UMB_DOCUMENT_WORKSPACE_CONTEXT"] }, { path: '@umbraco-cms/backoffice/entity-action', @@ -224,7 +224,7 @@ export const foundConsts = [{ }, { path: '@umbraco-cms/backoffice/member', - consts: ["UMB_MEMBER_COLLECTION_ALIAS","UMB_MEMBER_COLLECTION_CONTEXT","UMB_MEMBER_COLLECTION_REPOSITORY_ALIAS","UMB_MEMBER_TABLE_COLLECTION_VIEW_ALIAS","UMB_MEMBER_PICKER_MODAL","UMB_MEMBER_CREATE_OPTIONS_MODAL","UMB_MEMBER_ENTITY_TYPE","UMB_MEMBER_ROOT_ENTITY_TYPE","UMB_MEMBER_WORKSPACE_PATH","UMB_MEMBER_ROOT_WORKSPACE_PATH","UMB_CREATE_MEMBER_WORKSPACE_PATH_PATTERN","UMB_MEMBER_VARIANT_CONTEXT","UMB_MEMBER_DETAIL_REPOSITORY_ALIAS","UMB_MEMBER_DETAIL_STORE_ALIAS","UMB_MEMBER_DETAIL_STORE_CONTEXT","UMB_MEMBER_ITEM_REPOSITORY_ALIAS","UMB_MEMBER_STORE_ALIAS","UMB_MEMBER_ITEM_STORE_CONTEXT","UMB_MEMBER_VALIDATION_REPOSITORY_ALIAS","UMB_MEMBER_SEARCH_PROVIDER_ALIAS","UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD","UMB_MEMBER_WORKSPACE_ALIAS","UMB_MEMBER_WORKSPACE_CONTEXT","UMB_MEMBER_ROOT_WORKSPACE_ALIAS"] + consts: ["UMB_MEMBER_COLLECTION_ALIAS","UMB_MEMBER_COLLECTION_CONTEXT","UMB_MEMBER_COLLECTION_REPOSITORY_ALIAS","UMB_MEMBER_TABLE_COLLECTION_VIEW_ALIAS","UMB_MEMBER_PICKER_MODAL","UMB_MEMBER_CREATE_OPTIONS_MODAL","UMB_MEMBER_ENTITY_TYPE","UMB_MEMBER_ROOT_ENTITY_TYPE","UMB_MEMBER_ITEM_REPOSITORY_ALIAS","UMB_MEMBER_STORE_ALIAS","UMB_MEMBER_ITEM_STORE_CONTEXT","UMB_MEMBER_WORKSPACE_PATH","UMB_MEMBER_ROOT_WORKSPACE_PATH","UMB_CREATE_MEMBER_WORKSPACE_PATH_PATTERN","UMB_MEMBER_VARIANT_CONTEXT","UMB_MEMBER_DETAIL_REPOSITORY_ALIAS","UMB_MEMBER_DETAIL_STORE_ALIAS","UMB_MEMBER_DETAIL_STORE_CONTEXT","UMB_MEMBER_VALIDATION_REPOSITORY_ALIAS","UMB_MEMBER_SEARCH_PROVIDER_ALIAS","UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD","UMB_MEMBER_WORKSPACE_ALIAS","UMB_MEMBER_WORKSPACE_CONTEXT","UMB_MEMBER_ROOT_WORKSPACE_ALIAS"] }, { path: '@umbraco-cms/backoffice/menu', @@ -232,7 +232,7 @@ export const foundConsts = [{ }, { path: '@umbraco-cms/backoffice/modal', - consts: ["UMB_CONFIRM_MODAL","UMB_DISCARD_CHANGES_MODAL","UMB_ITEM_PICKER_MODAL","UMB_MODAL_MANAGER_CONTEXT","UMB_MODAL_CONTEXT"] + consts: ["UMB_CONFIRM_MODAL","UMB_DISCARD_CHANGES_MODAL","UMB_ERROR_VIEWER_MODAL","UMB_ITEM_PICKER_MODAL","UMB_MODAL_MANAGER_CONTEXT","UMB_MODAL_CONTEXT"] }, { path: '@umbraco-cms/backoffice/models', @@ -260,7 +260,7 @@ export const foundConsts = [{ }, { path: '@umbraco-cms/backoffice/picker-input', - consts: [] + consts: ["UMB_PICKER_INPUT_CONTEXT"] }, { path: '@umbraco-cms/backoffice/picker', @@ -384,7 +384,7 @@ export const foundConsts = [{ }, { path: '@umbraco-cms/backoffice/tree', - consts: ["UMB_TREE_CONTEXT","UMB_DUPLICATE_TO_MODAL_ALIAS","UMB_DUPLICATE_TO_MODAL","UMB_SORT_CHILDREN_OF_MODAL_ALIAS","UMB_SORT_CHILDREN_OF_MODAL","UMB_FOLDER_CREATE_MODAL","UMB_FOLDER_UPDATE_MODAL","UMB_TREE_ITEM_CONTEXT","UMB_TREE_PICKER_MODAL_ALIAS","UMB_TREE_PICKER_MODAL"] + consts: ["UMB_TREE_CONTEXT","UMB_DUPLICATE_TO_MODAL_ALIAS","UMB_DUPLICATE_TO_MODAL","UMB_SORT_CHILDREN_OF_MODAL_ALIAS","UMB_SORT_CHILDREN_OF_MODAL","UMB_FOLDER_CREATE_MODAL","UMB_FOLDER_UPDATE_MODAL","UMB_TREE_ITEM_CONTEXT","UMB_TREE_ITEM_DEFAULT_KIND_MANIFEST","UMB_TREE_PICKER_MODAL_ALIAS","UMB_TREE_PICKER_MODAL"] }, { path: '@umbraco-cms/backoffice/ufm', @@ -420,7 +420,7 @@ export const foundConsts = [{ }, { path: '@umbraco-cms/backoffice/webhook', - consts: ["UMB_WEBHOOK_WORKSPACE_ALIAS","UMB_WEBHOOK_WORKSPACE","UMB_WEBHOOK_ENTITY_TYPE","UMB_WEBHOOK_ROOT_ENTITY_TYPE","UMB_WEBHOOK_DELIVERY_ENTITY_TYPE","UMB_WEBHOOK_COLLECTION_ALIAS","UMB_WEBHOOK_COLLECTION_REPOSITORY_ALIAS","UMB_WEBHOOK_TABLE_COLLECTION_VIEW_ALIAS","UMB_WEBHOOK_DETAIL_REPOSITORY_ALIAS","UMB_WEBHOOK_DETAIL_STORE_ALIAS","UMB_WEBHOOK_DETAIL_STORE_CONTEXT","UMB_WEBHOOK_ITEM_REPOSITORY_ALIAS","UMB_WEBHOOK_STORE_ALIAS","UMB_WEBHOOK_ITEM_STORE_CONTEXT","UMB_WEBHOOK_WORKSPACE_CONTEXT","UMB_WEBHOOK_DELIVERY_COLLECTION_ALIAS","UMB_WEBHOOK_DELIVERY_COLLECTION_REPOSITORY_ALIAS","UMB_WEBHOOK_EVENTS_MODAL","UMB_WEBHOOK_EVENT_REPOSITORY_ALIAS","UMB_WEBHOOK_EVENT_STORE_ALIAS","UMB_WEBHOOK_EVENT_STORE_CONTEXT","UMB_WEBHOOK_ROOT_WORKSPACE_ALIAS"] + consts: ["UMB_WEBHOOK_WORKSPACE_ALIAS","UMB_WEBHOOK_WORKSPACE","UMB_WEBHOOK_ENTITY_TYPE","UMB_WEBHOOK_ROOT_ENTITY_TYPE","UMB_WEBHOOK_DELIVERY_ENTITY_TYPE","UMB_WEBHOOK_COLLECTION_ALIAS","UMB_WEBHOOK_COLLECTION_REPOSITORY_ALIAS","UMB_WEBHOOK_TABLE_COLLECTION_VIEW_ALIAS","UMB_WEBHOOK_WORKSPACE_PATH","UMB_CREATE_WEBHOOK_WORKSPACE_PATH_PATTERN","UMB_EDIT_WEBHOOK_WORKSPACE_PATH_PATTERN","UMB_WEBHOOK_DETAIL_REPOSITORY_ALIAS","UMB_WEBHOOK_DETAIL_STORE_ALIAS","UMB_WEBHOOK_DETAIL_STORE_CONTEXT","UMB_WEBHOOK_ITEM_REPOSITORY_ALIAS","UMB_WEBHOOK_STORE_ALIAS","UMB_WEBHOOK_ITEM_STORE_CONTEXT","UMB_WEBHOOK_WORKSPACE_CONTEXT","UMB_WEBHOOK_DELIVERY_COLLECTION_ALIAS","UMB_WEBHOOK_DELIVERY_COLLECTION_REPOSITORY_ALIAS","UMB_WEBHOOK_EVENTS_MODAL","UMB_WEBHOOK_EVENT_REPOSITORY_ALIAS","UMB_WEBHOOK_EVENT_STORE_ALIAS","UMB_WEBHOOK_EVENT_STORE_CONTEXT","UMB_WEBHOOK_ROOT_WORKSPACE_PATH","UMB_WEBHOOK_ROOT_WORKSPACE_ALIAS"] }, { path: '@umbraco-cms/backoffice/workspace', From 0a62426515a5b0dfd9904901e0d0231cff56d536 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Feb 2025 15:07:45 +0100 Subject: [PATCH 099/145] align naming --- ...> document-reference-response.management-api.mapping.ts} | 4 ++-- .../documents/documents/reference/repository/manifests.ts | 6 +++--- .../packages/media/media/reference/repository/manifests.ts | 6 +++--- ...s => media-reference-response.management-api.mapping.ts} | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/{document-reference-response-model.mapping.ts => document-reference-response.management-api.mapping.ts} (89%) rename src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/{media-reference-response-model.mapping.ts => media-reference-response.management-api.mapping.ts} (87%) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response-model.mapping.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response.management-api.mapping.ts similarity index 89% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response-model.mapping.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response.management-api.mapping.ts index 91addf082985..97baecf6526a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response-model.mapping.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference-response.management-api.mapping.ts @@ -7,7 +7,7 @@ import { import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbDataMapping } from '@umbraco-cms/backoffice/repository'; -export class UmbDocumentReferenceResponseModelDataMapping +export class UmbDocumentReferenceResponseManagementApiDataMapping extends UmbControllerBase implements UmbDataMapping { @@ -35,4 +35,4 @@ export class UmbDocumentReferenceResponseModelDataMapping } } -export { UmbDocumentReferenceResponseModelDataMapping as api }; +export { UmbDocumentReferenceResponseManagementApiDataMapping as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts index 82bc4d2f3d9d..81955fe4442e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts @@ -10,9 +10,9 @@ export const manifests: Array = [ }, { type: 'dataMapping', - alias: 'Umb.DataMapping.DocumentReferenceResponseModel', - name: 'Document Reference Response Model to Client Model Data Mapping', - api: () => import('./document-reference-response-model.mapping.js'), + alias: 'Umb.DataMapping.ManagementApi.DocumentReferenceResponse', + name: 'Document Reference Response Management Api Data Mapping', + api: () => import('./document-reference-response.management-api.mapping.js'), dataSourceIdentifier: UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER, dataModelIdentifier: 'DocumentReferenceResponseModel', }, diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts index 087e23ed6316..28d8749c1e7a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts @@ -10,9 +10,9 @@ export const manifests: Array = [ }, { type: 'dataMapping', - alias: 'Umb.DataMapping.MediaReferenceResponseModel', - name: 'Media Reference Response Model to Client Model Data Mapping', - api: () => import('./media-reference-response-model.mapping.js'), + alias: 'Umb.DataMapping.ManagementApi.MediaReferenceResponse', + name: 'Media Reference Response Management Api Data Mapping', + api: () => import('./media-reference-response.management-api.mapping.js'), dataSourceIdentifier: UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER, dataModelIdentifier: 'MediaReferenceResponseModel', }, diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response-model.mapping.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response.management-api.mapping.ts similarity index 87% rename from src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response-model.mapping.ts rename to src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response.management-api.mapping.ts index 0cadae7acf0e..f00cf503c248 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response-model.mapping.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference-response.management-api.mapping.ts @@ -4,7 +4,7 @@ import type { MediaReferenceResponseModel } from '@umbraco-cms/backoffice/extern import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbDataMapping } from '@umbraco-cms/backoffice/repository'; -export class UmbMediaReferenceResponseModelDataMapping +export class UmbMediaReferenceResponseManagementApiDataMapping extends UmbControllerBase implements UmbDataMapping { @@ -30,4 +30,4 @@ export class UmbMediaReferenceResponseModelDataMapping } } -export { UmbMediaReferenceResponseModelDataMapping as api }; +export { UmbMediaReferenceResponseManagementApiDataMapping as api }; From f83ee80bcfc5c0e701c8c3b75282f339cc2b2bbe Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Feb 2025 15:27:57 +0100 Subject: [PATCH 100/145] show references when deleting a document --- .../documents/entity-actions/manifests.ts | 4 +- .../delete-with-relation-modal.element.ts | 119 +++--------------- ...onfirm-action-entity-references.element.ts | 9 ++ .../packages/relations/relations/manifests.ts | 2 + 4 files changed, 29 insertions(+), 105 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/manifests.ts index 3c1a1fcd1be2..ecbb1a7e5c24 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-actions/manifests.ts @@ -2,6 +2,7 @@ import { UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS } from '../repository/index.js'; import { UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS } from '../item/constants.js'; import { UMB_DOCUMENT_ENTITY_TYPE } from '../entity.js'; import { UMB_USER_PERMISSION_DOCUMENT_DELETE } from '../user-permissions/constants.js'; +import { UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS } from '../reference/constants.js'; import { manifests as createBlueprintManifests } from './create-blueprint/manifests.js'; import { manifests as createManifests } from './create/manifests.js'; import { manifests as cultureAndHostnamesManifests } from './culture-and-hostnames/manifests.js'; @@ -15,13 +16,14 @@ import { UMB_ENTITY_IS_TRASHED_CONDITION_ALIAS } from '@umbraco-cms/backoffice/r const entityActions: Array = [ { type: 'entityAction', - kind: 'delete', + kind: 'deleteWithRelation', alias: 'Umb.EntityAction.Document.Delete', name: 'Delete Document Entity Action', forEntityTypes: [UMB_DOCUMENT_ENTITY_TYPE], meta: { itemRepositoryAlias: UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS, detailRepositoryAlias: UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS, + referenceRepositoryAlias: UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS, }, conditions: [ { diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts index 524a90a680be..3bb05b085e42 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts @@ -1,15 +1,16 @@ -import type { UmbEntityReferenceRepository, UmbReferenceItemModel } from '../../../types.js'; import type { UmbDeleteWithRelationConfirmModalData, UmbDeleteWithRelationConfirmModalValue, } from './delete-with-relation-modal.token.js'; -import { html, customElement, css, state, nothing, type PropertyValues } from '@umbraco-cms/backoffice/external/lit'; +import { html, customElement, css, state, type PropertyValues, nothing } from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; import { umbFocus } from '@umbraco-cms/backoffice/lit-element'; import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; +import '../../local-components/confirm-action-entity-references.element.js'; + @customElement('umb-delete-with-relation-confirm-modal') export class UmbDeleteWithRelationConfirmModalElement extends UmbModalBaseElement< UmbDeleteWithRelationConfirmModalData, @@ -19,21 +20,9 @@ export class UmbDeleteWithRelationConfirmModalElement extends UmbModalBaseElemen _name?: string; @state() - _referencedByItems: Array = []; - - @state() - _totalReferencedByItems: number = 0; - - @state() - _totalDescendantsWithReferences: number = 0; - - @state() - _descendantsWithReferences: Array = []; + _referencesConfig?: any; #itemRepository?: UmbItemRepository; - #referenceRepository?: UmbEntityReferenceRepository; - - #limitItems = 3; protected override firstUpdated(_changedProperties: PropertyValues): void { super.firstUpdated(_changedProperties); @@ -43,7 +32,6 @@ export class UmbDeleteWithRelationConfirmModalElement extends UmbModalBaseElemen async #initData() { if (!this.data) { this.#itemRepository?.destroy(); - this.#referenceRepository?.destroy(); return; } @@ -55,76 +43,24 @@ export class UmbDeleteWithRelationConfirmModalElement extends UmbModalBaseElemen this._name = item.name; - if (!this.data?.referenceRepositoryAlias) { - throw new Error('Missing referenceRepositoryAlias in data.'); - } - - this.#referenceRepository = await createExtensionApiByAlias( - this, - this.data?.referenceRepositoryAlias, - ); - - this.#loadReferencedBy(); - this.#loadDescendantsWithReferences(); - } - - async #loadReferencedBy() { - if (!this.#referenceRepository) { - throw new Error('Failed to create reference repository.'); - } - - if (!this.data?.unique) { - throw new Error('Missing unique in data.'); - } - - const { data } = await this.#referenceRepository.requestReferencedBy(this.data.unique, 0, this.#limitItems); - - if (data) { - this._referencedByItems = [...data.items]; - this._totalReferencedByItems = data.total; - } - } - - async #loadDescendantsWithReferences() { - if (!this.#referenceRepository) { - throw new Error('Failed to create reference repository.'); - } - - if (!this.#itemRepository) { - throw new Error('Failed to create item repository.'); - } - - // If the repository does not have the method, we don't need to load the referenced descendants. - if (!this.#referenceRepository.requestDescendantsWithReferences) return; - - if (!this.data?.unique) { - throw new Error('Missing unique in data.'); - } + this._referencesConfig = { + unique: this.data.unique, + itemRepositoryAlias: this.data.itemRepositoryAlias, + referenceRepositoryAlias: this.data.referenceRepositoryAlias, + }; - const { data } = await this.#referenceRepository.requestDescendantsWithReferences( - this.data.unique, - 0, - this.#limitItems, - ); - - if (data) { - this._totalDescendantsWithReferences = data.total; - const uniques = data.items.map((item) => item.unique).filter((unique) => unique) as Array; - const { data: items } = await this.#itemRepository.requestItems(uniques); - this._descendantsWithReferences = items ?? []; - } + debugger; } override render() { return html`

Are you sure you want to move ${this._name} to the recycle bin?

- ${this.#renderItems('references_labelDependsOnThis', this._referencedByItems, this._totalReferencedByItems)} - ${this.#renderItems( - 'references_labelDependentDescendants', - this._descendantsWithReferences, - this._totalDescendantsWithReferences, - )} + + ${this._referencesConfig + ? html`` + : nothing} @@ -140,37 +76,12 @@ export class UmbDeleteWithRelationConfirmModalElement extends UmbModalBaseElemen `; } - #renderItems(headline: string, items: Array, total: number) { - if (total === 0) return nothing; - - return html` -
${this.localize.term(headline)}
- - ${items.map( - (item) => - html` `, - )} - - ${total > this.#limitItems - ? html`${this.localize.term('references_labelMoreReferences', total - this.#limitItems)}` - : nothing} - `; - } - static override styles = [ UmbTextStyles, css` uui-dialog-layout { max-inline-size: 60ch; } - - #reference-headline { - margin-bottom: var(--uui-size-3); - } - - uui-ref-list { - margin-bottom: var(--uui-size-2); - } `, ]; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts index 8fc56fc2306f..dbba7e2b2fdd 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts @@ -61,6 +61,15 @@ export class UmbConfirmActionEntityReferencesElement extends UmbLitElement { this.config?.referenceRepositoryAlias, ); + if (!this.config?.itemRepositoryAlias) { + throw new Error('Missing itemRepositoryAlias in config.'); + } + + this.#itemRepository = await createExtensionApiByAlias>( + this, + this.config.itemRepositoryAlias, + ); + this.#loadReferencedBy(); this.#loadDescendantsWithReferences(); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts index 30dd3979a3f1..574ed691cfbd 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts @@ -1,8 +1,10 @@ import { manifests as collectionManifests } from './collection/manifests.js'; +import { manifests as deleteManifests } from './entity-actions/delete/manifests.js'; import { manifests as trashManifests } from './entity-actions/trash/manifests.js'; import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; export const manifests: Array = [ ...collectionManifests, + ...deleteManifests, ...trashManifests, ]; From 1443b9cda2f4e4e3e881c5d5b1272e72262126be Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Feb 2025 15:28:50 +0100 Subject: [PATCH 101/145] Update delete-with-relation-modal.element.ts --- .../delete/modal/delete-with-relation-modal.element.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts index 3bb05b085e42..2353791d7006 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts @@ -48,8 +48,6 @@ export class UmbDeleteWithRelationConfirmModalElement extends UmbModalBaseElemen itemRepositoryAlias: this.data.itemRepositoryAlias, referenceRepositoryAlias: this.data.referenceRepositoryAlias, }; - - debugger; } override render() { From 681516068327979ccf44f48463442a4e4daf7080 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Feb 2025 15:42:10 +0100 Subject: [PATCH 102/145] use deleteWithRelation kind for media --- .../src/packages/media/media/entity-actions/manifests.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-actions/manifests.ts index c27a0c6bb13c..f1c4effd4088 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-actions/manifests.ts @@ -1,4 +1,8 @@ -import { UMB_MEDIA_DETAIL_REPOSITORY_ALIAS, UMB_MEDIA_ITEM_REPOSITORY_ALIAS } from '../constants.js'; +import { + UMB_MEDIA_DETAIL_REPOSITORY_ALIAS, + UMB_MEDIA_ITEM_REPOSITORY_ALIAS, + UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS, +} from '../constants.js'; import { UMB_MEDIA_ENTITY_TYPE } from '../entity.js'; import { manifests as createManifests } from './create/manifests.js'; import { manifests as moveManifests } from './move-to/manifests.js'; @@ -11,11 +15,12 @@ export const manifests: Array = [ type: 'entityAction', alias: 'Umb.EntityAction.Media.Delete', name: 'Delete Media Entity Action ', - kind: 'delete', + kind: 'deleteWithRelation', forEntityTypes: [UMB_MEDIA_ENTITY_TYPE], meta: { itemRepositoryAlias: UMB_MEDIA_ITEM_REPOSITORY_ALIAS, detailRepositoryAlias: UMB_MEDIA_DETAIL_REPOSITORY_ALIAS, + referenceRepositoryAlias: UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS, }, conditions: [ { From 0e206b685d39151b748ee1d520e5100c85c5f240 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Feb 2025 16:38:39 +0100 Subject: [PATCH 103/145] clean up --- .../common/delete/delete.action.ts | 6 ++++ .../delete/delete-with-relation.action.ts | 11 ++++++- .../delete-with-relation-modal.element.ts | 30 ++++++++++++++----- ...onfirm-action-entity-references.element.ts | 8 ++--- .../trash-with-relation-modal.element.ts | 4 +-- 5 files changed, 44 insertions(+), 15 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 0fadb1aa7867..0fbf2fc6728b 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,9 +38,15 @@ export class UmbDeleteEntityAction extends UmbEntityActionBase>( + this, + this.args.meta.detailRepositoryAlias, + ); + + await detailRepository.delete(this.args.unique); + + await this.#notify(); } async #notify() { diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts index 2353791d7006..539568c271ad 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/modal/delete-with-relation-modal.element.ts @@ -2,7 +2,15 @@ import type { UmbDeleteWithRelationConfirmModalData, UmbDeleteWithRelationConfirmModalValue, } from './delete-with-relation-modal.token.js'; -import { html, customElement, css, state, type PropertyValues, nothing } from '@umbraco-cms/backoffice/external/lit'; +import { + html, + customElement, + css, + state, + type PropertyValues, + nothing, + unsafeHTML, +} from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; import { umbFocus } from '@umbraco-cms/backoffice/lit-element'; @@ -51,23 +59,29 @@ export class UmbDeleteWithRelationConfirmModalElement extends UmbModalBaseElemen } override render() { - return html` - -

Are you sure you want to move ${this._name} to the recycle bin?

+ const headline = this.localize.string('#actions_delete'); + const content = this.localize.string('#defaultdialogs_confirmdelete', this._name); + return html` + +

${unsafeHTML(content)}

${this._referencesConfig - ? html`` + ? html`` : nothing} - +
diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts index dbba7e2b2fdd..73c8d8b41abe 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts @@ -13,8 +13,8 @@ import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -@customElement('umb-confirm-action-entity-references') -export class UmbConfirmActionEntityReferencesElement extends UmbLitElement { +@customElement('umb-confirm-action-modal-entity-references') +export class UmbConfirmActionModalEntityReferencesElement extends UmbLitElement { @property({ type: Object, attribute: false }) config?: { itemRepositoryAlias: string; @@ -163,10 +163,10 @@ export class UmbConfirmActionEntityReferencesElement extends UmbLitElement { ]; } -export { UmbConfirmActionEntityReferencesElement as element }; +export { UmbConfirmActionModalEntityReferencesElement as element }; declare global { interface HTMLElementTagNameMap { - 'umb-confirm-action-entity-references': UmbConfirmActionEntityReferencesElement; + 'umb-confirm-action-modal-entity-references': UmbConfirmActionModalEntityReferencesElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts index cdfc9d0639d8..52f07bf28a71 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts @@ -57,8 +57,8 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement

Are you sure you want to move ${this._name} to the recycle bin?

${this._referencesConfig - ? html`` + ? html`` : nothing} From 2823164bbba3fc283c466ad21486015d6f8e3706 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Feb 2025 16:57:03 +0100 Subject: [PATCH 104/145] localize trash --- .../src/assets/lang/en.ts | 1 + .../entity-action/trash/trash.action.ts | 12 +++++++++--- .../trash-with-relation-modal.element.ts | 19 +++++++++++++++---- 3 files changed, 25 insertions(+), 7 deletions(-) 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 40c1be0e3f3e..30874d36cf8c 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts @@ -510,6 +510,7 @@ export default { confirmremoveusageof: 'Are you sure you want to remove the usage of %0%', confirmlogout: 'Are you sure?', confirmSure: 'Are you sure?', + confirmtrash: (name: string) => `Are you sure you want to move ${name} to the Recycle Bin?`, cut: 'Cut', editDictionary: 'Edit dictionary item', editLanguage: 'Edit language', diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts index 999b1fe0fb88..5cda8799f942 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts @@ -6,6 +6,7 @@ import { umbConfirmModal } from '@umbraco-cms/backoffice/modal'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; import { UmbEntityActionBase, UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/entity-action'; +import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api'; /** * Entity action for trashing an item. @@ -13,6 +14,8 @@ import { UmbEntityActionBase, UmbRequestReloadStructureForEntityEvent } from '@u * @augments {UmbEntityActionBase} */ export class UmbTrashEntityAction extends UmbEntityActionBase { + #localize = new UmbLocalizationController(this); + /** * Executes the action. * @memberof UmbTrashEntityAction @@ -29,12 +32,15 @@ export class UmbTrashEntityAction extends UmbEntityActionBase( diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts index 52f07bf28a71..35c2032fd679 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts @@ -2,7 +2,15 @@ import type { UmbTrashWithRelationConfirmModalData, UmbTrashWithRelationConfirmModalValue, } from './trash-with-relation-modal.token.js'; -import { html, customElement, css, state, type PropertyValues, nothing } from '@umbraco-cms/backoffice/external/lit'; +import { + html, + customElement, + css, + state, + type PropertyValues, + nothing, + unsafeHTML, +} from '@umbraco-cms/backoffice/external/lit'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; import { umbFocus } from '@umbraco-cms/backoffice/lit-element'; @@ -52,9 +60,12 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement } override render() { + const headline = this.localize.string('#actions_trash'); + const content = this.localize.string('#defaultdialogs_confirmtrash', this._name); + return html` - -

Are you sure you want to move ${this._name} to the recycle bin?

+ +

${unsafeHTML(content)}

${this._referencesConfig ? html`
From e0eca329bb25f35027adf115e1a5a3e6c216e111 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Feb 2025 17:23:45 +0100 Subject: [PATCH 105/145] fix type --- src/Umbraco.Web.UI.Client/src/packages/relations/manifests.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/manifests.ts index 66c4ca9ee9ab..0f5c2ccc4c99 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/manifests.ts @@ -2,8 +2,9 @@ import { manifests as menuManifests } from './menu/manifests.js'; import { manifests as relationManifests } from './relations/manifests.js'; import { manifests as relationTypeManifests } from './relation-types/manifests.js'; import { manifests as workspaceManifests } from './workspace/manifests.js'; +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; -export const manifests: Array = [ +export const manifests: Array = [ ...menuManifests, ...relationManifests, ...relationTypeManifests, From 1f264f6cd3a537da418e69b22f3b4bf3fad8deeb Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Feb 2025 18:18:05 +0100 Subject: [PATCH 106/145] Update trash-with-relation.action.ts --- .../entity-actions/trash/trash-with-relation.action.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/trash-with-relation.action.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/trash-with-relation.action.ts index 444b2341ed4f..3a04788f905c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/trash-with-relation.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/trash-with-relation.action.ts @@ -4,7 +4,7 @@ import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-reg import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; import { UmbEntityActionBase, UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/entity-action'; -import { UmbEntityTrashedEvent } from '@umbraco-cms/backoffice/recycle-bin'; +import { UmbEntityTrashedEvent, type UmbRecycleBinRepository } from '@umbraco-cms/backoffice/recycle-bin'; /** * Entity action for trashing an item with relations. From c37302ee1619f3538552d9f6e40f9d9a67768ef6 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Feb 2025 19:47:15 +0100 Subject: [PATCH 107/145] override confirm methods in trash and delete actions --- .../src/assets/lang/en.ts | 2 +- .../common/delete/delete.action.ts | 34 ++++++++++---- .../entity-action/trash/trash.action.ts | 35 +++++++++----- .../delete/delete-with-relation.action.ts | 33 ++----------- .../trash/trash-with-relation.action.ts | 46 ++----------------- 5 files changed, 57 insertions(+), 93 deletions(-) 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 30874d36cf8c..8875dbea0980 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts @@ -510,7 +510,7 @@ export default { confirmremoveusageof: 'Are you sure you want to remove the usage of %0%', confirmlogout: 'Are you sure?', confirmSure: 'Are you sure?', - confirmtrash: (name: string) => `Are you sure you want to move ${name} to the Recycle Bin?`, + confirmtrash: (name: string) => `Are you sure you want to move ${name} to the Recycle Bin?`, cut: 'Cut', editDictionary: 'Edit dictionary item', editLanguage: 'Edit language', 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 0fbf2fc6728b..4fa014b07371 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,22 +7,30 @@ 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'; -export class UmbDeleteEntityAction extends UmbEntityActionBase { +export class UmbDeleteEntityAction< + MetaKind extends MetaEntityActionDeleteKind = MetaEntityActionDeleteKind, +> 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.'); - const itemRepository = await createExtensionApiByAlias>( + const item = await this.#requestItem(); + + await this._confirmDelete(item); + + const detailRepository = await createExtensionApiByAlias>( this, - this.args.meta.itemRepositoryAlias, + this.args.meta.detailRepositoryAlias, ); - const { data } = await itemRepository.requestItems([this.args.unique]); - const item = data?.[0]; - if (!item) throw new Error('Item not found.'); + await detailRepository.delete(this.args.unique); + + await this.#notify(); + } + async _confirmDelete(item: any) { const headline = this.args.meta.confirm?.headline ?? '#actions_delete'; const message = this.args.meta.confirm?.message ?? '#defaultdialogs_confirmdelete'; @@ -33,15 +41,21 @@ export class UmbDeleteEntityAction extends UmbEntityActionBase>( + async #requestItem() { + if (!this.args.unique) throw new Error('Cannot delete an item without a unique identifier.'); + + const itemRepository = await createExtensionApiByAlias>( this, - this.args.meta.detailRepositoryAlias, + this.args.meta.itemRepositoryAlias, ); - await detailRepository.delete(this.args.unique); + const { data } = await itemRepository.requestItems([this.args.unique]); + const item = data?.[0]; + if (!item) throw new Error('Item not found.'); - await this.#notify(); + return item; } async #notify() { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts index 5cda8799f942..69f2fe69b400 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts @@ -13,7 +13,9 @@ import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization- * @class UmbTrashEntityAction * @augments {UmbEntityActionBase} */ -export class UmbTrashEntityAction extends UmbEntityActionBase { +export class UmbTrashEntityAction< + MetaKindType extends MetaEntityActionTrashKind = MetaEntityActionTrashKind, +> extends UmbEntityActionBase { #localize = new UmbLocalizationController(this); /** @@ -23,15 +25,21 @@ export class UmbTrashEntityAction extends UmbEntityActionBase>( + const item = await this.#requestItem(); + + await this._confirmTrash(item); + + const recycleBinRepository = await createExtensionApiByAlias( this, - this.args.meta.itemRepositoryAlias, + this.args.meta.recycleBinRepositoryAlias, ); - const { data } = await itemRepository.requestItems([this.args.unique]); - const item = data?.[0]; - if (!item) throw new Error('Item not found.'); + await recycleBinRepository.requestTrash({ unique: this.args.unique }); + + this.#notify(); + } + protected async _confirmTrash(item: any) { const headline = '#actions_trash'; const message = '#defaultdialogs_confirmtrash'; @@ -42,15 +50,20 @@ export class UmbTrashEntityAction extends UmbEntityActionBase( + async #requestItem() { + if (!this.args.unique) throw new Error('Cannot trash an item without a unique identifier.'); + + const itemRepository = await createExtensionApiByAlias>( this, - this.args.meta.recycleBinRepositoryAlias, + this.args.meta.itemRepositoryAlias, ); - await recycleBinRepository.requestTrash({ unique: this.args.unique }); - - this.#notify(); + const { data } = await itemRepository.requestItems([this.args.unique]); + const item = data?.[0]; + if (!item) throw new Error('Item not found.'); + return item; } async #notify() { diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/delete-with-relation.action.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/delete-with-relation.action.ts index 328f0b4958ec..89e5c23c7e1d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/delete-with-relation.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/delete-with-relation.action.ts @@ -1,22 +1,15 @@ import type { MetaEntityActionDeleteWithRelationKind } from './types.js'; import { UMB_DELETE_WITH_RELATION_CONFIRM_MODAL } from './modal/constants.js'; import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; -import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; -import { UmbEntityActionBase, UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/entity-action'; -import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; -import type { UmbDetailRepository } from '@umbraco-cms/backoffice/repository'; +import { UmbDeleteEntityAction } from '@umbraco-cms/backoffice/entity-action'; /** * Entity action for deleting an item with relations. * @class UmbDeleteWithRelationEntityAction * @augments {UmbEntityActionBase} */ -export class UmbDeleteWithRelationEntityAction extends UmbEntityActionBase { - /** - * Executes the action. - * @memberof UmbDeleteWithRelationEntityAction - */ - override async execute() { +export class UmbDeleteWithRelationEntityAction extends UmbDeleteEntityAction { + override async _confirmDelete() { if (!this.args.unique) throw new Error('Cannot delete an item without a unique identifier.'); const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); @@ -31,26 +24,6 @@ export class UmbDeleteWithRelationEntityAction extends UmbEntityActionBase>( - this, - this.args.meta.detailRepositoryAlias, - ); - - await detailRepository.delete(this.args.unique); - - await this.#notify(); - } - - async #notify() { - const actionEventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); - - const event = new UmbRequestReloadStructureForEntityEvent({ - unique: this.args.unique, - entityType: this.args.entityType, - }); - - actionEventContext.dispatchEvent(event); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/trash-with-relation.action.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/trash-with-relation.action.ts index 3a04788f905c..f5ac8dd4518c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/trash-with-relation.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/trash-with-relation.action.ts @@ -1,63 +1,27 @@ import type { MetaEntityActionTrashWithRelationKind } from './types.js'; import { UMB_TRASH_WITH_RELATION_CONFIRM_MODAL } from './modal/constants.js'; -import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; -import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; -import { UmbEntityActionBase, UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/entity-action'; -import { UmbEntityTrashedEvent, type UmbRecycleBinRepository } from '@umbraco-cms/backoffice/recycle-bin'; +import { UmbTrashEntityAction } from '@umbraco-cms/backoffice/recycle-bin'; /** * Entity action for trashing an item with relations. * @class UmbTrashWithRelationEntityAction * @augments {UmbEntityActionBase} */ -export class UmbTrashWithRelationEntityAction extends UmbEntityActionBase { - /** - * Executes the action. - * @memberof UmbTrashWithRelationEntityAction - */ - override async execute() { - if (!this.args.unique) throw new Error('Cannot trash an item without a unique identifier.'); - +export class UmbTrashWithRelationEntityAction extends UmbTrashEntityAction { + override async _confirmTrash(item: any) { const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); const modal = modalManager.open(this, UMB_TRASH_WITH_RELATION_CONFIRM_MODAL, { data: { - unique: this.args.unique, - entityType: this.args.entityType, + unique: item.unique, + entityType: item.entityType, itemRepositoryAlias: this.args.meta.itemRepositoryAlias, referenceRepositoryAlias: this.args.meta.referenceRepositoryAlias, }, }); await modal.onSubmit(); - - const recycleBinRepository = await createExtensionApiByAlias( - this, - this.args.meta.recycleBinRepositoryAlias, - ); - - await recycleBinRepository.requestTrash({ unique: this.args.unique }); - - this.#notify(); - } - - async #notify() { - const actionEventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); - - const event = new UmbRequestReloadStructureForEntityEvent({ - unique: this.args.unique, - entityType: this.args.entityType, - }); - - actionEventContext.dispatchEvent(event); - - const trashedEvent = new UmbEntityTrashedEvent({ - unique: this.args.unique, - entityType: this.args.entityType, - }); - - actionEventContext.dispatchEvent(trashedEvent); } } From cbd7ea49385944fff47fcbf3fb940b0f4040a3bf Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Feb 2025 19:47:56 +0100 Subject: [PATCH 108/145] Update index.ts --- src/Umbraco.Web.UI.Client/utils/all-umb-consts/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 60c23df656c7..dddd09efbfac 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 @@ -144,7 +144,7 @@ export const foundConsts = [{ }, { path: '@umbraco-cms/backoffice/entity-action', - consts: ["UMB_ENTITY_CREATE_OPTION_ACTION_LIST_MODAL_ALIAS","UMB_ENTITY_CREATE_OPTION_ACTION_LIST_MODAL","UMB_ENTITY_ACTION_DEFAULT_KIND_MANIFEST"] + consts: ["UMB_ENTITY_CREATE_OPTION_ACTION_LIST_MODAL_ALIAS","UMB_ENTITY_CREATE_OPTION_ACTION_LIST_MODAL","UMB_ENTITY_ACTION_DELETE_KIND_MANIFEST","UMB_ENTITY_ACTION_DEFAULT_KIND_MANIFEST"] }, { path: '@umbraco-cms/backoffice/entity-bulk-action', @@ -284,7 +284,7 @@ export const foundConsts = [{ }, { path: '@umbraco-cms/backoffice/recycle-bin', - consts: ["UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS","UMB_ENTITY_IS_TRASHED_CONDITION_ALIAS","UMB_IS_TRASHED_ENTITY_CONTEXT","UMB_RESTORE_FROM_RECYCLE_BIN_MODAL"] + consts: ["UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS","UMB_ENTITY_IS_TRASHED_CONDITION_ALIAS","UMB_IS_TRASHED_ENTITY_CONTEXT","UMB_RESTORE_FROM_RECYCLE_BIN_MODAL","UMB_ENTITY_ACTION_TRASH_KIND_MANIFEST"] }, { path: '@umbraco-cms/backoffice/relation-type', @@ -292,11 +292,11 @@ export const foundConsts = [{ }, { path: '@umbraco-cms/backoffice/relations', - consts: ["UMB_RELATION_COLLECTION_REPOSITORY_ALIAS","UMB_RELATION_ENTITY_TYPE"] + consts: ["UMB_RELATION_COLLECTION_REPOSITORY_ALIAS","UMB_DELETE_WITH_RELATION_CONFIRM_MODAL","UMB_TRASH_WITH_RELATION_CONFIRM_MODAL","UMB_RELATION_ENTITY_TYPE"] }, { path: '@umbraco-cms/backoffice/repository', - consts: [] + consts: ["UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER"] }, { path: '@umbraco-cms/backoffice/resources', From 76550891095eb67bbf8692bbef00215bea54e4d4 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Feb 2025 19:51:28 +0100 Subject: [PATCH 109/145] export constants --- .../src/packages/relations/relations/constants.ts | 4 +++- .../relations/relations/entity-actions/delete/constants.ts | 1 + .../relations/relations/entity-actions/trash/constants.ts | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/constants.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/constants.ts index fcb47bcacf62..1ad52da7ec8a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/constants.ts @@ -1,2 +1,4 @@ -export * from './collection/constants.js'; export { UMB_RELATION_ENTITY_TYPE } from './entity.js'; +export * from './collection/constants.js'; +export * from './entity-actions/delete/constants.js'; +export * from './entity-actions/trash/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/constants.ts new file mode 100644 index 000000000000..26f4f0dd5f39 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/delete/constants.ts @@ -0,0 +1 @@ +export * from './modal/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/constants.ts new file mode 100644 index 000000000000..26f4f0dd5f39 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/constants.ts @@ -0,0 +1 @@ +export * from './modal/constants.js'; From a17842499fe31186bd5118494aed46c97bfacd7e Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Mon, 17 Feb 2025 21:33:33 +0100 Subject: [PATCH 110/145] Limit referenced-by document and media endpoints to references only. --- .../Document/References/ReferencedByDocumentController.cs | 4 ++-- .../Media/References/ReferencedByMediaController.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Document/References/ReferencedByDocumentController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Document/References/ReferencedByDocumentController.cs index a818e70af89f..47df66fd6df6 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Document/References/ReferencedByDocumentController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Document/References/ReferencedByDocumentController.cs @@ -1,4 +1,4 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Umbraco.Cms.Api.Common.ViewModels.Pagination; @@ -37,7 +37,7 @@ public async Task>> Referen int skip = 0, int take = 20) { - PagedModel relationItems = await _trackedReferencesService.GetPagedRelationsForItemAsync(id, skip, take, false); + PagedModel relationItems = await _trackedReferencesService.GetPagedRelationsForItemAsync(id, skip, take, true); var pagedViewModel = new PagedViewModel { diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Media/References/ReferencedByMediaController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Media/References/ReferencedByMediaController.cs index b457ee602c1e..63748741b1f7 100644 --- a/src/Umbraco.Cms.Api.Management/Controllers/Media/References/ReferencedByMediaController.cs +++ b/src/Umbraco.Cms.Api.Management/Controllers/Media/References/ReferencedByMediaController.cs @@ -1,4 +1,4 @@ -using Asp.Versioning; +using Asp.Versioning; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Umbraco.Cms.Api.Common.ViewModels.Pagination; @@ -37,7 +37,7 @@ public async Task>> Referen int skip = 0, int take = 20) { - PagedModel relationItems = await _trackedReferencesService.GetPagedRelationsForItemAsync(id, skip, take, false); + PagedModel relationItems = await _trackedReferencesService.GetPagedRelationsForItemAsync(id, skip, take, true); var pagedViewModel = new PagedViewModel { From 3d6be7ada410282a07a5dee20e74b14e5d0d7b4f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 18 Feb 2025 10:08:22 +0100 Subject: [PATCH 111/145] Update document-reference-table.element.ts --- .../reference/components/document-reference-table.element.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/components/document-reference-table.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/components/document-reference-table.element.ts index 805d7c357c65..5e73b4c2e9a8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/components/document-reference-table.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/components/document-reference-table.element.ts @@ -44,7 +44,8 @@ export class UmbDocumentReferenceTableElement extends UmbLitElement { } if (!data) return; - + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore this._items = data.items; this._hasMoreReferences = data.total > this.#pageSize ? data.total - this.#pageSize : 0; } From ac837751d861bcfbf2a6d5aaf69e2363580cfaf5 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 18 Feb 2025 12:36:13 +0100 Subject: [PATCH 112/145] add methods to get bulk references for documents --- .../document-reference.repository.ts | 5 +++ .../document-reference.server.data.ts | 32 +++++++++++++++++++ .../relations/relations/reference/types.ts | 14 ++++++++ 3 files changed, 51 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.repository.ts index fa3b1f6dbe3a..0f1ae193f249 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.repository.ts @@ -16,6 +16,11 @@ export class UmbDocumentReferenceRepository extends UmbControllerBase implements return this.#referenceSource.getReferencedBy(unique, skip, take); } + async requestAreReferenced(uniques: Array, skip = 0, take = 20) { + if (!uniques || uniques.length === 0) throw new Error(`uniques is required`); + return this.#referenceSource.getAreReferenced(uniques, skip, take); + } + async requestDescendantsWithReferences(unique: string, skip = 0, take = 20) { if (!unique) throw new Error(`unique is required`); return this.#referenceSource.getReferencedDescendants(unique, skip, take); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts index ccaecbea1d23..6b3a247d63f4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts @@ -55,6 +55,38 @@ export class UmbDocumentReferenceServerDataSource extends UmbControllerBase impl return { data, error }; } + /** + * Fetches items that are referenced by the given uniques from the server + * @param {Array} uniques - The unique identifiers of the items to fetch + * @param {number} skip - The number of items to skip + * @param {number} take - The number of items to take + * @returns {Promise>>} - Items that are referenced by other items + * @memberof UmbDocumentReferenceServerDataSource + */ + async getAreReferenced( + uniques: Array, + skip: number = 0, + take: number = 20, + ): Promise>> { + const { data, error } = await tryExecuteAndNotify( + this, + DocumentService.getDocumentAreReferenced({ id: uniques, skip, take }), + ); + + if (data) { + const items: Array = data.items.map((item) => { + return { + unique: item.id, + entityType: UMB_DOCUMENT_ENTITY_TYPE, + }; + }); + + return { data: { items, total: data.total } }; + } + + return { data, error }; + } + /** * Returns any descendants of the given unique that is referenced by other items * @param {string} unique - The unique identifier of the item to fetch descendants for diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts index a84034a6421b..599ee7559b9b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/reference/types.ts @@ -21,6 +21,13 @@ export interface UmbEntityReferenceRepository extends UmbApi { skip?: number, take?: number, ): Promise>>; + + requestAreReferenced( + uniques: Array, + skip?: number, + take?: number, + ): Promise>>; + requestDescendantsWithReferences?( unique: string, skip?: number, @@ -34,6 +41,13 @@ export interface UmbEntityReferenceDataSource { skip?: number, take?: number, ): Promise>>; + + getAreReferenced( + uniques: Array, + skip?: number, + take?: number, + ): Promise>>; + getReferencedDescendants?( unique: string, skip?: number, From b4de0be6a9a95b61d4398e88551561e229bb1f5d Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 18 Feb 2025 15:15:08 +0100 Subject: [PATCH 113/145] wip bulk trash --- .../common/trash/manifests.ts | 2 +- .../entity-bulk-action.extension.ts | 4 +- .../bulk-trash/bulk-trash.action.kind.ts | 24 ++++++ .../bulk-trash/bulk-trash.action.ts | 84 +++++++++++++++++++ .../bulk-trash/constants.ts | 1 + .../entity-bulk-action/bulk-trash/index.ts | 3 + .../bulk-trash/manifests.ts | 4 + .../entity-bulk-action/bulk-trash/types.ts | 20 +++++ .../packages/core/recycle-bin/manifests.ts | 2 + .../entity-bulk-actions/trash/manifests.ts | 5 +- 10 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/manifests.ts index 46ec59d132b6..a7d8f840985d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/manifests.ts @@ -1,4 +1,4 @@ import { manifest as trashKindManifest } from './trash.action.kind.js'; import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; -export const manifests: Array = [trashKindManifest]; +export const manifests: Array = []; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/extensions/entity-bulk-action.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/extensions/entity-bulk-action.extension.ts index 969a1e28a638..4d5b2adcb532 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/extensions/entity-bulk-action.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/extension-registry/extensions/entity-bulk-action.extension.ts @@ -17,7 +17,9 @@ export interface ManifestEntityBulkAction { +export interface ManifestEntityBulkActionDefaultKind< + MetaKindType extends MetaEntityBulkActionDefaultKind = MetaEntityBulkActionDefaultKind, +> extends ManifestEntityBulkAction { type: 'entityBulkAction'; kind: 'default'; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts new file mode 100644 index 000000000000..9cdfc0882255 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts @@ -0,0 +1,24 @@ +import { UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST } from '@umbraco-cms/backoffice/entity-bulk-action'; +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const UMB_ENTITY_BULK_ACTION_TRASH_KIND_MANIFEST: UmbExtensionManifestKind = { + type: 'kind', + alias: 'Umb.Kind.EntityBulkAction.Trash', + matchKind: 'trash', + matchType: 'entityBulkAction', + manifest: { + ...UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST.manifest, + type: 'entityBulkAction', + kind: 'trash', + api: () => import('./bulk-trash.action.js'), + weight: 1150, + meta: { + icon: 'icon-trash', + label: '#actions_trash', + itemRepositoryAlias: '', + recycleBinRepositoryAlias: '', + }, + }, +}; + +export const manifest = UMB_ENTITY_BULK_ACTION_TRASH_KIND_MANIFEST; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts new file mode 100644 index 000000000000..e226b1cd2260 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts @@ -0,0 +1,84 @@ +import type { UmbRecycleBinRepository } from '../../recycle-bin-repository.interface.js'; +import { UmbEntityTrashedEvent } from '../../entity-action/trash/index.js'; +import type { MetaEntityBulkActionTrashKind } from './types.js'; +import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; +import { umbConfirmModal } from '@umbraco-cms/backoffice/modal'; +import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; +import { UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/entity-action'; +import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; +import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; + +export class UmbTrashEntityBulkAction< + MetaKindType extends MetaEntityBulkActionTrashKind = MetaEntityBulkActionTrashKind, +> extends UmbEntityBulkActionBase { + override async execute() { + if (this.selection?.length === 0) { + throw new Error('No items selected.'); + } + + await this._confirmTrash(); + await this.#requestBulkTrash(this.selection); + await this.#notify(); + } + + protected async _confirmTrash() { + const headline = '#actions_trash'; + + // TODO: handle items with variants + await umbConfirmModal(this._host, { + headline, + content: `Are you sure you want to move ${this.selection.length} ${this.selection.length === 1 ? 'item' : 'items'} to the recycle bin?`, + color: 'danger', + confirmLabel: '#actions_trash', + }); + } + + async #requestBulkTrash(uniques: Array) { + const recycleBinRepository = await createExtensionApiByAlias( + this, + this.args.meta.recycleBinRepositoryAlias, + ); + + const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT); + + let count = 0; + + for (const unique of uniques) { + const { error } = await recycleBinRepository.requestTrash({ unique }); + + if (error) { + const notification = { data: { message: error.message } }; + notificationContext?.peek('danger', notification); + } else { + count++; + } + } + + if (count > 0) { + const notification = { data: { message: `Trashed ${count} ${count === 1 ? 'item' : 'items'}` } }; + notificationContext?.peek('positive', notification); + } + + return {}; + } + + async #notify() { + const actionEventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); + + const event = new UmbRequestReloadStructureForEntityEvent({ + unique: this.args.unique, + entityType: this.args.entityType, + }); + + actionEventContext.dispatchEvent(event); + + const trashedEvent = new UmbEntityTrashedEvent({ + unique: this.args.unique, + entityType: this.args.entityType, + }); + + actionEventContext.dispatchEvent(trashedEvent); + } +} + +export { UmbTrashEntityBulkAction as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/constants.ts new file mode 100644 index 000000000000..062d0418eac7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/constants.ts @@ -0,0 +1 @@ +export { UMB_ENTITY_BULK_ACTION_TRASH_KIND_MANIFEST as UMB_ENTITY_ACTION_TRASH_KIND_MANIFEST } from './bulk-trash.action.kind.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/index.ts new file mode 100644 index 000000000000..befc46802424 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/index.ts @@ -0,0 +1,3 @@ +export * from './bulk-trash.action.js'; +export * from './bulk-trash.event.js'; +export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/manifests.ts new file mode 100644 index 000000000000..066b290bebb2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/manifests.ts @@ -0,0 +1,4 @@ +import { manifest as trashKindManifest } from './bulk-trash.action.kind.js'; +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [trashKindManifest]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/types.ts new file mode 100644 index 000000000000..8a8492c24ce1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/types.ts @@ -0,0 +1,20 @@ +import type { + ManifestEntityBulkAction, + MetaEntityBulkActionDefaultKind, +} from '@umbraco-cms/backoffice/extension-registry'; + +export interface ManifestEntityBulkActionTrashKind extends ManifestEntityBulkAction { + type: 'entityBulkAction'; + kind: 'trash'; +} + +export interface MetaEntityBulkActionTrashKind extends MetaEntityBulkActionDefaultKind { + recycleBinRepositoryAlias: string; + itemRepositoryAlias: string; +} + +declare global { + interface UmbExtensionManifestMap { + umbManifestEntityBulkActionTrashKind: ManifestEntityBulkActionTrashKind; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/manifests.ts index f5fc0ea7da8c..b9eabac4a733 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/manifests.ts @@ -2,6 +2,7 @@ import { manifests as conditionManifests } from './conditions/manifests.js'; import { manifests as emptyRecycleBinEntityActionManifests } from './entity-action/empty-recycle-bin/manifests.js'; import { manifests as restoreFromRecycleBinEntityActionManifests } from './entity-action/restore-from-recycle-bin/manifests.js'; import { manifests as trashEntityActionManifests } from './entity-action/trash/manifests.js'; +import { manifests as trashEntityBulkActionManifests } from './entity-bulk-action/bulk-trash/manifests.js'; import { manifests as treeManifests } from './tree/manifests.js'; import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; @@ -11,5 +12,6 @@ export const manifests: Array = ...emptyRecycleBinEntityActionManifests, ...restoreFromRecycleBinEntityActionManifests, ...trashEntityActionManifests, + ...trashEntityBulkActionManifests, ...treeManifests, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts index d1ff3f6058e5..f7d76331a2bb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts @@ -1,7 +1,7 @@ import { UMB_DOCUMENT_COLLECTION_ALIAS } from '../../collection/constants.js'; +import { UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS, UMB_DOCUMENT_RECYCLE_BIN_REPOSITORY_ALIAS } from '../../constants.js'; import { UMB_DOCUMENT_ENTITY_TYPE } from '../../entity.js'; import { UMB_USER_PERMISSION_DOCUMENT_DELETE } from '../../user-permissions/constants.js'; -import { UMB_BULK_TRASH_DOCUMENT_REPOSITORY_ALIAS } from './repository/constants.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection'; @@ -14,7 +14,8 @@ export const manifests: Array = [ weight: 10, forEntityTypes: [UMB_DOCUMENT_ENTITY_TYPE], meta: { - bulkTrashRepositoryAlias: UMB_BULK_TRASH_DOCUMENT_REPOSITORY_ALIAS, + itemRepositoryAlias: UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS, + recycleBinRepositoryAlias: UMB_DOCUMENT_RECYCLE_BIN_REPOSITORY_ALIAS, }, conditions: [ { From c17d1983f2884a323595fbd099d8df186c6a6325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 18 Feb 2025 20:22:01 +0100 Subject: [PATCH 114/145] add todo comment --- .../paste/clipboard-paste-translator-value-resolver.ts | 1 + .../core/repository/data-mapper/mapping/data-mapping-resolver.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/clipboard/property/value-translator/paste/clipboard-paste-translator-value-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/clipboard/property/value-translator/paste/clipboard-paste-translator-value-resolver.ts index 5797083f148e..9f5bcb9e288a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/clipboard/property/value-translator/paste/clipboard-paste-translator-value-resolver.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/clipboard/property/value-translator/paste/clipboard-paste-translator-value-resolver.ts @@ -79,6 +79,7 @@ export class UmbClipboardPastePropertyValueTranslatorValueResolver< } // Pick the manifest with the highest priority + // TODO: This should have been handled in the extension registry, but until then we do it here: [NL] return supportedManifests.sort((a: ManifestBase, b: ManifestBase): number => (b.weight || 0) - (a.weight || 0))[0]; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping-resolver.ts index 29a415e68ac0..bd5523216fff 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping-resolver.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping-resolver.ts @@ -50,6 +50,7 @@ export class UmbDataMappingResolver extends UmbControllerBase { } // Pick the manifest with the highest priority + // TODO: This should have been handled in the extension registry, but until then we do it here: [NL] return supportedManifests.sort((a: ManifestBase, b: ManifestBase): number => (b.weight || 0) - (a.weight || 0))[0]; } From 6dcc89798683c35de52914a302e38e0ee8957ba9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 18 Feb 2025 20:53:59 +0100 Subject: [PATCH 115/145] implement path pattern for media item --- .../documents/item/document-item-ref.element.ts | 2 +- .../media/media/item/media-item-ref.element.ts | 15 ++++----------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index 96ea52dc40ce..9bb5c90ba8c3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -72,7 +72,7 @@ export class UmbDocumentItemRefElement extends UmbLitElement { } #getHref() { - if (!this._unique) return undefined; + if (!this._unique) return; const path = UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN.generateLocal({ unique: this._unique }); return `${this._editPath}/${path}`; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts index 2b7aade2c369..6b3d2f04dc60 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts @@ -7,6 +7,7 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UMB_SECTION_USER_PERMISSION_CONDITION_ALIAS } from '@umbraco-cms/backoffice/section'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; +import { UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN } from '../paths.js'; @customElement('umb-media-item-ref') export class UmbMediaItemRefElement extends UmbLitElement { @@ -17,16 +18,7 @@ export class UmbMediaItemRefElement extends UmbLitElement { return this.#item; } public set item(value: UmbMediaItemModel | undefined) { - const oldValue = this.#item; this.#item = value; - - if (!this.#item) { - this.#modalRoute?.destroy(); - return; - } - if (oldValue?.unique === this.#item.unique) { - return; - } } @property({ type: Boolean }) @@ -67,8 +59,9 @@ export class UmbMediaItemRefElement extends UmbLitElement { } #getHref(item: UmbMediaItemModel) { - if (!this._editPath) return; - return `${this._editPath}/edit/${item.unique}`; + if (!this._editPath) return undefined; + const path = UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN.generateLocal({ unique: item.unique }); + return `${this._editPath}/${path}`; } override render() { From 8dd829384d124fb40ab7dfa0bd26497a7c26e0dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 18 Feb 2025 20:54:07 +0100 Subject: [PATCH 116/145] clean up --- .../src/packages/media/media/item/media-item-ref.element.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts index 6b3d2f04dc60..76fd80e3d30c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts @@ -33,8 +33,6 @@ export class UmbMediaItemRefElement extends UmbLitElement { @state() _userHasSectionAccess = false; - #modalRoute?: any; - constructor() { super(); From 608b1038c83c73230f9865fc985b8692ad1e6270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 18 Feb 2025 20:54:18 +0100 Subject: [PATCH 117/145] more clean up --- .../src/packages/media/media/item/media-item-ref.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts index 76fd80e3d30c..a556dfca8f6f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts @@ -47,7 +47,7 @@ export class UmbMediaItemRefElement extends UmbLitElement { }, ]); - this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) .onSetup(() => { return { data: { entityType: UMB_MEDIA_ENTITY_TYPE, preset: {} } }; }) From 3e067495c10cfe7c56c52934ab258dfa408d00b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 18 Feb 2025 20:54:35 +0100 Subject: [PATCH 118/145] sort imports --- .../src/packages/media/media/item/media-item-ref.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts index a556dfca8f6f..94861d2b6779 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts @@ -1,13 +1,13 @@ import type { UmbMediaItemModel } from '../repository/types.js'; import { UMB_MEDIA_SECTION_ALIAS } from '../../media-section/constants.js'; import { UMB_MEDIA_ENTITY_TYPE } from '../entity.js'; +import { UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN } from '../paths.js'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; import { customElement, html, ifDefined, nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UMB_SECTION_USER_PERMISSION_CONDITION_ALIAS } from '@umbraco-cms/backoffice/section'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; -import { UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN } from '../paths.js'; @customElement('umb-media-item-ref') export class UmbMediaItemRefElement extends UmbLitElement { From a92ea32d8a228ca4b804153d2bc8b9c64e2d5826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 18 Feb 2025 20:57:55 +0100 Subject: [PATCH 119/145] member edit path pattern --- .../src/packages/media/media/item/media-item-ref.element.ts | 2 +- .../packages/members/member/item/member-item-ref.element.ts | 4 +++- .../src/packages/members/member/paths.ts | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts index 94861d2b6779..ae9dd01bbb96 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts @@ -57,7 +57,7 @@ export class UmbMediaItemRefElement extends UmbLitElement { } #getHref(item: UmbMediaItemModel) { - if (!this._editPath) return undefined; + if (!this._editPath) return; const path = UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN.generateLocal({ unique: item.unique }); return `${this._editPath}/${path}`; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts index 5ed664278a0e..09010f05b07c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts @@ -7,6 +7,7 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UMB_SECTION_USER_PERMISSION_CONDITION_ALIAS } from '@umbraco-cms/backoffice/section'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; +import { UMB_EDIT_MEMBER_WORKSPACE_PATH_PATTERN } from '../paths.js'; @customElement('umb-member-item-ref') export class UmbMemberItemRefElement extends UmbLitElement { @@ -68,7 +69,8 @@ export class UmbMemberItemRefElement extends UmbLitElement { #getHref(item: UmbMemberItemModel) { if (!this._editPath) return; - return `${this._editPath}/edit/${item.unique}`; + const path = UMB_EDIT_MEMBER_WORKSPACE_PATH_PATTERN.generateLocal({ unique: item.unique }); + return `${this._editPath}/${path}`; } override render() { diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/paths.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/paths.ts index 65d1ab878705..5d5f51d8f8c7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/paths.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/paths.ts @@ -16,3 +16,5 @@ export const UMB_MEMBER_ROOT_WORKSPACE_PATH = UMB_WORKSPACE_PATH_PATTERN.generat export const UMB_CREATE_MEMBER_WORKSPACE_PATH_PATTERN = new UmbPathPattern<{ memberTypeUnique: string; }>('create/:memberTypeUnique', UMB_MEMBER_WORKSPACE_PATH); + +export const UMB_EDIT_MEMBER_WORKSPACE_PATH_PATTERN = new UmbPathPattern<{ unique: string }>('edit/:unique'); From 9b1534ff8647deebc3af3116179962785dbeb522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Tue, 18 Feb 2025 21:07:34 +0100 Subject: [PATCH 120/145] clean up --- .../item/document-item-ref.element.ts | 10 +------ .../media/item/media-item-ref.element.ts | 1 + .../member/item/member-item-ref.element.ts | 15 ++--------- .../user/user/item/user-item-ref.element.ts | 27 +++++-------------- .../src/packages/user/user/paths.ts | 3 +++ 5 files changed, 14 insertions(+), 42 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index 9bb5c90ba8c3..4647041b7241 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -44,19 +44,11 @@ export class UmbDocumentItemRefElement extends UmbLitElement { @state() _editPath = ''; - @state() - _defaultCulture?: string; - - @state() - _appCulture?: string; - - @state() - _propertyDataSetCulture?: UmbVariantId; - constructor() { super(); new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addUniquePaths(['unique']) .onSetup(() => { return { data: { entityType: UMB_DOCUMENT_ENTITY_TYPE, preset: {} } }; }) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts index ae9dd01bbb96..d948326a53c8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/item/media-item-ref.element.ts @@ -48,6 +48,7 @@ export class UmbMediaItemRefElement extends UmbLitElement { ]); new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + .addUniquePaths(['unique']) .onSetup(() => { return { data: { entityType: UMB_MEDIA_ENTITY_TYPE, preset: {} } }; }) diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts index 09010f05b07c..a097ea138e0e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/member-item-ref.element.ts @@ -1,5 +1,6 @@ import { UMB_MEMBER_ENTITY_TYPE } from '../entity.js'; import { UMB_MEMBER_MANAGEMENT_SECTION_ALIAS } from '../../section/constants.js'; +import { UMB_EDIT_MEMBER_WORKSPACE_PATH_PATTERN } from '../paths.js'; import type { UmbMemberItemModel } from './repository/types.js'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; import { customElement, html, ifDefined, nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; @@ -7,7 +8,6 @@ import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UMB_SECTION_USER_PERMISSION_CONDITION_ALIAS } from '@umbraco-cms/backoffice/section'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; -import { UMB_EDIT_MEMBER_WORKSPACE_PATH_PATTERN } from '../paths.js'; @customElement('umb-member-item-ref') export class UmbMemberItemRefElement extends UmbLitElement { @@ -18,16 +18,7 @@ export class UmbMemberItemRefElement extends UmbLitElement { return this.#item; } public set item(value: UmbMemberItemModel | undefined) { - const oldValue = this.#item; this.#item = value; - - if (!this.#item) { - this.#modalRoute?.destroy(); - return; - } - if (oldValue?.unique === this.#item.unique) { - return; - } } @property({ type: Boolean }) @@ -42,8 +33,6 @@ export class UmbMemberItemRefElement extends UmbLitElement { @state() _userHasSectionAccess = false; - #modalRoute?: any; - constructor() { super(); @@ -58,7 +47,7 @@ export class UmbMemberItemRefElement extends UmbLitElement { }, ]); - this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) + new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) .onSetup(() => { return { data: { entityType: UMB_MEMBER_ENTITY_TYPE, preset: {} } }; }) diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts index f910931ba47c..f61cc1bec984 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/item/user-item-ref.element.ts @@ -1,7 +1,8 @@ import { UMB_USER_ENTITY_TYPE } from '../entity.js'; import type { UmbUserItemModel } from '../repository/index.js'; import { UMB_USER_MANAGEMENT_SECTION_ALIAS } from '../../section/constants.js'; -import { css, customElement, html, nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; +import { UMB_EDIT_USER_WORKSPACE_PATH_PATTERN } from '../paths.js'; +import { css, customElement, html, ifDefined, nothing, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UMB_SECTION_USER_PERMISSION_CONDITION_ALIAS } from '@umbraco-cms/backoffice/section'; @@ -17,19 +18,7 @@ export class UmbUserItemRefElement extends UmbLitElement { return this.#item; } public set item(value: UmbUserItemModel | undefined) { - const oldValue = this.#item; this.#item = value; - - if (!this.#item) { - this.#modalRoute?.destroy(); - return; - } - - if (oldValue?.unique === this.#item.unique) { - return; - } - - this.#modalRoute?.setUniquePathValue('unique', this.#item.unique); } @property({ type: Boolean }) @@ -44,8 +33,6 @@ export class UmbUserItemRefElement extends UmbLitElement { @state() _userHasSectionAccess = false; - #modalRoute?: any; - constructor() { super(); @@ -60,9 +47,7 @@ export class UmbUserItemRefElement extends UmbLitElement { }, ]); - this.#modalRoute = new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) - .addAdditionalPath(UMB_USER_ENTITY_TYPE) - .addUniquePaths(['unique']) + new UmbModalRouteRegistrationController(this, UMB_WORKSPACE_MODAL) .onSetup(() => { return { data: { entityType: UMB_USER_ENTITY_TYPE, preset: {} } }; }) @@ -72,7 +57,9 @@ export class UmbUserItemRefElement extends UmbLitElement { } #getHref(item: UmbUserItemModel) { - return `${this._editPath}/edit/${item.unique}`; + if (!this._editPath) return; + const path = UMB_EDIT_USER_WORKSPACE_PATH_PATTERN.generateLocal({ unique: item.unique }); + return `${this._editPath}/${path}`; } override render() { @@ -81,7 +68,7 @@ export class UmbUserItemRefElement extends UmbLitElement { return html` ('edit/:unique'); From 9b070c06592e09801e158eee6d9ff920e5434bf1 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 19 Feb 2025 08:42:12 +0100 Subject: [PATCH 121/145] remove unused variant id --- .../documents/documents/item/document-item-ref.element.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts index 4647041b7241..9bee87cc6a17 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/document-item-ref.element.ts @@ -6,7 +6,6 @@ import { customElement, html, ifDefined, nothing, property, state } from '@umbra import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/router'; import { UMB_WORKSPACE_MODAL } from '@umbraco-cms/backoffice/workspace'; -import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; @customElement('umb-document-item-ref') export class UmbDocumentItemRefElement extends UmbLitElement { From 32c3d17c4880a01071dff197652331d80954d691 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 19 Feb 2025 09:16:21 +0100 Subject: [PATCH 122/145] export extension types --- .../src/packages/core/repository/data-mapper/mapping/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/types.ts index a9cb7efdde94..4dc1a4883ed2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/types.ts @@ -1,4 +1,5 @@ import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; +export type * from './data-mapping.extension.js'; export interface UmbDataMapping extends UmbApi { map: (data: fromModelType) => Promise; From c60a51960d01841462a2d4abff5393a2335ab530 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 19 Feb 2025 11:10:59 +0100 Subject: [PATCH 123/145] wip bulk trash with relation --- .../src/assets/lang/en.ts | 2 + .../packages/core/recycle-bin/constants.ts | 1 + .../bulk-trash/bulk-trash.action.ts | 7 +- .../bulk-trash/constants.ts | 2 +- .../entity-bulk-action/bulk-trash/index.ts | 1 - .../entity-bulk-action/constants.ts | 1 + .../recycle-bin/entity-bulk-action/index.ts | 1 + .../recycle-bin/entity-bulk-action/types.ts | 1 + .../src/packages/core/recycle-bin/index.ts | 3 +- .../recycle-bin-repository-base.ts | 19 ++- .../src/packages/core/recycle-bin/types.ts | 1 + .../entity-bulk-actions/trash/manifests.ts | 9 +- .../packages/relations/relations/constants.ts | 1 + .../bulk-trash-with-relation.action.kind.ts | 15 ++ .../bulk-trash-with-relation.action.ts | 22 +++ .../entity-actions/bulk-trash/constants.ts | 1 + .../entity-actions/bulk-trash/index.ts | 2 + .../entity-actions/bulk-trash/manifests.ts | 6 + .../bulk-trash-with-relation-modal.element.ts | 86 +++++++++++ .../bulk-trash-with-relation-modal.token.ts | 18 +++ .../bulk-trash/modal/constants.ts | 1 + .../bulk-trash/modal/manifests.ts | 8 ++ .../entity-actions/bulk-trash/types.ts | 18 +++ ...m-bulk-action-entity-references.element.ts | 134 ++++++++++++++++++ .../packages/relations/relations/manifests.ts | 2 + 25 files changed, 349 insertions(+), 13 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/types.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/bulk-trash-with-relation.action.kind.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/bulk-trash-with-relation.action.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.token.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/types.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-bulk-action-entity-references.element.ts 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 088d1ea036a8..8d45fca997a3 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts @@ -511,6 +511,8 @@ export default { confirmlogout: 'Are you sure?', confirmSure: 'Are you sure?', confirmtrash: (name: string) => `Are you sure you want to move ${name} to the Recycle Bin?`, + confirmbulktrash: (total: number) => + `Are you sure you want to move ${total} ${total === 1 ? 'item' : 'items'} to the Recycle Bin?`, cut: 'Cut', editDictionary: 'Edit dictionary item', editLanguage: 'Edit language', diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/constants.ts index 27f0cb615081..19138819b598 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/constants.ts @@ -2,3 +2,4 @@ export * from './conditions/is-not-trashed/constants.js'; export * from './conditions/is-trashed/constants.js'; export * from './contexts/is-trashed/constants.js'; export * from './entity-action/constants.js'; +export * from './entity-bulk-action/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts index e226b1cd2260..3b69c80950e4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts @@ -7,10 +7,13 @@ import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; import { UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/entity-action'; import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; +import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api'; export class UmbTrashEntityBulkAction< MetaKindType extends MetaEntityBulkActionTrashKind = MetaEntityBulkActionTrashKind, > extends UmbEntityBulkActionBase { + #localize = new UmbLocalizationController(this); + override async execute() { if (this.selection?.length === 0) { throw new Error('No items selected.'); @@ -23,11 +26,11 @@ export class UmbTrashEntityBulkAction< protected async _confirmTrash() { const headline = '#actions_trash'; + const message = '#defaultdialogs_confirmbulktrash'; - // TODO: handle items with variants await umbConfirmModal(this._host, { headline, - content: `Are you sure you want to move ${this.selection.length} ${this.selection.length === 1 ? 'item' : 'items'} to the recycle bin?`, + content: this.#localize.string(message, this.selection.length), color: 'danger', confirmLabel: '#actions_trash', }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/constants.ts index 062d0418eac7..258564816886 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/constants.ts @@ -1 +1 @@ -export { UMB_ENTITY_BULK_ACTION_TRASH_KIND_MANIFEST as UMB_ENTITY_ACTION_TRASH_KIND_MANIFEST } from './bulk-trash.action.kind.js'; +export { UMB_ENTITY_BULK_ACTION_TRASH_KIND_MANIFEST } from './bulk-trash.action.kind.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/index.ts index befc46802424..a281a0235157 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/index.ts @@ -1,3 +1,2 @@ export * from './bulk-trash.action.js'; -export * from './bulk-trash.event.js'; export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/constants.ts new file mode 100644 index 000000000000..e96d7ef38da7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/constants.ts @@ -0,0 +1 @@ +export * from './bulk-trash/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/index.ts new file mode 100644 index 000000000000..b88b7cd9add9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/index.ts @@ -0,0 +1 @@ +export * from './bulk-trash/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/types.ts new file mode 100644 index 000000000000..83d23b4b0c82 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/types.ts @@ -0,0 +1 @@ +export type * from './bulk-trash/types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/index.ts index e27c2c13ac53..83cdb218b85a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/index.ts @@ -1,5 +1,6 @@ -export * from './entity-action/index.js'; export * from './constants.js'; +export * from './entity-action/index.js'; +export * from './entity-bulk-action/index.js'; export type * from './types.js'; export { UmbRecycleBinRepositoryBase } from './recycle-bin-repository-base.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/recycle-bin-repository-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/recycle-bin-repository-base.ts index b7c101717f5b..e246dac49d33 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/recycle-bin-repository-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/recycle-bin-repository-base.ts @@ -8,6 +8,7 @@ import type { UmbRecycleBinRestoreRequestArgs, UmbRecycleBinTrashRequestArgs, } from './types.js'; +import type { UmbNotificationHandler } from '@umbraco-cms/backoffice/notification'; import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; @@ -21,6 +22,9 @@ import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; */ export abstract class UmbRecycleBinRepositoryBase extends UmbRepositoryBase implements UmbRecycleBinRepository { #recycleBinSource: UmbRecycleBinDataSource; + #notificationContext?: typeof UMB_NOTIFICATION_CONTEXT.TYPE; + #requestTrashSuccessNotification?: UmbNotificationHandler; + #requestRestoreSuccessNotification?: UmbNotificationHandler; /** * Creates an instance of UmbRecycleBinRepositoryBase. @@ -31,6 +35,10 @@ export abstract class UmbRecycleBinRepositoryBase extends UmbRepositoryBase impl constructor(host: UmbControllerHost, recycleBinSource: UmbRecycleBinDataSourceConstructor) { super(host); this.#recycleBinSource = new recycleBinSource(this); + + this.consumeContext(UMB_NOTIFICATION_CONTEXT, (context) => { + this.#notificationContext = context; + }); } /** @@ -43,9 +51,9 @@ export abstract class UmbRecycleBinRepositoryBase extends UmbRepositoryBase impl const { error } = await this.#recycleBinSource.trash(args); if (!error) { - const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT); + this.#requestTrashSuccessNotification?.close(); const notification = { data: { message: `Trashed` } }; - notificationContext.peek('positive', notification); + this.#requestTrashSuccessNotification = this.#notificationContext?.peek('positive', notification); } return { error }; @@ -61,9 +69,9 @@ export abstract class UmbRecycleBinRepositoryBase extends UmbRepositoryBase impl const { error } = await this.#recycleBinSource.restore(args); if (!error) { - const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT); + this.#requestRestoreSuccessNotification?.close(); const notification = { data: { message: `Restored` } }; - notificationContext.peek('positive', notification); + this.#requestRestoreSuccessNotification = this.#notificationContext?.peek('positive', notification); } return { error }; @@ -78,9 +86,8 @@ export abstract class UmbRecycleBinRepositoryBase extends UmbRepositoryBase impl const { error } = await this.#recycleBinSource.empty(); if (!error) { - const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT); const notification = { data: { message: `Recycle Bin Emptied` } }; - notificationContext.peek('positive', notification); + this.#notificationContext?.peek('positive', notification); } return this.#recycleBinSource.empty(); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/types.ts index 587bcc35d1b7..52db4d7f185a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/types.ts @@ -1,5 +1,6 @@ export type * from './conditions/types.js'; export type * from './entity-action/types.js'; +export type * from './entity-bulk-action/types.js'; export type { UmbRecycleBinDataSource } from './recycle-bin-data-source.interface.js'; export type { UmbRecycleBinRepository } from './recycle-bin-repository.interface.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts index f7d76331a2bb..fc8037d05a05 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts @@ -1,5 +1,9 @@ import { UMB_DOCUMENT_COLLECTION_ALIAS } from '../../collection/constants.js'; -import { UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS, UMB_DOCUMENT_RECYCLE_BIN_REPOSITORY_ALIAS } from '../../constants.js'; +import { + UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS, + UMB_DOCUMENT_RECYCLE_BIN_REPOSITORY_ALIAS, + UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS, +} from '../../constants.js'; import { UMB_DOCUMENT_ENTITY_TYPE } from '../../entity.js'; import { UMB_USER_PERMISSION_DOCUMENT_DELETE } from '../../user-permissions/constants.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; @@ -8,7 +12,7 @@ import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collecti export const manifests: Array = [ { type: 'entityBulkAction', - kind: 'trash', + kind: 'trashWithRelation', alias: 'Umb.EntityBulkAction.Document.Trash', name: 'Trash Document Entity Bulk Action', weight: 10, @@ -16,6 +20,7 @@ export const manifests: Array = [ meta: { itemRepositoryAlias: UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS, recycleBinRepositoryAlias: UMB_DOCUMENT_RECYCLE_BIN_REPOSITORY_ALIAS, + referenceRepositoryAlias: UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS, }, conditions: [ { diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/constants.ts index 1ad52da7ec8a..d153a3f3e17d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/constants.ts @@ -2,3 +2,4 @@ export { UMB_RELATION_ENTITY_TYPE } from './entity.js'; export * from './collection/constants.js'; export * from './entity-actions/delete/constants.js'; export * from './entity-actions/trash/constants.js'; +export * from './entity-actions/bulk-trash/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/bulk-trash-with-relation.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/bulk-trash-with-relation.action.kind.ts new file mode 100644 index 000000000000..85d2deb8c8af --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/bulk-trash-with-relation.action.kind.ts @@ -0,0 +1,15 @@ +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; +import { UMB_ENTITY_BULK_ACTION_TRASH_KIND_MANIFEST } from '@umbraco-cms/backoffice/recycle-bin'; + +export const manifest: UmbExtensionManifestKind = { + type: 'kind', + alias: 'Umb.Kind.EntityBulkAction.TrashWithRelation', + matchKind: 'trashWithRelation', + matchType: 'entityBulkAction', + manifest: { + ...UMB_ENTITY_BULK_ACTION_TRASH_KIND_MANIFEST.manifest, + type: 'entityBulkAction', + kind: 'trashWithRelation', + api: () => import('./bulk-trash-with-relation.action.js'), + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/bulk-trash-with-relation.action.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/bulk-trash-with-relation.action.ts new file mode 100644 index 000000000000..40383894fd3f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/bulk-trash-with-relation.action.ts @@ -0,0 +1,22 @@ +import type { MetaEntityBulkActionTrashWithRelationKind } from './types.js'; +import { UMB_BULK_TRASH_WITH_RELATION_CONFIRM_MODAL } from './modal/constants.js'; +import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; +import { UmbTrashEntityBulkAction } from '@umbraco-cms/backoffice/recycle-bin'; + +export class UmbBulkTrashWithRelationEntityAction extends UmbTrashEntityBulkAction { + override async _confirmTrash() { + const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); + + const modal = modalManager.open(this, UMB_BULK_TRASH_WITH_RELATION_CONFIRM_MODAL, { + data: { + uniques: this.selection, + itemRepositoryAlias: this.args.meta.itemRepositoryAlias, + referenceRepositoryAlias: this.args.meta.referenceRepositoryAlias, + }, + }); + + await modal.onSubmit(); + } +} + +export { UmbBulkTrashWithRelationEntityAction as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/constants.ts new file mode 100644 index 000000000000..26f4f0dd5f39 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/constants.ts @@ -0,0 +1 @@ +export * from './modal/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/index.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/index.ts new file mode 100644 index 000000000000..5f67a28b7978 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/index.ts @@ -0,0 +1,2 @@ +export * from './bulk-trash-with-relation.action.js'; +export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/manifests.ts new file mode 100644 index 000000000000..d51d0e198106 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/manifests.ts @@ -0,0 +1,6 @@ +import { manifest as trashKindManifest } from './bulk-trash-with-relation.action.kind.js'; +import { manifests as modalManifests } from './modal/manifests.js'; + +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [trashKindManifest, ...modalManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.element.ts new file mode 100644 index 000000000000..108ab3520fcd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.element.ts @@ -0,0 +1,86 @@ +import type { + UmbBulkTrashWithRelationConfirmModalData, + UmbBulkTrashWithRelationConfirmModalValue, +} from './bulk-trash-with-relation-modal.token.js'; +import { + html, + customElement, + css, + state, + type PropertyValues, + nothing, + unsafeHTML, +} from '@umbraco-cms/backoffice/external/lit'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; +import { umbFocus } from '@umbraco-cms/backoffice/lit-element'; + +// import of local component +import '../../local-components/confirm-bulk-action-entity-references.element.js'; + +@customElement('umb-bulk-trash-with-relation-confirm-modal') +export class UmbBulkTrashWithRelationConfirmModalElement extends UmbModalBaseElement< + UmbBulkTrashWithRelationConfirmModalData, + UmbBulkTrashWithRelationConfirmModalValue +> { + @state() + _referencesConfig?: any; + + protected override firstUpdated(_changedProperties: PropertyValues): void { + super.firstUpdated(_changedProperties); + this.#initData(); + } + + async #initData() { + if (!this.data) return; + + this._referencesConfig = { + uniques: this.data.uniques, + itemRepositoryAlias: this.data.itemRepositoryAlias, + referenceRepositoryAlias: this.data.referenceRepositoryAlias, + }; + } + + override render() { + const headline = this.localize.string('#actions_trash'); + const message = '#defaultdialogs_confirmbulktrash'; + + return html` + +

${unsafeHTML(this.localize.string(message, this.data?.uniques.length))}

+ ${this._referencesConfig + ? html`` + : nothing} + + + + +
+ `; + } + + static override styles = [ + UmbTextStyles, + css` + uui-dialog-layout { + max-inline-size: 60ch; + } + `, + ]; +} + +export { UmbBulkTrashWithRelationConfirmModalElement as element }; + +declare global { + interface HTMLElementTagNameMap { + 'umb-trash-with-relation-confirm-modal': UmbBulkTrashWithRelationConfirmModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.token.ts new file mode 100644 index 000000000000..2726358d2100 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.token.ts @@ -0,0 +1,18 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbBulkTrashWithRelationConfirmModalData { + uniques: Array; + itemRepositoryAlias: string; + referenceRepositoryAlias: string; +} + +export type UmbBulkTrashWithRelationConfirmModalValue = undefined; + +export const UMB_BULK_TRASH_WITH_RELATION_CONFIRM_MODAL = new UmbModalToken< + UmbBulkTrashWithRelationConfirmModalData, + UmbBulkTrashWithRelationConfirmModalValue +>('Umb.Modal.BulkTrashWithRelation', { + modal: { + type: 'dialog', + }, +}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/constants.ts new file mode 100644 index 000000000000..6d6d2883f90e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/constants.ts @@ -0,0 +1 @@ +export * from './bulk-trash-with-relation-modal.token.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/manifests.ts new file mode 100644 index 000000000000..8252cb163dcf --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/manifests.ts @@ -0,0 +1,8 @@ +export const manifests: Array = [ + { + type: 'modal', + alias: 'Umb.Modal.BulkTrashWithRelation', + name: 'Bulk Trash With Relation Modal', + element: () => import('./bulk-trash-with-relation-modal.element.js'), + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/types.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/types.ts new file mode 100644 index 000000000000..e173e1bf97c7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/types.ts @@ -0,0 +1,18 @@ +import type { ManifestEntityBulkAction } from '@umbraco-cms/backoffice/extension-registry'; +import type { MetaEntityBulkActionTrashKind } from '@umbraco-cms/backoffice/recycle-bin'; + +export interface ManifestEntityBulkActionTrashWithRelationKind + extends ManifestEntityBulkAction { + type: 'entityBulkAction'; + kind: 'trashWithRelation'; +} + +export interface MetaEntityBulkActionTrashWithRelationKind extends MetaEntityBulkActionTrashKind { + referenceRepositoryAlias: string; +} + +declare global { + interface UmbExtensionManifestMap { + umbManifestEntityBulkActionTrashWithRelationKind: ManifestEntityBulkActionTrashWithRelationKind; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-bulk-action-entity-references.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-bulk-action-entity-references.element.ts new file mode 100644 index 000000000000..4d07370a05a9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-bulk-action-entity-references.element.ts @@ -0,0 +1,134 @@ +import type { UmbEntityReferenceRepository } from '../../reference/types.js'; +import { + html, + customElement, + css, + state, + nothing, + type PropertyValues, + property, +} from '@umbraco-cms/backoffice/external/lit'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; +import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; + +@customElement('umb-confirm-bulk-action-modal-entity-references') +export class UmbConfirmBulkActionModalEntityReferencesElement extends UmbLitElement { + @property({ type: Object, attribute: false }) + config?: { + uniques: Array; + itemRepositoryAlias: string; + referenceRepositoryAlias: string; + }; + + @state() + _items: Array = []; + + @state() + _totalItems: number = 0; + + #itemRepository?: UmbItemRepository; + #referenceRepository?: UmbEntityReferenceRepository; + + #limitItems = 5; + + protected override firstUpdated(_changedProperties: PropertyValues): void { + super.firstUpdated(_changedProperties); + this.#initData(); + } + + async #initData() { + if (!this.config) { + this.#itemRepository?.destroy(); + this.#referenceRepository?.destroy(); + return; + } + + if (!this.config?.referenceRepositoryAlias) { + throw new Error('Missing referenceRepositoryAlias in config.'); + } + + this.#referenceRepository = await createExtensionApiByAlias( + this, + this.config?.referenceRepositoryAlias, + ); + + if (!this.config?.itemRepositoryAlias) { + throw new Error('Missing itemRepositoryAlias in config.'); + } + + this.#itemRepository = await createExtensionApiByAlias>( + this, + this.config.itemRepositoryAlias, + ); + + this.#loadAreReferenced(); + } + + async #loadAreReferenced() { + if (!this.#referenceRepository) { + throw new Error('Failed to create reference repository.'); + } + + if (!this.#itemRepository) { + throw new Error('Failed to create item repository.'); + } + + if (!this.config?.uniques) { + throw new Error('Missing uniques in config.'); + } + + const { data } = await this.#referenceRepository.requestAreReferenced(this.config.uniques, 0, this.#limitItems); + + if (data) { + this._totalItems = data.total; + const uniques = data.items.map((item) => item.unique).filter((unique) => unique) as Array; + const { data: items } = await this.#itemRepository.requestItems(uniques); + this._items = items ?? []; + } + } + + override render() { + if (this._totalItems === 0) return nothing; + + return html` +
The following items are used by other content.
+ + ${this._items.map( + (item) => + html` `, + )} + + ${this._totalItems > this.#limitItems + ? html`${this.localize.term('references_labelMoreReferences', this._totalItems - this.#limitItems)}` + : nothing} + `; + } + + static override styles = [ + UmbTextStyles, + css` + #reference-headline { + margin-bottom: var(--uui-size-3); + } + + uui-ref-list { + margin-bottom: var(--uui-size-2); + } + `, + ]; +} + +export { UmbConfirmBulkActionModalEntityReferencesElement as element }; + +declare global { + interface HTMLElementTagNameMap { + 'umb-confirm-bulk-action-modal-entity-references': UmbConfirmBulkActionModalEntityReferencesElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts index 574ed691cfbd..0f882bc45eb9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts @@ -1,9 +1,11 @@ +import { manifests as bulkTrashManifests } from './entity-actions/bulk-trash/manifests.js'; import { manifests as collectionManifests } from './collection/manifests.js'; import { manifests as deleteManifests } from './entity-actions/delete/manifests.js'; import { manifests as trashManifests } from './entity-actions/trash/manifests.js'; import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; export const manifests: Array = [ + ...bulkTrashManifests, ...collectionManifests, ...deleteManifests, ...trashManifests, From 474eb5133d075de13f84495ee5a7f2c2077c7c46 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 19 Feb 2025 12:47:03 +0100 Subject: [PATCH 124/145] debounce incoming events --- .../tree/tree-item/recycle-bin-tree-item.context.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/tree/tree-item/recycle-bin-tree-item.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/tree/tree-item/recycle-bin-tree-item.context.ts index 50c6a06dfb64..ff1156ed0bbc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/tree/tree-item/recycle-bin-tree-item.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/tree/tree-item/recycle-bin-tree-item.context.ts @@ -4,6 +4,7 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbActionEventContext } from '@umbraco-cms/backoffice/action'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; import { UmbEntityTrashedEvent } from '@umbraco-cms/backoffice/recycle-bin'; +import { debounce } from '@umbraco-cms/backoffice/utils'; export class UmbRecycleBinTreeItemContext< RecycleBinTreeItemModelType extends UmbTreeItemModel, @@ -25,6 +26,8 @@ export class UmbRecycleBinTreeItemContext< }); } + #debounceLoadChildren = debounce(() => this.loadChildren(), 100); + #onEntityTrashed = (event: UmbEntityTrashedEvent) => { const entityType = event.getEntityType(); if (!entityType) throw new Error('Entity type is required'); @@ -36,7 +39,7 @@ export class UmbRecycleBinTreeItemContext< } if (supportedEntityTypes.includes(entityType)) { - this.loadChildren(); + this.#debounceLoadChildren(); } }; From 4332a37c2d4b67aa8f00ac95886f24dd4fccf326 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 19 Feb 2025 12:49:41 +0100 Subject: [PATCH 125/145] look up items + notify --- .../bulk-trash/bulk-trash.action.ts | 78 +++++++++++++------ 1 file changed, 56 insertions(+), 22 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts index 3b69c80950e4..77bd9c7ae163 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts @@ -4,38 +4,56 @@ import type { MetaEntityBulkActionTrashKind } from './types.js'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; import { umbConfirmModal } from '@umbraco-cms/backoffice/modal'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; -import { UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/entity-action'; +import { + UmbRequestReloadChildrenOfEntityEvent, + UmbRequestReloadStructureForEntityEvent, +} from '@umbraco-cms/backoffice/entity-action'; import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api'; +import { UMB_ENTITY_CONTEXT } from '@umbraco-cms/backoffice/entity'; +import type { UmbItemRepository } from '@umbraco-cms/backoffice/repository'; export class UmbTrashEntityBulkAction< MetaKindType extends MetaEntityBulkActionTrashKind = MetaEntityBulkActionTrashKind, > extends UmbEntityBulkActionBase { #localize = new UmbLocalizationController(this); + _items: Array = []; override async execute() { if (this.selection?.length === 0) { throw new Error('No items selected.'); } - await this._confirmTrash(); + // TODO: Move item look up to a future bulk action context + await this.#requestItems(); + await this._confirmTrash(this._items); await this.#requestBulkTrash(this.selection); - await this.#notify(); } - protected async _confirmTrash() { + protected async _confirmTrash(items: Array) { const headline = '#actions_trash'; const message = '#defaultdialogs_confirmbulktrash'; await umbConfirmModal(this._host, { headline, - content: this.#localize.string(message, this.selection.length), + content: this.#localize.string(message, items.length), color: 'danger', confirmLabel: '#actions_trash', }); } + async #requestItems() { + const itemRepository = await createExtensionApiByAlias>( + this, + this.args.meta.itemRepositoryAlias, + ); + + const { data } = await itemRepository.requestItems(this.selection); + + this._items = data ?? []; + } + async #requestBulkTrash(uniques: Array) { const recycleBinRepository = await createExtensionApiByAlias( this, @@ -44,7 +62,7 @@ export class UmbTrashEntityBulkAction< const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT); - let count = 0; + const succeeded: Array = []; for (const unique of uniques) { const { error } = await recycleBinRepository.requestTrash({ unique }); @@ -53,34 +71,50 @@ export class UmbTrashEntityBulkAction< const notification = { data: { message: error.message } }; notificationContext?.peek('danger', notification); } else { - count++; + succeeded.push(unique); } } - if (count > 0) { - const notification = { data: { message: `Trashed ${count} ${count === 1 ? 'item' : 'items'}` } }; + if (succeeded.length > 0) { + const notification = { + data: { message: `Trashed ${succeeded.length} ${succeeded.length === 1 ? 'item' : 'items'}` }, + }; notificationContext?.peek('positive', notification); } - return {}; + await this.#notify(succeeded); } - async #notify() { - const actionEventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); + async #notify(succeeded: Array) { + const entityContext = await this.getContext(UMB_ENTITY_CONTEXT); + if (!entityContext) throw new Error('Entity Context is not available'); - const event = new UmbRequestReloadStructureForEntityEvent({ - unique: this.args.unique, - entityType: this.args.entityType, - }); + const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); + if (!eventContext) throw new Error('Event Context is not available'); - actionEventContext.dispatchEvent(event); + const entityType = entityContext.getEntityType(); + const unique = entityContext.getUnique(); - const trashedEvent = new UmbEntityTrashedEvent({ - unique: this.args.unique, - entityType: this.args.entityType, - }); + if (entityType && unique !== undefined) { + const args = { entityType, unique }; + + const reloadChildren = new UmbRequestReloadChildrenOfEntityEvent(args); + eventContext.dispatchEvent(reloadChildren); + + const reloadStructure = new UmbRequestReloadStructureForEntityEvent(args); + eventContext.dispatchEvent(reloadStructure); + } - actionEventContext.dispatchEvent(trashedEvent); + const succeededItems = this._items.filter((item) => succeeded.includes(item.unique)); + + succeededItems.forEach((item) => { + const trashedEvent = new UmbEntityTrashedEvent({ + unique: item.unique, + entityType: item.entityType, + }); + + eventContext.dispatchEvent(trashedEvent); + }); } } From 9ab8987dc7009b20fd7a70a9b28e6d099a970f13 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 19 Feb 2025 12:52:18 +0100 Subject: [PATCH 126/145] add todo --- .../entity-bulk-action/bulk-trash/bulk-trash.action.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts index 77bd9c7ae163..4c4e5eeb3d11 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts @@ -35,6 +35,7 @@ export class UmbTrashEntityBulkAction< const headline = '#actions_trash'; const message = '#defaultdialogs_confirmbulktrash'; + // TODO: consider showing more details about the items being trashed await umbConfirmModal(this._host, { headline, content: this.#localize.string(message, items.length), From b0459c07a8201f94bafb44178994d52a16041a97 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 19 Feb 2025 13:01:50 +0100 Subject: [PATCH 127/145] temp solution to make it non breaking --- .../core/entity-bulk-action/common/trash/manifests.ts | 2 +- .../entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/manifests.ts index a7d8f840985d..46ec59d132b6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/manifests.ts @@ -1,4 +1,4 @@ import { manifest as trashKindManifest } from './trash.action.kind.js'; import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; -export const manifests: Array = []; +export const manifests: Array = [trashKindManifest]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts index 9cdfc0882255..d475c5b79a12 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts @@ -4,12 +4,12 @@ import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension export const UMB_ENTITY_BULK_ACTION_TRASH_KIND_MANIFEST: UmbExtensionManifestKind = { type: 'kind', alias: 'Umb.Kind.EntityBulkAction.Trash', - matchKind: 'trash', + matchKind: 'trashV2', matchType: 'entityBulkAction', manifest: { ...UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST.manifest, type: 'entityBulkAction', - kind: 'trash', + kind: 'trashV2', api: () => import('./bulk-trash.action.js'), weight: 1150, meta: { From 91914abffd5dd7775127e8dccd6babc10f67c983 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 19 Feb 2025 15:26:51 +0100 Subject: [PATCH 128/145] add bulk delete --- .../src/assets/lang/en.ts | 6 +- .../entity-action/entity-deleted.event.ts | 10 ++ .../src/packages/core/entity-action/index.ts | 1 + .../bulk-delete/bulk-delete.action.kind.ts | 22 ++++ .../common/bulk-delete/bulk-delete.action.ts | 121 ++++++++++++++++++ .../common/bulk-delete/constants.ts | 1 + .../common/bulk-delete/index.ts | 2 + .../common/bulk-delete/manifests.ts | 4 + .../common/bulk-delete/types.ts | 20 +++ .../common/{index.ts => types.ts} | 1 + .../packages/core/entity-bulk-action/index.ts | 3 - .../core/entity-bulk-action/manifests.ts | 3 + .../packages/core/entity-bulk-action/types.ts | 4 + .../entity-action/trash/trash.action.ts | 2 +- .../bulk-trash/bulk-trash.action.ts | 2 +- .../detail/detail-repository-base.ts | 15 ++- .../bulk-trash-with-relation-modal.element.ts | 2 +- .../trash-with-relation-modal.element.ts | 2 +- .../entity-bulk-actions/manifests.ts | 6 +- 19 files changed, 211 insertions(+), 16 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-deleted.event.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.kind.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/types.ts rename src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/{index.ts => types.ts} (73%) 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 8d45fca997a3..47b5f6c14b5e 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts @@ -510,9 +510,11 @@ export default { confirmremoveusageof: 'Are you sure you want to remove the usage of %0%', confirmlogout: 'Are you sure?', confirmSure: 'Are you sure?', - confirmtrash: (name: string) => `Are you sure you want to move ${name} to the Recycle Bin?`, - confirmbulktrash: (total: number) => + confirmTrash: (name: string) => `Are you sure you want to move ${name} to the Recycle Bin?`, + confirmBulkTrash: (total: number) => `Are you sure you want to move ${total} ${total === 1 ? 'item' : 'items'} to the Recycle Bin?`, + confirmBulkDelete: (total: number) => + `Are you sure you want to delete ${total} ${total === 1 ? 'item' : 'items'}?`, cut: 'Cut', editDictionary: 'Edit dictionary item', editLanguage: 'Edit language', diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-deleted.event.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-deleted.event.ts new file mode 100644 index 000000000000..9e2bfa0548ad --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-deleted.event.ts @@ -0,0 +1,10 @@ +import type { UmbEntityActionEventArgs } from './entity-action.event.js'; +import { UmbEntityActionEvent } from './entity-action.event.js'; + +export class UmbEntityDeletedEvent extends UmbEntityActionEvent { + static readonly TYPE = 'entity-deleted'; + + constructor(args: UmbEntityActionEventArgs) { + super(UmbEntityDeletedEvent.TYPE, args); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/index.ts index 37d12fa9f0da..886f167a4269 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/index.ts @@ -6,6 +6,7 @@ export * from './entity-action-base.js'; export * from './entity-action-list.element.js'; export * from './entity-action.event.js'; export * from './entity-updated.event.js'; +export * from './entity-deleted.event.js'; export type * from './types.js'; export { UmbRequestReloadStructureForEntityEvent } from './request-reload-structure-for-entity.event.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.kind.ts new file mode 100644 index 000000000000..186b1d6ba576 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.kind.ts @@ -0,0 +1,22 @@ +import { UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST } from '@umbraco-cms/backoffice/entity-bulk-action'; +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const UMB_ENTITY_BULK_ACTION_DELETE_KIND_MANIFEST: UmbExtensionManifestKind = { + type: 'kind', + alias: 'Umb.Kind.EntityBulkAction.Delete', + matchKind: 'delete', + matchType: 'entityBulkAction', + manifest: { + ...UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST.manifest, + type: 'entityBulkAction', + kind: 'delete', + api: () => import('./bulk-delete.action.js'), + weight: 1100, + meta: { + icon: 'icon-trash', + label: '#actions_delete', + }, + }, +}; + +export const manifest = UMB_ENTITY_BULK_ACTION_DELETE_KIND_MANIFEST; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.ts new file mode 100644 index 000000000000..a4f4a3b2cc21 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.ts @@ -0,0 +1,121 @@ +import type { MetaEntityBulkActionDeleteKind } from './types.js'; +import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; +import { umbConfirmModal } from '@umbraco-cms/backoffice/modal'; +import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; +import { + UmbEntityDeletedEvent, + UmbRequestReloadChildrenOfEntityEvent, + UmbRequestReloadStructureForEntityEvent, +} from '@umbraco-cms/backoffice/entity-action'; +import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; +import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; +import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api'; +import { UMB_ENTITY_CONTEXT, type UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import type { UmbDetailRepository, UmbItemRepository } from '@umbraco-cms/backoffice/repository'; + +export class UmbDeleteEntityBulkAction< + MetaKindType extends MetaEntityBulkActionDeleteKind = MetaEntityBulkActionDeleteKind, +> extends UmbEntityBulkActionBase { + #localize = new UmbLocalizationController(this); + _items: Array = []; + + override async execute() { + if (this.selection?.length === 0) { + throw new Error('No items selected.'); + } + + // TODO: Move item look up to a future bulk action context + await this.#requestItems(); + await this._confirmDelete(this._items); + await this.#requestBulkDelete(this.selection); + } + + protected async _confirmDelete(items: Array) { + const headline = '#actions_delete'; + const message = '#defaultdialogs_confirmBulkDelete'; + + // TODO: consider showing more details about the items being deleted + await umbConfirmModal(this._host, { + headline, + content: this.#localize.string(message, items.length), + color: 'danger', + confirmLabel: '#actions_delete', + }); + } + + async #requestItems() { + const itemRepository = await createExtensionApiByAlias>( + this, + this.args.meta.itemRepositoryAlias, + ); + + const { data } = await itemRepository.requestItems(this.selection); + + this._items = data ?? []; + } + + async #requestBulkDelete(uniques: Array) { + const detailRepository = await createExtensionApiByAlias>( + this, + this.args.meta.detailRepositoryAlias, + ); + + const notificationContext = await this.getContext(UMB_NOTIFICATION_CONTEXT); + + const succeeded: Array = []; + + for (const unique of uniques) { + const { error } = await detailRepository.delete(unique); + + if (error) { + const notification = { data: { message: error.message } }; + notificationContext?.peek('danger', notification); + } else { + succeeded.push(unique); + } + } + + if (succeeded.length > 0) { + const notification = { + data: { message: `Deleted ${succeeded.length} ${succeeded.length === 1 ? 'item' : 'items'}` }, + }; + notificationContext?.peek('positive', notification); + } + + await this.#notify(succeeded); + } + + async #notify(succeeded: Array) { + const entityContext = await this.getContext(UMB_ENTITY_CONTEXT); + if (!entityContext) throw new Error('Entity Context is not available'); + + const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); + if (!eventContext) throw new Error('Event Context is not available'); + + const entityType = entityContext.getEntityType(); + const unique = entityContext.getUnique(); + + if (entityType && unique !== undefined) { + const args = { entityType, unique }; + + const reloadChildren = new UmbRequestReloadChildrenOfEntityEvent(args); + eventContext.dispatchEvent(reloadChildren); + + const reloadStructure = new UmbRequestReloadStructureForEntityEvent(args); + eventContext.dispatchEvent(reloadStructure); + } + + const succeededItems = this._items.filter((item) => succeeded.includes(item.unique)); + + succeededItems.forEach((item) => { + const deletedEvent = new UmbEntityDeletedEvent({ + unique: item.unique, + entityType: item.entityType, + }); + + eventContext.dispatchEvent(deletedEvent); + }); + } +} + +export { UmbDeleteEntityBulkAction as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/constants.ts new file mode 100644 index 000000000000..796004d94686 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/constants.ts @@ -0,0 +1 @@ +export { UMB_ENTITY_BULK_ACTION_DELETE_KIND_MANIFEST } from './bulk-delete.action.kind.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/index.ts new file mode 100644 index 000000000000..07e2f108e454 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/index.ts @@ -0,0 +1,2 @@ +export * from './bulk-delete.action.js'; +export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/manifests.ts new file mode 100644 index 000000000000..558f12b16c96 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/manifests.ts @@ -0,0 +1,4 @@ +import { manifest as deleteKindManifest } from './bulk-delete.action.kind.js'; +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [deleteKindManifest]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/types.ts new file mode 100644 index 000000000000..17ff0c6f4834 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/types.ts @@ -0,0 +1,20 @@ +import type { + ManifestEntityBulkAction, + MetaEntityBulkActionDefaultKind, +} from '@umbraco-cms/backoffice/extension-registry'; + +export interface ManifestEntityBulkActionDeleteKind extends ManifestEntityBulkAction { + type: 'entityBulkAction'; + kind: 'delete'; +} + +export interface MetaEntityBulkActionDeleteKind extends MetaEntityBulkActionDefaultKind { + detailRepositoryAlias: string; + itemRepositoryAlias: string; +} + +declare global { + interface UmbExtensionManifestMap { + umbManifestEntityBulkActionDeleteKind: ManifestEntityBulkActionDeleteKind; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/types.ts similarity index 73% rename from src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/index.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/types.ts index e3330f3081fa..7dd2feb9d193 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/types.ts @@ -1,3 +1,4 @@ export type * from './duplicate-to/index.js'; export type * from './move-to/index.js'; export type * from './trash/index.js'; +export type * from './bulk-delete/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts index bcc30c388e3f..5e3f63211ef3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts @@ -1,8 +1,5 @@ -export type * from './common/index.js'; export * from './entity-bulk-action-base.js'; export * from './entity-bulk-action.element.js'; -export type * from './entity-bulk-action.interface.js'; -export type * from './entity-bulk-action-element.interface.js'; export type * from './types.js'; export { UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST } from './default/default.action.kind.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/manifests.ts index 57fab22a3d4c..2d3fde2e9296 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/manifests.ts @@ -2,6 +2,8 @@ import { manifests as defaultEntityBulkActionManifests } from './default/manifes import { manifests as duplicateEntityBulkActionManifests } from './common/duplicate-to/manifests.js'; import { manifests as moveToEntityBulkActionManifests } from './common/move-to/manifests.js'; import { manifests as trashEntityBulkActionManifests } from './common/trash/manifests.js'; +import { manifests as deleteEntityBulkActionManifests } from './common/bulk-delete/manifests.js'; + import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; export const manifests: Array = [ @@ -9,4 +11,5 @@ export const manifests: Array = ...duplicateEntityBulkActionManifests, ...moveToEntityBulkActionManifests, ...trashEntityBulkActionManifests, + ...deleteEntityBulkActionManifests, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/types.ts index 49faf0bca553..6e7241553175 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/types.ts @@ -1,5 +1,9 @@ import type { MetaEntityBulkAction } from '../extension-registry/extensions/entity-bulk-action.extension.js'; +export type * from './common/types.js'; +export type * from './entity-bulk-action.interface.js'; +export type * from './entity-bulk-action-element.interface.js'; + export interface UmbEntityBulkActionArgs { entityType: string; meta: MetaArgsType; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts index 69f2fe69b400..bd83e0976d42 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts @@ -41,7 +41,7 @@ export class UmbTrashEntityAction< protected async _confirmTrash(item: any) { const headline = '#actions_trash'; - const message = '#defaultdialogs_confirmtrash'; + const message = '#defaultdialogs_confirmTrash'; // TODO: handle items with variants await umbConfirmModal(this._host, { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts index 4c4e5eeb3d11..384e111ed5eb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.ts @@ -33,7 +33,7 @@ export class UmbTrashEntityBulkAction< protected async _confirmTrash(items: Array) { const headline = '#actions_trash'; - const message = '#defaultdialogs_confirmbulktrash'; + const message = '#defaultdialogs_confirmBulkTrash'; // TODO: consider showing more details about the items being trashed await umbConfirmModal(this._host, { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/detail/detail-repository-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/detail/detail-repository-base.ts index 12a77e5437a8..831cdab778a8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/detail/detail-repository-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/detail/detail-repository-base.ts @@ -3,7 +3,7 @@ import type { UmbRepositoryResponse, UmbRepositoryResponseWithAsObservable } fro import type { UmbDetailDataSource, UmbDetailDataSourceConstructor } from './detail-data-source.interface.js'; import type { UmbDetailRepository } from './detail-repository.interface.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import type { UmbNotificationContext } from '@umbraco-cms/backoffice/notification'; +import type { UmbNotificationContext, UmbNotificationHandler } from '@umbraco-cms/backoffice/notification'; import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; import type { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; import type { UmbDetailStore } from '@umbraco-cms/backoffice/store'; @@ -22,6 +22,9 @@ export abstract class UmbDetailRepositoryBase< #detailStore?: UmbDetailStore; protected detailDataSource: UmbDetailDataSourceType; #notificationContext?: UmbNotificationContext; + #createSuccessNotification?: UmbNotificationHandler; + #updateSuccessNotification?: UmbNotificationHandler; + #deleteSuccessNotification?: UmbNotificationHandler; constructor( host: UmbControllerHost, @@ -94,10 +97,10 @@ export abstract class UmbDetailRepositoryBase< if (createdData) { this.#detailStore?.append(createdData); - + this.#createSuccessNotification?.close(); // TODO: how do we handle generic notifications? Is this the correct place to do it? const notification = { data: { message: `Created` } }; - this.#notificationContext!.peek('positive', notification); + this.#createSuccessNotification = this.#notificationContext!.peek('positive', notification); } return { data: createdData, error }; @@ -120,8 +123,9 @@ export abstract class UmbDetailRepositoryBase< this.#detailStore!.updateItem(model.unique, updatedData); // TODO: how do we handle generic notifications? Is this the correct place to do it? + this.#updateSuccessNotification?.close(); const notification = { data: { message: `Saved` } }; - this.#notificationContext!.peek('positive', notification); + this.#updateSuccessNotification = this.#notificationContext!.peek('positive', notification); } return { data: updatedData, error }; @@ -142,9 +146,10 @@ export abstract class UmbDetailRepositoryBase< if (!error) { this.#detailStore!.removeItem(unique); + this.#deleteSuccessNotification?.close(); // TODO: how do we handle generic notifications? Is this the correct place to do it? const notification = { data: { message: `Deleted` } }; - this.#notificationContext!.peek('positive', notification); + this.#deleteSuccessNotification = this.#notificationContext!.peek('positive', notification); } return { error }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.element.ts index 108ab3520fcd..27f77486f140 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.element.ts @@ -43,7 +43,7 @@ export class UmbBulkTrashWithRelationConfirmModalElement extends UmbModalBaseEle override render() { const headline = this.localize.string('#actions_trash'); - const message = '#defaultdialogs_confirmbulktrash'; + const message = '#defaultdialogs_confirmBulkTrash'; return html` diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts index 35c2032fd679..61f40cf2bcb2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts @@ -61,7 +61,7 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement override render() { const headline = this.localize.string('#actions_trash'); - const content = this.localize.string('#defaultdialogs_confirmtrash', this._name); + const content = this.localize.string('#defaultdialogs_confirmTrash', this._name); return html` diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/entity-bulk-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/entity-bulk-actions/manifests.ts index f39f8550377d..783805774e3b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/entity-bulk-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/entity-bulk-actions/manifests.ts @@ -1,17 +1,19 @@ import { UMB_USER_GROUP_COLLECTION_ALIAS } from '../collection/index.js'; +import { UMB_USER_GROUP_DETAIL_REPOSITORY_ALIAS, UMB_USER_GROUP_ITEM_REPOSITORY_ALIAS } from '../constants.js'; import { UMB_USER_GROUP_ENTITY_TYPE } from '../entity.js'; import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection'; export const manifests: Array = [ { type: 'entityBulkAction', + kind: 'delete', alias: 'Umb.EntityBulkAction.UserGroup.Delete', name: 'Delete User Group Entity Bulk Action', weight: 400, - api: () => import('./delete/delete.action.js'), forEntityTypes: [UMB_USER_GROUP_ENTITY_TYPE], meta: { - label: 'Delete', + itemRepositoryAlias: UMB_USER_GROUP_ITEM_REPOSITORY_ALIAS, + detailRepositoryAlias: UMB_USER_GROUP_DETAIL_REPOSITORY_ALIAS, }, conditions: [ { From 9b0601e792050e917c66b0c7eb6d4cbd71a2ba49 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 19 Feb 2025 17:39:49 +0100 Subject: [PATCH 129/145] better description --- .../reference/repository/document-reference.server.data.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts index 6b3a247d63f4..0dd3a5e97d27 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts @@ -9,7 +9,7 @@ import { UmbManagementApiDataMapper } from '@umbraco-cms/backoffice/repository'; /** * @class UmbDocumentReferenceServerDataSource - * @implements {RepositoryDetailDataSource} + * @implements {UmbEntityReferenceDataSource} */ export class UmbDocumentReferenceServerDataSource extends UmbControllerBase implements UmbEntityReferenceDataSource { #dataMapper = new UmbManagementApiDataMapper(this); @@ -56,7 +56,7 @@ export class UmbDocumentReferenceServerDataSource extends UmbControllerBase impl } /** - * Fetches items that are referenced by the given uniques from the server + * Checks if the items are referenced by other items * @param {Array} uniques - The unique identifiers of the items to fetch * @param {number} skip - The number of items to skip * @param {number} take - The number of items to take From 0a871522828ff0b70da93997e3525487b3577ce6 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 19 Feb 2025 17:40:15 +0100 Subject: [PATCH 130/145] implement methods for are referenced --- .../repository/media-reference.repository.ts | 11 ++++++ .../repository/media-reference.server.data.ts | 34 ++++++++++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.repository.ts index ab5ac83a5fc7..53ed8b45e1d3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.repository.ts @@ -2,6 +2,8 @@ import { UmbMediaReferenceServerDataSource } from './media-reference.server.data import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbEntityReferenceRepository } from '@umbraco-cms/backoffice/relations'; +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; +import type { UmbRepositoryResponse, UmbPagedModel } from '@umbraco-cms/backoffice/repository'; export class UmbMediaReferenceRepository extends UmbControllerBase implements UmbEntityReferenceRepository { #referenceSource: UmbMediaReferenceServerDataSource; @@ -20,6 +22,15 @@ export class UmbMediaReferenceRepository extends UmbControllerBase implements Um if (!unique) throw new Error(`unique is required`); return this.#referenceSource.getReferencedDescendants(unique, skip, take); } + + async requestAreReferenced( + uniques: Array, + skip?: number, + take?: number, + ): Promise>> { + if (!uniques || uniques.length === 0) throw new Error(`uniques is required`); + return this.#referenceSource.getAreReferenced(uniques, skip, take); + } } export default UmbMediaReferenceRepository; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts index 8aadc0fdae5b..193fef87f587 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts @@ -9,7 +9,7 @@ import type { UmbPagedModel, UmbDataSourceResponse } from '@umbraco-cms/backoffi /** * @class UmbMediaReferenceServerDataSource - * @implements {RepositoryDetailDataSource} + * @implements {UmbEntityReferenceDataSource} */ export class UmbMediaReferenceServerDataSource extends UmbControllerBase implements UmbEntityReferenceDataSource { #dataMapper = new UmbManagementApiDataMapper(this); @@ -55,6 +55,38 @@ export class UmbMediaReferenceServerDataSource extends UmbControllerBase impleme return { data, error }; } + /** + * Checks if the items are referenced by other items + * @param {Array} uniques - The unique identifiers of the items to fetch + * @param {number} skip - The number of items to skip + * @param {number} take - The number of items to take + * @returns {Promise>>} - Items that are referenced by other items + * @memberof UmbMediaReferenceServerDataSource + */ + async getAreReferenced( + uniques: Array, + skip: number = 0, + take: number = 20, + ): Promise>> { + const { data, error } = await tryExecuteAndNotify( + this, + MediaService.getMediaAreReferenced({ id: uniques, skip, take }), + ); + + if (data) { + const items: Array = data.items.map((item) => { + return { + unique: item.id, + entityType: UMB_MEDIA_ENTITY_TYPE, + }; + }); + + return { data: { items, total: data.total } }; + } + + return { data, error }; + } + /** * Returns any descendants of the given unique that is referenced by other items * @param {string} unique - The unique identifier of the item to fetch descendants for From d7c0081cf4c438331019675ff6a9d3d0a1eb218f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 19 Feb 2025 17:40:38 +0100 Subject: [PATCH 131/145] change to use bulk trash with relation --- .../media/entity-bulk-actions/trash/manifests.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts index 48bc80af0007..65cb4ee366f6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts @@ -1,18 +1,22 @@ -import { UMB_MEDIA_COLLECTION_ALIAS } from '../../constants.js'; +import { + UMB_MEDIA_COLLECTION_ALIAS, + UMB_MEDIA_ITEM_REPOSITORY_ALIAS, + UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS, +} from '../../constants.js'; import { UMB_MEDIA_ENTITY_TYPE } from '../../entity.js'; -import { UMB_BULK_TRASH_MEDIA_REPOSITORY_ALIAS } from './constants.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection'; const bulkTrashAction: UmbExtensionManifest = { type: 'entityBulkAction', - kind: 'trash', + kind: 'trashWithRelation', alias: 'Umb.EntityBulkAction.Media.Trash', name: 'Trash Media Entity Bulk Action', weight: 10, forEntityTypes: [UMB_MEDIA_ENTITY_TYPE], meta: { - bulkTrashRepositoryAlias: UMB_BULK_TRASH_MEDIA_REPOSITORY_ALIAS, + itemRepositoryAlias: UMB_MEDIA_ITEM_REPOSITORY_ALIAS, + referenceRepositoryAlias: UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS, }, conditions: [ { From dc5b622f43016c48b37a9021dc6a4d6ad10a1b50 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 19 Feb 2025 18:17:14 +0100 Subject: [PATCH 132/145] implement delete with relation kind --- .../packages/core/entity-bulk-action/index.ts | 2 + .../entity-bulk-actions/trash/manifests.ts | 2 + .../packages/relations/relations/constants.ts | 3 +- .../bulk-delete-with-relation.action.kind.ts | 15 ++++ .../bulk-delete-with-relation.action.ts | 22 +++++ .../entity-actions/bulk-delete/constants.ts | 1 + .../entity-actions/bulk-delete/index.ts | 2 + .../entity-actions/bulk-delete/manifests.ts | 9 ++ ...bulk-delete-with-relation-modal.element.ts | 86 +++++++++++++++++++ .../bulk-delete-with-relation-modal.token.ts | 18 ++++ .../bulk-delete/modal/constants.ts | 1 + .../bulk-delete/modal/manifests.ts | 8 ++ .../entity-actions/bulk-delete/types.ts | 18 ++++ .../packages/relations/relations/manifests.ts | 2 + 14 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/bulk-delete-with-relation.action.kind.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/bulk-delete-with-relation.action.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/bulk-delete-with-relation-modal.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/bulk-delete-with-relation-modal.token.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/constants.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/manifests.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts index 5e3f63211ef3..f70666f08b8e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts @@ -1,5 +1,7 @@ export * from './entity-bulk-action-base.js'; export * from './entity-bulk-action.element.js'; +export * from './common/bulk-delete/index.js'; export type * from './types.js'; export { UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST } from './default/default.action.kind.js'; +export { UMB_ENTITY_BULK_ACTION_DELETE_KIND_MANIFEST } from './common/bulk-delete/bulk-delete.action.kind.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts index 65cb4ee366f6..3a68ea28bdbb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts @@ -1,6 +1,7 @@ import { UMB_MEDIA_COLLECTION_ALIAS, UMB_MEDIA_ITEM_REPOSITORY_ALIAS, + UMB_MEDIA_RECYCLE_BIN_REPOSITORY_ALIAS, UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS, } from '../../constants.js'; import { UMB_MEDIA_ENTITY_TYPE } from '../../entity.js'; @@ -16,6 +17,7 @@ const bulkTrashAction: UmbExtensionManifest = { forEntityTypes: [UMB_MEDIA_ENTITY_TYPE], meta: { itemRepositoryAlias: UMB_MEDIA_ITEM_REPOSITORY_ALIAS, + recycleBinRepositoryAlias: UMB_MEDIA_RECYCLE_BIN_REPOSITORY_ALIAS, referenceRepositoryAlias: UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS, }, conditions: [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/constants.ts index d153a3f3e17d..6d7855c1514e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/constants.ts @@ -1,5 +1,6 @@ export { UMB_RELATION_ENTITY_TYPE } from './entity.js'; export * from './collection/constants.js'; +export * from './entity-actions/bulk-delete/constants.js'; +export * from './entity-actions/bulk-trash/constants.js'; export * from './entity-actions/delete/constants.js'; export * from './entity-actions/trash/constants.js'; -export * from './entity-actions/bulk-trash/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/bulk-delete-with-relation.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/bulk-delete-with-relation.action.kind.ts new file mode 100644 index 000000000000..44582b7e6aa9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/bulk-delete-with-relation.action.kind.ts @@ -0,0 +1,15 @@ +import { UMB_ENTITY_BULK_ACTION_DELETE_KIND_MANIFEST } from '@umbraco-cms/backoffice/entity-bulk-action'; +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifest: UmbExtensionManifestKind = { + type: 'kind', + alias: 'Umb.Kind.EntityBulkAction.DeleteWithRelation', + matchKind: 'deleteWithRelation', + matchType: 'entityBulkAction', + manifest: { + ...UMB_ENTITY_BULK_ACTION_DELETE_KIND_MANIFEST.manifest, + type: 'entityBulkAction', + kind: 'deleteWithRelation', + api: () => import('./bulk-delete-with-relation.action.js'), + }, +}; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/bulk-delete-with-relation.action.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/bulk-delete-with-relation.action.ts new file mode 100644 index 000000000000..71b26bf65337 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/bulk-delete-with-relation.action.ts @@ -0,0 +1,22 @@ +import type { MetaEntityBulkActionDeleteWithRelationKind } from './types.js'; +import { UMB_BULK_DELETE_WITH_RELATION_CONFIRM_MODAL } from './modal/bulk-delete-with-relation-modal.token.js'; +import { UmbDeleteEntityBulkAction } from '@umbraco-cms/backoffice/entity-bulk-action'; +import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; + +export class UmbBulkDeleteWithRelationEntityAction extends UmbDeleteEntityBulkAction { + override async _confirmDelete() { + const modalManager = await this.getContext(UMB_MODAL_MANAGER_CONTEXT); + + const modal = modalManager.open(this, UMB_BULK_DELETE_WITH_RELATION_CONFIRM_MODAL, { + data: { + uniques: this.selection, + itemRepositoryAlias: this.args.meta.itemRepositoryAlias, + referenceRepositoryAlias: this.args.meta.referenceRepositoryAlias, + }, + }); + + await modal.onSubmit(); + } +} + +export { UmbBulkDeleteWithRelationEntityAction as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/constants.ts new file mode 100644 index 000000000000..26f4f0dd5f39 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/constants.ts @@ -0,0 +1 @@ +export * from './modal/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/index.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/index.ts new file mode 100644 index 000000000000..64a7503c0f05 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/index.ts @@ -0,0 +1,2 @@ +export * from './bulk-delete-with-relation.action.js'; +export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/manifests.ts new file mode 100644 index 000000000000..9d922686b089 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/manifests.ts @@ -0,0 +1,9 @@ +import { manifest as deleteKindManifest } from './bulk-delete-with-relation.action.kind.js'; +import { manifests as modalManifests } from './modal/manifests.js'; + +import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; + +export const manifests: Array = [ + deleteKindManifest, + ...modalManifests, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/bulk-delete-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/bulk-delete-with-relation-modal.element.ts new file mode 100644 index 000000000000..656f3088aad3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/bulk-delete-with-relation-modal.element.ts @@ -0,0 +1,86 @@ +import type { + UmbBulkDeleteWithRelationConfirmModalData, + UmbBulkDeleteWithRelationConfirmModalValue, +} from './bulk-delete-with-relation-modal.token.js'; +import { + html, + customElement, + css, + state, + type PropertyValues, + nothing, + unsafeHTML, +} from '@umbraco-cms/backoffice/external/lit'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; +import { umbFocus } from '@umbraco-cms/backoffice/lit-element'; + +// import of local component +import '../../local-components/confirm-bulk-action-entity-references.element.js'; + +@customElement('umb-bulk-delete-with-relation-confirm-modal') +export class UmbBulkDeleteWithRelationConfirmModalElement extends UmbModalBaseElement< + UmbBulkDeleteWithRelationConfirmModalData, + UmbBulkDeleteWithRelationConfirmModalValue +> { + @state() + _referencesConfig?: any; + + protected override firstUpdated(_changedProperties: PropertyValues): void { + super.firstUpdated(_changedProperties); + this.#initData(); + } + + async #initData() { + if (!this.data) return; + + this._referencesConfig = { + uniques: this.data.uniques, + itemRepositoryAlias: this.data.itemRepositoryAlias, + referenceRepositoryAlias: this.data.referenceRepositoryAlias, + }; + } + + override render() { + const headline = this.localize.string('#actions_delete'); + const message = '#defaultdialogs_confirmBulkDelete'; + + return html` + +

${unsafeHTML(this.localize.string(message, this.data?.uniques.length))}

+ ${this._referencesConfig + ? html`` + : nothing} + + + + +
+ `; + } + + static override styles = [ + UmbTextStyles, + css` + uui-dialog-layout { + max-inline-size: 60ch; + } + `, + ]; +} + +export { UmbBulkDeleteWithRelationConfirmModalElement as element }; + +declare global { + interface HTMLElementTagNameMap { + 'umb-delete-with-relation-confirm-modal': UmbBulkDeleteWithRelationConfirmModalElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/bulk-delete-with-relation-modal.token.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/bulk-delete-with-relation-modal.token.ts new file mode 100644 index 000000000000..b66ee86cb194 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/bulk-delete-with-relation-modal.token.ts @@ -0,0 +1,18 @@ +import { UmbModalToken } from '@umbraco-cms/backoffice/modal'; + +export interface UmbBulkDeleteWithRelationConfirmModalData { + uniques: Array; + itemRepositoryAlias: string; + referenceRepositoryAlias: string; +} + +export type UmbBulkDeleteWithRelationConfirmModalValue = undefined; + +export const UMB_BULK_DELETE_WITH_RELATION_CONFIRM_MODAL = new UmbModalToken< + UmbBulkDeleteWithRelationConfirmModalData, + UmbBulkDeleteWithRelationConfirmModalValue +>('Umb.Modal.BulkDeleteWithRelation', { + modal: { + type: 'dialog', + }, +}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/constants.ts new file mode 100644 index 000000000000..8fcf44dcdad8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/constants.ts @@ -0,0 +1 @@ +export * from './bulk-delete-with-relation-modal.token.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/manifests.ts new file mode 100644 index 000000000000..13a881cd09dc --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/manifests.ts @@ -0,0 +1,8 @@ +export const manifests: Array = [ + { + type: 'modal', + alias: 'Umb.Modal.BulkDeleteWithRelation', + name: 'Bulk Delete With Relation Modal', + element: () => import('./bulk-delete-with-relation-modal.element.js'), + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/types.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/types.ts new file mode 100644 index 000000000000..b8388273627d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/types.ts @@ -0,0 +1,18 @@ +import type { MetaEntityBulkActionDeleteKind } from '@umbraco-cms/backoffice/entity-bulk-action'; +import type { ManifestEntityBulkAction } from '@umbraco-cms/backoffice/extension-registry'; + +export interface ManifestEntityBulkActionDeleteWithRelationKind + extends ManifestEntityBulkAction { + type: 'entityBulkAction'; + kind: 'deleteWithRelation'; +} + +export interface MetaEntityBulkActionDeleteWithRelationKind extends MetaEntityBulkActionDeleteKind { + referenceRepositoryAlias: string; +} + +declare global { + interface UmbExtensionManifestMap { + umbManifestEntityBulkActionDeleteWithRelationKind: ManifestEntityBulkActionDeleteWithRelationKind; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts index 0f882bc45eb9..fceac92145e1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/manifests.ts @@ -1,3 +1,4 @@ +import { manifests as bulkDeleteManifests } from './entity-actions/bulk-delete/manifests.js'; import { manifests as bulkTrashManifests } from './entity-actions/bulk-trash/manifests.js'; import { manifests as collectionManifests } from './collection/manifests.js'; import { manifests as deleteManifests } from './entity-actions/delete/manifests.js'; @@ -5,6 +6,7 @@ import { manifests as trashManifests } from './entity-actions/trash/manifests.js import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; export const manifests: Array = [ + ...bulkDeleteManifests, ...bulkTrashManifests, ...collectionManifests, ...deleteManifests, From db83007fd01a7f18c8516d480376483325f16d55 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 19 Feb 2025 21:00:30 +0100 Subject: [PATCH 133/145] deprecation warnings --- .../bulk-delete/bulk-delete.action.kind.ts | 6 ++++-- .../common/bulk-delete/constants.ts | 5 ++++- .../common/trash/constants.ts | 1 + .../trash/trash-repository.interface.ts | 7 ++++++- .../common/trash/trash.action.kind.ts | 5 +++-- .../common/trash/trash.action.ts | 20 ++++++++++++++++++- .../packages/core/entity-bulk-action/index.ts | 5 ++++- .../bulk-trash/bulk-trash.action.kind.ts | 7 +++++-- .../bulk-trash/constants.ts | 5 ++++- .../entity-bulk-actions/trash/manifests.ts | 3 ++- .../trash/repository/trash.repository.ts | 10 ++++++++++ .../entity-bulk-actions/trash/manifests.ts | 3 ++- .../trash/repository/trash.repository.ts | 10 ++++++++++ .../bulk-delete-with-relation.action.kind.ts | 6 ++++-- .../entity-actions/bulk-delete/constants.ts | 1 + ...bulk-delete-with-relation-modal.element.ts | 2 +- .../bulk-trash-with-relation.action.kind.ts | 2 ++ .../entity-actions/bulk-trash/constants.ts | 1 + .../bulk-trash-with-relation-modal.element.ts | 2 +- .../entity-bulk-actions/manifests.ts | 3 ++- 20 files changed, 86 insertions(+), 18 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/constants.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.kind.ts index 186b1d6ba576..86ab68fdd413 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.kind.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.kind.ts @@ -1,15 +1,17 @@ import { UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST } from '@umbraco-cms/backoffice/entity-bulk-action'; import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; +export const UMB_ENTITY_BULK_ACTION_DELETE_KIND = 'delete'; + export const UMB_ENTITY_BULK_ACTION_DELETE_KIND_MANIFEST: UmbExtensionManifestKind = { type: 'kind', alias: 'Umb.Kind.EntityBulkAction.Delete', - matchKind: 'delete', + matchKind: UMB_ENTITY_BULK_ACTION_DELETE_KIND, matchType: 'entityBulkAction', manifest: { ...UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST.manifest, type: 'entityBulkAction', - kind: 'delete', + kind: UMB_ENTITY_BULK_ACTION_DELETE_KIND, api: () => import('./bulk-delete.action.js'), weight: 1100, meta: { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/constants.ts index 796004d94686..b88413e675f9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/constants.ts @@ -1 +1,4 @@ -export { UMB_ENTITY_BULK_ACTION_DELETE_KIND_MANIFEST } from './bulk-delete.action.kind.js'; +export { + UMB_ENTITY_BULK_ACTION_DELETE_KIND_MANIFEST, + UMB_ENTITY_BULK_ACTION_DELETE_KIND, +} from './bulk-delete.action.kind.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/constants.ts new file mode 100644 index 000000000000..f919f4aea61b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/constants.ts @@ -0,0 +1 @@ +export const UMB_ENTITY_BULK_ACTION_TRASH_KIND = 'trash'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash-repository.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash-repository.interface.ts index 195b2f772480..8570bfc8ad77 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash-repository.interface.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash-repository.interface.ts @@ -1,7 +1,12 @@ import type { UmbRepositoryErrorResponse } from '../../../repository/types.js'; import type { UmbBulkTrashRequestArgs } from './types.js'; import type { UmbApi } from '@umbraco-cms/backoffice/extension-api'; - +/** + * @deprecated since 15.3.0. Will be removed in 17.0.0. Call trash method on UmbRecycleBin repositories instead. + * @exports + * @interface UmbBulkTrashRepository + * @augments UmbApi + */ export interface UmbBulkTrashRepository extends UmbApi { requestBulkTrash(args: UmbBulkTrashRequestArgs): Promise; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash.action.kind.ts index 2c36d6dc35f3..dd6d35119250 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash.action.kind.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash.action.kind.ts @@ -1,15 +1,16 @@ import { UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST } from '../../default/default.action.kind.js'; +import { UMB_ENTITY_BULK_ACTION_TRASH_KIND } from './constants.js'; import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; export const manifest: UmbExtensionManifestKind = { type: 'kind', alias: 'Umb.Kind.EntityBulkAction.Trash', - matchKind: 'trash', + matchKind: UMB_ENTITY_BULK_ACTION_TRASH_KIND, matchType: 'entityBulkAction', manifest: { ...UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST.manifest, type: 'entityBulkAction', - kind: 'trash', + kind: UMB_ENTITY_BULK_ACTION_TRASH_KIND, api: () => import('./trash.action.js'), weight: 700, forEntityTypes: [], diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash.action.ts index 70cbc7ffd501..84d27501ccb5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/trash/trash.action.ts @@ -1,6 +1,6 @@ import type { UmbBulkTrashRepository } from './trash-repository.interface.js'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; -import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; +import { UmbEntityBulkActionBase, type UmbEntityBulkActionArgs } from '@umbraco-cms/backoffice/entity-bulk-action'; import { UmbRequestReloadChildrenOfEntityEvent, UmbRequestReloadStructureForEntityEvent, @@ -9,8 +9,26 @@ import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; import { UMB_ENTITY_CONTEXT } from '@umbraco-cms/backoffice/entity'; import { umbConfirmModal } from '@umbraco-cms/backoffice/modal'; import type { MetaEntityBulkActionTrashKind } from '@umbraco-cms/backoffice/extension-registry'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbDeprecation } from '@umbraco-cms/backoffice/utils'; +/** + * @deprecated since v15.3.0. Will be removed in v17.0.0. import `UmbMediaTrashEntityBulkAction` from @umbraco-cms/backoffice/recycle-bin instead. + * @exports + * @class UmbMediaTrashEntityBulkAction + * @augments {UmbEntityBulkActionBase} + */ export class UmbMediaTrashEntityBulkAction extends UmbEntityBulkActionBase { + constructor(host: UmbControllerHost, args: UmbEntityBulkActionArgs) { + super(host, args); + + new UmbDeprecation({ + removeInVersion: '17.0.0', + deprecated: 'UmbMediaTrashEntityBulkAction', + solution: 'import UmbMediaTrashEntityBulkAction from @umbraco-cms/backoffice/recycle-bin instead.', + }).warn(); + } + async execute() { if (this.selection?.length === 0) return; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts index f70666f08b8e..97b5f594911e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts @@ -4,4 +4,7 @@ export * from './common/bulk-delete/index.js'; export type * from './types.js'; export { UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST } from './default/default.action.kind.js'; -export { UMB_ENTITY_BULK_ACTION_DELETE_KIND_MANIFEST } from './common/bulk-delete/bulk-delete.action.kind.js'; +export { + UMB_ENTITY_BULK_ACTION_DELETE_KIND_MANIFEST, + UMB_ENTITY_BULK_ACTION_DELETE_KIND, +} from './common/bulk-delete/bulk-delete.action.kind.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts index d475c5b79a12..b96fc8edd7b8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts @@ -1,15 +1,18 @@ import { UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST } from '@umbraco-cms/backoffice/entity-bulk-action'; import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; +// TODO: v17: rename kind to trash +export const UMB_ENTITY_BULK_ACTION_TRASH_KIND = 'trashV2'; + export const UMB_ENTITY_BULK_ACTION_TRASH_KIND_MANIFEST: UmbExtensionManifestKind = { type: 'kind', alias: 'Umb.Kind.EntityBulkAction.Trash', - matchKind: 'trashV2', + matchKind: UMB_ENTITY_BULK_ACTION_TRASH_KIND, matchType: 'entityBulkAction', manifest: { ...UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST.manifest, type: 'entityBulkAction', - kind: 'trashV2', + kind: UMB_ENTITY_BULK_ACTION_TRASH_KIND, api: () => import('./bulk-trash.action.js'), weight: 1150, meta: { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/constants.ts index 258564816886..65c101c9fbc7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/constants.ts @@ -1 +1,4 @@ -export { UMB_ENTITY_BULK_ACTION_TRASH_KIND_MANIFEST } from './bulk-trash.action.kind.js'; +export { + UMB_ENTITY_BULK_ACTION_TRASH_KIND_MANIFEST, + UMB_ENTITY_BULK_ACTION_TRASH_KIND, +} from './bulk-trash.action.kind.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts index fc8037d05a05..9115d85f5cb0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts @@ -7,12 +7,13 @@ import { import { UMB_DOCUMENT_ENTITY_TYPE } from '../../entity.js'; import { UMB_USER_PERMISSION_DOCUMENT_DELETE } from '../../user-permissions/constants.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; +import { UMB_ENTITY_BULK_ACTION_TRASH_WITH_RELATION_KIND } from '@umbraco-cms/backoffice/relations'; import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection'; export const manifests: Array = [ { type: 'entityBulkAction', - kind: 'trashWithRelation', + kind: UMB_ENTITY_BULK_ACTION_TRASH_WITH_RELATION_KIND, alias: 'Umb.EntityBulkAction.Document.Trash', name: 'Trash Document Entity Bulk Action', weight: 10, diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/trash.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/trash.repository.ts index edd03d8400fd..389ea6f0667c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/trash.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/trash.repository.ts @@ -4,7 +4,11 @@ import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; import type { UmbBulkTrashRepository, UmbBulkTrashRequestArgs } from '@umbraco-cms/backoffice/entity-bulk-action'; import type { UmbRepositoryErrorResponse } from '@umbraco-cms/backoffice/repository'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbDeprecation } from '@umbraco-cms/backoffice/utils'; +/** + * @deprecated since 15.3.0. Will be removed in 17.0.0. Call trash method on UmbDocumentRecycleBinRepository instead. + */ export class UmbBulkTrashDocumentRepository extends UmbRepositoryBase implements UmbBulkTrashRepository { #notificationContext?: typeof UMB_NOTIFICATION_CONTEXT.TYPE; #recycleBinSource = new UmbDocumentRecycleBinServerDataSource(this); @@ -12,6 +16,12 @@ export class UmbBulkTrashDocumentRepository extends UmbRepositoryBase implements constructor(host: UmbControllerHost) { super(host); + new UmbDeprecation({ + removeInVersion: '17.0.0', + deprecated: 'UmbBulkTrashDocumentRepository', + solution: 'Call trash method on UmbDocumentRecycleBinRepository instead.', + }).warn(); + this.consumeContext(UMB_NOTIFICATION_CONTEXT, (notificationContext) => { this.#notificationContext = notificationContext; }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts index 3a68ea28bdbb..15b52f007233 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts @@ -7,10 +7,11 @@ import { import { UMB_MEDIA_ENTITY_TYPE } from '../../entity.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection'; +import { UMB_ENTITY_BULK_ACTION_TRASH_KIND } from '@umbraco-cms/backoffice/recycle-bin'; const bulkTrashAction: UmbExtensionManifest = { type: 'entityBulkAction', - kind: 'trashWithRelation', + kind: UMB_ENTITY_BULK_ACTION_TRASH_KIND, alias: 'Umb.EntityBulkAction.Media.Trash', name: 'Trash Media Entity Bulk Action', weight: 10, diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/trash.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/trash.repository.ts index d84cd3e95603..e558546e2e7c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/trash.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/trash.repository.ts @@ -4,7 +4,11 @@ import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; import type { UmbBulkTrashRepository, UmbBulkTrashRequestArgs } from '@umbraco-cms/backoffice/entity-bulk-action'; import type { UmbRepositoryErrorResponse } from '@umbraco-cms/backoffice/repository'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbDeprecation } from '@umbraco-cms/backoffice/utils'; +/** + * @deprecated since 15.3.0. Will be removed in 17.0.0. Call trash method on UmbMediaRecycleBinRepository instead. + */ export class UmbBulkTrashMediaRepository extends UmbRepositoryBase implements UmbBulkTrashRepository { #notificationContext?: typeof UMB_NOTIFICATION_CONTEXT.TYPE; #recycleBinSource = new UmbMediaRecycleBinServerDataSource(this); @@ -12,6 +16,12 @@ export class UmbBulkTrashMediaRepository extends UmbRepositoryBase implements Um constructor(host: UmbControllerHost) { super(host); + new UmbDeprecation({ + removeInVersion: '17.0.0', + deprecated: 'UmbBulkTrashDocumentRepository', + solution: 'Call trash method on UmbMediaRecycleBinRepository instead.', + }).warn(); + this.consumeContext(UMB_NOTIFICATION_CONTEXT, (notificationContext) => { this.#notificationContext = notificationContext; }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/bulk-delete-with-relation.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/bulk-delete-with-relation.action.kind.ts index 44582b7e6aa9..177f452f1784 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/bulk-delete-with-relation.action.kind.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/bulk-delete-with-relation.action.kind.ts @@ -1,15 +1,17 @@ import { UMB_ENTITY_BULK_ACTION_DELETE_KIND_MANIFEST } from '@umbraco-cms/backoffice/entity-bulk-action'; import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; +export const UMB_ENTITY_BULK_ACTION_DELETE_WITH_RELATION_KIND = 'deleteWithRelation'; + export const manifest: UmbExtensionManifestKind = { type: 'kind', alias: 'Umb.Kind.EntityBulkAction.DeleteWithRelation', - matchKind: 'deleteWithRelation', + matchKind: UMB_ENTITY_BULK_ACTION_DELETE_WITH_RELATION_KIND, matchType: 'entityBulkAction', manifest: { ...UMB_ENTITY_BULK_ACTION_DELETE_KIND_MANIFEST.manifest, type: 'entityBulkAction', - kind: 'deleteWithRelation', + kind: UMB_ENTITY_BULK_ACTION_DELETE_WITH_RELATION_KIND, api: () => import('./bulk-delete-with-relation.action.js'), }, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/constants.ts index 26f4f0dd5f39..255321445a42 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/constants.ts @@ -1 +1,2 @@ export * from './modal/constants.js'; +export { UMB_ENTITY_BULK_ACTION_DELETE_WITH_RELATION_KIND } from './bulk-delete-with-relation.action.kind.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/bulk-delete-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/bulk-delete-with-relation-modal.element.ts index 656f3088aad3..c7d2a22c79c0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/bulk-delete-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-delete/modal/bulk-delete-with-relation-modal.element.ts @@ -81,6 +81,6 @@ export { UmbBulkDeleteWithRelationConfirmModalElement as element }; declare global { interface HTMLElementTagNameMap { - 'umb-delete-with-relation-confirm-modal': UmbBulkDeleteWithRelationConfirmModalElement; + 'umb-bulk-delete-with-relation-confirm-modal': UmbBulkDeleteWithRelationConfirmModalElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/bulk-trash-with-relation.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/bulk-trash-with-relation.action.kind.ts index 85d2deb8c8af..88b74d93c86e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/bulk-trash-with-relation.action.kind.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/bulk-trash-with-relation.action.kind.ts @@ -1,6 +1,8 @@ import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; import { UMB_ENTITY_BULK_ACTION_TRASH_KIND_MANIFEST } from '@umbraco-cms/backoffice/recycle-bin'; +export const UMB_ENTITY_BULK_ACTION_TRASH_WITH_RELATION_KIND = 'trashWithRelation'; + export const manifest: UmbExtensionManifestKind = { type: 'kind', alias: 'Umb.Kind.EntityBulkAction.TrashWithRelation', diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/constants.ts index 26f4f0dd5f39..98307596b7ba 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/constants.ts @@ -1 +1,2 @@ export * from './modal/constants.js'; +export { UMB_ENTITY_BULK_ACTION_TRASH_WITH_RELATION_KIND } from './bulk-trash-with-relation.action.kind.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.element.ts index 27f77486f140..8785fe42e13d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/bulk-trash/modal/bulk-trash-with-relation-modal.element.ts @@ -81,6 +81,6 @@ export { UmbBulkTrashWithRelationConfirmModalElement as element }; declare global { interface HTMLElementTagNameMap { - 'umb-trash-with-relation-confirm-modal': UmbBulkTrashWithRelationConfirmModalElement; + 'umb-bulk-trash-with-relation-confirm-modal': UmbBulkTrashWithRelationConfirmModalElement; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/entity-bulk-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/entity-bulk-actions/manifests.ts index 783805774e3b..3bae91ba418f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/entity-bulk-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/entity-bulk-actions/manifests.ts @@ -1,12 +1,13 @@ import { UMB_USER_GROUP_COLLECTION_ALIAS } from '../collection/index.js'; import { UMB_USER_GROUP_DETAIL_REPOSITORY_ALIAS, UMB_USER_GROUP_ITEM_REPOSITORY_ALIAS } from '../constants.js'; import { UMB_USER_GROUP_ENTITY_TYPE } from '../entity.js'; +import { UMB_ENTITY_BULK_ACTION_DELETE_KIND } from '@umbraco-cms/backoffice/entity-bulk-action'; import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection'; export const manifests: Array = [ { type: 'entityBulkAction', - kind: 'delete', + kind: UMB_ENTITY_BULK_ACTION_DELETE_KIND, alias: 'Umb.EntityBulkAction.UserGroup.Delete', name: 'Delete User Group Entity Bulk Action', weight: 400, From 74242eacef7992247aff18fe8ed0438fd4da88ac Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 19 Feb 2025 21:09:16 +0100 Subject: [PATCH 134/145] move files --- .../documents/documents/entity-bulk-actions/constants.ts | 1 - .../documents/documents/entity-bulk-actions/manifests.ts | 3 +-- .../packages/documents/documents/recycle-bin/constants.ts | 1 + .../entity-action/bulk-trash}/constants.ts | 0 .../entity-action/bulk-trash}/index.ts | 0 .../entity-action/bulk-trash}/manifests.ts | 8 ++++---- .../entity-action/bulk-trash}/repository/constants.ts | 0 .../entity-action/bulk-trash}/repository/index.ts | 0 .../entity-action/bulk-trash}/repository/manifests.ts | 0 .../bulk-trash}/repository/trash.repository.ts | 2 +- .../documents/recycle-bin/entity-action/constants.ts | 1 + .../documents/recycle-bin/entity-action/manifests.ts | 2 ++ 12 files changed, 10 insertions(+), 8 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/{entity-bulk-actions/trash => recycle-bin/entity-action/bulk-trash}/constants.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/{entity-bulk-actions/trash => recycle-bin/entity-action/bulk-trash}/index.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/{entity-bulk-actions/trash => recycle-bin/entity-action/bulk-trash}/manifests.ts (81%) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/{entity-bulk-actions/trash => recycle-bin/entity-action/bulk-trash}/repository/constants.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/{entity-bulk-actions/trash => recycle-bin/entity-action/bulk-trash}/repository/index.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/{entity-bulk-actions/trash => recycle-bin/entity-action/bulk-trash}/repository/manifests.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/documents/documents/{entity-bulk-actions/trash => recycle-bin/entity-action/bulk-trash}/repository/trash.repository.ts (96%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/constants.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/constants.ts index 8d305a645829..8d2371e6f323 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/constants.ts @@ -1,3 +1,2 @@ export * from './duplicate-to/constants.js'; export * from './move-to/constants.js'; -export * from './trash/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/manifests.ts index 65ee8658fc9a..b67ea4c1a08f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/manifests.ts @@ -1,5 +1,4 @@ import { manifests as duplicateToManifests } from './duplicate-to/manifests.js'; import { manifests as moveToManifests } from './move-to/manifests.js'; -import { manifests as trashManifests } from './trash/manifests.js'; -export const manifests: Array = [...duplicateToManifests, ...moveToManifests, ...trashManifests]; +export const manifests: Array = [...duplicateToManifests, ...moveToManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/constants.ts index 0002782c2b1c..9af32d7bb73a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/constants.ts @@ -1,3 +1,4 @@ +export * from './entity-action/constants.js'; export * from './repository/constants.js'; export * from './tree/constants.js'; export const UMB_DOCUMENT_RECYCLE_BIN_ROOT_ENTITY_TYPE = 'document-recycle-bin-root'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/constants.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/constants.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/constants.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/index.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/index.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/manifests.ts similarity index 81% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/manifests.ts index 9115d85f5cb0..f49fc7121db0 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/manifests.ts @@ -1,11 +1,11 @@ -import { UMB_DOCUMENT_COLLECTION_ALIAS } from '../../collection/constants.js'; +import { UMB_DOCUMENT_COLLECTION_ALIAS } from '../../../collection/constants.js'; import { UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS, UMB_DOCUMENT_RECYCLE_BIN_REPOSITORY_ALIAS, UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS, -} from '../../constants.js'; -import { UMB_DOCUMENT_ENTITY_TYPE } from '../../entity.js'; -import { UMB_USER_PERMISSION_DOCUMENT_DELETE } from '../../user-permissions/constants.js'; +} from '../../../constants.js'; +import { UMB_DOCUMENT_ENTITY_TYPE } from '../../../entity.js'; +import { UMB_USER_PERMISSION_DOCUMENT_DELETE } from '../../../user-permissions/constants.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; import { UMB_ENTITY_BULK_ACTION_TRASH_WITH_RELATION_KIND } from '@umbraco-cms/backoffice/relations'; import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/repository/constants.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/constants.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/repository/constants.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/repository/index.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/index.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/repository/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/repository/manifests.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/manifests.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/repository/manifests.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/trash.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/repository/trash.repository.ts similarity index 96% rename from src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/trash.repository.ts rename to src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/repository/trash.repository.ts index 389ea6f0667c..43c2ed8c1dc9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/entity-bulk-actions/trash/repository/trash.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/repository/trash.repository.ts @@ -1,4 +1,4 @@ -import { UmbDocumentRecycleBinServerDataSource } from '../../../recycle-bin/repository/document-recycle-bin.server.data-source.js'; +import { UmbDocumentRecycleBinServerDataSource } from '../../../repository/document-recycle-bin.server.data-source.js'; import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; import type { UmbBulkTrashRepository, UmbBulkTrashRequestArgs } from '@umbraco-cms/backoffice/entity-bulk-action'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/constants.ts new file mode 100644 index 000000000000..e96d7ef38da7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/constants.ts @@ -0,0 +1 @@ +export * from './bulk-trash/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/manifests.ts index db98e6e0bbef..6c4cf7b4b217 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/manifests.ts @@ -7,6 +7,7 @@ import { } from '../../constants.js'; import { UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS } from '../../reference/constants.js'; import { UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS } from '../../item/constants.js'; +import { manifests as bulkTrashManifests } from './bulk-trash/manifests.js'; import { UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS, UMB_ENTITY_IS_TRASHED_CONDITION_ALIAS, @@ -71,4 +72,5 @@ export const manifests: Array = [ }, ], }, + ...bulkTrashManifests, ]; From 9b4d22daf6234e539ff69b2c1a38cf37d338e103 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 19 Feb 2025 21:18:06 +0100 Subject: [PATCH 135/145] move files --- .../entity-action/bulk-trash/manifests.ts | 14 ++++++-------- .../media/media/entity-bulk-actions/constants.ts | 1 - .../media/media/entity-bulk-actions/manifests.ts | 3 +-- .../packages/media/media/recycle-bin/constants.ts | 1 + .../entity-action/bulk-trash}/constants.ts | 0 .../entity-action/bulk-trash}/index.ts | 0 .../entity-action/bulk-trash}/manifests.ts | 14 ++++++-------- .../bulk-trash}/repository/constants.ts | 0 .../entity-action/bulk-trash}/repository/index.ts | 0 .../bulk-trash}/repository/manifests.ts | 0 .../bulk-trash}/repository/trash.repository.ts | 2 +- .../media/recycle-bin/entity-action/constants.ts | 1 + .../media/recycle-bin/entity-action/manifests.ts | 2 ++ .../utils/all-umb-consts/index.ts | 10 +++++----- 14 files changed, 23 insertions(+), 25 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/media/media/{entity-bulk-actions/trash => recycle-bin/entity-action/bulk-trash}/constants.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/media/media/{entity-bulk-actions/trash => recycle-bin/entity-action/bulk-trash}/index.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/media/media/{entity-bulk-actions/trash => recycle-bin/entity-action/bulk-trash}/manifests.ts (69%) rename src/Umbraco.Web.UI.Client/src/packages/media/media/{entity-bulk-actions/trash => recycle-bin/entity-action/bulk-trash}/repository/constants.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/media/media/{entity-bulk-actions/trash => recycle-bin/entity-action/bulk-trash}/repository/index.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/media/media/{entity-bulk-actions/trash => recycle-bin/entity-action/bulk-trash}/repository/manifests.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/media/media/{entity-bulk-actions/trash => recycle-bin/entity-action/bulk-trash}/repository/trash.repository.ts (93%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/constants.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/manifests.ts index f49fc7121db0..2ac56f94f52d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/recycle-bin/entity-action/bulk-trash/manifests.ts @@ -1,14 +1,12 @@ -import { UMB_DOCUMENT_COLLECTION_ALIAS } from '../../../collection/constants.js'; -import { - UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS, - UMB_DOCUMENT_RECYCLE_BIN_REPOSITORY_ALIAS, - UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS, -} from '../../../constants.js'; -import { UMB_DOCUMENT_ENTITY_TYPE } from '../../../entity.js'; import { UMB_USER_PERMISSION_DOCUMENT_DELETE } from '../../../user-permissions/constants.js'; +import { UMB_DOCUMENT_ENTITY_TYPE } from '../../../entity.js'; +import { UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS } from '../../../item/constants.js'; +import { UMB_DOCUMENT_RECYCLE_BIN_REPOSITORY_ALIAS } from '../../repository/constants.js'; +import { UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS } from '../../../reference/constants.js'; +import { UMB_DOCUMENT_COLLECTION_ALIAS } from '../../../collection/constants.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; -import { UMB_ENTITY_BULK_ACTION_TRASH_WITH_RELATION_KIND } from '@umbraco-cms/backoffice/relations'; import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection'; +import { UMB_ENTITY_BULK_ACTION_TRASH_WITH_RELATION_KIND } from '@umbraco-cms/backoffice/relations'; export const manifests: Array = [ { diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/constants.ts index 35432ce6cd17..5e9a915209f2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/constants.ts @@ -1,2 +1 @@ export * from './move-to/constants.js'; -export * from './trash/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/manifests.ts index 4930ca05302c..397a31367809 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/manifests.ts @@ -1,4 +1,3 @@ import { manifests as moveToManifests } from './move-to/manifests.js'; -import { manifests as trashManifests } from './trash/manifests.js'; -export const manifests: Array = [...moveToManifests, ...trashManifests]; +export const manifests: Array = [...moveToManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/constants.ts index e05617eb5acb..a77985d16439 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/constants.ts @@ -1,3 +1,4 @@ export * from './tree/constants.js'; export * from './repository/constants.js'; +export * from './entity-action/constants.js'; export const UMB_MEDIA_RECYCLE_BIN_ROOT_ENTITY_TYPE = 'media-recycle-bin-root'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/constants.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/constants.ts rename to src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/constants.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/index.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/index.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/index.ts rename to src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/manifests.ts similarity index 69% rename from src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts rename to src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/manifests.ts index 15b52f007233..79af11ce7847 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/manifests.ts @@ -1,13 +1,11 @@ -import { - UMB_MEDIA_COLLECTION_ALIAS, - UMB_MEDIA_ITEM_REPOSITORY_ALIAS, - UMB_MEDIA_RECYCLE_BIN_REPOSITORY_ALIAS, - UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS, -} from '../../constants.js'; -import { UMB_MEDIA_ENTITY_TYPE } from '../../entity.js'; +import { UMB_MEDIA_ENTITY_TYPE } from '../../../entity.js'; +import { UMB_MEDIA_ITEM_REPOSITORY_ALIAS } from '../../../repository/constants.js'; +import { UMB_MEDIA_RECYCLE_BIN_REPOSITORY_ALIAS } from '../../repository/constants.js'; +import { UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS } from '../../../reference/constants.js'; +import { UMB_MEDIA_COLLECTION_ALIAS } from '../../../collection/constants.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; -import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection'; import { UMB_ENTITY_BULK_ACTION_TRASH_KIND } from '@umbraco-cms/backoffice/recycle-bin'; +import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection'; const bulkTrashAction: UmbExtensionManifest = { type: 'entityBulkAction', diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/repository/constants.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/constants.ts rename to src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/repository/constants.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/repository/index.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/index.ts rename to src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/repository/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/repository/manifests.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/manifests.ts rename to src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/repository/manifests.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/trash.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/repository/trash.repository.ts similarity index 93% rename from src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/trash.repository.ts rename to src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/repository/trash.repository.ts index e558546e2e7c..f75ccf79897e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/entity-bulk-actions/trash/repository/trash.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/repository/trash.repository.ts @@ -1,4 +1,4 @@ -import { UmbMediaRecycleBinServerDataSource } from '../../../recycle-bin/repository/media-recycle-bin.server.data-source.js'; +import { UmbMediaRecycleBinServerDataSource } from '../../../repository/media-recycle-bin.server.data-source.js'; import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; import type { UmbBulkTrashRepository, UmbBulkTrashRequestArgs } from '@umbraco-cms/backoffice/entity-bulk-action'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/constants.ts new file mode 100644 index 000000000000..e96d7ef38da7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/constants.ts @@ -0,0 +1 @@ +export * from './bulk-trash/constants.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/manifests.ts index cf87461c8924..65b3693975d2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/manifests.ts @@ -5,6 +5,7 @@ import { } from '../../constants.js'; import { UMB_MEDIA_RECYCLE_BIN_ROOT_ENTITY_TYPE, UMB_MEDIA_RECYCLE_BIN_REPOSITORY_ALIAS } from '../constants.js'; import { UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS } from '../../reference/constants.js'; +import { manifests as bulkTrashManifests } from './bulk-trash/manifests.js'; import { UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS, UMB_ENTITY_IS_TRASHED_CONDITION_ALIAS, @@ -55,4 +56,5 @@ export const manifests: Array = [ recycleBinRepositoryAlias: UMB_MEDIA_RECYCLE_BIN_REPOSITORY_ALIAS, }, }, + ...bulkTrashManifests, ]; 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 dddd09efbfac..cbf40a382562 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 @@ -140,7 +140,7 @@ export const foundConsts = [{ }, { path: '@umbraco-cms/backoffice/document', - consts: ["UMB_DOCUMENT_COLLECTION_ALIAS","UMB_DOCUMENT_COLLECTION_CONTEXT","UMB_DOCUMENT_COLLECTION_REPOSITORY_ALIAS","UMB_DOCUMENT_GRID_COLLECTION_VIEW_ALIAS","UMB_DOCUMENT_TABLE_COLLECTION_VIEW_ALIAS","UMB_DOCUMENT_CREATE_OPTIONS_MODAL","UMB_CREATE_BLUEPRINT_MODAL","UMB_DOCUMENT_CREATE_BLUEPRINT_REPOSITORY_ALIAS","UMB_CULTURE_AND_HOSTNAMES_MODAL","UMB_DOCUMENT_CULTURE_AND_HOSTNAMES_REPOSITORY_ALIAS","UMB_DUPLICATE_DOCUMENT_MODAL","UMB_DUPLICATE_DOCUMENT_MODAL_ALIAS","UMB_DUPLICATE_DOCUMENT_REPOSITORY_ALIAS","UMB_MOVE_DOCUMENT_REPOSITORY_ALIAS","UMB_DOCUMENT_NOTIFICATIONS_MODAL","UMB_DOCUMENT_NOTIFICATIONS_MODAL_ALIAS","UMB_DOCUMENT_NOTIFICATIONS_REPOSITORY_ALIAS","UMB_PUBLIC_ACCESS_MODAL","UMB_DOCUMENT_PUBLIC_ACCESS_REPOSITORY_ALIAS","UMB_SORT_CHILDREN_OF_DOCUMENT_REPOSITORY_ALIAS","UMB_BULK_DUPLICATE_DOCUMENT_REPOSITORY_ALIAS","UMB_BULK_MOVE_DOCUMENT_REPOSITORY_ALIAS","UMB_BULK_TRASH_DOCUMENT_REPOSITORY_ALIAS","UMB_DOCUMENT_ENTITY_TYPE","UMB_DOCUMENT_ROOT_ENTITY_TYPE","UMB_DOCUMENT_CONFIGURATION_CONTEXT","UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS","UMB_DOCUMENT_STORE_ALIAS","UMB_DOCUMENT_ITEM_STORE_CONTEXT","UMB_CONTENT_MENU_ALIAS","UMB_DOCUMENT_PICKER_MODAL","UMB_DOCUMENT_SAVE_MODAL","UMB_DOCUMENT_SAVE_MODAL_ALIAS","UMB_DOCUMENT_WORKSPACE_PATH","UMB_CREATE_FROM_BLUEPRINT_DOCUMENT_WORKSPACE_PATH_PATTERN","UMB_CREATE_DOCUMENT_WORKSPACE_PATH_PATTERN","UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN","UMB_DOCUMENT_PROPERTY_DATASET_CONTEXT","UMB_DOCUMENT_PUBLISH_MODAL_ALIAS","UMB_DOCUMENT_PUBLISH_MODAL","UMB_DOCUMENT_PUBLISH_WITH_DESCENDANTS_MODAL_ALIAS","UMB_DOCUMENT_PUBLISH_WITH_DESCENDANTS_MODAL","UMB_DOCUMENT_PUBLISHING_REPOSITORY_ALIAS","UMB_DOCUMENT_SCHEDULE_MODAL_ALIAS","UMB_DOCUMENT_SCHEDULE_MODAL","UMB_DOCUMENT_UNPUBLISH_MODAL_ALIAS","UMB_DOCUMENT_UNPUBLISH_MODAL","UMB_DOCUMENT_PUBLISHING_WORKSPACE_CONTEXT","UMB_DOCUMENT_RECYCLE_BIN_ROOT_ENTITY_TYPE","UMB_DOCUMENT_RECYCLE_BIN_REPOSITORY_ALIAS","UMB_DOCUMENT_RECYCLE_BIN_TREE_REPOSITORY_ALIAS","UMB_DOCUMENT_RECYCLE_BIN_TREE_STORE_ALIAS","UMB_DOCUMENT_RECYCLE_BIN_TREE_ALIAS","UMB_DOCUMENT_RECYCLE_BIN_TREE_STORE_CONTEXT","UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS","UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS","UMB_DOCUMENT_DETAIL_STORE_ALIAS","UMB_DOCUMENT_DETAIL_STORE_CONTEXT","UMB_DOCUMENT_VALIDATION_REPOSITORY_ALIAS","UMB_ROLLBACK_MODAL_ALIAS","UMB_ROLLBACK_MODAL","UMB_ROLLBACK_REPOSITORY_ALIAS","UMB_DOCUMENT_SEARCH_PROVIDER_ALIAS","UMB_DOCUMENT_TREE_STORE_CONTEXT","UMB_DOCUMENT_TREE_REPOSITORY_ALIAS","UMB_DOCUMENT_TREE_STORE_ALIAS","UMB_DOCUMENT_TREE_ALIAS","UMB_DOCUMENT_URL_REPOSITORY_ALIAS","UMB_DOCUMENT_URL_STORE_ALIAS","UMB_DOCUMENT_URL_STORE_CONTEXT","UMB_DOCUMENT_USER_PERMISSION_CONDITION_ALIAS","UMB_USER_PERMISSION_DOCUMENT_CREATE","UMB_USER_PERMISSION_DOCUMENT_READ","UMB_USER_PERMISSION_DOCUMENT_UPDATE","UMB_USER_PERMISSION_DOCUMENT_DELETE","UMB_USER_PERMISSION_DOCUMENT_CREATE_BLUEPRINT","UMB_USER_PERMISSION_DOCUMENT_NOTIFICATIONS","UMB_USER_PERMISSION_DOCUMENT_PUBLISH","UMB_USER_PERMISSION_DOCUMENT_PERMISSIONS","UMB_USER_PERMISSION_DOCUMENT_UNPUBLISH","UMB_USER_PERMISSION_DOCUMENT_DUPLICATE","UMB_USER_PERMISSION_DOCUMENT_MOVE","UMB_USER_PERMISSION_DOCUMENT_SORT","UMB_USER_PERMISSION_DOCUMENT_CULTURE_AND_HOSTNAMES","UMB_USER_PERMISSION_DOCUMENT_PUBLIC_ACCESS","UMB_USER_PERMISSION_DOCUMENT_ROLLBACK","UMB_DOCUMENT_PERMISSION_REPOSITORY_ALIAS","UMB_DOCUMENT_IS_NOT_TRASHED_CONDITION_ALIAS","UMB_DOCUMENT_IS_TRASHED_CONDITION_ALIAS","UMB_DOCUMENT_WORKSPACE_ALIAS","UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD","UMB_DOCUMENT_WORKSPACE_CONTEXT"] + consts: ["UMB_DOCUMENT_COLLECTION_ALIAS","UMB_DOCUMENT_COLLECTION_CONTEXT","UMB_DOCUMENT_COLLECTION_REPOSITORY_ALIAS","UMB_DOCUMENT_GRID_COLLECTION_VIEW_ALIAS","UMB_DOCUMENT_TABLE_COLLECTION_VIEW_ALIAS","UMB_DOCUMENT_CREATE_OPTIONS_MODAL","UMB_CREATE_BLUEPRINT_MODAL","UMB_DOCUMENT_CREATE_BLUEPRINT_REPOSITORY_ALIAS","UMB_CULTURE_AND_HOSTNAMES_MODAL","UMB_DOCUMENT_CULTURE_AND_HOSTNAMES_REPOSITORY_ALIAS","UMB_DUPLICATE_DOCUMENT_MODAL","UMB_DUPLICATE_DOCUMENT_MODAL_ALIAS","UMB_DUPLICATE_DOCUMENT_REPOSITORY_ALIAS","UMB_MOVE_DOCUMENT_REPOSITORY_ALIAS","UMB_DOCUMENT_NOTIFICATIONS_MODAL","UMB_DOCUMENT_NOTIFICATIONS_MODAL_ALIAS","UMB_DOCUMENT_NOTIFICATIONS_REPOSITORY_ALIAS","UMB_PUBLIC_ACCESS_MODAL","UMB_DOCUMENT_PUBLIC_ACCESS_REPOSITORY_ALIAS","UMB_SORT_CHILDREN_OF_DOCUMENT_REPOSITORY_ALIAS","UMB_BULK_DUPLICATE_DOCUMENT_REPOSITORY_ALIAS","UMB_BULK_MOVE_DOCUMENT_REPOSITORY_ALIAS","UMB_DOCUMENT_ENTITY_TYPE","UMB_DOCUMENT_ROOT_ENTITY_TYPE","UMB_DOCUMENT_CONFIGURATION_CONTEXT","UMB_DOCUMENT_ITEM_REPOSITORY_ALIAS","UMB_DOCUMENT_STORE_ALIAS","UMB_DOCUMENT_ITEM_STORE_CONTEXT","UMB_CONTENT_MENU_ALIAS","UMB_DOCUMENT_PICKER_MODAL","UMB_DOCUMENT_SAVE_MODAL","UMB_DOCUMENT_SAVE_MODAL_ALIAS","UMB_DOCUMENT_WORKSPACE_PATH","UMB_CREATE_FROM_BLUEPRINT_DOCUMENT_WORKSPACE_PATH_PATTERN","UMB_CREATE_DOCUMENT_WORKSPACE_PATH_PATTERN","UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN","UMB_DOCUMENT_PROPERTY_DATASET_CONTEXT","UMB_DOCUMENT_PUBLISH_MODAL_ALIAS","UMB_DOCUMENT_PUBLISH_MODAL","UMB_DOCUMENT_PUBLISH_WITH_DESCENDANTS_MODAL_ALIAS","UMB_DOCUMENT_PUBLISH_WITH_DESCENDANTS_MODAL","UMB_DOCUMENT_PUBLISHING_REPOSITORY_ALIAS","UMB_DOCUMENT_SCHEDULE_MODAL_ALIAS","UMB_DOCUMENT_SCHEDULE_MODAL","UMB_DOCUMENT_UNPUBLISH_MODAL_ALIAS","UMB_DOCUMENT_UNPUBLISH_MODAL","UMB_DOCUMENT_PUBLISHING_WORKSPACE_CONTEXT","UMB_DOCUMENT_RECYCLE_BIN_ROOT_ENTITY_TYPE","UMB_BULK_TRASH_DOCUMENT_REPOSITORY_ALIAS","UMB_DOCUMENT_RECYCLE_BIN_REPOSITORY_ALIAS","UMB_DOCUMENT_RECYCLE_BIN_TREE_REPOSITORY_ALIAS","UMB_DOCUMENT_RECYCLE_BIN_TREE_STORE_ALIAS","UMB_DOCUMENT_RECYCLE_BIN_TREE_ALIAS","UMB_DOCUMENT_RECYCLE_BIN_TREE_STORE_CONTEXT","UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS","UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS","UMB_DOCUMENT_DETAIL_STORE_ALIAS","UMB_DOCUMENT_DETAIL_STORE_CONTEXT","UMB_DOCUMENT_VALIDATION_REPOSITORY_ALIAS","UMB_ROLLBACK_MODAL_ALIAS","UMB_ROLLBACK_MODAL","UMB_ROLLBACK_REPOSITORY_ALIAS","UMB_DOCUMENT_SEARCH_PROVIDER_ALIAS","UMB_DOCUMENT_TREE_STORE_CONTEXT","UMB_DOCUMENT_TREE_REPOSITORY_ALIAS","UMB_DOCUMENT_TREE_STORE_ALIAS","UMB_DOCUMENT_TREE_ALIAS","UMB_DOCUMENT_URL_REPOSITORY_ALIAS","UMB_DOCUMENT_URL_STORE_ALIAS","UMB_DOCUMENT_URL_STORE_CONTEXT","UMB_DOCUMENT_USER_PERMISSION_CONDITION_ALIAS","UMB_USER_PERMISSION_DOCUMENT_CREATE","UMB_USER_PERMISSION_DOCUMENT_READ","UMB_USER_PERMISSION_DOCUMENT_UPDATE","UMB_USER_PERMISSION_DOCUMENT_DELETE","UMB_USER_PERMISSION_DOCUMENT_CREATE_BLUEPRINT","UMB_USER_PERMISSION_DOCUMENT_NOTIFICATIONS","UMB_USER_PERMISSION_DOCUMENT_PUBLISH","UMB_USER_PERMISSION_DOCUMENT_PERMISSIONS","UMB_USER_PERMISSION_DOCUMENT_UNPUBLISH","UMB_USER_PERMISSION_DOCUMENT_DUPLICATE","UMB_USER_PERMISSION_DOCUMENT_MOVE","UMB_USER_PERMISSION_DOCUMENT_SORT","UMB_USER_PERMISSION_DOCUMENT_CULTURE_AND_HOSTNAMES","UMB_USER_PERMISSION_DOCUMENT_PUBLIC_ACCESS","UMB_USER_PERMISSION_DOCUMENT_ROLLBACK","UMB_DOCUMENT_PERMISSION_REPOSITORY_ALIAS","UMB_DOCUMENT_IS_NOT_TRASHED_CONDITION_ALIAS","UMB_DOCUMENT_IS_TRASHED_CONDITION_ALIAS","UMB_DOCUMENT_WORKSPACE_ALIAS","UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD","UMB_DOCUMENT_WORKSPACE_CONTEXT"] }, { path: '@umbraco-cms/backoffice/entity-action', @@ -148,7 +148,7 @@ export const foundConsts = [{ }, { path: '@umbraco-cms/backoffice/entity-bulk-action', - consts: ["UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST"] + consts: ["UMB_ENTITY_BULK_ACTION_DELETE_KIND","UMB_ENTITY_BULK_ACTION_DELETE_KIND_MANIFEST","UMB_ENTITY_BULK_ACTION_TRASH_KIND","UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST"] }, { path: '@umbraco-cms/backoffice/entity-create-option-action', @@ -212,7 +212,7 @@ export const foundConsts = [{ }, { path: '@umbraco-cms/backoffice/media', - consts: ["UMB_MEDIA_COLLECTION_ALIAS","UMB_MEDIA_COLLECTION_CONTEXT","UMB_MEDIA_COLLECTION_REPOSITORY_ALIAS","UMB_MEDIA_GRID_COLLECTION_VIEW_ALIAS","UMB_MEDIA_TABLE_COLLECTION_VIEW_ALIAS","UMB_DROPZONE_MEDIA_TYPE_PICKER_MODAL","UMB_MEDIA_CREATE_OPTIONS_MODAL","UMB_MOVE_MEDIA_REPOSITORY_ALIAS","UMB_SORT_CHILDREN_OF_MEDIA_REPOSITORY_ALIAS","UMB_BULK_MOVE_MEDIA_REPOSITORY_ALIAS","UMB_BULK_TRASH_MEDIA_REPOSITORY_ALIAS","UMB_MEDIA_ENTITY_TYPE","UMB_MEDIA_ROOT_ENTITY_TYPE","UMB_MEDIA_PLACEHOLDER_ENTITY_TYPE","UMB_MEDIA_MENU_ALIAS","UMB_IMAGE_CROPPER_EDITOR_MODAL","UMB_MEDIA_CAPTION_ALT_TEXT_MODAL","UMB_MEDIA_PICKER_MODAL","UMB_MEDIA_WORKSPACE_PATH","UMB_CREATE_MEDIA_WORKSPACE_PATH_PATTERN","UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN","UMB_MEDIA_VARIANT_CONTEXT","UMB_MEDIA_RECYCLE_BIN_ROOT_ENTITY_TYPE","UMB_MEDIA_RECYCLE_BIN_REPOSITORY_ALIAS","UMB_MEDIA_RECYCLE_BIN_TREE_REPOSITORY_ALIAS","UMB_MEDIA_RECYCLE_BIN_TREE_STORE_ALIAS","UMB_MEDIA_RECYCLE_BIN_TREE_ALIAS","UMB_MEDIA_RECYCLE_BIN_TREE_STORE_CONTEXT","UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS","UMB_MEDIA_DETAIL_REPOSITORY_ALIAS","UMB_MEDIA_DETAIL_STORE_ALIAS","UMB_MEDIA_DETAIL_STORE_CONTEXT","UMB_MEDIA_ITEM_REPOSITORY_ALIAS","UMB_MEDIA_STORE_ALIAS","UMB_MEDIA_ITEM_STORE_CONTEXT","UMB_MEDIA_VALIDATION_REPOSITORY_ALIAS","UMB_MEDIA_SEARCH_PROVIDER_ALIAS","UMB_MEDIA_TREE_REPOSITORY_ALIAS","UMB_MEDIA_TREE_STORE_ALIAS","UMB_MEDIA_TREE_ALIAS","UMB_MEDIA_TREE_PICKER_MODAL","UMB_MEDIA_TREE_STORE_CONTEXT","UMB_MEDIA_URL_REPOSITORY_ALIAS","UMB_MEDIA_URL_STORE_ALIAS","UMB_MEDIA_URL_STORE_CONTEXT","UMB_MEDIA_WORKSPACE_ALIAS","UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD","UMB_MEDIA_WORKSPACE_CONTEXT"] + consts: ["UMB_MEDIA_COLLECTION_ALIAS","UMB_MEDIA_COLLECTION_CONTEXT","UMB_MEDIA_COLLECTION_REPOSITORY_ALIAS","UMB_MEDIA_GRID_COLLECTION_VIEW_ALIAS","UMB_MEDIA_TABLE_COLLECTION_VIEW_ALIAS","UMB_DROPZONE_MEDIA_TYPE_PICKER_MODAL","UMB_MEDIA_CREATE_OPTIONS_MODAL","UMB_MOVE_MEDIA_REPOSITORY_ALIAS","UMB_SORT_CHILDREN_OF_MEDIA_REPOSITORY_ALIAS","UMB_BULK_MOVE_MEDIA_REPOSITORY_ALIAS","UMB_MEDIA_ENTITY_TYPE","UMB_MEDIA_ROOT_ENTITY_TYPE","UMB_MEDIA_PLACEHOLDER_ENTITY_TYPE","UMB_MEDIA_MENU_ALIAS","UMB_IMAGE_CROPPER_EDITOR_MODAL","UMB_MEDIA_CAPTION_ALT_TEXT_MODAL","UMB_MEDIA_PICKER_MODAL","UMB_MEDIA_WORKSPACE_PATH","UMB_CREATE_MEDIA_WORKSPACE_PATH_PATTERN","UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN","UMB_MEDIA_VARIANT_CONTEXT","UMB_MEDIA_RECYCLE_BIN_ROOT_ENTITY_TYPE","UMB_BULK_TRASH_MEDIA_REPOSITORY_ALIAS","UMB_MEDIA_RECYCLE_BIN_REPOSITORY_ALIAS","UMB_MEDIA_RECYCLE_BIN_TREE_REPOSITORY_ALIAS","UMB_MEDIA_RECYCLE_BIN_TREE_STORE_ALIAS","UMB_MEDIA_RECYCLE_BIN_TREE_ALIAS","UMB_MEDIA_RECYCLE_BIN_TREE_STORE_CONTEXT","UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS","UMB_MEDIA_DETAIL_REPOSITORY_ALIAS","UMB_MEDIA_DETAIL_STORE_ALIAS","UMB_MEDIA_DETAIL_STORE_CONTEXT","UMB_MEDIA_ITEM_REPOSITORY_ALIAS","UMB_MEDIA_STORE_ALIAS","UMB_MEDIA_ITEM_STORE_CONTEXT","UMB_MEDIA_VALIDATION_REPOSITORY_ALIAS","UMB_MEDIA_SEARCH_PROVIDER_ALIAS","UMB_MEDIA_TREE_REPOSITORY_ALIAS","UMB_MEDIA_TREE_STORE_ALIAS","UMB_MEDIA_TREE_ALIAS","UMB_MEDIA_TREE_PICKER_MODAL","UMB_MEDIA_TREE_STORE_CONTEXT","UMB_MEDIA_URL_REPOSITORY_ALIAS","UMB_MEDIA_URL_STORE_ALIAS","UMB_MEDIA_URL_STORE_CONTEXT","UMB_MEDIA_WORKSPACE_ALIAS","UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD","UMB_MEDIA_WORKSPACE_CONTEXT"] }, { path: '@umbraco-cms/backoffice/member-group', @@ -284,7 +284,7 @@ export const foundConsts = [{ }, { path: '@umbraco-cms/backoffice/recycle-bin', - consts: ["UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS","UMB_ENTITY_IS_TRASHED_CONDITION_ALIAS","UMB_IS_TRASHED_ENTITY_CONTEXT","UMB_RESTORE_FROM_RECYCLE_BIN_MODAL","UMB_ENTITY_ACTION_TRASH_KIND_MANIFEST"] + consts: ["UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS","UMB_ENTITY_IS_TRASHED_CONDITION_ALIAS","UMB_IS_TRASHED_ENTITY_CONTEXT","UMB_RESTORE_FROM_RECYCLE_BIN_MODAL","UMB_ENTITY_ACTION_TRASH_KIND_MANIFEST","UMB_ENTITY_BULK_ACTION_TRASH_KIND","UMB_ENTITY_BULK_ACTION_TRASH_KIND_MANIFEST"] }, { path: '@umbraco-cms/backoffice/relation-type', @@ -292,7 +292,7 @@ export const foundConsts = [{ }, { path: '@umbraco-cms/backoffice/relations', - consts: ["UMB_RELATION_COLLECTION_REPOSITORY_ALIAS","UMB_DELETE_WITH_RELATION_CONFIRM_MODAL","UMB_TRASH_WITH_RELATION_CONFIRM_MODAL","UMB_RELATION_ENTITY_TYPE"] + consts: ["UMB_RELATION_COLLECTION_REPOSITORY_ALIAS","UMB_ENTITY_BULK_ACTION_DELETE_WITH_RELATION_KIND","UMB_BULK_DELETE_WITH_RELATION_CONFIRM_MODAL","UMB_ENTITY_BULK_ACTION_TRASH_WITH_RELATION_KIND","UMB_BULK_TRASH_WITH_RELATION_CONFIRM_MODAL","UMB_DELETE_WITH_RELATION_CONFIRM_MODAL","UMB_TRASH_WITH_RELATION_CONFIRM_MODAL","UMB_RELATION_ENTITY_TYPE"] }, { path: '@umbraco-cms/backoffice/repository', From e61d63c9552dc8ecb7351a9cc1c87dfec6e4094e Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 19 Feb 2025 21:21:26 +0100 Subject: [PATCH 136/145] export const --- .../src/packages/core/entity-bulk-action/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts index 97b5f594911e..91126a472751 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/index.ts @@ -8,3 +8,5 @@ export { UMB_ENTITY_BULK_ACTION_DELETE_KIND_MANIFEST, UMB_ENTITY_BULK_ACTION_DELETE_KIND, } from './common/bulk-delete/bulk-delete.action.kind.js'; + +export { UMB_ENTITY_BULK_ACTION_TRASH_KIND } from './common/trash/constants.js'; From b486cf9c2e3d02acf61f9ddfc80d4fdf5a009d44 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 20 Feb 2025 08:49:00 +0100 Subject: [PATCH 137/145] use correct kind --- .../media/recycle-bin/entity-action/bulk-trash/manifests.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/manifests.ts index 79af11ce7847..f1fccda364cc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/recycle-bin/entity-action/bulk-trash/manifests.ts @@ -4,12 +4,12 @@ import { UMB_MEDIA_RECYCLE_BIN_REPOSITORY_ALIAS } from '../../repository/constan import { UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS } from '../../../reference/constants.js'; import { UMB_MEDIA_COLLECTION_ALIAS } from '../../../collection/constants.js'; import { manifests as repositoryManifests } from './repository/manifests.js'; -import { UMB_ENTITY_BULK_ACTION_TRASH_KIND } from '@umbraco-cms/backoffice/recycle-bin'; import { UMB_COLLECTION_ALIAS_CONDITION } from '@umbraco-cms/backoffice/collection'; +import { UMB_ENTITY_BULK_ACTION_TRASH_WITH_RELATION_KIND } from '@umbraco-cms/backoffice/relations'; const bulkTrashAction: UmbExtensionManifest = { type: 'entityBulkAction', - kind: UMB_ENTITY_BULK_ACTION_TRASH_KIND, + kind: UMB_ENTITY_BULK_ACTION_TRASH_WITH_RELATION_KIND, alias: 'Umb.EntityBulkAction.Media.Trash', name: 'Trash Media Entity Bulk Action', weight: 10, From 2b0ceabf0b65fe72ff68c28ab38114e9937ed399 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 20 Feb 2025 09:22:21 +0100 Subject: [PATCH 138/145] align naming --- .../core/repository/data-mapper/data-mapper.ts | 10 +++++----- .../management-api-data-mapper.ts | 4 ++-- .../mapping/data-mapping-resolver.ts | 18 ++++++++---------- .../mapping/data-mapping.extension.ts | 4 ++-- .../document-reference.server.data.ts | 2 +- .../reference/repository/manifests.ts | 4 ++-- .../media/reference/repository/manifests.ts | 4 ++-- .../repository/media-reference.server.data.ts | 2 +- 8 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.ts index 0c192046a423..24de99cdd182 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/data-mapper.ts @@ -2,8 +2,8 @@ import { UmbDataMappingResolver } from './mapping/data-mapping-resolver.js'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; export interface UmbDataMapperMapArgs { - dataModelIdentifier: string; - dataSourceIdentifier: string; + forDataModel: string; + forDataSource: string; data: fromModelType; fallback?: (data: fromModelType) => Promise; } @@ -12,11 +12,11 @@ export class UmbDataMapper exten #dataMappingResolver = new UmbDataMappingResolver(this); async map(args: UmbDataMapperMapArgs) { - if (!args.dataSourceIdentifier) { + if (!args.forDataSource) { throw new Error('data source identifier is required'); } - if (!args.dataModelIdentifier) { + if (!args.forDataModel) { throw new Error('data identifier is required'); } @@ -24,7 +24,7 @@ export class UmbDataMapper exten throw new Error('data is required'); } - const dataMapping = await this.#dataMappingResolver.resolve(args.dataSourceIdentifier, args.dataModelIdentifier); + const dataMapping = await this.#dataMappingResolver.resolve(args.forDataSource, args.forDataModel); if (!dataMapping && !args.fallback) { throw new Error('Data mapping not found and no fallback provided.'); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/management-api-data-mapper.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/management-api-data-mapper.ts index 747b1bcff980..d220ee390dd8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/management-api-data-mapper.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/management-api-data-mapper.ts @@ -10,10 +10,10 @@ export class UmbManagementApiDataMapper extends UmbControllerBase { super(host); } - map(args: Omit) { + map(args: Omit) { return this.#dataMapper.map({ ...args, - dataSourceIdentifier: UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER, + forDataSource: UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER, }); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping-resolver.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping-resolver.ts index bd5523216fff..0f7b1c46e1c1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping-resolver.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping-resolver.ts @@ -6,16 +6,16 @@ import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registr export class UmbDataMappingResolver extends UmbControllerBase { #apiCache = new Map(); - async resolve(dataSourceIdentifier: string, dataModelIdentifier: string): Promise { - if (!dataSourceIdentifier) { + async resolve(forDataSource: string, forDataModel: string): Promise { + if (!forDataSource) { throw new Error('data source identifier is required'); } - if (!dataModelIdentifier) { + if (!forDataModel) { throw new Error('data identifier is required'); } - const manifest = this.#getManifestWithBestFit(dataSourceIdentifier, dataModelIdentifier); + const manifest = this.#getManifestWithBestFit(forDataSource, forDataModel); if (!manifest) { return undefined; @@ -42,8 +42,8 @@ export class UmbDataMappingResolver extends UmbControllerBase { return dataMapping; } - #getManifestWithBestFit(dataSourceIdentifier: string, dataModelIdentifier: string) { - const supportedManifests = this.#getSupportedManifests(dataSourceIdentifier, dataModelIdentifier); + #getManifestWithBestFit(forDataSource: string, forDataModel: string) { + const supportedManifests = this.#getSupportedManifests(forDataSource, forDataModel); if (!supportedManifests.length) { return undefined; @@ -54,11 +54,9 @@ export class UmbDataMappingResolver extends UmbControllerBase { return supportedManifests.sort((a: ManifestBase, b: ManifestBase): number => (b.weight || 0) - (a.weight || 0))[0]; } - #getSupportedManifests(dataSourceIdentifier: string, dataModelIdentifier: string) { + #getSupportedManifests(forDataSource: string, forDataModel: string) { const supportedManifests = umbExtensionsRegistry.getByTypeAndFilter('dataMapping', (manifest) => { - return ( - manifest.dataSourceIdentifier === dataSourceIdentifier && manifest.dataModelIdentifier === dataModelIdentifier - ); + return manifest.forDataSource === forDataSource && manifest.forDataModel === forDataModel; }); return supportedManifests; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping.extension.ts index 47505a748a1f..64e85b272201 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping.extension.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/mapping/data-mapping.extension.ts @@ -4,8 +4,8 @@ import type { ManifestApi } from '@umbraco-cms/backoffice/extension-api'; export interface ManifestDataMapping extends ManifestApi { type: 'dataMapping'; - dataSourceIdentifier: string; - dataModelIdentifier: string; + forDataSource: string; + forDataModel: string; meta: MetaType; } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts index 322ce6fe150c..077394524034 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/document-reference.server.data.ts @@ -25,7 +25,7 @@ export class UmbDocumentReferenceServerDataSource extends UmbControllerBase { if (data) { const promises = data.items.map(async (item) => { return this.#dataMapper.map({ - dataModelIdentifier: item.$type, + forDataModel: item.$type, data: item, fallback: async () => { return { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts index 81955fe4442e..8e2dc6740b88 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts @@ -13,7 +13,7 @@ export const manifests: Array = [ alias: 'Umb.DataMapping.ManagementApi.DocumentReferenceResponse', name: 'Document Reference Response Management Api Data Mapping', api: () => import('./document-reference-response.management-api.mapping.js'), - dataSourceIdentifier: UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER, - dataModelIdentifier: 'DocumentReferenceResponseModel', + forDataSource: UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER, + forDataModel: 'DocumentReferenceResponseModel', }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts index 28d8749c1e7a..c885ccb85c61 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts @@ -13,7 +13,7 @@ export const manifests: Array = [ alias: 'Umb.DataMapping.ManagementApi.MediaReferenceResponse', name: 'Media Reference Response Management Api Data Mapping', api: () => import('./media-reference-response.management-api.mapping.js'), - dataSourceIdentifier: UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER, - dataModelIdentifier: 'MediaReferenceResponseModel', + forDataSource: UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER, + forDataModel: 'MediaReferenceResponseModel', }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts index e05b48fab9c0..5c5eac9ea5bf 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/media-reference.server.data.ts @@ -25,7 +25,7 @@ export class UmbMediaReferenceServerDataSource extends UmbControllerBase { if (data) { const promises = data.items.map(async (item) => { return this.#dataMapper.map({ - dataModelIdentifier: item.$type, + forDataModel: item.$type, data: item, fallback: async () => { return { From d7410a08e1017cb5498bef5c0c69615d76b66dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 20 Feb 2025 15:55:16 +0100 Subject: [PATCH 139/145] upper case Trash --- src/Umbraco.Web.UI.Client/src/assets/lang/en.ts | 2 +- .../core/recycle-bin/entity-action/trash/trash.action.ts | 2 +- .../trash/modal/trash-with-relation-modal.element.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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 0c153a799ccf..675909459358 100644 --- a/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts +++ b/src/Umbraco.Web.UI.Client/src/assets/lang/en.ts @@ -510,7 +510,7 @@ export default { confirmremoveusageof: 'Are you sure you want to remove the usage of %0%', confirmlogout: 'Are you sure?', confirmSure: 'Are you sure?', - confirmtrash: (name: string) => `Are you sure you want to move ${name} to the Recycle Bin?`, + confirmTrash: (name: string) => `Are you sure you want to move ${name} to the Recycle Bin?`, cut: 'Cut', editDictionary: 'Edit dictionary item', editLanguage: 'Edit language', diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts index 69f2fe69b400..bd83e0976d42 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-action/trash/trash.action.ts @@ -41,7 +41,7 @@ export class UmbTrashEntityAction< protected async _confirmTrash(item: any) { const headline = '#actions_trash'; - const message = '#defaultdialogs_confirmtrash'; + const message = '#defaultdialogs_confirmTrash'; // TODO: handle items with variants await umbConfirmModal(this._host, { diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts index 35c2032fd679..61f40cf2bcb2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/trash/modal/trash-with-relation-modal.element.ts @@ -61,7 +61,7 @@ export class UmbTrashWithRelationConfirmModalElement extends UmbModalBaseElement override render() { const headline = this.localize.string('#actions_trash'); - const content = this.localize.string('#defaultdialogs_confirmtrash', this._name); + const content = this.localize.string('#defaultdialogs_confirmTrash', this._name); return html` From 6e3ff8689d2edc5892f244da6e490e14a60efce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 20 Feb 2025 16:32:41 +0100 Subject: [PATCH 140/145] correct uui-text impl --- .../confirm-action-entity-references.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts index 73c8d8b41abe..282d2c29875a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/relations/relations/entity-actions/local-components/confirm-action-entity-references.element.ts @@ -136,7 +136,7 @@ export class UmbConfirmActionModalEntityReferencesElement extends UmbLitElement if (total === 0) return nothing; return html` -
${this.localize.term(headline)}
+
${this.localize.term(headline)}
${items.map( (item) => From 8aed597424d513d932e272f7f01bcd3bc94f197d Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 20 Feb 2025 18:26:54 +0100 Subject: [PATCH 141/145] add comment about the v2 name --- .../entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts index b96fc8edd7b8..1e659cc7e839 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/recycle-bin/entity-bulk-action/bulk-trash/bulk-trash.action.kind.ts @@ -1,7 +1,9 @@ import { UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST } from '@umbraco-cms/backoffice/entity-bulk-action'; import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; -// TODO: v17: rename kind to trash +/* TODO: v17: rename kind to trash + this is named v2 to avoid a name clash. The original trash kind is deprecated. +We have added a constant to try and prevent too big a breaking change when renaming. */ export const UMB_ENTITY_BULK_ACTION_TRASH_KIND = 'trashV2'; export const UMB_ENTITY_BULK_ACTION_TRASH_KIND_MANIFEST: UmbExtensionManifestKind = { From 91f695238dc35f16a8af328bd77b1a6b1e5da3a8 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 21 Feb 2025 09:46:19 +0100 Subject: [PATCH 142/145] fix circular depdendencies --- .../common/bulk-delete/bulk-delete.action.kind.ts | 2 +- .../entity-bulk-action/common/bulk-delete/bulk-delete.action.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.kind.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.kind.ts index 86ab68fdd413..c0a727b3e019 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.kind.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.kind.ts @@ -1,4 +1,4 @@ -import { UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST } from '@umbraco-cms/backoffice/entity-bulk-action'; +import { UMB_ENTITY_BULK_ACTION_DEFAULT_KIND_MANIFEST } from '../../default/default.action.kind.js'; import type { UmbExtensionManifestKind } from '@umbraco-cms/backoffice/extension-registry'; export const UMB_ENTITY_BULK_ACTION_DELETE_KIND = 'delete'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.ts index a4f4a3b2cc21..8da90bffc561 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-bulk-action/common/bulk-delete/bulk-delete.action.ts @@ -1,3 +1,4 @@ +import { UmbEntityBulkActionBase } from '../../entity-bulk-action-base.js'; import type { MetaEntityBulkActionDeleteKind } from './types.js'; import { createExtensionApiByAlias } from '@umbraco-cms/backoffice/extension-registry'; import { umbConfirmModal } from '@umbraco-cms/backoffice/modal'; @@ -7,7 +8,6 @@ import { UmbRequestReloadChildrenOfEntityEvent, UmbRequestReloadStructureForEntityEvent, } from '@umbraco-cms/backoffice/entity-action'; -import { UmbEntityBulkActionBase } from '@umbraco-cms/backoffice/entity-bulk-action'; import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; import { UmbLocalizationController } from '@umbraco-cms/backoffice/localization-api'; import { UMB_ENTITY_CONTEXT, type UmbEntityModel } from '@umbraco-cms/backoffice/entity'; From 6f49a754ba634ad1ba5848f9899fa7d0dd2e1cdd Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 21 Feb 2025 14:50:38 +0100 Subject: [PATCH 143/145] rename const --- .../core/repository/data-mapper/management-api/constants.ts | 2 +- .../data-mapper/management-api/management-api-data-mapper.ts | 4 ++-- .../documents/documents/reference/repository/manifests.ts | 4 ++-- .../packages/media/media/reference/repository/manifests.ts | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/constants.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/constants.ts index 25d3b5812fab..52e1d472b861 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/constants.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/constants.ts @@ -1 +1 @@ -export const UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER = 'Umb.ManagementApi'; +export const UMB_MANAGEMENT_API_DATA_SOURCE_ALIAS = 'Umb.ManagementApi'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/management-api-data-mapper.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/management-api-data-mapper.ts index d220ee390dd8..9df1eb8da1b5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/management-api-data-mapper.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/data-mapper/management-api/management-api-data-mapper.ts @@ -1,5 +1,5 @@ import { UmbDataMapper, type UmbDataMapperMapArgs } from '../data-mapper.js'; -import { UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER } from './constants.js'; +import { UMB_MANAGEMENT_API_DATA_SOURCE_ALIAS } from './constants.js'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; @@ -13,7 +13,7 @@ export class UmbManagementApiDataMapper extends UmbControllerBase { map(args: Omit) { return this.#dataMapper.map({ ...args, - forDataSource: UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER, + forDataSource: UMB_MANAGEMENT_API_DATA_SOURCE_ALIAS, }); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts index 8e2dc6740b88..ce1cd3712f82 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/reference/repository/manifests.ts @@ -1,5 +1,5 @@ import { UMB_DOCUMENT_REFERENCE_REPOSITORY_ALIAS } from './constants.js'; -import { UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER } from '@umbraco-cms/backoffice/repository'; +import { UMB_MANAGEMENT_API_DATA_SOURCE_ALIAS } from '@umbraco-cms/backoffice/repository'; export const manifests: Array = [ { @@ -13,7 +13,7 @@ export const manifests: Array = [ alias: 'Umb.DataMapping.ManagementApi.DocumentReferenceResponse', name: 'Document Reference Response Management Api Data Mapping', api: () => import('./document-reference-response.management-api.mapping.js'), - forDataSource: UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER, + forDataSource: UMB_MANAGEMENT_API_DATA_SOURCE_ALIAS, forDataModel: 'DocumentReferenceResponseModel', }, ]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts index c885ccb85c61..b623096738d7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/reference/repository/manifests.ts @@ -1,5 +1,5 @@ import { UMB_MEDIA_REFERENCE_REPOSITORY_ALIAS } from './constants.js'; -import { UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER } from '@umbraco-cms/backoffice/repository'; +import { UMB_MANAGEMENT_API_DATA_SOURCE_ALIAS } from '@umbraco-cms/backoffice/repository'; export const manifests: Array = [ { @@ -13,7 +13,7 @@ export const manifests: Array = [ alias: 'Umb.DataMapping.ManagementApi.MediaReferenceResponse', name: 'Media Reference Response Management Api Data Mapping', api: () => import('./media-reference-response.management-api.mapping.js'), - forDataSource: UMB_MANAGEMENT_API_DATA_SOURCE_IDENTIFIER, + forDataSource: UMB_MANAGEMENT_API_DATA_SOURCE_ALIAS, forDataModel: 'MediaReferenceResponseModel', }, ]; From 3d62521dd2ed4d95d83d0c48d9566e4ad1584d60 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 21 Feb 2025 15:05:42 +0100 Subject: [PATCH 144/145] split to module --- src/Umbraco.Web.UI.Client/package.json | 1 + .../default-item-ref.element.ts | 0 .../entity-item-ref.element.ts | 4 +- .../entity-item-ref.extension.ts | 0 .../entity-item-ref/index.ts | 0 .../entity-item-ref/types.ts | 0 .../src/packages/core/entity-item/index.ts | 1 + .../src/packages/core/entity-item/types.ts | 5 + .../src/packages/core/entity/index.ts | 1 - .../src/packages/core/entity/types.ts | 4 - .../src/packages/core/vite.config.ts | 1 + src/Umbraco.Web.UI.Client/tsconfig.json | 1 + .../utils/all-umb-consts/imports.ts | 265 +++++++++--------- 13 files changed, 146 insertions(+), 137 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/core/{entity => entity-item}/entity-item-ref/default-item-ref.element.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/core/{entity => entity-item}/entity-item-ref/entity-item-ref.element.ts (98%) rename src/Umbraco.Web.UI.Client/src/packages/core/{entity => entity-item}/entity-item-ref/entity-item-ref.extension.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/core/{entity => entity-item}/entity-item-ref/index.ts (100%) rename src/Umbraco.Web.UI.Client/src/packages/core/{entity => entity-item}/entity-item-ref/types.ts (100%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-item/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-item/types.ts diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index f012dd2ac180..369297a9bb02 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -45,6 +45,7 @@ "./entity-bulk-action": "./dist-cms/packages/core/entity-bulk-action/index.js", "./entity-create-option-action": "./dist-cms/packages/core/entity-create-option-action/index.js", "./entity": "./dist-cms/packages/core/entity/index.js", + "./entity-item": "./dist-cms/packages/core/entity-item/index.js", "./event": "./dist-cms/packages/core/event/index.js", "./extension-registry": "./dist-cms/packages/core/extension-registry/index.js", "./health-check": "./dist-cms/packages/health-check/index.js", diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/default-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/default-item-ref.element.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/default-item-ref.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/default-item-ref.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/entity-item-ref.element.ts similarity index 98% rename from src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/entity-item-ref.element.ts index de07c6a3d5f1..f239f3ebe474 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/entity-item-ref.element.ts @@ -1,13 +1,13 @@ -import type { UmbEntityModel } from '../types.js'; import type { ManifestEntityItemRef } from './entity-item-ref.extension.js'; import { customElement, property, type PropertyValueMap, state, css, html } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbExtensionsElementInitializer } from '@umbraco-cms/backoffice/extension-api'; import { UMB_MARK_ATTRIBUTE_NAME } from '@umbraco-cms/backoffice/const'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; +import { UmbRoutePathAddendumContext } from '@umbraco-cms/backoffice/router'; +import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; import './default-item-ref.element.js'; -import { UmbRoutePathAddendumContext } from '@umbraco-cms/backoffice/router'; @customElement('umb-entity-item-ref') export class UmbEntityItemRefElement extends UmbLitElement { diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.extension.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/entity-item-ref.extension.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/entity-item-ref.extension.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/entity-item-ref.extension.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/index.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/index.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/types.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/core/entity/entity-item-ref/types.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/types.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/index.ts new file mode 100644 index 000000000000..5ada9eda75c7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/index.ts @@ -0,0 +1 @@ +export * from './entity-item-ref/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/types.ts new file mode 100644 index 000000000000..31240f7f67d9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/types.ts @@ -0,0 +1,5 @@ +import type { UmbNamedEntityModel } from '@umbraco-cms/backoffice/entity'; + +export interface UmbDefaultItemModel extends UmbNamedEntityModel { + icon?: string; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/index.ts index 7fbfc9d7f634..737d7bf4828c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/index.ts @@ -1,4 +1,3 @@ export { UMB_ENTITY_CONTEXT } from './entity.context-token.js'; export { UmbEntityContext } from './entity.context.js'; -export * from './entity-item-ref/index.js'; export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity/types.ts index 09ec5529e207..f2fcb7dde994 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity/types.ts @@ -8,7 +8,3 @@ export interface UmbEntityModel { export interface UmbNamedEntityModel extends UmbEntityModel { name: string; } - -export interface UmbDefaultItemModel extends UmbNamedEntityModel { - icon?: string; -} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/vite.config.ts b/src/Umbraco.Web.UI.Client/src/packages/core/vite.config.ts index 893def16fc7f..691e31b0b315 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/vite.config.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/vite.config.ts @@ -26,6 +26,7 @@ export default defineConfig({ 'entity-bulk-action/index': './entity-bulk-action/index.ts', 'entity-create-option-action/index': './entity-create-option-action/index.ts', 'entity/index': './entity/index.ts', + 'entity-item/index': './entity-item/index.ts', 'entry-point': 'entry-point.ts', 'event/index': './event/index.ts', 'extension-registry/index': './extension-registry/index.ts', diff --git a/src/Umbraco.Web.UI.Client/tsconfig.json b/src/Umbraco.Web.UI.Client/tsconfig.json index da094f92b187..512ce70e9a7b 100644 --- a/src/Umbraco.Web.UI.Client/tsconfig.json +++ b/src/Umbraco.Web.UI.Client/tsconfig.json @@ -74,6 +74,7 @@ DON'T EDIT THIS FILE DIRECTLY. It is generated by /devops/tsconfig/index.js "./src/packages/core/entity-create-option-action/index.ts" ], "@umbraco-cms/backoffice/entity": ["./src/packages/core/entity/index.ts"], + "@umbraco-cms/backoffice/entity-item": ["./src/packages/core/entity-item/index.ts"], "@umbraco-cms/backoffice/event": ["./src/packages/core/event/index.ts"], "@umbraco-cms/backoffice/extension-registry": ["./src/packages/core/extension-registry/index.ts"], "@umbraco-cms/backoffice/health-check": ["./src/packages/health-check/index.ts"], diff --git a/src/Umbraco.Web.UI.Client/utils/all-umb-consts/imports.ts b/src/Umbraco.Web.UI.Client/utils/all-umb-consts/imports.ts index 4d0720208b39..0cd1f3878320 100644 --- a/src/Umbraco.Web.UI.Client/utils/all-umb-consts/imports.ts +++ b/src/Umbraco.Web.UI.Client/utils/all-umb-consts/imports.ts @@ -38,71 +38,72 @@ import * as import35 from '@umbraco-cms/backoffice/entity-action'; import * as import36 from '@umbraco-cms/backoffice/entity-bulk-action'; import * as import37 from '@umbraco-cms/backoffice/entity-create-option-action'; import * as import38 from '@umbraco-cms/backoffice/entity'; -import * as import39 from '@umbraco-cms/backoffice/event'; -import * as import40 from '@umbraco-cms/backoffice/extension-registry'; -import * as import41 from '@umbraco-cms/backoffice/health-check'; -import * as import42 from '@umbraco-cms/backoffice/help'; -import * as import43 from '@umbraco-cms/backoffice/icon'; -import * as import44 from '@umbraco-cms/backoffice/id'; -import * as import45 from '@umbraco-cms/backoffice/imaging'; -import * as import46 from '@umbraco-cms/backoffice/language'; -import * as import47 from '@umbraco-cms/backoffice/lit-element'; -import * as import48 from '@umbraco-cms/backoffice/localization'; -import * as import49 from '@umbraco-cms/backoffice/log-viewer'; -import * as import50 from '@umbraco-cms/backoffice/media-type'; -import * as import51 from '@umbraco-cms/backoffice/media'; -import * as import52 from '@umbraco-cms/backoffice/member-group'; -import * as import53 from '@umbraco-cms/backoffice/member-type'; -import * as import54 from '@umbraco-cms/backoffice/member'; -import * as import55 from '@umbraco-cms/backoffice/menu'; -import * as import56 from '@umbraco-cms/backoffice/modal'; -import * as import57 from '@umbraco-cms/backoffice/multi-url-picker'; -import * as import58 from '@umbraco-cms/backoffice/notification'; -import * as import59 from '@umbraco-cms/backoffice/object-type'; -import * as import60 from '@umbraco-cms/backoffice/package'; -import * as import61 from '@umbraco-cms/backoffice/partial-view'; -import * as import62 from '@umbraco-cms/backoffice/picker-input'; -import * as import63 from '@umbraco-cms/backoffice/picker'; -import * as import64 from '@umbraco-cms/backoffice/property-action'; -import * as import65 from '@umbraco-cms/backoffice/property-editor'; -import * as import66 from '@umbraco-cms/backoffice/property-type'; -import * as import67 from '@umbraco-cms/backoffice/property'; -import * as import68 from '@umbraco-cms/backoffice/recycle-bin'; -import * as import69 from '@umbraco-cms/backoffice/relation-type'; -import * as import70 from '@umbraco-cms/backoffice/relations'; -import * as import71 from '@umbraco-cms/backoffice/repository'; -import * as import72 from '@umbraco-cms/backoffice/resources'; -import * as import73 from '@umbraco-cms/backoffice/router'; -import * as import74 from '@umbraco-cms/backoffice/rte'; -import * as import75 from '@umbraco-cms/backoffice/script'; -import * as import76 from '@umbraco-cms/backoffice/search'; -import * as import77 from '@umbraco-cms/backoffice/section'; -import * as import78 from '@umbraco-cms/backoffice/server-file-system'; -import * as import79 from '@umbraco-cms/backoffice/settings'; -import * as import80 from '@umbraco-cms/backoffice/sorter'; -import * as import81 from '@umbraco-cms/backoffice/static-file'; -import * as import82 from '@umbraco-cms/backoffice/store'; -import * as import83 from '@umbraco-cms/backoffice/style'; -import * as import84 from '@umbraco-cms/backoffice/stylesheet'; -import * as import85 from '@umbraco-cms/backoffice/sysinfo'; -import * as import86 from '@umbraco-cms/backoffice/tags'; -import * as import87 from '@umbraco-cms/backoffice/template'; -import * as import88 from '@umbraco-cms/backoffice/temporary-file'; -import * as import89 from '@umbraco-cms/backoffice/themes'; -import * as import90 from '@umbraco-cms/backoffice/tiny-mce'; -import * as import91 from '@umbraco-cms/backoffice/tiptap'; -import * as import92 from '@umbraco-cms/backoffice/translation'; -import * as import93 from '@umbraco-cms/backoffice/tree'; -import * as import94 from '@umbraco-cms/backoffice/ufm'; -import * as import95 from '@umbraco-cms/backoffice/user-change-password'; -import * as import96 from '@umbraco-cms/backoffice/user-group'; -import * as import97 from '@umbraco-cms/backoffice/user-permission'; -import * as import98 from '@umbraco-cms/backoffice/user'; -import * as import99 from '@umbraco-cms/backoffice/utils'; -import * as import100 from '@umbraco-cms/backoffice/validation'; -import * as import101 from '@umbraco-cms/backoffice/variant'; -import * as import102 from '@umbraco-cms/backoffice/webhook'; -import * as import103 from '@umbraco-cms/backoffice/workspace'; +import * as import39 from '@umbraco-cms/backoffice/entity-item'; +import * as import40 from '@umbraco-cms/backoffice/event'; +import * as import41 from '@umbraco-cms/backoffice/extension-registry'; +import * as import42 from '@umbraco-cms/backoffice/health-check'; +import * as import43 from '@umbraco-cms/backoffice/help'; +import * as import44 from '@umbraco-cms/backoffice/icon'; +import * as import45 from '@umbraco-cms/backoffice/id'; +import * as import46 from '@umbraco-cms/backoffice/imaging'; +import * as import47 from '@umbraco-cms/backoffice/language'; +import * as import48 from '@umbraco-cms/backoffice/lit-element'; +import * as import49 from '@umbraco-cms/backoffice/localization'; +import * as import50 from '@umbraco-cms/backoffice/log-viewer'; +import * as import51 from '@umbraco-cms/backoffice/media-type'; +import * as import52 from '@umbraco-cms/backoffice/media'; +import * as import53 from '@umbraco-cms/backoffice/member-group'; +import * as import54 from '@umbraco-cms/backoffice/member-type'; +import * as import55 from '@umbraco-cms/backoffice/member'; +import * as import56 from '@umbraco-cms/backoffice/menu'; +import * as import57 from '@umbraco-cms/backoffice/modal'; +import * as import58 from '@umbraco-cms/backoffice/multi-url-picker'; +import * as import59 from '@umbraco-cms/backoffice/notification'; +import * as import60 from '@umbraco-cms/backoffice/object-type'; +import * as import61 from '@umbraco-cms/backoffice/package'; +import * as import62 from '@umbraco-cms/backoffice/partial-view'; +import * as import63 from '@umbraco-cms/backoffice/picker-input'; +import * as import64 from '@umbraco-cms/backoffice/picker'; +import * as import65 from '@umbraco-cms/backoffice/property-action'; +import * as import66 from '@umbraco-cms/backoffice/property-editor'; +import * as import67 from '@umbraco-cms/backoffice/property-type'; +import * as import68 from '@umbraco-cms/backoffice/property'; +import * as import69 from '@umbraco-cms/backoffice/recycle-bin'; +import * as import70 from '@umbraco-cms/backoffice/relation-type'; +import * as import71 from '@umbraco-cms/backoffice/relations'; +import * as import72 from '@umbraco-cms/backoffice/repository'; +import * as import73 from '@umbraco-cms/backoffice/resources'; +import * as import74 from '@umbraco-cms/backoffice/router'; +import * as import75 from '@umbraco-cms/backoffice/rte'; +import * as import76 from '@umbraco-cms/backoffice/script'; +import * as import77 from '@umbraco-cms/backoffice/search'; +import * as import78 from '@umbraco-cms/backoffice/section'; +import * as import79 from '@umbraco-cms/backoffice/server-file-system'; +import * as import80 from '@umbraco-cms/backoffice/settings'; +import * as import81 from '@umbraco-cms/backoffice/sorter'; +import * as import82 from '@umbraco-cms/backoffice/static-file'; +import * as import83 from '@umbraco-cms/backoffice/store'; +import * as import84 from '@umbraco-cms/backoffice/style'; +import * as import85 from '@umbraco-cms/backoffice/stylesheet'; +import * as import86 from '@umbraco-cms/backoffice/sysinfo'; +import * as import87 from '@umbraco-cms/backoffice/tags'; +import * as import88 from '@umbraco-cms/backoffice/template'; +import * as import89 from '@umbraco-cms/backoffice/temporary-file'; +import * as import90 from '@umbraco-cms/backoffice/themes'; +import * as import91 from '@umbraco-cms/backoffice/tiny-mce'; +import * as import92 from '@umbraco-cms/backoffice/tiptap'; +import * as import93 from '@umbraco-cms/backoffice/translation'; +import * as import94 from '@umbraco-cms/backoffice/tree'; +import * as import95 from '@umbraco-cms/backoffice/ufm'; +import * as import96 from '@umbraco-cms/backoffice/user-change-password'; +import * as import97 from '@umbraco-cms/backoffice/user-group'; +import * as import98 from '@umbraco-cms/backoffice/user-permission'; +import * as import99 from '@umbraco-cms/backoffice/user'; +import * as import100 from '@umbraco-cms/backoffice/utils'; +import * as import101 from '@umbraco-cms/backoffice/validation'; +import * as import102 from '@umbraco-cms/backoffice/variant'; +import * as import103 from '@umbraco-cms/backoffice/webhook'; +import * as import104 from '@umbraco-cms/backoffice/workspace'; export const imports = [ { @@ -262,264 +263,268 @@ import * as import103 from '@umbraco-cms/backoffice/workspace'; package: import38 }, { - path: '@umbraco-cms/backoffice/event', + path: '@umbraco-cms/backoffice/entity-item', package: import39 }, { - path: '@umbraco-cms/backoffice/extension-registry', + path: '@umbraco-cms/backoffice/event', package: import40 }, { - path: '@umbraco-cms/backoffice/health-check', + path: '@umbraco-cms/backoffice/extension-registry', package: import41 }, { - path: '@umbraco-cms/backoffice/help', + path: '@umbraco-cms/backoffice/health-check', package: import42 }, { - path: '@umbraco-cms/backoffice/icon', + path: '@umbraco-cms/backoffice/help', package: import43 }, { - path: '@umbraco-cms/backoffice/id', + path: '@umbraco-cms/backoffice/icon', package: import44 }, { - path: '@umbraco-cms/backoffice/imaging', + path: '@umbraco-cms/backoffice/id', package: import45 }, { - path: '@umbraco-cms/backoffice/language', + path: '@umbraco-cms/backoffice/imaging', package: import46 }, { - path: '@umbraco-cms/backoffice/lit-element', + path: '@umbraco-cms/backoffice/language', package: import47 }, { - path: '@umbraco-cms/backoffice/localization', + path: '@umbraco-cms/backoffice/lit-element', package: import48 }, { - path: '@umbraco-cms/backoffice/log-viewer', + path: '@umbraco-cms/backoffice/localization', package: import49 }, { - path: '@umbraco-cms/backoffice/media-type', + path: '@umbraco-cms/backoffice/log-viewer', package: import50 }, { - path: '@umbraco-cms/backoffice/media', + path: '@umbraco-cms/backoffice/media-type', package: import51 }, { - path: '@umbraco-cms/backoffice/member-group', + path: '@umbraco-cms/backoffice/media', package: import52 }, { - path: '@umbraco-cms/backoffice/member-type', + path: '@umbraco-cms/backoffice/member-group', package: import53 }, { - path: '@umbraco-cms/backoffice/member', + path: '@umbraco-cms/backoffice/member-type', package: import54 }, { - path: '@umbraco-cms/backoffice/menu', + path: '@umbraco-cms/backoffice/member', package: import55 }, { - path: '@umbraco-cms/backoffice/modal', + path: '@umbraco-cms/backoffice/menu', package: import56 }, { - path: '@umbraco-cms/backoffice/multi-url-picker', + path: '@umbraco-cms/backoffice/modal', package: import57 }, { - path: '@umbraco-cms/backoffice/notification', + path: '@umbraco-cms/backoffice/multi-url-picker', package: import58 }, { - path: '@umbraco-cms/backoffice/object-type', + path: '@umbraco-cms/backoffice/notification', package: import59 }, { - path: '@umbraco-cms/backoffice/package', + path: '@umbraco-cms/backoffice/object-type', package: import60 }, { - path: '@umbraco-cms/backoffice/partial-view', + path: '@umbraco-cms/backoffice/package', package: import61 }, { - path: '@umbraco-cms/backoffice/picker-input', + path: '@umbraco-cms/backoffice/partial-view', package: import62 }, { - path: '@umbraco-cms/backoffice/picker', + path: '@umbraco-cms/backoffice/picker-input', package: import63 }, { - path: '@umbraco-cms/backoffice/property-action', + path: '@umbraco-cms/backoffice/picker', package: import64 }, { - path: '@umbraco-cms/backoffice/property-editor', + path: '@umbraco-cms/backoffice/property-action', package: import65 }, { - path: '@umbraco-cms/backoffice/property-type', + path: '@umbraco-cms/backoffice/property-editor', package: import66 }, { - path: '@umbraco-cms/backoffice/property', + path: '@umbraco-cms/backoffice/property-type', package: import67 }, { - path: '@umbraco-cms/backoffice/recycle-bin', + path: '@umbraco-cms/backoffice/property', package: import68 }, { - path: '@umbraco-cms/backoffice/relation-type', + path: '@umbraco-cms/backoffice/recycle-bin', package: import69 }, { - path: '@umbraco-cms/backoffice/relations', + path: '@umbraco-cms/backoffice/relation-type', package: import70 }, { - path: '@umbraco-cms/backoffice/repository', + path: '@umbraco-cms/backoffice/relations', package: import71 }, { - path: '@umbraco-cms/backoffice/resources', + path: '@umbraco-cms/backoffice/repository', package: import72 }, { - path: '@umbraco-cms/backoffice/router', + path: '@umbraco-cms/backoffice/resources', package: import73 }, { - path: '@umbraco-cms/backoffice/rte', + path: '@umbraco-cms/backoffice/router', package: import74 }, { - path: '@umbraco-cms/backoffice/script', + path: '@umbraco-cms/backoffice/rte', package: import75 }, { - path: '@umbraco-cms/backoffice/search', + path: '@umbraco-cms/backoffice/script', package: import76 }, { - path: '@umbraco-cms/backoffice/section', + path: '@umbraco-cms/backoffice/search', package: import77 }, { - path: '@umbraco-cms/backoffice/server-file-system', + path: '@umbraco-cms/backoffice/section', package: import78 }, { - path: '@umbraco-cms/backoffice/settings', + path: '@umbraco-cms/backoffice/server-file-system', package: import79 }, { - path: '@umbraco-cms/backoffice/sorter', + path: '@umbraco-cms/backoffice/settings', package: import80 }, { - path: '@umbraco-cms/backoffice/static-file', + path: '@umbraco-cms/backoffice/sorter', package: import81 }, { - path: '@umbraco-cms/backoffice/store', + path: '@umbraco-cms/backoffice/static-file', package: import82 }, { - path: '@umbraco-cms/backoffice/style', + path: '@umbraco-cms/backoffice/store', package: import83 }, { - path: '@umbraco-cms/backoffice/stylesheet', + path: '@umbraco-cms/backoffice/style', package: import84 }, { - path: '@umbraco-cms/backoffice/sysinfo', + path: '@umbraco-cms/backoffice/stylesheet', package: import85 }, { - path: '@umbraco-cms/backoffice/tags', + path: '@umbraco-cms/backoffice/sysinfo', package: import86 }, { - path: '@umbraco-cms/backoffice/template', + path: '@umbraco-cms/backoffice/tags', package: import87 }, { - path: '@umbraco-cms/backoffice/temporary-file', + path: '@umbraco-cms/backoffice/template', package: import88 }, { - path: '@umbraco-cms/backoffice/themes', + path: '@umbraco-cms/backoffice/temporary-file', package: import89 }, { - path: '@umbraco-cms/backoffice/tiny-mce', + path: '@umbraco-cms/backoffice/themes', package: import90 }, { - path: '@umbraco-cms/backoffice/tiptap', + path: '@umbraco-cms/backoffice/tiny-mce', package: import91 }, { - path: '@umbraco-cms/backoffice/translation', + path: '@umbraco-cms/backoffice/tiptap', package: import92 }, { - path: '@umbraco-cms/backoffice/tree', + path: '@umbraco-cms/backoffice/translation', package: import93 }, { - path: '@umbraco-cms/backoffice/ufm', + path: '@umbraco-cms/backoffice/tree', package: import94 }, { - path: '@umbraco-cms/backoffice/user-change-password', + path: '@umbraco-cms/backoffice/ufm', package: import95 }, { - path: '@umbraco-cms/backoffice/user-group', + path: '@umbraco-cms/backoffice/user-change-password', package: import96 }, { - path: '@umbraco-cms/backoffice/user-permission', + path: '@umbraco-cms/backoffice/user-group', package: import97 }, { - path: '@umbraco-cms/backoffice/user', + path: '@umbraco-cms/backoffice/user-permission', package: import98 }, { - path: '@umbraco-cms/backoffice/utils', + path: '@umbraco-cms/backoffice/user', package: import99 }, { - path: '@umbraco-cms/backoffice/validation', + path: '@umbraco-cms/backoffice/utils', package: import100 }, { - path: '@umbraco-cms/backoffice/variant', + path: '@umbraco-cms/backoffice/validation', package: import101 }, { - path: '@umbraco-cms/backoffice/webhook', + path: '@umbraco-cms/backoffice/variant', package: import102 }, { - path: '@umbraco-cms/backoffice/workspace', + path: '@umbraco-cms/backoffice/webhook', package: import103 + }, +{ + path: '@umbraco-cms/backoffice/workspace', + package: import104 } ]; \ No newline at end of file From 9339a6e12949c2ba36663d35ff9fbbbba3fac0b3 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 21 Feb 2025 15:13:13 +0100 Subject: [PATCH 145/145] import global components --- .../core/entity-item/entity-item-ref/global-components.ts | 1 + .../src/packages/core/entity-item/entity-item-ref/index.ts | 2 -- .../src/packages/core/entity-item/global-components.ts | 1 + src/Umbraco.Web.UI.Client/src/packages/core/entry-point.ts | 1 + 4 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/global-components.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-item/global-components.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/global-components.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/global-components.ts new file mode 100644 index 000000000000..b04a6b66a05e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/global-components.ts @@ -0,0 +1 @@ +import './entity-item-ref.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/index.ts index 338849e06997..0dfe5acf102a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/entity-item-ref/index.ts @@ -1,3 +1 @@ -import './entity-item-ref.element.js'; - export * from './entity-item-ref.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/global-components.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/global-components.ts new file mode 100644 index 000000000000..a518da723360 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/global-components.ts @@ -0,0 +1 @@ +import './entity-item-ref/global-components.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entry-point.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entry-point.ts index df77e8a18b13..cf71700dced6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entry-point.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entry-point.ts @@ -9,6 +9,7 @@ import { UmbExtensionsApiInitializer, type UmbEntryPointOnInit } from '@umbraco- import './property-action/components/index.js'; import './menu/components/index.js'; import './extension-registry/components/index.js'; +import './entity-item/global-components.js'; export const onInit: UmbEntryPointOnInit = (host, extensionRegistry) => { new UmbExtensionsApiInitializer(host, extensionRegistry, 'globalContext', [host]);