From b2c078a9e205007f0e4ccc75adbe2bb1e09111bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 15 Feb 2024 13:34:02 +0100 Subject: [PATCH] area entry pluming --- ...ck-grid-area-config-entry.context-token.ts | 6 + .../block-grid-area-config-entry.context.ts | 71 +++++++++++ .../block-grid-area-config-entry.element.ts | 117 ++++++++++++++++++ .../block-grid-area-config-entry/index.ts | 1 + ...itor-ui-block-grid-areas-config.element.ts | 42 ++++++- .../src/packages/block/block-grid/types.ts | 2 +- 6 files changed, 236 insertions(+), 3 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/block-grid-area-config-entry.context-token.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/block-grid-area-config-entry.context.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/block-grid-area-config-entry.element.ts create mode 100644 src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/index.ts diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/block-grid-area-config-entry.context-token.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/block-grid-area-config-entry.context-token.ts new file mode 100644 index 0000000000..e09f1b22dd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/block-grid-area-config-entry.context-token.ts @@ -0,0 +1,6 @@ +import type { UmbBlockGridAreaConfigEntryContext } from './block-grid-area-config-entry.context.js'; +import { UmbContextToken } from '@umbraco-cms/backoffice/context-api'; + +export const UMB_BLOCK_GRID_AREA_CONFIG_ENTRY_CONTEXT = new UmbContextToken( + 'UmbBlockAreaConfigEntryContext', +); diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/block-grid-area-config-entry.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/block-grid-area-config-entry.context.ts new file mode 100644 index 0000000000..4bf1b86c60 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/block-grid-area-config-entry.context.ts @@ -0,0 +1,71 @@ +import { UMB_BLOCK_GRID_AREA_CONFIG_ENTRY_CONTEXT } from './block-grid-area-config-entry.context-token.js'; +import type { UmbBlockGridTypeAreaType } from '@umbraco-cms/backoffice/block'; +import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api'; +import { UmbObjectState } from '@umbraco-cms/backoffice/observable-api'; +import { UmbContextBase } from '@umbraco-cms/backoffice/class-api'; +import { UMB_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/property'; +import { UMB_CONFIRM_MODAL, UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal'; +export class UmbBlockGridAreaConfigEntryContext extends UmbContextBase { + // + #propertyContext?: typeof UMB_PROPERTY_CONTEXT.TYPE; + // + #areaKey?: string; + #area = new UmbObjectState(undefined); + readonly alias = this.#area.asObservablePart((x) => x?.alias); + readonly columnSpan = this.#area.asObservablePart((x) => x?.columnSpan); + readonly rowSpan = this.#area.asObservablePart((x) => x?.rowSpan ?? 1); + + constructor(host: UmbControllerHost) { + super(host, UMB_BLOCK_GRID_AREA_CONFIG_ENTRY_CONTEXT); + + this.consumeContext(UMB_PROPERTY_CONTEXT, (context) => { + this.#propertyContext = context; + this.#observeAreaData(); + }); + } + + setAreaKey(areaKey: string) { + if (this.#areaKey === areaKey) return; + this.#areaKey = areaKey; + this.#observeAreaData(); + } + + #observeAreaData() { + if (!this.#areaKey || !this.#propertyContext) return; + this.observe( + this.#propertyContext.value, + (value: Array | undefined) => { + if (value) { + this.#area.setValue(value.find((x) => x.key === this.#areaKey)); + } + }, + 'observeAreaKey', + ); + } + + requestDelete() { + this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, async (modalManager) => { + const modalContext = modalManager.open(UMB_CONFIRM_MODAL, { + data: { + headline: `Delete ${this.alias}`, + content: 'Are you sure you want to delete this Area?', + confirmLabel: 'Delete', + color: 'danger', + }, + }); + await modalContext.onSubmit(); + this.delete(); + }); + } + public delete() { + if (!this.#areaKey || !this.#propertyContext) return; + const value = this.#propertyContext.getValue() as Array | undefined; + if (!value) return; + this.#propertyContext.setValue(value.filter((x) => x.key !== this.#areaKey)); + } + + destroy() { + super.destroy(); + this.#area.destroy(); + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/block-grid-area-config-entry.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/block-grid-area-config-entry.element.ts new file mode 100644 index 0000000000..8e9fe3d16d --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/block-grid-area-config-entry.element.ts @@ -0,0 +1,117 @@ +import { UmbBlockGridAreaConfigEntryContext } from './block-grid-area-config-entry.context.js'; +import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { html, css, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; +import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; +import '../block-grid-block-view/index.js'; + +/** + * @element umb-block-area-config-entry + */ +@customElement('umb-block-area-config-entry') +export class UmbBlockGridAreaConfigEntryElement extends UmbLitElement implements UmbPropertyEditorUiElement { + // + @property({ attribute: false }) + public get areaKey(): string | undefined { + return this._areaKey; + } + public set areaKey(value: string | undefined) { + if (!value) return; + this._areaKey = value; + this.setAttribute('data-area-key', value); + this.#context.setAreaKey(value); + } + private _areaKey?: string | undefined; + // + + #context = new UmbBlockGridAreaConfigEntryContext(this); + + @state() + _columnSpan?: number; + + @state() + _rowSpan?: number; + + @state() + _alias = ''; + + constructor() { + super(); + + // Misc: + this.observe(this.#context.alias, (alias) => { + this._alias = alias ?? ''; + }); + } + + connectedCallback(): void { + super.connectedCallback(); + // element styling: + this.observe( + this.#context.columnSpan, + (columnSpan) => { + this._columnSpan = columnSpan; + this.setAttribute('data-col-span', columnSpan ? columnSpan.toString() : ''); + this.style.setProperty('--umb-block-grid--grid-column', columnSpan ? columnSpan.toString() : ''); + this.style.setProperty('--umb-block-grid--area-column-span', columnSpan ? columnSpan.toString() : ''); + }, + 'columnSpan', + ); + this.observe( + this.#context.rowSpan, + (rowSpan) => { + this._rowSpan = rowSpan; + this.setAttribute('data-row-span', rowSpan ? rowSpan.toString() : ''); + this.style.setProperty('--umb-block-grid--area-row-span', rowSpan ? rowSpan.toString() : ''); + }, + 'rowSpan', + ); + } + + #renderBlock() { + return this._areaKey + ? html` +
+
${this._alias}
+ + + + + this.#context.requestDelete()}> + + + +
+ ` + : ''; + } + + render() { + return this.#renderBlock(); + } + + static styles = [ + css` + :host { + position: relative; + display: block; + } + uui-action-bar { + position: absolute; + top: var(--uui-size-2); + right: var(--uui-size-2); + } + + :host([drag-placeholder]) { + opacity: 0.2; + } + `, + ]; +} + +export default UmbBlockGridAreaConfigEntryElement; + +declare global { + interface HTMLElementTagNameMap { + 'umb-block-area-config-entry': UmbBlockGridAreaConfigEntryElement; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/index.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/index.ts new file mode 100644 index 0000000000..1b48acd409 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-area-config-entry/index.ts @@ -0,0 +1 @@ +export * from './block-grid-area-config-entry.element.js'; diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-areas-config/property-editor-ui-block-grid-areas-config.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-areas-config/property-editor-ui-block-grid-areas-config.element.ts index 61f32cc38e..0289bdb5f8 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-areas-config/property-editor-ui-block-grid-areas-config.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-areas-config/property-editor-ui-block-grid-areas-config.element.ts @@ -1,10 +1,11 @@ import type { UmbBlockGridTypeAreaType } from '../../index.js'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; -import { html, customElement, property, css, state } from '@umbraco-cms/backoffice/external/lit'; +import { html, customElement, property, css, state, repeat } from '@umbraco-cms/backoffice/external/lit'; import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry'; import { UmbTextStyles } from '@umbraco-cms/backoffice/style'; import { UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property'; import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor'; +import { UmbId } from '@umbraco-cms/backoffice/id'; @customElement('umb-property-editor-ui-block-grid-areas-config') export class UmbPropertyEditorUIBlockGridAreasConfigElement @@ -49,8 +50,45 @@ export class UmbPropertyEditorUIBlockGridAreasConfigElement this._areaGridColumns = this.#valueOfAreaGridColumns ?? this.#defaultAreaGridColumns; } + #addNewArea() { + if (!this._areaGridColumns) return; + const halfGridColumns = this._areaGridColumns * 0.5; + const columnSpan = halfGridColumns === Math.round(halfGridColumns) ? halfGridColumns : this._areaGridColumns; + + this.value.push({ + key: UmbId.new(), + alias: '', // TODO: Should we auto generate something here? + columnSpan: columnSpan, + rowSpan: 1, + minAllowed: 0, + maxAllowed: undefined, + specifiedAllowance: [], + }); + + //TODO: vm.openAreaOverlay(newArea); + } + render() { - return this._areaGridColumns ? html`
Hello columns: ${this._areaGridColumns}
` : ''; + return this._areaGridColumns + ? html`
+ ${repeat( + this.value, + (area) => area.key, + (area) => + html``, + )} +
+ + ` + : ''; } static styles = [UmbTextStyles, css``]; diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/types.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/types.ts index a7fec0aca8..a9f056eb76 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/types.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/types.ts @@ -18,7 +18,7 @@ export interface UmbBlockGridTypeModel extends UmbBlockTypeBaseModel { export interface UmbBlockGridTypeAreaType { key: string; alias: string; - colSpan?: number; + columnSpan?: number; rowSpan?: number; minAllowed?: number; maxAllowed?: number;