Files

135 lines
3.8 KiB
TypeScript

import React from 'react';
import Tree from 'rc-tree';
import { DataNode, EventDataNode } from 'rc-tree/lib/interface';
import { useNavigate } from 'react-router';
import Loading from '../../common/lib/Loading';
import { BrainAtlasType, MultiLang } from '../../config';
import Functions from '../../functions';
import IndexUtil, { INDEX_ID_PUBLIC, Index } from '../lib/IndexUtil';
import styles from './IndexTree.module.css';
interface Props {
lang: MultiLang;
type: BrainAtlasType;
}
const IndexTree: React.FC<Props> = (props) => {
const { lang, type } = props;
const navigate = useNavigate();
const [tree, setTree] = React.useState<DataNode[]>([]);
const [keys, setKeys] = React.useState<string[]>([]);
const [expandedKeys, setExpandedKeys] = React.useState<string[]>([]);
const [selectedKeys, setSelectedKeys] = React.useState<number[]>([]);
React.useEffect(() => {
const tree: DataNode[] = [];
const keys: string[] = [];
const eKeys: string[] = [];
const makeTreeNode = (index: Index, depth: number, func: (node: DataNode) => void): void => {
const title =
Functions.mlang(index.title, lang) +
(index.numOfItems > 0 ? ' (' + index.numOfItems + ')' : '');
IndexUtil.getChildren(type, index.id, (children) => {
if (children.length === 0) {
func({ key: String(index.id), title: title });
} else {
if (depth < 1) {
eKeys.push(String(index.id));
}
keys.push(String(index.id));
const childTreeNodes: DataNode[] = [];
let called = 0;
children.forEach((value: Index) => {
makeTreeNode(value, depth + 1, (cNode) => {
called++;
childTreeNodes.push(cNode);
if (called === children.length) {
func({ key: String(index.id), title: title, children: childTreeNodes });
}
});
});
}
});
};
IndexUtil.get(type, INDEX_ID_PUBLIC, (index) => {
if (index != null) {
makeTreeNode(index, 0, (node) => {
tree.push(node);
setTree(tree);
setKeys(keys);
setExpandedKeys(eKeys);
setSelectedKeys([]);
});
}
});
}, [lang, type]);
const handleClickOpenAll = () => {
setExpandedKeys(keys);
};
const handleClickCloseAll = () => {
setExpandedKeys([]);
};
const handleExpand: (
expandedKeys: React.Key[],
info: {
node: EventDataNode<DataNode>;
expanded: boolean;
nativeEvent: MouseEvent;
},
) => void = (expandedKeys) => {
const keys: string[] = expandedKeys.map((key) => {
return typeof key === 'string' ? key : String(key);
});
setExpandedKeys(keys);
};
const handleSelect: (
selectedKeys: React.Key[],
info: {
event: 'select';
selected: boolean;
node: EventDataNode<DataNode>;
selectedNodes: DataNode[];
nativeEvent: MouseEvent;
},
) => void = (selectedKeys) => {
const selectedKey = selectedKeys.shift() ?? 0;
const key = typeof selectedKey === 'string' ? parseInt(selectedKey, 10) : selectedKey;
const url = IndexUtil.getUrl(type, key);
navigate(url);
setSelectedKeys([]);
};
if (tree.length === 0) {
return <Loading />;
}
return (
<div className={styles.container}>
<button className={styles.formButton} onClick={handleClickOpenAll}>
open all
</button>
<button className={styles.formButton} onClick={handleClickCloseAll}>
close all
</button>
<Tree
className={styles.indexTree}
expandedKeys={expandedKeys}
selectedKeys={selectedKeys}
onExpand={handleExpand}
onSelect={handleSelect}
showIcon={false}
treeData={tree}
/>
</div>
);
};
export default IndexTree;