mega commit tuesday
This commit is contained in:
@@ -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`<umb-ref-grid-block .label=${this._label}></umb-ref-grid-block>`;
|
||||
}
|
||||
|
||||
#renderBlock() {
|
||||
return html`
|
||||
<umb-extension-slot
|
||||
type="blockEditorCustomView"
|
||||
default-element=${'umb-ref-grid-block'}
|
||||
.props=${this._blockViewProps}
|
||||
>${this.#renderRefBlock()}</umb-extension-slot
|
||||
>
|
||||
<uui-action-bar>
|
||||
${this._workspaceEditPath
|
||||
? html`<uui-button label="edit" compact href=${this._workspaceEditPath}>
|
||||
<uui-icon name="icon-edit"></uui-icon>
|
||||
</uui-button>`
|
||||
: ''}
|
||||
${this._workspaceEditPath && this._hasSettings
|
||||
? html`<uui-button label="Edit settings" compact href=${this._workspaceEditPath + '/view/settings'}>
|
||||
<uui-icon name="icon-settings"></uui-icon>
|
||||
</uui-button>`
|
||||
: ''}
|
||||
<uui-button label="delete" compact @click=${this.#context.requestDelete}>
|
||||
<uui-icon name="icon-remove"></uui-icon>
|
||||
</uui-button>
|
||||
</uui-action-bar>
|
||||
`;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './block-grid-block.element.js';
|
||||
@@ -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<UmbBlockGridEntriesContext>('UmbBlockEntriesContext');
|
||||
@@ -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<UmbBlockGridEntriesContext> {
|
||||
//
|
||||
#blockManager?: typeof UMB_BLOCK_GRID_MANAGER_CONTEXT.TYPE;
|
||||
#catalogueModal: UmbModalRouteRegistrationController<typeof UMB_BLOCK_CATALOGUE_MODAL.DATA, undefined>;
|
||||
#catalogueRouteBuilder?: UmbModalRouteBuilder;
|
||||
|
||||
#layoutEntries = new UmbArrayState<UmbBlockGridLayoutModel>([], (x) => x.contentUdi);
|
||||
layoutEntries = this.#layoutEntries.asObservable();
|
||||
|
||||
setLayoutEntries(layoutEntries: Array<UmbBlockGridLayoutModel>) {
|
||||
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() {}
|
||||
}
|
||||
@@ -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<UmbBlockGridEntryContext>('UmbBlockEntryContext');
|
||||
@@ -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<UmbBlockGridLayoutAreaItemModel>([], (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() {
|
||||
@@ -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<UmbBlockGridContext>('UmbBlockContext');
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './block-grid-entries.context-token.js';
|
||||
export * from './block-grid-entry.context-token.js';
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './workspace/index.js';
|
||||
export * from './context/index.js';
|
||||
export * from './types.js';
|
||||
export * from './workspace/index.js';
|
||||
|
||||
@@ -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<UmbBlockGridTypeModel, BlockLayoutType> {
|
||||
//
|
||||
/*
|
||||
#inlineEditingMode = new UmbBooleanState(undefined);
|
||||
inlineEditingMode = this.#inlineEditingMode.asObservable();
|
||||
//
|
||||
#blockGroups = new UmbArrayState(<Array<UmbBlockTypeGroup>>[], (x) => x.key);
|
||||
public readonly blockGroups = this.#blockGroups.asObservable();
|
||||
|
||||
setInlineEditingMode(inlineEditingMode: boolean | undefined) {
|
||||
this.#inlineEditingMode.setValue(inlineEditingMode ?? false);
|
||||
setBlockGroups(blockGroups: Array<UmbBlockTypeGroup>) {
|
||||
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.
|
||||
|
||||
@@ -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<UmbBlockGridLayoutModel>) {
|
||||
this.#context.setLayoutEntries(value);
|
||||
}
|
||||
public get layoutEntries(): Array<UmbBlockGridLayoutModel> {
|
||||
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<UmbBlockGridLayoutModel> = [];
|
||||
|
||||
@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`<uui-button-inline-create
|
||||
href=${this.#context.getPathForCreateBlock(index) ?? ''}></uui-button-inline-create>
|
||||
<umb-property-editor-ui-block-list-block data-udi=${layoutEntry.contentUdi} .layout=${layoutEntry}>
|
||||
</umb-property-editor-ui-block-list-block> `,
|
||||
)}
|
||||
<uui-button-group>
|
||||
<uui-button
|
||||
id="add-button"
|
||||
look="placeholder"
|
||||
label=${this._createButtonLabel}
|
||||
href=${this.#context.getPathForCreateBlock(-1) ?? ''}></uui-button>
|
||||
<uui-button
|
||||
label=${this.localize.term('content_createFromClipboard')}
|
||||
look="placeholder"
|
||||
href=${this.#context.getPathForClipboard(-1) ?? ''}>
|
||||
<uui-icon name="icon-paste-in"></uui-icon>
|
||||
</uui-button>
|
||||
</uui-button-group>`;
|
||||
//
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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<typeof UMB_BLOCK_CATALOGUE_MODAL.DATA, undefined>;
|
||||
|
||||
@state()
|
||||
private _catalogueRouteBuilder?: UmbModalRouteBuilder;
|
||||
|
||||
@state()
|
||||
private _blocks?: Array<UmbBlockTypeBaseModel>;
|
||||
|
||||
@property({ attribute: false })
|
||||
public set layoutEntries(value: Array<UmbBlockGridLayoutModel>) {
|
||||
this._layoutEntries = value;
|
||||
}
|
||||
public get layoutEntries(): Array<UmbBlockGridLayoutModel> {
|
||||
return this._layoutEntries;
|
||||
}
|
||||
private _layoutEntries: Array<UmbBlockGridLayoutModel> = [];
|
||||
|
||||
@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`<uui-button-inline-create
|
||||
href=${this._catalogueRouteBuilder?.({ view: 'create', index: index }) ?? ''}></uui-button-inline-create>
|
||||
<umb-property-editor-ui-block-list-block data-udi=${layoutEntry.contentUdi} .layout=${layoutEntry}>
|
||||
</umb-property-editor-ui-block-list-block> `,
|
||||
)}
|
||||
<uui-button-group>
|
||||
<uui-button
|
||||
id="add-button"
|
||||
look="placeholder"
|
||||
label=${this._createButtonLabel}
|
||||
href=${createPath ?? ''}></uui-button>
|
||||
<uui-button
|
||||
label=${this.localize.term('content_createFromClipboard')}
|
||||
look="placeholder"
|
||||
href=${this._catalogueRouteBuilder?.({ view: 'clipboard', index: -1 }) ?? ''}>
|
||||
<uui-icon name="icon-paste-in"></uui-icon>
|
||||
</uui-button>
|
||||
</uui-button-group>`;
|
||||
//
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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<UmbBlockTypeBaseModel>;
|
||||
|
||||
@state()
|
||||
private _blockGroups?: Array<UmbBlockTypeGroup>;
|
||||
|
||||
@state()
|
||||
private _rootLayouts: Array<UmbBlockGridLayoutModel> = [];
|
||||
|
||||
@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<Array<UmbBlockTypeBaseModel>>('blocks') ?? [];
|
||||
this._blockGroups = config.getValueByAlias<Array<UmbBlockTypeGroup>>('blockGroups') ?? [];
|
||||
const blocks = config.getValueByAlias<Array<UmbBlockGridTypeModel>>('blocks') ?? [];
|
||||
this.#context.setBlockTypes(blocks);
|
||||
|
||||
const customCreateButtonLabel = config.getValueByAlias<string>('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<Array<UmbBlockTypeGroup>>('blockGroups') ?? [];
|
||||
this.#context.setBlockGroups(blockGroups);
|
||||
|
||||
//const useInlineEditingAsDefault = config.getValueByAlias<boolean>('useInlineEditingAsDefault');
|
||||
|
||||
//this.#context.setInlineEditingMode(useInlineEditingAsDefault);
|
||||
//config.useSingleBlockMode
|
||||
//config.useLiveEditing
|
||||
//config.useInlineEditingAsDefault
|
||||
this.style.maxWidth = config.getValueByAlias<string>('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<UmbBlockGridValueModel> = 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<UmbBlockGridLayoutModel> = [];
|
||||
|
||||
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`<umb-property-editor-ui-block-grid-entries
|
||||
.layoutEntries=${this._rootLayouts}></umb-property-editor-ui-block-grid-entries>`;
|
||||
.layoutEntries=${this._rootLayouts}
|
||||
.parentUnique=${'root'}
|
||||
.areaKey=${'root'}></umb-property-editor-ui-block-grid-entries>`;
|
||||
}
|
||||
|
||||
static styles = [
|
||||
|
||||
@@ -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<number>;
|
||||
allowAtRoot: boolean;
|
||||
@@ -23,6 +24,10 @@ export interface UmbBlockGridGroupTypeConfiguration extends Partial<UmbBlockGrid
|
||||
blocks: Array<UmbBlockTypeWithGroupKey>;
|
||||
}
|
||||
|
||||
// Content models:
|
||||
|
||||
export interface UmbBlockGridValueModel extends UmbBlockValueType<UmbBlockGridLayoutModel> {}
|
||||
|
||||
export interface UmbBlockGridLayoutModel extends UmbBlockLayoutBaseModel {
|
||||
columnSpan: number;
|
||||
rowSpan: number;
|
||||
|
||||
@@ -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`<umb-ref-list-block .label=${this._label}></umb-ref-list-block>`;
|
||||
}
|
||||
@@ -109,7 +94,7 @@ export class UmbPropertyEditorUIBlockListBlockElement extends UmbLitElement impl
|
||||
<uui-icon name="icon-settings"></uui-icon>
|
||||
</uui-button>`
|
||||
: ''}
|
||||
<uui-button label="delete" compact @click=${this.#requestDelete}>
|
||||
<uui-button label="delete" compact @click=${this.#context.requestDelete}>
|
||||
<uui-icon name="icon-remove"></uui-icon>
|
||||
</uui-button>
|
||||
</uui-action-bar>
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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<UmbBlockListEntryContext>('UmbBlockEntryContext');
|
||||
@@ -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
|
||||
> {
|
||||
@@ -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<UmbBlockListContext>('UmbBlockContext');
|
||||
@@ -0,0 +1 @@
|
||||
export * from './block-list-entry.context-token.js';
|
||||
@@ -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';
|
||||
|
||||
@@ -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<UmbBlockListLayoutModel> {}
|
||||
|
||||
const SORTER_CONFIG: UmbSorterConfig<UmbBlockListLayoutModel, UmbPropertyEditorUIBlockListBlockElement> = {
|
||||
getUniqueOfElement: (element) => {
|
||||
return element.getAttribute('data-udi');
|
||||
@@ -94,9 +91,8 @@ export class UmbPropertyEditorUIBlockListElement extends UmbLitElement implement
|
||||
|
||||
const useInlineEditingAsDefault = config.getValueByAlias<boolean>('useInlineEditingAsDefault');
|
||||
this.#context.setInlineEditingMode(useInlineEditingAsDefault);
|
||||
//config.useSingleBlockMode
|
||||
//config.useLiveEditing
|
||||
//config.useInlineEditingAsDefault
|
||||
// TODO:
|
||||
//config.useSingleBlockMode, not done jey
|
||||
this.style.maxWidth = config.getValueByAlias<string>('maxPropertyWidth') ?? '';
|
||||
|
||||
this.#context.setEditorConfiguration(config);
|
||||
|
||||
@@ -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<UmbBlockListLayoutModel> {}
|
||||
|
||||
@@ -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, BlockManagerContextType>,
|
||||
BlockManagerContextType extends UmbBlockManagerContext<BlockType, BlockLayoutType>,
|
||||
BlockType extends UmbBlockTypeBaseModel = UmbBlockTypeBaseModel,
|
||||
BlockLayoutType extends UmbBlockLayoutBaseModel = UmbBlockLayoutBaseModel,
|
||||
> extends UmbContextBase<
|
||||
UmbBlockContext<BlockManagerContextTokenType, BlockManagerContextType, BlockType, BlockLayoutType>
|
||||
> {
|
||||
//
|
||||
_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<typeof UMB_BLOCK_MANAGER_CONTEXT, typeof UMB_BLOCK_MANAGER_CONTEXT.TYPE>
|
||||
>('UmbBlockEntryContext');
|
||||
@@ -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<BlockManagerContextType, BlockManagerContextType>,
|
||||
@@ -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<typeof UMB_BLOCK_MANAGER_CONTEXT, typeof UMB_BLOCK_MANAGER_CONTEXT.TYPE>
|
||||
>('UmbBlockContext');
|
||||
>('UmbBlockEntryContext');
|
||||
|
||||
@@ -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<UmbBlockManagerContext> {
|
||||
//
|
||||
#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(<Array<ElementTypeModel>>[], (x) => x.unique);
|
||||
public readonly contentTypes = this.#contentTypes.asObservable();
|
||||
|
||||
@@ -42,6 +47,14 @@ export abstract class UmbBlockManagerContext<
|
||||
#settings = new UmbArrayState(<Array<UmbBlockDataType>>[], (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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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` <test-my-sorter-controller></test-my-sorter-controller> `);
|
||||
});
|
||||
|
||||
// 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...
|
||||
});
|
||||
Reference in New Issue
Block a user