From 41b77142291d97e50920e81ae47ffb70ad86f665 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 15 Apr 2024 18:22:30 +0100 Subject: [PATCH 1/3] ColorPicker: Prefixes values with a hash in property-editor component, not the input component. The assumption is that the color hex values would already have a hash prefix. --- .../input-color/input-color.element.ts | 22 +++++------- ...property-editor-ui-color-picker.element.ts | 34 ++++++++++++++----- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-color/input-color.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-color/input-color.element.ts index b616c98dfd..9f3be5034e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-color/input-color.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-color/input-color.element.ts @@ -1,7 +1,7 @@ import { html, customElement, property, map, nothing } from '@umbraco-cms/backoffice/external/lit'; -import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui'; import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui'; import type { UmbSwatchDetails } from '@umbraco-cms/backoffice/models'; import type { UUIColorSwatchesEvent } from '@umbraco-cms/backoffice/external/uui'; @@ -11,25 +11,24 @@ import type { UUIColorSwatchesEvent } from '@umbraco-cms/backoffice/external/uui */ @customElement('umb-input-color') export class UmbInputColorElement extends UUIFormControlMixin(UmbLitElement, '') { - @property({ type: Boolean }) - showLabels = false; - - @property({ type: Array }) - swatches?: UmbSwatchDetails[]; - protected getFormElement() { return undefined; } + @property({ type: Boolean }) + showLabels = false; + + @property({ type: Array }) + swatches?: Array; + #onChange(event: UUIColorSwatchesEvent) { - event.stopPropagation(); this.value = event.target.value; this.dispatchEvent(new UmbChangeEvent()); } render() { return html` - + ${this.#renderColors()} `; @@ -40,10 +39,7 @@ export class UmbInputColorElement extends UUIFormControlMixin(UmbLitElement, '') return map( this.swatches, (swatch) => html` - + `, ); } diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/color-picker/property-editor-ui-color-picker.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/color-picker/property-editor-ui-color-picker.element.ts index 505a769cce..02b4ac2e34 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/color-picker/property-editor-ui-color-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/color-picker/property-editor-ui-color-picker.element.ts @@ -14,20 +14,38 @@ export class UmbPropertyEditorUIColorPickerElement extends UmbLitElement impleme #defaultShowLabels = false; @property({ type: Object }) - value?: UmbSwatchDetails; + public set value(value: UmbSwatchDetails | undefined) { + if (!value) return; + this.#value = this.#ensureHashPrefix(value); + } + public get value(): UmbSwatchDetails | undefined { + return this.#value; + } + #value?: UmbSwatchDetails | undefined; @state() private _showLabels = this.#defaultShowLabels; @state() - private _swatches: UmbSwatchDetails[] = []; + private _swatches: Array = []; public set config(config: UmbPropertyEditorConfigCollection | undefined) { - this._showLabels = config?.getValueByAlias('useLabel') ?? this.#defaultShowLabels; - this._swatches = config?.getValueByAlias('items') ?? []; + if (!config) return; + + this._showLabels = config?.getValueByAlias('useLabel') ?? this.#defaultShowLabels; + + const swatches = config?.getValueByAlias>('items') ?? []; + this._swatches = swatches.map((swatch) => this.#ensureHashPrefix(swatch)); } - private _onChange(event: UUIColorSwatchesEvent) { + #ensureHashPrefix(swatch: UmbSwatchDetails): UmbSwatchDetails { + return { + label: swatch.label, + value: swatch.value.startsWith('#') ? swatch.value : `#${swatch.value}`, + }; + } + + #onChange(event: UUIColorSwatchesEvent) { const value = event.target.value; this.value = this._swatches.find((swatch) => swatch.value === value); this.dispatchEvent(new UmbPropertyValueChangeEvent()); @@ -35,10 +53,10 @@ export class UmbPropertyEditorUIColorPickerElement extends UmbLitElement impleme render() { return html``; + ?showLabels=${this._showLabels} + @change=${this.#onChange}>`; } } From d3f6a2ba3a789640c41c1890dff7dc462c5ab98a Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 15 Apr 2024 19:07:08 +0100 Subject: [PATCH 2/3] Collection View configuration fixes Shows the "Choose" input button for fresh/empty config. --- .../column/column-configuration.element.ts | 30 ++++++++++++------- .../layout/layout-configuration.element.ts | 11 ++++++- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/collection-view/config/column/column-configuration.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/collection-view/config/column/column-configuration.element.ts index 4445927e3e..872a98d141 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/collection-view/config/column/column-configuration.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/collection-view/config/column/column-configuration.element.ts @@ -1,5 +1,5 @@ import type { UmbCollectionColumnConfiguration } from '../../../../../collection/types.js'; -import { html, customElement, property, repeat, css, state, nothing, when } from '@umbraco-cms/backoffice/external/lit'; +import { html, customElement, property, repeat, css, state, nothing } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; @@ -16,7 +16,6 @@ export class UmbPropertyEditorUICollectionViewColumnConfigurationElement extends UmbLitElement implements UmbPropertyEditorUiElement { - // TODO: [LK] Add sorting. @property({ type: Array }) @@ -74,15 +73,11 @@ export class UmbPropertyEditorUICollectionViewColumnConfigurationElement } render() { - if (!this.value) return nothing; + return html`${this.#renderColumns()} ${this.#renderInput()}`; + } + + #renderInput() { return html` -
- ${repeat( - this.value, - (column) => column.alias, - (column) => this.#renderField(column), - )} -
+ ${repeat( + this.value, + (column) => column.alias, + (column) => this.#renderColumn(column), + )} + + `; + } + + #renderColumn(column: UmbCollectionColumnConfiguration) { return html`
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/collection-view/config/layout/layout-configuration.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/collection-view/config/layout/layout-configuration.element.ts index 40f7d221dd..f8b20bdb53 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/collection-view/config/layout/layout-configuration.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/uis/collection-view/config/layout/layout-configuration.element.ts @@ -51,6 +51,8 @@ export class UmbPropertyEditorUICollectionViewLayoutConfigurationElement #onAdd(event: { target: UmbInputManifestElement }) { const manifest = event.target.value; + // TODO: [LK] Disallow duplicate `collectionView` aliases selections. [LK] + this.value = [ ...(this.value ?? []), { @@ -97,6 +99,14 @@ export class UmbPropertyEditorUICollectionViewLayoutConfigurationElement } render() { + return html`${this.#renderLayouts()} ${this.#renderInput()}`; + } + + #renderInput() { + return html``; + } + + #renderLayouts() { if (!this.value) return nothing; return html`
@@ -106,7 +116,6 @@ export class UmbPropertyEditorUICollectionViewLayoutConfigurationElement (layout, index) => this.#renderLayout(layout, index), )}
- `; } From 70d901fe50746523cb796c608a879a0dd634d08b Mon Sep 17 00:00:00 2001 From: Mads Rasmussen Date: Mon, 15 Apr 2024 22:08:20 +0200 Subject: [PATCH 3/3] check for tree root items --- .../src/packages/data-type/tree/data-type-tree.repository.ts | 5 ++++- .../packages/dictionary/tree/dictionary-tree.repository.ts | 5 ++++- .../tree/document-blueprint-tree.repository.ts | 5 ++++- .../document-types/tree/document-type-tree.repository.ts | 5 ++++- .../documents/documents/tree/document-tree.repository.ts | 5 ++++- .../media/media-types/tree/media-type-tree.repository.ts | 5 ++++- .../src/packages/media/media/tree/media-tree.repository.ts | 5 ++++- .../members/member-type/tree/member-type-tree.repository.ts | 5 ++++- .../packages/static-file/tree/static-file-tree.repository.ts | 5 ++++- .../partial-views/tree/partial-view-tree.repository.ts | 5 ++++- .../templating/scripts/tree/script-tree.repository.ts | 5 ++++- .../stylesheets/tree/stylesheet-tree.repository.ts | 5 ++++- .../templating/templates/tree/template-tree.repository.ts | 5 ++++- 13 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/data-type/tree/data-type-tree.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/data-type/tree/data-type-tree.repository.ts index 2c9f04fc7c..c961dc6913 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/data-type/tree/data-type-tree.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/data-type/tree/data-type-tree.repository.ts @@ -15,11 +15,14 @@ export class UmbDataTypeTreeRepository } async requestTreeRoot() { + const { data: treeRootData } = await this._treeSource.getRootItems({ skip: 0, take: 1 }); + const hasChildren = treeRootData ? treeRootData.total > 0 : false; + const data: UmbDataTypeTreeRootModel = { unique: null, entityType: UMB_DATA_TYPE_ROOT_ENTITY_TYPE, name: '#treeHeaders_dataTypes', - hasChildren: true, + hasChildren, isFolder: true, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/dictionary/tree/dictionary-tree.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/dictionary/tree/dictionary-tree.repository.ts index b772686501..855b280b0d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/dictionary/tree/dictionary-tree.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/dictionary/tree/dictionary-tree.repository.ts @@ -15,11 +15,14 @@ export class UmbDictionaryTreeRepository } async requestTreeRoot() { + const { data: treeRootData } = await this._treeSource.getRootItems({ skip: 0, take: 1 }); + const hasChildren = treeRootData ? treeRootData.total > 0 : false; + const data: UmbDictionaryTreeRootModel = { unique: null, entityType: UMB_DICTIONARY_ROOT_ENTITY_TYPE, name: '#treeHeaders_dictionary', - hasChildren: true, + hasChildren, isFolder: true, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/tree/document-blueprint-tree.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/tree/document-blueprint-tree.repository.ts index 55e303dfc5..ac03769d7e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/tree/document-blueprint-tree.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-blueprints/tree/document-blueprint-tree.repository.ts @@ -15,11 +15,14 @@ export class UmbDocumentBlueprintTreeRepository } async requestTreeRoot() { + const { data: treeRootData } = await this._treeSource.getRootItems({ skip: 0, take: 1 }); + const hasChildren = treeRootData ? treeRootData.total > 0 : false; + const data: UmbDocumentBlueprintTreeRootModel = { unique: null, entityType: UMB_DOCUMENT_BLUEPRINT_ENTITY_TYPE, name: 'Document Blueprints', - hasChildren: true, + hasChildren, isFolder: true, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/tree/document-type-tree.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/tree/document-type-tree.repository.ts index 15d2f7f74c..6cce66d739 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/tree/document-type-tree.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/document-types/tree/document-type-tree.repository.ts @@ -15,11 +15,14 @@ export class UmbDocumentTypeTreeRepository } async requestTreeRoot() { + const { data: treeRootData } = await this._treeSource.getRootItems({ skip: 0, take: 1 }); + const hasChildren = treeRootData ? treeRootData.total > 0 : false; + const data: UmbDocumentTypeTreeRootModel = { unique: null, entityType: UMB_DOCUMENT_TYPE_ROOT_ENTITY_TYPE, name: '#treeHeaders_documentTypes', - hasChildren: true, + hasChildren, isFolder: true, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/document-tree.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/document-tree.repository.ts index 999e7aff82..6869a26fae 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/document-tree.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/document-tree.repository.ts @@ -15,11 +15,14 @@ export class UmbDocumentTreeRepository } async requestTreeRoot() { + const { data: treeRootData } = await this._treeSource.getRootItems({ skip: 0, take: 1 }); + const hasChildren = treeRootData ? treeRootData.total > 0 : false; + const data: UmbDocumentTreeRootModel = { unique: null, entityType: UMB_DOCUMENT_ROOT_ENTITY_TYPE, name: '#treeHeaders_content', - hasChildren: true, + hasChildren, isFolder: true, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/tree/media-type-tree.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/tree/media-type-tree.repository.ts index deac728c26..12c5cba48e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media-types/tree/media-type-tree.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media-types/tree/media-type-tree.repository.ts @@ -15,11 +15,14 @@ export class UmbMediaTypeTreeRepository } async requestTreeRoot() { + const { data: treeRootData } = await this._treeSource.getRootItems({ skip: 0, take: 1 }); + const hasChildren = treeRootData ? treeRootData.total > 0 : false; + const data: UmbMediaTypeTreeRootModel = { unique: null, entityType: UMB_MEDIA_TYPE_ROOT_ENTITY_TYPE, name: '#treeHeaders_mediaTypes', - hasChildren: true, + hasChildren, isFolder: true, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/media/media/tree/media-tree.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/media/media/tree/media-tree.repository.ts index 7fea19f1ac..8b3478a9ed 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/media/media/tree/media-tree.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/media/media/tree/media-tree.repository.ts @@ -15,11 +15,14 @@ export class UmbMediaTreeRepository } async requestTreeRoot() { + const { data: treeRootData } = await this._treeSource.getRootItems({ skip: 0, take: 1 }); + const hasChildren = treeRootData ? treeRootData.total > 0 : false; + const data: UmbMediaTreeRootModel = { unique: null, entityType: UMB_MEDIA_ROOT_ENTITY_TYPE, name: '#treeHeaders_media', - hasChildren: true, + hasChildren, isFolder: true, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/tree/member-type-tree.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/tree/member-type-tree.repository.ts index fa6123d7d7..d0f4dc69fc 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/members/member-type/tree/member-type-tree.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/members/member-type/tree/member-type-tree.repository.ts @@ -15,11 +15,14 @@ export class UmbMemberTypeTreeRepository } async requestTreeRoot() { + const { data: treeRootData } = await this._treeSource.getRootItems({ skip: 0, take: 1 }); + const hasChildren = treeRootData ? treeRootData.total > 0 : false; + const data: UmbMemberTypeTreeRootModel = { unique: null, entityType: UMB_MEMBER_TYPE_ROOT_ENTITY_TYPE, name: '#treeHeaders_memberTypes', - hasChildren: true, + hasChildren, isFolder: true, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/static-file/tree/static-file-tree.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/static-file/tree/static-file-tree.repository.ts index 7afccab991..42a317833d 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/static-file/tree/static-file-tree.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/static-file/tree/static-file-tree.repository.ts @@ -15,11 +15,14 @@ export class UmbStaticFileTreeRepository } async requestTreeRoot() { + const { data: treeRootData } = await this._treeSource.getRootItems({ skip: 0, take: 1 }); + const hasChildren = treeRootData ? treeRootData.total > 0 : false; + const data: UmbStaticFileTreeRootModel = { unique: null, entityType: UMB_STATIC_FILE_ROOT_ENTITY_TYPE, name: 'Static Files', - hasChildren: true, + hasChildren, isFolder: true, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/partial-view-tree.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/partial-view-tree.repository.ts index 27cd6feb94..69b1777f4c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/partial-view-tree.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/partial-views/tree/partial-view-tree.repository.ts @@ -15,11 +15,14 @@ export class UmbPartialViewTreeRepository } async requestTreeRoot() { + const { data: treeRootData } = await this._treeSource.getRootItems({ skip: 0, take: 1 }); + const hasChildren = treeRootData ? treeRootData.total > 0 : false; + const data: UmbPartialViewTreeRootModel = { unique: null, entityType: UMB_PARTIAL_VIEW_ROOT_ENTITY_TYPE, name: '#treeHeaders_partialViews', - hasChildren: true, + hasChildren, isFolder: true, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/scripts/tree/script-tree.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/scripts/tree/script-tree.repository.ts index 2dec0c4450..bb3c68e1af 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/scripts/tree/script-tree.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/scripts/tree/script-tree.repository.ts @@ -12,11 +12,14 @@ export class UmbScriptTreeRepository extends UmbTreeRepositoryBase 0 : false; + const data: UmbScriptTreeRootModel = { unique: null, entityType: UMB_SCRIPT_ROOT_ENTITY_TYPE, name: '#treeHeaders_scripts', - hasChildren: true, + hasChildren, isFolder: true, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/tree/stylesheet-tree.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/tree/stylesheet-tree.repository.ts index 3de3703eca..6edec84a7a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/tree/stylesheet-tree.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/stylesheets/tree/stylesheet-tree.repository.ts @@ -14,11 +14,14 @@ export class UmbStylesheetTreeRepository extends UmbTreeRepositoryBase< } async requestTreeRoot() { + const { data: treeRootData } = await this._treeSource.getRootItems({ skip: 0, take: 1 }); + const hasChildren = treeRootData ? treeRootData.total > 0 : false; + const data: UmbStylesheetTreeRootModel = { unique: null, entityType: UMB_STYLESHEET_ROOT_ENTITY_TYPE, name: '#treeHeaders_stylesheets', - hasChildren: true, + hasChildren, isFolder: true, }; diff --git a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/tree/template-tree.repository.ts b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/tree/template-tree.repository.ts index d4c5dbbcb4..77ec7b89aa 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/templating/templates/tree/template-tree.repository.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/templating/templates/tree/template-tree.repository.ts @@ -15,11 +15,14 @@ export class UmbTemplateTreeRepository } async requestTreeRoot() { + const { data: treeRootData } = await this._treeSource.getRootItems({ skip: 0, take: 1 }); + const hasChildren = treeRootData ? treeRootData.total > 0 : false; + const data: UmbTemplateTreeRootModel = { unique: null, entityType: UMB_TEMPLATE_ROOT_ENTITY_TYPE, name: '#treeHeaders_templates', - hasChildren: true, + hasChildren, isFolder: true, };