feat: rename conversation
This commit is contained in:
parent
627f2ed0c7
commit
c5df762558
6 changed files with 198 additions and 19 deletions
78
web/src/components/rename-modal/index.tsx
Normal file
78
web/src/components/rename-modal/index.tsx
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
import { Form, Input, Modal } from 'antd';
|
||||
import { useEffect } from 'react';
|
||||
import { IModalManagerChildrenProps } from '../modal-manager';
|
||||
|
||||
interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
|
||||
loading: boolean;
|
||||
initialName: string;
|
||||
onOk: (name: string) => void;
|
||||
showModal?(): void;
|
||||
}
|
||||
|
||||
const RenameModal = ({
|
||||
visible,
|
||||
hideModal,
|
||||
loading,
|
||||
initialName,
|
||||
onOk,
|
||||
}: IProps) => {
|
||||
const [form] = Form.useForm();
|
||||
|
||||
type FieldType = {
|
||||
name?: string;
|
||||
};
|
||||
|
||||
const handleOk = async () => {
|
||||
const ret = await form.validateFields();
|
||||
|
||||
return onOk(ret.name);
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
hideModal();
|
||||
};
|
||||
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Success:', values);
|
||||
};
|
||||
|
||||
const onFinishFailed = (errorInfo: any) => {
|
||||
console.log('Failed:', errorInfo);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
form.setFieldValue('name', initialName);
|
||||
}, [initialName, form]);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="Rename"
|
||||
open={visible}
|
||||
onOk={handleOk}
|
||||
onCancel={handleCancel}
|
||||
okButtonProps={{ loading }}
|
||||
confirmLoading={loading}
|
||||
>
|
||||
<Form
|
||||
name="basic"
|
||||
labelCol={{ span: 4 }}
|
||||
wrapperCol={{ span: 20 }}
|
||||
style={{ maxWidth: 600 }}
|
||||
onFinish={onFinish}
|
||||
onFinishFailed={onFinishFailed}
|
||||
autoComplete="off"
|
||||
form={form}
|
||||
>
|
||||
<Form.Item<FieldType>
|
||||
label="Name"
|
||||
name="name"
|
||||
rules={[{ required: true, message: 'Please input name!' }]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default RenameModal;
|
||||
|
|
@ -8,7 +8,7 @@ import classNames from 'classnames';
|
|||
import { ChangeEventHandler, useCallback, useMemo, useState } from 'react';
|
||||
import reactStringReplace from 'react-string-replace';
|
||||
import {
|
||||
useFetchConversation,
|
||||
useFetchConversationOnMount,
|
||||
useGetFileIcon,
|
||||
useScrollToBottom,
|
||||
useSendMessage,
|
||||
|
|
@ -187,7 +187,7 @@ const MessageItem = ({
|
|||
|
||||
const ChatContainer = () => {
|
||||
const [value, setValue] = useState('');
|
||||
const conversation: IClientConversation = useFetchConversation();
|
||||
const conversation: IClientConversation = useFetchConversationOnMount();
|
||||
const { sendMessage } = useSendMessage();
|
||||
const loading = useOneNamespaceEffectsLoading('chatModel', [
|
||||
'completeConversation',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import showDeleteConfirm from '@/components/deleting-confirm';
|
||||
import { MessageType } from '@/constants/chat';
|
||||
import { fileIconMap } from '@/constants/common';
|
||||
import { useSetModalState } from '@/hooks/commonHooks';
|
||||
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
||||
import { IConversation, IDialog } from '@/interfaces/database/chat';
|
||||
import { getFileExtension } from '@/utils';
|
||||
import omit from 'lodash/omit';
|
||||
|
|
@ -14,7 +16,7 @@ import {
|
|||
VariableTableDataType,
|
||||
} from './interface';
|
||||
import { ChatModelState } from './model';
|
||||
import { isConversationIdNotExist } from './utils';
|
||||
import { isConversationIdExist } from './utils';
|
||||
|
||||
export const useFetchDialogList = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
|
@ -392,30 +394,50 @@ export const useSetConversation = () => {
|
|||
return { setConversation };
|
||||
};
|
||||
|
||||
export const useFetchConversation = () => {
|
||||
const dispatch = useDispatch();
|
||||
const { conversationId } = useGetChatSearchParams();
|
||||
const conversation = useSelector(
|
||||
export const useSelectCurrentConversation = () => {
|
||||
const conversation: IClientConversation = useSelector(
|
||||
(state: any) => state.chatModel.currentConversation,
|
||||
);
|
||||
const setCurrentConversation = useSetCurrentConversation();
|
||||
|
||||
const fetchConversation = useCallback(() => {
|
||||
if (isConversationIdNotExist(conversationId)) {
|
||||
dispatch({
|
||||
return conversation;
|
||||
};
|
||||
|
||||
export const useFetchConversation = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const fetchConversation = useCallback(
|
||||
(conversationId: string, needToBeSaved = true) => {
|
||||
return dispatch<any>({
|
||||
type: 'chatModel/getConversation',
|
||||
payload: {
|
||||
needToBeSaved,
|
||||
conversation_id: conversationId,
|
||||
},
|
||||
});
|
||||
},
|
||||
[dispatch],
|
||||
);
|
||||
|
||||
return fetchConversation;
|
||||
};
|
||||
|
||||
export const useFetchConversationOnMount = () => {
|
||||
const { conversationId } = useGetChatSearchParams();
|
||||
const conversation = useSelectCurrentConversation();
|
||||
const setCurrentConversation = useSetCurrentConversation();
|
||||
const fetchConversation = useFetchConversation();
|
||||
|
||||
const fetchConversationOnMount = useCallback(() => {
|
||||
if (isConversationIdExist(conversationId)) {
|
||||
fetchConversation(conversationId);
|
||||
} else {
|
||||
setCurrentConversation({} as IClientConversation);
|
||||
}
|
||||
}, [dispatch, conversationId, setCurrentConversation]);
|
||||
}, [fetchConversation, setCurrentConversation, conversationId]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchConversation();
|
||||
}, [fetchConversation]);
|
||||
fetchConversationOnMount();
|
||||
}, [fetchConversationOnMount]);
|
||||
|
||||
return conversation;
|
||||
};
|
||||
|
|
@ -522,4 +544,56 @@ export const useRemoveConversation = () => {
|
|||
|
||||
return { onRemoveConversation };
|
||||
};
|
||||
|
||||
export const useRenameConversation = () => {
|
||||
const dispatch = useDispatch();
|
||||
const [conversation, setConversation] = useState<IClientConversation>(
|
||||
{} as IClientConversation,
|
||||
);
|
||||
const fetchConversation = useFetchConversation();
|
||||
const {
|
||||
visible: conversationRenameVisible,
|
||||
hideModal: hideConversationRenameModal,
|
||||
showModal: showConversationRenameModal,
|
||||
} = useSetModalState();
|
||||
|
||||
const onConversationRenameOk = useCallback(
|
||||
async (name: string) => {
|
||||
const ret = await dispatch<any>({
|
||||
type: 'chatModel/setConversation',
|
||||
payload: { ...conversation, conversation_id: conversation.id, name },
|
||||
});
|
||||
|
||||
if (ret.retcode === 0) {
|
||||
hideConversationRenameModal();
|
||||
}
|
||||
},
|
||||
[dispatch, conversation, hideConversationRenameModal],
|
||||
);
|
||||
|
||||
const loading = useOneNamespaceEffectsLoading('chatModel', [
|
||||
'setConversation',
|
||||
]);
|
||||
|
||||
const handleShowConversationRenameModal = useCallback(
|
||||
async (conversationId: string) => {
|
||||
const ret = await fetchConversation(conversationId, false);
|
||||
if (ret.retcode === 0) {
|
||||
setConversation(ret.data);
|
||||
}
|
||||
showConversationRenameModal();
|
||||
},
|
||||
[showConversationRenameModal, fetchConversation],
|
||||
);
|
||||
|
||||
return {
|
||||
conversationRenameLoading: loading,
|
||||
initialConversationName: conversation.name,
|
||||
onConversationRenameOk,
|
||||
conversationRenameVisible,
|
||||
hideConversationRenameModal,
|
||||
showConversationRenameModal: handleShowConversationRenameModal,
|
||||
};
|
||||
};
|
||||
|
||||
//#endregion
|
||||
|
|
|
|||
|
|
@ -25,11 +25,13 @@ import {
|
|||
useHandleItemHover,
|
||||
useRemoveConversation,
|
||||
useRemoveDialog,
|
||||
useRenameConversation,
|
||||
useSelectConversationList,
|
||||
useSelectFirstDialogOnMount,
|
||||
useSetCurrentDialog,
|
||||
} from './hooks';
|
||||
|
||||
import RenameModal from '@/components/rename-modal';
|
||||
import styles from './index.less';
|
||||
|
||||
const Chat = () => {
|
||||
|
|
@ -49,6 +51,14 @@ const Chat = () => {
|
|||
handleItemEnter: handleConversationItemEnter,
|
||||
handleItemLeave: handleConversationItemLeave,
|
||||
} = useHandleItemHover();
|
||||
const {
|
||||
conversationRenameLoading,
|
||||
initialConversationName,
|
||||
onConversationRenameOk,
|
||||
conversationRenameVisible,
|
||||
hideConversationRenameModal,
|
||||
showConversationRenameModal,
|
||||
} = useRenameConversation();
|
||||
|
||||
useFetchDialog(dialogId, true);
|
||||
|
||||
|
|
@ -87,6 +97,14 @@ const Chat = () => {
|
|||
onRemoveConversation([conversationId]);
|
||||
};
|
||||
|
||||
const handleShowConversationRenameModal =
|
||||
(conversationId: string): MenuItemProps['onClick'] =>
|
||||
({ domEvent }) => {
|
||||
domEvent.preventDefault();
|
||||
domEvent.stopPropagation();
|
||||
showConversationRenameModal(conversationId);
|
||||
};
|
||||
|
||||
const handleDialogCardClick = (dialogId: string) => () => {
|
||||
handleClickDialog(dialogId);
|
||||
};
|
||||
|
|
@ -143,7 +161,7 @@ const Chat = () => {
|
|||
const appItems: MenuProps['items'] = [
|
||||
{
|
||||
key: '1',
|
||||
onClick: handleShowChatConfigurationModal(conversationId),
|
||||
onClick: handleShowConversationRenameModal(conversationId),
|
||||
label: (
|
||||
<Space>
|
||||
<EditOutlined />
|
||||
|
|
@ -262,6 +280,13 @@ const Chat = () => {
|
|||
hideModal={hideModal}
|
||||
id={currentDialog.id}
|
||||
></ChatConfigurationModal>
|
||||
<RenameModal
|
||||
visible={conversationRenameVisible}
|
||||
hideModal={hideConversationRenameModal}
|
||||
onOk={onConversationRenameOk}
|
||||
initialName={initialConversationName}
|
||||
loading={conversationRenameLoading}
|
||||
></RenameModal>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -110,8 +110,10 @@ const model: DvaModel<ChatModelState> = {
|
|||
return data.retcode;
|
||||
},
|
||||
*getConversation({ payload }, { call, put }) {
|
||||
const { data } = yield call(chatService.getConversation, payload);
|
||||
if (data.retcode === 0) {
|
||||
const { data } = yield call(chatService.getConversation, {
|
||||
conversation_id: payload.conversation_id,
|
||||
});
|
||||
if (data.retcode === 0 && payload.needToBeSaved) {
|
||||
yield put({
|
||||
type: 'kFModel/fetch_document_thumbnails',
|
||||
payload: {
|
||||
|
|
@ -120,7 +122,7 @@ const model: DvaModel<ChatModelState> = {
|
|||
});
|
||||
yield put({ type: 'setCurrentConversation', payload: data.data });
|
||||
}
|
||||
return data.retcode;
|
||||
return data;
|
||||
},
|
||||
*setConversation({ payload }, { call, put }) {
|
||||
const { data } = yield call(chatService.setConversation, payload);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export const excludeUnEnabledVariables = (values: any) => {
|
|||
);
|
||||
};
|
||||
|
||||
export const isConversationIdNotExist = (conversationId: string) => {
|
||||
export const isConversationIdExist = (conversationId: string) => {
|
||||
return conversationId !== EmptyConversationId && conversationId !== '';
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue