diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/index.ts index dd722fb56aba..a532e7485e92 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/index.ts @@ -8,5 +8,6 @@ export * from './controller/merge-content-variant-data.controller.js'; export * from './manager/index.js'; export * from './property-dataset-context/index.js'; export * from './workspace/index.js'; +export type * from './repository/index.js'; export type * from './types.js'; export type * from './variant-picker/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/repository/content-validation-repository.interface.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/repository/content-validation-repository.interface.ts new file mode 100644 index 000000000000..43c58b8fe928 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/repository/content-validation-repository.interface.ts @@ -0,0 +1,8 @@ +import type { UmbContentDetailModel } from '../types.js'; +import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; +import type { UmbRepositoryResponse } from '@umbraco-cms/backoffice/repository'; + +export interface UmbContentValidationRepository { + validateCreate(model: DetailModelType, parentUnique: string | null): Promise>; + validateSave(model: DetailModelType, variantIds: Array): Promise>; +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/repository/index.ts new file mode 100644 index 000000000000..73d477550497 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/repository/index.ts @@ -0,0 +1 @@ +export type * from './content-validation-repository.interface.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts index 814ffafd884c..db0a159d0df1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/content/workspace/content-detail-workspace-base.ts @@ -3,6 +3,7 @@ import { UmbContentWorkspaceDataManager } from '../manager/index.js'; import { UmbMergeContentVariantDataController } from '../controller/merge-content-variant-data.controller.js'; import type { UmbContentVariantPickerData, UmbContentVariantPickerValue } from '../variant-picker/index.js'; import type { UmbContentPropertyDatasetContext } from '../property-dataset-context/index.js'; +import type { UmbContentValidationRepository } from '../repository/content-validation-repository.interface.js'; import type { UmbContentWorkspaceContext } from './content-workspace-context.interface.js'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import type { UmbDetailRepository, UmbDetailRepositoryConstructor } from '@umbraco-cms/backoffice/repository'; @@ -33,6 +34,7 @@ import { UMB_VALIDATION_CONTEXT, UMB_VALIDATION_EMPTY_LOCALIZATION_KEY, UmbDataPathVariantQuery, + UmbServerModelValidatorContext, UmbValidationContext, UmbVariantsValidationPathTranslator, UmbVariantValuesValidationPathTranslator, @@ -44,6 +46,7 @@ import { UmbRequestReloadChildrenOfEntityEvent, UmbRequestReloadStructureForEntityEvent, } from '@umbraco-cms/backoffice/entity-action'; +import type { ClassConstructor } from '@umbraco-cms/backoffice/extension-api'; export interface UmbContentDetailWorkspaceContextArgs< DetailModelType extends UmbContentDetailModel, @@ -54,6 +57,8 @@ export interface UmbContentDetailWorkspaceContextArgs< VariantOptionModelType extends UmbEntityVariantOptionModel = UmbEntityVariantOptionModel, > extends UmbEntityDetailWorkspaceContextArgs { contentTypeDetailRepository: UmbDetailRepositoryConstructor; + contentValidationRepository?: ClassConstructor>; + skipValidationOnSubmit?: boolean; contentVariantScaffold: VariantModelType; saveModalToken?: UmbModalToken, UmbContentVariantPickerValue>; } @@ -118,6 +123,11 @@ export abstract class UmbContentDetailWorkspaceContextBase< // TODO: fix type error public readonly variantOptions; + #validateOnSubmit: boolean; + #serverValidation = new UmbServerModelValidatorContext(this); + #validationRepositoryClass?: ClassConstructor>; + #validationRepository?: UmbContentValidationRepository; + #saveModalToken?: UmbModalToken, UmbContentVariantPickerValue>; constructor( @@ -135,6 +145,8 @@ export abstract class UmbContentDetailWorkspaceContextBase< this.#saveModalToken = args.saveModalToken; const contentTypeDetailRepository = new args.contentTypeDetailRepository(this); + this.#validationRepositoryClass = args.contentValidationRepository; + this.#validateOnSubmit = args.skipValidationOnSubmit ? !args.skipValidationOnSubmit : true; this.structure = new UmbContentTypeStructureManager(this, contentTypeDetailRepository); this.variesByCulture = this.structure.ownerContentTypeObservablePart((x) => x?.variesByCulture); this.variesBySegment = this.structure.ownerContentTypeObservablePart((x) => x?.variesBySegment); @@ -470,6 +482,36 @@ export abstract class UmbContentDetailWorkspaceContextBase< } } + protected async _askServerToValidate(saveData: DetailModelType, variantIds: Array) { + if (this.#validationRepositoryClass) { + // Create the validation repository if it does not exist. (we first create this here when we need it) [NL] + this.#validationRepository ??= new this.#validationRepositoryClass(this); + + // We ask the server first to get a concatenated set of validation messages. So we see both front-end and back-end validation messages [NL] + if (this.getIsNew()) { + const parent = this.getParent(); + if (!parent) throw new Error('Parent is not set'); + await this.#serverValidation.askServerForValidation( + saveData, + this.#validationRepository.validateCreate(saveData, parent.unique), + ); + } else { + await this.#serverValidation.askServerForValidation( + saveData, + this.#validationRepository.validateSave(saveData, variantIds), + ); + } + } + } + + /** + * Request a submit of the workspace, in the case of Document Workspaces the validation does not need to be valid for this to be submitted. + * @returns {Promise} a promise which resolves once it has been completed. + */ + public override requestSubmit() { + return this._handleSubmit(); + } + public override submit() { return this._handleSubmit(); } @@ -513,7 +555,19 @@ export abstract class UmbContentDetailWorkspaceContextBase< const saveData = await this._data.constructData(variantIds); await this._runMandatoryValidationForSaveData(saveData); - await this._performCreateOrUpdate(variantIds, saveData); + if (this.#validateOnSubmit) { + await this._askServerToValidate(saveData, variantIds); + return this.validateAndSubmit( + async () => { + return this._performCreateOrUpdate(variantIds, saveData); + }, + async () => { + return this.invalidSubmit(); + }, + ); + } else { + await this._performCreateOrUpdate(variantIds, saveData); + } } protected async _performCreateOrUpdate(variantIds: Array, saveData: DetailModelType) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.repository.ts index 3f48df28c0cc..b8c5ac3106b2 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.repository.ts @@ -3,10 +3,14 @@ import { UmbDocumentValidationServerDataSource } from './document-validation.ser import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; +import type { UmbContentValidationRepository } from '@umbraco-cms/backoffice/content'; type DetailModelType = UmbDocumentDetailModel; -export class UmbDocumentValidationRepository extends UmbRepositoryBase { +export class UmbDocumentValidationRepository + extends UmbRepositoryBase + implements UmbContentValidationRepository +{ #validationDataSource: UmbDocumentValidationServerDataSource; constructor(host: UmbControllerHost) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.server.data-source.ts index d32e1120f0e1..85ab9d7550f1 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/repository/validation/document-validation.server.data-source.ts @@ -11,17 +11,10 @@ import type { UmbEntityUnique } from '@umbraco-cms/backoffice/entity'; /** * A server data source for Document Validation - * @class UmbDocumentPublishingServerDataSource - * @implements {DocumentTreeDataSource} */ export class UmbDocumentValidationServerDataSource { //#host: UmbControllerHost; - /** - * Creates an instance of UmbDocumentPublishingServerDataSource. - * @param {UmbControllerHost} host - The controller host for this controller to be appended to - * @memberof UmbDocumentPublishingServerDataSource - */ // TODO: [v15]: ignoring unused var here here to prevent a breaking change // eslint-disable-next-line @typescript-eslint/no-unused-vars constructor(host: UmbControllerHost) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts index 405372b8eeba..6cd365699286 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -33,7 +33,6 @@ import { UmbRequestReloadStructureForEntityEvent, } from '@umbraco-cms/backoffice/entity-action'; import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; -import { UmbServerModelValidatorContext } from '@umbraco-cms/backoffice/validation'; import { UmbDocumentBlueprintDetailRepository } from '@umbraco-cms/backoffice/document-blueprint'; import { UMB_NOTIFICATION_CONTEXT } from '@umbraco-cms/backoffice/notification'; import { @@ -62,9 +61,6 @@ export class UmbDocumentWorkspaceContext { public readonly publishingRepository = new UmbDocumentPublishingRepository(this); - #serverValidation = new UmbServerModelValidatorContext(this); - #validationRepository?: UmbDocumentValidationRepository; - readonly isTrashed = this._data.createObservablePartOfCurrent((data) => data?.isTrashed); readonly contentTypeUnique = this._data.createObservablePartOfCurrent((data) => data?.documentType.unique); readonly contentTypeHasCollection = this._data.createObservablePartOfCurrent( @@ -81,6 +77,8 @@ export class UmbDocumentWorkspaceContext workspaceAlias: UMB_DOCUMENT_WORKSPACE_ALIAS, detailRepositoryAlias: UMB_DOCUMENT_DETAIL_REPOSITORY_ALIAS, contentTypeDetailRepository: UmbDocumentTypeDetailRepository, + contentValidationRepository: UmbDocumentValidationRepository, + skipValidationOnSubmit: true, contentVariantScaffold: UMB_DOCUMENT_DETAIL_MODEL_VARIANT_SCAFFOLD, saveModalToken: UMB_DOCUMENT_SAVE_MODAL, }); @@ -206,19 +204,6 @@ export class UmbDocumentWorkspaceContext this._data.updateCurrent({ template: { unique: templateUnique } }); } - /** - * Request a submit of the workspace, in the case of Document Workspaces the validation does not need to be valid for this to be submitted. - * @returns {Promise} a promise which resolves once it has been completed. - */ - public override requestSubmit() { - return this._handleSubmit(); - } - - // Because we do not make validation prevent submission this also submits the workspace. [NL] - public override invalidSubmit() { - return this._handleSubmit(); - } - async #handleSaveAndPreview() { const unique = this.getUnique(); if (!unique) throw new Error('Unique is missing'); @@ -287,23 +272,7 @@ export class UmbDocumentWorkspaceContext const saveData = await this._data.constructData(variantIds); await this._runMandatoryValidationForSaveData(saveData); - // Create the validation repository if it does not exist. (we first create this here when we need it) [NL] - this.#validationRepository ??= new UmbDocumentValidationRepository(this); - - // We ask the server first to get a concatenated set of validation messages. So we see both front-end and back-end validation messages [NL] - if (this.getIsNew()) { - const parent = this.getParent(); - if (!parent) throw new Error('Parent is not set'); - this.#serverValidation.askServerForValidation( - saveData, - this.#validationRepository.validateCreate(saveData, parent.unique), - ); - } else { - this.#serverValidation.askServerForValidation( - saveData, - this.#validationRepository.validateSave(saveData, variantIds), - ); - } + await this._askServerToValidate(saveData, variantIds); // TODO: Only validate the specified selection.. [NL] return this.validateAndSubmit( diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/validation/media-validation.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/validation/media-validation.repository.ts index 85faf65a999a..54c0825d2ed4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/validation/media-validation.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/validation/media-validation.repository.ts @@ -3,10 +3,14 @@ import { UmbMediaValidationServerDataSource } from './media-validation.server.da import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; +import type { UmbContentValidationRepository } from '@umbraco-cms/backoffice/content'; type DetailModelType = UmbMediaDetailModel; -export class UmbMediaValidationRepository extends UmbRepositoryBase { +export class UmbMediaValidationRepository + extends UmbRepositoryBase + implements UmbContentValidationRepository +{ #validationDataSource: UmbMediaValidationServerDataSource; constructor(host: UmbControllerHost) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/validation/media-validation.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/validation/media-validation.server.data-source.ts index 875e6100ab60..ef4d12057b87 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/validation/media-validation.server.data-source.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/repository/validation/media-validation.server.data-source.ts @@ -10,16 +10,11 @@ import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import type { UmbEntityUnique } from '@umbraco-cms/backoffice/entity'; /** - * A server data source for Media Validatiom + * A server data source for Media Validation */ export class UmbMediaValidationServerDataSource { //#host: UmbControllerHost; - /** - * Creates an instance of UmbDocumentPublishingServerDataSource. - * @param {UmbControllerHost} host - The controller host for this controller to be appended to - * @memberof UmbDocumentPublishingServerDataSource - */ // TODO: [v15]: ignoring unused var here here to prevent a breaking change // eslint-disable-next-line @typescript-eslint/no-unused-vars constructor(host: UmbControllerHost) { diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/media-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/media-workspace.context.ts index b96addbbd2d9..2a2e35395b21 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/media-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/workspace/media-workspace.context.ts @@ -4,6 +4,7 @@ import { UMB_MEDIA_ENTITY_TYPE } from '../entity.js'; import { UMB_MEDIA_DETAIL_REPOSITORY_ALIAS } from '../constants.js'; import type { UmbMediaDetailModel, UmbMediaVariantModel } from '../types.js'; import { UMB_CREATE_MEDIA_WORKSPACE_PATH_PATTERN, UMB_EDIT_MEDIA_WORKSPACE_PATH_PATTERN } from '../paths.js'; +import { UmbMediaValidationRepository } from '../repository/validation/media-validation.repository.js'; import { UMB_MEDIA_COLLECTION_ALIAS } from '../collection/constants.js'; import type { UmbMediaDetailRepository } from '../repository/index.js'; import { UMB_MEDIA_WORKSPACE_ALIAS, UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD } from './constants.js'; @@ -48,6 +49,7 @@ export class UmbMediaWorkspaceContext workspaceAlias: UMB_MEDIA_WORKSPACE_ALIAS, detailRepositoryAlias: UMB_MEDIA_DETAIL_REPOSITORY_ALIAS, contentTypeDetailRepository: UmbMediaTypeDetailRepository, + contentValidationRepository: UmbMediaValidationRepository, contentVariantScaffold: UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD, }); diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/index.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/index.ts index 42dddc85da25..d54682b8ca73 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/index.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/index.ts @@ -1,2 +1,3 @@ export { UmbMemberDetailRepository } from './detail/index.js'; export { UmbMemberItemRepository, type UmbMemberItemModel } from './item/index.js'; +export * from './validation/index.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/manifests.ts index 4dfb0c911f4e..74a3121896bb 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/manifests.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/manifests.ts @@ -1,4 +1,5 @@ import { manifests as detailManifests } from './detail/manifests.js'; import { manifests as itemManifests } from './item/manifests.js'; +import { manifests as validationManifests } from './validation/manifests.js'; -export const manifests: Array = [...detailManifests, ...itemManifests]; +export const manifests: Array = [...detailManifests, ...itemManifests, ...validationManifests]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/validation/index.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/validation/index.ts new file mode 100644 index 000000000000..b9b6aaf0dc65 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/validation/index.ts @@ -0,0 +1,2 @@ +export { UmbMemberValidationRepository } from './member-validation.repository.js'; +export { UMB_MEMBER_VALIDATION_REPOSITORY_ALIAS } from './manifests.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/validation/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/validation/manifests.ts new file mode 100644 index 000000000000..e88d2792af2e --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/validation/manifests.ts @@ -0,0 +1,10 @@ +export const UMB_MEMBER_VALIDATION_REPOSITORY_ALIAS = 'Umb.Repository.Member.Validation'; + +export const manifests: Array = [ + { + type: 'repository', + alias: UMB_MEMBER_VALIDATION_REPOSITORY_ALIAS, + name: 'Member Validation Repository', + api: () => import('./member-validation.repository.js'), + }, +]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/validation/member-validation.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/validation/member-validation.repository.ts new file mode 100644 index 000000000000..648b5b9a9efa --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/validation/member-validation.repository.ts @@ -0,0 +1,48 @@ +import type { UmbMemberDetailModel } from '../../types.js'; +import { UmbMemberValidationServerDataSource } from './member-validation.server.data-source.js'; +import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbRepositoryBase } from '@umbraco-cms/backoffice/repository'; +import type { UmbContentValidationRepository } from '@umbraco-cms/backoffice/content'; + +type DetailModelType = UmbMemberDetailModel; + +export class UmbMemberValidationRepository + extends UmbRepositoryBase + implements UmbContentValidationRepository +{ + #validationDataSource: UmbMemberValidationServerDataSource; + + constructor(host: UmbControllerHost) { + super(host); + + this.#validationDataSource = new UmbMemberValidationServerDataSource(this); + } + + /** + * Returns a promise with an observable of the detail for the given unique + * @param {DetailModelType} model - The model to validate + * @param {string | null} [parentUnique] - The parent unique + * @returns {*} + */ + async validateCreate(model: DetailModelType, parentUnique: string | null) { + if (!model) throw new Error('Data is missing'); + + return this.#validationDataSource.validateCreate(model, parentUnique); + } + + /** + * Saves the given data + * @param {DetailModelType} model - The model to save + * @param {Array} variantIds - The variant ids to save + * @returns {*} + */ + async validateSave(model: DetailModelType, variantIds: Array) { + if (!model) throw new Error('Data is missing'); + if (!model.unique) throw new Error('Unique is missing'); + + return this.#validationDataSource.validateUpdate(model, variantIds); + } +} + +export { UmbMemberValidationRepository as api }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/validation/member-validation.server.data-source.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/validation/member-validation.server.data-source.ts new file mode 100644 index 000000000000..6dac610d9c98 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/repository/validation/member-validation.server.data-source.ts @@ -0,0 +1,89 @@ +import type { UmbMemberDetailModel } from '../../types.js'; +import { + type CreateMemberRequestModel, + MemberService, + type UpdateMemberRequestModel, +} from '@umbraco-cms/backoffice/external/backend-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { tryExecute } from '@umbraco-cms/backoffice/resources'; +import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; +import type { UmbEntityUnique } from '@umbraco-cms/backoffice/entity'; + +/** + * A server data source for Member Validation + */ +export class UmbMemberValidationServerDataSource { + //#host: UmbControllerHost; + + // TODO: [v15]: ignoring unused var here here to prevent a breaking change + // eslint-disable-next-line @typescript-eslint/no-unused-vars + constructor(host: UmbControllerHost) { + //this.#host = host; + } + + /** + * Validate a new Member on the server + * @param {UmbMemberDetailModel} model - Member Model + * @param {UmbEntityUnique} parentUnique - Parent Unique + * @returns {*} - The response from the server + */ + async validateCreate(model: UmbMemberDetailModel, parentUnique: UmbEntityUnique = null) { + if (!model) throw new Error('Member is missing'); + if (!model.unique) throw new Error('Member unique is missing'); + if (!model.newPassword) throw new Error('Member newPassword is missing'); + if (parentUnique === undefined) throw new Error('Parent unique is missing'); + + // TODO: make data mapper to prevent errors + const requestBody: CreateMemberRequestModel = { + email: model.email, + username: model.username, + password: model.newPassword, + isApproved: model.isApproved, + id: model.unique, + memberType: { id: model.memberType.unique }, + values: model.values, + variants: model.variants, + }; + + // Maybe use: tryExecuteAndNotify + return tryExecute( + //this.#host, + MemberService.postMemberValidate({ + requestBody, + }), + ); + } + + /** + * Validate a existing Member + * @param {UmbMemberDetailModel} model - Member Model + * @param {Array} variantIds - Variant Ids + * @returns {Promise<*>} - The response from the server + */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + async validateUpdate(model: UmbMemberDetailModel, variantIds: Array) { + if (!model.unique) throw new Error('Unique is missing'); + + //const cultures = variantIds.map((id) => id.culture).filter((culture) => culture !== null) as Array; + + // TODO: make data mapper to prevent errors + const requestBody: UpdateMemberRequestModel = { + email: model.email, + username: model.username, + isApproved: model.isApproved, + isLockedOut: model.isLockedOut, + isTwoFactorEnabled: model.isTwoFactorEnabled, + values: model.values, + variants: model.variants, + }; + + // Maybe use: tryExecuteAndNotify + return tryExecute( + //this.#host, + MemberService.putMemberByIdValidate({ + id: model.unique, + requestBody, + }), + ); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/member-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/member-workspace.context.ts index 3b26a9c35c41..42dad88cd03b 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/member-workspace.context.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member/workspace/member/member-workspace.context.ts @@ -38,6 +38,8 @@ export class UmbMemberWorkspaceContext workspaceAlias: UMB_MEMBER_WORKSPACE_ALIAS, detailRepositoryAlias: UMB_MEMBER_DETAIL_REPOSITORY_ALIAS, contentTypeDetailRepository: UmbMemberTypeDetailRepository, + // TODO: Enable Validation Repository when we have UI for showing validation issues on other tabs. [NL] + //contentValidationRepository: UmbMemberValidationRepository, contentVariantScaffold: UMB_MEMBER_DETAIL_MODEL_VARIANT_SCAFFOLD, });