Skip to content

Commit 2f043ec

Browse files
committed
AC-12692: Widget category tree is not rendered correctly
1 parent 29cd372 commit 2f043ec

File tree

1 file changed

+62
-100
lines changed
  • app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/widget

1 file changed

+62
-100
lines changed

app/code/Magento/Catalog/view/adminhtml/templates/catalog/category/widget/tree.phtml

Lines changed: 62 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88
?>
99

1010
<?php $_divId = 'tree' . $block->getId() ?>
11-
<div id="<?= $block->escapeHtmlAttr($_divId) ?>" class="tree"></div>
11+
<div id="<?= $escaper->escapeHtmlAttr($_divId) ?>" class="tree"></div>
1212
<?php
1313
$isUseMassAction = $block->getUseMassaction() ? 1 : 0;
1414
$isAnchorOnly = $block->getIsAnchorOnly() ? 1 : 0;
15+
1516
$scriptString = <<<script
1617
1718
require(['jquery', 'jquery/jstree/jquery.jstree'], function($) {
@@ -20,42 +21,27 @@ require(['jquery', 'jquery/jstree/jquery.jstree'], function($) {
2021
let useMassAction = {$isUseMassAction};
2122
let isAnchorOnly = {$isAnchorOnly};
2223
let checkedNodes = [];
23-
24-
function addLastNodeProperty(nodes) {
25-
return nodes.map(node => {
26-
return node.children
27-
? { ...node, children: addLastNodeProperty(node.children) }
28-
: { ...node, lastNode: true };
29-
});
30-
}
24+
let anchorNodes = [];
25+
let nonAnchorNodes = [];
3126
3227
function actionBasedOnIsAnchorOnly() {
33-
tree.jstree().get_json('#', { flat: true }).each((node, value) => {
34-
const attrId = node.a_attr.id;
35-
const rootNode = tree.jstree().get_node("#");
36-
const rootId = rootNode.children[0];
37-
38-
if (isAnchorOnly === 1 && node.id === rootId) {
39-
tree.jstree(true).disable_node(node);
40-
} else if (isAnchorOnly === 0 && node.id !== rootId) {
41-
tree.jstree(true).disable_node(node);
42-
}
43-
});
28+
if(isAnchorOnly){
29+
tree.jstree(true).disable_node(nonAnchorNodes);
30+
}else{
31+
tree.jstree(true).disable_node(anchorNodes);
32+
}
4433
}
4534
46-
function handleLoadedTree(e, data) {
35+
function handleLoadedNode(e, data) {
4736
const container = $(e.target).closest('div.chooser_container');
48-
checkedNodes = container.find('input[type="text"].entities').val().split(',').map(item => item.trim());
49-
50-
data.instance.get_json('#', { flat: true }).forEach(nodeId => {
51-
const node = data.instance.get_node(nodeId);
52-
53-
if (checkedNodes.includes(node.id)) {
54-
tree.jstree(true).select_node(node.id);
55-
}
37+
if(container.find('input[type="text"].entities').val() !== ''){
38+
checkedNodes = container.find('input[type="text"].entities').val().split(',').map(item => item.trim());
39+
}
5640
41+
if (data.status) {
42+
tree.jstree(true).select_node(checkedNodes);
5743
actionBasedOnIsAnchorOnly();
58-
});
44+
}
5945
}
6046
6147
function handleChange(e, data) {
@@ -65,18 +51,16 @@ require(['jquery', 'jquery/jstree/jquery.jstree'], function($) {
6551
6652
if (useMassAction) {
6753
const clickedNodeID = data.node.id;
68-
const currentCheckedNodes = data.instance.get_checked();
6954
7055
if (data.action === 'select_node' && !checkedNodes.includes(clickedNodeID)) {
71-
checkedNodes = currentCheckedNodes;
56+
checkedNodes.push(clickedNodeID);
7257
} else if (data.action === 'deselect_node') {
73-
checkedNodes = currentCheckedNodes.filter(nodeID => nodeID !== clickedNodeID);
58+
checkedNodes = checkedNodes.filter(nodeID => nodeID !== clickedNodeID);
7459
}
7560
7661
checkedNodes.sort((a, b) => a - b);
77-
7862
const container = $(e.target).closest('div.chooser_container');
79-
container.find('input[type="text"].entities').val(checkedNodes.join(', '));
63+
container.find('input[type="text"].entities').val(checkedNodes.join(','));
8064
} else {
8165
node = data.node;
8266
node.attributes = node.original;
@@ -85,77 +69,56 @@ require(['jquery', 'jquery/jstree/jquery.jstree'], function($) {
8569
}
8670
}
8771
88-
function getCheckedNodeIds(tree, node) {
89-
if (node.children_d && node.children_d.length > 0) {
90-
const selectChildrenNodes = node.children_d.filter(item => checkedNodes.includes(item));
91-
92-
if (selectChildrenNodes.length > 0) {
93-
tree.jstree(true).select_node(selectChildrenNodes);
72+
function updateChildrenKey(treeJson) {
73+
treeJson.forEach(node => {
74+
if (Array.isArray(node.children) && node.children.length === 0) {
75+
node.children = true;
76+
} else if (Array.isArray(node.children)) {
77+
updateChildrenKey(node.children);
9478
}
95-
}
96-
}
9779
98-
function addLastNodeFlag(treeData) {
99-
if (treeData.children) {
100-
treeData.children.forEach(child => addLastNodeFlag(child));
101-
} else {
102-
treeData.lastNode = true;
103-
}
104-
}
105-
106-
function handleSuccessResponse(response, childNode, data) {
107-
if (response.length > 0) {
108-
response.forEach(newNode => {
109-
addLastNodeFlag(newNode);
110-
111-
// Create the new node and execute node callback
112-
data.instance.create_node(childNode, newNode, 'last', node => {
113-
if (useMassAction) {
114-
if (checkedNodes.includes(node.id)) {
115-
tree.jstree(true).select_node(node.id);
116-
}
117-
getCheckedNodeIds(tree, node);
118-
actionBasedOnIsAnchorOnly();
119-
}
120-
});
121-
});
122-
}
123-
}
124-
125-
function handleOpenNode(e, data) {
126-
let parentNode = data.node;
127-
128-
if (parentNode.children.length > 0) {
129-
let childNode = data.instance.get_node(parentNode.children, false);
130-
131-
// Check if the child node has no children (is not yet loaded)
132-
if (childNode.children && childNode.children.length === 0
133-
&& childNode.original && !childNode.original.lastNode) {
134-
$.ajax({
135-
url: '{$block->escapeJs($block->escapeUrl($block->getLoadTreeUrl()))}',
136-
data: {
137-
id: childNode.original.id,
138-
store: childNode.original.store,
139-
form_key: FORM_KEY
140-
},
141-
dataType: 'json',
142-
success: function (response) {
143-
handleSuccessResponse(response, childNode, data);
144-
},
145-
error: function (jqXHR, status, error) {
146-
console.log(status + ': ' + error + 'Response text:' + jqXHR.responseText);
147-
}
148-
});
80+
if(node.is_anchor === 1){
81+
anchorNodes.push(node.id);
82+
}else{
83+
nonAnchorNodes.push(node.id);
14984
}
150-
}
85+
});
86+
return treeJson;
15187
}
15288
15389
var jstreeConfig = {
15490
core: {
155-
data: addLastNodeProperty({$block->getTreeJson()}),
91+
data: function (obj, callback) {
92+
if(obj.id != '#' && obj.children.length === 0){
93+
let data = {
94+
id: obj.id,
95+
store: obj.original.store,
96+
node: obj.id,
97+
form_key: FORM_KEY
98+
};
99+
100+
$.ajax({
101+
url: '{$block->escapeJs($block->getLoadTreeUrl())}',
102+
type: "POST",
103+
data: data,
104+
dataType: 'json',
105+
success: function (response) {
106+
response = updateChildrenKey(response);
107+
callback.call(this, response);
108+
},
109+
error: function (jqXHR, status, error) {
110+
console.log(status + ': ' + error);
111+
}
112+
});
113+
114+
}else{
115+
let defaultTree = updateChildrenKey({$block->getTreeJson()});
116+
callback.call(this, defaultTree);
117+
}
118+
},
156119
check_callback: true
157120
},
158-
plugins: []
121+
plugins: ['dnd']
159122
};
160123
161124
if (useMassAction) {
@@ -168,18 +131,17 @@ require(['jquery', 'jquery/jstree/jquery.jstree'], function($) {
168131
tree.jstree(jstreeConfig);
169132
170133
if (useMassAction) {
171-
tree.on('loaded.jstree', (e, data) => handleLoadedTree(e, data));
134+
tree.on('load_node.jstree', (e, data) => handleLoadedNode(e, data));
172135
}
173136
174137
tree.on('changed.jstree', (e, data) => handleChange(e, data));
175-
tree.on('open_node.jstree', (e, data) => handleOpenNode(e, data));
176138
});
177139
178140
script;
179141
?>
180142
<?= /* @noEscape */ $secureRenderer->renderStyleAsTag(
181143
'overflow-x: auto;',
182-
'#tree' . $block->escapeJs($block->getId())
144+
'#tree' . $escaper->escapeJs($block->getId())
183145
);
184146
?>
185147
<?= /* @noEscape */ $secureRenderer->renderTag('script', [], $scriptString, false); ?>

0 commit comments

Comments
 (0)