area entry pluming

This commit is contained in:
Niels Lyngsø
2024-02-15 13:34:02 +01:00
parent 0ada41210f
commit b2c078a9e2
6 changed files with 236 additions and 3 deletions

View File

@@ -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<UmbBlockGridAreaConfigEntryContext>(
'UmbBlockAreaConfigEntryContext',
);

View File

@@ -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<UmbBlockGridAreaConfigEntryContext> {
//
#propertyContext?: typeof UMB_PROPERTY_CONTEXT.TYPE;
//
#areaKey?: string;
#area = new UmbObjectState<UmbBlockGridTypeAreaType | undefined>(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<UmbBlockGridTypeAreaType> | 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<UmbBlockGridTypeAreaType> | undefined;
if (!value) return;
this.#propertyContext.setValue(value.filter((x) => x.key !== this.#areaKey));
}
destroy() {
super.destroy();
this.#area.destroy();
}
}

View File

@@ -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`
<div class="umb-block-grid-area-editor__area">
<div>${this._alias}</div>
<uui-action-bar>
<uui-button label="edit" compact href=${'#edit_area_path_missing'}>
<uui-icon name="icon-edit"></uui-icon>
</uui-button>
<uui-button label="delete" compact @click=${() => this.#context.requestDelete()}>
<uui-icon name="icon-remove"></uui-icon>
</uui-button>
</uui-action-bar>
</div>
`
: '';
}
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;
}
}

View File

@@ -0,0 +1 @@
export * from './block-grid-area-config-entry.element.js';

View File

@@ -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`<div id="wrapper">Hello columns: ${this._areaGridColumns}</div>` : '';
return this._areaGridColumns
? html`<div
class="umb-block-grid__area-container"
style="--umb-block-grid--area-grid-columns: ${this._areaGridColumns}">
${repeat(
this.value,
(area) => area.key,
(area) =>
html`<umb-block-grid-area-placeholder
class="umb-block-grid__area"
.areaKey=${area.key}></umb-block-grid-area-placeholder>`,
)}
</div>
<uui-button
id="add-button"
look="placeholder"
label=${this.localize.term('blockEditor_addBlock')}
@click=${this.#addNewArea}>
</uui-button>`
: '';
}
static styles = [UmbTextStyles, css``];

View File

@@ -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;