mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-23 23:16:58 +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:
@ -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';
|
||||
|
||||
Reference in New Issue
Block a user