import Tree from 'rc-tree'; import type { DataNode, EventDataNode } from 'rc-tree/lib/interface'; import { type Key, useMemo, useState } from 'react'; import { useNavigate } from 'react-router'; import type { MultiLang } from '../../config'; import Functions from '../../functions'; import IndexUtil, { INDEX_ID_PUBLIC, type Index } from '../lib/IndexUtil'; import styles from './IndexTree.module.css'; interface Props { lang: MultiLang; } interface TreeData { elements: DataNode[]; expandableKeys: string[]; defaultExpandedKeys: string[]; } const load = (lang: MultiLang): TreeData => { const expandableKeys: string[] = []; const defaultExpandedKeys: string[] = []; const makeTreeNode = (index: Index, depth: number): DataNode => { const title = Functions.mlang(index.title, lang) + (index.numOfItems > 0 ? ` (${index.numOfItems})` : ''); const children = IndexUtil.getChildren(index.id); if (children.length === 0) { return { key: String(index.id), title: title }; } const childTreeNodes = children.map((value: Index) => makeTreeNode(value, depth + 1)); if (depth < 1) { defaultExpandedKeys.push(String(index.id)); } expandableKeys.push(String(index.id)); return { key: String(index.id), title: title, children: childTreeNodes }; }; const elements: DataNode[] = []; const index = IndexUtil.get(INDEX_ID_PUBLIC); if (index !== null) { elements.push(makeTreeNode(index, 0)); } return { elements, expandableKeys, defaultExpandedKeys }; }; const toStringKeys = (keys: Key[]): string[] => keys.map((key) => (typeof key === 'string' ? key : String(key))); const IndexTree = (props: Props) => { const { lang } = props; const data = useMemo(() => load(lang), [lang]); const [expandedKeys, setExpandedKeys] = useState(data.defaultExpandedKeys); const navigate = useNavigate(); const handleExpand = ( keys: Key[], _info: { node: EventDataNode; expanded: boolean; nativeEvent: MouseEvent } ) => { setExpandedKeys(toStringKeys(keys)); }; const handleSelect = ( selectedKeys: Key[], _info: { event: 'select'; selected: boolean; node: EventDataNode; selectedNodes: DataNode[]; nativeEvent: MouseEvent; } ) => { const selectedKey = selectedKeys[0] ?? 0; const key = typeof selectedKey === 'string' ? parseInt(selectedKey, 10) : Number(selectedKey); void navigate(IndexUtil.getUrl(key)); }; return (
); }; export default IndexTree;