From 0895b8b359a142bdd0d839bd2b2116571be70583 Mon Sep 17 00:00:00 2001 From: "Louis (loco)" Date: Thu, 14 Dec 2023 14:56:44 +0100 Subject: [PATCH] [FIX] website: correctly update carousel thumbnails on image insertion Steps to reproduce the bug: - Add an "Image Gallery" on the website. - Add a new image on the snippet. -> Problem: the thumbnail of the first image of the carousel has been replaced by the new added image. To solve the problem, the triggering of the `image_changed` event has been removed on extra image added. It was introduced by [1] to trigger the re-rendering of the thumbnail when adding a new image on the carousel but was actually useless. Indeed, the mechanism was the same as now; when a new image was added on the carousel, the `website.gallery.slideshow` that already handles the thumbnails was re-rendered. An important thing to note is that the system was also never intercepting this `image_changed` event as it was triggered on an element that was not in the DOM (as it was removed at the `_replaceContent()` call in the `slideshow()` method). However, since [2], the images rendered by the `website.gallery.slideshow` are replaced by the images (or the wrapped anchored images) returned by `_getImgHolderEls`. Therefore, `$newImageToSelect` is part of the DOM and the `image_changed` event is intercepted by the gallery option. As the active carousel item is always the first one of the carousel after a `website.gallery.slideshow` re-rendering, the system changed the thumbnail of the first item with the new added image. [1]: https://github.com/odoo/odoo/commit/85990768592cbdefbb178b5ffa38c1e29b9eeb87 [2]: https://github.com/odoo/odoo/commit/0fd2477d993e822fe6fd4497aace9f746af7a481 task-3736301 closes odoo/odoo#153409 Signed-off-by: Quentin Smetz (qsm) --- .../src/snippets/s_image_gallery/options.js | 8 +---- .../tests/tours/snippet_image_gallery.js | 29 +++++++++++++++++++ addons/website/tests/test_snippets.py | 11 +++++++ 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/addons/website/static/src/snippets/s_image_gallery/options.js b/addons/website/static/src/snippets/s_image_gallery/options.js index 0e7234699acc3..34bde89d87e43 100644 --- a/addons/website/static/src/snippets/s_image_gallery/options.js +++ b/addons/website/static/src/snippets/s_image_gallery/options.js @@ -112,9 +112,8 @@ options.registry.gallery = options.Class.extend({ save: images => { // TODO In master: restore addImages Promise result. this.trigger_up('snippet_edition_request', {exec: () => { - let $newImageToSelect; for (const image of images) { - const $img = $('', { + $('', { class: $images.length > 0 ? $images[0].className : 'img img-fluid d-block ', src: image.src, 'data-index': ++index, @@ -122,15 +121,10 @@ options.registry.gallery = options.Class.extend({ 'data-name': _t('Image'), style: $images.length > 0 ? $images[0].style.cssText : '', }).appendTo($container); - if (!$newImageToSelect) { - $newImageToSelect = $img; - } } if (images.length > 0) { return this._modeWithImageWait('reset', this.getMode()).then(() => { this.trigger_up('cover_update'); - // Triggers the re-rendering of the thumbnail - $newImageToSelect.trigger('image_changed'); }); } }}); diff --git a/addons/website/static/tests/tours/snippet_image_gallery.js b/addons/website/static/tests/tours/snippet_image_gallery.js index 99cee0ea8c37d..6aeab19e166c3 100644 --- a/addons/website/static/tests/tours/snippet_image_gallery.js +++ b/addons/website/static/tests/tours/snippet_image_gallery.js @@ -92,3 +92,32 @@ wTourUtils.registerWebsitePreviewTour("snippet_image_gallery_reorder", { trigger: ".snippet-option-ImageTools we-select:contains('Filter') we-toggler:contains('Blur')", run: () => null, // This is a check. }]); + +wTourUtils.registerWebsitePreviewTour("snippet_image_gallery_thumbnail_update", { + test: true, + url: "/", + edition: true, +}, [ + wTourUtils.dragNDrop({ + id: "s_image_gallery", + name: "Image Gallery", + }), + wTourUtils.clickOnSnippet({ + id: "s_image_gallery", + name: "Image Gallery", + }), + wTourUtils.changeOption("gallery", "we-button[data-add-images]"), +{ + content: "Click on the default image", + trigger: ".o_select_media_dialog img[title='s_default_image.jpg']", +}, + wTourUtils.addMedia(), +{ + content: "Check that the new image has been added", + trigger: "iframe .s_image_gallery:has(img[data-index='3'])", + run: () => null, // This is a check. +}, { + content: "Check that the thumbnail of the first image has not been changed", + trigger: "iframe .s_image_gallery ul.carousel-indicators li:first-child[style='background-image: url(/web/image/website.library_image_08)']", + run: () => null, // This is a check. +}]); diff --git a/addons/website/tests/test_snippets.py b/addons/website/tests/test_snippets.py index 2b8f20908582a..05e3e6f6a9bbc 100644 --- a/addons/website/tests/test_snippets.py +++ b/addons/website/tests/test_snippets.py @@ -110,3 +110,14 @@ def test_drag_and_drop_on_non_editable(self): def test_snippet_image_gallery_reorder(self): self.start_tour("/", "snippet_image_gallery_reorder", login='admin') + + def test_snippet_image_gallery_thumbnail_update(self): + IrAttachment = self.env['ir.attachment'] + base = 'http://%s:%s' % (HOST, config['http_port']) + IrAttachment.create({ + 'public': True, + 'name': 's_default_image.jpg', + 'type': 'url', + 'url': base + '/web/image/website.s_banner_default_image', + }) + self.start_tour('/', 'snippet_image_gallery_thumbnail_update', login='admin')