mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-05-24 13:38:55 +08:00
### What problem does this PR solve? fix: new message appears in wrong chat window. #1289 ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
parent
4df75ca84e
commit
06fd35d420
@ -214,7 +214,7 @@ export const useSendMessageWithSse = (
|
||||
[url],
|
||||
);
|
||||
|
||||
return { send, answer, done };
|
||||
return { send, answer, done, setDone };
|
||||
};
|
||||
|
||||
//#region chat hooks
|
@ -8,7 +8,7 @@ import { useCallback, useMemo } from 'react';
|
||||
import { useLocation } from 'umi';
|
||||
import Toolbar from '../right-toolbar';
|
||||
|
||||
import { useFetchAppConf } from '@/hooks/logicHooks';
|
||||
import { useFetchAppConf } from '@/hooks/logic-hooks';
|
||||
import { MessageOutlined } from '@ant-design/icons';
|
||||
import styles from './index.less';
|
||||
|
||||
|
@ -6,7 +6,7 @@ import React from 'react';
|
||||
import User from '../user';
|
||||
|
||||
import { LanguageList } from '@/constants/common';
|
||||
import { useChangeLanguage } from '@/hooks/logicHooks';
|
||||
import { useChangeLanguage } from '@/hooks/logic-hooks';
|
||||
import { useSelector } from 'umi';
|
||||
import styled from './index.less';
|
||||
|
||||
|
@ -15,7 +15,7 @@ import {
|
||||
import {
|
||||
useChangeDocumentParser,
|
||||
useSetSelectedRecord,
|
||||
} from '@/hooks/logicHooks';
|
||||
} from '@/hooks/logic-hooks';
|
||||
import { useFetchTenantInfo } from '@/hooks/userSettingHook';
|
||||
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
||||
import { getExtension, isFileUploadDone } from '@/utils/documentUtils';
|
||||
|
@ -1,233 +1,234 @@
|
||||
import ChunkMethodModal from '@/components/chunk-method-modal';
|
||||
import SvgIcon from '@/components/svg-icon';
|
||||
import {
|
||||
useSelectDocumentList,
|
||||
useSetDocumentStatus,
|
||||
} from '@/hooks/documentHooks';
|
||||
import { useSetSelectedRecord } from '@/hooks/logicHooks';
|
||||
import { useSelectParserList } from '@/hooks/userSettingHook';
|
||||
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
||||
import { getExtension } from '@/utils/documentUtils';
|
||||
import { Divider, Flex, Switch, Table, Typography } from 'antd';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import CreateFileModal from './create-file-modal';
|
||||
import WebCrawlModal from './web-crawl-modal';
|
||||
import DocumentToolbar from './document-toolbar';
|
||||
import {
|
||||
useChangeDocumentParser,
|
||||
useCreateEmptyDocument,
|
||||
useFetchDocumentListOnMount,
|
||||
useGetPagination,
|
||||
useGetRowSelection,
|
||||
useHandleUploadDocument, useHandleWebCrawl,
|
||||
useNavigateToOtherPage,
|
||||
useRenameDocument,
|
||||
} from './hooks';
|
||||
import ParsingActionCell from './parsing-action-cell';
|
||||
import ParsingStatusCell from './parsing-status-cell';
|
||||
import RenameModal from './rename-modal';
|
||||
|
||||
import FileUploadModal from '@/components/file-upload-modal';
|
||||
import { formatDate } from '@/utils/date';
|
||||
import styles from './index.less';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
const KnowledgeFile = () => {
|
||||
const data = useSelectDocumentList();
|
||||
const { fetchDocumentList } = useFetchDocumentListOnMount();
|
||||
const parserList = useSelectParserList();
|
||||
const { pagination } = useGetPagination(fetchDocumentList);
|
||||
const onChangeStatus = useSetDocumentStatus();
|
||||
const { toChunk } = useNavigateToOtherPage();
|
||||
const { currentRecord, setRecord } = useSetSelectedRecord();
|
||||
const {
|
||||
renameLoading,
|
||||
onRenameOk,
|
||||
renameVisible,
|
||||
hideRenameModal,
|
||||
showRenameModal,
|
||||
} = useRenameDocument(currentRecord.id);
|
||||
const {
|
||||
createLoading,
|
||||
onCreateOk,
|
||||
createVisible,
|
||||
hideCreateModal,
|
||||
showCreateModal,
|
||||
} = useCreateEmptyDocument();
|
||||
const {
|
||||
changeParserLoading,
|
||||
onChangeParserOk,
|
||||
changeParserVisible,
|
||||
hideChangeParserModal,
|
||||
showChangeParserModal,
|
||||
} = useChangeDocumentParser(currentRecord.id);
|
||||
const {
|
||||
documentUploadVisible,
|
||||
hideDocumentUploadModal,
|
||||
showDocumentUploadModal,
|
||||
onDocumentUploadOk,
|
||||
documentUploadLoading,
|
||||
} = useHandleUploadDocument();
|
||||
const {
|
||||
webCrawlUploadVisible,
|
||||
hideWebCrawlUploadModal,
|
||||
showWebCrawlUploadModal,
|
||||
onWebCrawlUploadOk,
|
||||
webCrawlUploadLoading,
|
||||
} = useHandleWebCrawl();
|
||||
const { t } = useTranslation('translation', {
|
||||
keyPrefix: 'knowledgeDetails',
|
||||
});
|
||||
|
||||
const rowSelection = useGetRowSelection();
|
||||
|
||||
const columns: ColumnsType<IKnowledgeFile> = [
|
||||
{
|
||||
title: t('name'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
fixed: 'left',
|
||||
render: (text: any, { id, thumbnail, name }) => (
|
||||
<div className={styles.toChunks} onClick={() => toChunk(id)}>
|
||||
<Flex gap={10} align="center">
|
||||
{thumbnail ? (
|
||||
<img className={styles.img} src={thumbnail} alt="" />
|
||||
) : (
|
||||
<SvgIcon
|
||||
name={`file-icon/${getExtension(name)}`}
|
||||
width={24}
|
||||
></SvgIcon>
|
||||
)}
|
||||
<Text ellipsis={{ tooltip: text }} className={styles.nameText}>
|
||||
{text}
|
||||
</Text>
|
||||
</Flex>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t('chunkNumber'),
|
||||
dataIndex: 'chunk_num',
|
||||
key: 'chunk_num',
|
||||
},
|
||||
{
|
||||
title: t('uploadDate'),
|
||||
dataIndex: 'create_time',
|
||||
key: 'create_time',
|
||||
render(value) {
|
||||
return formatDate(value);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('chunkMethod'),
|
||||
dataIndex: 'parser_id',
|
||||
key: 'parser_id',
|
||||
render: (text) => {
|
||||
return parserList.find((x) => x.value === text)?.label;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('enabled'),
|
||||
key: 'status',
|
||||
dataIndex: 'status',
|
||||
render: (_, { status, id }) => (
|
||||
<>
|
||||
<Switch
|
||||
checked={status === '1'}
|
||||
onChange={(e) => {
|
||||
onChangeStatus(e, id);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t('parsingStatus'),
|
||||
dataIndex: 'run',
|
||||
key: 'run',
|
||||
render: (text, record) => {
|
||||
return <ParsingStatusCell record={record}></ParsingStatusCell>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('action'),
|
||||
key: 'action',
|
||||
render: (_, record) => (
|
||||
<ParsingActionCell
|
||||
setCurrentRecord={setRecord}
|
||||
showRenameModal={showRenameModal}
|
||||
showChangeParserModal={showChangeParserModal}
|
||||
record={record}
|
||||
></ParsingActionCell>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const finalColumns = columns.map((x) => ({
|
||||
...x,
|
||||
className: `${styles.column}`,
|
||||
}));
|
||||
|
||||
return (
|
||||
<div className={styles.datasetWrapper}>
|
||||
<h3>{t('dataset')}</h3>
|
||||
<p>{t('datasetDescription')}</p>
|
||||
<Divider></Divider>
|
||||
<DocumentToolbar
|
||||
selectedRowKeys={rowSelection.selectedRowKeys as string[]}
|
||||
showCreateModal={showCreateModal}
|
||||
showWebCrawlModal={showWebCrawlUploadModal}
|
||||
showDocumentUploadModal={showDocumentUploadModal}
|
||||
></DocumentToolbar>
|
||||
<Table
|
||||
rowKey="id"
|
||||
columns={finalColumns}
|
||||
dataSource={data}
|
||||
// loading={loading}
|
||||
pagination={pagination}
|
||||
rowSelection={rowSelection}
|
||||
className={styles.documentTable}
|
||||
scroll={{ scrollToFirstRowOnChange: true, x: 1300 }}
|
||||
/>
|
||||
<CreateFileModal
|
||||
visible={createVisible}
|
||||
hideModal={hideCreateModal}
|
||||
loading={createLoading}
|
||||
onOk={onCreateOk}
|
||||
/>
|
||||
<ChunkMethodModal
|
||||
documentId={currentRecord.id}
|
||||
parserId={currentRecord.parser_id}
|
||||
parserConfig={currentRecord.parser_config}
|
||||
documentExtension={getExtension(currentRecord.name)}
|
||||
onOk={onChangeParserOk}
|
||||
visible={changeParserVisible}
|
||||
hideModal={hideChangeParserModal}
|
||||
loading={changeParserLoading}
|
||||
/>
|
||||
<RenameModal
|
||||
visible={renameVisible}
|
||||
onOk={onRenameOk}
|
||||
loading={renameLoading}
|
||||
hideModal={hideRenameModal}
|
||||
initialName={currentRecord.name}
|
||||
></RenameModal>
|
||||
<FileUploadModal
|
||||
visible={documentUploadVisible}
|
||||
hideModal={hideDocumentUploadModal}
|
||||
loading={documentUploadLoading}
|
||||
onOk={onDocumentUploadOk}
|
||||
></FileUploadModal>
|
||||
<WebCrawlModal
|
||||
visible={webCrawlUploadVisible}
|
||||
hideModal={hideWebCrawlUploadModal}
|
||||
loading={webCrawlUploadLoading}
|
||||
onOk={onWebCrawlUploadOk}
|
||||
></WebCrawlModal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default KnowledgeFile;
|
||||
import ChunkMethodModal from '@/components/chunk-method-modal';
|
||||
import SvgIcon from '@/components/svg-icon';
|
||||
import {
|
||||
useSelectDocumentList,
|
||||
useSetDocumentStatus,
|
||||
} from '@/hooks/documentHooks';
|
||||
import { useSetSelectedRecord } from '@/hooks/logic-hooks';
|
||||
import { useSelectParserList } from '@/hooks/userSettingHook';
|
||||
import { IKnowledgeFile } from '@/interfaces/database/knowledge';
|
||||
import { getExtension } from '@/utils/documentUtils';
|
||||
import { Divider, Flex, Switch, Table, Typography } from 'antd';
|
||||
import type { ColumnsType } from 'antd/es/table';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import CreateFileModal from './create-file-modal';
|
||||
import DocumentToolbar from './document-toolbar';
|
||||
import {
|
||||
useChangeDocumentParser,
|
||||
useCreateEmptyDocument,
|
||||
useFetchDocumentListOnMount,
|
||||
useGetPagination,
|
||||
useGetRowSelection,
|
||||
useHandleUploadDocument,
|
||||
useHandleWebCrawl,
|
||||
useNavigateToOtherPage,
|
||||
useRenameDocument,
|
||||
} from './hooks';
|
||||
import ParsingActionCell from './parsing-action-cell';
|
||||
import ParsingStatusCell from './parsing-status-cell';
|
||||
import RenameModal from './rename-modal';
|
||||
import WebCrawlModal from './web-crawl-modal';
|
||||
|
||||
import FileUploadModal from '@/components/file-upload-modal';
|
||||
import { formatDate } from '@/utils/date';
|
||||
import styles from './index.less';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
const KnowledgeFile = () => {
|
||||
const data = useSelectDocumentList();
|
||||
const { fetchDocumentList } = useFetchDocumentListOnMount();
|
||||
const parserList = useSelectParserList();
|
||||
const { pagination } = useGetPagination(fetchDocumentList);
|
||||
const onChangeStatus = useSetDocumentStatus();
|
||||
const { toChunk } = useNavigateToOtherPage();
|
||||
const { currentRecord, setRecord } = useSetSelectedRecord();
|
||||
const {
|
||||
renameLoading,
|
||||
onRenameOk,
|
||||
renameVisible,
|
||||
hideRenameModal,
|
||||
showRenameModal,
|
||||
} = useRenameDocument(currentRecord.id);
|
||||
const {
|
||||
createLoading,
|
||||
onCreateOk,
|
||||
createVisible,
|
||||
hideCreateModal,
|
||||
showCreateModal,
|
||||
} = useCreateEmptyDocument();
|
||||
const {
|
||||
changeParserLoading,
|
||||
onChangeParserOk,
|
||||
changeParserVisible,
|
||||
hideChangeParserModal,
|
||||
showChangeParserModal,
|
||||
} = useChangeDocumentParser(currentRecord.id);
|
||||
const {
|
||||
documentUploadVisible,
|
||||
hideDocumentUploadModal,
|
||||
showDocumentUploadModal,
|
||||
onDocumentUploadOk,
|
||||
documentUploadLoading,
|
||||
} = useHandleUploadDocument();
|
||||
const {
|
||||
webCrawlUploadVisible,
|
||||
hideWebCrawlUploadModal,
|
||||
showWebCrawlUploadModal,
|
||||
onWebCrawlUploadOk,
|
||||
webCrawlUploadLoading,
|
||||
} = useHandleWebCrawl();
|
||||
const { t } = useTranslation('translation', {
|
||||
keyPrefix: 'knowledgeDetails',
|
||||
});
|
||||
|
||||
const rowSelection = useGetRowSelection();
|
||||
|
||||
const columns: ColumnsType<IKnowledgeFile> = [
|
||||
{
|
||||
title: t('name'),
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
fixed: 'left',
|
||||
render: (text: any, { id, thumbnail, name }) => (
|
||||
<div className={styles.toChunks} onClick={() => toChunk(id)}>
|
||||
<Flex gap={10} align="center">
|
||||
{thumbnail ? (
|
||||
<img className={styles.img} src={thumbnail} alt="" />
|
||||
) : (
|
||||
<SvgIcon
|
||||
name={`file-icon/${getExtension(name)}`}
|
||||
width={24}
|
||||
></SvgIcon>
|
||||
)}
|
||||
<Text ellipsis={{ tooltip: text }} className={styles.nameText}>
|
||||
{text}
|
||||
</Text>
|
||||
</Flex>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t('chunkNumber'),
|
||||
dataIndex: 'chunk_num',
|
||||
key: 'chunk_num',
|
||||
},
|
||||
{
|
||||
title: t('uploadDate'),
|
||||
dataIndex: 'create_time',
|
||||
key: 'create_time',
|
||||
render(value) {
|
||||
return formatDate(value);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('chunkMethod'),
|
||||
dataIndex: 'parser_id',
|
||||
key: 'parser_id',
|
||||
render: (text) => {
|
||||
return parserList.find((x) => x.value === text)?.label;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('enabled'),
|
||||
key: 'status',
|
||||
dataIndex: 'status',
|
||||
render: (_, { status, id }) => (
|
||||
<>
|
||||
<Switch
|
||||
checked={status === '1'}
|
||||
onChange={(e) => {
|
||||
onChangeStatus(e, id);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: t('parsingStatus'),
|
||||
dataIndex: 'run',
|
||||
key: 'run',
|
||||
render: (text, record) => {
|
||||
return <ParsingStatusCell record={record}></ParsingStatusCell>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('action'),
|
||||
key: 'action',
|
||||
render: (_, record) => (
|
||||
<ParsingActionCell
|
||||
setCurrentRecord={setRecord}
|
||||
showRenameModal={showRenameModal}
|
||||
showChangeParserModal={showChangeParserModal}
|
||||
record={record}
|
||||
></ParsingActionCell>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const finalColumns = columns.map((x) => ({
|
||||
...x,
|
||||
className: `${styles.column}`,
|
||||
}));
|
||||
|
||||
return (
|
||||
<div className={styles.datasetWrapper}>
|
||||
<h3>{t('dataset')}</h3>
|
||||
<p>{t('datasetDescription')}</p>
|
||||
<Divider></Divider>
|
||||
<DocumentToolbar
|
||||
selectedRowKeys={rowSelection.selectedRowKeys as string[]}
|
||||
showCreateModal={showCreateModal}
|
||||
showWebCrawlModal={showWebCrawlUploadModal}
|
||||
showDocumentUploadModal={showDocumentUploadModal}
|
||||
></DocumentToolbar>
|
||||
<Table
|
||||
rowKey="id"
|
||||
columns={finalColumns}
|
||||
dataSource={data}
|
||||
// loading={loading}
|
||||
pagination={pagination}
|
||||
rowSelection={rowSelection}
|
||||
className={styles.documentTable}
|
||||
scroll={{ scrollToFirstRowOnChange: true, x: 1300 }}
|
||||
/>
|
||||
<CreateFileModal
|
||||
visible={createVisible}
|
||||
hideModal={hideCreateModal}
|
||||
loading={createLoading}
|
||||
onOk={onCreateOk}
|
||||
/>
|
||||
<ChunkMethodModal
|
||||
documentId={currentRecord.id}
|
||||
parserId={currentRecord.parser_id}
|
||||
parserConfig={currentRecord.parser_config}
|
||||
documentExtension={getExtension(currentRecord.name)}
|
||||
onOk={onChangeParserOk}
|
||||
visible={changeParserVisible}
|
||||
hideModal={hideChangeParserModal}
|
||||
loading={changeParserLoading}
|
||||
/>
|
||||
<RenameModal
|
||||
visible={renameVisible}
|
||||
onOk={onRenameOk}
|
||||
loading={renameLoading}
|
||||
hideModal={hideRenameModal}
|
||||
initialName={currentRecord.name}
|
||||
></RenameModal>
|
||||
<FileUploadModal
|
||||
visible={documentUploadVisible}
|
||||
hideModal={hideDocumentUploadModal}
|
||||
loading={documentUploadLoading}
|
||||
onOk={onDocumentUploadOk}
|
||||
></FileUploadModal>
|
||||
<WebCrawlModal
|
||||
visible={webCrawlUploadVisible}
|
||||
hideModal={hideWebCrawlUploadModal}
|
||||
loading={webCrawlUploadLoading}
|
||||
onOk={onWebCrawlUploadOk}
|
||||
></WebCrawlModal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default KnowledgeFile;
|
||||
|
@ -15,7 +15,10 @@ import ModelSetting from './model-setting';
|
||||
import PromptEngine from './prompt-engine';
|
||||
|
||||
import { useTranslate } from '@/hooks/commonHooks';
|
||||
import { useFetchLlmModelOnVisible, useFetchModelId } from '@/hooks/logicHooks';
|
||||
import {
|
||||
useFetchLlmModelOnVisible,
|
||||
useFetchModelId,
|
||||
} from '@/hooks/logic-hooks';
|
||||
import { getBase64FromUploadFileList } from '@/utils/fileUtil';
|
||||
import { removeUselessFieldsFromValues } from '@/utils/form';
|
||||
import styles from './index.less';
|
||||
|
@ -23,7 +23,7 @@ import {
|
||||
useShowDeleteConfirm,
|
||||
useTranslate,
|
||||
} from '@/hooks/commonHooks';
|
||||
import { useSendMessageWithSse } from '@/hooks/logicHooks';
|
||||
import { useSendMessageWithSse } from '@/hooks/logic-hooks';
|
||||
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
||||
import {
|
||||
IAnswer,
|
||||
@ -552,7 +552,7 @@ export const useSendMessage = (
|
||||
const { handleInputChange, value, setValue } = useHandleMessageInputChange();
|
||||
|
||||
const { handleClickConversation } = useClickConversationCard();
|
||||
const { send, answer, done } = useSendMessageWithSse();
|
||||
const { send, answer, done, setDone } = useSendMessageWithSse();
|
||||
|
||||
const sendMessage = useCallback(
|
||||
async (message: string, id?: string) => {
|
||||
@ -609,11 +609,19 @@ export const useSendMessage = (
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// #1289
|
||||
if (answer.answer && answer?.conversationId === conversationId) {
|
||||
addNewestAnswer(answer);
|
||||
}
|
||||
}, [answer, addNewestAnswer, conversationId]);
|
||||
|
||||
useEffect(() => {
|
||||
// #1289 switch to another conversion window when the last conversion answer doesn't finish.
|
||||
if (conversationId) {
|
||||
setDone(true);
|
||||
}
|
||||
}, [setDone, conversationId]);
|
||||
|
||||
const handlePressEnter = useCallback(() => {
|
||||
if (trim(value) === '') return;
|
||||
|
||||
|
@ -1,381 +1,381 @@
|
||||
import { ReactComponent as ChatAppCube } from '@/assets/svg/chat-app-cube.svg';
|
||||
import RenameModal from '@/components/rename-modal';
|
||||
import {
|
||||
CloudOutlined,
|
||||
DeleteOutlined,
|
||||
EditOutlined,
|
||||
PlusOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
Card,
|
||||
Divider,
|
||||
Dropdown,
|
||||
Flex,
|
||||
MenuProps,
|
||||
Space,
|
||||
Spin,
|
||||
Tag,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
import { MenuItemProps } from 'antd/lib/menu/MenuItem';
|
||||
import classNames from 'classnames';
|
||||
import { useCallback } from 'react';
|
||||
import ChatConfigurationModal from './chat-configuration-modal';
|
||||
import ChatContainer from './chat-container';
|
||||
import {
|
||||
useClickConversationCard,
|
||||
useClickDialogCard,
|
||||
useDeleteConversation,
|
||||
useDeleteDialog,
|
||||
useEditDialog,
|
||||
useFetchConversationListOnMount,
|
||||
useFetchDialogOnMount,
|
||||
useGetChatSearchParams,
|
||||
useHandleItemHover,
|
||||
useRenameConversation,
|
||||
useSelectConversationListLoading,
|
||||
useSelectDerivedConversationList,
|
||||
useSelectDialogListLoading,
|
||||
useSelectFirstDialogOnMount,
|
||||
} from './hooks';
|
||||
|
||||
import { useSetModalState, useTranslate } from '@/hooks/commonHooks';
|
||||
import { useSetSelectedRecord } from '@/hooks/logicHooks';
|
||||
import { IDialog } from '@/interfaces/database/chat';
|
||||
import ChatOverviewModal from './chat-overview-modal';
|
||||
import styles from './index.less';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
const Chat = () => {
|
||||
const dialogList = useSelectFirstDialogOnMount();
|
||||
const { onRemoveDialog } = useDeleteDialog();
|
||||
const { onRemoveConversation } = useDeleteConversation();
|
||||
const { handleClickDialog } = useClickDialogCard();
|
||||
const { handleClickConversation } = useClickConversationCard();
|
||||
const { dialogId, conversationId } = useGetChatSearchParams();
|
||||
const { list: conversationList, addTemporaryConversation } =
|
||||
useSelectDerivedConversationList();
|
||||
const { activated, handleItemEnter, handleItemLeave } = useHandleItemHover();
|
||||
const {
|
||||
activated: conversationActivated,
|
||||
handleItemEnter: handleConversationItemEnter,
|
||||
handleItemLeave: handleConversationItemLeave,
|
||||
} = useHandleItemHover();
|
||||
const {
|
||||
conversationRenameLoading,
|
||||
initialConversationName,
|
||||
onConversationRenameOk,
|
||||
conversationRenameVisible,
|
||||
hideConversationRenameModal,
|
||||
showConversationRenameModal,
|
||||
} = useRenameConversation();
|
||||
const {
|
||||
dialogSettingLoading,
|
||||
initialDialog,
|
||||
onDialogEditOk,
|
||||
dialogEditVisible,
|
||||
clearDialog,
|
||||
hideDialogEditModal,
|
||||
showDialogEditModal,
|
||||
} = useEditDialog();
|
||||
const dialogLoading = useSelectDialogListLoading();
|
||||
const conversationLoading = useSelectConversationListLoading();
|
||||
const { t } = useTranslate('chat');
|
||||
const {
|
||||
visible: overviewVisible,
|
||||
hideModal: hideOverviewModal,
|
||||
showModal: showOverviewModal,
|
||||
} = useSetModalState();
|
||||
const { currentRecord, setRecord } = useSetSelectedRecord<IDialog>();
|
||||
|
||||
useFetchDialogOnMount(dialogId, true);
|
||||
|
||||
const handleAppCardEnter = (id: string) => () => {
|
||||
handleItemEnter(id);
|
||||
};
|
||||
|
||||
const handleConversationCardEnter = (id: string) => () => {
|
||||
handleConversationItemEnter(id);
|
||||
};
|
||||
|
||||
const handleShowChatConfigurationModal =
|
||||
(dialogId?: string): any =>
|
||||
(info: any) => {
|
||||
info?.domEvent?.preventDefault();
|
||||
info?.domEvent?.stopPropagation();
|
||||
showDialogEditModal(dialogId);
|
||||
};
|
||||
|
||||
const handleRemoveDialog =
|
||||
(dialogId: string): MenuItemProps['onClick'] =>
|
||||
({ domEvent }) => {
|
||||
domEvent.preventDefault();
|
||||
domEvent.stopPropagation();
|
||||
onRemoveDialog([dialogId]);
|
||||
};
|
||||
|
||||
const handleShowOverviewModal =
|
||||
(dialog: IDialog): any =>
|
||||
(info: any) => {
|
||||
info?.domEvent?.preventDefault();
|
||||
info?.domEvent?.stopPropagation();
|
||||
setRecord(dialog);
|
||||
showOverviewModal();
|
||||
};
|
||||
|
||||
const handleRemoveConversation =
|
||||
(conversationId: string): MenuItemProps['onClick'] =>
|
||||
({ domEvent }) => {
|
||||
domEvent.preventDefault();
|
||||
domEvent.stopPropagation();
|
||||
onRemoveConversation([conversationId]);
|
||||
};
|
||||
|
||||
const handleShowConversationRenameModal =
|
||||
(conversationId: string): MenuItemProps['onClick'] =>
|
||||
({ domEvent }) => {
|
||||
domEvent.preventDefault();
|
||||
domEvent.stopPropagation();
|
||||
showConversationRenameModal(conversationId);
|
||||
};
|
||||
|
||||
const handleDialogCardClick = (dialogId: string) => () => {
|
||||
handleClickDialog(dialogId);
|
||||
};
|
||||
|
||||
const handleConversationCardClick = (dialogId: string) => () => {
|
||||
handleClickConversation(dialogId);
|
||||
};
|
||||
|
||||
const handleCreateTemporaryConversation = useCallback(() => {
|
||||
addTemporaryConversation();
|
||||
}, [addTemporaryConversation]);
|
||||
|
||||
const items: MenuProps['items'] = [
|
||||
{
|
||||
key: '1',
|
||||
onClick: handleCreateTemporaryConversation,
|
||||
label: (
|
||||
<Space>
|
||||
<PlusOutlined />
|
||||
{t('newChat')}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const buildAppItems = (dialog: IDialog) => {
|
||||
const dialogId = dialog.id;
|
||||
|
||||
const appItems: MenuProps['items'] = [
|
||||
{
|
||||
key: '1',
|
||||
onClick: handleShowChatConfigurationModal(dialogId),
|
||||
label: (
|
||||
<Space>
|
||||
<EditOutlined />
|
||||
{t('edit', { keyPrefix: 'common' })}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{ type: 'divider' },
|
||||
{
|
||||
key: '2',
|
||||
onClick: handleRemoveDialog(dialogId),
|
||||
label: (
|
||||
<Space>
|
||||
<DeleteOutlined />
|
||||
{t('delete', { keyPrefix: 'common' })}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{ type: 'divider' },
|
||||
{
|
||||
key: '3',
|
||||
onClick: handleShowOverviewModal(dialog),
|
||||
label: (
|
||||
<Space>
|
||||
<CloudOutlined />
|
||||
{t('overview')}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return appItems;
|
||||
};
|
||||
|
||||
const buildConversationItems = (conversationId: string) => {
|
||||
const appItems: MenuProps['items'] = [
|
||||
{
|
||||
key: '1',
|
||||
onClick: handleShowConversationRenameModal(conversationId),
|
||||
label: (
|
||||
<Space>
|
||||
<EditOutlined />
|
||||
{t('rename', { keyPrefix: 'common' })}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{ type: 'divider' },
|
||||
{
|
||||
key: '2',
|
||||
onClick: handleRemoveConversation(conversationId),
|
||||
label: (
|
||||
<Space>
|
||||
<DeleteOutlined />
|
||||
{t('delete', { keyPrefix: 'common' })}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return appItems;
|
||||
};
|
||||
|
||||
useFetchConversationListOnMount();
|
||||
|
||||
return (
|
||||
<Flex className={styles.chatWrapper}>
|
||||
<Flex className={styles.chatAppWrapper}>
|
||||
<Flex flex={1} vertical>
|
||||
<Button type="primary" onClick={handleShowChatConfigurationModal()}>
|
||||
{t('createAssistant')}
|
||||
</Button>
|
||||
<Divider></Divider>
|
||||
<Flex className={styles.chatAppContent} vertical gap={10}>
|
||||
<Spin spinning={dialogLoading} wrapperClassName={styles.chatSpin}>
|
||||
{dialogList.map((x) => (
|
||||
<Card
|
||||
key={x.id}
|
||||
hoverable
|
||||
className={classNames(styles.chatAppCard, {
|
||||
[styles.chatAppCardSelected]: dialogId === x.id,
|
||||
})}
|
||||
onMouseEnter={handleAppCardEnter(x.id)}
|
||||
onMouseLeave={handleItemLeave}
|
||||
onClick={handleDialogCardClick(x.id)}
|
||||
>
|
||||
<Flex justify="space-between" align="center">
|
||||
<Space size={15}>
|
||||
<Avatar src={x.icon} shape={'square'} />
|
||||
<section>
|
||||
<b>
|
||||
<Text
|
||||
ellipsis={{ tooltip: x.name }}
|
||||
style={{ width: 130 }}
|
||||
>
|
||||
{x.name}
|
||||
</Text>
|
||||
</b>
|
||||
<div>{x.description}</div>
|
||||
</section>
|
||||
</Space>
|
||||
{activated === x.id && (
|
||||
<section>
|
||||
<Dropdown menu={{ items: buildAppItems(x) }}>
|
||||
<ChatAppCube
|
||||
className={styles.cubeIcon}
|
||||
></ChatAppCube>
|
||||
</Dropdown>
|
||||
</section>
|
||||
)}
|
||||
</Flex>
|
||||
</Card>
|
||||
))}
|
||||
</Spin>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Divider type={'vertical'} className={styles.divider}></Divider>
|
||||
<Flex className={styles.chatTitleWrapper}>
|
||||
<Flex flex={1} vertical>
|
||||
<Flex
|
||||
justify={'space-between'}
|
||||
align="center"
|
||||
className={styles.chatTitle}
|
||||
>
|
||||
<Space>
|
||||
<b>{t('chat')}</b>
|
||||
<Tag>{conversationList.length}</Tag>
|
||||
</Space>
|
||||
<Dropdown menu={{ items }}>
|
||||
{/* <FormOutlined /> */}
|
||||
<PlusOutlined />
|
||||
</Dropdown>
|
||||
</Flex>
|
||||
<Divider></Divider>
|
||||
<Flex vertical gap={10} className={styles.chatTitleContent}>
|
||||
<Spin
|
||||
spinning={conversationLoading}
|
||||
wrapperClassName={styles.chatSpin}
|
||||
>
|
||||
{conversationList.map((x) => (
|
||||
<Card
|
||||
key={x.id}
|
||||
hoverable
|
||||
onClick={handleConversationCardClick(x.id)}
|
||||
onMouseEnter={handleConversationCardEnter(x.id)}
|
||||
onMouseLeave={handleConversationItemLeave}
|
||||
className={classNames(styles.chatTitleCard, {
|
||||
[styles.chatTitleCardSelected]: x.id === conversationId,
|
||||
})}
|
||||
>
|
||||
<Flex justify="space-between" align="center">
|
||||
<div>
|
||||
<Text
|
||||
ellipsis={{ tooltip: x.name }}
|
||||
style={{ width: 150 }}
|
||||
>
|
||||
{x.name}
|
||||
</Text>
|
||||
</div>
|
||||
{conversationActivated === x.id && x.id !== '' && (
|
||||
<section>
|
||||
<Dropdown
|
||||
menu={{ items: buildConversationItems(x.id) }}
|
||||
>
|
||||
<ChatAppCube
|
||||
className={styles.cubeIcon}
|
||||
></ChatAppCube>
|
||||
</Dropdown>
|
||||
</section>
|
||||
)}
|
||||
</Flex>
|
||||
</Card>
|
||||
))}
|
||||
</Spin>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Divider type={'vertical'} className={styles.divider}></Divider>
|
||||
<ChatContainer></ChatContainer>
|
||||
<ChatConfigurationModal
|
||||
visible={dialogEditVisible}
|
||||
initialDialog={initialDialog}
|
||||
showModal={showDialogEditModal}
|
||||
hideModal={hideDialogEditModal}
|
||||
loading={dialogSettingLoading}
|
||||
onOk={onDialogEditOk}
|
||||
clearDialog={clearDialog}
|
||||
></ChatConfigurationModal>
|
||||
<RenameModal
|
||||
visible={conversationRenameVisible}
|
||||
hideModal={hideConversationRenameModal}
|
||||
onOk={onConversationRenameOk}
|
||||
initialName={initialConversationName}
|
||||
loading={conversationRenameLoading}
|
||||
></RenameModal>
|
||||
<ChatOverviewModal
|
||||
visible={overviewVisible}
|
||||
hideModal={hideOverviewModal}
|
||||
dialog={currentRecord}
|
||||
></ChatOverviewModal>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default Chat;
|
||||
import { ReactComponent as ChatAppCube } from '@/assets/svg/chat-app-cube.svg';
|
||||
import RenameModal from '@/components/rename-modal';
|
||||
import {
|
||||
CloudOutlined,
|
||||
DeleteOutlined,
|
||||
EditOutlined,
|
||||
PlusOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import {
|
||||
Avatar,
|
||||
Button,
|
||||
Card,
|
||||
Divider,
|
||||
Dropdown,
|
||||
Flex,
|
||||
MenuProps,
|
||||
Space,
|
||||
Spin,
|
||||
Tag,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
import { MenuItemProps } from 'antd/lib/menu/MenuItem';
|
||||
import classNames from 'classnames';
|
||||
import { useCallback } from 'react';
|
||||
import ChatConfigurationModal from './chat-configuration-modal';
|
||||
import ChatContainer from './chat-container';
|
||||
import {
|
||||
useClickConversationCard,
|
||||
useClickDialogCard,
|
||||
useDeleteConversation,
|
||||
useDeleteDialog,
|
||||
useEditDialog,
|
||||
useFetchConversationListOnMount,
|
||||
useFetchDialogOnMount,
|
||||
useGetChatSearchParams,
|
||||
useHandleItemHover,
|
||||
useRenameConversation,
|
||||
useSelectConversationListLoading,
|
||||
useSelectDerivedConversationList,
|
||||
useSelectDialogListLoading,
|
||||
useSelectFirstDialogOnMount,
|
||||
} from './hooks';
|
||||
|
||||
import { useSetModalState, useTranslate } from '@/hooks/commonHooks';
|
||||
import { useSetSelectedRecord } from '@/hooks/logic-hooks';
|
||||
import { IDialog } from '@/interfaces/database/chat';
|
||||
import ChatOverviewModal from './chat-overview-modal';
|
||||
import styles from './index.less';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
const Chat = () => {
|
||||
const dialogList = useSelectFirstDialogOnMount();
|
||||
const { onRemoveDialog } = useDeleteDialog();
|
||||
const { onRemoveConversation } = useDeleteConversation();
|
||||
const { handleClickDialog } = useClickDialogCard();
|
||||
const { handleClickConversation } = useClickConversationCard();
|
||||
const { dialogId, conversationId } = useGetChatSearchParams();
|
||||
const { list: conversationList, addTemporaryConversation } =
|
||||
useSelectDerivedConversationList();
|
||||
const { activated, handleItemEnter, handleItemLeave } = useHandleItemHover();
|
||||
const {
|
||||
activated: conversationActivated,
|
||||
handleItemEnter: handleConversationItemEnter,
|
||||
handleItemLeave: handleConversationItemLeave,
|
||||
} = useHandleItemHover();
|
||||
const {
|
||||
conversationRenameLoading,
|
||||
initialConversationName,
|
||||
onConversationRenameOk,
|
||||
conversationRenameVisible,
|
||||
hideConversationRenameModal,
|
||||
showConversationRenameModal,
|
||||
} = useRenameConversation();
|
||||
const {
|
||||
dialogSettingLoading,
|
||||
initialDialog,
|
||||
onDialogEditOk,
|
||||
dialogEditVisible,
|
||||
clearDialog,
|
||||
hideDialogEditModal,
|
||||
showDialogEditModal,
|
||||
} = useEditDialog();
|
||||
const dialogLoading = useSelectDialogListLoading();
|
||||
const conversationLoading = useSelectConversationListLoading();
|
||||
const { t } = useTranslate('chat');
|
||||
const {
|
||||
visible: overviewVisible,
|
||||
hideModal: hideOverviewModal,
|
||||
showModal: showOverviewModal,
|
||||
} = useSetModalState();
|
||||
const { currentRecord, setRecord } = useSetSelectedRecord<IDialog>();
|
||||
|
||||
useFetchDialogOnMount(dialogId, true);
|
||||
|
||||
const handleAppCardEnter = (id: string) => () => {
|
||||
handleItemEnter(id);
|
||||
};
|
||||
|
||||
const handleConversationCardEnter = (id: string) => () => {
|
||||
handleConversationItemEnter(id);
|
||||
};
|
||||
|
||||
const handleShowChatConfigurationModal =
|
||||
(dialogId?: string): any =>
|
||||
(info: any) => {
|
||||
info?.domEvent?.preventDefault();
|
||||
info?.domEvent?.stopPropagation();
|
||||
showDialogEditModal(dialogId);
|
||||
};
|
||||
|
||||
const handleRemoveDialog =
|
||||
(dialogId: string): MenuItemProps['onClick'] =>
|
||||
({ domEvent }) => {
|
||||
domEvent.preventDefault();
|
||||
domEvent.stopPropagation();
|
||||
onRemoveDialog([dialogId]);
|
||||
};
|
||||
|
||||
const handleShowOverviewModal =
|
||||
(dialog: IDialog): any =>
|
||||
(info: any) => {
|
||||
info?.domEvent?.preventDefault();
|
||||
info?.domEvent?.stopPropagation();
|
||||
setRecord(dialog);
|
||||
showOverviewModal();
|
||||
};
|
||||
|
||||
const handleRemoveConversation =
|
||||
(conversationId: string): MenuItemProps['onClick'] =>
|
||||
({ domEvent }) => {
|
||||
domEvent.preventDefault();
|
||||
domEvent.stopPropagation();
|
||||
onRemoveConversation([conversationId]);
|
||||
};
|
||||
|
||||
const handleShowConversationRenameModal =
|
||||
(conversationId: string): MenuItemProps['onClick'] =>
|
||||
({ domEvent }) => {
|
||||
domEvent.preventDefault();
|
||||
domEvent.stopPropagation();
|
||||
showConversationRenameModal(conversationId);
|
||||
};
|
||||
|
||||
const handleDialogCardClick = (dialogId: string) => () => {
|
||||
handleClickDialog(dialogId);
|
||||
};
|
||||
|
||||
const handleConversationCardClick = (dialogId: string) => () => {
|
||||
handleClickConversation(dialogId);
|
||||
};
|
||||
|
||||
const handleCreateTemporaryConversation = useCallback(() => {
|
||||
addTemporaryConversation();
|
||||
}, [addTemporaryConversation]);
|
||||
|
||||
const items: MenuProps['items'] = [
|
||||
{
|
||||
key: '1',
|
||||
onClick: handleCreateTemporaryConversation,
|
||||
label: (
|
||||
<Space>
|
||||
<PlusOutlined />
|
||||
{t('newChat')}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const buildAppItems = (dialog: IDialog) => {
|
||||
const dialogId = dialog.id;
|
||||
|
||||
const appItems: MenuProps['items'] = [
|
||||
{
|
||||
key: '1',
|
||||
onClick: handleShowChatConfigurationModal(dialogId),
|
||||
label: (
|
||||
<Space>
|
||||
<EditOutlined />
|
||||
{t('edit', { keyPrefix: 'common' })}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{ type: 'divider' },
|
||||
{
|
||||
key: '2',
|
||||
onClick: handleRemoveDialog(dialogId),
|
||||
label: (
|
||||
<Space>
|
||||
<DeleteOutlined />
|
||||
{t('delete', { keyPrefix: 'common' })}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{ type: 'divider' },
|
||||
{
|
||||
key: '3',
|
||||
onClick: handleShowOverviewModal(dialog),
|
||||
label: (
|
||||
<Space>
|
||||
<CloudOutlined />
|
||||
{t('overview')}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return appItems;
|
||||
};
|
||||
|
||||
const buildConversationItems = (conversationId: string) => {
|
||||
const appItems: MenuProps['items'] = [
|
||||
{
|
||||
key: '1',
|
||||
onClick: handleShowConversationRenameModal(conversationId),
|
||||
label: (
|
||||
<Space>
|
||||
<EditOutlined />
|
||||
{t('rename', { keyPrefix: 'common' })}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{ type: 'divider' },
|
||||
{
|
||||
key: '2',
|
||||
onClick: handleRemoveConversation(conversationId),
|
||||
label: (
|
||||
<Space>
|
||||
<DeleteOutlined />
|
||||
{t('delete', { keyPrefix: 'common' })}
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return appItems;
|
||||
};
|
||||
|
||||
useFetchConversationListOnMount();
|
||||
|
||||
return (
|
||||
<Flex className={styles.chatWrapper}>
|
||||
<Flex className={styles.chatAppWrapper}>
|
||||
<Flex flex={1} vertical>
|
||||
<Button type="primary" onClick={handleShowChatConfigurationModal()}>
|
||||
{t('createAssistant')}
|
||||
</Button>
|
||||
<Divider></Divider>
|
||||
<Flex className={styles.chatAppContent} vertical gap={10}>
|
||||
<Spin spinning={dialogLoading} wrapperClassName={styles.chatSpin}>
|
||||
{dialogList.map((x) => (
|
||||
<Card
|
||||
key={x.id}
|
||||
hoverable
|
||||
className={classNames(styles.chatAppCard, {
|
||||
[styles.chatAppCardSelected]: dialogId === x.id,
|
||||
})}
|
||||
onMouseEnter={handleAppCardEnter(x.id)}
|
||||
onMouseLeave={handleItemLeave}
|
||||
onClick={handleDialogCardClick(x.id)}
|
||||
>
|
||||
<Flex justify="space-between" align="center">
|
||||
<Space size={15}>
|
||||
<Avatar src={x.icon} shape={'square'} />
|
||||
<section>
|
||||
<b>
|
||||
<Text
|
||||
ellipsis={{ tooltip: x.name }}
|
||||
style={{ width: 130 }}
|
||||
>
|
||||
{x.name}
|
||||
</Text>
|
||||
</b>
|
||||
<div>{x.description}</div>
|
||||
</section>
|
||||
</Space>
|
||||
{activated === x.id && (
|
||||
<section>
|
||||
<Dropdown menu={{ items: buildAppItems(x) }}>
|
||||
<ChatAppCube
|
||||
className={styles.cubeIcon}
|
||||
></ChatAppCube>
|
||||
</Dropdown>
|
||||
</section>
|
||||
)}
|
||||
</Flex>
|
||||
</Card>
|
||||
))}
|
||||
</Spin>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Divider type={'vertical'} className={styles.divider}></Divider>
|
||||
<Flex className={styles.chatTitleWrapper}>
|
||||
<Flex flex={1} vertical>
|
||||
<Flex
|
||||
justify={'space-between'}
|
||||
align="center"
|
||||
className={styles.chatTitle}
|
||||
>
|
||||
<Space>
|
||||
<b>{t('chat')}</b>
|
||||
<Tag>{conversationList.length}</Tag>
|
||||
</Space>
|
||||
<Dropdown menu={{ items }}>
|
||||
{/* <FormOutlined /> */}
|
||||
<PlusOutlined />
|
||||
</Dropdown>
|
||||
</Flex>
|
||||
<Divider></Divider>
|
||||
<Flex vertical gap={10} className={styles.chatTitleContent}>
|
||||
<Spin
|
||||
spinning={conversationLoading}
|
||||
wrapperClassName={styles.chatSpin}
|
||||
>
|
||||
{conversationList.map((x) => (
|
||||
<Card
|
||||
key={x.id}
|
||||
hoverable
|
||||
onClick={handleConversationCardClick(x.id)}
|
||||
onMouseEnter={handleConversationCardEnter(x.id)}
|
||||
onMouseLeave={handleConversationItemLeave}
|
||||
className={classNames(styles.chatTitleCard, {
|
||||
[styles.chatTitleCardSelected]: x.id === conversationId,
|
||||
})}
|
||||
>
|
||||
<Flex justify="space-between" align="center">
|
||||
<div>
|
||||
<Text
|
||||
ellipsis={{ tooltip: x.name }}
|
||||
style={{ width: 150 }}
|
||||
>
|
||||
{x.name}
|
||||
</Text>
|
||||
</div>
|
||||
{conversationActivated === x.id && x.id !== '' && (
|
||||
<section>
|
||||
<Dropdown
|
||||
menu={{ items: buildConversationItems(x.id) }}
|
||||
>
|
||||
<ChatAppCube
|
||||
className={styles.cubeIcon}
|
||||
></ChatAppCube>
|
||||
</Dropdown>
|
||||
</section>
|
||||
)}
|
||||
</Flex>
|
||||
</Card>
|
||||
))}
|
||||
</Spin>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Divider type={'vertical'} className={styles.divider}></Divider>
|
||||
<ChatContainer></ChatContainer>
|
||||
<ChatConfigurationModal
|
||||
visible={dialogEditVisible}
|
||||
initialDialog={initialDialog}
|
||||
showModal={showDialogEditModal}
|
||||
hideModal={hideDialogEditModal}
|
||||
loading={dialogSettingLoading}
|
||||
onOk={onDialogEditOk}
|
||||
clearDialog={clearDialog}
|
||||
></ChatConfigurationModal>
|
||||
<RenameModal
|
||||
visible={conversationRenameVisible}
|
||||
hideModal={hideConversationRenameModal}
|
||||
onOk={onConversationRenameOk}
|
||||
initialName={initialConversationName}
|
||||
loading={conversationRenameLoading}
|
||||
></RenameModal>
|
||||
<ChatOverviewModal
|
||||
visible={overviewVisible}
|
||||
hideModal={hideOverviewModal}
|
||||
dialog={currentRecord}
|
||||
></ChatOverviewModal>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default Chat;
|
||||
|
@ -3,7 +3,7 @@ import {
|
||||
useCreateSharedConversation,
|
||||
useFetchSharedConversation,
|
||||
} from '@/hooks/chatHooks';
|
||||
import { useSendMessageWithSse } from '@/hooks/logicHooks';
|
||||
import { useSendMessageWithSse } from '@/hooks/logic-hooks';
|
||||
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
||||
import { IAnswer } from '@/interfaces/database/chat';
|
||||
import api from '@/utils/api';
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
useSelectParentFolderList,
|
||||
useUploadFile,
|
||||
} from '@/hooks/fileManagerHooks';
|
||||
import { useGetPagination, useSetPagination } from '@/hooks/logicHooks';
|
||||
import { useGetPagination, useSetPagination } from '@/hooks/logic-hooks';
|
||||
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
||||
import { IFile } from '@/interfaces/database/file-manager';
|
||||
import { PaginationProps } from 'antd';
|
||||
|
@ -4,7 +4,7 @@ import {
|
||||
useHandleMessageInputChange,
|
||||
useScrollToBottom,
|
||||
useSendMessageWithSse,
|
||||
} from '@/hooks/logicHooks';
|
||||
} from '@/hooks/logic-hooks';
|
||||
import { IAnswer } from '@/interfaces/database/chat';
|
||||
import { IMessage } from '@/pages/chat/interface';
|
||||
import api from '@/utils/api';
|
||||
|
@ -18,7 +18,7 @@ import {
|
||||
ModelVariableType,
|
||||
settledModelVariableMap,
|
||||
} from '@/constants/knowledge';
|
||||
import { useFetchModelId, useSendMessageWithSse } from '@/hooks/logicHooks';
|
||||
import { useFetchModelId, useSendMessageWithSse } from '@/hooks/logic-hooks';
|
||||
import { Variable } from '@/interfaces/database/chat';
|
||||
import api from '@/utils/api';
|
||||
import { useDebounceEffect } from 'ahooks';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { IModalManagerChildrenProps } from '@/components/modal-manager';
|
||||
import { useTranslate } from '@/hooks/commonHooks';
|
||||
import { useFetchFlowTemplates } from '@/hooks/flow-hooks';
|
||||
import { useSelectItem } from '@/hooks/logicHooks';
|
||||
import { useSelectItem } from '@/hooks/logic-hooks';
|
||||
import { Card, Flex, Form, Input, Modal, Space, Typography } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import { useEffect } from 'react';
|
||||
|
@ -32,7 +32,7 @@ import {
|
||||
|
||||
import { LanguageList } from '@/constants/common';
|
||||
import { useTranslate } from '@/hooks/commonHooks';
|
||||
import { useChangeLanguage } from '@/hooks/logicHooks';
|
||||
import { useChangeLanguage } from '@/hooks/logic-hooks';
|
||||
import parentStyles from '../index.less';
|
||||
import styles from './index.less';
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user