diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index 0de4402765..957c27da24 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -52,7 +52,7 @@ "@hey-api/openapi-ts": "^0.48.3", "@mdx-js/react": "^3.0.1", "@open-wc/testing": "^4.0.0", - "@playwright/test": "^1.45.2", + "@playwright/test": "^1.45.3", "@rollup/plugin-commonjs": "^26.0.1", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^15.2.3", @@ -97,7 +97,7 @@ "storybook": "^7.6.17", "tiny-glob": "^0.2.9", "tsc-alias": "^1.8.10", - "typedoc": "^0.26.4", + "typedoc": "^0.26.5", "typescript": "^5.5.3", "typescript-eslint": "^7.16.1", "typescript-json-schema": "^0.64.0", @@ -3386,12 +3386,12 @@ } }, "node_modules/@playwright/test": { - "version": "1.45.2", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.2.tgz", - "integrity": "sha512-JxG9eq92ET75EbVi3s+4sYbcG7q72ECeZNbdBlaMkGcNbiDQ4cAi8U2QP5oKkOx+1gpaiL1LDStmzCaEM1Z6fQ==", + "version": "1.45.3", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.3.tgz", + "integrity": "sha512-UKF4XsBfy+u3MFWEH44hva1Q8Da28G6RFtR2+5saw+jgAFQV5yYnB1fu68Mz7fO+5GJF3wgwAIs0UelU8TxFrA==", "dev": true, "dependencies": { - "playwright": "1.45.2" + "playwright": "1.45.3" }, "bin": { "playwright": "cli.js" @@ -17498,12 +17498,12 @@ } }, "node_modules/playwright": { - "version": "1.45.2", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.2.tgz", - "integrity": "sha512-ReywF2t/0teRvNBpfIgh5e4wnrI/8Su8ssdo5XsQKpjxJj+jspm00jSoz9BTg91TT0c9HRjXO7LBNVrgYj9X0g==", + "version": "1.45.3", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.3.tgz", + "integrity": "sha512-QhVaS+lpluxCaioejDZ95l4Y4jSFCsBvl2UZkpeXlzxmqS+aABr5c82YmfMHrL6x27nvrvykJAFpkzT2eWdJww==", "dev": true, "dependencies": { - "playwright-core": "1.45.2" + "playwright-core": "1.45.3" }, "bin": { "playwright": "cli.js" @@ -17516,9 +17516,9 @@ } }, "node_modules/playwright-core": { - "version": "1.45.2", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.2.tgz", - "integrity": "sha512-ha175tAWb0dTK0X4orvBIqi3jGEt701SMxMhyujxNrgd8K0Uy5wMSwwcQHtyB4om7INUkfndx02XnQ2p6dvLDw==", + "version": "1.45.3", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.3.tgz", + "integrity": "sha512-+ym0jNbcjikaOwwSZycFbwkWgfruWvYlJfThKYAlImbxUgdWFO2oW70ojPm4OpE4t6TAo2FY/smM+hpVTtkhDA==", "dev": true, "bin": { "playwright-core": "cli.js" @@ -20084,9 +20084,9 @@ "dev": true }, "node_modules/typedoc": { - "version": "0.26.4", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.26.4.tgz", - "integrity": "sha512-FlW6HpvULDKgc3rK04V+nbFyXogPV88hurarDPOjuuB5HAwuAlrCMQ5NeH7Zt68a/ikOKu6Z/0hFXAeC9xPccQ==", + "version": "0.26.5", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.26.5.tgz", + "integrity": "sha512-Vn9YKdjKtDZqSk+by7beZ+xzkkr8T8CYoiasqyt4TTRFy5+UHzL/mF/o4wGBjRF+rlWQHDb0t6xCpA3JNL5phg==", "dev": true, "dependencies": { "lunr": "^2.3.9", diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index 112daa104b..28fe0f6fb6 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -222,7 +222,7 @@ "@hey-api/openapi-ts": "^0.48.3", "@mdx-js/react": "^3.0.1", "@open-wc/testing": "^4.0.0", - "@playwright/test": "^1.45.2", + "@playwright/test": "^1.45.3", "@rollup/plugin-commonjs": "^26.0.1", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^15.2.3", @@ -267,7 +267,7 @@ "storybook": "^7.6.17", "tiny-glob": "^0.2.9", "tsc-alias": "^1.8.10", - "typedoc": "^0.26.4", + "typedoc": "^0.26.5", "typescript": "^5.5.3", "typescript-eslint": "^7.16.1", "typescript-json-schema": "^0.64.0", 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 eb9739e8c0..12e7c60eec 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 @@ -90,17 +90,18 @@ export class UmbCompositionPickerModalElement extends UmbModalBaseElement< await this.#init; if (!this.#compositionRepository) return; - const isElement = this.data?.isElement; - const currentPropertyAliases = this.data?.currentPropertyAliases; + // Notice isElement is not available on all types that can be composed. + const isElement = this.data?.isElement ?? undefined; + const currentPropertyAliases = this.data?.currentPropertyAliases ?? []; 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, + isElement: isElement, currentCompositeUniques: this._selection, - currentPropertyAliases: currentPropertyAliases ?? [], + currentPropertyAliases: currentPropertyAliases, }); if (!data) return; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/composition/index.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/composition/index.ts index 99c179ec94..8a9f7eae16 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/composition/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/composition/index.ts @@ -1,2 +1 @@ -export { UmbDocumentTypeCompositionRepository } from './document-type-composition.repository.js'; export { UMB_DOCUMENT_TYPE_COMPOSITION_REPOSITORY_ALIAS } from './manifests.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/composition/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/composition/manifests.ts index 1732701de6..b01f3b0be9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/composition/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/repository/composition/manifests.ts @@ -2,11 +2,11 @@ import type { ManifestRepository, ManifestTypes } from '@umbraco-cms/backoffice/ export const UMB_DOCUMENT_TYPE_COMPOSITION_REPOSITORY_ALIAS = 'Umb.Repository.DocumentType.Composition'; -const queryRepository: ManifestRepository = { +const compositionRepository: ManifestRepository = { type: 'repository', alias: UMB_DOCUMENT_TYPE_COMPOSITION_REPOSITORY_ALIAS, name: 'Document Type Composition Repository', api: () => import('./document-type-composition.repository.js'), }; -export const manifests: Array = [queryRepository]; +export const manifests: Array = [compositionRepository]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/health-check/views/health-check-group-box-overview.element.ts b/src/Umbraco.Web.UI.Client/src/packages/health-check/views/health-check-group-box-overview.element.ts index 42d8679729..3dadc4cee6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/health-check/views/health-check-group-box-overview.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/health-check/views/health-check-group-box-overview.element.ts @@ -64,25 +64,25 @@ export class UmbHealthCheckGroupBoxOverviewElement extends UmbLitElement { _renderCheckResults(resultObject: any) { return html`${resultObject.success > 0 ? html` - + ${resultObject.success} ` : nothing} ${resultObject.warning > 0 ? html` - + ${resultObject.warning} ` : nothing} ${resultObject.error > 0 ? html` - + ${resultObject.error} ` : nothing} ${resultObject.info > 0 ? html` - + ${resultObject.info} ` : nothing} `; diff --git a/src/Umbraco.Web.UI.Client/src/packages/health-check/views/health-check-group.element.ts b/src/Umbraco.Web.UI.Client/src/packages/health-check/views/health-check-group.element.ts index 787edc26c6..084d41a1a9 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/health-check/views/health-check-group.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/health-check/views/health-check-group.element.ts @@ -129,7 +129,7 @@ export class UmbDashboardHealthCheckGroupElement extends UmbLitElement { case StatusResultTypeModel.SUCCESS: return html``; case StatusResultTypeModel.WARNING: - return html``; + return html``; case StatusResultTypeModel.ERROR: return html``; case StatusResultTypeModel.INFO: diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/index.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/index.ts index 39c2b4ea8b..4fdc741116 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/index.ts @@ -1,12 +1,11 @@ import './components/index.js'; export * from './components/index.js'; -export * from './workspace/index.js'; - +export * from './entity.js'; export * from './repository/index.js'; export * from './tree/types.js'; -export * from './utils.ts/index.js'; export * from './types.js'; -export * from './entity.js'; +export * from './utils.ts/index.js'; +export * from './workspace/index.js'; export { UMB_MEDIA_TYPE_PICKER_MODAL } from './tree/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/composition/index.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/composition/index.ts new file mode 100644 index 0000000000..e9c3158173 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/composition/index.ts @@ -0,0 +1 @@ +export { UMB_MEDIA_TYPE_COMPOSITION_REPOSITORY_ALIAS } from './manifests.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/composition/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/composition/manifests.ts new file mode 100644 index 0000000000..16ad5b903c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/composition/manifests.ts @@ -0,0 +1,12 @@ +import type { ManifestRepository, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; + +export const UMB_MEDIA_TYPE_COMPOSITION_REPOSITORY_ALIAS = 'Umb.Repository.MediaType.Composition'; + +const compositionRepository: ManifestRepository = { + type: 'repository', + alias: UMB_MEDIA_TYPE_COMPOSITION_REPOSITORY_ALIAS, + name: 'Media Type Composition Repository', + api: () => import('./media-type-composition.repository.js'), +}; + +export const manifests: Array = [compositionRepository]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/composition/media-type-composition.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/composition/media-type-composition.repository.ts new file mode 100644 index 0000000000..a73570e069 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/composition/media-type-composition.repository.ts @@ -0,0 +1,36 @@ +import { UmbMediaTypeCompositionServerDataSource } from './media-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 { + UmbMediaTypeAvailableCompositionRequestModel, + UmbMediaTypeCompositionCompatibleModel, + UmbMediaTypeCompositionReferenceModel, +} from '@umbraco-cms/backoffice/media-type'; +import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; + +export class UmbMediaTypeCompositionRepository + extends UmbRepositoryBase + implements + UmbContentTypeCompositionRepository< + UmbMediaTypeCompositionReferenceModel, + UmbMediaTypeCompositionCompatibleModel, + UmbMediaTypeAvailableCompositionRequestModel + > +{ + #compositionSource: UmbMediaTypeCompositionServerDataSource; + + constructor(host: UmbControllerHost) { + super(host); + this.#compositionSource = new UmbMediaTypeCompositionServerDataSource(this); + } + + async getReferences(unique: string) { + return this.#compositionSource.getReferences(unique); + } + + async availableCompositions(args: UmbMediaTypeAvailableCompositionRequestModel) { + return this.#compositionSource.availableCompositions(args); + } +} + +export { UmbMediaTypeCompositionRepository as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/composition/media-type-composition.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/composition/media-type-composition.server.data-source.ts new file mode 100644 index 0000000000..81e1e7d28b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/composition/media-type-composition.server.data-source.ts @@ -0,0 +1,86 @@ +import type { + UmbMediaTypeCompositionCompatibleModel, + UmbMediaTypeCompositionReferenceModel, + UmbMediaTypeAvailableCompositionRequestModel, +} from '../../types.js'; +import { type MediaTypeCompositionRequestModel, MediaTypeService } 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 Media Type Composition that fetches data from the server + * @export + * @class UmbMediaTypeCompositionServerDataSource + */ +export class UmbMediaTypeCompositionServerDataSource + implements + UmbContentTypeCompositionDataSource< + UmbMediaTypeCompositionReferenceModel, + UmbMediaTypeCompositionCompatibleModel, + UmbMediaTypeAvailableCompositionRequestModel + > +{ + #host: UmbControllerHost; + + /** + * Creates an instance of UmbMediaTypeCompositionServerDataSource. + * @param {UmbControllerHost} host + * @memberof UmbMediaTypeCompositionServerDataSource + */ + constructor(host: UmbControllerHost) { + this.#host = host; + } + /** + * Fetches the compatible compositions for a Media type from the server + * @param {string} unique + * @return {*} + * @memberof UmbMediaTypeCompositionServerDataSource + */ + async getReferences(unique: string) { + const response = await tryExecuteAndNotify( + this.#host, + MediaTypeService.getMediaTypeByIdCompositionReferences({ id: unique }), + ); + const error = response.error; + const data: Array | undefined = response.data?.map((reference) => { + return { + unique: reference.id, + icon: reference.icon, + name: reference.name, + }; + }); + + return { data, error }; + } + /** + * Updates the compositions for a media type on the server + * @param {MediaTypeCompositionRequestModel} requestBody + * @return {*} + * @memberof UmbMediaTypeCompositionServerDataSource + */ + async availableCompositions(args: UmbMediaTypeAvailableCompositionRequestModel) { + const requestBody: MediaTypeCompositionRequestModel = { + id: args.unique, + currentCompositeIds: args.currentCompositeUniques, + currentPropertyAliases: args.currentPropertyAliases, + }; + + const response = await tryExecuteAndNotify( + this.#host, + MediaTypeService.postMediaTypeAvailableCompositions({ requestBody }), + ); + const error = response.error; + const data: Array | undefined = response.data?.map((composition) => { + return { + unique: composition.id, + name: composition.name, + icon: composition.icon, + folderPath: composition.folderPath, + isCompatible: composition.isCompatible, + }; + }); + + return { data, error }; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/index.ts index e84c58d982..e3bd416604 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/index.ts @@ -1,3 +1,4 @@ -export * from './item/index.js'; +export * from './composition/index.js'; export * from './detail/index.js'; +export * from './item/index.js'; export * from './structure/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/manifests.ts index 37dcb889ef..ce74b2570d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/repository/manifests.ts @@ -1,5 +1,6 @@ import { manifests as detailManifests } from './detail/manifests.js'; import { manifests as itemManifests } from './item/manifests.js'; +import { manifests as compositionManifests } from './composition/manifests.js'; import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; -export const manifests: Array = [...detailManifests, ...itemManifests]; +export const manifests: Array = [...detailManifests, ...itemManifests, ...compositionManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/types.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/types.ts index 828514db06..17acb2e86e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/types.ts @@ -1,6 +1,17 @@ import type { UmbMediaTypeEntityType } from './entity.js'; -import type { UmbContentTypeModel } from '@umbraco-cms/backoffice/content-type'; +import type { + UmbContentTypeAvailableCompositionRequestModel, + UmbContentTypeCompositionCompatibleModel, + UmbContentTypeCompositionReferenceModel, + UmbContentTypeModel, +} from '@umbraco-cms/backoffice/content-type'; export interface UmbMediaTypeDetailModel extends UmbContentTypeModel { entityType: UmbMediaTypeEntityType; } + +export interface UmbMediaTypeAvailableCompositionRequestModel extends UmbContentTypeAvailableCompositionRequestModel {} + +export interface UmbMediaTypeCompositionCompatibleModel extends UmbContentTypeCompositionCompatibleModel {} + +export interface UmbMediaTypeCompositionReferenceModel extends UmbContentTypeCompositionReferenceModel {} diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/manifests.ts index a0cb73a866..01293d0d96 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/workspace/manifests.ts @@ -1,3 +1,4 @@ +import { UMB_MEDIA_TYPE_COMPOSITION_REPOSITORY_ALIAS } from '../repository/index.js'; import { UMB_MEDIA_TYPE_WORKSPACE_ALIAS } from './constants.js'; import type { ManifestWorkspaces, @@ -29,6 +30,7 @@ const workspaceViews: Array = [ label: '#general_design', pathname: 'design', icon: 'icon-document-dashed-line', + compositionRepositoryAlias: UMB_MEDIA_TYPE_COMPOSITION_REPOSITORY_ALIAS, }, conditions: [ { diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/index.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/index.ts index 7a1a270d73..66b072b145 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/index.ts @@ -1,10 +1,9 @@ import './components/index.js'; -export * from './workspace/index.js'; export * from './components/index.js'; -export * from './repository/index.js'; export * from './entity.js'; -export * from './tree/index.js'; export * from './modal/member-type-picker-modal.token.js'; - -export type { UmbMemberTypeDetailModel } from './types.js'; +export * from './repository/index.js'; +export * from './tree/index.js'; +export * from './types.js'; +export * from './workspace/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/composition/index.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/composition/index.ts new file mode 100644 index 0000000000..7c68fa6579 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/composition/index.ts @@ -0,0 +1 @@ +export { UMB_MEMBER_TYPE_COMPOSITION_REPOSITORY_ALIAS } from './manifests.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/composition/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/composition/manifests.ts new file mode 100644 index 0000000000..bf8f9fa79f --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/composition/manifests.ts @@ -0,0 +1,12 @@ +import type { ManifestRepository, ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; + +export const UMB_MEMBER_TYPE_COMPOSITION_REPOSITORY_ALIAS = 'Umb.Repository.MemberType.Composition'; + +const compositionRepository: ManifestRepository = { + type: 'repository', + alias: UMB_MEMBER_TYPE_COMPOSITION_REPOSITORY_ALIAS, + name: 'Member Type Composition Repository', + api: () => import('./member-type-composition.repository.js'), +}; + +export const manifests: Array = [compositionRepository]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/composition/member-type-composition.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/composition/member-type-composition.repository.ts new file mode 100644 index 0000000000..a64e0a3ef8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/composition/member-type-composition.repository.ts @@ -0,0 +1,36 @@ +import { UmbMemberTypeCompositionServerDataSource } from './member-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 { + UmbMemberTypeAvailableCompositionRequestModel, + UmbMemberTypeCompositionCompatibleModel, + UmbMemberTypeCompositionReferenceModel, +} from '@umbraco-cms/backoffice/member-type'; +import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; + +export class UmbMemberTypeCompositionRepository + extends UmbRepositoryBase + implements + UmbContentTypeCompositionRepository< + UmbMemberTypeCompositionReferenceModel, + UmbMemberTypeCompositionCompatibleModel, + UmbMemberTypeAvailableCompositionRequestModel + > +{ + #compositionSource: UmbMemberTypeCompositionServerDataSource; + + constructor(host: UmbControllerHost) { + super(host); + this.#compositionSource = new UmbMemberTypeCompositionServerDataSource(this); + } + + async getReferences(unique: string) { + return this.#compositionSource.getReferences(unique); + } + + async availableCompositions(args: UmbMemberTypeAvailableCompositionRequestModel) { + return this.#compositionSource.availableCompositions(args); + } +} + +export { UmbMemberTypeCompositionRepository as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/composition/member-type-composition.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/composition/member-type-composition.server.data-source.ts new file mode 100644 index 0000000000..dc38ede4a2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/composition/member-type-composition.server.data-source.ts @@ -0,0 +1,89 @@ +import type { + UmbMemberTypeCompositionCompatibleModel, + UmbMemberTypeCompositionReferenceModel, + UmbMemberTypeAvailableCompositionRequestModel, +} from '../../types.js'; +import { + type MemberTypeCompositionRequestModel, + MemberTypeService, +} 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 Member Type Composition that fetches data from the server + * @export + * @class UmbMemberTypeCompositionServerDataSource + */ +export class UmbMemberTypeCompositionServerDataSource + implements + UmbContentTypeCompositionDataSource< + UmbMemberTypeCompositionReferenceModel, + UmbMemberTypeCompositionCompatibleModel, + UmbMemberTypeAvailableCompositionRequestModel + > +{ + #host: UmbControllerHost; + + /** + * Creates an instance of UmbMemberTypeCompositionServerDataSource. + * @param {UmbControllerHost} host + * @memberof UmbMemberTypeCompositionServerDataSource + */ + constructor(host: UmbControllerHost) { + this.#host = host; + } + /** + * Fetches the compatible compositions for a document type from the server + * @param {string} unique + * @return {*} + * @memberof UmbMemberTypeCompositionServerDataSource + */ + async getReferences(unique: string) { + const response = await tryExecuteAndNotify( + this.#host, + MemberTypeService.getMemberTypeByIdCompositionReferences({ id: unique }), + ); + const error = response.error; + const data: Array | undefined = response.data?.map((reference) => { + return { + unique: reference.id, + icon: reference.icon, + name: reference.name, + }; + }); + + return { data, error }; + } + /** + * Updates the compositions for a document type on the server + * @param {MemberTypeCompositionRequestModel} requestBody + * @return {*} + * @memberof UmbMemberTypeCompositionServerDataSource + */ + async availableCompositions(args: UmbMemberTypeAvailableCompositionRequestModel) { + const requestBody: MemberTypeCompositionRequestModel = { + id: args.unique, + currentCompositeIds: args.currentCompositeUniques, + currentPropertyAliases: args.currentPropertyAliases, + }; + + const response = await tryExecuteAndNotify( + this.#host, + MemberTypeService.postMemberTypeAvailableCompositions({ requestBody }), + ); + const error = response.error; + const data: Array | undefined = response.data?.map((composition) => { + return { + unique: composition.id, + name: composition.name, + icon: composition.icon, + folderPath: composition.folderPath, + isCompatible: composition.isCompatible, + }; + }); + + return { data, error }; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/index.ts index f396068800..5a07494cdb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/index.ts @@ -1,2 +1,3 @@ export { UmbMemberTypeDetailRepository, UMB_MEMBER_TYPE_DETAIL_REPOSITORY_ALIAS } from './detail/index.js'; export { UmbMemberTypeItemRepository, UMB_MEMBER_TYPE_ITEM_REPOSITORY_ALIAS } from './item/index.js'; +export { UMB_MEMBER_TYPE_COMPOSITION_REPOSITORY_ALIAS } from './composition/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/manifests.ts index 37dcb889ef..ce74b2570d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/repository/manifests.ts @@ -1,5 +1,6 @@ import { manifests as detailManifests } from './detail/manifests.js'; import { manifests as itemManifests } from './item/manifests.js'; +import { manifests as compositionManifests } from './composition/manifests.js'; import type { ManifestTypes } from '@umbraco-cms/backoffice/extension-registry'; -export const manifests: Array = [...detailManifests, ...itemManifests]; +export const manifests: Array = [...detailManifests, ...itemManifests, ...compositionManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/types.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/types.ts index 41bb9c2f08..c17ebcebe6 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/types.ts @@ -1,6 +1,17 @@ import type { UmbMemberTypeEntityType } from './entity.js'; -import type { UmbContentTypeModel } from '@umbraco-cms/backoffice/content-type'; +import type { + UmbContentTypeAvailableCompositionRequestModel, + UmbContentTypeCompositionCompatibleModel, + UmbContentTypeCompositionReferenceModel, + UmbContentTypeModel, +} from '@umbraco-cms/backoffice/content-type'; export interface UmbMemberTypeDetailModel extends UmbContentTypeModel { entityType: UmbMemberTypeEntityType; } + +export interface UmbMemberTypeAvailableCompositionRequestModel extends UmbContentTypeAvailableCompositionRequestModel {} + +export interface UmbMemberTypeCompositionCompatibleModel extends UmbContentTypeCompositionCompatibleModel {} + +export interface UmbMemberTypeCompositionReferenceModel extends UmbContentTypeCompositionReferenceModel {} diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/workspace/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/workspace/manifests.ts index ac2e37d3da..fbac4d07c2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/workspace/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/workspace/manifests.ts @@ -1,7 +1,8 @@ +import { UMB_MEMBER_TYPE_COMPOSITION_REPOSITORY_ALIAS } from '../repository/index.js'; import type { ManifestWorkspaces, ManifestWorkspaceActions, - ManifestWorkspaceView, + ManifestWorkspaceViews, ManifestTypes, } from '@umbraco-cms/backoffice/extension-registry'; import { UmbSubmitWorkspaceAction } from '@umbraco-cms/backoffice/workspace'; @@ -19,7 +20,7 @@ const workspace: ManifestWorkspaces = { }, }; -const workspaceViews: Array = [ +const workspaceViews: Array = [ { type: 'workspaceView', kind: 'contentTypeDesignEditor', @@ -29,6 +30,7 @@ const workspaceViews: Array = [ label: '#general_design', pathname: 'design', icon: 'icon-member-dashed-line', + compositionRepositoryAlias: UMB_MEMBER_TYPE_COMPOSITION_REPOSITORY_ALIAS, }, conditions: [ {