mirror of
https://github.com/sqlchat/sqlchat.git
synced 2025-09-27 18:15:49 +08:00
feat: allow update conversation bot in UI
This commit is contained in:
@ -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}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -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;
|
@ -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": {
|
||||||
|
@ -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": {
|
||||||
|
@ -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),
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user