Merge branch 'v14/fix/create-block-in-workspace' into v14/feature/block-grid-validation
This commit is contained in:
@@ -133,9 +133,30 @@ export class UmbBlockGridEntriesContext
|
||||
blockGroups: this._manager?.getBlockGroups() ?? [],
|
||||
openClipboard: routingInfo.view === 'clipboard',
|
||||
originData: { index: index, areaKey: this.#areaKey, parentUnique: this.#parentUnique },
|
||||
createBlockInWorkspace: true,
|
||||
},
|
||||
};
|
||||
})
|
||||
.onSubmit(async (value, data) => {
|
||||
if (value?.create && data) {
|
||||
const created = await this.create(
|
||||
value.create.contentElementTypeKey,
|
||||
// We can parse an empty object, cause the rest will be filled in by others.
|
||||
{} as any,
|
||||
data.originData as UmbBlockGridWorkspaceOriginData,
|
||||
);
|
||||
if (created) {
|
||||
this.insert(
|
||||
created.layout,
|
||||
created.content,
|
||||
created.settings,
|
||||
data.originData as UmbBlockGridWorkspaceOriginData,
|
||||
);
|
||||
} else {
|
||||
throw new Error('Failed to create block');
|
||||
}
|
||||
}
|
||||
})
|
||||
.observeRouteBuilder((routeBuilder) => {
|
||||
// TODO: Does it make any sense that this is a state? Check usage and confirm. [NL]
|
||||
this._catalogueRouteBuilderState.setValue(routeBuilder);
|
||||
|
||||
@@ -4,7 +4,6 @@ import type { UmbBlockRteLayoutModel, UmbBlockRteTypeModel } from '../types.js';
|
||||
import {
|
||||
UMB_BLOCK_RTE_WORKSPACE_MODAL,
|
||||
type UmbBlockRteWorkspaceOriginData,
|
||||
type UmbBlockRteWorkspaceData,
|
||||
} from '../workspace/block-rte-workspace.modal-token.js';
|
||||
import { UMB_BLOCK_RTE_MANAGER_CONTEXT } from './block-rte-manager.context-token.js';
|
||||
import { UmbBooleanState } from '@umbraco-cms/backoffice/observable-api';
|
||||
@@ -41,9 +40,30 @@ export class UmbBlockRteEntriesContext extends UmbBlockEntriesContext<
|
||||
blockGroups: [],
|
||||
openClipboard: routingInfo.view === 'clipboard',
|
||||
originData: {},
|
||||
createBlockInWorkspace: true,
|
||||
},
|
||||
};
|
||||
})
|
||||
.onSubmit(async (value, data) => {
|
||||
if (value?.create && data) {
|
||||
const created = await this.create(
|
||||
value.create.contentElementTypeKey,
|
||||
// We can parse an empty object, cause the rest will be filled in by others.
|
||||
{} as any,
|
||||
data.originData as UmbBlockRteWorkspaceOriginData,
|
||||
);
|
||||
if (created) {
|
||||
this.insert(
|
||||
created.layout,
|
||||
created.content,
|
||||
created.settings,
|
||||
data.originData as UmbBlockRteWorkspaceOriginData,
|
||||
);
|
||||
} else {
|
||||
throw new Error('Failed to create block');
|
||||
}
|
||||
}
|
||||
})
|
||||
.observeRouteBuilder((routeBuilder) => {
|
||||
this._catalogueRouteBuilderState.setValue(routeBuilder);
|
||||
});
|
||||
@@ -114,10 +134,10 @@ export class UmbBlockRteEntriesContext extends UmbBlockEntriesContext<
|
||||
async create(
|
||||
contentElementTypeKey: string,
|
||||
partialLayoutEntry?: Omit<UmbBlockRteLayoutModel, 'contentUdi'>,
|
||||
modalData?: UmbBlockRteWorkspaceData,
|
||||
originData?: UmbBlockRteWorkspaceOriginData,
|
||||
) {
|
||||
await this._retrieveManager;
|
||||
return this._manager?.create(contentElementTypeKey, partialLayoutEntry, modalData);
|
||||
return this._manager?.create(contentElementTypeKey, partialLayoutEntry, originData);
|
||||
}
|
||||
|
||||
// insert Block?
|
||||
@@ -126,10 +146,10 @@ export class UmbBlockRteEntriesContext extends UmbBlockEntriesContext<
|
||||
layoutEntry: UmbBlockRteLayoutModel,
|
||||
content: UmbBlockDataType,
|
||||
settings: UmbBlockDataType | undefined,
|
||||
modalData: UmbBlockRteWorkspaceData,
|
||||
originData: UmbBlockRteWorkspaceOriginData,
|
||||
) {
|
||||
await this._retrieveManager;
|
||||
return this._manager?.insert(layoutEntry, content, settings, modalData) ?? false;
|
||||
return this._manager?.insert(layoutEntry, content, settings, originData) ?? false;
|
||||
}
|
||||
|
||||
// create Block?
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { UmbBlockRteLayoutModel, UmbBlockRteTypeModel } from '../types.js';
|
||||
import type { UmbBlockRteWorkspaceData } from '../index.js';
|
||||
import type { UmbBlockRteWorkspaceOriginData } from '../index.js';
|
||||
import type { UmbBlockDataType } from '../../block/types.js';
|
||||
import type { Editor } from '@umbraco-cms/backoffice/external/tinymce';
|
||||
import { UmbBlockManagerContext } from '@umbraco-cms/backoffice/block';
|
||||
@@ -36,7 +36,7 @@ export class UmbBlockRteManagerContext<
|
||||
partialLayoutEntry?: Omit<BlockLayoutType, 'contentUdi'>,
|
||||
// This property is used by some implementations, but not used in this.
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
originData?: UmbBlockRteWorkspaceData,
|
||||
originData?: UmbBlockRteWorkspaceOriginData,
|
||||
) {
|
||||
const data = super.createBlockData(contentElementTypeKey, partialLayoutEntry);
|
||||
|
||||
@@ -57,13 +57,13 @@ export class UmbBlockRteManagerContext<
|
||||
layoutEntry: BlockLayoutType,
|
||||
content: UmbBlockDataType,
|
||||
settings: UmbBlockDataType | undefined,
|
||||
modalData: UmbBlockRteWorkspaceData,
|
||||
originData: UmbBlockRteWorkspaceOriginData,
|
||||
) {
|
||||
if (!this.#editor) return false;
|
||||
|
||||
this._layouts.appendOne(layoutEntry);
|
||||
|
||||
this.insertBlockData(layoutEntry, content, settings, modalData);
|
||||
this.insertBlockData(layoutEntry, content, settings, originData);
|
||||
|
||||
if (layoutEntry.displayInline) {
|
||||
this.#editor.selection.setContent(
|
||||
|
||||
@@ -21,7 +21,7 @@ export class UmbBlockTypeCardElement extends UmbLitElement {
|
||||
(x) => x.unique,
|
||||
);
|
||||
|
||||
@property({ type: String, attribute: false })
|
||||
@property({ type: String })
|
||||
href?: string;
|
||||
|
||||
@property({ type: String, attribute: false })
|
||||
|
||||
@@ -148,6 +148,10 @@ export abstract class UmbBlockManagerContext<
|
||||
getContentTypeNameOf(contentTypeKey: string) {
|
||||
return this.#contentTypes.getValue().find((x) => x.unique === contentTypeKey)?.name;
|
||||
}
|
||||
getContentTypeHasProperties(contentTypeKey: string) {
|
||||
const properties = this.#contentTypes.getValue().find((x) => x.unique === contentTypeKey)?.properties;
|
||||
return properties ? properties.length > 0 : false;
|
||||
}
|
||||
blockTypeOf(contentTypeKey: string) {
|
||||
return this.#blockTypes.asObservablePart((source) =>
|
||||
source.find((x) => x.contentElementTypeKey === contentTypeKey),
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { UMB_BLOCK_WORKSPACE_MODAL } from '../../workspace/index.js';
|
||||
import type { UmbBlockTypeGroup, UmbBlockTypeWithGroupKey } from '@umbraco-cms/backoffice/block-type';
|
||||
import type { UmbBlockCatalogueModalData, UmbBlockCatalogueModalValue } from '@umbraco-cms/backoffice/block';
|
||||
import {
|
||||
UMB_BLOCK_MANAGER_CONTEXT,
|
||||
type UmbBlockCatalogueModalData,
|
||||
type UmbBlockCatalogueModalValue,
|
||||
} from '@umbraco-cms/backoffice/block';
|
||||
import { css, html, customElement, state, repeat, nothing } from '@umbraco-cms/backoffice/external/lit';
|
||||
import type { UUIInputEvent } from '@umbraco-cms/backoffice/external/uui';
|
||||
import { UMB_MODAL_CONTEXT, UmbModalBaseElement } from '@umbraco-cms/backoffice/modal';
|
||||
@@ -14,8 +18,7 @@ export class UmbBlockCatalogueModalElement extends UmbModalBaseElement<
|
||||
UmbBlockCatalogueModalData,
|
||||
UmbBlockCatalogueModalValue
|
||||
> {
|
||||
//
|
||||
private _search = '';
|
||||
#search = '';
|
||||
|
||||
private _groupedBlocks: Array<{ name?: string; blocks: Array<UmbBlockTypeWithGroupKey> }> = [];
|
||||
|
||||
@@ -28,6 +31,9 @@ export class UmbBlockCatalogueModalElement extends UmbModalBaseElement<
|
||||
@state()
|
||||
private _filtered: Array<{ name?: string; blocks: Array<UmbBlockTypeWithGroupKey> }> = [];
|
||||
|
||||
@state()
|
||||
_manager?: typeof UMB_BLOCK_MANAGER_CONTEXT.TYPE;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
@@ -49,6 +55,10 @@ export class UmbBlockCatalogueModalElement extends UmbModalBaseElement<
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.consumeContext(UMB_BLOCK_MANAGER_CONTEXT, (manager) => {
|
||||
this._manager = manager;
|
||||
});
|
||||
}
|
||||
|
||||
override connectedCallback() {
|
||||
@@ -71,10 +81,10 @@ export class UmbBlockCatalogueModalElement extends UmbModalBaseElement<
|
||||
}
|
||||
|
||||
#updateFiltered() {
|
||||
if (this._search.length === 0) {
|
||||
if (this.#search.length === 0) {
|
||||
this._filtered = this._groupedBlocks;
|
||||
} else {
|
||||
const search = this._search.toLowerCase();
|
||||
const search = this.#search.toLowerCase();
|
||||
this._filtered = this._groupedBlocks.map((group) => {
|
||||
return { ...group, blocks: group.blocks.filter((block) => block.label?.toLocaleLowerCase().includes(search)) };
|
||||
});
|
||||
@@ -82,7 +92,7 @@ export class UmbBlockCatalogueModalElement extends UmbModalBaseElement<
|
||||
}
|
||||
|
||||
#onSearch(e: UUIInputEvent) {
|
||||
this._search = e.target.value as string;
|
||||
this.#search = e.target.value as string;
|
||||
this.#updateFiltered();
|
||||
}
|
||||
|
||||
@@ -98,7 +108,7 @@ export class UmbBlockCatalogueModalElement extends UmbModalBaseElement<
|
||||
override render() {
|
||||
return html`
|
||||
<umb-body-layout headline="${this.localize.term('blockEditor_addBlock')}">
|
||||
${this.#renderViews()} ${this._openClipboard ? this.#renderClipboard() : this.#renderCreateEmpty()}
|
||||
${this.#renderViews()}${this.#renderMain()}
|
||||
<div slot="actions">
|
||||
<uui-button label=${this.localize.term('general_close')} @click=${this._rejectModal}></uui-button>
|
||||
<uui-button
|
||||
@@ -111,6 +121,10 @@ export class UmbBlockCatalogueModalElement extends UmbModalBaseElement<
|
||||
`;
|
||||
}
|
||||
|
||||
#renderMain() {
|
||||
return this._manager ? (this._openClipboard ? this.#renderClipboard() : this.#renderCreateEmpty()) : nothing;
|
||||
}
|
||||
|
||||
#renderClipboard() {
|
||||
return html`Clipboard`;
|
||||
}
|
||||
@@ -140,7 +154,7 @@ export class UmbBlockCatalogueModalElement extends UmbModalBaseElement<
|
||||
.backgroundColor=${block.backgroundColor}
|
||||
.contentElementTypeKey=${block.contentElementTypeKey}
|
||||
@open=${() => this.#chooseBlock(block.contentElementTypeKey)}
|
||||
?href=${this._workspacePath
|
||||
.href=${this._workspacePath && this._manager!.getContentTypeHasProperties(block.contentElementTypeKey)
|
||||
? `${this._workspacePath}create/${block.contentElementTypeKey}`
|
||||
: undefined}>
|
||||
</umb-block-type-card>
|
||||
|
||||
@@ -332,7 +332,7 @@ export class UmbPropertyElement extends UmbLitElement {
|
||||
if ('checkValidity' in this._element) {
|
||||
const dataPath = this.dataPath;
|
||||
this.#controlValidator = new UmbFormControlValidator(this, this._element as any, dataPath);
|
||||
// We trust blindly that the dataPath is available at this stage. [NL]
|
||||
// We trust blindly that the dataPath will be present at this stage and not arrive later than this moment. [NL]
|
||||
if (dataPath) {
|
||||
this.#validationMessageBinder = new UmbBindServerValidationToFormControl(
|
||||
this,
|
||||
|
||||
Reference in New Issue
Block a user