fix: disable sending messages if both application and conversation are empty and add loading to all pages (#134)

* feat: add loading to all pages

* fix: disable sending messages if both application and conversation are empty

* feat: add chatSpin class to Spin of chat
This commit is contained in:
balibabu
2024-03-20 11:13:51 +08:00
committed by GitHub
parent d38e92aac8
commit 78727c8809
24 changed files with 629 additions and 473 deletions

View File

@@ -1,14 +1,13 @@
import { useFetchKnowledgeList } from '@/hooks/knowledgeHook';
import { PlusOutlined } from '@ant-design/icons';
import { Form, Input, Select, Upload } from 'antd';
import classNames from 'classnames';
import { ISegmentedContentProps } from '../interface';
import { useFetchKnowledgeList } from '@/hooks/knowledgeHook';
import { PlusOutlined } from '@ant-design/icons';
import styles from './index.less';
const AssistantSetting = ({ show }: ISegmentedContentProps) => {
const knowledgeList = useFetchKnowledgeList(true);
const { list: knowledgeList } = useFetchKnowledgeList(true);
const knowledgeOptions = knowledgeList.map((x) => ({
label: x.name,
value: x.id,

View File

@@ -30,6 +30,7 @@ import {
useClickDrawer,
useFetchConversationOnMount,
useGetFileIcon,
useGetSendButtonDisabled,
useSendMessage,
} from '../hooks';
@@ -248,11 +249,15 @@ const ChatContainer = () => {
addNewestConversation,
removeLatestMessage,
} = useFetchConversationOnMount();
const { handleInputChange, handlePressEnter, value, loading } =
useSendMessage(conversation, addNewestConversation, removeLatestMessage);
const {
handleInputChange,
handlePressEnter,
value,
loading: sendLoading,
} = useSendMessage(conversation, addNewestConversation, removeLatestMessage);
const { visible, hideModal, documentId, selectedChunk, clickDocumentButton } =
useClickDrawer();
const disabled = useGetSendButtonDisabled();
useGetFileIcon();
return (
@@ -284,8 +289,14 @@ const ChatContainer = () => {
size="large"
placeholder="Message Resume Assistant..."
value={value}
disabled={disabled}
suffix={
<Button type="primary" onClick={handlePressEnter} loading={loading}>
<Button
type="primary"
onClick={handlePressEnter}
loading={sendLoading}
disabled={disabled}
>
Send
</Button>
}

View File

@@ -767,4 +767,16 @@ export const useClickDrawer = () => {
};
};
export const useSelectDialogListLoading = () => {
return useOneNamespaceEffectsLoading('chatModel', ['listDialog']);
};
export const useSelectConversationListLoading = () => {
return useOneNamespaceEffectsLoading('chatModel', ['listConversation']);
};
export const useGetSendButtonDisabled = () => {
const { dialogId, conversationId } = useGetChatSearchParams();
return dialogId === '' && conversationId === '';
};
//#endregion

View File

@@ -41,6 +41,14 @@
overflow: auto;
}
.chatSpin {
:global(.ant-spin-container) {
display: flex;
flex-direction: column;
gap: 10px;
}
}
.chatTitleCard {
:global(.ant-card-body) {
padding: 8px;

View File

@@ -1,5 +1,4 @@
import { ReactComponent as ChatAppCube } from '@/assets/svg/chat-app-cube.svg';
import { useSetModalState } from '@/hooks/commonHooks';
import { DeleteOutlined, EditOutlined, FormOutlined } from '@ant-design/icons';
import {
Avatar,
@@ -10,6 +9,7 @@ import {
Flex,
MenuProps,
Space,
Spin,
Tag,
} from 'antd';
import { MenuItemProps } from 'antd/lib/menu/MenuItem';
@@ -29,8 +29,9 @@ import {
useRemoveDialog,
useRenameConversation,
useSelectConversationList,
useSelectConversationListLoading,
useSelectDialogListLoading,
useSelectFirstDialogOnMount,
useSetCurrentDialog,
} from './hooks';
import RenameModal from '@/components/rename-modal';
@@ -38,8 +39,6 @@ import styles from './index.less';
const Chat = () => {
const dialogList = useSelectFirstDialogOnMount();
const { visible, hideModal, showModal } = useSetModalState();
const { setCurrentDialog, currentDialog } = useSetCurrentDialog();
const { onRemoveDialog } = useRemoveDialog();
const { onRemoveConversation } = useRemoveConversation();
const { handleClickDialog } = useClickDialogCard();
@@ -70,6 +69,8 @@ const Chat = () => {
hideDialogEditModal,
showDialogEditModal,
} = useEditDialog();
const dialogLoading = useSelectDialogListLoading();
const conversationLoading = useSelectConversationListLoading();
useFetchDialogOnMount(dialogId, true);
@@ -204,35 +205,39 @@ const Chat = () => {
</Button>
<Divider></Divider>
<Flex className={styles.chatAppContent} vertical gap={10}>
{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>{x.name}</b>
<div>{x.description}</div>
</section>
</Space>
{activated === x.id && (
<section>
<Dropdown menu={{ items: buildAppItems(x.id) }}>
<ChatAppCube className={styles.cubeIcon}></ChatAppCube>
</Dropdown>
</section>
)}
</Flex>
</Card>
))}
<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>{x.name}</b>
<div>{x.description}</div>
</section>
</Space>
{activated === x.id && (
<section>
<Dropdown menu={{ items: buildAppItems(x.id) }}>
<ChatAppCube
className={styles.cubeIcon}
></ChatAppCube>
</Dropdown>
</section>
)}
</Flex>
</Card>
))}
</Spin>
</Flex>
</Flex>
</Flex>
@@ -254,29 +259,38 @@ const Chat = () => {
</Flex>
<Divider></Divider>
<Flex vertical gap={10} className={styles.chatTitleContent}>
{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>{x.name}</div>
{conversationActivated === x.id && x.id !== '' && (
<section>
<Dropdown menu={{ items: buildConversationItems(x.id) }}>
<ChatAppCube className={styles.cubeIcon}></ChatAppCube>
</Dropdown>
</section>
)}
</Flex>
</Card>
))}
<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>{x.name}</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>