[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) <tde@openerp.com>
This commit is contained in:
abd-msyukyu-odoo
2022-06-13 08:34:59 +02:00
parent 083e35f570
commit 0fd0987994
@@ -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');