Skip to content

Commit

Permalink
Hotfix: unnecessary Discard Changes dialog for RTEs (#17692)
Browse files Browse the repository at this point in the history
* remove code duplication

* remove unused code

* allow value to be undefined

* dot not build model if we have no markup

* do update the layout value if we don't get any layouts

* reset internals if there are no value

* clear value if tiny mce doesn't have any markup

* clear value if tip tap doesn't have any markup

* add method to check if tip tap element is empty

* use method to check for empty tip tap
  • Loading branch information
madsrasmussen authored Dec 2, 2024
1 parent ceafa83 commit 8141b6b
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import type {
import {
UmbBlockRteEntriesContext,
UmbBlockRteManagerContext,
type UmbBlockRteLayoutModel,
type UmbBlockRteTypeModel,
} from '@umbraco-cms/backoffice/block-rte';
import { UMB_PROPERTY_CONTEXT, UMB_PROPERTY_DATASET_CONTEXT } from '@umbraco-cms/backoffice/property';
import type { UmbBlockValueType } from '@umbraco-cms/backoffice/block';

// eslint-disable-next-line local-rules/enforce-element-suffix-on-element-class-name
export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement implements UmbPropertyEditorUiElement {
Expand All @@ -35,6 +37,16 @@ export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement im
},
})
public set value(value: UmbPropertyEditorUiValueType | undefined) {
if (!value) {
this._value = undefined;
this._markup = '';
this.#managerContext.setLayouts([]);
this.#managerContext.setContents([]);
this.#managerContext.setSettings([]);
this.#managerContext.setExposes([]);
return;
}

const buildUpValue: Partial<UmbPropertyEditorUiValueType> = value ? { ...value } : {};
buildUpValue.markup ??= '';
buildUpValue.blocks ??= { layout: {}, contentData: [], settingsData: [], expose: [] };
Expand Down Expand Up @@ -69,10 +81,7 @@ export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement im
protected _config?: UmbPropertyEditorConfigCollection;

@state()
protected _value: UmbPropertyEditorUiValueType = {
markup: '',
blocks: { layout: {}, contentData: [], settingsData: [], expose: [] },
};
protected _value?: UmbPropertyEditorUiValueType | undefined;

/**
* Separate state for markup, to avoid re-rendering/re-setting the value of the Tiptap editor when the value does not really change.
Expand Down Expand Up @@ -127,49 +136,30 @@ export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement im

// Observe the value of the property and update the editor value.
this.observe(this.#managerContext.layouts, (layouts) => {
this._value = {
...this._value,
blocks: { ...this._value.blocks, layout: { [UMB_BLOCK_RTE_PROPERTY_EDITOR_SCHEMA_ALIAS]: layouts } },
};
this._fireChangeEvent();
const blocksValue =
this._value && layouts?.length > 0
? { ...this._value.blocks, layout: { [UMB_BLOCK_RTE_PROPERTY_EDITOR_SCHEMA_ALIAS]: layouts } }
: undefined;

this.#setBlocksValue(blocksValue);
});

this.observe(this.#managerContext.contents, (contents) => {
this._value = { ...this._value, blocks: { ...this._value.blocks, contentData: contents } };
this._fireChangeEvent();
const blocksValue = this._value ? { ...this._value.blocks, contentData: contents } : undefined;
this.#setBlocksValue(blocksValue);
});

this.observe(this.#managerContext.settings, (settings) => {
this._value = { ...this._value, blocks: { ...this._value.blocks, settingsData: settings } };
this._fireChangeEvent();
const blocksValue = this._value ? { ...this._value.blocks, settingsData: settings } : undefined;
this.#setBlocksValue(blocksValue);
});

this.observe(this.#managerContext.exposes, (exposes) => {
this._value = { ...this._value, blocks: { ...this._value.blocks, expose: exposes } };
this._fireChangeEvent();
const blocksValue = this._value ? { ...this._value.blocks, expose: exposes } : undefined;
this.#setBlocksValue(blocksValue);
});

// The above could potentially be replaced with a single observeMultiple call, but it is not done for now to avoid potential issues with the order of the updates.
/*this.observe(
observeMultiple([
this.#managerContext.layouts,
this.#managerContext.contents,
this.#managerContext.settings,
this.#managerContext.exposes,
]).pipe(debounceTime(20)),
([layouts, contents, settings, exposes]) => {
this._value = {
...this._value,
blocks: {
layout: { [UMB_BLOCK_RTE_PROPERTY_EDITOR_SCHEMA_ALIAS]: layouts },
contentData: contents,
settingsData: settings,
expose: exposes,
},
};
this._fireChangeEvent();
},
'motherObserver',
);*/
});

this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, (context) => {
this.#managerContext.setVariantId(context.getVariantId());
});
Expand All @@ -191,6 +181,19 @@ export abstract class UmbPropertyEditorUiRteElementBase extends UmbLitElement im
});
}

#setBlocksValue(blocksValue?: UmbBlockValueType<UmbBlockRteLayoutModel>) {
if (!blocksValue || !this._value) {
return;
}

this._value = {
...this._value,
blocks: blocksValue,
};

this._fireChangeEvent();
}

protected _fireChangeEvent() {
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ export class UmbPropertyEditorUITinyMceElement extends UmbPropertyEditorUiRteEle
#onChange(event: CustomEvent & { target: UmbInputTinyMceElement }) {
const value = typeof event.target.value === 'string' ? event.target.value : '';

// If we don't get any markup clear the property editor value.
if (value === '') {
this.value = undefined;
this._fireChangeEvent();
return;
}

// Clone the DOM, to remove the classes and attributes on the original:
const div = document.createElement('div');
div.innerHTML = value;
Expand All @@ -38,10 +45,12 @@ export class UmbPropertyEditorUITinyMceElement extends UmbPropertyEditorUiRteEle

this._latestMarkup = markup;

this._value = {
...this._value,
markup: markup,
};
this._value = this._value
? {
...this._value,
markup: markup,
}
: undefined;

this._fireChangeEvent();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ export class UmbInputTiptapElement extends UmbFormControlMixin<string, typeof Um
await Promise.all([await this.#loadExtensions(), await this.#loadEditor()]);
}

/**
* Checks if the editor is empty.
* @returns {boolean}
*/
public isEmpty(): boolean {
return this._editor.isEmpty;
}

async #loadExtensions() {
await new Promise<void>((resolve) => {
this.observe(umbExtensionsRegistry.byType('tiptapExtension'), async (manifests) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,15 @@ const elementName = 'umb-property-editor-ui-tiptap';
@customElement(elementName)
export class UmbPropertyEditorUiTiptapElement extends UmbPropertyEditorUiRteElementBase {
#onChange(event: CustomEvent & { target: UmbInputTiptapElement }) {
const value = event.target.value;
const tipTapElement = event.target;
const value = tipTapElement.value;

// If we don't get any markup clear the property editor value.
if (tipTapElement.isEmpty()) {
this.value = undefined;
this._fireChangeEvent();
return;
}

// Remove unused Blocks of Blocks Layout. Leaving only the Blocks that are present in Markup.
const usedContentKeys: string[] = [];
Expand All @@ -32,10 +40,12 @@ export class UmbPropertyEditorUiTiptapElement extends UmbPropertyEditorUiRteElem

this._latestMarkup = value;

this._value = {
...this._value,
markup: this._latestMarkup,
};
this._value = this._value
? {
...this._value,
markup: this._latestMarkup,
}
: undefined;

this._fireChangeEvent();
}
Expand Down

0 comments on commit 8141b6b

Please sign in to comment.