feat: allow update conversation bot in UI

This commit is contained in:
steven
2023-04-17 17:33:20 +08:00
parent 4a0d652412
commit 2c7d816e1a
5 changed files with 50 additions and 25 deletions

View File

@ -13,12 +13,12 @@ import LocaleSwitch from "./LocaleSwitch";
import DarkModeSwitch from "./DarkModeSwitch"; import DarkModeSwitch from "./DarkModeSwitch";
import CreateConnectionModal from "./CreateConnectionModal"; import CreateConnectionModal from "./CreateConnectionModal";
import SettingModal from "./SettingModal"; import SettingModal from "./SettingModal";
import EditConversationTitleModal from "./EditConversationTitleModal"; import UpdateConversationModal from "./UpdateConversationModal";
interface State { interface State {
showCreateConnectionModal: boolean; showCreateConnectionModal: boolean;
showSettingModal: boolean; showSettingModal: boolean;
showEditConversationTitleModal: boolean; showUpdateConversationModal: boolean;
} }
const ConnectionSidebar = () => { const ConnectionSidebar = () => {
@ -29,10 +29,10 @@ const ConnectionSidebar = () => {
const [state, setState] = useState<State>({ const [state, setState] = useState<State>({
showCreateConnectionModal: false, showCreateConnectionModal: false,
showSettingModal: false, showSettingModal: false,
showEditConversationTitleModal: false, showUpdateConversationModal: false,
}); });
const [editConnectionModalContext, setEditConnectionModalContext] = useState<Connection>(); const [editConnectionModalContext, setEditConnectionModalContext] = useState<Connection>();
const [editConversationTitleModalContext, setEditConversationTitleModalContext] = useState<Conversation>(); const [updateConversationModalContext, setUpdateConversationModalContext] = useState<Conversation>();
const [isRequestingDatabase, setIsRequestingDatabase] = useState<boolean>(false); const [isRequestingDatabase, setIsRequestingDatabase] = useState<boolean>(false);
const connectionList = connectionStore.connectionList; const connectionList = connectionStore.connectionList;
const currentConnectionCtx = connectionStore.currentConnectionCtx; const currentConnectionCtx = connectionStore.currentConnectionCtx;
@ -88,10 +88,10 @@ const ConnectionSidebar = () => {
}); });
}; };
const toggleEditConversationTitleModal = (show = true) => { const toggleUpdateConversationModal = (show = true) => {
setState({ setState({
...state, ...state,
showEditConversationTitleModal: show, showUpdateConversationModal: show,
}); });
}; };
@ -139,11 +139,11 @@ const ConnectionSidebar = () => {
} }
}; };
const handleEditConversationTitle = (conversation: Conversation) => { const handleEditConversation = (conversation: Conversation) => {
setEditConversationTitleModalContext(conversation); setUpdateConversationModalContext(conversation);
setState({ setState({
...state, ...state,
showEditConversationTitleModal: true, showUpdateConversationModal: true,
}); });
}; };
@ -265,16 +265,16 @@ const ConnectionSidebar = () => {
<div className="p-1 flex flex-col justify-start items-start bg-white dark:bg-zinc-900 shadow-lg rounded-lg"> <div className="p-1 flex flex-col justify-start items-start bg-white dark:bg-zinc-900 shadow-lg rounded-lg">
<DropdownItem <DropdownItem
className="w-full p-1 px-2 flex flex-row justify-start items-center rounded-lg cursor-pointer hover:bg-gray-100 dark:hover:bg-zinc-800" className="w-full p-1 px-2 flex flex-row justify-start items-center rounded-lg cursor-pointer hover:bg-gray-100 dark:hover:bg-zinc-800"
onClick={() => handleEditConversationTitle(conversation)} onClick={() => handleEditConversation(conversation)}
> >
<Icon.FiEdit3 className="w-4 h-auto mr-1 opacity-70" /> <Icon.FiEdit3 className="w-4 h-auto mr-2 opacity-70" />
{t("common.edit")} {t("common.edit")}
</DropdownItem> </DropdownItem>
<DropdownItem <DropdownItem
className="w-full p-1 px-2 flex flex-row justify-start items-center rounded-lg cursor-pointer hover:bg-gray-100 dark:hover:bg-zinc-800" className="w-full p-1 px-2 flex flex-row justify-start items-center rounded-lg cursor-pointer hover:bg-gray-100 dark:hover:bg-zinc-800"
onClick={() => handleDeleteConversation(conversation)} onClick={() => handleDeleteConversation(conversation)}
> >
<Icon.IoTrash className="w-4 h-auto mr-1 opacity-70" /> <Icon.IoTrash className="w-4 h-auto mr-2 opacity-70" />
{t("common.delete")} {t("common.delete")}
</DropdownItem> </DropdownItem>
</div> </div>
@ -309,11 +309,8 @@ const ConnectionSidebar = () => {
{state.showSettingModal && <SettingModal close={() => toggleSettingModal(false)} />} {state.showSettingModal && <SettingModal close={() => toggleSettingModal(false)} />}
{editConversationTitleModalContext && state.showEditConversationTitleModal && ( {updateConversationModalContext && state.showUpdateConversationModal && (
<EditConversationTitleModal <UpdateConversationModal close={() => toggleUpdateConversationModal(false)} conversation={updateConversationModalContext} />
close={() => toggleEditConversationTitleModal(false)}
conversation={editConversationTitleModalContext}
/>
)} )}
</> </>
); );

View File

@ -1,22 +1,31 @@
import { useState } from "react"; import { useState } from "react";
import { toast } from "react-hot-toast"; import { toast } from "react-hot-toast";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useConversationStore } from "@/store"; import { assistantList, useConversationStore } from "@/store";
import { Conversation } from "@/types"; import { Conversation } from "@/types";
import TextField from "./kit/TextField"; import TextField from "./kit/TextField";
import Modal from "./kit/Modal"; import Modal from "./kit/Modal";
import Select from "./kit/Select";
interface Props { interface Props {
conversation: Conversation; conversation: Conversation;
close: () => void; close: () => void;
} }
const EditConversationTitleModal = (props: Props) => { const UpdateConversationModal = (props: Props) => {
const { close, conversation } = props; const { close, conversation } = props;
const { t } = useTranslation(); const { t } = useTranslation();
const conversationStore = useConversationStore(); const conversationStore = useConversationStore();
const [title, setTitle] = useState(conversation.title); const [title, setTitle] = useState(conversation.title);
const [assistantId, setAssistantId] = useState(conversation.assistantId);
const allowSave = title !== ""; const allowSave = title !== "";
const assistantItems = assistantList.map((assistant) => {
return {
value: assistant.id,
label: assistant.name,
};
});
const currentAssistant = assistantList.find((assistant) => assistant.id === assistantId);
const handleSaveEdit = () => { const handleSaveEdit = () => {
const formatedTitle = title.trim(); const formatedTitle = title.trim();
@ -26,16 +35,27 @@ const EditConversationTitleModal = (props: Props) => {
conversationStore.updateConversation(conversation.id, { conversationStore.updateConversation(conversation.id, {
title: formatedTitle, title: formatedTitle,
assistantId: assistantId,
}); });
toast.success("Conversation title updated"); toast.success("Conversation updated");
close(); close();
}; };
return ( return (
<Modal title={t("conversation.edit-title")} onClose={close}> <Modal title={t("conversation.update")} onClose={close}>
<div className="w-full flex flex-col justify-start items-start mt-2"> <div className="w-full flex flex-col justify-start items-start mt-2">
<label className="block text-sm font-medium text-gray-700 mb-1">{t("conversation.title")}</label>
<TextField placeholder={t("conversation.conversation-title") || ""} value={title} onChange={(value) => setTitle(value)} /> <TextField placeholder={t("conversation.conversation-title") || ""} value={title} onChange={(value) => setTitle(value)} />
</div> </div>
<div className="w-full flex flex-col justify-start items-start mt-2">
<label className="block text-sm font-medium text-gray-700 mb-1">{t("assistant.self")}</label>
<Select className="w-full" value={assistantId} itemList={assistantItems} onValueChange={(value) => setAssistantId(value)} />
{currentAssistant && (
<div className="w-full flex flex-col justify-start items-start">
<p className="block text-sm text-gray-700 mt-1 ml-3">{currentAssistant.description}</p>
</div>
)}
</div>
<div className="w-full flex flex-row justify-end items-center mt-4 space-x-2"> <div className="w-full flex flex-row justify-end items-center mt-4 space-x-2">
<button className="btn btn-outline" onClick={close}> <button className="btn btn-outline" onClick={close}>
{t("common.close")} {t("common.close")}
@ -48,4 +68,4 @@ const EditConversationTitleModal = (props: Props) => {
); );
}; };
export default EditConversationTitleModal; export default UpdateConversationModal;

View File

@ -14,13 +14,17 @@
"conversation": { "conversation": {
"new-chat": "New Chat", "new-chat": "New Chat",
"conversation-title": "Conversation title", "conversation-title": "Conversation title",
"edit-title": "Edit conversation title" "update": "Update conversation",
"title": "Title"
}, },
"connection": { "connection": {
"self": "Connection", "self": "Connection",
"new": "Create Connection", "new": "Create Connection",
"select-database": "Select your database" "select-database": "Select your database"
}, },
"assistant": {
"self": "Bot"
},
"execution": { "execution": {
"title": "Execute SQL", "title": "Execute SQL",
"message": { "message": {

View File

@ -14,13 +14,17 @@
"conversation": { "conversation": {
"new-chat": "新建会话", "new-chat": "新建会话",
"conversation-title": "会话标题", "conversation-title": "会话标题",
"edit-title": "编辑会话标题" "update": "更新会话",
"title": "标题"
}, },
"connection": { "connection": {
"self": "连接", "self": "连接",
"new": "创建连接", "new": "创建连接",
"select-database": "选择数据库" "select-database": "选择数据库"
}, },
"assistant": {
"self": "机器人"
},
"execution": { "execution": {
"title": "执行 SQL", "title": "执行 SQL",
"message": { "message": {

View File

@ -2,7 +2,7 @@ import { first } from "lodash-es";
import { Assistant, Id } from "@/types"; import { Assistant, Id } from "@/types";
import * as customAssistantList from "../../assistants"; import * as customAssistantList from "../../assistants";
const assistantList: Assistant[] = Object.keys(customAssistantList).map((name) => { export const assistantList: Assistant[] = Object.keys(customAssistantList).map((name) => {
return { return {
...((customAssistantList as any)[name].default as Assistant), ...((customAssistantList as any)[name].default as Assistant),
}; };