diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-block/block-grid-block.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-block/block-grid-block.element.ts
new file mode 100644
index 0000000000..79fd25581d
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-block/block-grid-block.element.ts
@@ -0,0 +1,125 @@
+import { UmbBlockGridEntryContext } from '../../context/block-grid-entry.context.js';
+import { html, css, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
+import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
+import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
+import type { UmbBlockGridLayoutModel } from '@umbraco-cms/backoffice/block';
+import '../ref-list-block/index.js';
+import '../inline-list-block/index.js';
+
+/**
+ * @element umb-property-editor-ui-block-grid-block
+ */
+@customElement('umb-property-editor-ui-block-grid-block')
+export class UmbPropertyEditorUIBlockGridBlockElement extends UmbLitElement implements UmbPropertyEditorUiElement {
+ //
+ @property({ attribute: false })
+ public get layout(): UmbBlockGridLayoutModel | undefined {
+ return this._layout;
+ }
+ public set layout(value: UmbBlockGridLayoutModel | undefined) {
+ this._layout = value;
+ this.#context.setLayout(value);
+ }
+ private _layout?: UmbBlockGridLayoutModel | undefined;
+
+ #context = new UmbBlockGridEntryContext(this);
+
+ @state()
+ _contentUdi?: string;
+
+ @state()
+ _hasSettings = false;
+
+ @state()
+ _label = '';
+
+ @state()
+ _workspaceEditPath?: string;
+
+ @state()
+ _inlineEditingMode?: boolean;
+
+ // TODO: Move type for the Block Properties, and use it on the Element Interface for the Manifest.
+ @state()
+ _blockViewProps: {
+ label?: string;
+ } = {};
+
+ constructor() {
+ super();
+
+ this.observe(this.#context.workspaceEditPath, (workspaceEditPath) => {
+ this._workspaceEditPath = workspaceEditPath;
+ });
+ this.observe(this.#context.contentUdi, (contentUdi) => {
+ this._contentUdi = contentUdi;
+ });
+ this.observe(this.#context.blockTypeSettingsElementTypeKey, (blockTypeSettingsElementTypeKey) => {
+ this._hasSettings = !!blockTypeSettingsElementTypeKey;
+ });
+ this.observe(this.#context.label, (label) => {
+ this._blockViewProps.label = label;
+ this._label = label;
+ });
+ }
+
+ #renderRefBlock() {
+ return html``;
+ }
+
+ #renderBlock() {
+ return html`
+ ${this.#renderRefBlock()}
+
+ ${this._workspaceEditPath
+ ? html`
+
+ `
+ : ''}
+ ${this._workspaceEditPath && this._hasSettings
+ ? html`
+
+ `
+ : ''}
+
+
+
+
+ `;
+ }
+
+ render() {
+ return this.layout && this._contentUdi ? 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 UmbPropertyEditorUIBlockGridBlockElement;
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'umb-property-editor-ui-block-grid-block': UmbPropertyEditorUIBlockGridBlockElement;
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-block/index.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-block/index.ts
new file mode 100644
index 0000000000..8afd0511df
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-block/index.ts
@@ -0,0 +1 @@
+export * from './block-grid-block.element.js';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/index.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/index.ts
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entries.context-token.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entries.context-token.ts
new file mode 100644
index 0000000000..6b05007c46
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entries.context-token.ts
@@ -0,0 +1,5 @@
+import type { UmbBlockGridEntriesContext } from './block-grid-entries.context.js';
+import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
+
+// TODO: Make discriminator method for this:
+export const UMB_BLOCK_GRID_ENTRIES_CONTEXT = new UmbContextToken('UmbBlockEntriesContext');
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entries.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entries.context.ts
new file mode 100644
index 0000000000..8940fb7dc8
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entries.context.ts
@@ -0,0 +1,93 @@
+import { UMB_BLOCK_CATALOGUE_MODAL } from '../../block/index.js';
+import { UMB_BLOCK_GRID_MANAGER_CONTEXT } from '../manager/block-grid-manager.context.js';
+import type { UmbBlockGridLayoutModel } from '../types.js';
+import { UMB_BLOCK_GRID_ENTRIES_CONTEXT } from './block-grid-entries.context-token.js';
+import { UMB_BLOCK_GRID_ENTRY_CONTEXT } from './block-grid-entry.context-token.js';
+import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+import { type UmbModalRouteBuilder, UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal';
+import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
+
+export class UmbBlockGridEntriesContext extends UmbContextBase {
+ //
+ #blockManager?: typeof UMB_BLOCK_GRID_MANAGER_CONTEXT.TYPE;
+ #catalogueModal: UmbModalRouteRegistrationController;
+ #catalogueRouteBuilder?: UmbModalRouteBuilder;
+
+ #layoutEntries = new UmbArrayState([], (x) => x.contentUdi);
+ layoutEntries = this.#layoutEntries.asObservable();
+
+ setLayoutEntries(layoutEntries: Array) {
+ this.#layoutEntries.setValue(layoutEntries);
+ }
+ getLayoutEntries() {
+ return this.#layoutEntries.value;
+ }
+
+ setParentKey(contentUdi: string) {
+ this.#catalogueModal.setUniquePathValue('parentUnique', contentUdi);
+ }
+ getParentKey() {
+ return '';
+ }
+
+ setAreaKey(areaKey: string) {
+ this.#catalogueModal.setUniquePathValue('areaKey', areaKey);
+ }
+ getAreaKey() {
+ return '';
+ }
+
+ constructor(host: UmbControllerHost) {
+ super(host, UMB_BLOCK_GRID_ENTRIES_CONTEXT.toString());
+
+ this.#catalogueModal = new UmbModalRouteRegistrationController(this, UMB_BLOCK_CATALOGUE_MODAL)
+ .addUniquePaths(['propertyAlias', 'parentUnique', 'areaKey'])
+ .addAdditionalPath(':view/:index')
+ .onSetup((routingInfo) => {
+ // Idea: Maybe on setup should be async, so it can retrieve the values when needed? [NL]
+ const index = routingInfo.index ? parseInt(routingInfo.index) : -1;
+ return {
+ data: {
+ blocks: [],
+ blockGroups: [],
+ openClipboard: routingInfo.view === 'clipboard',
+ blockOriginData: { index: index },
+ },
+ };
+ })
+ .observeRouteBuilder((routeBuilder) => {
+ this.#catalogueRouteBuilder = routeBuilder;
+ });
+
+ // TODO: Observe Blocks of the layout entries of this component.
+ this.consumeContext(UMB_BLOCK_GRID_MANAGER_CONTEXT, (blockGridManager) => {
+ this.#blockManager = blockGridManager;
+ this.#gotBlockManager();
+ });
+ }
+
+ #gotBlockManager() {
+ if (!this.#blockManager) return;
+
+ this.observe(
+ this.#blockManager.propertyAlias,
+ (alias) => {
+ this.#catalogueModal.setUniquePathValue('propertyAlias', alias);
+ },
+ 'observePropertyAlias',
+ );
+ }
+
+ getPathForCreateBlock(index: number) {
+ return this.#catalogueRouteBuilder?.({ view: 'create', index: index });
+ }
+
+ getPathForClipboard(index: number) {
+ return this.#catalogueRouteBuilder?.({ view: 'clipboard', index: index });
+ }
+
+ // create Block?
+
+ deleteBlock() {}
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context-token.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context-token.ts
new file mode 100644
index 0000000000..b5213a3c32
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context-token.ts
@@ -0,0 +1,5 @@
+import type { UmbBlockGridEntryContext } from './block-grid-entry.context.js';
+import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
+
+// TODO: Make discriminator method for this:
+export const UMB_BLOCK_GRID_ENTRY_CONTEXT = new UmbContextToken('UmbBlockEntryContext');
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context.ts
similarity index 69%
rename from src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid.context.ts
rename to src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context.ts
index 49a95d7aca..9fa8d9ad55 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context.ts
@@ -3,20 +3,25 @@ import {
UmbBlockContext,
type UmbBlockGridTypeModel,
type UmbBlockGridLayoutModel,
+ type UmbBlockGridLayoutAreaItemModel,
} from '@umbraco-cms/backoffice/block';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
-import { UmbBooleanState } from '@umbraco-cms/backoffice/observable-api';
-export class UmbBlockGridContext extends UmbBlockContext<
+import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
+export class UmbBlockGridEntryContext extends UmbBlockContext<
typeof UMB_BLOCK_GRID_MANAGER_CONTEXT,
typeof UMB_BLOCK_GRID_MANAGER_CONTEXT.TYPE,
UmbBlockGridTypeModel,
UmbBlockGridLayoutModel
> {
- #inlineEditingMode = new UmbBooleanState(undefined);
- inlineEditingMode = this.#inlineEditingMode.asObservable();
+ #areas = new UmbArrayState([], (x) => x.key);
+ areas = this.#areas.asObservable();
constructor(host: UmbControllerHost) {
super(host, UMB_BLOCK_GRID_MANAGER_CONTEXT);
+
+ this.observe(this.layout, (layout) => {
+ this.#areas.setValue(layout?.areas ?? []);
+ });
}
_gotManager() {
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid.context-token.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid.context-token.ts
deleted file mode 100644
index a8c429f977..0000000000
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid.context-token.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import type { UmbBlockGridContext } from './block-grid.context.js';
-import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
-
-// TODO: Make discriminator method for this:
-export const UMB_BLOCK_GRID_CONTEXT = new UmbContextToken('UmbBlockContext');
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/index.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/index.ts
new file mode 100644
index 0000000000..f652a039d7
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/index.ts
@@ -0,0 +1,2 @@
+export * from './block-grid-entries.context-token.js';
+export * from './block-grid-entry.context-token.js';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/index.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/index.ts
index 56ebdc81cc..577eea75f4 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/index.ts
@@ -1,2 +1,3 @@
-export * from './workspace/index.js';
+export * from './context/index.js';
export * from './types.js';
+export * from './workspace/index.js';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/manager/block-grid-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/manager/block-grid-manager.context.ts
index f0adca8e20..71087b2dd0 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/manager/block-grid-manager.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/manager/block-grid-manager.context.ts
@@ -1,7 +1,9 @@
import type { UmbBlockGridLayoutModel, UmbBlockGridTypeModel } from '../types.js';
import { UmbBlockManagerContext } from '../../block/manager/block-manager.context.js';
import type { UmbBlockGridWorkspaceData } from '../index.js';
+import type { UmbBlockTypeGroup } from '../../block-type/types.js';
import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
+import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
/**
* A implementation of the Block Manager specifically for the Block Grid Editor.
@@ -10,14 +12,16 @@ export class UmbBlockGridManagerContext<
BlockLayoutType extends UmbBlockGridLayoutModel = UmbBlockGridLayoutModel,
> extends UmbBlockManagerContext {
//
- /*
- #inlineEditingMode = new UmbBooleanState(undefined);
- inlineEditingMode = this.#inlineEditingMode.asObservable();
+ //
+ #blockGroups = new UmbArrayState(>[], (x) => x.key);
+ public readonly blockGroups = this.#blockGroups.asObservable();
- setInlineEditingMode(inlineEditingMode: boolean | undefined) {
- this.#inlineEditingMode.setValue(inlineEditingMode ?? false);
+ setBlockGroups(blockGroups: Array) {
+ this.#blockGroups.setValue(blockGroups);
+ }
+ getBlockGroups() {
+ return this.#blockGroups.value;
}
- */
_createBlock(modalData: UmbBlockGridWorkspaceData, layoutEntry: BlockLayoutType, contentElementTypeKey: string) {
// Here is room to append some extra layout properties if needed for this type.
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid-entries.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid-entries.element.ts
new file mode 100644
index 0000000000..557bad244c
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid-entries.element.ts
@@ -0,0 +1,109 @@
+import { UmbBlockGridEntriesContext } from '../../context/block-grid-entries.context.js';
+import type { UmbBlockGridLayoutModel } from '@umbraco-cms/backoffice/block';
+import { html, customElement, state, repeat, css, property } from '@umbraco-cms/backoffice/external/lit';
+import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
+import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
+
+/**
+ * @element umb-property-editor-ui-block-grid-entries
+ */
+@customElement('umb-property-editor-ui-block-grid-entries')
+export class UmbPropertyEditorUIBlockGridEntriesElement extends UmbLitElement {
+ //
+ // TODO: Make sure Sorter callbacks handles columnSpan when retrieving a new entry.
+
+ #context = new UmbBlockGridEntriesContext(this);
+
+ @property({ attribute: false })
+ public set layoutEntries(value: Array) {
+ this.#context.setLayoutEntries(value);
+ }
+ public get layoutEntries(): Array {
+ return this.#context.getLayoutEntries();
+ }
+
+ @property({ attribute: false })
+ public set parentUnique(value: string) {
+ this.#context.setParentKey(value);
+ }
+ public get parentUnique(): string {
+ return this.#context.getParentKey();
+ }
+
+ @property({ attribute: false })
+ public set areaKey(value: string) {
+ this.#context.setAreaKey(value);
+ }
+ public get areaKey(): string {
+ return this.#context.getAreaKey();
+ }
+
+ @state()
+ private _layoutEntries: Array = [];
+
+ @state()
+ private _createButtonLabel = this.localize.term('blockEditor_addBlock');
+
+ constructor() {
+ super();
+ this.observe(this.#context.layoutEntries, (layoutEntries) => {
+ this._layoutEntries = layoutEntries;
+ });
+ }
+
+ render() {
+ // TODO: Missing ability to jump directly to creating a Block, when there is only one Block Type.
+ return html` ${repeat(
+ this._layoutEntries,
+ (x) => x.contentUdi,
+ (layoutEntry, index) =>
+ html`
+
+ `,
+ )}
+
+
+
+
+
+ `;
+ //
+ }
+
+ static styles = [
+ UmbTextStyles,
+ css`
+ :host {
+ display: grid;
+ gap: 1px;
+ }
+ > div {
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ }
+
+ uui-button-group {
+ padding-top: 1px;
+ display: grid;
+ grid-template-columns: 1fr auto;
+ }
+ `,
+ ];
+}
+
+export default UmbPropertyEditorUIBlockGridEntriesElement;
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'umb-property-editor-ui-block-grid-entries': UmbPropertyEditorUIBlockGridEntriesElement;
+ }
+}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid-layout-container.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid-layout-container.element.ts
deleted file mode 100644
index afc0146d2e..0000000000
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid-layout-container.element.ts
+++ /dev/null
@@ -1,137 +0,0 @@
-import {
- UMB_BLOCK_CATALOGUE_MODAL,
- type UmbBlockGridLayoutModel,
- type UmbBlockTypeBaseModel,
-} from '@umbraco-cms/backoffice/block';
-import { html, customElement, state, repeat, css, property } from '@umbraco-cms/backoffice/external/lit';
-import { type UmbModalRouteBuilder, UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal';
-import { UMB_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/property';
-import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
-import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
-
-/**
- * @element umb-property-editor-ui-block-grid-entries
- */
-@customElement('umb-property-editor-ui-block-grid-entries')
-export class UmbPropertyEditorUIBlockGridEntriesElement extends UmbLitElement {
- // TODO: Make sure Sorter handles columnSpan when retrieving a new entry.
- #catalogueModal: UmbModalRouteRegistrationController;
-
- @state()
- private _catalogueRouteBuilder?: UmbModalRouteBuilder;
-
- @state()
- private _blocks?: Array;
-
- @property({ attribute: false })
- public set layoutEntries(value: Array) {
- this._layoutEntries = value;
- }
- public get layoutEntries(): Array {
- return this._layoutEntries;
- }
- private _layoutEntries: Array = [];
-
- @state()
- private _createButtonLabel = this.localize.term('content_createEmpty');
-
- constructor() {
- super();
-
- // TODO: Observe Blocks of the layout entries of this component.
-
- // TODO: Could this become part of the Block Manager Context?
- this.consumeContext(UMB_PROPERTY_CONTEXT, (propertyContext) => {
- this.observe(
- propertyContext?.alias,
- (alias) => {
- this.#catalogueModal.setUniquePathValue('propertyAlias', alias);
- },
- 'observePropertyAlias',
- );
- });
-
- // Maybe this can be moved to the Block Manager Context? As I don't want to know about groups here. Maybe just part of the onSetup method?
- this.#catalogueModal = new UmbModalRouteRegistrationController(this, UMB_BLOCK_CATALOGUE_MODAL)
- .addUniquePaths(['propertyAlias', 'parentUnique'])
- .addAdditionalPath(':view/:index')
- .onSetup((routingInfo) => {
- const index = routingInfo.index ? parseInt(routingInfo.index) : -1;
- return {
- data: {
- blocks: this._blocks ?? [],
- //blockGroups: this._blockGroups ?? [],
- blockGroups: [],
- openClipboard: routingInfo.view === 'clipboard',
- blockOriginData: { index: index },
- },
- };
- })
- .observeRouteBuilder((routeBuilder) => {
- this._catalogueRouteBuilder = routeBuilder;
- });
- }
-
- render() {
- let createPath: string | undefined;
- if (this._blocks?.length === 1) {
- const elementKey = this._blocks[0].contentElementTypeKey;
- createPath =
- this._catalogueRouteBuilder?.({ view: 'create', index: -1 }) + 'modal/umb-modal-workspace/create/' + elementKey;
- } else {
- createPath = this._catalogueRouteBuilder?.({ view: 'create', index: -1 });
- }
- return html` ${repeat(
- this._layoutEntries,
- (x) => x.contentUdi,
- (layoutEntry, index) =>
- html`
-
- `,
- )}
-
-
-
-
-
- `;
- //
- }
-
- static styles = [
- UmbTextStyles,
- css`
- :host {
- display: grid;
- gap: 1px;
- }
- > div {
- display: flex;
- flex-direction: column;
- align-items: stretch;
- }
-
- uui-button-group {
- padding-top: 1px;
- display: grid;
- grid-template-columns: 1fr auto;
- }
- `,
- ];
-}
-
-export default UmbPropertyEditorUIBlockGridEntriesElement;
-
-declare global {
- interface HTMLElementTagNameMap {
- 'umb-property-editor-ui-block-grid-entries': UmbPropertyEditorUIBlockGridEntriesElement;
- }
-}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid.element.ts
index 9e2141b81d..4d72d6cb1f 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid.element.ts
@@ -1,40 +1,31 @@
+import { UmbBlockGridManagerContext } from '../../manager/block-grid-manager.context.js';
+import { UMB_BLOCK_GRID_PROPERTY_EDITOR_ALIAS } from './manifests.js';
import { html, customElement, property, state, css } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
-import type { UmbBlockGridLayoutModel, UmbBlockTypeBaseModel, UmbBlockTypeGroup } from '@umbraco-cms/backoffice/block';
+import type {
+ UmbBlockGridLayoutModel,
+ UmbBlockGridTypeModel,
+ UmbBlockGridValueModel,
+ UmbBlockTypeGroup,
+} from '@umbraco-cms/backoffice/block';
import type { NumberRangeValueType } from '@umbraco-cms/backoffice/models';
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
-import { UMB_BLOCK_GRID_PROPERTY_EDITOR_ALIAS } from './manifests';
/**
* @element umb-property-editor-ui-block-grid
*/
@customElement('umb-property-editor-ui-block-grid')
export class UmbPropertyEditorUIBlockGridElement extends UmbLitElement implements UmbPropertyEditorUiElement {
- @property()
- value = '';
-
- @state()
- private _limitMin?: number;
- @state()
- private _limitMax?: number;
-
- @state()
- private _blocks?: Array;
-
- @state()
- private _blockGroups?: Array;
-
- @state()
- private _rootLayouts: Array = [];
-
- @state()
- private _directRoute?: string;
-
- @state()
- private _createButtonLabel = this.localize.term('blockEditor_addBlock');
+ #context = new UmbBlockGridManagerContext(this);
+ //
+ private _value: UmbBlockGridValueModel = {
+ layout: {},
+ contentData: [],
+ settingsData: [],
+ };
@property({ attribute: false })
public set config(config: UmbPropertyEditorConfigCollection | undefined) {
@@ -45,28 +36,42 @@ export class UmbPropertyEditorUIBlockGridElement extends UmbLitElement implement
this._limitMin = validationLimit?.min;
this._limitMax = validationLimit?.max;
- this._blocks = config.getValueByAlias>('blocks') ?? [];
- this._blockGroups = config.getValueByAlias>('blockGroups') ?? [];
+ const blocks = config.getValueByAlias>('blocks') ?? [];
+ this.#context.setBlockTypes(blocks);
- const customCreateButtonLabel = config.getValueByAlias('createLabel');
- if (customCreateButtonLabel) {
- this._createButtonLabel = customCreateButtonLabel;
- } else if (this._blocks.length === 1) {
- this._createButtonLabel = this.localize.term('blockEditor_addThis', [this._blocks[0].label]);
- }
+ const blockGroups = config.getValueByAlias>('blockGroups') ?? [];
+ this.#context.setBlockGroups(blockGroups);
- //const useInlineEditingAsDefault = config.getValueByAlias('useInlineEditingAsDefault');
-
- //this.#context.setInlineEditingMode(useInlineEditingAsDefault);
- //config.useSingleBlockMode
- //config.useLiveEditing
- //config.useInlineEditingAsDefault
this.style.maxWidth = config.getValueByAlias('maxPropertyWidth') ?? '';
- //this.#context.setEditorConfiguration(config);
+ //config.useLiveEditing, is covered by the EditorConfiguration of context.
+ this.#context.setEditorConfiguration(config);
}
- #context = new UmbBlockGridManagerContext(this);
+ //
+ @state()
+ private _limitMin?: number;
+ @state()
+ private _limitMax?: number;
+
+ @property({ attribute: false })
+ public get value(): UmbBlockGridValueModel {
+ return this._value;
+ }
+ public set value(value: UmbBlockGridValueModel | undefined) {
+ const buildUpValue: Partial = value ? { ...value } : {};
+ buildUpValue.layout ??= {};
+ buildUpValue.contentData ??= [];
+ buildUpValue.settingsData ??= [];
+ this._value = buildUpValue as UmbBlockGridValueModel;
+
+ this.#context.setLayouts(this._value.layout[UMB_BLOCK_GRID_PROPERTY_EDITOR_ALIAS] ?? []);
+ this.#context.setContents(buildUpValue.contentData);
+ this.#context.setSettings(buildUpValue.settingsData);
+ }
+
+ @state()
+ private _rootLayouts: Array = [];
constructor() {
super();
@@ -92,14 +97,13 @@ export class UmbPropertyEditorUIBlockGridElement extends UmbLitElement implement
//console.log('settings changed', this._value);
this.dispatchEvent(new UmbChangeEvent());
});
- this.observe(this.#context.blockTypes, (blockTypes) => {
- this._blocks = blockTypes;
- });
}
render() {
return html``;
+ .layoutEntries=${this._rootLayouts}
+ .parentUnique=${'root'}
+ .areaKey=${'root'}>`;
}
static styles = [
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 0a70b20f97..2c9368c59d 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
@@ -1,8 +1,9 @@
import type { UmbBlockTypeBaseModel, UmbBlockTypeWithGroupKey } from '../block-type/index.js';
-import type { UmbBlockLayoutBaseModel } from '../index.js';
+import type { UmbBlockLayoutBaseModel, UmbBlockValueType } from '../index.js';
export const UMB_BLOCK_GRID_TYPE = 'block-grid-type';
+// Configuration models:
export interface UmbBlockGridTypeModel extends UmbBlockTypeBaseModel {
columnSpanOptions: Array;
allowAtRoot: boolean;
@@ -23,6 +24,10 @@ export interface UmbBlockGridGroupTypeConfiguration extends Partial;
}
+// Content models:
+
+export interface UmbBlockGridValueModel extends UmbBlockValueType {}
+
export interface UmbBlockGridLayoutModel extends UmbBlockLayoutBaseModel {
columnSpan: number;
rowSpan: number;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/components/block-list-block/block-list-block.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/components/block-list-block/block-list-block.element.ts
index 897f888b4c..95b756a338 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/components/block-list-block/block-list-block.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/components/block-list-block/block-list-block.element.ts
@@ -1,4 +1,4 @@
-import { UmbBlockListContext } from '../../context/block-list.context.js';
+import { UmbBlockListEntryContext } from '../../context/block-list-entry.context.js';
import { html, css, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
@@ -23,7 +23,7 @@ export class UmbPropertyEditorUIBlockListBlockElement extends UmbLitElement impl
}
private _layout?: UmbBlockLayoutBaseModel | undefined;
- #context = new UmbBlockListContext(this);
+ #context = new UmbBlockListEntryContext(this);
@state()
_contentUdi?: string;
@@ -67,21 +67,6 @@ export class UmbPropertyEditorUIBlockListBlockElement extends UmbLitElement impl
});
}
- #requestDelete() {
- this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, async (modalManager) => {
- const modalContext = modalManager.open(UMB_CONFIRM_MODAL, {
- data: {
- headline: `Delete ${this._label}`,
- content: 'Are you sure you want to delete this [INSERT BLOCK TYPE NAME]?',
- confirmLabel: 'Delete',
- color: 'danger',
- },
- });
- await modalContext.onSubmit();
- this.#context.delete();
- });
- }
-
#renderRefBlock() {
return html``;
}
@@ -109,7 +94,7 @@ export class UmbPropertyEditorUIBlockListBlockElement extends UmbLitElement impl
`
: ''}
-
+
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/components/inline-list-block/inline-list-block.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/components/inline-list-block/inline-list-block.element.ts
index e177087318..714a3cc861 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/components/inline-list-block/inline-list-block.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/components/inline-list-block/inline-list-block.element.ts
@@ -1,4 +1,4 @@
-import { UMB_BLOCK_LIST_CONTEXT } from '../../index.js';
+import { UMB_BLOCK_LIST_ENTRY_CONTEXT } from '../../index.js';
import type { UMB_BLOCK_WORKSPACE_CONTEXT } from '../../../block/index.js';
import { UMB_BLOCK_WORKSPACE_ALIAS } from '../../../block/index.js';
import { UmbExtensionsApiInitializer, createExtensionApi } from '@umbraco-cms/backoffice/extension-api';
@@ -13,7 +13,7 @@ import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
*/
@customElement('umb-inline-list-block')
export class UmbInlineListBlockElement extends UmbLitElement {
- #blockContext?: typeof UMB_BLOCK_LIST_CONTEXT.TYPE;
+ #blockContext?: typeof UMB_BLOCK_LIST_ENTRY_CONTEXT.TYPE;
#workspaceContext?: typeof UMB_BLOCK_WORKSPACE_CONTEXT.TYPE;
#contentUdi?: string;
@@ -26,7 +26,7 @@ export class UmbInlineListBlockElement extends UmbLitElement {
constructor() {
super();
- this.consumeContext(UMB_BLOCK_LIST_CONTEXT, (blockContext) => {
+ this.consumeContext(UMB_BLOCK_LIST_ENTRY_CONTEXT, (blockContext) => {
this.#blockContext = blockContext;
this.observe(
this.#blockContext.contentUdi,
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/components/ref-list-block/ref-list-block.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/components/ref-list-block/ref-list-block.element.ts
index dce78e9855..56d52e4e0a 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/components/ref-list-block/ref-list-block.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/components/ref-list-block/ref-list-block.element.ts
@@ -1,4 +1,4 @@
-import { UMB_BLOCK_LIST_CONTEXT } from '../../context/block-list.context-token.js';
+import { UMB_BLOCK_LIST_ENTRY_CONTEXT } from '../../context/block-list-entry.context-token.js';
import { css, customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
@@ -17,7 +17,7 @@ export class UmbRefListBlockElement extends UmbLitElement {
constructor() {
super();
- this.consumeContext(UMB_BLOCK_LIST_CONTEXT, (context) => {
+ this.consumeContext(UMB_BLOCK_LIST_ENTRY_CONTEXT, (context) => {
this.observe(
context.workspaceEditPath,
(workspaceEditPath) => {
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entry.context-token.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entry.context-token.ts
new file mode 100644
index 0000000000..d914fdf834
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entry.context-token.ts
@@ -0,0 +1,5 @@
+import type { UmbBlockListEntryContext } from './block-list-entry.context.js';
+import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
+
+// TODO: Make discriminator method for this:
+export const UMB_BLOCK_LIST_ENTRY_CONTEXT = new UmbContextToken('UmbBlockEntryContext');
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entry.context.ts
similarity index 93%
rename from src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list.context.ts
rename to src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entry.context.ts
index 60b2c3b4c3..718df6fa0e 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entry.context.ts
@@ -2,7 +2,7 @@ import { UMB_BLOCK_LIST_MANAGER_CONTEXT } from '../manager/block-list-manager.co
import { UmbBlockContext } from '@umbraco-cms/backoffice/block';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbBooleanState } from '@umbraco-cms/backoffice/observable-api';
-export class UmbBlockListContext extends UmbBlockContext<
+export class UmbBlockListEntryContext extends UmbBlockContext<
typeof UMB_BLOCK_LIST_MANAGER_CONTEXT,
typeof UMB_BLOCK_LIST_MANAGER_CONTEXT.TYPE
> {
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list.context-token.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list.context-token.ts
deleted file mode 100644
index fb4f9c63fe..0000000000
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list.context-token.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import type { UmbBlockListContext } from './block-list.context.js';
-import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
-
-// TODO: Make discriminator method for this:
-export const UMB_BLOCK_LIST_CONTEXT = new UmbContextToken('UmbBlockContext');
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/index.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/index.ts
new file mode 100644
index 0000000000..235016411e
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/index.ts
@@ -0,0 +1 @@
+export * from './block-list-entry.context-token.js';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/index.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/index.ts
index 06bff7c73b..577eea75f4 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/index.ts
@@ -1,2 +1,3 @@
+export * from './context/index.js';
+export * from './types.js';
export * from './workspace/index.js';
-export * from './context/block-list.context-token.js';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/property-editors/block-list-editor/property-editor-ui-block-list.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/property-editors/block-list-editor/property-editor-ui-block-list.element.ts
index db0744379d..795467d4aa 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/property-editors/block-list-editor/property-editor-ui-block-list.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/property-editors/block-list-editor/property-editor-ui-block-list.element.ts
@@ -1,6 +1,7 @@
import { UmbBlockListManagerContext } from '../../manager/block-list-manager.context.js';
import '../../components/block-list-block/index.js';
import type { UmbPropertyEditorUIBlockListBlockElement } from '../../components/block-list-block/index.js';
+import type { UmbBlockListLayoutModel, UmbBlockListValueModel } from '../../types.js';
import { UMB_BLOCK_LIST_PROPERTY_EDITOR_ALIAS } from './manifests.js';
import { html, customElement, property, state, repeat, css } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
@@ -8,7 +9,7 @@ import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extensi
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import { UMB_BLOCK_CATALOGUE_MODAL } from '@umbraco-cms/backoffice/block';
-import type { UmbBlockLayoutBaseModel, UmbBlockTypeBaseModel, UmbBlockValueType } from '@umbraco-cms/backoffice/block';
+import type { UmbBlockLayoutBaseModel, UmbBlockTypeBaseModel } from '@umbraco-cms/backoffice/block';
import type { NumberRangeValueType } from '@umbraco-cms/backoffice/models';
import type { UmbModalRouteBuilder } from '@umbraco-cms/backoffice/modal';
import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal';
@@ -17,10 +18,6 @@ import type { UmbSorterConfig } from '@umbraco-cms/backoffice/sorter';
import { UmbSorterController } from '@umbraco-cms/backoffice/sorter';
import { UMB_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/property';
-export interface UmbBlockListLayoutModel extends UmbBlockLayoutBaseModel {}
-
-export interface UmbBlockListValueModel extends UmbBlockValueType {}
-
const SORTER_CONFIG: UmbSorterConfig = {
getUniqueOfElement: (element) => {
return element.getAttribute('data-udi');
@@ -94,9 +91,8 @@ export class UmbPropertyEditorUIBlockListElement extends UmbLitElement implement
const useInlineEditingAsDefault = config.getValueByAlias('useInlineEditingAsDefault');
this.#context.setInlineEditingMode(useInlineEditingAsDefault);
- //config.useSingleBlockMode
- //config.useLiveEditing
- //config.useInlineEditingAsDefault
+ // TODO:
+ //config.useSingleBlockMode, not done jey
this.style.maxWidth = config.getValueByAlias('maxPropertyWidth') ?? '';
this.#context.setEditorConfiguration(config);
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/types.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/types.ts
index bd1e8053c9..de8121d884 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/types.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/types.ts
@@ -1,7 +1,9 @@
import type { UmbBlockTypeBaseModel } from '../block-type/index.js';
-import type { UmbBlockLayoutBaseModel } from '../index.js';
+import type { UmbBlockLayoutBaseModel, UmbBlockValueType } from '../index.js';
export const UMB_BLOCK_LIST_TYPE = 'block-list-type';
export interface UmbBlockListTypeModel extends UmbBlockTypeBaseModel {}
export interface UmbBlockListLayoutModel extends UmbBlockLayoutBaseModel {}
+
+export interface UmbBlockListValueModel extends UmbBlockValueType {}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entities.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entities.context.ts
new file mode 100644
index 0000000000..51575f30fa
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entities.context.ts
@@ -0,0 +1,34 @@
+import type { UmbBlockTypeBaseModel } from '../../block-type/types.js';
+import type { UmbBlockLayoutBaseModel } from '../types.js';
+import type { UMB_BLOCK_MANAGER_CONTEXT, UmbBlockManagerContext } from '../manager/index.js';
+import { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
+import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
+import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
+
+export abstract class UmbBlockContext<
+ BlockManagerContextTokenType extends UmbContextToken,
+ BlockManagerContextType extends UmbBlockManagerContext,
+ BlockType extends UmbBlockTypeBaseModel = UmbBlockTypeBaseModel,
+ BlockLayoutType extends UmbBlockLayoutBaseModel = UmbBlockLayoutBaseModel,
+> extends UmbContextBase<
+ UmbBlockContext
+> {
+ //
+ _manager?: BlockManagerContextType;
+
+ constructor(host: UmbControllerHost, blockManagerContextToken: BlockManagerContextTokenType) {
+ super(host, UMB_BLOCK_ENTITY_CONTEXT.toString());
+ }
+
+ // Public methods:
+
+ //edit?
+ //editSettings
+ //requestDelete
+ //delete
+ //copy
+}
+
+export const UMB_BLOCK_ENTITY_CONTEXT = new UmbContextToken<
+ UmbBlockContext
+>('UmbBlockEntryContext');
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entity.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entity.context.ts
index 9f9d417e10..4a031d2a94 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entity.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entity.context.ts
@@ -6,6 +6,7 @@ import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
import { UmbObjectState, UmbStringState } from '@umbraco-cms/backoffice/observable-api';
import { encodeFilePath } from '@umbraco-cms/backoffice/utils';
+import { UMB_CONFIRM_MODAL, UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
export abstract class UmbBlockContext<
BlockManagerContextTokenType extends UmbContextToken,
@@ -21,6 +22,8 @@ export abstract class UmbBlockContext<
#blockTypeName = new UmbStringState(undefined);
public readonly blockTypeName = this.#blockTypeName.asObservable();
+ // TODO: index state + observable?
+
#label = new UmbStringState('');
public readonly label = this.#label.asObservable();
@@ -59,6 +62,15 @@ export abstract class UmbBlockContext<
this.#layout.setValue(layout);
}
+ /**
+ * Get the current value of this Blocks label.
+ * @method getLabel
+ * @returns {string}
+ */
+ getLabel() {
+ return this.#label.value;
+ }
+
constructor(host: UmbControllerHost, blockManagerContextToken: BlockManagerContextTokenType) {
super(host, UMB_BLOCK_ENTITY_CONTEXT.toString());
@@ -190,14 +202,34 @@ export abstract class UmbBlockContext<
// Public methods:
+ //activate
+ public edit() {}
+ //editSettings
+
+ requestDelete() {
+ this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, async (modalManager) => {
+ const modalContext = modalManager.open(UMB_CONFIRM_MODAL, {
+ data: {
+ headline: `Delete ${this.getLabel()}`,
+ content: 'Are you sure you want to delete this [INSERT BLOCK TYPE NAME]?',
+ confirmLabel: 'Delete',
+ color: 'danger',
+ },
+ });
+ await modalContext.onSubmit();
+ this.delete();
+ });
+ }
public delete() {
if (!this._manager) return;
const contentUdi = this.#layout.value?.contentUdi;
if (!contentUdi) return;
this._manager.deleteBlock(contentUdi);
}
+
+ //copy
}
export const UMB_BLOCK_ENTITY_CONTEXT = new UmbContextToken<
UmbBlockContext
->('UmbBlockContext');
+>('UmbBlockEntryContext');
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/manager/block-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/manager/block-manager.context.ts
index 0ab646f59a..c5faa4ce6d 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block/manager/block-manager.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/manager/block-manager.context.ts
@@ -10,6 +10,7 @@ import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/mod
import type { UmbContentTypeModel } from '@umbraco-cms/backoffice/content-type';
import { UmbId } from '@umbraco-cms/backoffice/id';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
+import { UMB_PROPERTY_CONTEXT } from '@umbraco-cms/backoffice/property';
// TODO: We are using backend model here, I think we should get our own model:
type ElementTypeModel = UmbContentTypeModel;
@@ -20,10 +21,14 @@ export abstract class UmbBlockManagerContext<
> extends UmbContextBase {
//
#contentTypeRepository = new UmbDocumentTypeDetailRepository(this);
+ #workspaceModal: UmbModalRouteRegistrationController;
#workspacePath = new UmbStringState(undefined);
workspacePath = this.#workspacePath.asObservable();
+ #propertyAlias = new UmbStringState(undefined);
+ propertyAlias = this.#propertyAlias.asObservable();
+
#contentTypes = new UmbArrayState(>[], (x) => x.unique);
public readonly contentTypes = this.#contentTypes.asObservable();
@@ -42,6 +47,14 @@ export abstract class UmbBlockManagerContext<
#settings = new UmbArrayState(>[], (x) => x.udi);
public readonly settings = this.#settings.asObservable();
+ setPropertyAlias(alias: string) {
+ this.#propertyAlias.setValue(alias);
+ this.#workspaceModal.setUniquePathValue('propertyAlias', alias);
+ }
+ getPropertyAlias() {
+ this.#propertyAlias.value;
+ }
+
setEditorConfiguration(configs: UmbPropertyEditorConfigCollection) {
this.#editorConfiguration.setValue(configs);
}
@@ -67,9 +80,18 @@ export abstract class UmbBlockManagerContext<
constructor(host: UmbControllerHost) {
super(host, UMB_BLOCK_MANAGER_CONTEXT);
- // TODO: This might will need the property alias as part of the URL, to avoid collision if multiple of these Editor on same Node.
- // IDEA: Make a Workspace registration controller that can be used to register a workspace, which does both edit and create?.
- new UmbModalRouteRegistrationController(this, UMB_BLOCK_WORKSPACE_MODAL)
+ this.consumeContext(UMB_PROPERTY_CONTEXT, (propertyContext) => {
+ this.observe(
+ propertyContext?.alias,
+ (alias) => {
+ this.#propertyAlias.setValue(alias);
+ },
+ 'observePropertyAlias',
+ );
+ });
+
+ this.#workspaceModal = new UmbModalRouteRegistrationController(this, UMB_BLOCK_WORKSPACE_MODAL)
+ .addUniquePaths(['propertyAlias'])
.addAdditionalPath('block')
.onSetup(() => {
return { data: { entityType: 'block', preset: {} }, modal: { size: 'medium' } };
@@ -191,9 +213,12 @@ export abstract class UmbBlockManagerContext<
return true;
}
+ // Idea: should we return true if it was successful?
deleteBlock(contentUdi: string) {
const layout = this._layouts.value.find((x) => x.contentUdi === contentUdi);
- if (!layout) return;
+ if (!layout) {
+ throw new Error(`Cannot delete block, missing layout for ${contentUdi}`);
+ }
if (layout.settingsUdi) {
this.#settings.removeOne(layout.settingsUdi);
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-workspace.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-workspace.context.ts
index 327498248a..3582efd244 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-workspace.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/workspace/block-workspace.context.ts
@@ -76,6 +76,7 @@ export class UmbBlockWorkspaceContext<
}
this.observe(
+ // TODO: Make a general concept of Block Entries Context, use it to retrieve the layout:
this.#blockManager.layoutOf(unique),
(layoutData) => {
this.#layout.setValue(layoutData as LayoutDataType);
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/sorter/sorter.controller.test.ts b/src/Umbraco.Web.UI.Client/src/packages/core/sorter/sorter.controller.test.ts
deleted file mode 100644
index 26e5f4b4ea..0000000000
--- a/src/Umbraco.Web.UI.Client/src/packages/core/sorter/sorter.controller.test.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { expect, fixture, html } from '@open-wc/testing';
-import { UmbSorterConfig, UmbSorterController } from './sorter.controller.js';
-import type UmbTestSorterControllerElement from './stories/test-sorter-controller.element.js';
-import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
-import { customElement } from '@umbraco-cms/backoffice/external/lit';
-
-describe('UmbContextConsumer', () => {
- let hostElement: UmbTestSorterControllerElement;
-
- beforeEach(async () => {
- hostElement = await fixture(html` `);
- });
-
- // TODO: Testing ideas:
- // - Test that the model is updated correctly?
- // - Test that the DOM is updated correctly?
- // - Use the controller to sort the DOM and test that the model is updated correctly...
-});