From 6b6b2e603e485ddf1645ce352ef1f6ec88617a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Sun, 3 Mar 2024 13:59:37 +0100 Subject: [PATCH] close modal and destroy modal element when context gets destroyed --- .../backoffice-modal-container.element.ts | 2 ++ ...element.element.ts => modal-base.element.ts} | 0 .../core/modal/component/modal.element.ts | 17 ++++++++++++++++- .../core/modal/context/modal.context.ts | 1 + .../src/packages/core/modal/index.ts | 2 +- 5 files changed, 20 insertions(+), 2 deletions(-) rename src/Umbraco.Web.UI.Client/src/packages/core/modal/component/{modal-element.element.ts => modal-base.element.ts} (100%) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/backoffice-modal-container/backoffice-modal-container.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/backoffice-modal-container/backoffice-modal-container.element.ts index f56ca854f6..48d0068860 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/backoffice-modal-container/backoffice-modal-container.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/backoffice-modal-container/backoffice-modal-container.element.ts @@ -41,6 +41,7 @@ export class UmbBackofficeModalContainerElement extends UmbLitElement { const oldModals = oldValue.filter((oldModal) => !modals.some((modal) => modal.key === oldModal.key)); oldModals.forEach((modal) => { + // TODO: I would not think this works as expected, the callback method has to be the exact same instance as the one added: [NL] this._modalElementMap.get(modal.key)?.removeEventListener('close-end', this.#onCloseEnd.bind(this, modal.key)); this._modalElementMap.delete(modal.key); }); @@ -57,6 +58,7 @@ export class UmbBackofficeModalContainerElement extends UmbLitElement { modalElement.modalContext = modal; modalElement.element?.addEventListener('close-end', this.#onCloseEnd.bind(this, modal.key)); + modal.addEventListener('umb:destroy', this.#onCloseEnd.bind(this, modal.key)); this._modalElementMap.set(modal.key, modalElement); this.requestUpdate(); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/component/modal-element.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/component/modal-base.element.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/packages/core/modal/component/modal-element.element.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/modal/component/modal-base.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/component/modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/component/modal.element.ts index 6757f2d6f5..83f5786e33 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/component/modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/component/modal.element.ts @@ -26,6 +26,7 @@ export class UmbModalElement extends UmbLitElement { return this.#modalContext; } public set modalContext(value: UmbModalContext | undefined) { + if (this.#modalContext === value) return; this.#modalContext = value; if (!value) { @@ -51,6 +52,7 @@ export class UmbModalElement extends UmbLitElement { #createModalElement() { if (!this.#modalContext) return; + this.#modalContext.addEventListener('umb:destroy', this.#onContextDestroy); this.element = this.#createContainerElement(); // Makes sure that the modal triggers the reject of the context promise when it is closed by pressing escape. @@ -136,9 +138,13 @@ export class UmbModalElement extends UmbLitElement { // TODO: add inner fallback element if no extension element is found const innerElement = await createExtensionElement(manifest); + if (!this.#modalContext) { + // If context does not exist any more, it means we have been destroyed. So we need to back out: + return undefined; + } if (innerElement) { innerElement.manifest = manifest; - innerElement.data = this.#modalContext!.data; + innerElement.data = this.#modalContext.data; innerElement.modalContext = this.#modalContext; } @@ -167,10 +173,19 @@ export class UmbModalElement extends UmbLitElement { this.destroy(); } + #onContextDestroy = () => { + this.destroy(); + }; + destroy() { this.#innerElement.complete(); this.#modalExtensionObserver?.destroy(); this.#modalExtensionObserver = undefined; + if (this.#modalContext) { + this.#modalContext.removeEventListener('umb:destroy', this.#onContextDestroy); + this.#modalContext.destroy(); + this.#modalContext = undefined; + } super.destroy(); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal.context.ts b/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal.context.ts index 6d167cd625..a22c2dd674 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/modal/context/modal.context.ts @@ -132,6 +132,7 @@ export class UmbModalContext