Tiptap RTE: Undo deleted blocks (#19851)
* RTE: Restore deleted blocks Maintains a state of unused (deleted) blocks, that could be restored later, e.g. with Tiptap RTE's undo action. Fixes #19637 * Updated with @copilot suggestions * Fixes restored block state on variant documents
This commit is contained in:
@@ -10,14 +10,16 @@ import {
|
||||
UMB_VALIDATION_EMPTY_LOCALIZATION_KEY,
|
||||
} from '@umbraco-cms/backoffice/validation';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
import { UmbVariantId } from '@umbraco-cms/backoffice/variant';
|
||||
import { UMB_CONTENT_WORKSPACE_CONTEXT } from '@umbraco-cms/backoffice/content';
|
||||
import { UMB_PROPERTY_CONTEXT, UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property';
|
||||
import type { UmbBlockRteTypeModel } from '@umbraco-cms/backoffice/block-rte';
|
||||
import type { StyleInfo } from '@umbraco-cms/backoffice/external/lit';
|
||||
import type { UmbBlockDataModel } from '@umbraco-cms/backoffice/block';
|
||||
import type { UmbBlockRteLayoutModel, UmbBlockRteTypeModel } from '@umbraco-cms/backoffice/block-rte';
|
||||
import type {
|
||||
UmbPropertyEditorUiElement,
|
||||
UmbPropertyEditorConfigCollection,
|
||||
} from '@umbraco-cms/backoffice/property-editor';
|
||||
import type { StyleInfo } from '@umbraco-cms/backoffice/external/lit';
|
||||
|
||||
export abstract class UmbPropertyEditorUiRteElementBase
|
||||
extends UmbFormControlMixin<UmbPropertyEditorRteValueType | undefined, typeof UmbLitElement, undefined>(UmbLitElement)
|
||||
@@ -127,6 +129,10 @@ export abstract class UmbPropertyEditorUiRteElementBase
|
||||
|
||||
readonly #validationContext = new UmbValidationContext(this);
|
||||
|
||||
readonly #unusedLayoutLookup: Map<string, UmbBlockRteLayoutModel> = new Map();
|
||||
readonly #unusedContentLookup: Map<string, UmbBlockDataModel> = new Map();
|
||||
readonly #unusedSettingsLookup: Map<string, UmbBlockDataModel> = new Map();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
@@ -262,9 +268,72 @@ export abstract class UmbPropertyEditorUiRteElementBase
|
||||
);
|
||||
}
|
||||
|
||||
#setUnusedBlockLookups(unusedLayouts: Array<UmbBlockRteLayoutModel>) {
|
||||
if (unusedLayouts.length) {
|
||||
unusedLayouts.forEach((layout) => {
|
||||
if (layout.contentKey) {
|
||||
this.#unusedLayoutLookup.set(layout.contentKey, layout);
|
||||
|
||||
const contentBlock = this.#managerContext.getContentOf(layout.contentKey);
|
||||
if (contentBlock) {
|
||||
this.#unusedContentLookup.set(layout.contentKey, contentBlock);
|
||||
} else {
|
||||
console.warn(
|
||||
`Expected content block for '${layout.contentKey}' was not found. This may indicate a data consistency issue.`,
|
||||
);
|
||||
}
|
||||
|
||||
if (layout.settingsKey) {
|
||||
const settingsBlock = this.#managerContext.getSettingsOf(layout.settingsKey);
|
||||
if (settingsBlock) {
|
||||
this.#unusedSettingsLookup.set(layout.settingsKey, settingsBlock);
|
||||
} else {
|
||||
console.warn(
|
||||
`Expected settings block for '${layout.settingsKey}' was not found. This may indicate a data consistency issue.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#restoreUnusedBlocks(usedContentKeys: Array<string | null>) {
|
||||
if (usedContentKeys.length) {
|
||||
usedContentKeys.forEach((contentKey) => {
|
||||
if (contentKey && this.#unusedLayoutLookup.has(contentKey)) {
|
||||
const layout = this.#unusedLayoutLookup.get(contentKey);
|
||||
if (layout) {
|
||||
this.#managerContext.setOneLayout(layout);
|
||||
this.#unusedLayoutLookup.delete(contentKey);
|
||||
|
||||
const contentBlock = this.#unusedContentLookup.get(contentKey);
|
||||
if (contentBlock) {
|
||||
this.#managerContext.setOneContent(contentBlock);
|
||||
this.#managerContext.setOneExpose(contentKey, UmbVariantId.CreateInvariant());
|
||||
this.#unusedContentLookup.delete(contentKey);
|
||||
}
|
||||
|
||||
if (layout.settingsKey && this.#unusedSettingsLookup.has(layout.settingsKey)) {
|
||||
const settingsBlock = this.#unusedSettingsLookup.get(layout.settingsKey);
|
||||
if (settingsBlock) {
|
||||
this.#managerContext.setOneSettings(settingsBlock);
|
||||
this.#unusedSettingsLookup.delete(layout.settingsKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected _filterUnusedBlocks(usedContentKeys: (string | null)[]) {
|
||||
const unusedLayouts = this.#managerContext.getLayouts().filter((x) => usedContentKeys.indexOf(x.contentKey) === -1);
|
||||
|
||||
// Temporarily set the unused layouts to the lookup, as they could be restored later, e.g. via an RTE undo action. [LK]
|
||||
this.#restoreUnusedBlocks(usedContentKeys);
|
||||
this.#setUnusedBlockLookups(unusedLayouts);
|
||||
|
||||
const unusedContentKeys = unusedLayouts.map((x) => x.contentKey);
|
||||
|
||||
const unusedSettingsKeys = unusedLayouts
|
||||
@@ -279,4 +348,11 @@ export abstract class UmbPropertyEditorUiRteElementBase
|
||||
protected _fireChangeEvent() {
|
||||
this.dispatchEvent(new UmbChangeEvent());
|
||||
}
|
||||
|
||||
override destroy() {
|
||||
super.destroy();
|
||||
this.#unusedLayoutLookup.clear();
|
||||
this.#unusedContentLookup.clear();
|
||||
this.#unusedSettingsLookup.clear();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user