diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/content-type-composition-data-source.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/content-type-composition-data-source.interface.ts new file mode 100644 index 0000000000..4579915e98 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/content-type-composition-data-source.interface.ts @@ -0,0 +1,17 @@ +import type { + UmbContentTypeCompositionCompatibleModel, + UmbContentTypeCompositionReferenceModel, + UmbContentTypeAvailableCompositionRequestModel, +} from './types.js'; +import type { UmbDataSourceResponse } from '@umbraco-cms/backoffice/repository'; + +export interface UmbContentTypeCompositionDataSource< + CompositionReferenceModelType extends UmbContentTypeCompositionReferenceModel, + CompositionCompatibleModelType extends UmbContentTypeCompositionCompatibleModel, + AvailableCompositionsRequestType extends UmbContentTypeAvailableCompositionRequestModel, +> { + getReferences(unique: string): Promise>>; + availableCompositions( + args: AvailableCompositionsRequestType, + ): Promise>>; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/content-type-composition-repository.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/content-type-composition-repository.interface.ts new file mode 100644 index 0000000000..4061213d6e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/content-type-composition-repository.interface.ts @@ -0,0 +1,20 @@ +import type { + UmbContentTypeCompositionCompatibleModel, + UmbContentTypeCompositionReferenceModel, + UmbContentTypeAvailableCompositionRequestModel, +} from './types.js'; +import type { UmbRepositoryResponse } from '@umbraco-cms/backoffice/repository'; + +export interface UmbContentTypeCompositionRepository< + CompositionReferenceModelType extends + UmbContentTypeCompositionReferenceModel = UmbContentTypeCompositionReferenceModel, + CompositionCompatibleModelType extends + UmbContentTypeCompositionCompatibleModel = UmbContentTypeCompositionCompatibleModel, + AvailableCompositionsRequestType extends + UmbContentTypeAvailableCompositionRequestModel = UmbContentTypeAvailableCompositionRequestModel, +> { + getReferences(unique: string): Promise>>; + availableCompositions( + args: AvailableCompositionsRequestType, + ): Promise>>; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/index.ts new file mode 100644 index 0000000000..c9b2fadc33 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/index.ts @@ -0,0 +1,4 @@ +export type { UmbContentTypeCompositionRepository } from './content-type-composition-repository.interface.js'; +export type { UmbContentTypeCompositionDataSource } from './content-type-composition-data-source.interface.js'; + +export * from './types.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/types.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/types.ts new file mode 100644 index 0000000000..4fcd9f44f1 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/composition/types.ts @@ -0,0 +1,19 @@ +export interface UmbContentTypeCompositionReferenceModel { + unique: string; + name: string; + icon: string; +} + +export interface UmbContentTypeAvailableCompositionRequestModel { + unique: string | null; + currentPropertyAliases: Array; + currentCompositeUniques: Array; +} + +export interface UmbContentTypeCompositionCompatibleModel { + unique: string; + name: string; + icon: string; + folderPath: Array; + isCompatible: boolean; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/index.ts index 6f9d7d26e5..03701d17e5 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/index.ts @@ -4,3 +4,4 @@ export * from './repository/index.js'; export * from './structure/index.js'; export * from './types.js'; export * from './workspace/index.js'; +export * from './composition/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/modals/composition-picker/composition-picker-modal.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/modals/composition-picker/composition-picker-modal.element.ts index 97c15ff002..0f56da20fe 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content-type/modals/composition-picker/composition-picker-modal.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content-type/modals/composition-picker/composition-picker-modal.element.ts @@ -1,20 +1,20 @@ +import type { + UmbContentTypeCompositionRepository, + UmbContentTypeCompositionCompatibleModel, + UmbContentTypeCompositionReferenceModel, +} from '../../composition/index.js'; import type { UmbCompositionPickerModalData, UmbCompositionPickerModalValue, } from './composition-picker-modal.token.js'; import { css, html, customElement, state, repeat, nothing } from '@umbraco-cms/backoffice/external/lit'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; -import type { - UmbDocumentTypeCompositionRepository, - UmbDocumentTypeCompositionCompatibleModel, - UmbDocumentTypeCompositionReferenceModel, -} from '@umbraco-cms/backoffice/document-type'; import { UmbExtensionApiInitializer } from '@umbraco-cms/backoffice/extension-api'; import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; interface CompatibleCompositions { path: string; - compositions: Array; + compositions: Array; } @customElement('umb-composition-picker-modal') @@ -23,12 +23,12 @@ export class UmbCompositionPickerModalElement extends UmbModalBaseElement< UmbCompositionPickerModalValue > { // TODO: Loosen this from begin specific to Document Types, so we can have a general interface for composition repositories. [NL] - #compositionRepository?: UmbDocumentTypeCompositionRepository; + #compositionRepository?: UmbContentTypeCompositionRepository; #unique: string | null = null; #init?: Promise; @state() - private _references: Array = []; + private _references: Array = []; @state() private _compatibleCompositions?: Array; @@ -41,7 +41,7 @@ export class UmbCompositionPickerModalElement extends UmbModalBaseElement< const alias = this.data?.compositionRepositoryAlias; if (alias) { this.#init = new UmbExtensionApiInitializer(this, umbExtensionsRegistry, alias, [this], (permitted, ctrl) => { - this.#compositionRepository = permitted ? (ctrl.api as UmbDocumentTypeCompositionRepository) : undefined; + this.#compositionRepository = permitted ? (ctrl.api as UmbContentTypeCompositionRepository) : undefined; }).asPromise(); } else { throw new Error('No composition repository alias provided'); @@ -74,6 +74,9 @@ export class UmbCompositionPickerModalElement extends UmbModalBaseElement< const { data } = await this.#compositionRepository.availableCompositions({ unique: this.#unique, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + // TODO: isElement is not available on all types that can be composed. isElement: isElement ?? false, currentCompositeUniques: this._selection, currentPropertyAliases: currentPropertyAliases ?? [], @@ -168,7 +171,7 @@ export class UmbCompositionPickerModalElement extends UmbModalBaseElement< } } - #renderCompositionsItems(compositionsList: Array) { + #renderCompositionsItems(compositionsList: Array) { return repeat( compositionsList, (compositions) => compositions.unique, diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/composition/document-type-composition.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/composition/document-type-composition.repository.ts index 1901072d48..81de3d55d6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/composition/document-type-composition.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/composition/document-type-composition.repository.ts @@ -1,9 +1,22 @@ import { UmbDocumentTypeCompositionServerDataSource } from './document-type-composition.server.data-source.js'; +import type { UmbContentTypeCompositionRepository } from '@umbraco-cms/backoffice/content-type'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import type { UmbDocumentTypeCompositionRequestModel } from '@umbraco-cms/backoffice/document-type'; +import type { + UmbDocumentTypeAvailableCompositionRequestModel, + UmbDocumentTypeCompositionCompatibleModel, + UmbDocumentTypeCompositionReferenceModel, +} from '@umbraco-cms/backoffice/document-type'; import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; -export class UmbDocumentTypeCompositionRepository extends UmbRepositoryBase { +export class UmbDocumentTypeCompositionRepository + extends UmbRepositoryBase + implements + UmbContentTypeCompositionRepository< + UmbDocumentTypeCompositionReferenceModel, + UmbDocumentTypeCompositionCompatibleModel, + UmbDocumentTypeAvailableCompositionRequestModel + > +{ #compositionSource: UmbDocumentTypeCompositionServerDataSource; constructor(host: UmbControllerHost) { @@ -15,7 +28,7 @@ export class UmbDocumentTypeCompositionRepository extends UmbRepositoryBase { return this.#compositionSource.getReferences(unique); } - async availableCompositions(args: UmbDocumentTypeCompositionRequestModel) { + async availableCompositions(args: UmbDocumentTypeAvailableCompositionRequestModel) { return this.#compositionSource.availableCompositions(args); } } diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/composition/document-type-composition.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/composition/document-type-composition.server.data-source.ts index 0422becef4..40215f54af 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/composition/document-type-composition.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/composition/document-type-composition.server.data-source.ts @@ -1,7 +1,7 @@ import type { UmbDocumentTypeCompositionCompatibleModel, UmbDocumentTypeCompositionReferenceModel, - UmbDocumentTypeCompositionRequestModel, + UmbDocumentTypeAvailableCompositionRequestModel, } from '../../types.js'; import { type DocumentTypeCompositionRequestModel, @@ -9,13 +9,21 @@ import { } from '@umbraco-cms/backoffice/external/backend-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { tryExecuteAndNotify } from '@umbraco-cms/backoffice/resources'; +import type { UmbContentTypeCompositionDataSource } from '@umbraco-cms/backoffice/content-type'; /** * A data source for the Document Type Composition that fetches data from the server * @export * @class UmbDocumentTypeCompositionServerDataSource */ -export class UmbDocumentTypeCompositionServerDataSource { +export class UmbDocumentTypeCompositionServerDataSource + implements + UmbContentTypeCompositionDataSource< + UmbDocumentTypeCompositionReferenceModel, + UmbDocumentTypeCompositionCompatibleModel, + UmbDocumentTypeAvailableCompositionRequestModel + > +{ #host: UmbControllerHost; /** @@ -54,7 +62,7 @@ export class UmbDocumentTypeCompositionServerDataSource { * @return {*} * @memberof UmbDocumentTypeCompositionServerDataSource */ - async availableCompositions(args: UmbDocumentTypeCompositionRequestModel) { + async availableCompositions(args: UmbDocumentTypeAvailableCompositionRequestModel) { const requestBody: DocumentTypeCompositionRequestModel = { id: args.unique, isElement: args.isElement, diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/types.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/types.ts index 49f17aac41..d9447c2864 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/types.ts @@ -1,5 +1,10 @@ import type { UmbDocumentTypeEntityType } from './entity.js'; -import type { UmbContentTypeModel } from '@umbraco-cms/backoffice/content-type'; +import type { + UmbContentTypeCompositionCompatibleModel, + UmbContentTypeCompositionReferenceModel, + UmbContentTypeAvailableCompositionRequestModel, + UmbContentTypeModel, +} from '@umbraco-cms/backoffice/content-type'; export interface UmbDocumentTypeDetailModel extends UmbContentTypeModel { entityType: UmbDocumentTypeEntityType; @@ -14,23 +19,11 @@ export type UmbDocumentTypeCleanupModel = { keepLatestVersionPerDayForDays?: number | null; }; -export interface UmbDocumentTypeCompositionRequestModel { - unique: string | null; +export interface UmbDocumentTypeAvailableCompositionRequestModel + extends UmbContentTypeAvailableCompositionRequestModel { isElement: boolean; - currentPropertyAliases: Array; - currentCompositeUniques: Array; } -export interface UmbDocumentTypeCompositionCompatibleModel { - unique: string; - name: string; - icon: string; - folderPath: Array; - isCompatible: boolean; -} +export interface UmbDocumentTypeCompositionCompatibleModel extends UmbContentTypeCompositionCompatibleModel {} -export interface UmbDocumentTypeCompositionReferenceModel { - unique: string; - name: string; - icon: string; -} +export interface UmbDocumentTypeCompositionReferenceModel extends UmbContentTypeCompositionReferenceModel {}