From 651d96cbbe002b1c4c81fd610ae6ed4def5379b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 12 Feb 2024 22:39:53 +0100 Subject: [PATCH] a lot of bindings monday evening commit --- .../block-grid-areas-container.element.ts | 7 +- .../block-grid-entries.element.ts | 62 +++++---- .../block-grid-entry.element.ts | 120 ++++++++++++++---- .../context/block-grid-entries.context.ts | 10 +- .../context/block-grid-entry.context.ts | 3 + .../context/block-grid-manager.context.ts | 5 +- .../block-grid-editor/manifests.ts | 12 ++ .../property-editor-ui-block-grid.element.ts | 14 +- .../block-list-entry.element.ts | 12 +- .../context/block-list-entries.context.ts | 10 +- .../block/context/block-entries.context.ts | 12 +- .../block/context/block-entry.context.ts | 104 ++++++++++----- .../block/context/block-manager.context.ts | 5 +- .../schemas/Umbraco.BlockGrid.ts | 12 -- 14 files changed, 274 insertions(+), 114 deletions(-) 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: [ {