diff --git a/src/packages/core/collection/collection-default.context.ts b/src/packages/core/collection/collection-default.context.ts index 008922dd60..e6838f1f86 100644 --- a/src/packages/core/collection/collection-default.context.ts +++ b/src/packages/core/collection/collection-default.context.ts @@ -53,7 +53,7 @@ export class UmbDefaultCollectionContext = []; - #selectionManager = new UmbSelectionManager(); + #selectionManager = new UmbSelectionManager(this); #submit() { this.modalContext?.submit({ @@ -38,7 +38,8 @@ export class UmbSectionPickerModalElement extends UmbModalBaseElement< this.observe( umbExtensionsRegistry.extensionsOfType('section'), (sections: Array) => (this._sections = sections), - ), 'umbSectionsObserver'; + ), + 'umbSectionsObserver'; } render() { diff --git a/src/packages/core/tree/tree-item-base/tree-item-base.context.ts b/src/packages/core/tree/tree-item-base/tree-item-base.context.ts index 7fb269d591..5bb3b483e1 100644 --- a/src/packages/core/tree/tree-item-base/tree-item-base.context.ts +++ b/src/packages/core/tree/tree-item-base/tree-item-base.context.ts @@ -105,12 +105,12 @@ export class UmbTreeItemContextBase public select() { if (this.unique === undefined) throw new Error('Could not select, unique key is missing'); - this.treeContext?.select(this.unique); + this.treeContext?.selection.select(this.unique); } public deselect() { if (this.unique === undefined) throw new Error('Could not deselect, unique key is missing'); - this.treeContext?.deselect(this.unique); + this.treeContext?.selection.deselect(this.unique); } #consumeContexts() { @@ -138,7 +138,7 @@ export class UmbTreeItemContextBase #observeIsSelectable() { if (!this.treeContext) return; this.observe( - this.treeContext.selectable, + this.treeContext.selection.selectable, (value) => { this.#isSelectableContext.next(value); @@ -156,7 +156,7 @@ export class UmbTreeItemContextBase if (!this.treeContext || !this.unique) return; this.observe( - this.treeContext.selection.pipe(map((selection) => selection.includes(this.unique!))), + this.treeContext.selection.selection.pipe(map((selection) => selection.includes(this.unique!))), (isSelected) => { this.#isSelected.next(isSelected); }, diff --git a/src/packages/core/tree/tree.context.ts b/src/packages/core/tree/tree.context.ts index ddd3c0af26..ddfc37f131 100644 --- a/src/packages/core/tree/tree.context.ts +++ b/src/packages/core/tree/tree.context.ts @@ -13,20 +13,10 @@ import { type UmbControllerHostElement } from '@umbraco-cms/backoffice/controlle import { UmbExtensionApiInitializer } from '@umbraco-cms/backoffice/extension-api'; import { ProblemDetails } from '@umbraco-cms/backoffice/backend-api'; import { UmbSelectionManager } from '@umbraco-cms/backoffice/utils'; -import { UmbSelectionChangeEvent } from '@umbraco-cms/backoffice/event'; // TODO: update interface export interface UmbTreeContext extends UmbBaseController { - readonly selectable: Observable; - readonly selection: Observable>; - setSelectable(value: boolean): void; - getSelectable(): boolean; - setMultiple(value: boolean): void; - getMultiple(): boolean; - setSelection(value: Array): void; - getSelection(): Array; - select(unique: string | null): void; - deselect(unique: string | null): void; + selection: UmbSelectionManager; requestChildrenOf: (parentUnique: string | null) => Promise<{ data?: UmbPagedData; error?: ProblemDetails; @@ -38,17 +28,11 @@ export class UmbTreeContextBase extends UmbBaseController implements UmbTreeContext { - #selectionManager = new UmbSelectionManager(); - - #selectable = new UmbBooleanState(false); - public readonly selectable = this.#selectable.asObservable(); - - public readonly multiple = this.#selectionManager.multiple; - public readonly selection = this.#selectionManager.selection; - public repository?: UmbTreeRepository; public selectableFilter?: (item: TreeItemType) => boolean = () => true; + public readonly selection = new UmbSelectionManager(this._host); + #treeAlias?: string; #initResolver?: () => void; @@ -82,41 +66,6 @@ export class UmbTreeContextBase return this.#treeAlias; } - public setSelectable(value: boolean) { - this.#selectable.next(value); - } - - public getSelectable() { - return this.#selectable.getValue(); - } - - public setMultiple(value: boolean) { - this.#selectionManager.setMultiple(value); - } - - public getMultiple() { - return this.#selectionManager.getMultiple(); - } - - public setSelection(value: Array) { - this.#selectionManager.setSelection(value); - } - - public getSelection() { - return this.#selectionManager.getSelection(); - } - - public select(unique: string | null) { - if (!this.getSelectable()) return; - this.#selectionManager.select(unique); - this._host.getHostElement().dispatchEvent(new UmbSelectionChangeEvent()); - } - - public deselect(unique: string | null) { - this.#selectionManager.deselect(unique); - this._host.getHostElement().dispatchEvent(new UmbSelectionChangeEvent()); - } - public async requestTreeRoot() { await this.#init; return this.repository!.requestTreeRoot(); diff --git a/src/packages/core/tree/tree.element.ts b/src/packages/core/tree/tree.element.ts index 72a2a8194e..8d78adf200 100644 --- a/src/packages/core/tree/tree.element.ts +++ b/src/packages/core/tree/tree.element.ts @@ -19,27 +19,27 @@ export class UmbTreeElement extends UmbLitElement { @property({ type: Boolean, reflect: true }) get selectable() { - return this.#treeContext.getSelectable(); + return this.#treeContext.selection.getSelectable(); } set selectable(newVal) { - this.#treeContext.setSelectable(newVal); + this.#treeContext.selection.setSelectable(newVal); } @property({ type: Array }) get selection() { - return this.#treeContext.getSelection(); + return this.#treeContext.selection.getSelection(); } set selection(newVal) { if (!Array.isArray(newVal)) return; - this.#treeContext?.setSelection(newVal); + this.#treeContext?.selection.setSelection(newVal); } @property({ type: Boolean, reflect: true }) get multiple() { - return this.#treeContext.getMultiple(); + return this.#treeContext.selection.getMultiple(); } set multiple(newVal) { - this.#treeContext.setMultiple(newVal); + this.#treeContext.selection.setMultiple(newVal); } // TODO: what is the best name for this functionality? diff --git a/src/packages/settings/languages/modals/language-picker/language-picker-modal.element.ts b/src/packages/settings/languages/modals/language-picker/language-picker-modal.element.ts index a83e66e5eb..66aa223c50 100644 --- a/src/packages/settings/languages/modals/language-picker/language-picker-modal.element.ts +++ b/src/packages/settings/languages/modals/language-picker/language-picker-modal.element.ts @@ -18,7 +18,7 @@ export class UmbLanguagePickerModalElement extends UmbModalBaseElement< private _languages: Array = []; #languageRepository = new UmbLanguageRepository(this); - #selectionManager = new UmbSelectionManager(); + #selectionManager = new UmbSelectionManager(this); connectedCallback(): void { super.connectedCallback(); diff --git a/src/packages/user/user-group/modals/user-group-picker/user-group-picker-modal.element.ts b/src/packages/user/user-group/modals/user-group-picker/user-group-picker-modal.element.ts index 88af248707..82bc18b6be 100644 --- a/src/packages/user/user-group/modals/user-group-picker/user-group-picker-modal.element.ts +++ b/src/packages/user/user-group/modals/user-group-picker/user-group-picker-modal.element.ts @@ -12,7 +12,7 @@ export class UmbUserGroupPickerModalElement extends UmbModalBaseElement = []; - #selectionManager = new UmbSelectionManager(); + #selectionManager = new UmbSelectionManager(this); #userGroupCollectionRepository = new UmbUserGroupCollectionRepository(this); connectedCallback(): void { diff --git a/src/packages/user/user/modals/user-picker/user-picker-modal.element.ts b/src/packages/user/user/modals/user-picker/user-picker-modal.element.ts index 134b025628..a945307a83 100644 --- a/src/packages/user/user/modals/user-picker/user-picker-modal.element.ts +++ b/src/packages/user/user/modals/user-picker/user-picker-modal.element.ts @@ -10,7 +10,7 @@ export class UmbUserPickerModalElement extends UmbModalBaseElement = []; - #selectionManager = new UmbSelectionManager(); + #selectionManager = new UmbSelectionManager(this); #userCollectionRepository = new UmbUserCollectionRepository(this); connectedCallback(): void { diff --git a/src/shared/utils/selection-manager.ts b/src/shared/utils/selection-manager.ts index b8d73d63e9..740da02d2c 100644 --- a/src/shared/utils/selection-manager.ts +++ b/src/shared/utils/selection-manager.ts @@ -1,3 +1,6 @@ +import { UmbBaseController } from '@umbraco-cms/backoffice/class-api'; +import { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbSelectionChangeEvent } from '@umbraco-cms/backoffice/event'; import { UmbArrayState, UmbBooleanState } from '@umbraco-cms/backoffice/observable-api'; /** @@ -5,13 +8,38 @@ import { UmbArrayState, UmbBooleanState } from '@umbraco-cms/backoffice/observab * @export * @class UmbSelectionManager */ -export class UmbSelectionManager { +export class UmbSelectionManager extends UmbBaseController { + #selectable = new UmbBooleanState(false); + public readonly selectable = this.#selectable.asObservable(); + #selection = new UmbArrayState(>[], (x) => x); public readonly selection = this.#selection.asObservable(); #multiple = new UmbBooleanState(false); public readonly multiple = this.#multiple.asObservable(); + constructor(host: UmbControllerHost) { + super(host); + } + + /** + * Returns whether items can be selected. + * @return {*} + * @memberof UmbSelectionManager + */ + public getSelectable() { + return this.#selectable.getValue(); + } + + /** + * Sets whether items can be selected. + * @param {boolean} value + * @memberof UmbSelectionManager + */ + public setSelectable(value: boolean) { + this.#selectable.next(value); + } + /** * Returns the current selection. * @return {*} @@ -27,6 +55,7 @@ export class UmbSelectionManager { * @memberof UmbSelectionManager */ public setSelection(value: Array) { + if (this.getSelectable() === false) return; if (value === undefined) throw new Error('Value cannot be undefined'); this.#selection.next(value); } @@ -55,6 +84,7 @@ export class UmbSelectionManager { * @memberof UmbSelectionManager */ public toggleSelect(unique: string | null) { + if (this.getSelectable() === false) return; this.isSelected(unique) ? this.deselect(unique) : this.select(unique); } @@ -64,8 +94,10 @@ export class UmbSelectionManager { * @memberof UmbSelectionManager */ public select(unique: string | null) { + if (this.getSelectable() === false) return; const newSelection = this.getMultiple() ? [...this.getSelection(), unique] : [unique]; this.#selection.next(newSelection); + this._host.getHostElement().dispatchEvent(new UmbSelectionChangeEvent()); } /** @@ -74,8 +106,10 @@ export class UmbSelectionManager { * @memberof UmbSelectionManager */ public deselect(unique: string | null) { + if (this.getSelectable() === false) return; const newSelection = this.getSelection().filter((x) => x !== unique); this.#selection.next(newSelection); + this._host.getHostElement().dispatchEvent(new UmbSelectionChangeEvent()); } /**