UNPKG

react-antd-admin-panel

Version:

Easy prototyping admin panel using React and Antd

210 lines 8.56 kB
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