From 542ecfcb41b2416fabc1de0652adc61d8ed48625 Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 17 Apr 2023 16:56:05 +0200 Subject: [PATCH] move store crud logic to base class, add interface + add item store interface --- .../libs/store/entity-tree-store.ts | 46 +++++-------------- .../libs/store/file-system-tree.store.ts | 46 +++++-------------- .../libs/store/item-store.interface.ts | 7 +++ .../libs/store/store-base.ts | 43 ++++++++++++++++- .../libs/store/store.interface.ts | 5 ++ src/Umbraco.Web.UI.Client/libs/store/store.ts | 1 + .../libs/store/tree-store.interface.ts | 8 ++-- 7 files changed, 81 insertions(+), 75 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/libs/store/item-store.interface.ts create mode 100644 src/Umbraco.Web.UI.Client/libs/store/store.interface.ts diff --git a/src/Umbraco.Web.UI.Client/libs/store/entity-tree-store.ts b/src/Umbraco.Web.UI.Client/libs/store/entity-tree-store.ts index ea94db043a..b7817f6c8e 100644 --- a/src/Umbraco.Web.UI.Client/libs/store/entity-tree-store.ts +++ b/src/Umbraco.Web.UI.Client/libs/store/entity-tree-store.ts @@ -1,49 +1,27 @@ import { EntityTreeItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; -import { ArrayState, partialUpdateFrozenArray } from '@umbraco-cms/backoffice/observable-api'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; import { UmbStoreBase, UmbTreeStore } from '@umbraco-cms/backoffice/store'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; /** * @export * @class UmbEntityTreeStore * @extends {UmbStoreBase} - * @description - General Tree Data Store + * @description - Entity Tree Store */ -export class UmbEntityTreeStore extends UmbStoreBase implements UmbTreeStore { - #data = new ArrayState([], (x) => x.id); - - /** - * Appends items to the store - * @param {Array} items - * @memberof UmbEntityTreeStore - */ - appendItems(items: Array) { - this.#data.append(items); - } - - /** - * Updates an item in the store - * @param {string} id - * @param {Partial} data - * @memberof UmbEntityTreeStore - */ - updateItem(id: string, data: Partial) { - this.#data.next(partialUpdateFrozenArray(this.#data.getValue(), data, (entry) => entry.id === id)); - } - - /** - * Removes an item from the store - * @param {string} id - * @memberof UmbEntityTreeStore - */ - removeItem(id: string) { - this.#data.removeOne(id); +export class UmbEntityTreeStore + extends UmbStoreBase + implements UmbTreeStore +{ + constructor(host: UmbControllerHostElement, storeAlias: string) { + super(host, storeAlias, new ArrayState([], (x) => x.id)); } /** * An observable to observe the root items * @memberof UmbEntityTreeStore */ - rootItems = this.#data.getObservablePart((items) => items.filter((item) => item.parentId === null)); + rootItems = this._data.getObservablePart((items) => items.filter((item) => item.parentId === null)); /** * Returns an observable to observe the children of a given parent @@ -52,7 +30,7 @@ export class UmbEntityTreeStore extends UmbStoreBase implements UmbTreeStore items.filter((item) => item.parentId === parentId)); + return this._data.getObservablePart((items) => items.filter((item) => item.parentId === parentId)); } /** @@ -62,6 +40,6 @@ export class UmbEntityTreeStore extends UmbStoreBase implements UmbTreeStore) { - return this.#data.getObservablePart((items) => items.filter((item) => ids.includes(item.id ?? ''))); + return this._data.getObservablePart((items) => items.filter((item) => ids.includes(item.id ?? ''))); } } diff --git a/src/Umbraco.Web.UI.Client/libs/store/file-system-tree.store.ts b/src/Umbraco.Web.UI.Client/libs/store/file-system-tree.store.ts index 8afa8ca62e..e1f7eff059 100644 --- a/src/Umbraco.Web.UI.Client/libs/store/file-system-tree.store.ts +++ b/src/Umbraco.Web.UI.Client/libs/store/file-system-tree.store.ts @@ -1,49 +1,27 @@ import { FileSystemTreeItemPresentationModel } from '@umbraco-cms/backoffice/backend-api'; -import { ArrayState, partialUpdateFrozenArray } from '@umbraco-cms/backoffice/observable-api'; +import { ArrayState } from '@umbraco-cms/backoffice/observable-api'; import { UmbStoreBase, UmbTreeStore } from '@umbraco-cms/backoffice/store'; +import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; /** * @export * @class UmbFileSystemTreeStore * @extends {UmbStoreBase} - * @description - General Tree Data Store + * @description - File System Tree Store */ -export class UmbFileSystemTreeStore extends UmbStoreBase implements UmbTreeStore { - #data = new ArrayState([], (x) => x.path); - - /** - * Appends items to the store - * @param {Array} items - * @memberof UmbFileSystemTreeStore - */ - appendItems(items: Array) { - this.#data.append(items); - } - - /** - * Updates an item in the store - * @param {string} path - * @param {Partial} data - * @memberof UmbFileSystemTreeStore - */ - updateItem(path: string, data: Partial) { - this.#data.appendOne(data); - } - - /** - * Removes an item from the store - * @param {string} path - * @memberof UmbFileSystemTreeStore - */ - removeItem(path: string) { - this.#data.removeOne(path); +export class UmbFileSystemTreeStore + extends UmbStoreBase + implements UmbTreeStore +{ + constructor(host: UmbControllerHostElement, storeAlias: string) { + super(host, storeAlias, new ArrayState([], (x) => x.path)); } /** * An observable to observe the root items * @memberof UmbFileSystemTreeStore */ - rootItems = this.#data.getObservablePart((items) => items.filter((item) => item.path?.includes('/') === false)); + rootItems = this._data.getObservablePart((items) => items.filter((item) => item.path?.includes('/') === false)); /** * Returns an observable to observe the children of a given parent @@ -52,7 +30,7 @@ export class UmbFileSystemTreeStore extends UmbStoreBase implements UmbTreeStore * @memberof UmbFileSystemTreeStore */ childrenOf(parentPath: string | null) { - return this.#data.getObservablePart((items) => items.filter((item) => item.path?.startsWith(parentPath + '/'))); + return this._data.getObservablePart((items) => items.filter((item) => item.path?.startsWith(parentPath + '/'))); } /** @@ -62,6 +40,6 @@ export class UmbFileSystemTreeStore extends UmbStoreBase implements UmbTreeStore * @memberof UmbFileSystemTreeStore */ items(paths: Array) { - return this.#data.getObservablePart((items) => items.filter((item) => paths.includes(item.path ?? ''))); + return this._data.getObservablePart((items) => items.filter((item) => paths.includes(item.path ?? ''))); } } diff --git a/src/Umbraco.Web.UI.Client/libs/store/item-store.interface.ts b/src/Umbraco.Web.UI.Client/libs/store/item-store.interface.ts new file mode 100644 index 0000000000..d5d8e3d124 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/store/item-store.interface.ts @@ -0,0 +1,7 @@ +import type { Observable } from 'rxjs'; +import { ItemResponseModelBaseModel } from '../backend-api'; +import { UmbStore } from './store.interface'; + +export interface UmbItemStore extends UmbStore { + items: (uniques: Array) => Observable>; +} diff --git a/src/Umbraco.Web.UI.Client/libs/store/store-base.ts b/src/Umbraco.Web.UI.Client/libs/store/store-base.ts index 4021307cd6..36589bda21 100644 --- a/src/Umbraco.Web.UI.Client/libs/store/store-base.ts +++ b/src/Umbraco.Web.UI.Client/libs/store/store-base.ts @@ -1,9 +1,48 @@ +import { UmbStore } from './store.interface'; import { UmbContextProviderController } from '@umbraco-cms/backoffice/context-api'; import { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller'; +import { ArrayState, partialUpdateFrozenArray } from '@umbraco-cms/backoffice/observable-api'; // TODO: Make a Store interface? -export class UmbStoreBase { - constructor(protected _host: UmbControllerHostElement, public readonly storeAlias: string) { +export class UmbStoreBase implements UmbStore { + protected _host: UmbControllerHostElement; + protected _data: ArrayState; + + public readonly storeAlias: string; + + constructor(_host: UmbControllerHostElement, storeAlias: string, data: ArrayState) { + this._host = _host; + this.storeAlias = storeAlias; + this._data = data; + new UmbContextProviderController(_host, storeAlias, this); } + + /** + * Appends items to the store + * @param {Array} items + * @memberof UmbEntityTreeStore + */ + appendItems(items: Array) { + this._data.append(items); + } + + /** + * Updates an item in the store + * @param {string} id + * @param {Partial} data + * @memberof UmbEntityTreeStore + */ + updateItem(id: string, data: Partial) { + this._data.next(partialUpdateFrozenArray(this._data.getValue(), data, (entry) => entry.id === id)); + } + + /** + * Removes an item from the store + * @param {string} id + * @memberof UmbEntityTreeStore + */ + removeItem(id: string) { + this._data.removeOne(id); + } } diff --git a/src/Umbraco.Web.UI.Client/libs/store/store.interface.ts b/src/Umbraco.Web.UI.Client/libs/store/store.interface.ts new file mode 100644 index 0000000000..0f094a1d4f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/libs/store/store.interface.ts @@ -0,0 +1,5 @@ +export interface UmbStore { + appendItems: (items: Array) => void; + updateItem: (unique: string, item: Partial) => void; + removeItem: (unique: string) => void; +} diff --git a/src/Umbraco.Web.UI.Client/libs/store/store.ts b/src/Umbraco.Web.UI.Client/libs/store/store.ts index 4961162767..b2c48aedde 100644 --- a/src/Umbraco.Web.UI.Client/libs/store/store.ts +++ b/src/Umbraco.Web.UI.Client/libs/store/store.ts @@ -1,3 +1,4 @@ +// TODO: delete when the last usages are gone import type { Observable } from 'rxjs'; export interface UmbDataStoreIdentifiers { diff --git a/src/Umbraco.Web.UI.Client/libs/store/tree-store.interface.ts b/src/Umbraco.Web.UI.Client/libs/store/tree-store.interface.ts index 80a366ada5..cbe7b563d8 100644 --- a/src/Umbraco.Web.UI.Client/libs/store/tree-store.interface.ts +++ b/src/Umbraco.Web.UI.Client/libs/store/tree-store.interface.ts @@ -1,12 +1,10 @@ import type { Observable } from 'rxjs'; import { TreeItemPresentationModel } from '../backend-api'; +import { UmbStore } from './store.interface'; -export interface UmbTreeStore { - appendItems: (items: Array) => void; - updateItem: (unique: string, item: Partial) => void; - removeItem: (unique: string) => void; - +export interface UmbTreeStore extends UmbStore { rootItems: Observable>; childrenOf: (parentUnique: string | null) => Observable>; + // TODO: remove this one when all repositories are using an item store items: (uniques: Array) => Observable>; }