diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-areas-container/block-grid-areas-container.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-areas-container/block-grid-areas-container.element.ts
index 96737aef10..b0d28229d1 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-areas-container/block-grid-areas-container.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-areas-container/block-grid-areas-container.element.ts
@@ -43,11 +43,14 @@ export class UmbBlockGridAreaContainerElement extends UmbLitElement {
render() {
return this._areas
? html` ${this.#styleElement}
-
+
${repeat(
this._areas,
(area) => area.key,
- (area) => html``,
+ (area) =>
+ html``,
)}
`
: '';
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-entries/block-grid-entries.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-entries/block-grid-entries.element.ts
index 1e5f17347f..24dbb888d8 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-entries/block-grid-entries.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-entries/block-grid-entries.element.ts
@@ -1,9 +1,9 @@
+import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbBlockGridEntriesContext } from '../../context/block-grid-entries.context.js';
import type { UmbBlockGridEntryElement } from '../block-grid-entry/index.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/backoffice/lit-element';
import '../block-grid-entry/index.js';
import { UmbSorterController, type UmbSorterConfig } from '@umbraco-cms/backoffice/sorter';
@@ -45,6 +45,9 @@ export class UmbBlockGridEntriesElement extends UmbLitElement {
return null; // Not implemented.
}
+ @state()
+ private _styleElement?: HTMLLinkElement;
+
@state()
private _layoutEntries: Array
= [];
@@ -59,32 +62,45 @@ export class UmbBlockGridEntriesElement extends UmbLitElement {
this.#sorter.setModel(layoutEntries);
this.requestUpdate('layoutEntries', oldValue);
});
+
+ this.#context.getManager().then((manager) => {
+ this.observe(
+ manager.layoutStylesheet,
+ (stylesheet) => {
+ this._styleElement = document.createElement('link');
+ this._styleElement.setAttribute('rel', 'stylesheet');
+ this._styleElement.setAttribute('href', stylesheet);
+ },
+ 'observeStylesheet',
+ );
+ });
}
+ // TODO: Missing ability to jump directly to creating a Block, when there is only one Block Type.
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`
-
+ return html` ${this._styleElement}
+
+ ${repeat(
+ this._layoutEntries,
+ (x) => x.contentUdi,
+ (layoutEntry, index) =>
+ html`
`,
- )}
-
-
-
-
-
- `;
+ )}
+
+
+
+
+
+
+
`;
//
}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts
index 7ff77559d4..376f2ae0c8 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/components/block-grid-entry/block-grid-entry.element.ts
@@ -1,6 +1,6 @@
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbBlockGridEntryContext } from '../../context/block-grid-entry.context.js';
-import { html, css, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
+import { html, css, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import '../ref-grid-block/index.js';
import type { UmbBlockGridLayoutModel, UmbBlockViewPropsType } from '@umbraco-cms/backoffice/block';
@@ -11,6 +11,14 @@ import type { UmbBlockGridLayoutModel, UmbBlockViewPropsType } from '@umbraco-cm
@customElement('umb-block-grid-entry')
export class UmbBlockGridEntryElement extends UmbLitElement implements UmbPropertyEditorUiElement {
//
+ @property({ type: Number })
+ public get index(): number | undefined {
+ return this.#context.getIndex();
+ }
+ public set index(value: number | undefined) {
+ this.#context.setIndex(value);
+ }
+
@property({ attribute: false })
public get contentUdi(): string | undefined {
return this._contentUdi;
@@ -26,10 +34,24 @@ export class UmbBlockGridEntryElement extends UmbLitElement implements UmbProper
#context = new UmbBlockGridEntryContext(this);
+ @state()
+ _contentElementTypeKey?: string;
+
+ @state()
+ _contentElementTypeAlias?: string;
+
+ @state()
+ _columnSpan?: number;
+
+ @state()
+ _rowSpan?: number;
+
@state()
_showContentEdit = false;
@state()
_hasSettings = false;
+ @state()
+ _createPath?: string;
@state()
_label = '';
@@ -50,11 +72,17 @@ export class UmbBlockGridEntryElement extends UmbLitElement implements UmbProper
constructor() {
super();
+ this.observe(this.#context.createPath, (createPath) => {
+ const oldValue = this._createPath;
+ console.log('createPath', createPath);
+ this._createPath = createPath;
+ this.requestUpdate('_createPath', oldValue);
+ });
this.observe(this.#context.showContentEdit, (showContentEdit) => {
this._showContentEdit = showContentEdit;
});
- this.observe(this.#context.blockTypeSettingsElementTypeKey, (blockTypeSettingsElementTypeKey) => {
- this._hasSettings = !!blockTypeSettingsElementTypeKey;
+ this.observe(this.#context.settingsElementTypeKey, (settingsElementTypeKey) => {
+ this._hasSettings = !!settingsElementTypeKey;
});
this.observe(this.#context.label, (label) => {
this._blockViewProps.label = label;
@@ -82,34 +110,76 @@ export class UmbBlockGridEntryElement extends UmbLitElement implements UmbProper
});
}
+ createRenderRoot() {
+ return this;
+ }
+
+ connectedCallback(): void {
+ super.connectedCallback();
+ // element styling:
+ this.observe(
+ this.#context.columnSpan,
+ (columnSpan) => {
+ this._columnSpan = columnSpan;
+ },
+ 'columnSpan',
+ );
+ this.observe(
+ this.#context.rowSpan,
+ (rowSpan) => {
+ this._rowSpan = rowSpan;
+ },
+ 'rowSpan',
+ );
+ this.observe(this.#context.contentElementTypeKey, (contentElementTypeKey) => {
+ this._contentElementTypeKey = contentElementTypeKey;
+ });
+ this.observe(this.#context.contentElementTypeAlias, (contentElementTypeAlias) => {
+ this._contentElementTypeAlias = contentElementTypeAlias;
+ });
+ }
+
#renderRefBlock() {
return html``;
}
#renderBlock() {
- return this.contentUdi
+ return this.contentUdi && this._createPath
? html`
- ${this.#renderRefBlock()}
-
- ${this._showContentEdit && this._workspaceEditContentPath
- ? html`
-
- `
- : ''}
- ${this._hasSettings && this._workspaceEditSettingsPath
- ? html`
-
- `
- : ''}
- this.#context.requestDelete()}>
-
-
-
+
+
+ ${this.#renderRefBlock()}
+
+ ${this._showContentEdit && this._workspaceEditContentPath
+ ? html`
+
+ `
+ : ''}
+ ${this._hasSettings && this._workspaceEditSettingsPath
+ ? html`
+
+ `
+ : ''}
+ this.#context.requestDelete()}>
+
+
+
+
`
: '';
}
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
index 9d841d3e29..92542b506b 100644
--- 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
@@ -4,7 +4,7 @@ import { UMB_BLOCK_GRID_ENTRY_CONTEXT, type UmbBlockGridWorkspaceData } from '..
import type { UmbBlockGridLayoutModel, UmbBlockGridTypeModel } from '../types.js';
import { UMB_BLOCK_GRID_MANAGER_CONTEXT } from './block-grid-manager.context.js';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
-import { type UmbModalRouteBuilder, UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal';
+import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal';
export class UmbBlockGridEntriesContext extends UmbBlockEntriesContext<
typeof UMB_BLOCK_GRID_MANAGER_CONTEXT,
@@ -14,7 +14,6 @@ export class UmbBlockGridEntriesContext extends UmbBlockEntriesContext<
> {
//
#catalogueModal: UmbModalRouteRegistrationController;
- #catalogueRouteBuilder?: UmbModalRouteBuilder;
#parentEntry?: typeof UMB_BLOCK_GRID_ENTRY_CONTEXT.TYPE;
#retrieveParentEntry;
@@ -60,8 +59,7 @@ export class UmbBlockGridEntriesContext extends UmbBlockEntriesContext<
};
})
.observeRouteBuilder((routeBuilder) => {
- this.#catalogueRouteBuilder = routeBuilder;
- // TODO: Trigger render update?
+ this._catalogueRouteBuilderState.setValue(routeBuilder);
});
}
@@ -147,11 +145,11 @@ export class UmbBlockGridEntriesContext extends UmbBlockEntriesContext<
}
getPathForCreateBlock(index: number) {
- return this.#catalogueRouteBuilder?.({ view: 'create', index: index });
+ return this._catalogueRouteBuilderState.getValue()?.({ view: 'create', index: index });
}
getPathForClipboard(index: number) {
- return this.#catalogueRouteBuilder?.({ view: 'clipboard', index: index });
+ return this._catalogueRouteBuilderState.getValue()?.({ view: 'clipboard', index: index });
}
async create(
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context.ts
index 061c7670f6..0047122f29 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-entry.context.ts
@@ -15,6 +15,9 @@ export class UmbBlockGridEntryContext extends UmbBlockEntryContext<
UmbBlockGridTypeModel,
UmbBlockGridLayoutModel
> {
+ //
+ columnSpan = this._layout.asObservablePart((x) => x?.columnSpan);
+ rowSpan = this._layout.asObservablePart((x) => x?.rowSpan ?? 1);
areas = this._layout.asObservablePart((x) => x?.areas ?? []);
readonly showContentEdit = this._blockType.asObservablePart((x) => !x?.forceHideContentEditorInOverlay);
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-manager.context.ts
index 15fc8cb129..42a8d8698a 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-manager.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/context/block-grid-manager.context.ts
@@ -14,7 +14,6 @@ const UMB_BLOCK_GRID_DEFAULT_LAYOUT_STYLESHEET = '/umbraco/backoffice/css/umbrac
export class UmbBlockGridManagerContext<
BlockLayoutType extends UmbBlockGridLayoutModel = UmbBlockGridLayoutModel,
> extends UmbBlockManagerContext {
- //
//
#blockGroups = new UmbArrayState(>[], (x) => x.key);
public readonly blockGroups = this.#blockGroups.asObservable();
@@ -22,6 +21,10 @@ export class UmbBlockGridManagerContext<
layoutStylesheet = this._editorConfiguration.asObservablePart(
(x) => (x?.getValueByAlias('layoutStylesheet') as string) ?? UMB_BLOCK_GRID_DEFAULT_LAYOUT_STYLESHEET,
);
+ gridColumns = this._editorConfiguration.asObservablePart((x) => {
+ const value = x?.getValueByAlias('gridColumns') as string | undefined;
+ return parseInt(value && value !== '' ? value : '12');
+ });
setBlockGroups(blockGroups: Array) {
this.#blockGroups.setValue(blockGroups);
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/manifests.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/manifests.ts
index aee0e499fe..73b05e3f9a 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/manifests.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/manifests.ts
@@ -32,6 +32,18 @@ export const manifest: ManifestPropertyEditorUi = {
description: 'Override the label text for adding a new block, Example Add Widget',
propertyEditorUiAlias: 'Umb.PropertyEditorUi.TextBox',
},
+ {
+ alias: 'gridColumns',
+ label: 'Grid Columns',
+ description: 'Set the number of columns for the layout. (defaults to 12)',
+ propertyEditorUiAlias: 'Umb.PropertyEditorUi.Number',
+ },
+ {
+ alias: 'layoutStylesheet',
+ label: 'Layout Stylesheet',
+ description: 'Override default stylesheet for backoffice layout.',
+ propertyEditorUiAlias: 'Umb.PropertyEditorUi.BlockGridLayoutStylesheet',
+ },
],
},
},
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 9a8a6cf5c0..a2f8177c4e 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,9 +1,9 @@
+import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbBlockGridManagerContext } from '../../context/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 { html, customElement, property, state, css, type PropertyValueMap } 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/backoffice/lit-element';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import type {
UmbBlockGridLayoutModel,
@@ -100,6 +100,16 @@ export class UmbPropertyEditorUIBlockGridElement extends UmbLitElement implement
});
}
+ protected firstUpdated(_changedProperties: PropertyValueMap | Map): void {
+ super.firstUpdated(_changedProperties);
+
+ this.observe(this.#context.gridColumns, (gridColumns) => {
+ if (gridColumns) {
+ this.style.setProperty('--umb-block-grid--grid-columns', gridColumns.toString());
+ }
+ });
+ }
+
render() {
return html``;
}
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/components/block-list-entry/block-list-entry.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/components/block-list-entry/block-list-entry.element.ts
index 5a3ab32e79..ad6f5ace56 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/components/block-list-entry/block-list-entry.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/components/block-list-entry/block-list-entry.element.ts
@@ -12,6 +12,14 @@ import type { UmbBlockListLayoutModel, UmbBlockViewPropsType } from '@umbraco-cm
@customElement('umb-block-list-entry')
export class UmbBlockListEntryElement extends UmbLitElement implements UmbPropertyEditorUiElement {
//
+ @property({ type: Number })
+ public get index(): number | undefined {
+ return this.#context.getIndex();
+ }
+ public set index(value: number | undefined) {
+ this.#context.setIndex(value);
+ }
+
@property({ attribute: false })
public get contentUdi(): string | undefined {
return this._contentUdi;
@@ -52,8 +60,8 @@ export class UmbBlockListEntryElement extends UmbLitElement implements UmbProper
this.observe(this.#context.showContentEdit, (showContentEdit) => {
this._showContentEdit = showContentEdit;
});
- this.observe(this.#context.blockTypeSettingsElementTypeKey, (blockTypeSettingsElementTypeKey) => {
- this._hasSettings = !!blockTypeSettingsElementTypeKey;
+ this.observe(this.#context.settingsElementTypeKey, (settingsElementTypeKey) => {
+ this._hasSettings = !!settingsElementTypeKey;
});
this.observe(this.#context.label, (label) => {
const oldValue = this._label;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entries.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entries.context.ts
index 204d95266e..b414bd249c 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entries.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-list/context/block-list-entries.context.ts
@@ -4,7 +4,7 @@ import type { UmbBlockListWorkspaceData } from '../index.js';
import type { UmbBlockListLayoutModel, UmbBlockListTypeModel } from '../types.js';
import { UMB_BLOCK_LIST_MANAGER_CONTEXT } from './block-list-manager.context.js';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
-import { type UmbModalRouteBuilder, UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal';
+import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal';
export class UmbBlockListEntriesContext extends UmbBlockEntriesContext<
typeof UMB_BLOCK_LIST_MANAGER_CONTEXT,
@@ -14,7 +14,6 @@ export class UmbBlockListEntriesContext extends UmbBlockEntriesContext<
> {
//
#catalogueModal: UmbModalRouteRegistrationController;
- #catalogueRouteBuilder?: UmbModalRouteBuilder;
constructor(host: UmbControllerHost) {
super(host, UMB_BLOCK_LIST_MANAGER_CONTEXT);
@@ -35,8 +34,7 @@ export class UmbBlockListEntriesContext extends UmbBlockEntriesContext<
};
})
.observeRouteBuilder((routeBuilder) => {
- this.#catalogueRouteBuilder = routeBuilder;
- // TODO: Trigger render update?
+ this._catalogueRouteBuilderState.setValue(routeBuilder);
});
}
@@ -78,11 +76,11 @@ export class UmbBlockListEntriesContext extends UmbBlockEntriesContext<
}
getPathForCreateBlock(index: number) {
- return this.#catalogueRouteBuilder?.({ view: 'create', index: index });
+ return this._catalogueRouteBuilderState.getValue()?.({ view: 'create', index: index });
}
getPathForClipboard(index: number) {
- return this.#catalogueRouteBuilder?.({ view: 'clipboard', index: index });
+ return this._catalogueRouteBuilderState.getValue()?.({ view: 'clipboard', index: index });
}
async create(
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entries.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entries.context.ts
index e1cc7bc7e4..310b99af4e 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entries.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entries.context.ts
@@ -6,8 +6,8 @@ import { UMB_BLOCK_ENTRIES_CONTEXT } from './block-entries.context-token.js';
import type { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
import { UmbContextBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';
-import { UmbArrayState, UmbStringState } from '@umbraco-cms/backoffice/observable-api';
-import { UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal';
+import { UmbArrayState, UmbBasicState, UmbStringState } from '@umbraco-cms/backoffice/observable-api';
+import { type UmbModalRouteBuilder, UmbModalRouteRegistrationController } from '@umbraco-cms/backoffice/modal';
export abstract class UmbBlockEntriesContext<
BlockManagerContextTokenType extends UmbContextToken,
@@ -23,6 +23,9 @@ export abstract class UmbBlockEntriesContext<
_workspaceModal: UmbModalRouteRegistrationController;
+ protected _catalogueRouteBuilderState = new UmbBasicState(undefined);
+ readonly catalogueRouteBuilder = this._catalogueRouteBuilderState.asObservable();
+
#workspacePath = new UmbStringState(undefined);
workspacePath = this.#workspacePath.asObservable();
@@ -67,6 +70,11 @@ export abstract class UmbBlockEntriesContext<
});
}
+ async getManager() {
+ await this._retrieveManager;
+ return this._manager!;
+ }
+
protected abstract _gotBlockManager(): void;
// Public methods:
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entry.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entry.context.ts
index b4b3690a9c..ec74030e38 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entry.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-entry.context.ts
@@ -1,3 +1,4 @@
+import type { Observable } from '@umbraco-cms/backoffice/external/rxjs/index.js';
import type { UmbBlockTypeBaseModel } from '../../block-type/types.js';
import type { UmbBlockLayoutBaseModel, UmbBlockDataType } from '../types.js';
import type { UmbBlockManagerContext } from '../index.js';
@@ -5,10 +6,9 @@ import type { UmbBlockEntriesContext } from './block-entries.context.js';
import type { UmbContextToken } from '@umbraco-cms/backoffice/context-api';
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 { UmbNumberState, 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';
-import { Observable } from '@umbraco-cms/backoffice/external/rxjs/index.js';
export abstract class UmbBlockEntryContext<
BlockManagerContextTokenType extends UmbContextToken,
@@ -29,27 +29,47 @@ export abstract class UmbBlockEntryContext<
#contentUdi?: string;
- #blockTypeName = new UmbStringState(undefined);
- public readonly blockTypeName = this.#blockTypeName.asObservable();
+ #index = new UmbNumberState(undefined);
+ readonly index = this.#index.asObservable();
+ getIndex() {
+ return this.#index.value;
+ }
+ setIndex(index: number | undefined) {
+ this.#index.setValue(index);
+ }
+
+ #createPath = new UmbStringState(undefined);
+ readonly createPath = this.#createPath.asObservable();
+
+ #contentElementTypeName = new UmbStringState(undefined);
+ public readonly contentElementTypeName = this.#contentElementTypeName.asObservable();
+ #contentElementTypeAlias = new UmbStringState(undefined);
+ public readonly contentElementTypeAlias = this.#contentElementTypeAlias.asObservable();
// TODO: index state + observable?
#label = new UmbStringState('');
public readonly label = this.#label.asObservable();
+ #generateWorkspaceEditContentPath = (path?: string) =>
+ path ? path + 'edit/' + encodeFilePath(this.getContentUdi() ?? '') + '/view/content' : '';
+
+ #generateWorkspaceEditSettingsPath = (path?: string) =>
+ path ? path + 'edit/' + encodeFilePath(this.getContentUdi() ?? '') + '/view/settings' : '';
+
#workspacePath = new UmbStringState(undefined);
public readonly workspacePath = this.#workspacePath.asObservable();
- public readonly workspaceEditContentPath = this.#workspacePath.asObservablePart((path) =>
- path ? path + 'edit/' + encodeFilePath(this.getContentUdi() ?? '') + '/view/content' : '',
+ public readonly workspaceEditContentPath = this.#workspacePath.asObservablePart(
+ this.#generateWorkspaceEditContentPath,
);
- public readonly workspaceEditSettingsPath = this.#workspacePath.asObservablePart((path) =>
- path ? path + 'edit/' + encodeFilePath(this.getContentUdi() ?? '') + '/view/settings' : '',
+ public readonly workspaceEditSettingsPath = this.#workspacePath.asObservablePart(
+ this.#generateWorkspaceEditSettingsPath,
);
_blockType = new UmbObjectState(undefined);
public readonly blockType = this._blockType.asObservable();
- public readonly blockTypeContentElementTypeKey = this._blockType.asObservablePart((x) => x?.contentElementTypeKey);
- public readonly blockTypeSettingsElementTypeKey = this._blockType.asObservablePart((x) => x?.settingsElementTypeKey);
+ public readonly contentElementTypeKey = this._blockType.asObservablePart((x) => x?.contentElementTypeKey);
+ public readonly settingsElementTypeKey = this._blockType.asObservablePart((x) => x?.settingsElementTypeKey);
_layout = new UmbObjectState(undefined);
public readonly layout = this._layout.asObservable();
@@ -119,21 +139,40 @@ export abstract class UmbBlockEntryContext<
// Observe contentElementTypeKey:
this.observe(this.contentTypeKey, (contentElementTypeKey) => {
if (!contentElementTypeKey) return;
+ this.#observeContentType();
this.#observeBlockType();
});
// Observe blockType:
this.observe(this.blockType, (blockType) => {
if (!blockType) return;
- this.#observeBlockTypeContentElementName();
this.#observeBlockTypeLabel();
});
+
+ this.observe(this.index, () => {
+ this.#updateCreatePath();
+ });
}
getContentUdi() {
return this._layout.value?.contentUdi;
}
+ #updateCreatePath() {
+ const index = this.#index.value;
+ if (this._entries && index !== undefined) {
+ this.observe(
+ this._entries.catalogueRouteBuilder,
+ (catalogueRouteBuilder) => {
+ if (catalogueRouteBuilder) {
+ this.#createPath.setValue(this._entries!.getPathForCreateBlock(index));
+ }
+ },
+ 'observeRouteBuilderCreate',
+ );
+ }
+ }
+
#observeLayout() {
if (!this._entries || !this.#contentUdi) return;
@@ -163,6 +202,7 @@ export abstract class UmbBlockEntryContext<
abstract _gotManager(): void;
#gotEntries() {
+ this.#updateCreatePath();
this.#observeLayout();
if (this._entries) {
this.observe(
@@ -224,6 +264,21 @@ export abstract class UmbBlockEntryContext<
}
}
+ #observeContentType() {
+ if (!this._manager) return;
+ const contentTypeKey = this.#content.value?.contentTypeKey;
+ if (!contentTypeKey) return;
+
+ // observe blockType:
+ this.observe(
+ this._manager.contentTypeOf(contentTypeKey),
+ (contentType) => {
+ this.#contentElementTypeAlias.setValue(contentType?.alias);
+ this.#contentElementTypeName.setValue(contentType?.name);
+ },
+ 'observeContentElementType',
+ );
+ }
#observeBlockType() {
if (!this._manager) return;
const contentTypeKey = this.#content.value?.contentTypeKey;
@@ -239,21 +294,6 @@ export abstract class UmbBlockEntryContext<
);
}
- #observeBlockTypeContentElementName() {
- if (!this._manager) return;
- const contentElementTypeKey = this._blockType.value?.contentElementTypeKey;
- if (!contentElementTypeKey) return;
-
- // observe blockType:
- this.observe(
- this._manager.contentTypeNameOf(contentElementTypeKey),
- (contentTypeName) => {
- this.#blockTypeName.setValue(contentTypeName);
- },
- 'observeBlockTypeContentElementTypeName',
- );
- }
-
#observeBlockTypeLabel() {
if (!this._manager) return;
const blockType = this._blockType.value;
@@ -268,11 +308,11 @@ export abstract class UmbBlockEntryContext<
// TODO: Maybe this could be skipped if we had a fallback label which was set to get the content element type name?
// Get the name of the content element type for label:
this.observe(
- this.blockTypeName,
+ this.contentElementTypeName,
(contentTypeName) => {
this.#label.setValue(contentTypeName ?? 'no name');
},
- 'observeBlockTypeName',
+ 'observeContentTypeName',
);
}
}
@@ -280,8 +320,12 @@ export abstract class UmbBlockEntryContext<
// Public methods:
//activate
- public edit() {}
- //editSettings
+ public edit() {
+ window.location.href = this.#generateWorkspaceEditContentPath(this.#workspacePath.value);
+ }
+ public editSettings() {
+ window.location.href = this.#generateWorkspaceEditSettingsPath(this.#workspacePath.value);
+ }
requestDelete() {
this.consumeContext(UMB_MODAL_MANAGER_CONTEXT, async (modalManager) => {
diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts
index 25aa9360e1..01d5645acf 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/block/block/context/block-manager.context.ts
@@ -120,9 +120,8 @@ export abstract class UmbBlockManagerContext<
return data;
}
- contentTypeOf(contentTypeUdi: string) {
- const contentTypeUnique = getKeyFromUdi(contentTypeUdi);
- return this.#contentTypes.asObservablePart((source) => source.find((x) => x.unique === contentTypeUnique));
+ contentTypeOf(contentTypeKey: string) {
+ return this.#contentTypes.asObservablePart((source) => source.find((x) => x.unique === contentTypeKey));
}
contentTypeNameOf(contentTypeKey: string) {
return this.#contentTypes.asObservablePart((source) => source.find((x) => x.unique === contentTypeKey)?.name);
diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/schemas/Umbraco.BlockGrid.ts b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/schemas/Umbraco.BlockGrid.ts
index c03c459cfb..fb5d4ec47b 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/schemas/Umbraco.BlockGrid.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/core/property-editor/schemas/Umbraco.BlockGrid.ts
@@ -24,18 +24,6 @@ export const manifest: ManifestPropertyEditorSchema = {
label: 'Amount',
propertyEditorUiAlias: 'Umb.PropertyEditorUi.NumberRange',
},
- {
- alias: 'gridColumns',
- label: 'Grid Columns',
- description: 'Set the number of columns for the layout. (defaults to 12)',
- propertyEditorUiAlias: 'Umb.PropertyEditorUi.Number',
- },
- {
- alias: 'layoutStylesheet',
- label: 'Layout Stylesheet',
- description: 'Override default stylesheet for backoffice layout.',
- propertyEditorUiAlias: 'Umb.PropertyEditorUi.BlockGridLayoutStylesheet',
- },
],
defaultData: [
{