diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/tree-repository.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/tree-repository.interface.ts index 46f52b5f06..0ad6c918bf 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/tree-repository.interface.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/tree-repository.interface.ts @@ -6,7 +6,7 @@ import { UmbApi } from '@umbraco-cms/backoffice/extension-api'; export interface UmbTreeRepository< TreeItemType extends EntityTreeItemResponseModel, - TreeRootType extends UmbTreeRootModel = UmbTreeRootEntityModel + TreeRootType extends UmbTreeRootModel = UmbTreeRootEntityModel, > extends UmbApi { requestTreeRoot: () => Promise<{ data?: TreeRootType; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/repository/item/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/repository/item/manifests.ts new file mode 100644 index 0000000000..70162ca789 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/repository/item/manifests.ts @@ -0,0 +1,20 @@ +import { UmbStylesheetItemStore } from './stylesheet-item.store.js'; +import { UmbStylesheetItemRepository } from './stylesheet-item.repository.js'; +import type { ManifestRepository, ManifestItemStore } from '@umbraco-cms/backoffice/extension-registry'; + +export const STYLESHEET_ITEM_REPOSITORY_ALIAS = 'Umb.Repository.StylesheetItem'; +const repository: ManifestRepository = { + type: 'repository', + alias: STYLESHEET_ITEM_REPOSITORY_ALIAS, + name: 'Stylesheet Item Repository', + api: UmbStylesheetItemRepository, +}; + +const itemStore: ManifestItemStore = { + type: 'itemStore', + alias: 'Umb.ItemStore.Stylesheet', + name: 'Stylesheet Item Store', + api: UmbStylesheetItemStore, +}; + +export const manifests = [repository, itemStore]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/repository/item/stylesheet-item.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/repository/item/stylesheet-item.repository.ts new file mode 100644 index 0000000000..d0f31aa9ee --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/repository/item/stylesheet-item.repository.ts @@ -0,0 +1,50 @@ +import { UmbStylesheetItemServerDataSource } from './stylesheet-item.server.data.js'; +import { UMB_STYLESHEET_ITEM_STORE_CONTEXT_TOKEN, UmbStylesheetItemStore } from './stylesheet-item.store.js'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbItemDataSource, UmbItemRepository, UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; +import { StylesheetItemResponseModel, UserItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; + +export class UmbStylesheetItemRepository extends UmbRepositoryBase implements UmbItemRepository { + #init; + #itemSource: UmbItemDataSource; + #itemStore?: UmbStylesheetItemStore; + + constructor(host: UmbControllerHost) { + super(host); + this.#itemSource = new UmbStylesheetItemServerDataSource(host); + + this.#init = this.consumeContext(UMB_STYLESHEET_ITEM_STORE_CONTEXT_TOKEN, (instance) => { + this.#itemStore = instance; + }).asPromise(); + } + + /** + * Requests the stylesheet items for the given ids + * @param {Array} ids + * @return {*} + * @memberof UmbStylesheetItemRepository + */ + async requestItems(ids: Array) { + if (!ids) throw new Error('Ids are missing'); + await this.#init; + + const { data, error } = await this.#itemSource.getItems(ids); + + if (data) { + this.#itemStore?.appendItems(data); + } + + return { data, error, asObservable: () => this.#itemStore!.items(ids) }; + } + + /** + * Returns a promise with an observable of the stylesheet items for the given ids + * @param {Array} ids + * @return {Promise>} + * @memberof UmbStylesheetItemRepository + */ + async items(ids: Array) { + await this.#init; + return this.#itemStore!.items(ids); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/repository/item/stylesheet-item.server.data.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/repository/item/stylesheet-item.server.data.ts new file mode 100644 index 0000000000..2c65c2a56c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/repository/item/stylesheet-item.server.data.ts @@ -0,0 +1,40 @@ +import type { UmbItemDataSource } from '@umbraco-cms/backoffice/repository'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; +import { StylesheetItemResponseModel, StylesheetResource } from '@umbraco-cms/backoffice/backend-api'; + +/** + * A data source for stylesheet items that fetches data from the server + * @export + * @class UmbStylesheetItemServerDataSource + * @implements {UmbItemDataSource} + */ +export class UmbStylesheetItemServerDataSource implements UmbItemDataSource { + #host: UmbControllerHost; + + /** + * Creates an instance of UmbStylesheetItemServerDataSource. + * @param {UmbControllerHost} host + * @memberof UmbStylesheetItemServerDataSource + */ + constructor(host: UmbControllerHost) { + this.#host = host; + } + + /** + * Fetches the items for the given paths from the server + * @param {Array} paths + * @return {*} + * @memberof UmbStylesheetItemServerDataSource + */ + async getItems(paths: Array) { + if (!paths) throw new Error('Paths are missing'); + + return tryExecuteAndNotify( + this.#host, + StylesheetResource.getStylesheetItem({ + path: paths, + }), + ); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/repository/item/stylesheet-item.store.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/repository/item/stylesheet-item.store.ts new file mode 100644 index 0000000000..c80754a7a3 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/repository/item/stylesheet-item.store.ts @@ -0,0 +1,38 @@ +import type { StylesheetItemResponseModel } from '@umbraco-cms/backoffice/backend-api'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; +import type { UmbControllerHostElement } from '@umbraco-cms/backoffice/controller-api'; +import { UmbItemStore, UmbStoreBase } from '@umbraco-cms/backoffice/store'; +import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api'; + +/** + * @export + * @class UmbStylesheetItemStore + * @extends {UmbStoreBase} + * @description - Data Store for Stylesheet items + */ + +export class UmbStylesheetItemStore + extends UmbStoreBase + implements UmbItemStore +{ + /** + * Creates an instance of UmbStylesheetItemStore. + * @param {UmbControllerHostElement} host + * @memberof UmbStylesheetItemStore + */ + constructor(host: UmbControllerHostElement) { + super( + host, + UMB_STYLESHEET_ITEM_STORE_CONTEXT_TOKEN.toString(), + new UmbArrayState([], (x) => x.path), + ); + } + + items(ids: Array) { + return this._data.asObservablePart((items) => items.filter((item) => ids.includes(item.path ?? ''))); + } +} + +export const UMB_STYLESHEET_ITEM_STORE_CONTEXT_TOKEN = new UmbContextToken( + 'UmbStylesheetItemStore', +); diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/repository/manifests.ts index 97f5b9c49f..21121d4f14 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/repository/manifests.ts @@ -1,5 +1,6 @@ import { STYLESHEET_REPOSITORY_ALIAS } from '../config.js'; import { UmbStylesheetRepository } from './stylesheet.repository.js'; +import { manifests as itemManifests } from './item/manifests.js'; import { ManifestRepository } from '@umbraco-cms/backoffice/extension-registry'; const repository: ManifestRepository = { @@ -9,4 +10,4 @@ const repository: ManifestRepository = { api: UmbStylesheetRepository, }; -export const manifests = [repository]; +export const manifests = [repository, itemManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/tree/stylesheet-tree.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/tree/stylesheet-tree.repository.ts index 8f68a1e0dc..e84a6fb730 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/tree/stylesheet-tree.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/tree/stylesheet-tree.repository.ts @@ -61,13 +61,6 @@ export class UmbStylesheetTreeRepository return { data, error, asObservable: () => this.#treeStore!.childrenOf(path) }; } - async requestItems(paths: Array) { - if (!paths) throw new Error('Paths are missing'); - await this.#init; - const { data, error } = await this.#treeDataSource.getItems(paths); - return { data, error }; - } - async rootTreeItems() { await this.#init; return this.#treeStore!.rootItems;