From 724cda740f2abc80994b989b4262fd3f53219920 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 17 Jan 2025 12:28:20 +0100 Subject: [PATCH 01/27] remove condition in manifest --- .../documents/rollback/entity-action/manifests.ts | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/entity-action/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/entity-action/manifests.ts index 83800af9fa..14ba979d3e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/entity-action/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/entity-action/manifests.ts @@ -1,9 +1,4 @@ -import { - UMB_USER_PERMISSION_DOCUMENT_ROLLBACK, - UMB_DOCUMENT_ENTITY_TYPE, - UMB_DOCUMENT_WORKSPACE_ALIAS, -} from '../../constants.js'; -import { UMB_WORKSPACE_CONDITION_ALIAS } from '@umbraco-cms/backoffice/workspace'; +import { UMB_USER_PERMISSION_DOCUMENT_ROLLBACK, UMB_DOCUMENT_ENTITY_TYPE } from '../../constants.js'; import { UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS } from '@umbraco-cms/backoffice/recycle-bin'; export const manifests: Array = [ @@ -27,12 +22,6 @@ export const manifests: Array = [ { alias: UMB_ENTITY_IS_NOT_TRASHED_CONDITION_ALIAS, }, - /* Currently the rollback is tightly coupled to the workspace contexts so we only allow it to show up - In the document workspace. */ - { - alias: UMB_WORKSPACE_CONDITION_ALIAS, - match: UMB_DOCUMENT_WORKSPACE_ALIAS, - }, ], }, ]; From a271822f027955e920350603a79fef9d8ca423ec Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 17 Jan 2025 13:25:09 +0100 Subject: [PATCH 02/27] wip decouple of workspace --- .../rollback/modal/rollback-modal.element.ts | 81 ++++++++++++++----- 1 file changed, 61 insertions(+), 20 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts index c8949086cc..ee13207b04 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts @@ -1,5 +1,7 @@ -import { UMB_DOCUMENT_WORKSPACE_CONTEXT, UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN } from '../../constants.js'; +import type { UMB_DOCUMENT_WORKSPACE_CONTEXT } from '../../constants.js'; +import { UMB_DOCUMENT_ENTITY_TYPE, UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN } from '../../constants.js'; import { UmbRollbackRepository } from '../repository/rollback.repository.js'; +import { UmbDocumentItemRepository, type UmbDocumentItemModel } from '../../repository/index.js'; import type { UmbRollbackModalData, UmbRollbackModalValue } from './types.js'; import { diffWords, type Change } from '@umbraco-cms/backoffice/external/diff'; import { css, customElement, html, nothing, repeat, state, unsafeHTML } from '@umbraco-cms/backoffice/external/lit'; @@ -8,6 +10,9 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbUserItemRepository } from '@umbraco-cms/backoffice/user'; import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property'; import type { UUISelectEvent } from '@umbraco-cms/backoffice/external/uui'; +import { UMB_APP_LANGUAGE_CONTEXT } from '@umbraco-cms/backoffice/language'; +import { UMB_ENTITY_CONTEXT, type UmbEntityUnique } from '@umbraco-cms/backoffice/entity'; +import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import '../../modals/shared/document-variant-language-picker.element.js'; @@ -42,13 +47,13 @@ export class UmbRollbackModalElement extends UmbModalBaseElement { - this.#propertyDatasetContext = instance; - this.currentCulture = instance.getVariantId().culture ?? undefined; - this.#requestVersions(); + this.#currentDatasetCulture = instance.getVariantId().culture ?? undefined; + this.#setCurrentCulture(); }); - this.consumeContext(UMB_DOCUMENT_WORKSPACE_CONTEXT, (instance) => { - this.#workspaceContext = instance; + this.consumeContext(UMB_APP_LANGUAGE_CONTEXT, (instance) => { + this.#currentAppCulture = instance.getAppCulture(); + this.#setCurrentCulture(); + }); - this.observe(instance.variantOptions, (options) => { - this.availableVariants = options.map((option) => { + this.consumeContext(UMB_ENTITY_CONTEXT, async (instance) => { + if (instance.getEntityType() !== UMB_DOCUMENT_ENTITY_TYPE) { + throw new Error(`Entity type is not ${UMB_DOCUMENT_ENTITY_TYPE}`); + } + + this.#documentUnique = instance?.getUnique(); + + if (!this.#documentUnique) { + throw new Error('Document unique is not set'); + } + + const { data: documentItems } = await new UmbDocumentItemRepository(this).requestItems([this.#documentUnique]); + this.#documentItem = documentItems?.[0]; + const itemVariants = this.#documentItem?.variants ?? []; + + this.isInvariant = itemVariants.length === 1 && new UmbVariantId(itemVariants[0].culture).isInvariant(); + this.#setCurrentCulture(); + + this.availableVariants = itemVariants + .filter((variant) => { + return variant.culture !== null; + }) + .map((variant) => { + const culture = variant.culture as string; return { - name: option.language.name, - value: option.language.unique, - selected: option.language.unique === this.currentCulture, + name: culture, + value: culture, + selected: variant.culture === this.currentCulture, }; }); - }); + + this.#requestVersions(); }); } + #setCurrentCulture() { + this.currentCulture = this.isInvariant ? undefined : (this.#currentDatasetCulture ?? this.#currentAppCulture); + } + async #requestVersions() { - if (!this.#propertyDatasetContext) return; + if (!this.#documentUnique) { + throw new Error('Document unique is not set'); + } - const documentId = this.#propertyDatasetContext.getUnique(); - if (!documentId) return; - - const { data } = await this.#rollbackRepository.requestVersionsByDocumentId(documentId, this.currentCulture); + const { data } = await this.#rollbackRepository.requestVersionsByDocumentId( + this.#documentUnique, + this.currentCulture, + ); if (!data) return; const tempItems: DocumentVersion[] = []; @@ -145,6 +185,7 @@ export class UmbRollbackModalElement extends UmbModalBaseElement 1 ? this.currentCulture : undefined; this.#rollbackRepository.rollback(id, culture); + debugger; const docUnique = this.#workspaceContext?.getUnique() ?? ''; // TODO Use the load method on the context instead of location.href, when it works. From 6d31a0ae6c846794058a5ffbb5beb5501ed3e49f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 27 Jan 2025 12:39:39 +0100 Subject: [PATCH 03/27] get name from language --- .../rollback/modal/rollback-modal.element.ts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts index ee13207b04..2c6a6b6903 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts @@ -10,7 +10,7 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbUserItemRepository } from '@umbraco-cms/backoffice/user'; import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property'; import type { UUISelectEvent } from '@umbraco-cms/backoffice/external/uui'; -import { UMB_APP_LANGUAGE_CONTEXT } from '@umbraco-cms/backoffice/language'; +import { UMB_APP_LANGUAGE_CONTEXT, UmbLanguageItemRepository } from '@umbraco-cms/backoffice/language'; import { UMB_ENTITY_CONTEXT, type UmbEntityUnique } from '@umbraco-cms/backoffice/entity'; import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; @@ -97,18 +97,20 @@ export class UmbRollbackModalElement extends UmbModalBaseElement { - return variant.culture !== null; - }) - .map((variant) => { - const culture = variant.culture as string; + const cultures = itemVariants.map((x) => x.culture).filter((x) => x !== null) as string[]; + const { data: languageItems } = await new UmbLanguageItemRepository(this).requestItems(cultures); + + if (languageItems) { + this.availableVariants = languageItems.map((language) => { return { - name: culture, - value: culture, - selected: variant.culture === this.currentCulture, + name: language.name, + value: language.unique, + selected: language.unique === this.currentCulture, }; }); + } else { + this.availableVariants = []; + } this.#requestVersions(); }); @@ -185,7 +187,6 @@ export class UmbRollbackModalElement extends UmbModalBaseElement 1 ? this.currentCulture : undefined; this.#rollbackRepository.rollback(id, culture); - debugger; const docUnique = this.#workspaceContext?.getUnique() ?? ''; // TODO Use the load method on the context instead of location.href, when it works. @@ -222,7 +223,6 @@ export class UmbRollbackModalElement extends UmbModalBaseElement ${this.localize.term('general_language')} From 4988162b3663bd838cf4e2532e732b1aabd2794f Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 27 Jan 2025 12:53:12 +0100 Subject: [PATCH 04/27] update naming --- .../rollback/modal/rollback-modal.element.ts | 57 +++++++++---------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts index 2c6a6b6903..362770e301 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts @@ -30,7 +30,7 @@ export class UmbRollbackModalElement extends UmbModalBaseElement { this.#currentDatasetCulture = instance.getVariantId().culture ?? undefined; - this.#setCurrentCulture(); + this.#selectCulture(); }); this.consumeContext(UMB_APP_LANGUAGE_CONTEXT, (instance) => { this.#currentAppCulture = instance.getAppCulture(); - this.#setCurrentCulture(); + this.#selectCulture(); }); this.consumeContext(UMB_ENTITY_CONTEXT, async (instance) => { @@ -95,7 +95,7 @@ export class UmbRollbackModalElement extends UmbModalBaseElement x.culture).filter((x) => x !== null) as string[]; const { data: languageItems } = await new UmbLanguageItemRepository(this).requestItems(cultures); @@ -105,7 +105,7 @@ export class UmbRollbackModalElement extends UmbModalBaseElement item.isCurrentlyPublishedVersion)?.id; if (id) { - this.#setCurrentVersion(id); + this.#selectVersion(id); } } - async #setCurrentVersion(id: string) { + async #selectVersion(id: string) { const version = this.versions.find((item) => item.id === id); if (!version) return; const { data } = await this.#rollbackRepository.requestVersionById(id); if (!data) return; - this.currentVersion = { + this.selectedVersion = { date: version.date, user: version.user, - name: data.variants.find((x) => x.culture === this.currentCulture)?.name || data.variants[0].name, + name: data.variants.find((x) => x.culture === this.selectedCulture)?.name || data.variants[0].name, id: data.id, properties: data.values - .filter((x) => x.culture === this.currentCulture || !x.culture) // When invariant, culture is undefined or null. + .filter((x) => x.culture === this.selectedCulture || !x.culture) // When invariant, culture is undefined or null. .map((value: any) => { return { alias: value.alias, @@ -182,10 +182,10 @@ export class UmbRollbackModalElement extends UmbModalBaseElement 1 ? this.currentCulture : undefined; + const id = this.selectedVersion.id; + const culture = this.availableVariants.length > 1 ? this.selectedCulture : undefined; this.#rollbackRepository.rollback(id, culture); const docUnique = this.#workspaceContext?.getUnique() ?? ''; @@ -200,7 +200,7 @@ export class UmbRollbackModalElement extends UmbModalBaseElement this.#onVersionClicked(item.id)} @keydown=${() => {}} - class="rollback-item ${this.currentVersion?.id === item.id ? 'active' : ''}"> + class="rollback-item ${this.selectedVersion?.id === item.id ? 'active' : ''}">

@@ -262,20 +262,19 @@ export class UmbRollbackModalElement extends UmbModalBaseElement) ?? []; + let currentPropertyValues = this.#workspaceContext?.getData()?.values ?? []; - draftValues = draftValues.filter((x) => x.culture === this.currentCulture || !x.culture); // When invariant, culture is undefined or null. + currentPropertyValues = currentPropertyValues.filter((x) => x.culture === this.selectedCulture || !x.culture); // When invariant, culture is undefined or null. const diffs: Array<{ alias: string; diff: Change[] }> = []; - const nameDiff = diffWords(this.#workspaceContext?.getName() ?? '', this.currentVersion.name); + const nameDiff = diffWords(this.#workspaceContext?.getName() ?? '', this.selectedVersion.name); diffs.push({ alias: 'name', diff: nameDiff }); - this.currentVersion.properties.forEach((item) => { - const draftValue = draftValues.find((x) => x.alias === item.alias); + this.selectedVersion.properties.forEach((item) => { + const draftValue = currentPropertyValues.find((x) => x.alias === item.alias); if (!draftValue) return; @@ -333,9 +332,9 @@ export class UmbRollbackModalElement extends UmbModalBaseElement Date: Mon, 27 Jan 2025 13:02:50 +0100 Subject: [PATCH 05/27] extract logic from rendering --- .../rollback/modal/rollback-modal.element.ts | 61 +++++++++++++------ 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts index 362770e301..f458285cf1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts @@ -1,7 +1,11 @@ -import type { UMB_DOCUMENT_WORKSPACE_CONTEXT } from '../../constants.js'; +import { UMB_DOCUMENT_WORKSPACE_CONTEXT } from '../../constants.js'; import { UMB_DOCUMENT_ENTITY_TYPE, UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN } from '../../constants.js'; import { UmbRollbackRepository } from '../repository/rollback.repository.js'; -import { UmbDocumentItemRepository, type UmbDocumentItemModel } from '../../repository/index.js'; +import { + UmbDocumentDetailRepository, + UmbDocumentItemRepository, + type UmbDocumentItemModel, +} from '../../repository/index.js'; import type { UmbRollbackModalData, UmbRollbackModalValue } from './types.js'; import { diffWords, type Change } from '@umbraco-cms/backoffice/external/diff'; import { css, customElement, html, nothing, repeat, state, unsafeHTML } from '@umbraco-cms/backoffice/external/lit'; @@ -50,6 +54,9 @@ export class UmbRollbackModalElement extends UmbModalBaseElement = []; + #rollbackRepository = new UmbRollbackRepository(this); #userItemRepository = new UmbUserItemRepository(this); #workspaceContext?: typeof UMB_DOCUMENT_WORKSPACE_CONTEXT.TYPE; @@ -69,6 +76,10 @@ export class UmbRollbackModalElement extends UmbModalBaseElement { + this.#workspaceContext = instance; + }); + this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, (instance) => { this.#currentDatasetCulture = instance.getVariantId().culture ?? undefined; this.#selectCulture(); @@ -179,6 +190,8 @@ export class UmbRollbackModalElement extends UmbModalBaseElement @@ -261,12 +278,26 @@ export class UmbRollbackModalElement extends UmbModalBaseElement x.culture === this.selectedCulture || !x.culture); // When invariant, culture is undefined or null. + if (this.#workspaceContext) { + newestPropertyValues = this.#workspaceContext?.getData()?.values ?? []; + } else { + if (!this.#documentUnique) { + throw new Error('Document unique is not set'); + } + + const repo = new UmbDocumentDetailRepository(this); + const { data } = await repo.requestByUnique(this.#documentUnique); + if (!data) return; + + newestPropertyValues = data.values; + } + + newestPropertyValues = newestPropertyValues.filter((x) => x.culture === this.selectedCulture || !x.culture); // When invariant, culture is undefined or null. const diffs: Array<{ alias: string; diff: Change[] }> = []; @@ -274,25 +305,21 @@ export class UmbRollbackModalElement extends UmbModalBaseElement { - const draftValue = currentPropertyValues.find((x) => x.alias === item.alias); + const draftValue = newestPropertyValues.find((x) => x.alias === item.alias); if (!draftValue) return; - const draftValueString = trimQuotes(JSON.stringify(draftValue.value)); - const versionValueString = trimQuotes(JSON.stringify(item.value)); + const draftValueString = this.#trimQuotes(JSON.stringify(draftValue.value)); + const versionValueString = this.#trimQuotes(JSON.stringify(item.value)); const diff = diffWords(draftValueString, versionValueString); diffs.push({ alias: item.alias, diff }); }); - /** - * - * @param str - */ - function trimQuotes(str: string): string { - return str.replace(/^['"]|['"]$/g, ''); - } + this._diffs = [...diffs]; + } + #renderCurrentVersion() { return html` ${unsafeHTML(this.localize.term('rollback_diffHelp'))} @@ -304,10 +331,10 @@ export class UmbRollbackModalElement extends UmbModalBaseElement${this.localize.term('general_value')} ${repeat( - diffs, + this._diffs, (item) => item.alias, (item) => { - const diff = diffs.find((x) => x?.alias === item.alias); + const diff = this._diffs.find((x) => x?.alias === item.alias); return html` ${item.alias} From 7e68573628195e2886de8793d6c3e2eabd650b38 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 27 Jan 2025 13:51:33 +0100 Subject: [PATCH 06/27] support invariant documents --- .../rollback/modal/rollback-modal.element.ts | 123 ++++++++---------- 1 file changed, 54 insertions(+), 69 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts index f458285cf1..a4a9e3a482 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts @@ -1,11 +1,7 @@ -import { UMB_DOCUMENT_WORKSPACE_CONTEXT } from '../../constants.js'; -import { UMB_DOCUMENT_ENTITY_TYPE, UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN } from '../../constants.js'; +import { UMB_DOCUMENT_ENTITY_TYPE } from '../../constants.js'; import { UmbRollbackRepository } from '../repository/rollback.repository.js'; -import { - UmbDocumentDetailRepository, - UmbDocumentItemRepository, - type UmbDocumentItemModel, -} from '../../repository/index.js'; +import { UmbDocumentDetailRepository } from '../../repository/index.js'; +import type { UmbDocumentDetailModel } from '../../types.js'; import type { UmbRollbackModalData, UmbRollbackModalValue } from './types.js'; import { diffWords, type Change } from '@umbraco-cms/backoffice/external/diff'; import { css, customElement, html, nothing, repeat, state, unsafeHTML } from '@umbraco-cms/backoffice/external/lit'; @@ -31,10 +27,10 @@ type DocumentVersion = { @customElement('umb-rollback-modal') export class UmbRollbackModalElement extends UmbModalBaseElement { @state() - versions: DocumentVersion[] = []; + _versions: DocumentVersion[] = []; @state() - selectedVersion?: { + _selectedVersion?: { date: string; name: string; user: string; @@ -46,20 +42,19 @@ export class UmbRollbackModalElement extends UmbModalBaseElement = []; #rollbackRepository = new UmbRollbackRepository(this); #userItemRepository = new UmbUserItemRepository(this); - #workspaceContext?: typeof UMB_DOCUMENT_WORKSPACE_CONTEXT.TYPE; #localizeDateOptions: Intl.DateTimeFormatOptions = { day: 'numeric', @@ -68,18 +63,13 @@ export class UmbRollbackModalElement extends UmbModalBaseElement { - this.#workspaceContext = instance; - }); - this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, (instance) => { this.#currentDatasetCulture = instance.getVariantId().culture ?? undefined; this.#selectCulture(); @@ -95,32 +85,34 @@ export class UmbRollbackModalElement extends UmbModalBaseElement x.culture).filter((x) => x !== null) as string[]; const { data: languageItems } = await new UmbLanguageItemRepository(this).requestItems(cultures); if (languageItems) { - this.availableVariants = languageItems.map((language) => { + this._availableVariants = languageItems.map((language) => { return { name: language.name, value: language.unique, - selected: language.unique === this.selectedCulture, + selected: language.unique === this._selectedCulture, }; }); } else { - this.availableVariants = []; + this._availableVariants = []; } this.#requestVersions(); @@ -128,17 +120,18 @@ export class UmbRollbackModalElement extends UmbModalBaseElement item.isCurrentlyPublishedVersion)?.id; if (id) { @@ -170,19 +163,19 @@ export class UmbRollbackModalElement extends UmbModalBaseElement item.id === id); + const version = this._versions.find((item) => item.id === id); if (!version) return; const { data } = await this.#rollbackRepository.requestVersionById(id); if (!data) return; - this.selectedVersion = { + this._selectedVersion = { date: version.date, user: version.user, - name: data.variants.find((x) => x.culture === this.selectedCulture)?.name || data.variants[0].name, + name: data.variants.find((x) => x.culture === this._selectedCulture)?.name || data.variants[0].name, id: data.id, properties: data.values - .filter((x) => x.culture === this.selectedCulture || !x.culture) // When invariant, culture is undefined or null. + .filter((x) => x.culture === this._selectedCulture || !x.culture) // When invariant, culture is undefined or null. .map((value: any) => { return { alias: value.alias, @@ -195,16 +188,12 @@ export class UmbRollbackModalElement extends UmbModalBaseElement 1 ? this.selectedCulture : undefined; + const id = this._selectedVersion.id; + const culture = this._selectedCulture ?? undefined; this.#rollbackRepository.rollback(id, culture); - const docUnique = this.#workspaceContext?.getUnique() ?? ''; - // TODO Use the load method on the context instead of location.href, when it works. - // this.#workspaceContext?.load(docUnique); - location.href = UMB_EDIT_DOCUMENT_WORKSPACE_PATH_PATTERN.generateAbsolute({ unique: docUnique }); this.modalContext?.reject(); } @@ -221,7 +210,7 @@ export class UmbRollbackModalElement extends UmbModalBaseElement item.id === id); + const version = this._versions.find((item) => item.id === id); if (!version) return; version.preventCleanup = preventCleanup; @@ -231,7 +220,7 @@ export class UmbRollbackModalElement extends UmbModalBaseElement ${this.localize.term('general_language')} - +

`; } @@ -251,14 +240,14 @@ export class UmbRollbackModalElement extends UmbModalBaseElement item.id, (item) => { return html`
this.#onVersionClicked(item.id)} @keydown=${() => {}} - class="rollback-item ${this.selectedVersion?.id === item.id ? 'active' : ''}"> + class="rollback-item ${this._selectedVersion?.id === item.id ? 'active' : ''}">

@@ -279,33 +268,29 @@ export class UmbRollbackModalElement extends UmbModalBaseElement x.culture === this._selectedCulture || !x.culture, + ); // When invariant, culture is undefined or null. - if (this.#workspaceContext) { - newestPropertyValues = this.#workspaceContext?.getData()?.values ?? []; - } else { - if (!this.#documentUnique) { - throw new Error('Document unique is not set'); - } - - const repo = new UmbDocumentDetailRepository(this); - const { data } = await repo.requestByUnique(this.#documentUnique); - if (!data) return; - - newestPropertyValues = data.values; + if (!currentPropertyValues) { + throw new Error('Current property values are not set'); } - newestPropertyValues = newestPropertyValues.filter((x) => x.culture === this.selectedCulture || !x.culture); // When invariant, culture is undefined or null. + const currentName = this.#currentDocument?.variants.find((x) => x.culture === this._selectedCulture)?.name; + + if (!currentName) { + throw new Error('Current name is not set'); + } const diffs: Array<{ alias: string; diff: Change[] }> = []; - const nameDiff = diffWords(this.#workspaceContext?.getName() ?? '', this.selectedVersion.name); + const nameDiff = diffWords(currentName, this._selectedVersion.name); diffs.push({ alias: 'name', diff: nameDiff }); - this.selectedVersion.properties.forEach((item) => { - const draftValue = newestPropertyValues.find((x) => x.alias === item.alias); + this._selectedVersion.properties.forEach((item) => { + const draftValue = currentPropertyValues.find((x) => x.alias === item.alias); if (!draftValue) return; @@ -359,9 +344,9 @@ export class UmbRollbackModalElement extends UmbModalBaseElement Date: Mon, 27 Jan 2025 14:06:17 +0100 Subject: [PATCH 07/27] styling adjustments --- .../rollback/modal/rollback-modal.element.ts | 47 ++++++++++++------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts index a4a9e3a482..44f63f7c55 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts @@ -229,17 +229,18 @@ export class UmbRollbackModalElement extends UmbModalBaseElement - ${this.localize.term('general_language')} - -

+ `; } #renderVersions() { - return html` ${this.#renderCultureSelect()} - ${repeat( + return html` ${repeat( this._versions, (item) => item.id, (item) => { @@ -354,9 +355,14 @@ export class UmbRollbackModalElement extends UmbModalBaseElement
- -
${this.#renderVersions()}
-
+
+ + ${this.#renderCultureSelect()} + + + ${this.#renderVersions()} + +
${this.#renderCurrentVersion()}
@@ -381,14 +387,15 @@ export class UmbRollbackModalElement extends UmbModalBaseElement Date: Mon, 27 Jan 2025 14:13:43 +0100 Subject: [PATCH 08/27] Update rollback-modal.element.ts hide box if there are no cultures --- .../rollback/modal/rollback-modal.element.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts index 44f63f7c55..2cca09b470 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts @@ -11,7 +11,7 @@ import { UmbUserItemRepository } from '@umbraco-cms/backoffice/user'; import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property'; import type { UUISelectEvent } from '@umbraco-cms/backoffice/external/uui'; import { UMB_APP_LANGUAGE_CONTEXT, UmbLanguageItemRepository } from '@umbraco-cms/backoffice/language'; -import { UMB_ENTITY_CONTEXT, type UmbEntityUnique } from '@umbraco-cms/backoffice/entity'; +import { UMB_ENTITY_CONTEXT } from '@umbraco-cms/backoffice/entity'; import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import '../../modals/shared/document-variant-language-picker.element.js'; @@ -229,8 +229,6 @@ export class UmbRollbackModalElement extends UmbModalBaseElement
- - ${this.#renderCultureSelect()} - + ${this._availableVariants.length + ? html` + + ${this.#renderCultureSelect()} + + ` + : nothing} ${this.#renderVersions()} From a68ff52bae04b5accb45448c5bfdf9dc21a9376b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 27 Jan 2025 14:13:51 +0100 Subject: [PATCH 09/27] change weight --- .../documents/documents/rollback/entity-action/manifests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/entity-action/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/entity-action/manifests.ts index 14ba979d3e..2f736381e6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/entity-action/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/entity-action/manifests.ts @@ -7,7 +7,7 @@ export const manifests: Array = [ kind: 'default', alias: 'Umb.EntityAction.Document.Rollback', name: 'Rollback Document Entity Action', - weight: 500, + weight: 450, api: () => import('./rollback.action.js'), forEntityTypes: [UMB_DOCUMENT_ENTITY_TYPE], meta: { From 1048234d806b723006c9fe45d630efcfdcb9b9e9 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 27 Jan 2025 15:45:19 +0100 Subject: [PATCH 10/27] reload workspace on entity detail updated event --- .../entity-detail-updated.event.ts | 10 +++++++ .../src/packages/core/entity-action/index.ts | 1 + .../rollback/modal/rollback-modal.element.ts | 25 ++++++++++++++-- .../workspace/document-workspace.context.ts | 29 +++++++++++++++++++ 4 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-detail-updated.event.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-detail-updated.event.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-detail-updated.event.ts new file mode 100644 index 0000000000..259e3ed458 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-detail-updated.event.ts @@ -0,0 +1,10 @@ +import type { UmbEntityActionEventArgs } from './entity-action.event.js'; +import { UmbEntityActionEvent } from './entity-action.event.js'; + +export class UmbEntityDetailUpdatedEvent extends UmbEntityActionEvent { + static readonly TYPE = 'entity-detail-updated'; + + constructor(args: UmbEntityActionEventArgs) { + super(UmbEntityDetailUpdatedEvent.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 4347644d1f..a1f34f7ee9 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 @@ -5,6 +5,7 @@ export * from './constants.js'; export * from './entity-action-base.js'; export * from './entity-action-list.element.js'; export * from './entity-action.event.js'; +export * from './entity-detail-updated.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/documents/documents/rollback/modal/rollback-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts index 2cca09b470..574434848b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts @@ -15,6 +15,11 @@ import { UMB_ENTITY_CONTEXT } from '@umbraco-cms/backoffice/entity'; import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import '../../modals/shared/document-variant-language-picker.element.js'; +import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; +import { + UmbEntityDetailUpdatedEvent, + UmbRequestReloadStructureForEntityEvent, +} from '@umbraco-cms/backoffice/entity-action'; type DocumentVersion = { id: string; @@ -187,12 +192,28 @@ export class UmbRollbackModalElement extends UmbModalBaseElement { + this.#eventContext = context; + + this.#eventContext.removeEventListener( + UmbEntityDetailUpdatedEvent.TYPE, + this.#onEntityDetailUpdatedEvent as unknown as EventListener, + ); + + this.#eventContext.addEventListener( + UmbEntityDetailUpdatedEvent.TYPE, + this.#onEntityDetailUpdatedEvent as unknown as EventListener, + ); + }); } override async load(unique: string) { @@ -326,6 +343,18 @@ export class UmbDocumentWorkspaceContext ): UmbDocumentPropertyDatasetContext { return new UmbDocumentPropertyDatasetContext(host, this, variantId); } + + // TODO: This is currently only a local implementation. Looks into a solution for all detail workspaces + #onEntityDetailUpdatedEvent = (event: UmbEntityDetailUpdatedEvent) => { + const eventUnique = event.getUnique(); + const eventEntityType = event.getEntityType(); + + // Ignore events for other entities + if (eventEntityType !== this.getEntityType()) return; + if (eventUnique !== this.getUnique()) return; + + this.load(this.getUnique()!); + }; } export default UmbDocumentWorkspaceContext; From 77f6ac87c67ebd730299bc1fb7d4746cf773ae36 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 27 Jan 2025 15:50:55 +0100 Subject: [PATCH 11/27] submit modal --- .../documents/rollback/modal/rollback-modal.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts index 574434848b..cdc406d535 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts @@ -215,7 +215,7 @@ export class UmbRollbackModalElement extends UmbModalBaseElement Date: Mon, 27 Jan 2025 21:46:52 +0100 Subject: [PATCH 12/27] render empty states --- .../rollback/modal/rollback-modal.element.ts | 153 ++++++++++-------- 1 file changed, 88 insertions(+), 65 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts index cdc406d535..7f257657b1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts @@ -169,10 +169,20 @@ export class UmbRollbackModalElement extends UmbModalBaseElement item.id === id); - if (!version) return; + + if (!version) { + this._selectedVersion = undefined; + this._diffs = []; + return; + } const { data } = await this.#rollbackRepository.requestVersionById(id); - if (!data) return; + + if (!data) { + this._selectedVersion = undefined; + this._diffs = []; + return; + } this._selectedVersion = { date: version.date, @@ -259,32 +269,38 @@ export class UmbRollbackModalElement extends UmbModalBaseElement item.id, - (item) => { - return html` -
this.#onVersionClicked(item.id)} - @keydown=${() => {}} - class="rollback-item ${this._selectedVersion?.id === item.id ? 'active' : ''}"> -
-

- -

-

${item.user}

-

${item.isCurrentlyPublishedVersion ? this.localize.term('rollback_currentPublishedVersion') : ''}

+ if (!this._versions.length) { + return html`No versions available`; + } + + return html` + ${repeat( + this._versions, + (item) => item.id, + (item) => { + return html` +
this.#onVersionClicked(item.id)} + @keydown=${() => {}} + class="rollback-item ${this._selectedVersion?.id === item.id ? 'active' : ''}"> +
+

+ +

+

${item.user}

+

${item.isCurrentlyPublishedVersion ? this.localize.term('rollback_currentPublishedVersion') : ''}

+
+ this.#onPreventCleanup(event, item.id, !item.preventCleanup)} + label=${item.preventCleanup + ? this.localize.term('contentTypeEditor_historyCleanupEnableCleanup') + : this.localize.term('contentTypeEditor_historyCleanupPreventCleanup')}>
- this.#onPreventCleanup(event, item.id, !item.preventCleanup)} - label=${item.preventCleanup - ? this.localize.term('contentTypeEditor_historyCleanupEnableCleanup') - : this.localize.term('contentTypeEditor_historyCleanupPreventCleanup')}> -
- `; - }, - )}`; + `; + }, + )}`; } async #setDiffs() { @@ -324,41 +340,50 @@ export class UmbRollbackModalElement extends UmbModalBaseElement - - + #renderSelectedVersion() { + if (!this._selectedVersion) + return html` + No selected version + `; - - ${this.localize.term('general_alias')} - ${this.localize.term('general_value')} - - ${repeat( - this._diffs, - (item) => item.alias, - (item) => { - const diff = this._diffs.find((x) => x?.alias === item.alias); - return html` - - ${item.alias} - - ${diff - ? diff.diff.map((part) => - part.added - ? html`${part.value}` - : part.removed - ? html`${part.value}` - : part.value, - ) - : nothing} - - - `; - }, - )} - + return html` + + ${unsafeHTML(this.localize.term('rollback_diffHelp'))} + + + + + + ${this.localize.term('general_alias')} + ${this.localize.term('general_value')} + + ${repeat( + this._diffs, + (item) => item.alias, + (item) => { + const diff = this._diffs.find((x) => x?.alias === item.alias); + return html` + + ${item.alias} + + ${diff + ? diff.diff.map((part) => + part.added + ? html`${part.value}` + : part.removed + ? html`${part.value}` + : part.value, + ) + : nothing} + + + `; + }, + )} + + `; } @@ -382,11 +407,9 @@ export class UmbRollbackModalElement extends UmbModalBaseElement ` : nothing} - - ${this.#renderVersions()} - + ${this.#renderVersions()}
- ${this.#renderCurrentVersion()} + ${this.#renderSelectedVersion()}
Date: Mon, 27 Jan 2025 21:53:47 +0100 Subject: [PATCH 13/27] disable submit button until a version is selected --- .../documents/rollback/modal/rollback-modal.element.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts index 7f257657b1..b0e5dd95ca 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts @@ -421,7 +421,8 @@ export class UmbRollbackModalElement extends UmbModalBaseElement + label=${this.localize.term('actions_rollback')} + ?disabled=${!this._selectedVersion}> `; From 80b8d6f89f992a0a276b42e0333b9cc437bfae21 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 28 Jan 2025 13:40:32 +0100 Subject: [PATCH 14/27] remove from document workspace --- .../workspace/document-workspace.context.ts | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts index 7e8d90bda2..c4eb63ebf7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -33,8 +33,6 @@ import type { UmbDocumentTypeDetailModel } from '@umbraco-cms/backoffice/documen import { UmbIsTrashedEntityContext } from '@umbraco-cms/backoffice/recycle-bin'; import { UMB_APP_CONTEXT } from '@umbraco-cms/backoffice/app'; import { UmbDeprecation } from '@umbraco-cms/backoffice/utils'; -import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; -import { UmbEntityDetailUpdatedEvent } from '@umbraco-cms/backoffice/entity-action'; type ContentModel = UmbDocumentDetailModel; type ContentTypeModel = UmbDocumentTypeDetailModel; @@ -68,7 +66,6 @@ export class UmbDocumentWorkspaceContext #isTrashedContext = new UmbIsTrashedEntityContext(this); #publishingContext?: typeof UMB_DOCUMENT_PUBLISHING_WORKSPACE_CONTEXT.TYPE; - #eventContext?: typeof UMB_ACTION_EVENT_CONTEXT.TYPE; constructor(host: UmbControllerHost) { super(host, { @@ -138,20 +135,6 @@ export class UmbDocumentWorkspaceContext }, }, ]); - - this.consumeContext(UMB_ACTION_EVENT_CONTEXT, (context) => { - this.#eventContext = context; - - this.#eventContext.removeEventListener( - UmbEntityDetailUpdatedEvent.TYPE, - this.#onEntityDetailUpdatedEvent as unknown as EventListener, - ); - - this.#eventContext.addEventListener( - UmbEntityDetailUpdatedEvent.TYPE, - this.#onEntityDetailUpdatedEvent as unknown as EventListener, - ); - }); } override async load(unique: string) { @@ -343,18 +326,6 @@ export class UmbDocumentWorkspaceContext ): UmbDocumentPropertyDatasetContext { return new UmbDocumentPropertyDatasetContext(host, this, variantId); } - - // TODO: This is currently only a local implementation. Looks into a solution for all detail workspaces - #onEntityDetailUpdatedEvent = (event: UmbEntityDetailUpdatedEvent) => { - const eventUnique = event.getUnique(); - const eventEntityType = event.getEntityType(); - - // Ignore events for other entities - if (eventEntityType !== this.getEntityType()) return; - if (eventUnique !== this.getUnique()) return; - - this.load(this.getUnique()!); - }; } export default UmbDocumentWorkspaceContext; From 0a786481754cc43cbefbf7df46d98039cdc5a55e Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 28 Jan 2025 14:04:35 +0100 Subject: [PATCH 15/27] add event discriminator option --- .../packages/core/entity-action/entity-action.event.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-action.event.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-action.event.ts index e6567e5a7c..0c0e2da1d3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-action.event.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-action.event.ts @@ -2,7 +2,9 @@ import { UmbControllerEvent } from '@umbraco-cms/backoffice/controller-api'; import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; // eslint-disable-next-line @typescript-eslint/no-empty-object-type -export interface UmbEntityActionEventArgs extends UmbEntityModel {} +export interface UmbEntityActionEventArgs extends UmbEntityModel { + discriminator?: string; +} export class UmbEntityActionEvent< ArgsType extends UmbEntityActionEventArgs = UmbEntityActionEventArgs, @@ -21,4 +23,8 @@ export class UmbEntityActionEvent< getUnique(): string | null { return this._args.unique; } + + getDiscriminator(): string | undefined { + return this._args.discriminator; + } } From 7ac2fff839a650ca33f92091eebfbf760878fd66 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 28 Jan 2025 14:24:57 +0100 Subject: [PATCH 16/27] dispatch event when content is saved --- .../content-detail-workspace-base.ts | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts index eb5b9eb869..d150497ca2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -42,10 +42,12 @@ import type { UmbModalToken } from '@umbraco-cms/backoffice/modal'; import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; import { + UmbEntityDetailUpdatedEvent, UmbRequestReloadChildrenOfEntityEvent, UmbRequestReloadStructureForEntityEvent, } from '@umbraco-cms/backoffice/entity-action'; import type { ClassConstructor } from '@umbraco-cms/backoffice/extension-api'; +import { UmbId } from '@umbraco-cms/backoffice/id'; export interface UmbContentDetailWorkspaceContextArgs< DetailModelType extends UmbContentDetailModel, @@ -144,6 +146,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< #validationRepository?: UmbContentValidationRepository; #saveModalToken?: UmbModalToken, UmbContentVariantPickerValue>; + #eventContext?: typeof UMB_ACTION_EVENT_CONTEXT.TYPE; constructor( host: UmbControllerHost, @@ -709,13 +712,21 @@ export abstract class UmbContentDetailWorkspaceContextBase< ); this._data.setCurrent(newCurrentData); + const unique = this.getUnique()!; + const entityType = this.getEntityType(); + const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); - const event = new UmbRequestReloadStructureForEntityEvent({ - entityType: this.getEntityType(), - unique: this.getUnique()!, + const structureEvent = new UmbRequestReloadStructureForEntityEvent({ unique, entityType }); + eventContext.dispatchEvent(structureEvent); + + const updatedEvent = new UmbEntityDetailUpdatedEvent({ + unique, + entityType, + discriminator: this._workspaceEventDiscriminator, }); - eventContext.dispatchEvent(event); + eventContext.dispatchEvent(updatedEvent); + this._closeModal(); } From fc55f5eb7f30adbcc249c2ff2c294047b242c20d Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 28 Jan 2025 14:25:26 +0100 Subject: [PATCH 17/27] listen to events on entity updates --- .../entity-detail-workspace-base.ts | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index 574f0e6faf..30f9e76284 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -7,6 +7,7 @@ import { UmbEntityContext, type UmbEntityModel, type UmbEntityUnique } from '@um import { UMB_DISCARD_CHANGES_MODAL, UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; import { + UmbEntityDetailUpdatedEvent, UmbRequestReloadChildrenOfEntityEvent, UmbRequestReloadStructureForEntityEvent, } from '@umbraco-cms/backoffice/entity-action'; @@ -15,6 +16,7 @@ import { umbExtensionsRegistry, type ManifestRepository } from '@umbraco-cms/bac import type { UmbDetailRepository } from '@umbraco-cms/backoffice/repository'; import { UmbStateManager } from '@umbraco-cms/backoffice/utils'; import { UmbValidationContext } from '@umbraco-cms/backoffice/validation'; +import { UmbId } from '@umbraco-cms/backoffice/id'; const LOADING_STATE_UNIQUE = 'umbLoadingEntityDetail'; @@ -45,6 +47,8 @@ export abstract class UmbEntityDetailWorkspaceContextBase< protected _getDataPromise?: Promise; protected _detailRepository?: DetailRepositoryType; + #eventContext?: typeof UMB_ACTION_EVENT_CONTEXT.TYPE; + #parent = new UmbObjectState<{ entityType: string; unique: UmbEntityUnique } | undefined>(undefined); public readonly parentUnique = this.#parent.asObservablePart((parent) => (parent ? parent.unique : undefined)); public readonly parentEntityType = this.#parent.asObservablePart((parent) => @@ -85,6 +89,19 @@ export abstract class UmbEntityDetailWorkspaceContextBase< window.addEventListener('willchangestate', this.#onWillNavigate); this.#observeRepository(args.detailRepositoryAlias); this.addValidationContext(this.validationContext); + + this.consumeContext(UMB_ACTION_EVENT_CONTEXT, (context) => { + this.#eventContext = context; + + this.#eventContext.removeEventListener( + UmbEntityDetailUpdatedEvent.TYPE, + this.#onEntityDetailUpdatedEvent as unknown as EventListener, + ); + this.#eventContext.addEventListener( + UmbEntityDetailUpdatedEvent.TYPE, + this.#onEntityDetailUpdatedEvent as unknown as EventListener, + ); + }); } /** @@ -396,8 +413,30 @@ export abstract class UmbEntityDetailWorkspaceContextBase< } } + // Discriminator to identify events from this workspace context + protected readonly _workspaceEventDiscriminator = UmbId.new(); + + #onEntityDetailUpdatedEvent = (event: UmbEntityDetailUpdatedEvent) => { + const eventEntityUnique = event.getUnique(); + const eventEntityType = event.getEntityType(); + const eventDiscriminator = event.getDiscriminator(); + + // Ignore events for other entities + if (eventEntityType !== this.getEntityType()) return; + if (eventEntityUnique !== this.getUnique()) return; + + // Ignore events from this workspace so we don't reload the data twice. Ex saving this workspace + if (eventDiscriminator === this._workspaceEventDiscriminator) return; + + this.load(this.getUnique()!); + }; + public override destroy(): void { window.removeEventListener('willchangestate', this.#onWillNavigate); + this.#eventContext?.removeEventListener( + UmbEntityDetailUpdatedEvent.TYPE, + this.#onEntityDetailUpdatedEvent as unknown as EventListener, + ); this._detailRepository?.destroy(); this.#entityContext.destroy(); super.destroy(); From 15342ea2bcfa9ac29f92e818abbdf1a358017b7e Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 28 Jan 2025 14:28:39 +0100 Subject: [PATCH 18/27] remove detail from event --- .../content/workspace/content-detail-workspace-base.ts | 4 ++-- ...detail-updated.event.ts => entity-updated.event.ts} | 6 +++--- .../entity-detail/entity-detail-workspace-base.ts | 10 +++++----- .../documents/rollback/modal/rollback-modal.element.ts | 7 ++----- 4 files changed, 12 insertions(+), 15 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/core/entity-action/{entity-detail-updated.event.ts => entity-updated.event.ts} (53%) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts index d150497ca2..1d09c6ffe3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -42,7 +42,7 @@ import type { UmbModalToken } from '@umbraco-cms/backoffice/modal'; import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; import { - UmbEntityDetailUpdatedEvent, + UmbEntityUpdatedEvent, UmbRequestReloadChildrenOfEntityEvent, UmbRequestReloadStructureForEntityEvent, } from '@umbraco-cms/backoffice/entity-action'; @@ -719,7 +719,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< const structureEvent = new UmbRequestReloadStructureForEntityEvent({ unique, entityType }); eventContext.dispatchEvent(structureEvent); - const updatedEvent = new UmbEntityDetailUpdatedEvent({ + const updatedEvent = new UmbEntityUpdatedEvent({ unique, entityType, discriminator: this._workspaceEventDiscriminator, diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-detail-updated.event.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-updated.event.ts similarity index 53% rename from src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-detail-updated.event.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-updated.event.ts index 259e3ed458..19bfc62daa 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-detail-updated.event.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-updated.event.ts @@ -1,10 +1,10 @@ import type { UmbEntityActionEventArgs } from './entity-action.event.js'; import { UmbEntityActionEvent } from './entity-action.event.js'; -export class UmbEntityDetailUpdatedEvent extends UmbEntityActionEvent { - static readonly TYPE = 'entity-detail-updated'; +export class UmbEntityUpdatedEvent extends UmbEntityActionEvent { + static readonly TYPE = 'entity-updated'; constructor(args: UmbEntityActionEventArgs) { - super(UmbEntityDetailUpdatedEvent.TYPE, args); + super(UmbEntityUpdatedEvent.TYPE, args); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index 30f9e76284..bb7b160181 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -7,7 +7,7 @@ import { UmbEntityContext, type UmbEntityModel, type UmbEntityUnique } from '@um import { UMB_DISCARD_CHANGES_MODAL, UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; import { - UmbEntityDetailUpdatedEvent, + UmbEntityUpdatedEvent, UmbRequestReloadChildrenOfEntityEvent, UmbRequestReloadStructureForEntityEvent, } from '@umbraco-cms/backoffice/entity-action'; @@ -94,11 +94,11 @@ export abstract class UmbEntityDetailWorkspaceContextBase< this.#eventContext = context; this.#eventContext.removeEventListener( - UmbEntityDetailUpdatedEvent.TYPE, + UmbEntityUpdatedEvent.TYPE, this.#onEntityDetailUpdatedEvent as unknown as EventListener, ); this.#eventContext.addEventListener( - UmbEntityDetailUpdatedEvent.TYPE, + UmbEntityUpdatedEvent.TYPE, this.#onEntityDetailUpdatedEvent as unknown as EventListener, ); }); @@ -416,7 +416,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase< // Discriminator to identify events from this workspace context protected readonly _workspaceEventDiscriminator = UmbId.new(); - #onEntityDetailUpdatedEvent = (event: UmbEntityDetailUpdatedEvent) => { + #onEntityDetailUpdatedEvent = (event: UmbEntityUpdatedEvent) => { const eventEntityUnique = event.getUnique(); const eventEntityType = event.getEntityType(); const eventDiscriminator = event.getDiscriminator(); @@ -434,7 +434,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase< public override destroy(): void { window.removeEventListener('willchangestate', this.#onWillNavigate); this.#eventContext?.removeEventListener( - UmbEntityDetailUpdatedEvent.TYPE, + UmbEntityUpdatedEvent.TYPE, this.#onEntityDetailUpdatedEvent as unknown as EventListener, ); this._detailRepository?.destroy(); diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts index b0e5dd95ca..116745a661 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts @@ -16,10 +16,7 @@ import { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import '../../modals/shared/document-variant-language-picker.element.js'; import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; -import { - UmbEntityDetailUpdatedEvent, - UmbRequestReloadStructureForEntityEvent, -} from '@umbraco-cms/backoffice/entity-action'; +import { UmbEntityUpdatedEvent, UmbRequestReloadStructureForEntityEvent } from '@umbraco-cms/backoffice/entity-action'; type DocumentVersion = { id: string; @@ -222,7 +219,7 @@ export class UmbRollbackModalElement extends UmbModalBaseElement Date: Tue, 28 Jan 2025 14:29:30 +0100 Subject: [PATCH 19/27] Update index.ts --- .../src/packages/core/entity-action/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a1f34f7ee9..37d12fa9f0 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 @@ -5,7 +5,7 @@ export * from './constants.js'; export * from './entity-action-base.js'; export * from './entity-action-list.element.js'; export * from './entity-action.event.js'; -export * from './entity-detail-updated.event.js'; +export * from './entity-updated.event.js'; export type * from './types.js'; export { UmbRequestReloadStructureForEntityEvent } from './request-reload-structure-for-entity.event.js'; From ee1dff2e5067f0587ce894e393fc20b999d97264 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 28 Jan 2025 14:34:41 +0100 Subject: [PATCH 20/27] Update rollback-modal.element.ts --- .../documents/rollback/modal/rollback-modal.element.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts index 116745a661..e41ad2d053 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/modal/rollback-modal.element.ts @@ -216,11 +216,12 @@ export class UmbRollbackModalElement extends UmbModalBaseElement Date: Tue, 28 Jan 2025 14:48:05 +0100 Subject: [PATCH 21/27] remove unused --- .../core/content/workspace/content-detail-workspace-base.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts index 1d09c6ffe3..d39b529e71 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -146,7 +146,6 @@ export abstract class UmbContentDetailWorkspaceContextBase< #validationRepository?: UmbContentValidationRepository; #saveModalToken?: UmbModalToken, UmbContentVariantPickerValue>; - #eventContext?: typeof UMB_ACTION_EVENT_CONTEXT.TYPE; constructor( host: UmbControllerHost, From e6cc9cfc6cbd25c19bc35d82fc787abff69be91b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 28 Jan 2025 14:59:59 +0100 Subject: [PATCH 22/27] reload items --- .../repository/repository-items.manager.ts | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/repository-items.manager.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/repository-items.manager.ts index c8b2e5b8bd..ca8c8235ac 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/repository-items.manager.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/repository-items.manager.ts @@ -4,6 +4,8 @@ import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api'; import { type ManifestRepository, umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import { UmbExtensionApiInitializer } from '@umbraco-cms/backoffice/extension-api'; import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import { UMB_ACTION_EVENT_CONTEXT } from '@umbraco-cms/backoffice/action'; +import { UmbEntityUpdatedEvent } from '@umbraco-cms/backoffice/entity-action'; const ObserveRepositoryAlias = Symbol(); @@ -14,6 +16,7 @@ export class UmbRepositoryItemsManager exte #init: Promise; #currentRequest?: Promise; + #eventContext?: typeof UMB_ACTION_EVENT_CONTEXT.TYPE; // the init promise is used externally for recognizing when the manager is ready. public get init() { @@ -70,6 +73,20 @@ export class UmbRepositoryItemsManager exte }, null, ); + + this.consumeContext(UMB_ACTION_EVENT_CONTEXT, (context) => { + this.#eventContext = context; + + this.#eventContext.removeEventListener( + UmbEntityUpdatedEvent.TYPE, + this.#onEntityDetailUpdatedEvent as unknown as EventListener, + ); + + this.#eventContext.addEventListener( + UmbEntityUpdatedEvent.TYPE, + this.#onEntityDetailUpdatedEvent as unknown as EventListener, + ); + }); } getUniques(): Array { @@ -122,6 +139,25 @@ export class UmbRepositoryItemsManager exte } } + async #reloadItem(unique: string): Promise { + await this.#init; + if (!this.repository) throw new Error('Repository is not initialized'); + + const { data } = await this.repository.requestItems([unique]); + + if (data) { + const items = this.getItems(); + const item = items.find((item) => this.#getUnique(item) === unique); + + if (item) { + const index = items.indexOf(item); + const newItems = [...items]; + newItems[index] = data[0]; + this.#items.setValue(this.#sortByUniques(newItems)); + } + } + } + #sortByUniques(data: Array): Array { const uniques = this.getUniques(); return [...data].sort((a, b) => { @@ -130,4 +166,25 @@ export class UmbRepositoryItemsManager exte return aIndex - bIndex; }); } + + #onEntityDetailUpdatedEvent = (event: UmbEntityUpdatedEvent) => { + const eventUnique = event.getUnique(); + + const items = this.getItems(); + if (items.length === 0) return; + + // Ignore events if the entity is not in the list of items. + const item = items.find((item) => this.#getUnique(item) === eventUnique); + if (!item) return; + + this.#reloadItem(item.unique); + }; + + override destroy(): void { + this.#eventContext?.removeEventListener( + UmbEntityUpdatedEvent.TYPE, + this.#onEntityDetailUpdatedEvent as unknown as EventListener, + ); + super.destroy(); + } } From aa5c58f753428e3cbeece7611a3b54277d5a5e70 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Tue, 28 Jan 2025 17:15:27 +0100 Subject: [PATCH 23/27] use reload --- .../workspace/entity-detail/entity-detail-workspace-base.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index bb7b160181..ff83c234fb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -428,7 +428,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase< // Ignore events from this workspace so we don't reload the data twice. Ex saving this workspace if (eventDiscriminator === this._workspaceEventDiscriminator) return; - this.load(this.getUnique()!); + this.reload(); }; public override destroy(): void { From 0b5e760fd512c3c500ba2b4ea9a7408a904c4b1c Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 29 Jan 2025 10:04:57 +0100 Subject: [PATCH 24/27] correct name --- .../packages/core/repository/repository-items.manager.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/repository-items.manager.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/repository-items.manager.ts index a862a4e758..d54166a951 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/repository-items.manager.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/repository-items.manager.ts @@ -79,12 +79,12 @@ export class UmbRepositoryItemsManager exte this.#eventContext.removeEventListener( UmbEntityUpdatedEvent.TYPE, - this.#onEntityDetailUpdatedEvent as unknown as EventListener, + this.#onEntityUpdatedEvent as unknown as EventListener, ); this.#eventContext.addEventListener( UmbEntityUpdatedEvent.TYPE, - this.#onEntityDetailUpdatedEvent as unknown as EventListener, + this.#onEntityUpdatedEvent as unknown as EventListener, ); }); } @@ -167,7 +167,7 @@ export class UmbRepositoryItemsManager exte }); } - #onEntityDetailUpdatedEvent = (event: UmbEntityUpdatedEvent) => { + #onEntityUpdatedEvent = (event: UmbEntityUpdatedEvent) => { const eventUnique = event.getUnique(); const items = this.getItems(); @@ -183,7 +183,7 @@ export class UmbRepositoryItemsManager exte override destroy(): void { this.#eventContext?.removeEventListener( UmbEntityUpdatedEvent.TYPE, - this.#onEntityDetailUpdatedEvent as unknown as EventListener, + this.#onEntityUpdatedEvent as unknown as EventListener, ); super.destroy(); } From 6b94a20043b06cad7406a0513a973c4f05ee0bac Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 29 Jan 2025 10:05:36 +0100 Subject: [PATCH 25/27] dispatch event from detail-workspace-base --- .../entity-detail-workspace-base.ts | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index ff83c234fb..6b29057800 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -95,11 +95,11 @@ export abstract class UmbEntityDetailWorkspaceContextBase< this.#eventContext.removeEventListener( UmbEntityUpdatedEvent.TYPE, - this.#onEntityDetailUpdatedEvent as unknown as EventListener, + this.#onEntityUpdatedEvent as unknown as EventListener, ); this.#eventContext.addEventListener( UmbEntityUpdatedEvent.TYPE, - this.#onEntityDetailUpdatedEvent as unknown as EventListener, + this.#onEntityUpdatedEvent as unknown as EventListener, ); }); } @@ -324,13 +324,21 @@ export abstract class UmbEntityDetailWorkspaceContextBase< this._data.setPersisted(data); this._data.setCurrent(data); - const actionEventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); - const event = new UmbRequestReloadStructureForEntityEvent({ - unique: this.getUnique()!, - entityType: this.getEntityType(), + const unique = this.getUnique()!; + const entityType = this.getEntityType(); + + const eventContext = await this.getContext(UMB_ACTION_EVENT_CONTEXT); + const event = new UmbRequestReloadStructureForEntityEvent({ unique, entityType }); + + eventContext.dispatchEvent(event); + + const updatedEvent = new UmbEntityUpdatedEvent({ + unique, + entityType, + discriminator: this._workspaceEventDiscriminator, }); - actionEventContext.dispatchEvent(event); + eventContext.dispatchEvent(updatedEvent); } #allowNavigateAway = false; @@ -416,7 +424,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase< // Discriminator to identify events from this workspace context protected readonly _workspaceEventDiscriminator = UmbId.new(); - #onEntityDetailUpdatedEvent = (event: UmbEntityUpdatedEvent) => { + #onEntityUpdatedEvent = (event: UmbEntityUpdatedEvent) => { const eventEntityUnique = event.getUnique(); const eventEntityType = event.getEntityType(); const eventDiscriminator = event.getDiscriminator(); @@ -435,7 +443,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase< window.removeEventListener('willchangestate', this.#onWillNavigate); this.#eventContext?.removeEventListener( UmbEntityUpdatedEvent.TYPE, - this.#onEntityDetailUpdatedEvent as unknown as EventListener, + this.#onEntityUpdatedEvent as unknown as EventListener, ); this._detailRepository?.destroy(); this.#entityContext.destroy(); From 99cb36b29d029f79c57e8a55065cac16b6323b08 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Wed, 29 Jan 2025 11:16:54 +0100 Subject: [PATCH 26/27] remove unused --- .../core/content/workspace/content-detail-workspace-base.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts index d39b529e71..db8c76f469 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -47,7 +47,6 @@ import { UmbRequestReloadStructureForEntityEvent, } from '@umbraco-cms/backoffice/entity-action'; import type { ClassConstructor } from '@umbraco-cms/backoffice/extension-api'; -import { UmbId } from '@umbraco-cms/backoffice/id'; export interface UmbContentDetailWorkspaceContextArgs< DetailModelType extends UmbContentDetailModel, From a2378e6b5f4ba6ae41ce7284b2389ecbeba2381d Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Fri, 31 Jan 2025 12:15:10 +0100 Subject: [PATCH 27/27] use unique instead of discriminator --- .../content/workspace/content-detail-workspace-base.ts | 2 +- .../packages/core/entity-action/entity-action.event.ts | 6 +++--- .../entity-detail/entity-detail-workspace-base.ts | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts index 31ed3aa190..42b8769acf 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -720,7 +720,7 @@ export abstract class UmbContentDetailWorkspaceContextBase< const updatedEvent = new UmbEntityUpdatedEvent({ unique, entityType, - discriminator: this._workspaceEventDiscriminator, + eventUnique: this._workspaceEventUnique, }); eventContext.dispatchEvent(updatedEvent); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-action.event.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-action.event.ts index 0c0e2da1d3..ff91281d89 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-action.event.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-action/entity-action.event.ts @@ -3,7 +3,7 @@ import type { UmbEntityModel } from '@umbraco-cms/backoffice/entity'; // eslint-disable-next-line @typescript-eslint/no-empty-object-type export interface UmbEntityActionEventArgs extends UmbEntityModel { - discriminator?: string; + eventUnique?: string; } export class UmbEntityActionEvent< @@ -24,7 +24,7 @@ export class UmbEntityActionEvent< return this._args.unique; } - getDiscriminator(): string | undefined { - return this._args.discriminator; + getEventUnique(): string | undefined { + return this._args.eventUnique; } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts index 6b29057800..07e3c570f9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/workspace/entity-detail/entity-detail-workspace-base.ts @@ -335,7 +335,7 @@ export abstract class UmbEntityDetailWorkspaceContextBase< const updatedEvent = new UmbEntityUpdatedEvent({ unique, entityType, - discriminator: this._workspaceEventDiscriminator, + eventUnique: this._workspaceEventUnique, }); eventContext.dispatchEvent(updatedEvent); @@ -422,19 +422,19 @@ export abstract class UmbEntityDetailWorkspaceContextBase< } // Discriminator to identify events from this workspace context - protected readonly _workspaceEventDiscriminator = UmbId.new(); + protected readonly _workspaceEventUnique = UmbId.new(); #onEntityUpdatedEvent = (event: UmbEntityUpdatedEvent) => { const eventEntityUnique = event.getUnique(); const eventEntityType = event.getEntityType(); - const eventDiscriminator = event.getDiscriminator(); + const eventDiscriminator = event.getEventUnique(); // Ignore events for other entities if (eventEntityType !== this.getEntityType()) return; if (eventEntityUnique !== this.getUnique()) return; // Ignore events from this workspace so we don't reload the data twice. Ex saving this workspace - if (eventDiscriminator === this._workspaceEventDiscriminator) return; + if (eventDiscriminator === this._workspaceEventUnique) return; this.reload(); };