diff --git a/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid.element.ts b/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid.element.ts index 0c597e5ded..afc2d9033b 100644 --- a/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid.element.ts +++ b/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid.element.ts @@ -29,7 +29,7 @@ export class UmbPropertyEditorUIBlockGridElement extends UmbFormControlMixin(UmbLitElement) implements UmbPropertyEditorUiElement { - #validationContext = new UmbValidationContext(this).provide(); + #validationContext = new UmbValidationContext(this); #contentDataPathTranslator?: UmbBlockElementDataValidationPathTranslator; #settingsDataPathTranslator?: UmbBlockElementDataValidationPathTranslator; #context = new UmbBlockGridManagerContext(this); diff --git a/src/packages/block/block-list/property-editors/block-list-editor/property-editor-ui-block-list.element.ts b/src/packages/block/block-list/property-editors/block-list-editor/property-editor-ui-block-list.element.ts index 5aa7bfe843..453fc7af90 100644 --- a/src/packages/block/block-list/property-editors/block-list-editor/property-editor-ui-block-list.element.ts +++ b/src/packages/block/block-list/property-editors/block-list-editor/property-editor-ui-block-list.element.ts @@ -52,7 +52,7 @@ export class UmbPropertyEditorUIBlockListElement }, }); - #validationContext = new UmbValidationContext(this).provide(); + #validationContext = new UmbValidationContext(this); #contentDataPathTranslator?: UmbBlockElementDataValidationPathTranslator; #settingsDataPathTranslator?: UmbBlockElementDataValidationPathTranslator; diff --git a/src/packages/block/block/workspace/block-element-manager.ts b/src/packages/block/block/workspace/block-element-manager.ts index cb1f037a1a..294a553c13 100644 --- a/src/packages/block/block/workspace/block-element-manager.ts +++ b/src/packages/block/block/workspace/block-element-manager.ts @@ -7,7 +7,7 @@ import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; import { type UmbClassInterface, UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; import { UmbDocumentTypeDetailRepository } from '@umbraco-cms/backoffice/document-type'; import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; -import { UmbValidationContext } from '@umbraco-cms/backoffice/validation'; +import { UmbValidationController } from '@umbraco-cms/backoffice/validation'; export class UmbBlockElementManager extends UmbControllerBase { // @@ -29,7 +29,7 @@ export class UmbBlockElementManager extends UmbControllerBase { new UmbDocumentTypeDetailRepository(this), ); - readonly validation = new UmbValidationContext(this); + readonly validation = new UmbValidationController(this); constructor(host: UmbControllerHost, dataPathPropertyName: string) { super(host); diff --git a/src/packages/core/property-type/workspace/property-type-workspace.context.ts b/src/packages/core/property-type/workspace/property-type-workspace.context.ts index 5311ea844f..42aef070df 100644 --- a/src/packages/core/property-type/workspace/property-type-workspace.context.ts +++ b/src/packages/core/property-type/workspace/property-type-workspace.context.ts @@ -41,7 +41,7 @@ export class UmbPropertyTypeWorkspaceContext('UmbValidationContext'); +export const UMB_VALIDATION_CONTEXT = new UmbContextToken('UmbValidationContext'); diff --git a/src/packages/core/validation/context/validation.context.ts b/src/packages/core/validation/context/validation.context.ts index f4d7193ec4..6deed36696 100644 --- a/src/packages/core/validation/context/validation.context.ts +++ b/src/packages/core/validation/context/validation.context.ts @@ -1,296 +1,32 @@ -import type { UmbValidator } from '../interfaces/validator.interface.js'; -import type { UmbValidationMessageTranslator } from '../translators/index.js'; -import { GetValueByJsonPath } from '../utils/json-path.function.js'; -import { type UmbValidationMessage, UmbValidationMessagesManager } from './validation-messages.manager.js'; +import { UmbValidationController } from '../controllers/validation.controller.js'; import { UMB_VALIDATION_CONTEXT } from './validation.context-token.js'; -import type { UmbContextProviderController } from '@umbraco-cms/backoffice/context-api'; -import { type UmbClassInterface, UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbClassInterface } from '@umbraco-cms/backoffice/class-api'; import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; -import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; - -/** - * Helper method to replace the start of a string with another string. - * @param path {string} - * @param startFrom {string} - * @param startTo {string} - * @returns {string} - */ -function ReplaceStartOfString(path: string, startFrom: string, startTo: string): string { - if (path.startsWith(startFrom + '.')) { - return startTo + path.slice(startFrom.length); - } - return path; -} - /** * Validation Context is the core of Validation. * It hosts Validators that has to validate for the context to be valid. * It can also be used as a Validator as part of a parent Validation Context. */ -export class UmbValidationContext extends UmbControllerBase implements UmbValidator { - // The current provider controller, that is providing this context: - #providerCtrl?: UmbContextProviderController; - - // Local version of the data send to the server, only use-case is for translation. - #translationData = new UmbObjectState(undefined); - translationDataOf(path: string): any { - return this.#translationData.asObservablePart((data) => GetValueByJsonPath(data, path)); - } - setTranslationData(data: any): void { - this.#translationData.setValue(data); - } - getTranslationData(): any { - return this.#translationData.getValue(); - } - - #validators: Array = []; - #validationMode: boolean = false; - #isValid: boolean = false; - - #parent?: UmbValidationContext; - #parentMessages?: Array; - #localMessages?: Array; - #baseDataPath?: string; - - public readonly messages = new UmbValidationMessagesManager(); - +export class UmbValidationContext extends UmbValidationController { constructor(host: UmbControllerHost) { // This is overridden to avoid setting a controllerAlias, this might make sense, but currently i want to leave it out. [NL] super(host); - } - - /** - * Add a path translator to this validation context. - * @param translator - */ - async addTranslator(translator: UmbValidationMessageTranslator) { - this.messages.addTranslator(translator); - } - - /** - * Remove a path translator from this validation context. - * @param translator - */ - async removeTranslator(translator: UmbValidationMessageTranslator) { - this.messages.removeTranslator(translator); + this.provideContext(UMB_VALIDATION_CONTEXT, this); } /** * Provides the validation context to the current host, if not already provided to a different host. - * @returns instance {UmbValidationContext} - Returns it self. + * @deprecated No need to provide, this happens automatically. (Do notice this was necessary in 14.3.-rc, but removed in 14.3 release) + * @returns instance {UmbValidationController} - Returns it self. */ - provide(): UmbValidationContext { - if (this.#providerCtrl) return this; - this.provideContext(UMB_VALIDATION_CONTEXT, this); + provide(): UmbValidationController { return this; } - /** - * Provide this validation context to a specific controller host. - * This can be used to Host a validation context in a Workspace, but provide it on a certain scope, like a specific Workspace View. - * @param controllerHost {UmbClassInterface} - */ - provideAt(controllerHost: UmbClassInterface): void { - this.#providerCtrl?.destroy(); - this.#providerCtrl = controllerHost.provideContext(UMB_VALIDATION_CONTEXT, this); - } - - /** - * Define a specific data path for this validation context. - * This will turn this validation context into a sub-context of the parent validation context. - * This means that a two-way binding for messages will be established between the parent and the sub-context. - * And it will inherit the Translation Data from its parent. - * - * messages and data will be localizes accordingly to the given data path. - * @param dataPath {string} - The data path to bind this validation context to. - * @example - * ```ts - * const validationContext = new UmbValidationContext(host); - * validationContext.setDataPath("$.values[?(@.alias='my-property')].value"); - * ``` - * - * A message with the path: '$.values[?(@.alias='my-property')].value.innerProperty', will for above example become '$.innerProperty' for the local Validation Context. - */ - setDataPath(dataPath: string): void { - if (this.#baseDataPath) { - if (this.#baseDataPath === dataPath) return; - console.log(this.#baseDataPath, dataPath); - // Just fire an error, as I haven't made the right clean up jet. Or haven't thought about what should happen if it changes while already setup. - // cause maybe all the messages should be removed as we are not interested in the old once any more. But then on the other side, some might be relevant as this is the same entity that changed its paths? - throw new Error('Data path is already set, we do not support changing the context data-path as of now.'); - } - if (!dataPath) return; - this.#baseDataPath = dataPath; - - this.consumeContext(UMB_VALIDATION_CONTEXT, (parent) => { - if (this.#parent) { - this.#parent.removeValidator(this); - } - this.#parent = parent; - parent.addValidator(this); - - this.messages.clear(); - - this.observe(parent.translationDataOf(dataPath), (data) => { - this.setTranslationData(data); - }); - - this.observe( - parent.messages.messagesOfPathAndDescendant(dataPath), - (msgs) => { - //this.messages.appendMessages(msgs); - if (this.#parentMessages) { - // Remove the local messages that does not exist in the parent anymore: - const toRemove = this.#parentMessages.filter((msg) => !msgs.find((m) => m.key === msg.key)); - toRemove.forEach((msg) => { - this.messages.removeMessageByKey(msg.key); - }); - } - this.#parentMessages = msgs; - msgs.forEach((msg) => { - const path = ReplaceStartOfString(msg.path, this.#baseDataPath!, '$'); - // Notice, the local message uses the same key. [NL] - this.messages.addMessage(msg.type, path, msg.body, msg.key); - }); - }, - 'observeParentMessages', - ); - - this.observe( - this.messages.messages, - (msgs) => { - if (!this.#parent) return; - //this.messages.appendMessages(msgs); - if (this.#localMessages) { - // Remove the parent messages that does not exist locally anymore: - const toRemove = this.#localMessages.filter((msg) => !msgs.find((m) => m.key === msg.key)); - toRemove.forEach((msg) => { - this.#parent!.messages.removeMessageByKey(msg.key); - }); - } - this.#localMessages = msgs; - msgs.forEach((msg) => { - // replace this.#baseDataPath (if it starts with it) with $ in the path, so it becomes relative to the parent context - const path = ReplaceStartOfString(msg.path, '$', this.#baseDataPath!); - // Notice, the parent message uses the same key. [NL] - this.#parent!.messages.addMessage(msg.type, path, msg.body, msg.key); - }); - }, - 'observeLocalMessages', - ); - }).skipHost(); - // Notice skipHost ^^, this is because we do not want it to consume it self, as this would be a match for this consumption, instead we will look at the parent and above. [NL] - } - - /** - * Get if this context is valid. - * Notice this does not verify the validity. - * @returns {boolean} - */ - get isValid(): boolean { - return this.#isValid; - } - - /** - * Add a validator to this context. - * This validator will have to be valid for the context to be valid. - * If the context is in validation mode, the validator will be validated immediately. - * @param validator { UmbValidator } - The validator to add to this context. - */ - addValidator(validator: UmbValidator): void { - if (this.#validators.includes(validator)) return; - this.#validators.push(validator); - //validator.addEventListener('change', this.#onValidatorChange); - if (this.#validationMode) { - this.validate(); - } - } - - /** - * Remove a validator from this context. - * @param validator {UmbValidator} - The validator to remove from this context. - */ - removeValidator(validator: UmbValidator): void { - const index = this.#validators.indexOf(validator); - if (index !== -1) { - // Remove the validator: - this.#validators.splice(index, 1); - // If we are in validation mode then we should re-validate to focus next invalid element: - if (this.#validationMode) { - this.validate(); - } - } - } - - /** - * Validate this context, all the validators of this context will be validated. - * Notice its a recursive check meaning sub validation contexts also validates their validators. - * @returns succeed {Promise} - Returns a promise that resolves to true if the validator succeeded, this depends on the validators and wether forceSucceed is set. - */ - async validate(): Promise { - // TODO: clear server messages here?, well maybe only if we know we will get new server messages? Do the server messages hook into the system like another validator? - this.#validationMode = true; - const resultsStatus = await Promise.all(this.#validators.map((v) => v.validate())).then( - () => Promise.resolve(true), - () => Promise.resolve(false), + // eslint-disable-next-line @typescript-eslint/no-unused-vars + override provideAt(controllerHost: UmbClassInterface): void { + throw new Error( + 'UmbValidationContext cannot be used to provide at a different host. Use the UmbValidationController instead.', ); - - if (!this.messages) { - // This Context has been destroyed while is was validating, so we should not continue. - return; - } - - // If we have any messages then we are not valid, otherwise lets check the validation results: [NL] - // This enables us to keep client validations though UI is not present anymore — because the client validations got defined as messages. [NL] - const isValid = this.messages.getHasAnyMessages() ? false : resultsStatus; - - this.#isValid = isValid; - - if (isValid === false) { - // Focus first invalid element: - this.focusFirstInvalidElement(); - return Promise.reject(); - } - - return Promise.resolve(); - } - - /** - * Focus the first invalid element that this context can find. - */ - focusFirstInvalidElement(): void { - const firstInvalid = this.#validators.find((v) => !v.isValid); - if (firstInvalid) { - firstInvalid.focusFirstInvalidElement(); - } - } - - /** - * Reset the validation state of this context. - */ - reset(): void { - this.#validationMode = false; - this.#validators.forEach((v) => v.reset()); - } - - #destroyValidators(): void { - if (this.#validators === undefined || this.#validators.length === 0) return; - this.#validators.forEach((validator) => { - validator.destroy(); - //validator.removeEventListener('change', this.#runValidate); - }); - this.#validators = []; - } - - override destroy(): void { - this.#providerCtrl = undefined; - if (this.#parent) { - this.#parent.removeValidator(this); - } - this.#parent = undefined; - this.#destroyValidators(); - this.messages?.destroy(); - (this.messages as unknown) = undefined; - super.destroy(); } } diff --git a/src/packages/core/validation/controllers/index.ts b/src/packages/core/validation/controllers/index.ts index 66e51504c5..4649c9f322 100644 --- a/src/packages/core/validation/controllers/index.ts +++ b/src/packages/core/validation/controllers/index.ts @@ -1,5 +1,4 @@ export * from './bind-server-validation-to-form-control.controller.js'; export * from './form-control-validator.controller.js'; export * from './observe-validation-state.controller.js'; -export * from './server-model-validator.context-token.js'; -export * from './server-model-validator.context.js'; +export * from './validation.controller.js'; diff --git a/src/packages/core/validation/controllers/validation.controller.ts b/src/packages/core/validation/controllers/validation.controller.ts new file mode 100644 index 0000000000..eac15a1308 --- /dev/null +++ b/src/packages/core/validation/controllers/validation.controller.ts @@ -0,0 +1,291 @@ +import type { UmbValidator } from '../interfaces/validator.interface.js'; +import type { UmbValidationMessageTranslator } from '../translators/index.js'; +import { GetValueByJsonPath } from '../utils/json-path.function.js'; +import { UMB_VALIDATION_CONTEXT } from '../context/validation.context-token.js'; +import { type UmbValidationMessage, UmbValidationMessagesManager } from '../context/validation-messages.manager.js'; +import type { UmbContextProviderController } from '@umbraco-cms/backoffice/context-api'; +import { type UmbClassInterface, UmbControllerBase } from '@umbraco-cms/backoffice/class-api'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; + +/** + * Helper method to replace the start of a string with another string. + * @param path {string} + * @param startFrom {string} + * @param startTo {string} + * @returns {string} + */ +function ReplaceStartOfString(path: string, startFrom: string, startTo: string): string { + if (path.startsWith(startFrom + '.')) { + return startTo + path.slice(startFrom.length); + } + return path; +} + +/** + * Validation Context is the core of Validation. + * It hosts Validators that has to validate for the context to be valid. + * It can also be used as a Validator as part of a parent Validation Context. + */ +export class UmbValidationController extends UmbControllerBase implements UmbValidator { + // The current provider controller, that is providing this context: + #providerCtrl?: UmbContextProviderController< + UmbValidationController, + UmbValidationController, + UmbValidationController + >; + + // Local version of the data send to the server, only use-case is for translation. + #translationData = new UmbObjectState(undefined); + translationDataOf(path: string): any { + return this.#translationData.asObservablePart((data) => GetValueByJsonPath(data, path)); + } + setTranslationData(data: any): void { + this.#translationData.setValue(data); + } + getTranslationData(): any { + return this.#translationData.getValue(); + } + + #validators: Array = []; + #validationMode: boolean = false; + #isValid: boolean = false; + + #parent?: UmbValidationController; + #parentMessages?: Array; + #localMessages?: Array; + #baseDataPath?: string; + + public readonly messages = new UmbValidationMessagesManager(); + + constructor(host: UmbControllerHost) { + // This is overridden to avoid setting a controllerAlias, this might make sense, but currently i want to leave it out. [NL] + super(host); + } + + /** + * Add a path translator to this validation context. + * @param translator + */ + async addTranslator(translator: UmbValidationMessageTranslator) { + this.messages.addTranslator(translator); + } + + /** + * Remove a path translator from this validation context. + * @param translator + */ + async removeTranslator(translator: UmbValidationMessageTranslator) { + this.messages.removeTranslator(translator); + } + + /** + * Provide this validation context to a specific controller host. + * This can be used to Host a validation context in a Workspace, but provide it on a certain scope, like a specific Workspace View. + * @param controllerHost {UmbClassInterface} + */ + provideAt(controllerHost: UmbClassInterface): void { + this.#providerCtrl?.destroy(); + this.#providerCtrl = controllerHost.provideContext(UMB_VALIDATION_CONTEXT, this); + } + + /** + * Define a specific data path for this validation context. + * This will turn this validation context into a sub-context of the parent validation context. + * This means that a two-way binding for messages will be established between the parent and the sub-context. + * And it will inherit the Translation Data from its parent. + * + * messages and data will be localizes accordingly to the given data path. + * @param dataPath {string} - The data path to bind this validation context to. + * @example + * ```ts + * const validationContext = new UmbValidationContext(this); + * validationContext.setDataPath("$.values[?(@.alias='my-property')].value"); + * ``` + * + * A message with the path: '$.values[?(@.alias='my-property')].value.innerProperty', will for above example become '$.innerProperty' for the local Validation Context. + */ + setDataPath(dataPath: string): void { + if (this.#baseDataPath) { + if (this.#baseDataPath === dataPath) return; + console.log(this.#baseDataPath, dataPath); + // Just fire an error, as I haven't made the right clean up jet. Or haven't thought about what should happen if it changes while already setup. + // cause maybe all the messages should be removed as we are not interested in the old once any more. But then on the other side, some might be relevant as this is the same entity that changed its paths? + throw new Error('Data path is already set, we do not support changing the context data-path as of now.'); + } + if (!dataPath) return; + this.#baseDataPath = dataPath; + + this.consumeContext(UMB_VALIDATION_CONTEXT, (parent) => { + if (this.#parent) { + this.#parent.removeValidator(this); + } + this.#parent = parent; + parent.addValidator(this); + + this.messages.clear(); + + this.observe(parent.translationDataOf(dataPath), (data) => { + this.setTranslationData(data); + }); + + this.observe( + parent.messages.messagesOfPathAndDescendant(dataPath), + (msgs) => { + //this.messages.appendMessages(msgs); + if (this.#parentMessages) { + // Remove the local messages that does not exist in the parent anymore: + const toRemove = this.#parentMessages.filter((msg) => !msgs.find((m) => m.key === msg.key)); + toRemove.forEach((msg) => { + this.messages.removeMessageByKey(msg.key); + }); + } + this.#parentMessages = msgs; + msgs.forEach((msg) => { + const path = ReplaceStartOfString(msg.path, this.#baseDataPath!, '$'); + // Notice, the local message uses the same key. [NL] + this.messages.addMessage(msg.type, path, msg.body, msg.key); + }); + }, + 'observeParentMessages', + ); + + this.observe( + this.messages.messages, + (msgs) => { + if (!this.#parent) return; + //this.messages.appendMessages(msgs); + if (this.#localMessages) { + // Remove the parent messages that does not exist locally anymore: + const toRemove = this.#localMessages.filter((msg) => !msgs.find((m) => m.key === msg.key)); + toRemove.forEach((msg) => { + this.#parent!.messages.removeMessageByKey(msg.key); + }); + } + this.#localMessages = msgs; + msgs.forEach((msg) => { + // replace this.#baseDataPath (if it starts with it) with $ in the path, so it becomes relative to the parent context + const path = ReplaceStartOfString(msg.path, '$', this.#baseDataPath!); + // Notice, the parent message uses the same key. [NL] + this.#parent!.messages.addMessage(msg.type, path, msg.body, msg.key); + }); + }, + 'observeLocalMessages', + ); + }).skipHost(); + // Notice skipHost ^^, this is because we do not want it to consume it self, as this would be a match for this consumption, instead we will look at the parent and above. [NL] + } + + /** + * Get if this context is valid. + * Notice this does not verify the validity. + * @returns {boolean} + */ + get isValid(): boolean { + return this.#isValid; + } + + /** + * Add a validator to this context. + * This validator will have to be valid for the context to be valid. + * If the context is in validation mode, the validator will be validated immediately. + * @param validator { UmbValidator } - The validator to add to this context. + */ + addValidator(validator: UmbValidator): void { + if (this.#validators.includes(validator)) return; + this.#validators.push(validator); + //validator.addEventListener('change', this.#onValidatorChange); + if (this.#validationMode) { + this.validate(); + } + } + + /** + * Remove a validator from this context. + * @param validator {UmbValidator} - The validator to remove from this context. + */ + removeValidator(validator: UmbValidator): void { + const index = this.#validators.indexOf(validator); + if (index !== -1) { + // Remove the validator: + this.#validators.splice(index, 1); + // If we are in validation mode then we should re-validate to focus next invalid element: + if (this.#validationMode) { + this.validate(); + } + } + } + + /** + * Validate this context, all the validators of this context will be validated. + * Notice its a recursive check meaning sub validation contexts also validates their validators. + * @returns succeed {Promise} - Returns a promise that resolves to true if the validator succeeded, this depends on the validators and wether forceSucceed is set. + */ + async validate(): Promise { + // TODO: clear server messages here?, well maybe only if we know we will get new server messages? Do the server messages hook into the system like another validator? + this.#validationMode = true; + + const resultsStatus = await Promise.all(this.#validators.map((v) => v.validate())).then( + () => Promise.resolve(true), + () => Promise.resolve(false), + ); + + if (!this.messages) { + // This Context has been destroyed while is was validating, so we should not continue. + return; + } + + // If we have any messages then we are not valid, otherwise lets check the validation results: [NL] + // This enables us to keep client validations though UI is not present anymore — because the client validations got defined as messages. [NL] + const isValid = this.messages.getHasAnyMessages() ? false : resultsStatus; + + this.#isValid = isValid; + + if (isValid === false) { + // Focus first invalid element: + this.focusFirstInvalidElement(); + return Promise.reject(); + } + + return Promise.resolve(); + } + + /** + * Focus the first invalid element that this context can find. + */ + focusFirstInvalidElement(): void { + const firstInvalid = this.#validators.find((v) => !v.isValid); + if (firstInvalid) { + firstInvalid.focusFirstInvalidElement(); + } + } + + /** + * Reset the validation state of this context. + */ + reset(): void { + this.#validationMode = false; + this.#validators.forEach((v) => v.reset()); + } + + #destroyValidators(): void { + if (this.#validators === undefined || this.#validators.length === 0) return; + this.#validators.forEach((validator) => { + validator.destroy(); + //validator.removeEventListener('change', this.#runValidate); + }); + this.#validators = []; + } + + override destroy(): void { + this.#providerCtrl = undefined; + if (this.#parent) { + this.#parent.removeValidator(this); + } + this.#parent = undefined; + this.#destroyValidators(); + this.messages?.destroy(); + (this.messages as unknown) = undefined; + super.destroy(); + } +} diff --git a/src/packages/core/workspace/contexts/submittable-workspace-context-base.ts b/src/packages/core/workspace/contexts/submittable-workspace-context-base.ts index ccc13c9526..0b7224ab3c 100644 --- a/src/packages/core/workspace/contexts/submittable-workspace-context-base.ts +++ b/src/packages/core/workspace/contexts/submittable-workspace-context-base.ts @@ -7,7 +7,7 @@ import { UmbBooleanState } from '@umbraco-cms/backoffice/observable-api'; import type { UmbModalContext } from '@umbraco-cms/backoffice/modal'; import { UMB_MODAL_CONTEXT } from '@umbraco-cms/backoffice/modal'; import type { Observable } from '@umbraco-cms/backoffice/external/rxjs'; -import type { UmbValidationContext } from '@umbraco-cms/backoffice/validation'; +import type { UmbValidationController } from '@umbraco-cms/backoffice/validation'; export abstract class UmbSubmittableWorkspaceContextBase extends UmbContextBase> @@ -19,13 +19,13 @@ export abstract class UmbSubmittableWorkspaceContextBase public readonly modalContext?: UmbModalContext<{ preset: object }>; //public readonly validation = new UmbValidationContext(this); - #validationContexts: Array = []; + #validationContexts: Array = []; /** * Appends a validation context to the workspace. * @param context */ - addValidationContext(context: UmbValidationContext) { + addValidationContext(context: UmbValidationController) { this.#validationContexts.push(context); } diff --git a/src/packages/data-type/workspace/data-type-workspace.context.ts b/src/packages/data-type/workspace/data-type-workspace.context.ts index 0f8bb744ec..d450aefc1e 100644 --- a/src/packages/data-type/workspace/data-type-workspace.context.ts +++ b/src/packages/data-type/workspace/data-type-workspace.context.ts @@ -100,7 +100,7 @@ export class UmbDataTypeWorkspaceContext constructor(host: UmbControllerHost) { super(host, 'Umb.Workspace.DataType'); - this.addValidationContext(new UmbValidationContext(this).provide()); + this.addValidationContext(new UmbValidationContext(this)); this.#observePropertyEditorSchemaAlias(); this.#observePropertyEditorUIAlias(); diff --git a/src/packages/documents/document-types/workspace/document-type-workspace.context.ts b/src/packages/documents/document-types/workspace/document-type-workspace.context.ts index 65ab3f5c5f..a18f945efd 100644 --- a/src/packages/documents/document-types/workspace/document-type-workspace.context.ts +++ b/src/packages/documents/document-types/workspace/document-type-workspace.context.ts @@ -80,7 +80,7 @@ export class UmbDocumentTypeWorkspaceContext constructor(host: UmbControllerHost) { super(host, 'Umb.Workspace.DocumentType'); - this.addValidationContext(new UmbValidationContext(this).provide()); + this.addValidationContext(new UmbValidationContext(this)); // General for content types: //this.data = this.structure.ownerContentType; diff --git a/src/packages/documents/documents/workspace/document-workspace.context.ts b/src/packages/documents/documents/workspace/document-workspace.context.ts index 9f11620d47..128c0e7dec 100644 --- a/src/packages/documents/documents/workspace/document-workspace.context.ts +++ b/src/packages/documents/documents/workspace/document-workspace.context.ts @@ -171,7 +171,7 @@ export class UmbDocumentWorkspaceContext constructor(host: UmbControllerHost) { super(host, UMB_DOCUMENT_WORKSPACE_ALIAS); - this.addValidationContext(new UmbValidationContext(this).provide()); + this.addValidationContext(new UmbValidationContext(this)); new UmbVariantValuesValidationPathTranslator(this); new UmbVariantsValidationPathTranslator(this);