From 773a155d36a5abae12ca16d83bc81378631d13a6 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 8 Jul 2024 16:24:17 +0100 Subject: [PATCH 1/4] Adds `validation` to the Property Context --- .../property/property/property.context.ts | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/packages/core/property/property/property.context.ts b/src/packages/core/property/property/property.context.ts index 9d1ea7be5d..76a0dbaa15 100644 --- a/src/packages/core/property/property/property.context.ts +++ b/src/packages/core/property/property/property.context.ts @@ -14,27 +14,39 @@ import type { UmbVariantId } from '@umbraco-cms/backoffice/variant'; import type { UmbPropertyEditorConfigProperty } from '@umbraco-cms/backoffice/property-editor'; import { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; -import type { UmbPropertyTypeAppearanceModel } from '@umbraco-cms/backoffice/content-type'; +import type { + UmbPropertyTypeAppearanceModel, + UmbPropertyTypeValidationModel, +} from '@umbraco-cms/backoffice/content-type'; export class UmbPropertyContext extends UmbContextBase> { #alias = new UmbStringState(undefined); public readonly alias = this.#alias.asObservable(); + #label = new UmbStringState(undefined); public readonly label = this.#label.asObservable(); + #description = new UmbStringState(undefined); public readonly description = this.#description.asObservable(); + #appearance = new UmbObjectState(undefined); public readonly appearance = this.#appearance.asObservable(); + #value = new UmbDeepState(undefined); public readonly value = this.#value.asObservable(); + #configValues = new UmbArrayState([], (x) => x.alias); public readonly configValues = this.#configValues.asObservable(); #config = new UmbClassState(undefined); public readonly config = this.#config.asObservable(); + #validation = new UmbObjectState(undefined); + public readonly validation = this.#validation.asObservable(); + private _editor = new UmbBasicState(undefined); public readonly editor = this._editor.asObservable(); + setEditor(editor: UmbPropertyEditorUiElement | undefined) { this._editor.setValue(editor ?? undefined); } @@ -108,24 +120,28 @@ export class UmbPropertyContext extends UmbContextBase extends UmbContextBase | undefined): void { this.#configValues.setValue(config ?? []); } public getConfig(): Array | undefined { return this.#configValues.getValue(); } + public setVariantId(variantId: UmbVariantId | undefined): void { this.#variantId.setValue(variantId); } @@ -156,6 +174,13 @@ export class UmbPropertyContext extends UmbContextBase Date: Mon, 8 Jul 2024 16:24:53 +0100 Subject: [PATCH 2/4] Passed the `validation` object through to the `umb-property` --- .../property-type-based-property.element.ts | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/packages/core/content-type/components/property-type-based-property/property-type-based-property.element.ts b/src/packages/core/content-type/components/property-type-based-property/property-type-based-property.element.ts index 7093fe2200..d0dafc2fdc 100644 --- a/src/packages/core/content-type/components/property-type-based-property/property-type-based-property.element.ts +++ b/src/packages/core/content-type/components/property-type-based-property/property-type-based-property.element.ts @@ -1,19 +1,17 @@ import type { UmbPropertyEditorConfig } from '../../../property-editor/index.js'; import type { UmbPropertyTypeModel } from '../../types.js'; +import { css, customElement, html, ifDefined, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbContentPropertyContext } from '@umbraco-cms/backoffice/content'; -import type { UmbDataTypeDetailModel } from '@umbraco-cms/backoffice/data-type'; import { UmbDataTypeDetailRepository } from '@umbraco-cms/backoffice/data-type'; -import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { css, html, ifDefined, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; +import type { UmbDataTypeDetailModel } from '@umbraco-cms/backoffice/data-type'; import type { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; -import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; + @customElement('umb-property-type-based-property') export class UmbPropertyTypeBasedPropertyElement extends UmbLitElement { @property({ type: Object, attribute: false }) - public get property(): UmbPropertyTypeModel | undefined { - return this._property; - } public set property(value: UmbPropertyTypeModel | undefined) { const oldProperty = this._property; this._property = value; @@ -21,6 +19,9 @@ export class UmbPropertyTypeBasedPropertyElement extends UmbLitElement { this._observeDataType(this._property?.dataType.unique); } } + public get property(): UmbPropertyTypeModel | undefined { + return this._property; + } private _property?: UmbPropertyTypeModel; @property({ type: String, attribute: 'data-path' }) @@ -73,16 +74,19 @@ export class UmbPropertyTypeBasedPropertyElement extends UmbLitElement { } override render() { - return this._propertyEditorUiAlias && this._property?.alias - ? html`` - : ''; + if (!this._propertyEditorUiAlias || !this._property?.alias) return; + return html` + + + `; } static override styles = [ From cfc5831e6db5195fa1f69932361be1579892832e Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 8 Jul 2024 16:25:50 +0100 Subject: [PATCH 3/4] Sets the context's `validation` and `mandatory` attribute on the `umb-property-layout`. --- .../property/property/property.element.ts | 56 ++++++++++++++----- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/src/packages/core/property/property/property.element.ts b/src/packages/core/property/property/property.element.ts index cb740eb832..2eda498629 100644 --- a/src/packages/core/property/property/property.element.ts +++ b/src/packages/core/property/property/property.element.ts @@ -1,21 +1,24 @@ import { UmbPropertyContext } from './property.context.js'; -import type { ManifestPropertyEditorUi } from '@umbraco-cms/backoffice/extension-registry'; -import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; -import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; -import { css, html, customElement, property, state, nothing } from '@umbraco-cms/backoffice/external/lit'; +import { css, customElement, html, property, state, nothing } from '@umbraco-cms/backoffice/external/lit'; import { createExtensionElement } from '@umbraco-cms/backoffice/extension-api'; -import type { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; +import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import type { - UmbPropertyEditorConfigCollection, - UmbPropertyEditorConfig, -} from '@umbraco-cms/backoffice/property-editor'; +import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UmbBindValidationMessageToFormControl, UmbFormControlValidator, UmbObserveValidationStateController, } from '@umbraco-cms/backoffice/validation'; -import type { UmbPropertyTypeAppearanceModel } from '@umbraco-cms/backoffice/content-type'; +import type { ManifestPropertyEditorUi } from '@umbraco-cms/backoffice/extension-registry'; +import type { + UmbPropertyEditorConfigCollection, + UmbPropertyEditorConfig, +} from '@umbraco-cms/backoffice/property-editor'; +import type { + UmbPropertyTypeAppearanceModel, + UmbPropertyTypeValidationModel, +} from '@umbraco-cms/backoffice/content-type'; +import type { UmbObserverController } from '@umbraco-cms/backoffice/observable-api'; /** * @element umb-property @@ -112,6 +115,17 @@ export class UmbPropertyElement extends UmbLitElement { return this.#propertyContext.getConfig(); } + /** + * Validation: Validation settings for the property. + */ + @property({ type: Object, attribute: false }) + public set validation(validation: UmbPropertyTypeValidationModel | undefined) { + this.#propertyContext.setValidation(validation); + } + public get validation() { + return this.#propertyContext.getValidation(); + } + /** * DataPath, declare the path to the value of the data that this property represents. * @public @@ -152,6 +166,9 @@ export class UmbPropertyElement extends UmbLitElement { @state() private _orientation: 'horizontal' | 'vertical' = 'horizontal'; + @state() + private _mandatory?: boolean; + #propertyContext = new UmbPropertyContext(this); #controlValidator?: UmbFormControlValidator; @@ -169,6 +186,7 @@ export class UmbPropertyElement extends UmbLitElement { }, null, ); + this.observe( this.#propertyContext.label, (label) => { @@ -176,6 +194,7 @@ export class UmbPropertyElement extends UmbLitElement { }, null, ); + this.observe( this.#propertyContext.description, (description) => { @@ -183,6 +202,7 @@ export class UmbPropertyElement extends UmbLitElement { }, null, ); + this.observe( this.#propertyContext.variantDifference, (variantDifference) => { @@ -190,6 +210,7 @@ export class UmbPropertyElement extends UmbLitElement { }, null, ); + this.observe( this.#propertyContext.appearance, (appearance) => { @@ -197,6 +218,14 @@ export class UmbPropertyElement extends UmbLitElement { }, null, ); + + this.observe( + this.#propertyContext.validation, + (validation) => { + this._mandatory = validation?.mandatory; + }, + null, + ); } private _onPropertyEditorChange = (e: CustomEvent): void => { @@ -297,10 +326,11 @@ export class UmbPropertyElement extends UmbLitElement { return html` ${this.#renderPropertyActionMenu()} ${this._variantDifference From 7365dac0ace75909aec02118e24611e59485d9da Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 8 Jul 2024 16:26:29 +0100 Subject: [PATCH 4/4] Displays the mandatory indicator on the property's `uui-label` --- .../property-layout/property-layout.element.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/packages/core/property/property-layout/property-layout.element.ts b/src/packages/core/property/property-layout/property-layout.element.ts index ba194a6e06..1724d318a1 100644 --- a/src/packages/core/property/property-layout/property-layout.element.ts +++ b/src/packages/core/property/property-layout/property-layout.element.ts @@ -51,7 +51,7 @@ export class UmbPropertyLayoutElement extends UmbLitElement { public description = ''; /** - * @description Make the property appear invalid + * @description Make the property appear invalid. * @type {boolean} * @attr * @default undefined @@ -59,11 +59,20 @@ export class UmbPropertyLayoutElement extends UmbLitElement { @property({ type: Boolean, reflect: true }) public invalid?: boolean; + /** + * @description Display a mandatory indicator. + * @type {boolean} + * @attr + * @default false + */ + @property({ type: Boolean, reflect: true }) + public mandatory?: boolean; + override render() { // TODO: Only show alias on label if user has access to DocumentType within settings: return html`
- + ${this.localize.string(this.label)} ${when(this.invalid, () => html`!`)}