mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 05:40:31 +00:00
117 lines
2.3 KiB
JavaScript
117 lines
2.3 KiB
JavaScript
|
|
export default class NestedSet {
|
|
/**
|
|
* Constructor method.
|
|
* @param {Object} options -
|
|
*/
|
|
constructor(items, options) {
|
|
this.options = {
|
|
parentId: 'parent_id',
|
|
id: 'id',
|
|
...options,
|
|
};
|
|
this.items = items || [];
|
|
this.tree = this.linkChildren();
|
|
}
|
|
|
|
setItems(items) {
|
|
this.items = items;
|
|
this.tree = this.linkChildren();
|
|
}
|
|
|
|
/**
|
|
* Link nodes children.
|
|
*/
|
|
linkChildren() {
|
|
if (this.items.length <= 0) return false;
|
|
|
|
const map = {};
|
|
this.items.forEach((item) => {
|
|
map[item.id] = item;
|
|
map[item.id].children = {};
|
|
});
|
|
|
|
this.items.forEach((item) => {
|
|
const parentNodeId = item[this.options.parentId];
|
|
if (parentNodeId) {
|
|
map[parentNodeId].children[item.id] = item;
|
|
}
|
|
});
|
|
return map;
|
|
}
|
|
|
|
toArray() {
|
|
const stack = [];
|
|
const treeNodes = this.items.map((i) => ({ ...i }));
|
|
|
|
const walk = (nodes) => {
|
|
nodes.forEach((node) => {
|
|
if (!node[this.options.parentId]) {
|
|
stack.push(node);
|
|
}
|
|
if (node.children) {
|
|
const childrenNodes = Object.values(node.children)
|
|
.map((i) => ({ ...i }));
|
|
|
|
node.children = childrenNodes;
|
|
walk(childrenNodes);
|
|
}
|
|
});
|
|
};
|
|
walk(treeNodes);
|
|
return stack;
|
|
}
|
|
|
|
getTree() {
|
|
return this.tree;
|
|
}
|
|
|
|
getElementById(id) {
|
|
return this.tree[id] || null
|
|
}
|
|
|
|
getParents(id) {
|
|
const item = this.getElementById(id);
|
|
const parents = [];
|
|
let index = 0;
|
|
|
|
const walk = (_item) => {
|
|
if (!item) return;
|
|
|
|
if (index) {
|
|
parents.push(_item);
|
|
}
|
|
if (_item[this.options.parentId]) {
|
|
const parentItem = this.getElementById(_item[this.options.parentId]);
|
|
|
|
index++;
|
|
walk(parentItem);
|
|
}
|
|
};
|
|
walk(item);
|
|
return parents;
|
|
}
|
|
|
|
toFlattenArray(nodeMapper) {
|
|
const flattenTree = [];
|
|
|
|
const traversal = (nodes, parentNode) => {
|
|
nodes.forEach((node) => {
|
|
let nodeMapped = node;
|
|
|
|
if (typeof nodeMapper === 'function') {
|
|
nodeMapped = nodeMapper(nodeMapped, parentNode);
|
|
}
|
|
flattenTree.push(nodeMapped);
|
|
|
|
if (node.children && node.children.length > 0) {
|
|
traversal(node.children, node);
|
|
}
|
|
});
|
|
};
|
|
traversal(this.collection);
|
|
|
|
return flattenTree;
|
|
}
|
|
}
|