badges + styling

This commit is contained in:
Niels Lyngsø
2024-08-14 12:46:02 +02:00
parent e8bbb863b3
commit 32bba703ad
4 changed files with 83 additions and 6 deletions

View File

@@ -10,6 +10,8 @@ import '../inline-list-block/index.js';
import { stringOrStringArrayContains } from '@umbraco-cms/backoffice/utils';
import { UmbBlockListEntryContext } from '../../context/block-list-entry.context.js';
import { UMB_BLOCK_LIST, type UmbBlockListLayoutModel } from '../../types.js';
import { UmbObserveValidationStateController } from '@umbraco-cms/backoffice/validation';
import { UmbDataPathBlockElementDataFilter } from '@umbraco-cms/backoffice/block';
/**
* @element umb-block-list-entry
@@ -33,6 +35,16 @@ export class UmbBlockListEntryElement extends UmbLitElement implements UmbProper
if (!value) return;
this._contentUdi = value;
this.#context.setContentUdi(value);
new UmbObserveValidationStateController(
this,
`$.contentData[${UmbDataPathBlockElementDataFilter({ udi: value })}]`,
(hasMessages) => {
this._contentInvalid = hasMessages;
this._blockViewProps.contentInvalid = hasMessages;
},
'observeMessagesForContent',
);
}
private _contentUdi?: string | undefined;
@@ -61,6 +73,14 @@ export class UmbBlockListEntryElement extends UmbLitElement implements UmbProper
@state()
_inlineEditingMode?: boolean;
// '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;
@state()
_blockViewProps: UmbBlockEditorCustomViewProperties<UmbBlockListLayoutModel> = {
contentUdi: undefined!,
@@ -141,6 +161,20 @@ export class UmbBlockListEntryElement extends UmbLitElement implements UmbProper
this.#context.settings,
(settings) => {
this.#updateBlockViewProps({ settings });
this.removeUmbControllerByAlias('observeMessagesForSettings');
if (settings) {
// Observe settings validation state:
new UmbObserveValidationStateController(
this,
`$.settingsData[${UmbDataPathBlockElementDataFilter(settings)}]`,
(hasMessages) => {
this._settingsInvalid = hasMessages;
this._blockViewProps.settingsInvalid = hasMessages;
},
'observeMessagesForSettings',
);
}
},
null,
);
@@ -218,16 +252,26 @@ export class UmbBlockListEntryElement extends UmbLitElement implements UmbProper
>
<uui-action-bar>
${this._showContentEdit && this._workspaceEditContentPath
? html`<uui-button label="edit" compact href=${this._workspaceEditContentPath}>
? html`<uui-button label="edit" look="secondary" href=${this._workspaceEditContentPath}>
<uui-icon name="icon-edit"></uui-icon>
${this._contentInvalid
? html`<uui-badge attention color="danger" label="Invalid settings">!</uui-badge>`
: ''}
</uui-button>`
: ''}
${this._hasSettings && this._workspaceEditSettingsPath
? html`<uui-button label="Edit settings" compact href=${this._workspaceEditSettingsPath}>
? html`<uui-button
label="Edit settings"
look="secondary"
color=${this._settingsInvalid ? 'danger' : ''}
href=${this._workspaceEditSettingsPath}>
<uui-icon name="icon-settings"></uui-icon>
${this._settingsInvalid
? html`<uui-badge attention color="danger" label="Invalid settings">!</uui-badge>`
: ''}
</uui-button>`
: ''}
<uui-button label="delete" compact @click=${() => this.#context.requestDelete()}>
<uui-button label="delete" look="secondary" @click=${() => this.#context.requestDelete()}>
<uui-icon name="icon-remove"></uui-icon>
</uui-button>
</uui-action-bar>
@@ -248,11 +292,33 @@ export class UmbBlockListEntryElement extends UmbLitElement implements UmbProper
position: absolute;
top: var(--uui-size-2);
right: var(--uui-size-2);
opacity: 0;
transition: opacity 120ms;
}
:host(:hover) uui-action-bar,
uui-action-bar:focus,
:host(:focus-within) uui-action-bar {
opacity: 1;
}
:host([drag-placeholder]) {
opacity: 0.2;
}
:host([settings-invalid])::before,
:host([content-invalid])::before {
content: '';
position: absolute;
inset: 0;
z-index: 1;
pointer-events: none;
border: 1px solid var(--uui-color-danger);
border-radius: var(--uui-border-radius);
}
uui-badge {
z-index: 2;
}
`,
];
}

View File

@@ -51,6 +51,7 @@ export class UmbPropertyEditorUIBlockListElement extends UmbLitElement implement
#validationContext = new UmbValidationContext(this).provide();
#contentDataPathTranslator?: UmbBlockElementDataValidationPathTranslator;
#settingsDataPathTranslator?: UmbBlockElementDataValidationPathTranslator;
//#catalogueModal: UmbModalRouteRegistrationController<typeof UMB_BLOCK_CATALOGUE_MODAL.DATA, undefined>;
@@ -133,9 +134,7 @@ export class UmbPropertyEditorUIBlockListElement extends UmbLitElement implement
this.observe(
context.dataPath,
(dataPath) => {
//
// TODO: Make translator for settings.
// Translate paths for content elements:
this.#contentDataPathTranslator?.destroy();
if (dataPath) {
// Set the data path for the local validation context:
@@ -143,6 +142,15 @@ export class UmbPropertyEditorUIBlockListElement extends UmbLitElement implement
this.#contentDataPathTranslator = new UmbBlockElementDataValidationPathTranslator(this, 'contentData');
}
// Translate paths for settings elements:
this.#settingsDataPathTranslator?.destroy();
if (dataPath) {
// Set the data path for the local validation context:
this.#validationContext.setDataPath(dataPath);
this.#settingsDataPathTranslator = new UmbBlockElementDataValidationPathTranslator(this, 'settingsData');
}
},
'observeDataPath',
);

View File

@@ -46,6 +46,8 @@ export interface UmbBlockEditorCustomViewProperties<
layout?: LayoutType;
content?: UmbBlockDataType;
settings?: UmbBlockDataType;
contentInvalid?: boolean;
settingsInvalid?: boolean;
}
export interface UmbBlockEditorCustomViewElement<

View File

@@ -276,6 +276,7 @@ export class UmbValidationContext extends UmbControllerBase implements UmbValida
}
override destroy(): void {
this.#providerCtrl = undefined;
if (this.#parent) {
this.#parent.removeValidator(this);
}