mirror of
https://github.com/labring/FastGPT.git
synced 2025-08-02 12:48:30 +00:00
v4.5.1 (#417)
This commit is contained in:
@@ -3,7 +3,7 @@ import { ModalBody, Textarea, ModalFooter, Button } from '@chakra-ui/react';
|
||||
import MyModal from '../MyModal';
|
||||
import { useRequest } from '@/web/common/hooks/useRequest';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { userUpdateChatFeedback } from '@/web/core/api/chat';
|
||||
import { userUpdateChatFeedback } from '@/web/core/chat/api';
|
||||
|
||||
const FeedbackModal = ({
|
||||
chatItemId,
|
||||
|
16
projects/app/src/components/ChatBox/MarkModal.tsx
Normal file
16
projects/app/src/components/ChatBox/MarkModal.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
const MarkModal = () => {
|
||||
const [adminMarkData, setAdminMarkData] = useState<{
|
||||
chatItemId: string;
|
||||
dataId?: string;
|
||||
datasetId?: string;
|
||||
collectionId?: string;
|
||||
q: string;
|
||||
a: string;
|
||||
}>();
|
||||
|
||||
return <div>MarkModal</div>;
|
||||
};
|
||||
|
||||
export default MarkModal;
|
@@ -1,23 +1,24 @@
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import { ModalBody, Box, useTheme, Flex, Progress } from '@chakra-ui/react';
|
||||
import { getDatasetDataItemById } from '@/web/core/api/dataset';
|
||||
import { getDatasetDataItemById } from '@/web/core/dataset/api';
|
||||
import { useLoading } from '@/web/common/hooks/useLoading';
|
||||
import { useToast } from '@/web/common/hooks/useToast';
|
||||
import { getErrText } from '@/utils/tools';
|
||||
import { QuoteItemType } from '@/types/chat';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import MyIcon from '@/components/Icon';
|
||||
import InputDataModal, { RawFileText } from '@/pages/kb/detail/components/InputDataModal';
|
||||
import InputDataModal, {
|
||||
RawSourceText,
|
||||
type InputDataType
|
||||
} from '@/pages/dataset/detail/components/InputDataModal';
|
||||
import MyModal from '../MyModal';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useRouter } from 'next/router';
|
||||
import type { SearchDataResponseItemType } from '@fastgpt/global/core/dataset/type';
|
||||
|
||||
const QuoteModal = ({
|
||||
onUpdateQuote,
|
||||
rawSearch = [],
|
||||
onClose
|
||||
}: {
|
||||
onUpdateQuote: (quoteId: string, sourceText?: string) => Promise<void>;
|
||||
rawSearch: QuoteItemType[];
|
||||
rawSearch: SearchDataResponseItemType[];
|
||||
onClose: () => void;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
@@ -25,7 +26,7 @@ const QuoteModal = ({
|
||||
const router = useRouter();
|
||||
const { toast } = useToast();
|
||||
const { setIsLoading, Loading } = useLoading();
|
||||
const [editDataItem, setEditDataItem] = useState<QuoteItemType>();
|
||||
const [editInputData, setEditInputData] = useState<InputDataType>();
|
||||
|
||||
const isShare = useMemo(() => router.pathname === '/chat/share', [router.pathname]);
|
||||
|
||||
@@ -33,18 +34,17 @@ const QuoteModal = ({
|
||||
* click edit, get new kbDataItem
|
||||
*/
|
||||
const onclickEdit = useCallback(
|
||||
async (item: QuoteItemType) => {
|
||||
async (item: InputDataType) => {
|
||||
if (!item.id) return;
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const data = await getDatasetDataItemById(item.id);
|
||||
|
||||
if (!data) {
|
||||
onUpdateQuote(item.id, '已删除');
|
||||
throw new Error('该数据已被删除');
|
||||
}
|
||||
|
||||
setEditDataItem(data);
|
||||
setEditInputData(data);
|
||||
} catch (err) {
|
||||
toast({
|
||||
status: 'warning',
|
||||
@@ -53,7 +53,7 @@ const QuoteModal = ({
|
||||
}
|
||||
setIsLoading(false);
|
||||
},
|
||||
[setIsLoading, toast, onUpdateQuote]
|
||||
[setIsLoading, toast]
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -94,10 +94,7 @@ const QuoteModal = ({
|
||||
>
|
||||
{!isShare && (
|
||||
<Flex alignItems={'center'} mb={1}>
|
||||
<RawFileText
|
||||
filename={item.source || t('common.Unknow') || 'Unknow'}
|
||||
fileId={item.file_id}
|
||||
/>
|
||||
<RawSourceText sourceName={item.sourceName} sourceId={item.sourceId} />
|
||||
<Box flex={'1'} />
|
||||
{item.score && (
|
||||
<>
|
||||
@@ -150,16 +147,17 @@ const QuoteModal = ({
|
||||
</ModalBody>
|
||||
<Loading fixed={false} />
|
||||
</MyModal>
|
||||
{editDataItem && (
|
||||
{editInputData && editInputData.id && (
|
||||
<InputDataModal
|
||||
onClose={() => setEditDataItem(undefined)}
|
||||
onSuccess={() => onUpdateQuote(editDataItem.id)}
|
||||
onDelete={() => onUpdateQuote(editDataItem.id, '已删除')}
|
||||
kbId={editDataItem.kb_id}
|
||||
defaultValues={{
|
||||
...editDataItem,
|
||||
dataId: editDataItem.id
|
||||
onClose={() => setEditInputData(undefined)}
|
||||
onSuccess={() => {
|
||||
console.log('更新引用成功');
|
||||
}}
|
||||
onDelete={() => {
|
||||
console.log('删除引用成功');
|
||||
}}
|
||||
datasetId={editInputData.datasetId}
|
||||
defaultValues={editInputData}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
@@ -3,7 +3,7 @@ import { ModalBody, ModalFooter, Button } from '@chakra-ui/react';
|
||||
import MyModal from '../MyModal';
|
||||
import { useRequest } from '@/web/common/hooks/useRequest';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { userUpdateChatFeedback } from '@/web/core/api/chat';
|
||||
import { userUpdateChatFeedback } from '@/web/core/chat/api';
|
||||
|
||||
const ReadFeedbackModal = ({
|
||||
chatItemId,
|
||||
@@ -39,14 +39,14 @@ const ReadFeedbackModal = ({
|
||||
<MyModal isOpen={true} onClose={onClose} title={t('chat.Feedback Modal')}>
|
||||
<ModalBody>{content}</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button mr={2} isLoading={isLoading} variant={'base'} onClick={mutate}>
|
||||
{t('chat.Feedback Close')}
|
||||
</Button>
|
||||
{!isMarked && (
|
||||
<Button variant={'base'} mr={2} onClick={onMark}>
|
||||
<Button mr={2} onClick={onMark}>
|
||||
{t('chat.Feedback Mark')}
|
||||
</Button>
|
||||
)}
|
||||
<Button isLoading={isLoading} onClick={mutate}>
|
||||
{t('chat.Feedback Close')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</MyModal>
|
||||
);
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import { ChatHistoryItemResType, ChatItemType, QuoteItemType } from '@/types/chat';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { ChatHistoryItemResType, ChatItemType } from '@/types/chat';
|
||||
import { Flex, BoxProps, useDisclosure } from '@chakra-ui/react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useGlobalStore } from '@/web/common/store/global';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import type { SearchDataResponseItemType } from '@fastgpt/global/core/dataset/type';
|
||||
import dynamic from 'next/dynamic';
|
||||
import Tag from '../Tag';
|
||||
import MyTooltip from '../MyTooltip';
|
||||
@@ -13,9 +14,9 @@ const ContextModal = dynamic(() => import('./ContextModal'), { ssr: false });
|
||||
const WholeResponseModal = dynamic(() => import('./WholeResponseModal'), { ssr: false });
|
||||
|
||||
const ResponseTags = ({ responseData = [] }: { responseData?: ChatHistoryItemResType[] }) => {
|
||||
const { isPc } = useGlobalStore();
|
||||
const { isPc } = useSystemStore();
|
||||
const { t } = useTranslation();
|
||||
const [quoteModalData, setQuoteModalData] = useState<QuoteItemType[]>();
|
||||
const [quoteModalData, setQuoteModalData] = useState<SearchDataResponseItemType[]>();
|
||||
const [contextModalData, setContextModalData] = useState<ChatItemType[]>();
|
||||
const {
|
||||
isOpen: isOpenWholeModal,
|
||||
@@ -37,14 +38,12 @@ const ResponseTags = ({ responseData = [] }: { responseData?: ChatHistoryItemRes
|
||||
.filter((item) => item.moduleType === FlowModuleTypeEnum.chatNode)
|
||||
.map((item) => item.quoteList)
|
||||
.flat()
|
||||
.filter((item) => item) as QuoteItemType[],
|
||||
.filter((item) => item) as SearchDataResponseItemType[],
|
||||
historyPreview: chatData?.historyPreview,
|
||||
runningTime: +responseData.reduce((sum, item) => sum + (item.runningTime || 0), 0).toFixed(2)
|
||||
};
|
||||
}, [responseData]);
|
||||
|
||||
const updateQuote = useCallback(async (quoteId: string, sourceText?: string) => {}, []);
|
||||
|
||||
const TagStyles: BoxProps = {
|
||||
mr: 2,
|
||||
bg: 'transparent'
|
||||
@@ -100,11 +99,7 @@ const ResponseTags = ({ responseData = [] }: { responseData?: ChatHistoryItemRes
|
||||
</MyTooltip>
|
||||
|
||||
{!!quoteModalData && (
|
||||
<QuoteModal
|
||||
rawSearch={quoteModalData}
|
||||
onUpdateQuote={updateQuote}
|
||||
onClose={() => setQuoteModalData(undefined)}
|
||||
/>
|
||||
<QuoteModal rawSearch={quoteModalData} onClose={() => setQuoteModalData(undefined)} />
|
||||
)}
|
||||
{!!contextModalData && (
|
||||
<ContextModal context={contextModalData} onClose={() => setContextModalData(undefined)} />
|
||||
|
@@ -1,114 +0,0 @@
|
||||
import React, { useState } from 'react';
|
||||
import { ModalBody, useTheme, ModalFooter, Button, Box, Card, Flex, Grid } from '@chakra-ui/react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useToast } from '@/web/common/hooks/useToast';
|
||||
import Avatar from '../Avatar';
|
||||
import MyIcon from '@/components/Icon';
|
||||
import { DatasetTypeEnum } from '@fastgpt/core/dataset/constant';
|
||||
import DatasetSelectModal, { useDatasetSelect } from '@/components/core/dataset/SelectModal';
|
||||
|
||||
const SelectDataset = ({
|
||||
isOpen,
|
||||
onSuccess,
|
||||
onClose
|
||||
}: {
|
||||
isOpen: boolean;
|
||||
onSuccess: (kbId: string) => void;
|
||||
onClose: () => void;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
const { toast } = useToast();
|
||||
const [selectedId, setSelectedId] = useState<string>();
|
||||
const { paths, parentId, setParentId, datasets } = useDatasetSelect();
|
||||
|
||||
return (
|
||||
<DatasetSelectModal
|
||||
isOpen={isOpen}
|
||||
paths={paths}
|
||||
onClose={onClose}
|
||||
parentId={parentId}
|
||||
setParentId={setParentId}
|
||||
tips={t('chat.Select Mark Kb Desc')}
|
||||
>
|
||||
<ModalBody flex={'1 0 0'} overflowY={'auto'}>
|
||||
<Grid
|
||||
gridTemplateColumns={['repeat(1,1fr)', 'repeat(2,1fr)', 'repeat(3,1fr)']}
|
||||
gridGap={3}
|
||||
userSelect={'none'}
|
||||
>
|
||||
{datasets.map((item) =>
|
||||
(() => {
|
||||
const selected = selectedId === item._id;
|
||||
return (
|
||||
<Card
|
||||
key={item._id}
|
||||
p={3}
|
||||
border={theme.borders.base}
|
||||
boxShadow={'sm'}
|
||||
h={'80px'}
|
||||
cursor={'pointer'}
|
||||
_hover={{
|
||||
boxShadow: 'md'
|
||||
}}
|
||||
{...(selected
|
||||
? {
|
||||
bg: 'myBlue.300'
|
||||
}
|
||||
: {})}
|
||||
onClick={() => {
|
||||
if (item.type === DatasetTypeEnum.folder) {
|
||||
setParentId(item._id);
|
||||
} else {
|
||||
setSelectedId(item._id);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Flex alignItems={'center'} h={'38px'}>
|
||||
<Avatar src={item.avatar} w={['24px', '28px', '32px']}></Avatar>
|
||||
<Box ml={3} fontWeight={'bold'} fontSize={['md', 'lg', 'xl']}>
|
||||
{item.name}
|
||||
</Box>
|
||||
</Flex>
|
||||
<Flex justifyContent={'flex-end'} alignItems={'center'} fontSize={'sm'}>
|
||||
<MyIcon mr={1} name="kbTest" w={'12px'} />
|
||||
<Box color={'myGray.500'}>{item.vectorModel.name}</Box>
|
||||
</Flex>
|
||||
</Card>
|
||||
);
|
||||
})()
|
||||
)}
|
||||
</Grid>
|
||||
{datasets.length === 0 && (
|
||||
<Flex mt={5} flexDirection={'column'} alignItems={'center'}>
|
||||
<MyIcon name="empty" w={'48px'} h={'48px'} color={'transparent'} />
|
||||
<Box mt={2} color={'myGray.500'}>
|
||||
这个目录已经没东西可选了~
|
||||
</Box>
|
||||
</Flex>
|
||||
)}
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button variant={'base'} mr={2} onClick={onClose}>
|
||||
{t('Cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (!selectedId) {
|
||||
return toast({
|
||||
status: 'warning',
|
||||
title: t('Select value is empty')
|
||||
});
|
||||
}
|
||||
|
||||
onSuccess(selectedId);
|
||||
}}
|
||||
>
|
||||
{t('Confirm')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</DatasetSelectModal>
|
||||
);
|
||||
};
|
||||
|
||||
export default SelectDataset;
|
195
projects/app/src/components/ChatBox/SelectMarkCollection.tsx
Normal file
195
projects/app/src/components/ChatBox/SelectMarkCollection.tsx
Normal file
@@ -0,0 +1,195 @@
|
||||
import React, { useState } from 'react';
|
||||
import { ModalBody, useTheme, ModalFooter, Button, Box, Card, Flex, Grid } from '@chakra-ui/react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import Avatar from '../Avatar';
|
||||
import MyIcon from '@/components/Icon';
|
||||
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constant';
|
||||
import DatasetSelectModal, { useDatasetSelect } from '@/components/core/dataset/SelectModal';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { MarkDataType } from '@/global/core/dataset/type';
|
||||
import SelectCollections from '@/web/core/dataset/components/SelectCollections';
|
||||
|
||||
const InputDataModal = dynamic(() => import('@/pages/dataset/detail/components/InputDataModal'));
|
||||
|
||||
export type AdminMarkType = {
|
||||
dataId?: string;
|
||||
datasetId?: string;
|
||||
collectionId?: string;
|
||||
q: string;
|
||||
a?: string;
|
||||
};
|
||||
|
||||
const SelectMarkCollection = ({
|
||||
adminMarkData,
|
||||
setAdminMarkData,
|
||||
onSuccess,
|
||||
onClose
|
||||
}: {
|
||||
adminMarkData: AdminMarkType;
|
||||
setAdminMarkData: (e: AdminMarkType) => void;
|
||||
onClose: () => void;
|
||||
onSuccess: (adminFeedback: MarkDataType) => void;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
const [selectedDatasetId, setSelectedDatasetId] = useState<string>();
|
||||
const [selectedDatasetCollectionIds, setSelectedDatasetCollectionIds] = useState<string[]>([]);
|
||||
const { paths, parentId, setParentId, datasets, isLoading } = useDatasetSelect();
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* select dataset */}
|
||||
{!adminMarkData.datasetId && (
|
||||
<DatasetSelectModal
|
||||
isOpen
|
||||
paths={paths}
|
||||
onClose={onClose}
|
||||
parentId={parentId}
|
||||
setParentId={setParentId}
|
||||
tips={t('chat.Select Mark Kb Desc')}
|
||||
>
|
||||
<ModalBody flex={'1 0 0'} overflowY={'auto'}>
|
||||
<Grid
|
||||
gridTemplateColumns={['repeat(1,1fr)', 'repeat(2,1fr)', 'repeat(3,1fr)']}
|
||||
gridGap={3}
|
||||
userSelect={'none'}
|
||||
>
|
||||
{datasets.map((item) =>
|
||||
(() => {
|
||||
const selected = selectedDatasetId === item._id;
|
||||
return (
|
||||
<Card
|
||||
key={item._id}
|
||||
p={3}
|
||||
border={theme.borders.base}
|
||||
boxShadow={'sm'}
|
||||
h={'80px'}
|
||||
cursor={'pointer'}
|
||||
_hover={{
|
||||
boxShadow: 'md'
|
||||
}}
|
||||
{...(selected
|
||||
? {
|
||||
bg: 'myBlue.300'
|
||||
}
|
||||
: {})}
|
||||
onClick={() => {
|
||||
if (item.type === DatasetTypeEnum.folder) {
|
||||
setParentId(item._id);
|
||||
} else {
|
||||
setSelectedDatasetId(item._id);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Flex alignItems={'center'} h={'38px'}>
|
||||
<Avatar src={item.avatar} w={['24px', '28px', '32px']}></Avatar>
|
||||
<Box ml={3} fontWeight={'bold'} fontSize={['md', 'lg', 'xl']}>
|
||||
{item.name}
|
||||
</Box>
|
||||
</Flex>
|
||||
<Flex justifyContent={'flex-end'} alignItems={'center'} fontSize={'sm'}>
|
||||
<MyIcon mr={1} name="kbTest" w={'12px'} />
|
||||
<Box color={'myGray.500'}>{item.vectorModel.name}</Box>
|
||||
</Flex>
|
||||
</Card>
|
||||
);
|
||||
})()
|
||||
)}
|
||||
</Grid>
|
||||
{datasets.length === 0 && (
|
||||
<Flex mt={'10vh'} flexDirection={'column'} alignItems={'center'}>
|
||||
<MyIcon name="empty" w={'48px'} h={'48px'} color={'transparent'} />
|
||||
<Box mt={2} color={'myGray.500'}>
|
||||
这个目录已经没东西可选了~
|
||||
</Box>
|
||||
</Flex>
|
||||
)}
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button
|
||||
isLoading={isLoading}
|
||||
isDisabled={!selectedDatasetId}
|
||||
onClick={() => {
|
||||
setAdminMarkData({ ...adminMarkData, datasetId: selectedDatasetId });
|
||||
}}
|
||||
>
|
||||
{t('common.Next Step')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
</DatasetSelectModal>
|
||||
)}
|
||||
|
||||
{/* select collection */}
|
||||
{adminMarkData.datasetId && !adminMarkData.collectionId && (
|
||||
<SelectCollections
|
||||
datasetId={adminMarkData.datasetId}
|
||||
type={'collection'}
|
||||
title={t('dataset.collections.Select One Collection To Store')}
|
||||
onClose={onClose}
|
||||
onChange={({ collectionIds }) => {
|
||||
setSelectedDatasetCollectionIds(collectionIds);
|
||||
}}
|
||||
CustomFooter={
|
||||
<ModalFooter>
|
||||
<Button
|
||||
variant={'base'}
|
||||
mr={2}
|
||||
onClick={() => {
|
||||
setAdminMarkData({
|
||||
...adminMarkData,
|
||||
datasetId: undefined
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t('common.Last Step')}
|
||||
</Button>
|
||||
<Button
|
||||
isDisabled={selectedDatasetCollectionIds.length === 0}
|
||||
onClick={() => {
|
||||
setAdminMarkData({
|
||||
...adminMarkData,
|
||||
collectionId: selectedDatasetCollectionIds[0]
|
||||
});
|
||||
}}
|
||||
>
|
||||
{t('common.Next Step')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* input data */}
|
||||
{adminMarkData.datasetId && adminMarkData.collectionId && (
|
||||
<InputDataModal
|
||||
onClose={onClose}
|
||||
datasetId={adminMarkData.datasetId}
|
||||
defaultValues={{
|
||||
id: adminMarkData.dataId,
|
||||
datasetId: adminMarkData.datasetId,
|
||||
collectionId: adminMarkData.collectionId,
|
||||
sourceName: '手动标注',
|
||||
q: adminMarkData.q,
|
||||
a: adminMarkData.a
|
||||
}}
|
||||
onSuccess={(data) => {
|
||||
if (!data.q || !adminMarkData.datasetId || !adminMarkData.collectionId || !data.id) {
|
||||
return onClose();
|
||||
}
|
||||
|
||||
onSuccess({
|
||||
dataId: data.id,
|
||||
datasetId: adminMarkData.datasetId,
|
||||
collectionId: adminMarkData.collectionId,
|
||||
q: data.q,
|
||||
a: data.a
|
||||
});
|
||||
onClose();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(SelectMarkCollection);
|
@@ -8,7 +8,7 @@ import Tabs from '../Tabs';
|
||||
import MyModal from '../MyModal';
|
||||
import MyTooltip from '../MyTooltip';
|
||||
import { QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||
import { formatPrice } from '@fastgpt/common/bill/index';
|
||||
import { formatPrice } from '@fastgpt/global/common/bill/tools';
|
||||
|
||||
function Row({ label, value }: { label: string; value?: string | number | React.ReactNode }) {
|
||||
const theme = useTheme();
|
||||
|
@@ -10,25 +10,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.newChat {
|
||||
.modelListContainer {
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.modelList {
|
||||
border-radius: 6px;
|
||||
}
|
||||
&:hover {
|
||||
.modelListContainer {
|
||||
height: 60vh;
|
||||
}
|
||||
.modelList {
|
||||
box-shadow: 0 0 5px rgba($color: #000000, $alpha: 0.05);
|
||||
border: 1px solid #dee0e2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.statusAnimation {
|
||||
animation: statusBox 0.8s linear infinite alternate;
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@ import React, {
|
||||
ForwardedRef,
|
||||
useEffect
|
||||
} from 'react';
|
||||
import Script from 'next/script';
|
||||
import { throttle } from 'lodash';
|
||||
import {
|
||||
ChatHistoryItemResType,
|
||||
@@ -17,7 +18,7 @@ import {
|
||||
} from '@/types/chat';
|
||||
import { useToast } from '@/web/common/hooks/useToast';
|
||||
import { useAudioPlay } from '@/web/common/utils/voice';
|
||||
import { getErrText } from '@/utils/tools';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import {
|
||||
Box,
|
||||
@@ -30,7 +31,7 @@ import {
|
||||
BoxProps,
|
||||
FlexProps
|
||||
} from '@chakra-ui/react';
|
||||
import { feConfigs } from '@/web/common/store/static';
|
||||
import { feConfigs } from '@/web/common/system/staticData';
|
||||
import { eventBus } from '@/web/common/utils/eventbus';
|
||||
import { adaptChat2GptMessages } from '@/utils/common/adapt/message';
|
||||
import { useMarkdown } from '@/web/common/hooks/useMarkdown';
|
||||
@@ -38,14 +39,15 @@ import { AppModuleItemType } from '@/types/app';
|
||||
import { VariableInputEnum } from '@/constants/app';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import type { MessageItemType } from '@/types/core/chat/type';
|
||||
import { fileDownload } from '@/web/common/utils/file';
|
||||
import { fileDownload } from '@/web/common/file/utils';
|
||||
import { htmlTemplate } from '@/constants/common';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useGlobalStore } from '@/web/common/store/global';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { TaskResponseKeyEnum } from '@/constants/chat';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { customAlphabet } from 'nanoid';
|
||||
import { userUpdateChatFeedback, adminUpdateChatFeedback } from '@/web/core/api/chat';
|
||||
import { adminUpdateChatFeedback, userUpdateChatFeedback } from '@/web/core/chat/api';
|
||||
import type { AdminMarkType } from './SelectMarkCollection';
|
||||
|
||||
import MyIcon from '@/components/Icon';
|
||||
import Avatar from '@/components/Avatar';
|
||||
@@ -56,14 +58,11 @@ import dynamic from 'next/dynamic';
|
||||
const ResponseTags = dynamic(() => import('./ResponseTags'));
|
||||
const FeedbackModal = dynamic(() => import('./FeedbackModal'));
|
||||
const ReadFeedbackModal = dynamic(() => import('./ReadFeedbackModal'));
|
||||
const SelectDataset = dynamic(() => import('./SelectDataset'));
|
||||
const InputDataModal = dynamic(() => import('@/pages/kb/detail/components/InputDataModal'));
|
||||
const SelectMarkCollection = dynamic(() => import('./SelectMarkCollection'));
|
||||
|
||||
import styles from './index.module.scss';
|
||||
import Script from 'next/script';
|
||||
import { postQuestionGuide } from '@/web/core/api/ai';
|
||||
import { splitGuideModule } from './utils';
|
||||
import { DatasetSpecialIdEnum } from '@fastgpt/core/dataset/constant';
|
||||
import { postQuestionGuide } from '@/web/core/ai/api';
|
||||
import { splitGuideModule } from '@/global/core/app/modules/utils';
|
||||
|
||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 24);
|
||||
|
||||
@@ -131,7 +130,7 @@ const ChatBox = (
|
||||
const router = useRouter();
|
||||
const { t } = useTranslation();
|
||||
const { toast } = useToast();
|
||||
const { isPc } = useGlobalStore();
|
||||
const { isPc } = useSystemStore();
|
||||
const TextareaDom = useRef<HTMLTextAreaElement>(null);
|
||||
const chatController = useRef(new AbortController());
|
||||
const questionGuideController = useRef(new AbortController());
|
||||
@@ -147,14 +146,7 @@ const ChatBox = (
|
||||
content: string;
|
||||
isMarked: boolean;
|
||||
}>();
|
||||
const [adminMarkData, setAdminMarkData] = useState<{
|
||||
// mark modal data
|
||||
kbId?: string;
|
||||
chatItemId: string;
|
||||
dataId?: string;
|
||||
q: string;
|
||||
a: string;
|
||||
}>();
|
||||
const [adminMarkData, setAdminMarkData] = useState<AdminMarkType & { chatItemId: string }>();
|
||||
const [questionGuides, setQuestionGuide] = useState<string[]>([]);
|
||||
|
||||
const isChatting = useMemo(
|
||||
@@ -674,10 +666,11 @@ const ChatBox = (
|
||||
if (item.adminFeedback) {
|
||||
setAdminMarkData({
|
||||
chatItemId: item.dataId,
|
||||
kbId: item.adminFeedback.kbId,
|
||||
datasetId: item.adminFeedback.datasetId,
|
||||
collectionId: item.adminFeedback.collectionId,
|
||||
dataId: item.adminFeedback.dataId,
|
||||
q: chatHistory[index - 1]?.value || '',
|
||||
a: item.adminFeedback.content
|
||||
q: item.adminFeedback.q || chatHistory[index - 1]?.value || '',
|
||||
a: item.adminFeedback.a
|
||||
});
|
||||
} else {
|
||||
setAdminMarkData({
|
||||
@@ -798,7 +791,9 @@ const ChatBox = (
|
||||
</Box>
|
||||
<Box h={'1px'} bg={'myGray.300'} flex={'1'} />
|
||||
</Flex>
|
||||
<Box>{item.adminFeedback.content}</Box>
|
||||
<Box whiteSpace={'pre'}>{`${item.adminFeedback.q || ''}${
|
||||
item.adminFeedback.a ? `\n${item.adminFeedback.a}` : ''
|
||||
}`}</Box>
|
||||
</Box>
|
||||
)}
|
||||
</Card>
|
||||
@@ -940,75 +935,44 @@ const ChatBox = (
|
||||
/>
|
||||
)}
|
||||
{/* admin mark data */}
|
||||
{showMarkIcon && (
|
||||
<>
|
||||
{/* select one dataset to insert markData */}
|
||||
<SelectDataset
|
||||
isOpen={!!adminMarkData && !adminMarkData.kbId}
|
||||
onClose={() => setAdminMarkData(undefined)}
|
||||
// @ts-ignore
|
||||
onSuccess={(kbId) => setAdminMarkData((state) => ({ ...state, kbId }))}
|
||||
/>
|
||||
{!!adminMarkData && (
|
||||
<SelectMarkCollection
|
||||
adminMarkData={adminMarkData}
|
||||
setAdminMarkData={(e) => setAdminMarkData({ ...e, chatItemId: adminMarkData.chatItemId })}
|
||||
onClose={() => setAdminMarkData(undefined)}
|
||||
onSuccess={(adminFeedback) => {
|
||||
adminUpdateChatFeedback({
|
||||
chatItemId: adminMarkData.chatItemId,
|
||||
...adminFeedback
|
||||
});
|
||||
// update dom
|
||||
setChatHistory((state) =>
|
||||
state.map((chatItem) =>
|
||||
chatItem.dataId === adminMarkData.chatItemId
|
||||
? {
|
||||
...chatItem,
|
||||
adminFeedback
|
||||
}
|
||||
: chatItem
|
||||
)
|
||||
);
|
||||
|
||||
{/* edit markData modal */}
|
||||
{adminMarkData && adminMarkData.kbId && (
|
||||
<InputDataModal
|
||||
onClose={() => setAdminMarkData(undefined)}
|
||||
onSuccess={async (data) => {
|
||||
if (!adminMarkData.kbId || !data.dataId) {
|
||||
return setAdminMarkData(undefined);
|
||||
}
|
||||
const adminFeedback = {
|
||||
kbId: adminMarkData.kbId,
|
||||
dataId: data.dataId,
|
||||
content: data.a
|
||||
};
|
||||
|
||||
// update dom
|
||||
setChatHistory((state) =>
|
||||
state.map((chatItem) =>
|
||||
chatItem.dataId === adminMarkData.chatItemId
|
||||
? {
|
||||
...chatItem,
|
||||
adminFeedback
|
||||
}
|
||||
: chatItem
|
||||
)
|
||||
);
|
||||
// request to update adminFeedback
|
||||
try {
|
||||
adminUpdateChatFeedback({
|
||||
chatItemId: adminMarkData.chatItemId,
|
||||
...adminFeedback
|
||||
});
|
||||
|
||||
if (readFeedbackData) {
|
||||
userUpdateChatFeedback({
|
||||
chatItemId: readFeedbackData.chatItemId,
|
||||
userFeedback: undefined
|
||||
});
|
||||
setChatHistory((state) =>
|
||||
state.map((chatItem) =>
|
||||
chatItem.dataId === readFeedbackData.chatItemId
|
||||
? { ...chatItem, userFeedback: undefined }
|
||||
: chatItem
|
||||
)
|
||||
);
|
||||
setReadFeedbackData(undefined);
|
||||
}
|
||||
} catch (error) {}
|
||||
setAdminMarkData(undefined);
|
||||
}}
|
||||
kbId={adminMarkData.kbId}
|
||||
defaultValues={{
|
||||
dataId: adminMarkData.dataId,
|
||||
q: adminMarkData.q,
|
||||
a: adminMarkData.a,
|
||||
file_id: DatasetSpecialIdEnum.mark
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
if (readFeedbackData) {
|
||||
userUpdateChatFeedback({
|
||||
chatItemId: readFeedbackData.chatItemId,
|
||||
userFeedback: undefined
|
||||
});
|
||||
setChatHistory((state) =>
|
||||
state.map((chatItem) =>
|
||||
chatItem.dataId === readFeedbackData.chatItemId
|
||||
? { ...chatItem, userFeedback: undefined }
|
||||
: chatItem
|
||||
)
|
||||
);
|
||||
setReadFeedbackData(undefined);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
|
@@ -1,24 +0,0 @@
|
||||
import { SystemInputEnum } from '@/constants/app';
|
||||
import { FlowModuleTypeEnum } from '@/constants/flow';
|
||||
import { AppModuleItemType, VariableItemType } from '@/types/app';
|
||||
|
||||
export const getGuideModule = (modules: AppModuleItemType[]) =>
|
||||
modules.find((item) => item.flowType === FlowModuleTypeEnum.userGuide);
|
||||
|
||||
export const splitGuideModule = (guideModules?: AppModuleItemType) => {
|
||||
const welcomeText: string =
|
||||
guideModules?.inputs?.find((item) => item.key === SystemInputEnum.welcomeText)?.value || '';
|
||||
|
||||
const variableModules: VariableItemType[] =
|
||||
guideModules?.inputs.find((item) => item.key === SystemInputEnum.variables)?.value || [];
|
||||
|
||||
const questionGuide: boolean =
|
||||
guideModules?.inputs?.find((item) => item.key === SystemInputEnum.questionGuide)?.value ||
|
||||
false;
|
||||
|
||||
return {
|
||||
welcomeText,
|
||||
variableModules,
|
||||
questionGuide
|
||||
};
|
||||
};
|
@@ -1,4 +0,0 @@
|
||||
.datePicker {
|
||||
--rdp-background-color: #d6e8ff;
|
||||
--rdp-accent-color: #0000ff;
|
||||
}
|
@@ -4,7 +4,6 @@ import { addDays, format } from 'date-fns';
|
||||
import { type DateRange, DayPicker } from 'react-day-picker';
|
||||
import MyIcon from '../Icon';
|
||||
import 'react-day-picker/dist/style.css';
|
||||
import styles from './index.module.scss';
|
||||
import zhCN from 'date-fns/locale/zh-CN';
|
||||
|
||||
const DateRangePicker = ({
|
||||
@@ -59,6 +58,10 @@ const DateRangePicker = ({
|
||||
<Card
|
||||
position={'absolute'}
|
||||
zIndex={1}
|
||||
css={{
|
||||
'--rdp-background-color': '#d6e8ff',
|
||||
' --rdp-accent-color': '#0000ff'
|
||||
}}
|
||||
{...(position === 'top'
|
||||
? {
|
||||
bottom: '40px'
|
||||
@@ -69,7 +72,6 @@ const DateRangePicker = ({
|
||||
locale={zhCN}
|
||||
id="test"
|
||||
mode="range"
|
||||
className={styles.datePicker}
|
||||
defaultMonth={defaultDate.to}
|
||||
selected={range}
|
||||
disabled={[
|
||||
|
20
projects/app/src/components/EmptyTip/index.tsx
Normal file
20
projects/app/src/components/EmptyTip/index.tsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import { Flex, Box, FlexProps } from '@chakra-ui/react';
|
||||
import MyIcon from '../Icon';
|
||||
|
||||
type Props = FlexProps & {
|
||||
text?: string | null;
|
||||
};
|
||||
|
||||
const EmptyTip = ({ text, ...props }: Props) => {
|
||||
return (
|
||||
<Flex mt={5} flexDirection={'column'} alignItems={'center'} pt={'10vh'} {...props}>
|
||||
<MyIcon name="empty" w={'48px'} h={'48px'} color={'transparent'} />
|
||||
<Box mt={2} color={'myGray.500'}>
|
||||
{text || '没有什么数据噢~'}
|
||||
</Box>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default EmptyTip;
|
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useToast } from '@chakra-ui/react';
|
||||
import { useUserStore } from '@/web/support/store/user';
|
||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
const unAuthPage: { [key: string]: boolean } = {
|
||||
|
@@ -2,14 +2,14 @@ import React, { useEffect, useMemo } from 'react';
|
||||
import { Box, useColorMode, Flex } from '@chakra-ui/react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useLoading } from '@/web/common/hooks/useLoading';
|
||||
import { useGlobalStore } from '@/web/common/store/global';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { throttle } from 'lodash';
|
||||
import Auth from './auth';
|
||||
import Navbar from './navbar';
|
||||
import NavbarPhone from './navbarPhone';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useUserStore } from '@/web/support/store/user';
|
||||
import { getUnreadCount } from '@/web/support/api/user';
|
||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||
import { getUnreadCount } from '@/web/support/user/api';
|
||||
|
||||
const pcUnShowLayoutRoute: Record<string, boolean> = {
|
||||
'/': true,
|
||||
@@ -30,7 +30,7 @@ const Layout = ({ children }: { children: JSX.Element }) => {
|
||||
const router = useRouter();
|
||||
const { colorMode, setColorMode } = useColorMode();
|
||||
const { Loading } = useLoading();
|
||||
const { loading, setScreenWidth, isPc, loadGitStar } = useGlobalStore();
|
||||
const { loading, setScreenWidth, isPc, loadGitStar } = useSystemStore();
|
||||
const { userInfo } = useUserStore();
|
||||
|
||||
const isChatPage = useMemo(
|
||||
|
@@ -1,16 +1,16 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { Box, Flex, Link } from '@chakra-ui/react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useUserStore } from '@/web/support/store/user';
|
||||
import { useChatStore } from '@/web/core/store/chat';
|
||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||
import { useChatStore } from '@/web/core/chat/storeChat';
|
||||
import { HUMAN_ICON } from '@/constants/chat';
|
||||
import { feConfigs } from '@/web/common/store/static';
|
||||
import { feConfigs } from '@/web/common/system/staticData';
|
||||
import NextLink from 'next/link';
|
||||
import Badge from '../Badge';
|
||||
import Avatar from '../Avatar';
|
||||
import MyIcon from '../Icon';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useGlobalStore } from '@/web/common/store/global';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import MyTooltip from '../MyTooltip';
|
||||
|
||||
export enum NavbarTypeEnum {
|
||||
@@ -22,7 +22,7 @@ const Navbar = ({ unread }: { unread: number }) => {
|
||||
const { t } = useTranslation();
|
||||
const router = useRouter();
|
||||
const { userInfo } = useUserStore();
|
||||
const { gitStar } = useGlobalStore();
|
||||
const { gitStar } = useSystemStore();
|
||||
const { lastChatAppId, lastChatId } = useChatStore();
|
||||
const navbarList = useMemo(
|
||||
() => [
|
||||
@@ -44,8 +44,8 @@ const Navbar = ({ unread }: { unread: number }) => {
|
||||
label: t('navbar.Datasets'),
|
||||
icon: 'dbLight',
|
||||
activeIcon: 'dbFill',
|
||||
link: `/kb/list`,
|
||||
activeLink: ['/kb/list', '/kb/detail']
|
||||
link: `/dataset/list`,
|
||||
activeLink: ['/dataset/list', '/dataset/detail']
|
||||
},
|
||||
...(feConfigs?.show_appStore
|
||||
? [
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { Flex, Box } from '@chakra-ui/react';
|
||||
import { useChatStore } from '@/web/core/store/chat';
|
||||
import { useChatStore } from '@/web/core/chat/storeChat';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Badge from '../Badge';
|
||||
import MyIcon from '../Icon';
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { Box, useTheme } from '@chakra-ui/react';
|
||||
import { getFileAndOpen } from '@/web/common/utils/file';
|
||||
import { getFileAndOpen } from '@/web/common/file/utils';
|
||||
import { useToast } from '@/web/common/hooks/useToast';
|
||||
import { getErrText } from '@/utils/tools';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
|
||||
type QuoteItemType = {
|
||||
file_id?: string;
|
||||
|
@@ -22,7 +22,7 @@ const MyModal = ({
|
||||
title,
|
||||
children,
|
||||
isCentered,
|
||||
w = 'auto',
|
||||
w = '100%',
|
||||
maxW = ['90vw', '600px'],
|
||||
...props
|
||||
}: Props) => {
|
||||
@@ -44,7 +44,12 @@ const MyModal = ({
|
||||
>
|
||||
{!!title && <ModalHeader>{title}</ModalHeader>}
|
||||
{onClose && <ModalCloseButton />}
|
||||
<Box overflow={'overlay'} h={'100%'} display={'flex'} flexDirection={'column'}>
|
||||
<Box
|
||||
overflow={props.overflow || 'overlay'}
|
||||
h={'100%'}
|
||||
display={'flex'}
|
||||
flexDirection={'column'}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
</ModalContent>
|
||||
|
@@ -1,13 +1,13 @@
|
||||
import React from 'react';
|
||||
import { Tooltip, TooltipProps } from '@chakra-ui/react';
|
||||
import { useGlobalStore } from '@/web/common/store/global';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
|
||||
interface Props extends TooltipProps {
|
||||
forceShow?: boolean;
|
||||
}
|
||||
|
||||
const MyTooltip = ({ children, forceShow = false, shouldWrapChildren = true, ...props }: Props) => {
|
||||
const { isPc } = useGlobalStore();
|
||||
const { isPc } = useSystemStore();
|
||||
return isPc || forceShow ? (
|
||||
<Tooltip
|
||||
bg={'white'}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import React, { useState } from 'react';
|
||||
import MyModal from '../MyModal';
|
||||
import { Box, Button, Grid, useTheme } from '@chakra-ui/react';
|
||||
import { PromptTemplateItem } from '@fastgpt/core/ai/type';
|
||||
import { PromptTemplateItem } from '@fastgpt/global/core/ai/type.d';
|
||||
import { ModalBody, ModalFooter } from '@chakra-ui/react';
|
||||
|
||||
const PromptTemplate = ({
|
||||
|
62
projects/app/src/components/common/ParentPaths/index.tsx
Normal file
62
projects/app/src/components/common/ParentPaths/index.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import MyIcon from '@/components/Icon';
|
||||
import { Box, Flex } from '@chakra-ui/react';
|
||||
import { ParentTreePathItemType } from '@fastgpt/global/common/parentFolder/type';
|
||||
import React, { useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const ParentPaths = (props: {
|
||||
paths?: ParentTreePathItemType[];
|
||||
rootName?: string;
|
||||
FirstPathDom?: React.ReactNode;
|
||||
onClick: (parentId: string) => void;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { paths = [], rootName = t('common.folder.Root Path'), FirstPathDom, onClick } = props;
|
||||
const concatPaths = useMemo(
|
||||
() => [
|
||||
{
|
||||
parentId: '',
|
||||
parentName: rootName
|
||||
},
|
||||
...paths
|
||||
],
|
||||
[rootName, paths]
|
||||
);
|
||||
|
||||
return paths.length === 0 && !!FirstPathDom ? (
|
||||
<>{FirstPathDom}</>
|
||||
) : (
|
||||
<Flex flex={1}>
|
||||
{concatPaths.map((item, i) => (
|
||||
<Flex key={item.parentId} alignItems={'center'}>
|
||||
<Box
|
||||
fontSize={['md', 'lg']}
|
||||
py={1}
|
||||
px={[0, 2]}
|
||||
borderRadius={'md'}
|
||||
{...(i === concatPaths.length - 1
|
||||
? {
|
||||
cursor: 'default'
|
||||
}
|
||||
: {
|
||||
cursor: 'pointer',
|
||||
_hover: {
|
||||
bg: 'myGray.100'
|
||||
},
|
||||
onClick: () => {
|
||||
onClick(item.parentId);
|
||||
}
|
||||
})}
|
||||
>
|
||||
{item.parentName}
|
||||
</Box>
|
||||
{i !== concatPaths.length - 1 && (
|
||||
<MyIcon name={'rightArrowLight'} color={'myGray.500'} w={['18px', '24px']} />
|
||||
)}
|
||||
</Flex>
|
||||
))}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default React.memo(ParentPaths);
|
@@ -1,9 +1,9 @@
|
||||
import { getDatasets, getDatasetPaths } from '@/web/core/api/dataset';
|
||||
import { getDatasets, getDatasetPaths } from '@/web/core/dataset/api';
|
||||
import MyModal from '@/components/MyModal';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import React, { Dispatch, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useGlobalStore } from '@/web/common/store/global';
|
||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||
import { Box, Flex, ModalHeader } from '@chakra-ui/react';
|
||||
import MyIcon from '@/components/Icon';
|
||||
|
||||
@@ -30,7 +30,7 @@ const DatasetSelectContainer = ({
|
||||
children: React.ReactNode;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { isPc } = useGlobalStore();
|
||||
const { isPc } = useSystemStore();
|
||||
|
||||
return (
|
||||
<MyModal isOpen={isOpen} onClose={onClose} w={'100%'} maxW={['90vw', '900px']} isCentered>
|
||||
@@ -86,11 +86,11 @@ const DatasetSelectContainer = ({
|
||||
);
|
||||
};
|
||||
|
||||
export const useDatasetSelect = () => {
|
||||
export function useDatasetSelect() {
|
||||
const { t } = useTranslation();
|
||||
const [parentId, setParentId] = useState<string>();
|
||||
|
||||
const { data } = useQuery(['loadDatasetData', parentId], () =>
|
||||
const { data, isLoading } = useQuery(['loadDatasetData', parentId], () =>
|
||||
Promise.all([getDatasets({ parentId }), getDatasetPaths(parentId)])
|
||||
);
|
||||
|
||||
@@ -98,7 +98,7 @@ export const useDatasetSelect = () => {
|
||||
() => [
|
||||
{
|
||||
parentId: '',
|
||||
parentName: t('kb.My Dataset')
|
||||
parentName: t('dataset.My Dataset')
|
||||
},
|
||||
...(data?.[1] || [])
|
||||
],
|
||||
@@ -109,8 +109,9 @@ export const useDatasetSelect = () => {
|
||||
parentId,
|
||||
setParentId,
|
||||
datasets: data?.[0] || [],
|
||||
paths
|
||||
paths,
|
||||
isLoading
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export default DatasetSelectContainer;
|
||||
|
@@ -25,14 +25,14 @@ import {
|
||||
createAOpenApiKey,
|
||||
delOpenApiById,
|
||||
putOpenApiKey
|
||||
} from '@/web/support/api/openapi';
|
||||
} from '@/web/support/openapi/api';
|
||||
import type { EditApiKeyProps } from '@/global/support/api/openapiReq';
|
||||
import { useQuery, useMutation } from '@tanstack/react-query';
|
||||
import { useLoading } from '@/web/common/hooks/useLoading';
|
||||
import dayjs from 'dayjs';
|
||||
import { AddIcon, QuestionOutlineIcon } from '@chakra-ui/icons';
|
||||
import { useCopyData } from '@/web/common/hooks/useCopyData';
|
||||
import { feConfigs } from '@/web/common/store/static';
|
||||
import { feConfigs } from '@/web/common/system/staticData';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import MyIcon from '@/components/Icon';
|
||||
import MyModal from '@/components/MyModal';
|
||||
|
Reference in New Issue
Block a user