[REF] website, *: automatically refresh widgets on option change
* website, website_mass_mailing Now, when any option method is called (editor left panel), the widgets related to the targeted DOM is automatically updated. This is possible to disable for a specific widget with `data-no-widget-refresh="true"`. This commit also makes the `_refreshPublicWidget` method better handle its async component: it is now "fully async" so the caller should wait for its resolution before executing some other related code.
This commit is contained in:
@@ -1560,11 +1560,36 @@ const SnippetOptionWidget = Widget.extend({
|
||||
*/
|
||||
_handleUserValueEvent: function (ev, previewMode) {
|
||||
ev.stopPropagation();
|
||||
this.trigger_up('snippet_edition_request', {exec: () => {
|
||||
this.trigger_up('snippet_edition_request', {exec: async () => {
|
||||
if (ev.data.prepare) {
|
||||
ev.data.prepare();
|
||||
}
|
||||
return this._select(previewMode, ev.data.widget);
|
||||
|
||||
const widget = ev.data.widget;
|
||||
if (previewMode && (widget.$el.closest('[data-no-preview="true"]').length)) {
|
||||
// TODO the flag should be fetched through widget params somehow
|
||||
return;
|
||||
}
|
||||
|
||||
// Call widget option methods and update $target
|
||||
await this._select(previewMode, widget);
|
||||
|
||||
// Trigger the related events notifying snippet changes
|
||||
let evName = 'snippet-option-reset';
|
||||
if (previewMode === false) {
|
||||
evName = 'snippet-option-change';
|
||||
} else if (previewMode === true) {
|
||||
evName = 'snippet-option-preview';
|
||||
}
|
||||
this.$target.trigger(evName, [this]);
|
||||
this.$target.trigger('content_changed');
|
||||
|
||||
// Update the UI of the correct widgets
|
||||
if (!previewMode) {
|
||||
await this.updateUI(w => !w.isPreviewed() || w === widget);
|
||||
} else {
|
||||
await this.updateUI(w => w !== widget && !w.isPreviewed());
|
||||
}
|
||||
}});
|
||||
},
|
||||
/**
|
||||
@@ -1702,12 +1727,6 @@ const SnippetOptionWidget = Widget.extend({
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_select: async function (previewMode, widget) {
|
||||
if (previewMode && (widget.$el.closest('[data-no-preview="true"]').length)) {
|
||||
// TODO the no-preview flag should be retrieved through widget
|
||||
// params somehow
|
||||
return;
|
||||
}
|
||||
|
||||
// If it is not preview mode, the user selected the option for good
|
||||
// (so record the action)
|
||||
if (!previewMode) {
|
||||
@@ -1730,23 +1749,6 @@ const SnippetOptionWidget = Widget.extend({
|
||||
await this[methodName](previewMode, widgetValue, params);
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger the related events notifying snippet changes
|
||||
let evName = 'snippet-option-reset';
|
||||
if (previewMode === false) {
|
||||
evName = 'snippet-option-change';
|
||||
} else if (previewMode === true) {
|
||||
evName = 'snippet-option-preview';
|
||||
}
|
||||
this.$target.trigger(evName, [this]);
|
||||
this.$target.trigger('content_changed');
|
||||
|
||||
// Update the UI of the correct widgets
|
||||
if (!previewMode) {
|
||||
await this.updateUI(w => !w.isPreviewed() || w === widget);
|
||||
} else {
|
||||
await this.updateUI(w => w !== widget && !w.isPreviewed());
|
||||
}
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -11,21 +11,8 @@ var options = require('web_editor.snippets.options');
|
||||
var _t = core._t;
|
||||
var qweb = core.qweb;
|
||||
|
||||
// TODO should we refresh public widgets for all option changes by default ?
|
||||
options.Class.include({
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Options
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
selectDataAttribute: async function (previewMode, widgetValue, params) {
|
||||
await this._super(...arguments);
|
||||
this._refreshPublicWidgets();
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -35,13 +22,28 @@ options.Class.include({
|
||||
*
|
||||
* @private
|
||||
* @param {jQuery} [$el=this.$target]
|
||||
* @param {Object} [options]
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_refreshPublicWidgets: function ($el, options) {
|
||||
this.trigger_up('widgets_start_request', _.extend({
|
||||
editableMode: true,
|
||||
$target: $el || this.$target,
|
||||
}, options || {}));
|
||||
_refreshPublicWidgets: function ($el) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.trigger_up('widgets_start_request', {
|
||||
editableMode: true,
|
||||
$target: $el || this.$target,
|
||||
onSuccess: resolve,
|
||||
onFailure: reject,
|
||||
});
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_select: async function (previewMode, widget) {
|
||||
await this._super(...arguments);
|
||||
|
||||
if (!widget.$el.closest('[data-no-widget-refresh="true"]').length) {
|
||||
// TODO the flag should be retrieved through widget params somehow
|
||||
await this._refreshPublicWidgets();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -109,7 +111,7 @@ options.registry.background.include({
|
||||
} else {
|
||||
delete target.dataset.bgVideoSrc;
|
||||
}
|
||||
this._refreshPublicWidgets();
|
||||
await this._refreshPublicWidgets();
|
||||
await this.updateUI();
|
||||
},
|
||||
/**
|
||||
@@ -685,16 +687,6 @@ options.registry.layout_column = options.Class.extend({
|
||||
});
|
||||
|
||||
options.registry.parallax = options.Class.extend({
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
var self = this;
|
||||
this.$target.on('snippet-option-change snippet-option-preview', function () {
|
||||
self._refreshPublicWidgets();
|
||||
});
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -965,7 +957,6 @@ options.registry.ul = options.Class.extend({
|
||||
.prepend('<a href="#" class="o_ul_toggle_next fa" />');
|
||||
$li.removeClass('o_open').next().addClass('o_close');
|
||||
this.$target.find('li').removeClass('o_open');
|
||||
this._refreshPublicWidgets();
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1310,7 +1301,6 @@ options.registry.gallery = options.Class.extend({
|
||||
// Apply layout animation
|
||||
this.$target.off('slide.bs.carousel').off('slid.bs.carousel');
|
||||
this.$('li.fa').off('click');
|
||||
this._refreshPublicWidgets();
|
||||
},
|
||||
/**
|
||||
* Allows to change the style of the individual images.
|
||||
@@ -1497,7 +1487,6 @@ options.registry.countdown = options.Class.extend({
|
||||
this.endMessage = $message[0].outerHTML;
|
||||
}
|
||||
}
|
||||
this._refreshPublicWidgets();
|
||||
},
|
||||
/**
|
||||
* Changes the countdown style.
|
||||
@@ -1525,7 +1514,6 @@ options.registry.countdown = options.Class.extend({
|
||||
break;
|
||||
}
|
||||
this.$target[0].dataset.layout = widgetValue;
|
||||
this._refreshPublicWidgets();
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -2162,15 +2150,19 @@ options.registry.InnerChart = options.Class.extend({
|
||||
/**
|
||||
* Set the color on the selected input.
|
||||
*/
|
||||
colorChange: function (previewMode, widgetValue, params) {
|
||||
colorChange: async function (previewMode, widgetValue, params) {
|
||||
if (widgetValue) {
|
||||
this.colorPaletteSelectedInput.dataset[params.attributeName] = widgetValue;
|
||||
} else {
|
||||
delete this.colorPaletteSelectedInput.dataset[params.attributeName];
|
||||
}
|
||||
this._reloadGraph();
|
||||
// To focus back the input that is edited we have to wait for the color picker to be fully reloaded.
|
||||
setTimeout(() => this.lastEditableSelectedInput.focus());
|
||||
await this._reloadGraph();
|
||||
// To focus back the input that is edited we have to wait for the color
|
||||
// picker to be fully reloaded.
|
||||
await new Promise(resolve => setTimeout(() => {
|
||||
this.lastEditableSelectedInput.focus();
|
||||
resolve();
|
||||
}));
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
@@ -2180,7 +2172,7 @@ options.registry.InnerChart = options.Class.extend({
|
||||
// Data might change if going from or to a pieChart.
|
||||
if (params.attributeName === 'type') {
|
||||
this._setDefaultSelectedInput();
|
||||
this._reloadGraph();
|
||||
await this._reloadGraph();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -2203,11 +2195,11 @@ options.registry.InnerChart = options.Class.extend({
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_reloadGraph: function () {
|
||||
_reloadGraph: async function () {
|
||||
const jsonValue = this._matrixToChartData();
|
||||
if (this.$target[0].dataset.data !== jsonValue) {
|
||||
this.$target[0].dataset.data = jsonValue;
|
||||
this._refreshPublicWidgets();
|
||||
await this._refreshPublicWidgets();
|
||||
}
|
||||
},
|
||||
/**
|
||||
@@ -2439,9 +2431,10 @@ options.registry.InnerChart = options.Class.extend({
|
||||
const usedColor = Array.from(this.tableEl.querySelectorAll('tr:first-child input')).map(el => el.dataset.backgroundColor);
|
||||
const color = this.themeArray.filter(el => !usedColor.includes(el))[0] || this._randomColor();
|
||||
this._addColumn(null, null, color, color);
|
||||
this._reloadGraph();
|
||||
this._displayRemoveColButton();
|
||||
this.updateUI();
|
||||
this._reloadGraph().then(() => {
|
||||
this._displayRemoveColButton();
|
||||
this.updateUI();
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Add a column at the end of the matrix and display it's remove button
|
||||
@@ -2450,9 +2443,10 @@ options.registry.InnerChart = options.Class.extend({
|
||||
*/
|
||||
_onAddRowClick: function () {
|
||||
this._addRow();
|
||||
this._reloadGraph();
|
||||
this._displayRemoveRowButton();
|
||||
this.updateUI();
|
||||
this._reloadGraph().then(() => {
|
||||
this._displayRemoveRowButton();
|
||||
this.updateUI();
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Remove the column and show the remove button of the next column or the last if no next.
|
||||
@@ -2467,8 +2461,9 @@ options.registry.InnerChart = options.Class.extend({
|
||||
el.children[cellIndex].remove();
|
||||
});
|
||||
this._displayRemoveColButton(cellIndex - 1);
|
||||
this._reloadGraph();
|
||||
this.updateUI();
|
||||
this._reloadGraph().then(() => {
|
||||
this.updateUI();
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Remove the row and show the remove button of the next row or the last if no next.
|
||||
@@ -2481,8 +2476,9 @@ options.registry.InnerChart = options.Class.extend({
|
||||
const rowIndex = row.rowIndex;
|
||||
row.remove();
|
||||
this._displayRemoveRowButton(rowIndex - 1);
|
||||
this._reloadGraph();
|
||||
this.updateUI();
|
||||
this._reloadGraph().then(() => {
|
||||
this.updateUI();
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
|
||||
@@ -70,11 +70,7 @@ options.registry.newsletter_popup = options.registry.mailing_list_subscribe.exte
|
||||
// So that the snippet is not enabled again by the editor
|
||||
ev.stopPropagation();
|
||||
self.$target.data('quick-open', true);
|
||||
options.onSuccess(new Promise(resolve => {
|
||||
self._refreshPublicWidgets(self.$target, {
|
||||
onSuccess: () => resolve(),
|
||||
});
|
||||
}));
|
||||
options.onSuccess(self._refreshPublicWidgets());
|
||||
});
|
||||
this.$target.on('shown.bs.modal.newsletter_popup_option hide.bs.modal.newsletter_popup_option', function () {
|
||||
self.$target.closest('.o_editable').trigger('content_changed');
|
||||
@@ -118,7 +114,7 @@ options.registry.newsletter_popup = options.registry.mailing_list_subscribe.exte
|
||||
return this._super.apply(this, arguments).then(function () {
|
||||
self.$target.data('quick-open', true);
|
||||
self.$target.removeData('content');
|
||||
self._refreshPublicWidgets();
|
||||
return self._refreshPublicWidgets();
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user