File size: 4,554 Bytes
1660911 5403bcb acd1df1 5403bcb 3927930 acd1df1 3927930 71d280d 3927930 5403bcb 3927930 5403bcb 1660911 71d280d acd1df1 71d280d acd1df1 71d280d acd1df1 71d280d acd1df1 71d280d acd1df1 71d280d 3927930 acd1df1 3927930 71d280d 5403bcb 0dc6759 5403bcb acd1df1 71d280d acd1df1 71d280d acd1df1 71d280d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
import { useFetchKnowledgeList } from '@/hooks/knowledge-hooks';
import { UserOutlined } from '@ant-design/icons';
import type { TreeDataNode, TreeProps } from 'antd';
import { Avatar, Layout, Space, Spin, Tree, Typography } from 'antd';
import classNames from 'classnames';
import {
Dispatch,
SetStateAction,
useCallback,
useEffect,
useMemo,
useState,
} from 'react';
import styles from './index.less';
const { Sider } = Layout;
interface IProps {
isFirstRender: boolean;
checkedList: string[];
setCheckedList: Dispatch<SetStateAction<string[]>>;
}
const SearchSidebar = ({
isFirstRender,
checkedList,
setCheckedList,
}: IProps) => {
const { list, loading } = useFetchKnowledgeList();
const groupedList = useMemo(() => {
return list.reduce((pre: TreeDataNode[], cur) => {
const parentItem = pre.find((x) => x.key === cur.embd_id);
const childItem: TreeDataNode = {
title: cur.name,
key: cur.id,
isLeaf: true,
};
if (parentItem) {
parentItem.children?.push(childItem);
} else {
pre.push({
title: cur.embd_id,
key: cur.embd_id,
isLeaf: false,
children: [childItem],
});
}
return pre;
}, []);
}, [list]);
const [expandedKeys, setExpandedKeys] = useState<React.Key[]>([]);
const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true);
const onExpand: TreeProps['onExpand'] = (expandedKeysValue) => {
// if not set autoExpandParent to false, if children expanded, parent can not collapse.
// or, you can remove all expanded children keys.
setExpandedKeys(expandedKeysValue);
setAutoExpandParent(false);
};
const onCheck: TreeProps['onCheck'] = (checkedKeysValue, info) => {
console.log('onCheck', checkedKeysValue, info);
const currentCheckedKeysValue = checkedKeysValue as string[];
let nextSelectedKeysValue: string[] = [];
const { isLeaf, checked, key, children } = info.node;
if (isLeaf) {
const item = list.find((x) => x.id === key);
if (!checked) {
const embeddingIds = currentCheckedKeysValue
.filter((x) => list.some((y) => y.id === x))
.map((x) => list.find((y) => y.id === x)?.embd_id);
if (embeddingIds.some((x) => x !== item?.embd_id)) {
nextSelectedKeysValue = [key as string];
} else {
nextSelectedKeysValue = currentCheckedKeysValue;
}
} else {
nextSelectedKeysValue = currentCheckedKeysValue;
}
} else {
if (!checked) {
nextSelectedKeysValue = [
key as string,
...(children?.map((x) => x.key as string) ?? []),
];
} else {
nextSelectedKeysValue = [];
}
}
setCheckedList(nextSelectedKeysValue);
};
const onSelect: TreeProps['onSelect'] = (selectedKeysValue, info) => {
console.log('onSelect', info);
setSelectedKeys(selectedKeysValue);
};
const renderTitle = useCallback(
(node: TreeDataNode) => {
const item = list.find((x) => x.id === node.key);
return (
<Space>
{node.isLeaf && (
<Avatar size={24} icon={<UserOutlined />} src={item?.avatar} />
)}
<Typography.Text
ellipsis={{ tooltip: node.title as string }}
className={node.isLeaf ? styles.knowledgeName : styles.embeddingId}
>
{node.title as string}
</Typography.Text>
</Space>
);
},
[list],
);
useEffect(() => {
const firstGroup = groupedList[0]?.children?.map((x) => x.key as string);
if (firstGroup) {
setCheckedList(firstGroup);
}
setExpandedKeys(groupedList.map((x) => x.key));
}, [groupedList, setExpandedKeys, setCheckedList]);
return (
<Sider
className={classNames(styles.searchSide, {
[styles.transparentSearchSide]: isFirstRender,
})}
theme={'light'}
width={'20%'}
>
<Spin spinning={loading}>
<Tree
className={styles.list}
checkable
onExpand={onExpand}
expandedKeys={expandedKeys}
autoExpandParent={autoExpandParent}
onCheck={onCheck}
checkedKeys={checkedList}
onSelect={onSelect}
selectedKeys={selectedKeys}
treeData={groupedList}
titleRender={renderTitle}
/>
</Spin>
</Sider>
);
};
export default SearchSidebar;
|