[FIX] web_editor: stop media-dialog from loading all db attachments

Before this commit, the media-dialog was reading all attachments that
matched certain criteria for each tab. On large databases, this results
in the search_read call timing out, preventing the media-dialog from
opening and making all images and documents un-editable.

One unfortunate consequence of this is that we can no longer use the
firstFilter and lastFilter features, as those rely on fetching all
records and sorting them client-side, as such, this feature has been
removed entirely.

task-2198527
closes https://github.com/odoo/odoo/issues/43113

closes odoo/odoo#46895

X-original-commit: 1e91a89b78ff6019c6120c73ea1eab09b3d58d2f
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
Samuel Degueldre
2020-03-04 14:31:06 +00:00
parent 67868583ac
commit 4e14151465
5 changed files with 44 additions and 61 deletions
@@ -421,7 +421,6 @@ eventHandler.modules.imageDialog.showImageDialog = function ($editable) {
$editable: $editable,
media: media,
options: {
lastFilters: ['background'],
onUpload: $editable.data('callbacks').onUpload,
noVideos:
$editable.data('oe-model') === "mail.compose.message" ||
@@ -1133,7 +1133,6 @@ const ImagepickerUserValueWidget = UserValueWidget.extend({
start: async function () {
await this._super(...arguments);
const allowedSelector = this.el.dataset.allowVideos;
this.firstFilters = (this.el.dataset.firstFilters || '').split(',').filter(s => s !== '');
this.allowVideos = allowedSelector ? this.$target.is(allowedSelector) : false;
this.editImageButton = document.createElement('we-button');
@@ -1190,7 +1189,6 @@ const ImagepickerUserValueWidget = UserValueWidget.extend({
isForBgVideo: true,
res_model: $editable.data('oe-model'),
res_id: $editable.data('oe-id'),
firstFilters: this.firstFilters,
}, dummyEl).open();
mediaDialog.on('save', this, data => {
if (data.bgVideoSrc) {
@@ -139,8 +139,6 @@ var FileWidget = SearchableMediaWidget.extend({
this.numberOfAttachmentsToDisplay = this.NUMBER_OF_ATTACHMENTS_TO_DISPLAY;
this.options = _.extend({
firstFilters: [],
lastFilters: [],
showQuickUpload: config.isDebug(),
}, options || {});
@@ -149,17 +147,6 @@ var FileWidget = SearchableMediaWidget.extend({
this._onUploadURLButtonClick = dom.makeAsyncHandler(this._onUploadURLButtonClick);
},
/**
* Loads all the existing images related to the target media.
*
* @override
*/
willStart: function () {
return Promise.all([
this._super.apply(this, arguments),
this.search('', true)
]);
},
/**
* @override
*/
@@ -176,8 +163,6 @@ var FileWidget = SearchableMediaWidget.extend({
this.$urlError = this.$('.o_we_url_error');
this.$errorText = this.$('.o_we_error_text');
this._renderImages();
// If there is already an attachment on the target, select by default
// that attachment if it is among the loaded images.
var o = {
@@ -190,13 +175,15 @@ var FileWidget = SearchableMediaWidget.extend({
o.url = this.$media.attr('href').replace(/[?].*/, '');
o.id = +o.url.match(/\/web\/content\/(\d+)/, '')[1];
}
if (o.url) {
self._selectAttachement(_.find(self.attachments, function (attachment) {
return attachment.url === o.url;
}) || o);
}
return def;
return this.search('').then(function () {
if (o.url) {
self._selectAttachement(_.find(self.attachments, function (attachment) {
return attachment.url === o.url;
}) || o);
}
return def;
});
},
//--------------------------------------------------------------------------
@@ -216,40 +203,35 @@ var FileWidget = SearchableMediaWidget.extend({
* @override
* @param {boolean} noRender: if true, do not render the found attachments
*/
search: function (needle, noRender) {
search: function (needle) {
var self = this;
this.attachments = [];
this.needle = needle;
return this.fetchAttachments(this.NUMBER_OF_ATTACHMENTS_TO_DISPLAY, 0).then(function () {
self._renderImages();
});
},
/**
* @param {Number} number - the number of attachments to fetch
* @param {Number} offset - from which result to start fetching
*/
fetchAttachments: function (number, offset) {
return this._rpc({
model: 'ir.attachment',
method: 'search_read',
args: [],
kwargs: {
domain: this._getAttachmentsDomain(needle),
domain: this._getAttachmentsDomain(this.needle),
fields: ['name', 'mimetype', 'checksum', 'url', 'type', 'res_id', 'res_model', 'public', 'access_token', 'image_src', 'image_width', 'image_height'],
order: [{name: 'id', asc: false}],
context: this.options.context,
// Try to fetch first record of next page just to know whether there is a next page.
limit: number + 1,
offset: offset,
},
}).then(function (attachments) {
self.attachments = _.chain(attachments)
.sortBy(function (r) {
if (_.any(self.options.firstFilters, function (filter) {
var regex = new RegExp(filter, 'i');
return r.name && r.name.match(regex);
})) {
return -1;
}
if (_.any(self.options.lastFilters, function (filter) {
var regex = new RegExp(filter, 'i');
return r.name && r.name.match(regex);
})) {
return 1;
}
return 0;
})
.value();
if (!noRender) {
self._renderImages();
}
}).then(attachments => {
this.attachments = this.attachments.slice();
Array.prototype.splice.apply(this.attachments, [offset, attachments.length].concat(attachments));
});
},
@@ -354,13 +336,15 @@ var FileWidget = SearchableMediaWidget.extend({
* @returns {Promise}
*/
_loadMoreImages: function (forceSearch) {
this.numberOfAttachmentsToDisplay += 10;
if (!forceSearch) {
this._renderImages();
return Promise.resolve();
} else {
return this.search(this.$('.o_we_search').val() || '');
}
return this.fetchAttachments(10, this.numberOfAttachmentsToDisplay).then(() => {
this.numberOfAttachmentsToDisplay += 10;
if (!forceSearch) {
this._renderImages();
return Promise.resolve();
} else {
return this.search(this.$('.o_we_search').val() || '');
}
});
},
/**
* Opens the image optimize dialog for the given attachment.
@@ -622,7 +606,6 @@ var FileWidget = SearchableMediaWidget.extend({
'data': result.split(',')[1],
'res_id': self.options.res_id,
'res_model': self.options.res_model,
'filters': self.options.firstFilters.join('_'),
};
if (self.quickUpload) {
params['width'] = self._computeOptimizedWidth();
@@ -738,7 +721,6 @@ var FileWidget = SearchableMediaWidget.extend({
'url': this.$urlInput.val(),
'res_id': this.options.res_id,
'res_model': this.options.res_model,
'filters': this.options.firstFilters.join('_'),
},
}).then(function (attachment) {
self.$urlInput.val('');
@@ -146,7 +146,11 @@ widgetsMedia.ImageWidget.include({
* @private
*/
_loadMoreImages: function (forceSearch) {
this._super(this._unsplash.isActive || forceSearch);
if (!this._unsplash.isActive) {
return this._super(forceSearch);
}
this.numberOfAttachmentsToDisplay += 10;
this.search(this.$('.o_we_search').val() || '');
},
/**
* @override
+3 -3
View File
@@ -259,7 +259,7 @@
<div data-js="background" string="Background"
data-selector="section, .parallax, .carousel-item"
data-exclude=".s_hr, .s_image_gallery, .o_gallery .carousel-item">
<we-imagepicker string="Background" data-background="" data-allow-videos=":not(.parallax, .s_parallax_bg)" data-first-filters="background"/>
<we-imagepicker string="Background" data-background="" data-allow-videos=":not(.parallax, .s_parallax_bg)"/>
</div>
<!-- Background Image Size/Position -->
@@ -424,7 +424,7 @@
data-drop-near=".o_mega_menu .nav-link"/>
<div data-js="CoverProperties" data-selector=".o_record_cover_container" data-no-check="true">
<we-imagepicker string="Image" data-background="" data-first-filters="cover" data-name="cover_background_opt"/>
<we-imagepicker string="Image" data-background="" data-name="cover_background_opt"/>
<we-select string="Size" data-cover-opt-name="size">
<we-button data-select-class="o_record_has_cover o_full_screen_height">Full Screen</we-button>
<we-button class="o_record_cover_opt_size_default" data-select-class="o_record_has_cover o_half_screen_height">Half Screen</we-button>
@@ -535,7 +535,7 @@
<we-button data-customize-website="website.option_custom_body_image">Image</we-button>
<we-button data-customize-website="website.option_custom_body_image, website.option_custom_body_pattern">Pattern</we-button>
</we-select>
<we-imagepicker data-dependencies="!no_background_opt" data-customize-body-bg="" data-first-filters="background"/>
<we-imagepicker data-dependencies="!no_background_opt" data-customize-body-bg=""/>
</we-row>
<we-select string="Layout">
<we-button data-customize-website="">Full</we-button>