From 5493c0a2a13afdbe924daf1ccf00a93ceaa91f40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Wed, 16 Oct 2024 12:03:35 +0200 Subject: [PATCH] implement expose button for rte block --- .../block-rte-entry.element.ts | 147 +++++++++++++----- 1 file changed, 111 insertions(+), 36 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/components/block-rte-entry/block-rte-entry.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/components/block-rte-entry/block-rte-entry.element.ts index f835c064c1..96b7c0de0a 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/components/block-rte-entry/block-rte-entry.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-rte/components/block-rte-entry/block-rte-entry.element.ts @@ -1,7 +1,7 @@ import { UMB_BLOCK_RTE, type UmbBlockRteLayoutModel } from '../../types.js'; import { UmbBlockRteEntryContext } from '../../context/block-rte-entry.context.js'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import { html, css, property, state, customElement } from '@umbraco-cms/backoffice/external/lit'; +import { html, css, property, state, customElement, nothing } from '@umbraco-cms/backoffice/external/lit'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/property-editor'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import type { @@ -11,6 +11,8 @@ import type { import { stringOrStringArrayContains } from '@umbraco-cms/backoffice/utils'; import '../ref-rte-block/index.js'; +import { UmbObserveValidationStateController } from '@umbraco-cms/backoffice/validation'; +import { UmbDataPathBlockElementDataQuery } from '@umbraco-cms/backoffice/block'; /** * @class UmbBlockRteEntryElement @@ -26,6 +28,16 @@ export class UmbBlockRteEntryElement extends UmbLitElement implements UmbPropert if (!value) return; this._contentKey = value; this.#context.setContentKey(value); + + new UmbObserveValidationStateController( + this, + `$.contentData[${UmbDataPathBlockElementDataQuery({ key: value })}]`, + (hasMessages) => { + this._contentInvalid = hasMessages; + this._blockViewProps.contentInvalid = hasMessages; + }, + 'observeMessagesForContent', + ); } private _contentKey?: string | undefined; @@ -55,12 +67,23 @@ export class UmbBlockRteEntryElement extends UmbLitElement implements UmbPropert @state() _contentElementTypeAlias?: string; + @state() + _contentTypeName?: string; + @state() _blockViewProps: UmbBlockEditorCustomViewProperties = { contentKey: undefined!, config: { showContentEdit: false, showSettingsEdit: false }, }; // Set to undefined cause it will be set before we render. + // 'content-invalid' attribute is used for styling purpose. + @property({ type: Boolean, attribute: 'content-invalid', reflect: true }) + _contentInvalid?: boolean; + + // 'settings-invalid' attribute is used for styling purpose. + @property({ type: Boolean, attribute: 'settings-invalid', reflect: true }) + _settingsInvalid?: boolean; + #updateBlockViewProps(incoming: Partial>) { this._blockViewProps = { ...this._blockViewProps, ...incoming }; this.requestUpdate('_blockViewProps'); @@ -72,17 +95,36 @@ export class UmbBlockRteEntryElement extends UmbLitElement implements UmbPropert // We do not have index for RTE Blocks at the moment. this.#context.setIndex(0); - this.observe(this.#context.showContentEdit, (showContentEdit) => { - this._showContentEdit = showContentEdit; - this.#updateBlockViewProps({ config: { ...this._blockViewProps.config!, showContentEdit } }); - }); - this.observe(this.#context.settingsElementTypeKey, (key) => { - this._hasSettings = !!key; - this.#updateBlockViewProps({ config: { ...this._blockViewProps.config!, showSettingsEdit: !!key } }); - }); - this.observe(this.#context.contentElementTypeAlias, (alias) => { - this._contentElementTypeAlias = alias; - }); + this.observe( + this.#context.showContentEdit, + (showContentEdit) => { + this._showContentEdit = showContentEdit; + this.#updateBlockViewProps({ config: { ...this._blockViewProps.config!, showContentEdit } }); + }, + null, + ); + this.observe( + this.#context.settingsElementTypeKey, + (key) => { + this._hasSettings = !!key; + this.#updateBlockViewProps({ config: { ...this._blockViewProps.config!, showSettingsEdit: !!key } }); + }, + null, + ); + this.observe( + this.#context.contentElementTypeAlias, + (alias) => { + this._contentElementTypeAlias = alias; + }, + null, + ); + this.observe( + this.#context.contentElementTypeName, + (contentElementTypeName) => { + this._contentTypeName = contentElementTypeName; + }, + null, + ); this.observe( this.#context.blockType, (blockType) => { @@ -126,8 +168,6 @@ export class UmbBlockRteEntryElement extends UmbLitElement implements UmbPropert this.#observeData(); - // TODO: Implement validation for RTE Blocks: [NL] - /* this.observe( this.#context.settingsKey, (settingsKey) => { @@ -147,7 +187,7 @@ export class UmbBlockRteEntryElement extends UmbLitElement implements UmbPropert }, null, ); - */ + this.observe( this.#context.workspaceEditContentPath, (path) => { @@ -188,15 +228,6 @@ export class UmbBlockRteEntryElement extends UmbLitElement implements UmbPropert this.setAttribute('contenteditable', 'false'); } - #renderRefBlock() { - return html``; - } - readonly #filterBlockCustomViews = (manifest: ManifestBlockEditorCustomView) => { const elementTypeAlias = this._contentElementTypeAlias ?? ''; const isForBlockEditor = @@ -206,6 +237,10 @@ export class UmbBlockRteEntryElement extends UmbLitElement implements UmbPropert return isForBlockEditor && isForContentTypeAlias; }; + #expose = () => { + this.#context.expose(); + }; + #renderBlock() { return html`
@@ -217,22 +252,62 @@ export class UmbBlockRteEntryElement extends UmbLitElement implements UmbPropert single> ${this.#renderRefBlock()} - - ${this._showContentEdit && this._workspaceEditContentPath - ? html` - - ` - : ''} - ${this._hasSettings && this._workspaceEditSettingsPath - ? html` - - ` - : ''} - + ${this.#renderEditAction()} ${this.#renderEditSettingsAction()} + ${!this._showContentEdit && this._contentInvalid + ? html`!` + : nothing}
`; } + #renderRefBlock() { + return html``; + } + + #renderEditAction() { + return this._showContentEdit && this._workspaceEditContentPath + ? html` + + ${this._contentInvalid + ? html`!` + : nothing} + ` + : this._showContentEdit === false && this._exposed === false + ? html`` + : nothing; + } + + #renderEditSettingsAction() { + return html` + ${this._hasSettings && this._workspaceEditSettingsPath + ? html` + + ${this._settingsInvalid + ? html`!` + : nothing} + ` + : nothing} + `; + } + override render() { return this.#renderBlock(); }