app/javascript/components/tree-view/helpers.js
import { Tree } from 'react-wooden-tree';
/**
* Helper
* Changes class to className.
* Sets undefined checkbox to null.
* Moves the key to attr.key.
*/
const normalize = (tree, fn) => tree.map((n) => {
let node = { ...n };
if (node.class) {
node = { ...node, classes: node.class };
delete node.class;
}
// The server cannot send null, just undefined, this is why it is tested as a string.
if (node.state.checked === 'undefined') {
node = { ...node, state: { ...node.state, checked: null } };
} else if (node.state.checked === null) {
node = { ...node, state: { ...node.state, checked: false } };
}
if (node.key) {
node = { ...node, attr: { key: node.key } };
delete node.key;
}
if (node.nodes) {
node = { ...node, nodes: normalize(node.nodes, fn) };
}
return fn ? fn(node) : node;
});
const flatten = (data) => Tree.convertHierarchicalTree(Tree.initHierarchicalTree(data));
// This function adjusts the nodes generated by the TreeBuilder for the usage with TreeView
const convert = (data, { check, select } = {}) => flatten(normalize(
data,
({ state: { checked, selected, ...state } = {}, ...node }) => ({
...node,
state: {
...state,
checked: check ? check(node) : checked,
selected: select ? select(node) : selected,
},
}),
));
/**
* Helper
* Activates the first active node in the tree, which is passed trought the props.
*
* FIXME Delete this function when bakcend is sending data where the initial node is activated,
* or when all the trees calling a reducer if they want to have an activated node at the start.
*/
const activateNode = (tree, doActivate, key) => {
if (!doActivate) {
return tree;
}
let node = Tree.nodeSelector(tree, Tree.nodeSearch(tree, null, 'key', key)[0]);
node = { ...node, state: { ...node.state, selected: true } };
return { ...tree, [node.nodeId]: node };
};
const callBack = (nodeId, type, value, namespace) => ({
nodeId, type, value, namespace,
});
export { convert, activateNode, callBack };