react-antd-admin-panel
Version:
Easy prototyping admin panel using React and Antd
210 lines • 8.56 kB
JavaScript
import React, { useEffect, useState } from "react";
import { Tree as TreeAnt, Col } from 'antd';
import { debounce, } from "../../typescript";
import { DownOutlined } from "@ant-design/icons/lib";
import TreeItem from './TreeItem';
const Tree = (props) => {
// The tree-model created in /views/*.tsx
let model = props.model;
let root = (() => {
let root = model._default;
root.get(model._getOnChild(root));
return [root];
})();
const [loadedKeys, setLoadedKeys] = useState([]);
const [expandedKeys, setExpandedKeys] = useState([]);
const [selectedKeys, setSelectedKeys] = useState([]);
const [tree, setTree] = useState();
/** ===================================================== */
const getKeysOfChildren = (item) => {
let arr = [];
let iterate = (el, ignore = false) => {
if (!ignore)
arr.push(el.key);
el.children.forEach((r) => iterate(r));
};
iterate(item, true);
return arr;
};
const getItemFromKey = (el, key) => {
let item = undefined;
el.children.forEach(r => {
if (r.key === key) {
item = r;
}
else {
let temp = getItemFromKey(r, key);
if (temp)
item = temp;
}
});
return item;
};
// 3.1
const expandNode = (expandedKeys, event) => {
if (loadedKeys.includes(event.node.key) && event.expanded) {
let keysOfChildren = getKeysOfChildren(event.node);
let nextLoadedKeys = loadedKeys.filter((r) => !keysOfChildren.includes(r));
setLoadedKeys(nextLoadedKeys);
fetchChildren(event.node.key, () => setAndStoreExpandedKeys(expandedKeys));
}
else {
setAndStoreExpandedKeys(expandedKeys);
}
};
// 3.
// Expand and shot edit on select
const selectNode = (selectedKeys, event, ignoreFetch = false) => {
var _a;
setAndStoreSelectedKeys(selectedKeys);
if (selectedKeys.length && event.node._canBeEdited) {
props.main._setSiderRightLoading(true);
model.editBuild(event.node, (sectionEdit) => {
props.main._setSiderRight(sectionEdit);
props.main._setSiderRightLoading(false);
}, props.main, model);
}
else {
props.main._setSiderRightClose();
}
if (!ignoreFetch &&
!((_a = model._getOnChildIgnoreIf) === null || _a === void 0 ? void 0 : _a.call(model, event.node)) &&
selectedKeys.length &&
!expandedKeys.includes(selectedKeys[0])) {
let keysOfChildren = getKeysOfChildren(event.node);
let nextLoadedKeys = loadedKeys.filter(r => !keysOfChildren.includes(r));
setLoadedKeys(nextLoadedKeys);
fetchChildren(selectedKeys[0], () => {
setLoadedKeys(loadedKeys.concat(selectedKeys[0]));
if (!expandedKeys.includes(selectedKeys[0])) {
setAndStoreExpandedKeys(expandedKeys.concat(selectedKeys[0]));
}
});
}
};
// 2.1
// Fetch children for a given key.
const fetchChildren = (key, next) => {
const complete = debounce((children) => {
setTree(drawTreeItems(root));
children.forEach((r) => {
if (selectedKeys.includes(r.key)) {
props.main._setSiderRightLoading(true);
model.editBuild(r, (sectionEdit) => {
props.main._setSiderRight(sectionEdit);
props.main._setSiderRightLoading(false);
}, props.main, model);
}
});
next();
}, 150, false);
const iterate = (children, key) => {
children.forEach((item) => {
if (key === item.key) {
item.onThen((r, children) => {
item.children = children.map((n) => n.get(model._getOnChild(n)));
if (!item.children.length)
item.leaf();
// @ts-ignore
complete(item.children);
});
item.fetch();
}
else if (item.children.length) {
iterate(item.children, key);
}
});
};
iterate(tree, key);
};
// 2.
// Load when a key should expand
const loadChildren = ({ key, children }) => {
return new Promise((next) => {
if (children && children.length) {
next();
return;
}
else {
fetchChildren(key, next);
}
});
};
// 1.
// Draws titles on the items.
const drawTreeItems = (items, parent = undefined) => {
return items.filter((r) => r._show).map(item => {
// Set the ReactNode
item.title = React.createElement(TreeItem, { parent: model, model: item });
item.parent(parent);
// Recursive call draw on children.
if (item.children.length) {
item.children = drawTreeItems(item.children, item);
}
return item;
});
};
const setAndStoreExpandedKeys = (value) => {
var _a;
setExpandedKeys(value);
try {
window.localStorage.setItem(`expandedKeys:${(_a = props.main.Store.cycle) === null || _a === void 0 ? void 0 : _a._path._actualPath}`, JSON.stringify(value));
}
catch (e) { }
};
const setAndStoreSelectedKeys = (value) => {
var _a;
setSelectedKeys(value);
try {
window.localStorage.setItem(`selectedKeys:${(_a = props.main.Store.cycle) === null || _a === void 0 ? void 0 : _a._path._actualPath}`, JSON.stringify(value));
}
catch (e) { }
};
model.selectNode = (key) => {
let item = getItemFromKey(tree[0], key);
if (item)
selectNode(item ? [item.key] : [], { node: item });
};
model.reloadLocal = (item) => {
if (item.key !== 0 && !item._parent)
return;
let prevExpandedKeys = [...expandedKeys];
let nextExpandedKeys;
let node;
if (item.key === 0) {
node = item;
nextExpandedKeys = expandedKeys.filter(r => r !== 0);
}
else {
node = item._parent;
nextExpandedKeys = expandedKeys.filter(r => r !== item.key && r !== item._parent.key);
}
expandNode(nextExpandedKeys, { expanded: false, node: node });
setTimeout(() => {
expandNode(prevExpandedKeys, { expanded: true, node: node });
}, 200);
};
useEffect(() => {
var _a, _b;
setTree(root[0] ? drawTreeItems(root) : []);
let expandedKeys = [root[0].key];
let selectedKeys = [root[0].key];
if (model.env.cacheTree) {
try {
let storedExpandedKeys = window.localStorage.getItem(`expandedKeys:${(_a = props.main.Store.cycle) === null || _a === void 0 ? void 0 : _a._path._actualPath}`);
let storedSelectedKeys = window.localStorage.getItem(`selectedKeys:${(_b = props.main.Store.cycle) === null || _b === void 0 ? void 0 : _b._path._actualPath}`);
if (storedExpandedKeys)
expandedKeys = JSON.parse(storedExpandedKeys);
if (storedSelectedKeys)
selectedKeys = JSON.parse(storedSelectedKeys);
}
catch (e) { }
}
setAndStoreExpandedKeys(expandedKeys);
setAndStoreSelectedKeys(selectedKeys);
}, []);
return (React.createElement(Col, null,
React.createElement(TreeAnt, { loadData: loadChildren, treeData: tree, onSelect: selectNode, onExpand: expandNode, selectedKeys: selectedKeys, onLoad: setLoadedKeys, loadedKeys: loadedKeys, expandedKeys: expandedKeys, switcherIcon: React.createElement(DownOutlined, { style: { fontSize: 12, opacity: 0.5 } }), showLine: { showLeafIcon: false } })));
};
export default Tree;
//# sourceMappingURL=Tree.js.map