From 822cfe9c286a1b40e2015dab8e6ed8ddda9dca0b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Thu, 8 May 2025 11:17:57 +0200 Subject: [PATCH] Batch item rest requests (#19233) --- .../src/packages/core/entity-item/index.ts | 1 + .../index.ts | 1 + .../item-data-api-get-request.controller.ts | 66 +++++++++++++++++++ .../types.ts | 6 ++ .../src/packages/core/entity-item/types.ts | 1 + .../item/item-server-data-source-base.ts | 24 ++++--- .../packages/core/resources/data-api/types.ts | 3 + .../src/packages/core/resources/index.ts | 13 ++-- .../try-execute/batch-try-execute.function.ts | 17 +++++ .../core/resources/try-execute/index.ts | 5 ++ .../try-execute.controller.ts | 8 +-- .../{ => try-execute}/tryExecute.function.ts | 2 +- .../tryExecuteAndNotify.function.ts | 2 +- .../tryXhrRequest.function.ts | 8 +-- .../src/packages/core/resources/types.ts | 1 + .../core/utils/array/batch-array.test.ts | 25 +++++++ .../packages/core/utils/array/batch-array.ts | 16 +++++ .../src/packages/core/utils/array/index.ts | 1 + .../src/packages/core/utils/index.ts | 1 + .../item/data-type-item.server.data-source.ts | 19 ++++-- .../dictionary-item.server.data-source.ts | 19 ++++-- ...ument-blueprint-item.server.data-source.ts | 24 ++++--- .../document-type-item.server.data-source.ts | 20 ++++-- .../document-item.server.data-source.ts | 19 ++++-- .../document-url.server.data-source.ts | 20 ++++-- .../item/language-item.server.data-source.ts | 19 ++++-- .../media-type-item.server.data-source.ts | 19 ++++-- .../item/media-item.server.data-source.ts | 26 +++++--- .../media-url.server.data-source.ts | 19 ++++-- .../member-group-item.server.data-source.ts | 19 ++++-- .../member-type-item.server.data-source.ts | 19 ++++-- .../member-item.server.data-source.ts | 19 ++++-- .../static-file-item.server.data-source.ts | 27 +++++--- .../item/template-item.server.data-source.ts | 19 ++++-- .../user-group-item.server.data-source.ts | 19 ++++-- .../item/user-item.server.data-source.ts | 19 ++++-- .../item/webhook-item.server.data-source.ts | 19 ++++-- 37 files changed, 450 insertions(+), 115 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-item/item-data-api-get-request-controller/index.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-item/item-data-api-get-request-controller/item-data-api-get-request.controller.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/entity-item/item-data-api-get-request-controller/types.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/resources/data-api/types.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/batch-try-execute.function.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/index.ts rename src/Umbraco.Web.UI.Client/src/packages/core/resources/{ => try-execute}/try-execute.controller.ts (86%) rename src/Umbraco.Web.UI.Client/src/packages/core/resources/{ => try-execute}/tryExecute.function.ts (93%) rename src/Umbraco.Web.UI.Client/src/packages/core/resources/{ => try-execute}/tryExecuteAndNotify.function.ts (96%) rename src/Umbraco.Web.UI.Client/src/packages/core/resources/{ => try-execute}/tryXhrRequest.function.ts (94%) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/array/batch-array.test.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/array/batch-array.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/core/utils/array/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/index.ts index 5ada9eda75..a0ee69f820 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/index.ts @@ -1 +1,2 @@ +export * from './item-data-api-get-request-controller/index.js'; export * from './entity-item-ref/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/item-data-api-get-request-controller/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/item-data-api-get-request-controller/index.ts new file mode 100644 index 0000000000..5bd7a5f06f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/item-data-api-get-request-controller/index.ts @@ -0,0 +1 @@ +export * from './item-data-api-get-request.controller.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/item-data-api-get-request-controller/item-data-api-get-request.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/item-data-api-get-request-controller/item-data-api-get-request.controller.ts new file mode 100644 index 0000000000..b10a783b97 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/item-data-api-get-request-controller/item-data-api-get-request.controller.ts @@ -0,0 +1,66 @@ +import type { UmbItemDataApiGetRequestControllerArgs } from './types.js'; +import { + batchTryExecute, + tryExecute, + UmbError, + type UmbApiError, + type UmbCancelError, + type UmbDataApiResponse, +} from '@umbraco-cms/backoffice/resources'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { batchArray } from '@umbraco-cms/backoffice/utils'; +import { umbPeekError } from '@umbraco-cms/backoffice/notification'; +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; + +export class UmbItemDataApiGetRequestController< + ResponseModelType extends UmbDataApiResponse, +> extends UmbControllerBase { + #apiCallback: (args: { uniques: Array }) => Promise; + #uniques: Array; + #batchSize: number = 40; + + constructor(host: UmbControllerHost, args: UmbItemDataApiGetRequestControllerArgs) { + super(host); + this.#apiCallback = args.api; + this.#uniques = args.uniques; + } + + async request() { + if (!this.#uniques) throw new Error('Uniques are missing'); + + let data: ResponseModelType['data'] | undefined; + let error: UmbError | UmbApiError | UmbCancelError | Error | undefined; + + if (this.#uniques.length > this.#batchSize) { + const chunks = batchArray(this.#uniques, this.#batchSize); + const results = await batchTryExecute(this, chunks, (chunk) => this.#apiCallback({ uniques: chunk })); + + const errors = results.filter((promiseResult) => promiseResult.status === 'rejected'); + + if (errors.length > 0) { + error = await this.#getAndHandleErrorResult(errors); + } + + data = results + .filter((promiseResult) => promiseResult.status === 'fulfilled') + .flatMap((promiseResult) => promiseResult.value.data); + } else { + const result = await tryExecute(this, this.#apiCallback({ uniques: this.#uniques })); + data = result.data; + error = result.error; + } + + return { data, error }; + } + + async #getAndHandleErrorResult(errors: Array) { + // TODO: We currently expect all the errors to be the same, but we should handle this better in the future. + const error = errors[0]; + await umbPeekError(this, { + headline: 'Error fetching items', + message: 'An error occurred while fetching items.', + }); + + return new UmbError(error.reason); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/item-data-api-get-request-controller/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/item-data-api-get-request-controller/types.ts new file mode 100644 index 0000000000..fc4f1a47e4 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/item-data-api-get-request-controller/types.ts @@ -0,0 +1,6 @@ +import type { UmbDataApiResponse } from '@umbraco-cms/backoffice/resources'; + +export interface UmbItemDataApiGetRequestControllerArgs { + api: (args: { uniques: Array }) => Promise; + uniques: Array; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/types.ts index 31240f7f67..78aae14245 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/entity-item/types.ts @@ -1,4 +1,5 @@ import type { UmbNamedEntityModel } from '@umbraco-cms/backoffice/entity'; +export type * from './item-data-api-get-request-controller/types.js'; export interface UmbDefaultItemModel extends UmbNamedEntityModel { icon?: string; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/repository/item/item-server-data-source-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/repository/item/item-server-data-source-base.ts index 02df1f5429..8e3f1eeea5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/repository/item/item-server-data-source-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/repository/item/item-server-data-source-base.ts @@ -1,10 +1,11 @@ +import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import type { UmbDataSourceResponse } from '../data-source-response.interface.js'; import type { UmbItemDataSource } from './item-data-source.interface.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { tryExecute } from '@umbraco-cms/backoffice/resources'; export interface UmbItemServerDataSourceBaseArgs { - getItems: (uniques: Array) => Promise>>; + getItems?: (uniques: Array) => Promise>>; mapper: (item: ServerItemType) => ClientItemType; } @@ -14,10 +15,10 @@ export interface UmbItemServerDataSourceBaseArgs + extends UmbControllerBase implements UmbItemDataSource { - #host: UmbControllerHost; - #getItems: (uniques: Array) => Promise>>; + #getItems?: (uniques: Array) => Promise>>; #mapper: (item: ServerItemType) => ClientItemType; /** @@ -27,7 +28,7 @@ export abstract class UmbItemServerDataSourceBase) { - this.#host = host; + super(host); this.#getItems = args.getItems; this.#mapper = args.mapper; } @@ -39,14 +40,17 @@ export abstract class UmbItemServerDataSourceBase) { + if (!this.#getItems) throw new Error('getItems is not implemented'); if (!uniques) throw new Error('Uniques are missing'); - const { data, error } = await tryExecute(this.#host, this.#getItems(uniques)); - if (data) { - const items = data.map((item) => this.#mapper(item)); - return { data: items }; - } + const { data, error } = await tryExecute(this, this.#getItems(uniques)); - return { error }; + return { data: this._getMappedItems(data), error }; + } + + protected _getMappedItems(items: Array | undefined): Array | undefined { + if (!items) return undefined; + if (!this.#mapper) throw new Error('Mapper is not implemented'); + return items.map((item) => this.#mapper(item)); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/resources/data-api/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/resources/data-api/types.ts new file mode 100644 index 0000000000..dfade83718 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/resources/data-api/types.ts @@ -0,0 +1,3 @@ +export interface UmbDataApiResponse { + data: ResponseType['data']; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/resources/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/resources/index.ts index e1e1756111..04e74539c4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/resources/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/resources/index.ts @@ -1,12 +1,9 @@ export * from './api-interceptor.controller.js'; -export * from './resource.controller.js'; -export * from './try-execute.controller.js'; -export * from './tryExecute.function.js'; -export * from './tryExecuteAndNotify.function.js'; -export * from './tryXhrRequest.function.js'; -export * from './extractUmbNotificationColor.function.js'; -export * from './extractUmbColorVariable.function.js'; -export * from './isUmbNotifications.function.js'; export * from './apiTypeValidators.function.js'; +export * from './extractUmbColorVariable.function.js'; +export * from './extractUmbNotificationColor.function.js'; +export * from './isUmbNotifications.function.js'; +export * from './resource.controller.js'; +export * from './try-execute/index.js'; export * from './umb-error.js'; export type * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/batch-try-execute.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/batch-try-execute.function.ts new file mode 100644 index 0000000000..47a810ceb8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/batch-try-execute.function.ts @@ -0,0 +1,17 @@ +import { tryExecute } from './tryExecute.function.js'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; + +/** + * Batches promises and returns a promise that resolves to an array of results + * @param {UmbControllerHost} host - The host to use for the request and where notifications will be shown + * @param {Array>} chunks - The array of chunks to process + * @param {(chunk: Array) => Promise} callback - The function to call for each chunk + * @returns {Promise[]>} - A promise that resolves to an array of results + */ +export function batchTryExecute( + host: UmbControllerHost, + chunks: Array>, + callback: (chunk: Array) => Promise, +): Promise[]> { + return Promise.allSettled(chunks.map((chunk) => tryExecute(host, callback(chunk), { disableNotifications: true }))); +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/index.ts new file mode 100644 index 0000000000..18d2ee9f97 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/index.ts @@ -0,0 +1,5 @@ +export * from './batch-try-execute.function.js'; +export * from './try-execute.controller.js'; +export * from './tryExecute.function.js'; +export * from './tryExecuteAndNotify.function.js'; +export * from './tryXhrRequest.function.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute.controller.ts b/src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/try-execute.controller.ts similarity index 86% rename from src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute.controller.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/try-execute.controller.ts index 353c081138..afca34ad55 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute.controller.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/try-execute.controller.ts @@ -1,7 +1,7 @@ -import { isProblemDetailsLike } from './apiTypeValidators.function.js'; -import { UmbResourceController } from './resource.controller.js'; -import type { UmbApiResponse, UmbTryExecuteOptions } from './types.js'; -import { UmbApiError, UmbCancelError } from './umb-error.js'; +import { isProblemDetailsLike } from '../apiTypeValidators.function.js'; +import { UmbResourceController } from '../resource.controller.js'; +import type { UmbApiResponse, UmbTryExecuteOptions } from '../types.js'; +import { UmbApiError, UmbCancelError } from '../umb-error.js'; export class UmbTryExecuteController extends UmbResourceController { #abortSignal?: AbortSignal; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/resources/tryExecute.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/tryExecute.function.ts similarity index 93% rename from src/Umbraco.Web.UI.Client/src/packages/core/resources/tryExecute.function.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/tryExecute.function.ts index 07c4b26cfd..7deca7c0e4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/resources/tryExecute.function.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/tryExecute.function.ts @@ -1,5 +1,5 @@ +import type { UmbApiResponse, UmbTryExecuteOptions } from '../types.js'; import { UmbTryExecuteController } from './try-execute.controller.js'; -import type { UmbApiResponse, UmbTryExecuteOptions } from './types.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; /** diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/resources/tryExecuteAndNotify.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/tryExecuteAndNotify.function.ts similarity index 96% rename from src/Umbraco.Web.UI.Client/src/packages/core/resources/tryExecuteAndNotify.function.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/tryExecuteAndNotify.function.ts index 1708d759c0..6bddf902de 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/resources/tryExecuteAndNotify.function.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/tryExecuteAndNotify.function.ts @@ -1,5 +1,5 @@ +import type { UmbApiResponse } from '../types.js'; import { UmbTryExecuteController } from './try-execute.controller.js'; -import type { UmbApiResponse } from './types.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbDeprecation } from '@umbraco-cms/backoffice/utils'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/resources/tryXhrRequest.function.ts b/src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/tryXhrRequest.function.ts similarity index 94% rename from src/Umbraco.Web.UI.Client/src/packages/core/resources/tryXhrRequest.function.ts rename to src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/tryXhrRequest.function.ts index a2e96d5d40..2be9e84fa7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/resources/tryXhrRequest.function.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/resources/try-execute/tryXhrRequest.function.ts @@ -1,8 +1,8 @@ +import { UmbCancelablePromise } from '../cancelable-promise.js'; +import { UmbApiError } from '../umb-error.js'; +import { isProblemDetailsLike } from '../apiTypeValidators.function.js'; +import type { UmbApiResponse, XhrRequestOptions } from '../types.js'; import { UmbTryExecuteController } from './try-execute.controller.js'; -import { UmbCancelablePromise } from './cancelable-promise.js'; -import { UmbApiError } from './umb-error.js'; -import { isProblemDetailsLike } from './apiTypeValidators.function.js'; -import type { UmbApiResponse, XhrRequestOptions } from './types.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { umbHttpClient } from '@umbraco-cms/backoffice/http-client'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/resources/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/resources/types.ts index fd7413e8f1..6a438f0bab 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/resources/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/resources/types.ts @@ -1,4 +1,5 @@ import type { UmbApiError, UmbCancelError, UmbError } from './umb-error.js'; +export type * from './data-api/types.js'; export interface XhrRequestOptions extends UmbTryExecuteOptions { baseUrl?: string; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/array/batch-array.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/array/batch-array.test.ts new file mode 100644 index 0000000000..e958f3fea1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/array/batch-array.test.ts @@ -0,0 +1,25 @@ +import { expect } from '@open-wc/testing'; +import { batchArray } from './batch-array.js'; + +describe('batchArray', () => { + it('should split an array into chunks of the specified size', () => { + const array = [1, 2, 3, 4, 5]; + const batchSize = 2; + const result = batchArray(array, batchSize); + expect(result).to.deep.equal([[1, 2], [3, 4], [5]]); + }); + + it('should handle arrays smaller than the batch size', () => { + const array = [1]; + const batchSize = 2; + const result = batchArray(array, batchSize); + expect(result).to.deep.equal([[1]]); + }); + + it('should handle empty arrays', () => { + const array: number[] = []; + const batchSize = 2; + const result = batchArray(array, batchSize); + expect(result).to.deep.equal([]); + }); +}); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/array/batch-array.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/array/batch-array.ts new file mode 100644 index 0000000000..fde5b6703d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/array/batch-array.ts @@ -0,0 +1,16 @@ +/** + * Splits an array into chunks of a specified size + * @param { Array } array - The array to split + * @param {number }batchSize - The size of each chunk + * @returns {Array>} - An array of chunks + */ +export function batchArray( + array: Array, + batchSize: number, +): Array> { + const chunks: Array> = []; + for (let i = 0; i < array.length; i += batchSize) { + chunks.push(array.slice(i, i + batchSize)); + } + return chunks; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/array/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/array/index.ts new file mode 100644 index 0000000000..106dce2d85 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/array/index.ts @@ -0,0 +1 @@ +export * from './batch-array.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts index aa191db2e7..a59e5dc990 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/utils/index.ts @@ -1,3 +1,4 @@ +export * from './array/index.js'; export * from './bytes/bytes.function.js'; export * from './debounce/debounce.function.js'; export * from './deprecation/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/data-type-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/data-type-item.server.data-source.ts index d373f16b32..4b578c8b1d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/data-type-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/repository/item/data-type-item.server.data-source.ts @@ -6,6 +6,7 @@ import { DataTypeService } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import type { ManifestPropertyEditorUi } from '@umbraco-cms/backoffice/property-editor'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; let manifestPropertyEditorUis: Array = []; @@ -26,7 +27,6 @@ export class UmbDataTypeItemServerDataSource extends UmbItemServerDataSourceBase constructor(host: UmbControllerHost) { super(host, { - getItems, mapper, }); @@ -37,10 +37,21 @@ export class UmbDataTypeItemServerDataSource extends UmbItemServerDataSourceBase }) .unsubscribe(); } -} -/* eslint-disable local-rules/no-direct-api-import */ -const getItems = (uniques: Array) => DataTypeService.getItemDataType({ query: { id: uniques } }); + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => DataTypeService.getItemDataType({ query: { id: args.uniques } }), + uniques, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; + } +} const mapper = (item: DataTypeItemResponseModel): UmbDataTypeItemModel => { return { diff --git a/src/Umbraco.Web.UI.Client/src/packages/dictionary/repository/item/dictionary-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/dictionary/repository/item/dictionary-item.server.data-source.ts index c5b3714b91..245931dbfc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/dictionary/repository/item/dictionary-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/dictionary/repository/item/dictionary-item.server.data-source.ts @@ -4,6 +4,7 @@ import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository' import type { DictionaryItemItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { DictionaryService } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; /** * A server data source for Dictionary items @@ -21,14 +22,24 @@ export class UmbDictionaryItemServerDataSource extends UmbItemServerDataSourceBa */ constructor(host: UmbControllerHost) { super(host, { - getItems, mapper, }); } -} -/* eslint-disable local-rules/no-direct-api-import */ -const getItems = (uniques: Array) => DictionaryService.getItemDictionary({ query: { id: uniques } }); + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => DictionaryService.getItemDictionary({ query: { id: args.uniques } }), + uniques, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; + } +} const mapper = (item: DictionaryItemItemResponseModel): UmbDictionaryItemModel => { return { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/repository/item/document-blueprint-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/repository/item/document-blueprint-item.server.data-source.ts index 104ecfbee1..bc44153a60 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/repository/item/document-blueprint-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/repository/item/document-blueprint-item.server.data-source.ts @@ -5,6 +5,7 @@ import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository' import type { DocumentBlueprintItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { tryExecute } from '@umbraco-cms/backoffice/resources'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; /** * A data source for Document Blueprint items that fetches data from the server @@ -15,7 +16,6 @@ export class UmbDocumentBlueprintItemServerDataSource extends UmbItemServerDataS DocumentBlueprintItemResponseModel, UmbDocumentBlueprintItemModel > { - #host: UmbControllerHost; /** * Creates an instance of UmbDocumentBlueprintItemServerDataSource. * @param {UmbControllerHost} host - The controller host for this controller to be appended to @@ -23,16 +23,14 @@ export class UmbDocumentBlueprintItemServerDataSource extends UmbItemServerDataS */ constructor(host: UmbControllerHost) { super(host, { - getItems, mapper, }); - this.#host = host; } async getItemsByDocumentType(unique: string) { if (!unique) throw new Error('Unique is missing'); const { data, error } = await tryExecute( - this.#host, + this, DocumentTypeService.getDocumentTypeByIdBlueprint({ path: { id: unique } }), ); @@ -47,11 +45,21 @@ export class UmbDocumentBlueprintItemServerDataSource extends UmbItemServerDataS return { error }; } -} -/* eslint-disable local-rules/no-direct-api-import */ -const getItems = (uniques: Array) => - DocumentBlueprintService.getItemDocumentBlueprint({ query: { id: uniques } }); + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => DocumentBlueprintService.getItemDocumentBlueprint({ query: { id: args.uniques } }), + uniques, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; + } +} const mapper = (item: DocumentBlueprintItemResponseModel): UmbDocumentBlueprintItemModel => { return { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item.server.data-source.ts index 1fed1d9574..f68f70d88c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/item/document-type-item.server.data-source.ts @@ -4,6 +4,7 @@ import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository' import type { DocumentTypeItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { DocumentTypeService } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; /** * A data source for Document Type items that fetches data from the server @@ -20,13 +21,24 @@ export class UmbDocumentTypeItemServerDataSource extends UmbItemServerDataSource * @memberof UmbDocumentTypeItemServerDataSource */ constructor(host: UmbControllerHost) { - super(host, { getItems, mapper }); + super(host, { mapper }); + } + + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => DocumentTypeService.getItemDocumentType({ query: { id: args.uniques } }), + uniques, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; } } -/* eslint-disable local-rules/no-direct-api-import */ -const getItems = (uniques: Array) => DocumentTypeService.getItemDocumentType({ query: { id: uniques } }); - const mapper = (item: DocumentTypeItemResponseModel): UmbDocumentTypeItemModel => { return { entityType: UMB_DOCUMENT_TYPE_ENTITY_TYPE, diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/document-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/document-item.server.data-source.ts index a9e2dfe005..5c6453b35e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/document-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/item/repository/document-item.server.data-source.ts @@ -4,6 +4,7 @@ import type { DocumentItemResponseModel } from '@umbraco-cms/backoffice/external import { DocumentService } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; /** * A data source for Document items that fetches data from the server @@ -21,14 +22,24 @@ export class UmbDocumentItemServerDataSource extends UmbItemServerDataSourceBase */ constructor(host: UmbControllerHost) { super(host, { - getItems, mapper, }); } -} -/* eslint-disable local-rules/no-direct-api-import */ -const getItems = (uniques: Array) => DocumentService.getItemDocument({ query: { id: uniques } }); + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => DocumentService.getItemDocument({ query: { id: args.uniques } }), + uniques, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; + } +} const mapper = (item: DocumentItemResponseModel): UmbDocumentItemModel => { return { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/url/repository/document-url.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/url/repository/document-url.server.data-source.ts index bcf61c137d..8891d6b6c1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/url/repository/document-url.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/url/repository/document-url.server.data-source.ts @@ -3,6 +3,7 @@ import { DocumentService } from '@umbraco-cms/backoffice/external/backend-api'; import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository'; import type { DocumentUrlInfoResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; /** * A server data source for Document URLs @@ -19,11 +20,22 @@ export class UmbDocumentUrlServerDataSource extends UmbItemServerDataSourceBase< * @memberof UmbDocumentUrlServerDataSource */ constructor(host: UmbControllerHost) { - super(host, { getItems, mapper }); + super(host, { mapper }); + } + + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => DocumentService.getDocumentUrls({ query: { id: args.uniques } }), + uniques, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; } } -/* eslint-disable local-rules/no-direct-api-import */ -const getItems = (uniques: Array) => DocumentService.getDocumentUrls({ query: { id: uniques } }); - const mapper = (item: DocumentUrlInfoResponseModel): UmbDocumentUrlsModel => ({ unique: item.id, urls: item.urlInfos }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/language/repository/item/language-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/language/repository/item/language-item.server.data-source.ts index 3e9b7e5fe9..b38c275278 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/language/repository/item/language-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/language/repository/item/language-item.server.data-source.ts @@ -4,6 +4,7 @@ import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository' import type { LanguageItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { LanguageService } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; /** * A server data source for Language items @@ -21,14 +22,24 @@ export class UmbLanguageItemServerDataSource extends UmbItemServerDataSourceBase */ constructor(host: UmbControllerHost) { super(host, { - getItems, mapper, }); } -} -/* eslint-disable local-rules/no-direct-api-import */ -const getItems = (uniques: Array) => LanguageService.getItemLanguage({ query: { isoCode: uniques } }); + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => LanguageService.getItemLanguage({ query: { isoCode: args.uniques } }), + uniques, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; + } +} const mapper = (item: LanguageItemResponseModel): UmbLanguageItemModel => { return { diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/item/media-type-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/item/media-type-item.server.data-source.ts index 8897295e51..402cb410a8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/item/media-type-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/item/media-type-item.server.data-source.ts @@ -4,6 +4,7 @@ import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository' import type { MediaTypeItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { MediaTypeService } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; /** * A data source for Media Type items that fetches data from the server @@ -21,14 +22,24 @@ export class UmbMediaTypeItemServerDataSource extends UmbItemServerDataSourceBas */ constructor(host: UmbControllerHost) { super(host, { - getItems, mapper, }); } -} -/* eslint-disable local-rules/no-direct-api-import */ -const getItems = (uniques: Array) => MediaTypeService.getItemMediaType({ query: { id: uniques } }); + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => MediaTypeService.getItemMediaType({ query: { id: args.uniques } }), + uniques, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; + } +} const mapper = (item: MediaTypeItemResponseModel): UmbMediaTypeItemModel => { return { diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/item/media-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/item/media-item.server.data-source.ts index e56a7d9567..d4edb0f5fc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/item/media-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/item/media-item.server.data-source.ts @@ -5,6 +5,7 @@ import { MediaService } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository'; import { tryExecute } from '@umbraco-cms/backoffice/resources'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; /** * A data source for Media items that fetches data from the server @@ -15,7 +16,6 @@ export class UmbMediaItemServerDataSource extends UmbItemServerDataSourceBase< MediaItemResponseModel, UmbMediaItemModel > { - #host: UmbControllerHost; /** * Creates an instance of UmbMediaItemServerDataSource. * @param {UmbControllerHost} host - The controller host for this controller to be appended to @@ -23,10 +23,8 @@ export class UmbMediaItemServerDataSource extends UmbItemServerDataSourceBase< */ constructor(host: UmbControllerHost) { super(host, { - getItems, mapper, }); - this.#host = host; } /** @@ -38,17 +36,25 @@ export class UmbMediaItemServerDataSource extends UmbItemServerDataSourceBase< * ``` */ async search({ query, skip, take }: { query: string; skip: number; take: number }) { - const { data, error } = await tryExecute( - this.#host, - MediaService.getItemMediaSearch({ query: { query, skip, take } }), - ); + const { data, error } = await tryExecute(this, MediaService.getItemMediaSearch({ query: { query, skip, take } })); const mapped = data?.items.map((item) => mapper(item)); return { data: mapped, error }; } -} -/* eslint-disable local-rules/no-direct-api-import */ -const getItems = (uniques: Array) => MediaService.getItemMedia({ query: { id: uniques } }); + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => MediaService.getItemMedia({ query: { id: args.uniques } }), + uniques, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; + } +} const mapper = (item: MediaItemResponseModel): UmbMediaItemModel => { return { diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/url/repository/media-url.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/url/repository/media-url.server.data-source.ts index d52e8952c6..24571d50d3 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/url/repository/media-url.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/url/repository/media-url.server.data-source.ts @@ -1,5 +1,6 @@ import type { UmbMediaUrlModel } from './types.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; import { MediaService, type MediaUrlInfoResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository'; @@ -19,14 +20,24 @@ export class UmbMediaUrlServerDataSource extends UmbItemServerDataSourceBase< */ constructor(host: UmbControllerHost) { super(host, { - getItems, mapper, }); } -} -/* eslint-disable local-rules/no-direct-api-import */ -const getItems = (uniques: Array) => MediaService.getMediaUrls({ query: { id: uniques } }); + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => MediaService.getMediaUrls({ query: { id: args.uniques } }), + uniques, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; + } +} const mapper = (item: MediaUrlInfoResponseModel): UmbMediaUrlModel => { const url = item.urlInfos.length ? item.urlInfos[0].url : undefined; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-group/repository/item/member-group-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-group/repository/item/member-group-item.server.data-source.ts index 3bdf68a8ee..6840673866 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member-group/repository/item/member-group-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-group/repository/item/member-group-item.server.data-source.ts @@ -4,6 +4,7 @@ import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository' import type { MemberGroupItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { MemberGroupService } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; /** * A server data source for Member Group items @@ -21,14 +22,24 @@ export class UmbMemberGroupItemServerDataSource extends UmbItemServerDataSourceB */ constructor(host: UmbControllerHost) { super(host, { - getItems, mapper, }); } -} -/* eslint-disable local-rules/no-direct-api-import */ -const getItems = (uniques: Array) => MemberGroupService.getItemMemberGroup({ query: { id: uniques } }); + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => MemberGroupService.getItemMemberGroup({ query: { id: args.uniques } }), + uniques, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; + } +} const mapper = (item: MemberGroupItemResponseModel): UmbMemberGroupItemModel => { return { diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/item/member-type-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/item/member-type-item.server.data-source.ts index c83d7443b9..68444ad9ef 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/item/member-type-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/item/member-type-item.server.data-source.ts @@ -4,6 +4,7 @@ import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository' import type { MemberTypeItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { MemberTypeService } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; /** * A server data source for Member Type items @@ -21,14 +22,24 @@ export class UmbMemberTypeItemServerDataSource extends UmbItemServerDataSourceBa */ constructor(host: UmbControllerHost) { super(host, { - getItems, mapper, }); } -} -/* eslint-disable local-rules/no-direct-api-import */ -const getItems = (uniques: Array) => MemberTypeService.getItemMemberType({ query: { id: uniques } }); + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => MemberTypeService.getItemMemberType({ query: { id: args.uniques } }), + uniques, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; + } +} const mapper = (item: MemberTypeItemResponseModel): UmbMemberTypeItemModel => { return { diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/member-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/member-item.server.data-source.ts index 2853948b74..adc992d919 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/member-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/item/repository/member-item.server.data-source.ts @@ -4,6 +4,7 @@ import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository' import type { MemberItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { MemberService } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; /** * A server data source for Member items @@ -21,14 +22,24 @@ export class UmbMemberItemServerDataSource extends UmbItemServerDataSourceBase< */ constructor(host: UmbControllerHost) { super(host, { - getItems, mapper, }); } -} -/* eslint-disable local-rules/no-direct-api-import */ -const getItems = (uniques: Array) => MemberService.getItemMember({ query: { id: uniques } }); + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => MemberService.getItemMember({ query: { id: args.uniques } }), + uniques, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; + } +} const mapper = (item: MemberItemResponseModel): UmbMemberItemModel => { return { diff --git a/src/Umbraco.Web.UI.Client/src/packages/static-file/repository/item/static-file-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/static-file/repository/item/static-file-item.server.data-source.ts index 3eba1cef8b..5e38b171e7 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/static-file/repository/item/static-file-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/static-file/repository/item/static-file-item.server.data-source.ts @@ -4,6 +4,7 @@ import type { StaticFileItemResponseModel } from '@umbraco-cms/backoffice/extern import { StaticFileService } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbServerFilePathUniqueSerializer } from '@umbraco-cms/backoffice/server-file-system'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; /** * A server data source for Static File items @@ -21,20 +22,28 @@ export class UmbStaticFileItemServerDataSource extends UmbItemServerDataSourceBa */ constructor(host: UmbControllerHost) { super(host, { - getItems, mapper, }); } + + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const serializer = new UmbServerFilePathUniqueSerializer(); + const paths = uniques.map((unique) => serializer.toServerPath(unique)!); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => StaticFileService.getItemStaticFile({ query: { path: args.uniques } }), + uniques: paths, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; + } } -const getItems = (uniques: Array) => { - const serializer = new UmbServerFilePathUniqueSerializer(); - const path = uniques.map((unique) => serializer.toServerPath(unique)!); - - /* eslint-disable local-rules/no-direct-api-import */ - return StaticFileService.getItemStaticFile({ query: { path } }); -}; - const mapper = (item: StaticFileItemResponseModel): UmbStaticFileItemModel => { const serializer = new UmbServerFilePathUniqueSerializer(); return { diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/repository/item/template-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/repository/item/template-item.server.data-source.ts index 2e5fc3c7c2..9355611023 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/repository/item/template-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/repository/item/template-item.server.data-source.ts @@ -4,6 +4,7 @@ import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository' import type { TemplateItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { TemplateService } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; /** * A server data source for Template items @@ -21,14 +22,24 @@ export class UmbTemplateItemServerDataSource extends UmbItemServerDataSourceBase */ constructor(host: UmbControllerHost) { super(host, { - getItems, mapper, }); } -} -/* eslint-disable local-rules/no-direct-api-import */ -const getItems = (uniques: Array) => TemplateService.getItemTemplate({ query: { id: uniques } }); + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => TemplateService.getItemTemplate({ query: { id: args.uniques } }), + uniques, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; + } +} const mapper = (item: TemplateItemResponseModel): UmbTemplateItemModel => { return { diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/repository/item/user-group-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/repository/item/user-group-item.server.data-source.ts index fdb9236739..aad5b6ef54 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user-group/repository/item/user-group-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user-group/repository/item/user-group-item.server.data-source.ts @@ -3,6 +3,7 @@ import type { UserGroupItemResponseModel } from '@umbraco-cms/backoffice/externa import { UserGroupService } from '@umbraco-cms/backoffice/external/backend-api'; import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; /** * A server data source for User Group items @@ -20,14 +21,24 @@ export class UmbUserGroupItemServerDataSource extends UmbItemServerDataSourceBas */ constructor(host: UmbControllerHost) { super(host, { - getItems, mapper, }); } -} -/* eslint-disable local-rules/no-direct-api-import */ -const getItems = (uniques: Array) => UserGroupService.getItemUserGroup({ query: { id: uniques } }); + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => UserGroupService.getItemUserGroup({ query: { id: args.uniques } }), + uniques, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; + } +} const mapper = (item: UserGroupItemResponseModel): UmbUserGroupItemModel => { return { diff --git a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/item/user-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/item/user-item.server.data-source.ts index 18f74820c8..323c08f8a6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/item/user-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/user/user/repository/item/user-item.server.data-source.ts @@ -1,6 +1,7 @@ import { UMB_USER_ENTITY_TYPE } from '../../entity.js'; import type { UmbUserItemModel } from './types.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; import type { UserItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { UserService } from '@umbraco-cms/backoffice/external/backend-api'; import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository'; @@ -18,14 +19,24 @@ export class UmbUserItemServerDataSource extends UmbItemServerDataSourceBase) => UserService.getItemUser({ query: { id: uniques } }); + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => UserService.getItemUser({ query: { id: args.uniques } }), + uniques, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; + } +} const mapper = (item: UserItemResponseModel): UmbUserItemModel => { return { diff --git a/src/Umbraco.Web.UI.Client/src/packages/webhook/webhook/repository/item/webhook-item.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/webhook/webhook/repository/item/webhook-item.server.data-source.ts index 91775f3ac7..f6115c194f 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/webhook/webhook/repository/item/webhook-item.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/webhook/webhook/repository/item/webhook-item.server.data-source.ts @@ -3,6 +3,7 @@ import { UmbItemServerDataSourceBase } from '@umbraco-cms/backoffice/repository' import type { WebhookItemResponseModel } from '@umbraco-cms/backoffice/external/backend-api'; import { WebhookService } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbItemDataApiGetRequestController } from '@umbraco-cms/backoffice/entity-item'; /** * A server data source for Webhook items @@ -20,14 +21,24 @@ export class UmbWebhookItemServerDataSource extends UmbItemServerDataSourceBase< */ constructor(host: UmbControllerHost) { super(host, { - getItems, mapper, }); } -} -/* eslint-disable local-rules/no-direct-api-import */ -const getItems = (uniques: Array) => WebhookService.getItemWebhook({ query: { id: uniques } }); + override async getItems(uniques: Array) { + if (!uniques) throw new Error('Uniques are missing'); + + const itemRequestManager = new UmbItemDataApiGetRequestController(this, { + // eslint-disable-next-line local-rules/no-direct-api-import + api: (args) => WebhookService.getItemWebhook({ query: { id: args.uniques } }), + uniques, + }); + + const { data, error } = await itemRequestManager.request(); + + return { data: this._getMappedItems(data), error }; + } +} const mapper = (item: WebhookItemResponseModel): UmbWebhookItemModel => { return {