[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:
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user