From 0fd0987994c315ab8a7802fcf948e604316a04d0 Mon Sep 17 00:00:00 2001 From: abd-msyukyu-odoo Date: Tue, 7 Jun 2022 16:26:20 +0000 Subject: [PATCH] [FIX] knowledge: fix move cancel failure in article tree There was an issue when canceling the move of an article from one section to another: a previous move which was not canceled could be undone when it should not have been. Impacted versions: * 15.4+ Steps to reproduce: 1. Have one article (A) in the "workspace" section and one article (B) in the "private" section 2. move (A) into "private", validate the move in the dialog 3. move (B) into "workspace", discard the move in the dialog Current behavior: * (A) is displayed as if it is currently in "workspace" but it is in fact still in "private" Expected behavior: * (A) and (B) should be displayed in the "private" section This commit fixes the problem by manually replacing the article whose move was discarded (B) at its previous position while triggering a "change" event instead of a "cancel" event. The bug is caused by an incorrect implementation of the "cancel" handler in `jquery.mjs.nestedSortable` library. Since this library uses jQuery and it is discontinued, we should consider to reimplement the feature internally in the future. This commit also synchronizes data-attr attributes (parent-id and section) with the hidden value data('attr') from jQuery for consistency. Task-2877766 closes odoo/odoo#93244 X-original-commit: 98aaeb32e04f99c06c75166593e3b89c4aa087df Signed-off-by: Thibault Delavallee (tde) --- .../static/src/js/knowledge_renderers.js | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/addons/knowledge/static/src/js/knowledge_renderers.js b/addons/knowledge/static/src/js/knowledge_renderers.js index dafadca2b37..127e44c59ee 100644 --- a/addons/knowledge/static/src/js/knowledge_renderers.js +++ b/addons/knowledge/static/src/js/knowledge_renderers.js @@ -372,15 +372,44 @@ const KnowledgeArticleFormRenderer = FormRenderer.extend(KnowledgeTreePanelMixin } } $li.data('parent-id', $parent.data('article-id')); + $li.attr('data-parent-id', $parent.data('article-id')); $li.data('category', data.newCategory); + $li.attr('data-category', data.newCategory); let $children = $li.find('.o_article'); $children.each((_, child) => { $(child).data('category', data.newCategory); + $(child).attr('data-category', data.newCategory); }); $sortable.sortable('enable'); }, onReject: () => { - $sortable.sortable('cancel'); + /** + * When a move between two connected nestedSortable + * trees is canceled, more than one operation may be + * undone (library bug). To bypass sortable('cancel'), + * the last moved $item is returned at its original + * location (which may have to be restored too if it was + * cleaned), and a 'change' event is triggered from that + * rectified position for consistency (see the + * nestedSortable library). + */ + const $item = ui.item.data('nestedSortableItem'); + if ($item.domPosition.prev) { + // Restore $item position after its previous sibling + $item.domPosition.prev.after($item.currentItem[0]); + } else { + // Restore $item as the first child of the parent ul + $item.domPosition.parent.prepend($item.currentItem[0]); + if (!$item.domPosition.parent.parentElement) { + // The ul was cleaned from the document since it + // was empty, so it has to be restored too + const offsetParent = $item.offsetParent[0]; + offsetParent.append($item.domPosition.parent); + } + } + // For consistency with the nestedSortable library, + // trigger the 'change' event from the moved $item + $item._trigger('change', null, $item._uiHash()); $sortable.sortable('enable'); this.$('.o_knowledge_empty_info').addClass('d-none'); this.$('.o_knowledge_empty_info:only-child').removeClass('d-none');