diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/editors/data-type/views/edit/editor-view-data-type-edit.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/editors/data-type/views/edit/editor-view-data-type-edit.element.ts index ba0d743335..aa108daa5f 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/editors/data-type/views/edit/editor-view-data-type-edit.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/editors/data-type/views/edit/editor-view-data-type-edit.element.ts @@ -39,35 +39,25 @@ export class UmbEditorViewDataTypeEditElement extends UmbContextConsumerMixin(Li private _dataTypeContext?: UmbDataTypeContext; private _extensionRegistry?: UmbExtensionRegistry; private _propertyEditorStore?: UmbPropertyEditorStore; + private _modalService?: UmbModalService; private _dataTypeSubscription?: Subscription; private _propertyEditorSubscription?: Subscription; private _propertyEditorUISubscription?: Subscription; - private _modalService?: UmbModalService; - constructor() { super(); - // TODO: wait for more contexts - this.consumeContext('umbModalService', (modalService) => { - this._modalService = modalService; - }); - - this.consumeContext('umbDataTypeContext', (dataTypeContext) => { - this._dataTypeContext = dataTypeContext; - this._observeDataType(); - }); - - this.consumeContext('umbPropertyEditorStore', (propertyEditorStore) => { - this._propertyEditorStore = propertyEditorStore; - this._observeDataType(); - }); - - this.consumeContext('umbExtensionRegistry', (extensionRegistry) => { - this._extensionRegistry = extensionRegistry; - this._observeDataType(); - }); + this.consumeAllContexts( + ['umbDataTypeContext', 'umbPropertyEditorStore', 'umbExtensionRegistry', 'umbModalService'], + (instances) => { + this._dataTypeContext = instances[0]; + this._propertyEditorStore = instances[1]; + this._extensionRegistry = instances[2]; + this._modalService = instances[3]; + this._observeDataType(); + } + ); } private _observeDataType() { diff --git a/src/Umbraco.Web.UI.Client/src/core/context/context-consumer.mixin.ts b/src/Umbraco.Web.UI.Client/src/core/context/context-consumer.mixin.ts index 5e639f9898..05d9016c17 100644 --- a/src/Umbraco.Web.UI.Client/src/core/context/context-consumer.mixin.ts +++ b/src/Umbraco.Web.UI.Client/src/core/context/context-consumer.mixin.ts @@ -2,7 +2,8 @@ import type { HTMLElementConstructor } from '../models'; import { UmbContextConsumer } from './context-consumer'; export declare class UmbContextConsumerInterface { - consumeContext(alias: string, callback?: (_instance: any) => void): void; + consumeContext(alias: string, callback: (_instance: any) => void): void; + consumeAllContexts(contexts: Array, callback: (_instances: Array) => void): void; whenAvailableOrChanged(contextAliases: string[], callback?: () => void): void; } @@ -16,37 +17,59 @@ export declare class UmbContextConsumerInterface { export const UmbContextConsumerMixin = (superClass: T) => { class UmbContextConsumerClass extends superClass { // all context requesters in the element - _consumers: Map = new Map(); + _consumers: Map = new Map(); // all successfully resolved context requests _resolved: Map = new Map(); _attached = false; /** - * Setup a subscription for a request on a given context of this component. + * Setup a subscription for a context. The callback is called when the context is resolved. * @param {string} alias - * @param {method} callback optional callback method called when context is received or when context is detached. + * @param {method} callback Callback method called when context is resolved. */ - consumeContext(alias: string, callback?: (_instance: unknown) => void): void { - if (this._consumers.has(alias)) return; - - const consumer = new UmbContextConsumer(this, alias, (_instance: any) => { - // Do we still have this consumer? - - callback?.(_instance); - - // don't to anything if the context is already resolved - if (this._resolved.has(alias) && this._resolved.get(alias) === _instance) return; - - this._resolved.set(alias, _instance); - this._consumeContextCallback(alias, _instance); + consumeContext(alias: string, callback: (_instance: unknown) => void): void { + this._createContextConsumers([alias], (resolvedContexts) => { + callback(resolvedContexts[0]); }); + } - this._consumers.set(alias, consumer); + /** + * Setup a subscription for multiple contexts. The callback is called when all contexts are resolved. + * @param {string} aliases + * @param {method} callback Callback method called when all contexts are resolved. + */ + consumeAllContexts(_contextAliases: string[], callback: (_instances: unknown[]) => void) { + this._createContextConsumers(_contextAliases, (resolvedContexts) => { + callback?.(resolvedContexts); + }); + } - if (this._attached) { - consumer.attach(); - } + private _createContextConsumers(aliases: Array, resolvedCallback: (_instances: unknown[]) => void) { + aliases.forEach((alias) => { + const consumer = new UmbContextConsumer(this, alias, (_instance: any) => { + this._resolved.set(alias, _instance); + + //check if all contexts are resolved + const resolvedContexts = aliases.map((alias) => this._resolved.get(alias)); + const allResolved = resolvedContexts.every((context) => context !== undefined); + + if (allResolved) { + resolvedCallback(resolvedContexts); + } + }); + + if (this._consumers.has(alias)) { + const consumers = this._consumers.get(alias); + consumers?.push(consumer); + } else { + this._consumers.set(alias, [consumer]); + } + + if (this._attached) { + consumer.attach(); + } + }); } // TODO: remove requester.. @@ -54,20 +77,16 @@ export const UmbContextConsumerMixin = (superC connectedCallback() { super.connectedCallback?.(); this._attached = true; - this._consumers.forEach((requester) => requester.attach()); + this._consumers.forEach((consumers) => consumers.forEach((consumer) => consumer.attach())); } disconnectedCallback() { super.disconnectedCallback?.(); this._attached = false; - this._consumers.forEach((requester) => requester.detach()); + this._consumers.forEach((consumers) => consumers.forEach((consumer) => consumer.detach())); this._resolved.clear(); } - _consumeContextCallback(_newAlias: string, _newInstance: unknown) { - // TODO: do be done. - } - // might return a object, so you can unsubscribe. whenAvailableOrChanged(_contextAliases: string[]) { // TODO: To be done.