import React, { useMemo, useState } from 'react'; import { Card, Flex, Box, Button, ModalBody, ModalFooter, useTheme, Textarea, Grid, Divider } from '@chakra-ui/react'; import Avatar from '@/components/Avatar'; import { useForm } from 'react-hook-form'; import { QuestionOutlineIcon } from '@chakra-ui/icons'; import type { SelectedKbType } from '@/types/plugin'; import { useToast } from '@/hooks/useToast'; import MySlider from '@/components/Slider'; import MyTooltip from '@/components/MyTooltip'; import MyModal from '@/components/MyModal'; import MyIcon from '@/components/Icon'; import { KbTypeEnum } from '@/constants/kb'; import { useTranslation } from 'react-i18next'; import { useQuery } from '@tanstack/react-query'; import { useDatasetStore } from '@/store/dataset'; import { feConfigs } from '@/store/static'; import DatasetSelectModal, { useDatasetSelect } from '@/components/core/dataset/SelectModal'; export type KbParamsType = { searchSimilarity: number; searchLimit: number; searchEmptyText: string; }; export const KBSelectModal = ({ isOpen, activeKbs = [], onChange, onClose }: { isOpen: boolean; activeKbs: SelectedKbType; onChange: (e: SelectedKbType) => void; onClose: () => void; }) => { const { t } = useTranslation(); const theme = useTheme(); const [selectedKbList, setSelectedKbList] = useState(activeKbs); const { toast } = useToast(); const { paths, parentId, setParentId, datasets } = useDatasetSelect(); const { allDatasets, loadAllDatasets } = useDatasetStore(); useQuery(['loadAllDatasets'], loadAllDatasets); const filterKbList = useMemo(() => { return { selected: allDatasets.filter((item) => selectedKbList.find((kb) => kb.kbId === item._id)), unSelected: datasets.filter((item) => !selectedKbList.find((kb) => kb.kbId === item._id)) }; }, [datasets, allDatasets, selectedKbList]); return ( {filterKbList.selected.map((item) => (() => { return ( {item.name} { setSelectedKbList((state) => state.filter((kb) => kb.kbId !== item._id)); }} /> ); })() )} {filterKbList.selected.length > 0 && } {filterKbList.unSelected.map((item) => (() => { return ( { if (item.type === KbTypeEnum.folder) { setParentId(item._id); } else if (item.type === KbTypeEnum.dataset) { const vectorModel = selectedKbList[0]?.vectorModel?.model; if (vectorModel && vectorModel !== item.vectorModel.model) { return toast({ status: 'warning', title: '仅能选择同一个索引模型的知识库' }); } setSelectedKbList((state) => [ ...state, { kbId: item._id, vectorModel: item.vectorModel } ]); } }} > {item.name} {item.type === KbTypeEnum.folder ? ( {t('Folder')} ) : ( <> {item.vectorModel.name} )} ); })() )} {filterKbList.unSelected.length === 0 && ( 这个目录已经没东西可选了~ )} ); }; export const KbParamsModal = ({ searchEmptyText, searchLimit, searchSimilarity, onClose, onChange }: KbParamsType & { onClose: () => void; onChange: (e: KbParamsType) => void }) => { const [refresh, setRefresh] = useState(false); const { register, setValue, getValues, handleSubmit } = useForm({ defaultValues: { searchEmptyText, searchLimit, searchSimilarity } }); return ( 相似度 { setValue('searchSimilarity', val); setRefresh(!refresh); }} /> 单次搜索数量 { setValue('searchLimit', val); setRefresh(!refresh); }} /> 空搜索回复 ); }; export default KBSelectModal;