From f5b01183e2c722b977231ae52a1c383e6b869931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 23 Sep 2024 14:17:52 +0200 Subject: [PATCH] Implement validation in insert field modal --- .../template-field-dropdown-list.element.ts | 40 ++++++++++++++--- ...lating-page-field-builder-modal.element.ts | 45 +++++++++++++------ 2 files changed, 66 insertions(+), 19 deletions(-) diff --git a/src/packages/templating/modals/templating-page-field-builder/components/template-field-dropdown-list/template-field-dropdown-list.element.ts b/src/packages/templating/modals/templating-page-field-builder/components/template-field-dropdown-list/template-field-dropdown-list.element.ts index ef744bf99c..d199e00ea3 100644 --- a/src/packages/templating/modals/templating-page-field-builder/components/template-field-dropdown-list/template-field-dropdown-list.element.ts +++ b/src/packages/templating/modals/templating-page-field-builder/components/template-field-dropdown-list/template-field-dropdown-list.element.ts @@ -16,6 +16,11 @@ import type { UUIComboboxEvent, UUIComboboxElement } from '@umbraco-cms/backoffi import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbMediaTypeDetailRepository, UMB_MEDIA_TYPE_PICKER_MODAL } from '@umbraco-cms/backoffice/media-type'; import { UMB_MODAL_MANAGER_CONTEXT, type UmbModalManagerContext } from '@umbraco-cms/backoffice/modal'; +import { + UMB_VALIDATION_EMPTY_LOCALIZATION_KEY, + UmbFormControlMixin, + type UmbFormControlValidatorConfig, +} from '@umbraco-cms/backoffice/validation'; interface FieldPickerValue { alias: string; @@ -29,19 +34,44 @@ enum FieldType { } @customElement('umb-template-field-dropdown-list') -export class UmbTemplateFieldDropdownListElement extends UmbLitElement { +export class UmbTemplateFieldDropdownListElement extends UmbFormControlMixin< + FieldPickerValue | undefined, + typeof UmbLitElement, + undefined +>(UmbLitElement) { + // + #requiredValidation?: UmbFormControlValidatorConfig; + @property({ type: Boolean }) + public get required(): boolean | undefined { + return undefined; + } + public set required(value: boolean | undefined) { + if (value === true) { + this.#requiredValidation ??= this.addValidator( + 'valueMissing', + () => this.requiredMessage, + () => !this._value, + ); + } else if (this.#requiredValidation) { + this.removeValidator(this.#requiredValidation); + } + } + + @property({ type: String }) + requiredMessage = UMB_VALIDATION_EMPTY_LOCALIZATION_KEY; + @property({ type: Boolean, attribute: 'exclude-media-type', reflect: true }) public excludeMediaType = false; private _value: FieldPickerValue | undefined; @property({ type: Object }) - public set value(val: FieldPickerValue | undefined) { + public override set value(val: FieldPickerValue | undefined) { const oldVal = this._value; this._value = val; this.requestUpdate('value', oldVal); this.dispatchEvent(new UmbChangeEvent()); } - public get value(): FieldPickerValue | undefined { + public override get value(): FieldPickerValue | undefined { return this._value; } @@ -176,8 +206,8 @@ export class UmbTemplateFieldDropdownListElement extends UmbLitElement { if (this._type !== FieldType.SYSTEM && !this._unique) return; return html` ${this.localize.string(this._uniqueName ?? '')} - - + + ${repeat( this._customFields, (field) => field.alias, diff --git a/src/packages/templating/modals/templating-page-field-builder/templating-page-field-builder-modal.element.ts b/src/packages/templating/modals/templating-page-field-builder/templating-page-field-builder-modal.element.ts index 9f8ea3fbba..9d1eec32e3 100644 --- a/src/packages/templating/modals/templating-page-field-builder/templating-page-field-builder-modal.element.ts +++ b/src/packages/templating/modals/templating-page-field-builder/templating-page-field-builder-modal.element.ts @@ -7,24 +7,35 @@ import type { UmbTemplateFieldDropdownListElement } from './components/template- import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { css, html, customElement, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbModalBaseElement } from '@umbraco-cms/backoffice/modal'; -import type { UUIBooleanInputEvent, UUIInputEvent } from '@umbraco-cms/backoffice/external/uui'; +import type { UUIBooleanInputEvent, UUIButtonState, UUIInputEvent } from '@umbraco-cms/backoffice/external/uui'; // import of local components import './components/template-field-dropdown-list/index.js'; +import { UmbValidationContext, umbBindToValidation } from '@umbraco-cms/backoffice/validation'; @customElement('umb-templating-page-field-builder-modal') export class UmbTemplatingPageFieldBuilderModalElement extends UmbModalBaseElement< UmbTemplatingPageFieldBuilderModalData, UmbTemplatingPageFieldBuilderModalValue > { - private _close() { + #validation = new UmbValidationContext(this); + + #close() { this.modalContext?.reject(); } - private _submit() { - if (!this._field) return; - this.value = { output: getUmbracoFieldSnippet(this._field, this._default, this._recursive) }; - this.modalContext?.submit(); + async #submit() { + this._submitButtonState = 'waiting'; + + try { + await this.#validation.validate(); + this._submitButtonState = 'success'; + + this.value = { output: getUmbracoFieldSnippet(this._field!, this._default, this._recursive) }; + this.modalContext?.submit(); + } catch { + this._submitButtonState = 'failed'; + } } @state() @@ -39,6 +50,9 @@ export class UmbTemplatingPageFieldBuilderModalElement extends UmbModalBaseEleme @state() private _recursive: boolean = false; + @state() + private _submitButtonState: UUIButtonState; + /** TODO: Implement "Choose field" */ #onChangeFieldValue(e: Event) { @@ -50,12 +64,14 @@ export class UmbTemplatingPageFieldBuilderModalElement extends UmbModalBaseEleme
- - Choose field - - + + + Default value @@ -85,14 +101,15 @@ export class UmbTemplatingPageFieldBuilderModalElement extends UmbModalBaseEleme `;