Skip to content

Commit 0368be7

Browse files
committed
PB-390: Nested Page Builder content can fail to save when action is performed quickly
- Add an ID to the render to ensure this is the last render
1 parent 4edaa60 commit 0368be7

File tree

4 files changed

+47
-39
lines changed

4 files changed

+47
-39
lines changed

app/code/Magento/PageBuilder/view/adminhtml/web/js/master-format/render/frame.js

Lines changed: 9 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/code/Magento/PageBuilder/view/adminhtml/web/js/stage.js

Lines changed: 16 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/code/Magento/PageBuilder/view/adminhtml/web/ts/js/master-format/render/frame.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@ let lastRenderId: string;
2525
/**
2626
* Debounce the render call, so we don't render until the final request
2727
*/
28-
const debounceRender = _.debounce((message: {stageId: string, tree: TreeItem}) => {
29-
const renderId = mageUtils.uniqueid();
30-
lastRenderId = renderId;
28+
const debounceRender = _.debounce((message: {stageId: string, tree: TreeItem}, renderId: string) => {
3129
render(message).then((output) => {
3230
// Only post the most recent render back to the parent
3331
if (lastRenderId === renderId) {
@@ -58,7 +56,9 @@ export default function listen(config: ConfigInterface) {
5856
portDeferred.resolve(port);
5957
port.onmessage = (messageEvent) => {
6058
if (messageEvent.data.type === "render") {
61-
debounceRender(messageEvent.data.message);
59+
const renderId = mageUtils.uniqueid();
60+
lastRenderId = renderId;
61+
debounceRender(messageEvent.data.message, renderId);
6262
}
6363
if (messageEvent.data.type === "template") {
6464
const message = messageEvent.data.message;
@@ -156,12 +156,10 @@ function render(message: {stageId: string, tree: TreeItem}) {
156156
// Combine this event with our engine waitForRenderFinish to ensure rendering is completed
157157
$.when(engine.waitForFinishRender(), renderFinished).then(() => {
158158
observer.disconnect();
159-
_.defer(() => {
160-
ko.cleanNode(element);
161-
const filtered: JQuery = filterHtml($(element));
162-
const output = decodeAllDataUrlsInString(filtered.html());
163-
resolve(output);
164-
});
159+
ko.cleanNode(element);
160+
const filtered: JQuery = filterHtml($(element));
161+
const output = decodeAllDataUrlsInString(filtered.html());
162+
resolve(output);
165163
});
166164

167165
ko.applyBindingsToNode(

app/code/Magento/PageBuilder/view/adminhtml/web/ts/js/stage.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import $ from "jquery";
77
import ko from "knockout";
88
import events from "Magento_PageBuilder/js/events";
99
import "Magento_PageBuilder/js/resource/jquery/ui/jquery.ui.touch-punch";
10+
import mageUtils from "mageUtils";
1011
import _ from "underscore";
1112
import "./binding/sortable";
1213
import Collection from "./collection";
@@ -40,21 +41,24 @@ export default class Stage {
4041
private template: string = "Magento_PageBuilder/content-type/preview";
4142
private render: Render;
4243
private collection: Collection = new Collection();
44+
private lastRenderId: string;
4345

4446
/**
4547
* Debounce the applyBindings call by 500ms to stop duplicate calls
4648
*
4749
* @type {(() => void) & _.Cancelable}
4850
*/
49-
private applyBindingsDebounce = _.debounce(() => {
51+
private applyBindingsDebounce = _.debounce((renderId: string) => {
5052
this.render.applyBindings(this.rootContainer)
5153
.then((renderedOutput: string) => {
52-
events.trigger(`stage:${ this.id }:masterFormatRenderAfter`, {
53-
value: renderedOutput,
54-
});
55-
this.renderingLocks.forEach((lock) => {
56-
lock.resolve(renderedOutput);
57-
});
54+
if (this.lastRenderId === renderId) {
55+
events.trigger(`stage:${ this.id }:masterFormatRenderAfter`, {
56+
value: renderedOutput,
57+
});
58+
this.renderingLocks.forEach((lock) => {
59+
lock.resolve(renderedOutput);
60+
});
61+
}
5862
}).catch((error: Error) => {
5963
if (error) {
6064
console.error(error);
@@ -133,7 +137,9 @@ export default class Stage {
133137
if (args.stageId === this.id) {
134138
// Create the rendering lock straight away
135139
this.createLock();
136-
this.applyBindingsDebounce();
140+
const renderId = mageUtils.uniqueid();
141+
this.lastRenderId = renderId;
142+
this.applyBindingsDebounce(renderId);
137143
}
138144
});
139145

0 commit comments

Comments
 (0)