mirror of
https://github.com/sqlchat/sqlchat.git
synced 2025-07-29 02:04:48 +08:00
feat: implement delete connection/chat
This commit is contained in:
@ -13,7 +13,7 @@ const ClearDataConfirmModal = (props: Props) => {
|
||||
toast.success("Message cleared. The page will be reloaded.");
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
}, 1500);
|
||||
}, 300);
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -50,10 +50,21 @@ const ConnectionSidebar = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const handleDeleteConnection = (connection: Connection) => {
|
||||
connectionStore.clearConnection((item) => item.id !== connection.id);
|
||||
if (currentConnectionCtx?.connection.id === connection.id) {
|
||||
connectionStore.setCurrentConnectionCtx(undefined);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDatabaseNameSelect = async (databaseName: string) => {
|
||||
if (!currentConnectionCtx?.connection) {
|
||||
return;
|
||||
}
|
||||
|
||||
const database = databaseList.find((database) => database.name === databaseName);
|
||||
connectionStore.setCurrentConnectionCtx({
|
||||
connection: currentConnectionCtx!.connection,
|
||||
connection: currentConnectionCtx.connection,
|
||||
database: database,
|
||||
});
|
||||
};
|
||||
@ -71,6 +82,13 @@ const ConnectionSidebar = () => {
|
||||
layoutStore.toggleSidebar(false);
|
||||
};
|
||||
|
||||
const handleDeleteChat = (chat: Chat) => {
|
||||
chatStore.clearChat((item) => item.id !== chat.id);
|
||||
if (chatStore.currentChat?.id === chat.id) {
|
||||
chatStore.setCurrentChat(undefined);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<aside className="drawer-side">
|
||||
@ -81,11 +99,20 @@ const ConnectionSidebar = () => {
|
||||
{connectionList.map((connection) => (
|
||||
<button
|
||||
key={connection.id}
|
||||
className={`w-full h-14 rounded-l-lg p-2 mt-2 ${
|
||||
className={`w-full h-14 rounded-l-lg p-2 mt-2 group ${
|
||||
currentConnectionCtx?.connection.id === connection.id && "bg-gray-100 shadow"
|
||||
}`}
|
||||
onClick={() => handleConnectionSelect(connection)}
|
||||
>
|
||||
<span
|
||||
className="absolute -ml-1.5 -mt-1.5 hidden opacity-60 group-hover:block hover:opacity-80"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleDeleteConnection(connection);
|
||||
}}
|
||||
>
|
||||
<Icon.IoClose className="w-4 h-auto" />
|
||||
</span>
|
||||
<EngineIcon engine={connection.engineType} className="w-auto h-full mx-auto" />
|
||||
</button>
|
||||
))}
|
||||
@ -135,17 +162,26 @@ const ConnectionSidebar = () => {
|
||||
{chatList.map((chat) => (
|
||||
<div
|
||||
key={chat.id}
|
||||
className={`w-full max-w-full mt-2 first:mt-4 py-3 px-4 rounded-lg flex flex-row justify-start items-center cursor-pointer border border-transparent hover:bg-gray-50 ${
|
||||
className={`w-full mt-2 first:mt-4 py-3 px-4 pr-3 rounded-lg flex flex-row justify-start items-center cursor-pointer border border-transparent group hover:bg-gray-50 ${
|
||||
chat.id === chatStore.currentChat?.id && "!bg-white border-gray-200 font-medium"
|
||||
}`}
|
||||
onClick={() => handleChatSelect(chat)}
|
||||
>
|
||||
{chat.id === chatStore.currentChat?.id ? (
|
||||
<Icon.IoChatbubble className="w-5 h-auto mr-2 shrink-0" />
|
||||
<Icon.IoChatbubble className="w-5 h-auto mr-1.5 shrink-0" />
|
||||
) : (
|
||||
<Icon.IoChatbubbleOutline className="w-5 h-auto mr-2 opacity-80 shrink-0" />
|
||||
<Icon.IoChatbubbleOutline className="w-5 h-auto mr-1.5 opacity-80 shrink-0" />
|
||||
)}
|
||||
<span className="truncate">{chat.title || "SQL Chat"}</span>
|
||||
<span
|
||||
className="ml-0.5 shrink-0 opacity-60 hidden group-hover:block hover:opacity-80"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleDeleteChat(chat);
|
||||
}}
|
||||
>
|
||||
<Icon.IoClose className="w-5 h-auto" />
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
<button
|
||||
|
@ -36,14 +36,14 @@ const SettingModal = (props: Props) => {
|
||||
<div className="w-full flex flex-col justify-start items-start space-y-3 pt-4">
|
||||
<h3>Danger Zone</h3>
|
||||
<div className="w-full border border-red-200 p-4 rounded-lg">
|
||||
<div className="w-full flex flex-row justify-between items-center gap-2">
|
||||
<div>
|
||||
<h4 className="leading-8">Clear all data</h4>
|
||||
<p className="text-gray-500 text-sm">SQLChat saves all of your data in localstorage. Please be sure to clear data.</p>
|
||||
</div>
|
||||
<button className="btn btn-error btn-sm" onClick={() => toggleClearDataConfirmModal(true)}>
|
||||
Clear data
|
||||
<div className="w-full flex flex-col justify-start items-start gap-2">
|
||||
<h4 className="w-full flex flex-row justify-between items-center leading-8">
|
||||
<span>Clear all data</span>
|
||||
<button className="btn btn-sm btn-error" onClick={() => toggleClearDataConfirmModal(true)}>
|
||||
Clear
|
||||
</button>
|
||||
</h4>
|
||||
<p className="text-gray-500 text-sm">SQLChat saves all of your data in localstorage. Please be sure to clear data.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -7,7 +7,6 @@
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@headlessui/react": "^1.7.13",
|
||||
"@vercel/analytics": "^0.1.11",
|
||||
"axios": "^1.3.4",
|
||||
"csstype": "^3.1.1",
|
||||
|
14
pnpm-lock.yaml
generated
14
pnpm-lock.yaml
generated
@ -1,7 +1,6 @@
|
||||
lockfileVersion: 5.4
|
||||
|
||||
specifiers:
|
||||
'@headlessui/react': ^1.7.13
|
||||
'@tailwindcss/typography': ^0.5.9
|
||||
'@types/lodash-es': ^4.17.7
|
||||
'@types/marked': ^4.0.8
|
||||
@ -37,7 +36,6 @@ specifiers:
|
||||
zustand: ^4.3.6
|
||||
|
||||
dependencies:
|
||||
'@headlessui/react': 1.7.13_biqbaboplfbrettd7655fr4n2y
|
||||
'@vercel/analytics': 0.1.11_react@18.2.0
|
||||
axios: 1.3.4
|
||||
csstype: 3.1.1
|
||||
@ -99,18 +97,6 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@headlessui/react/1.7.13_biqbaboplfbrettd7655fr4n2y:
|
||||
resolution: {integrity: sha512-9n+EQKRtD9266xIHXdY5MfiXPDfYwl7zBM7KOx2Ae3Gdgxy8QML1FkCMjq6AsOf0l6N9uvI4HcFtuFlenaldKg==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
react: ^16 || ^17 || ^18
|
||||
react-dom: ^16 || ^17 || ^18
|
||||
dependencies:
|
||||
client-only: 0.0.1
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
dev: false
|
||||
|
||||
/@humanwhocodes/config-array/0.9.5:
|
||||
resolution: {integrity: sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==}
|
||||
engines: {node: '>=10.10.0'}
|
||||
|
@ -19,6 +19,7 @@ interface ChatState {
|
||||
getState: () => ChatState;
|
||||
createChat: (connectionId?: Id, databaseName?: string) => Chat;
|
||||
setCurrentChat: (chat: Chat | undefined) => void;
|
||||
clearChat: (filter: (chat: Chat) => boolean) => void;
|
||||
}
|
||||
|
||||
export const useChatStore = create<ChatState>()(
|
||||
@ -39,6 +40,12 @@ export const useChatStore = create<ChatState>()(
|
||||
return chat;
|
||||
},
|
||||
setCurrentChat: (chat: Chat | undefined) => set(() => ({ currentChat: chat })),
|
||||
clearChat: (filter: (chat: Chat) => boolean) => {
|
||||
set((state) => ({
|
||||
...state,
|
||||
chatList: state.chatList.filter(filter),
|
||||
}));
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: "chat-storage",
|
||||
|
@ -2,30 +2,9 @@ import axios from "axios";
|
||||
import { uniqBy } from "lodash-es";
|
||||
import { create } from "zustand";
|
||||
import { persist } from "zustand/middleware";
|
||||
import { Connection, Database, Engine, Table, UNKNOWN_ID } from "@/types";
|
||||
import { Connection, Database, Table } from "@/types";
|
||||
import { generateUUID } from "@/utils";
|
||||
|
||||
export const connectionMySQLSampleData: Connection = {
|
||||
id: UNKNOWN_ID,
|
||||
title: "",
|
||||
engineType: Engine.MySQL,
|
||||
host: "127.0.0.1",
|
||||
port: "3306",
|
||||
username: "root",
|
||||
password: "",
|
||||
};
|
||||
|
||||
export const connectionPostgreSQLSampleData: Connection = {
|
||||
id: UNKNOWN_ID,
|
||||
title: "",
|
||||
engineType: Engine.PostgreSQL,
|
||||
host: "127.0.0.1",
|
||||
port: "5432",
|
||||
username: "postgres",
|
||||
password: "",
|
||||
database: "test",
|
||||
};
|
||||
|
||||
interface ConnectionContext {
|
||||
connection: Connection;
|
||||
database?: Database;
|
||||
@ -36,9 +15,10 @@ interface ConnectionState {
|
||||
databaseList: Database[];
|
||||
currentConnectionCtx?: ConnectionContext;
|
||||
createConnection: (connection: Connection) => Connection;
|
||||
setCurrentConnectionCtx: (connectionCtx: ConnectionContext) => void;
|
||||
setCurrentConnectionCtx: (connectionCtx: ConnectionContext | undefined) => void;
|
||||
getOrFetchDatabaseList: (connection: Connection) => Promise<Database[]>;
|
||||
getOrFetchDatabaseSchema: (database: Database) => Promise<Table[]>;
|
||||
clearConnection: (filter: (connection: Connection) => boolean) => void;
|
||||
}
|
||||
|
||||
export const useConnectionStore = create<ConnectionState>()(
|
||||
@ -57,7 +37,7 @@ export const useConnectionStore = create<ConnectionState>()(
|
||||
}));
|
||||
return createdConnection;
|
||||
},
|
||||
setCurrentConnectionCtx: (connectionCtx: ConnectionContext) =>
|
||||
setCurrentConnectionCtx: (connectionCtx: ConnectionContext | undefined) =>
|
||||
set((state) => ({
|
||||
...state,
|
||||
currentConnectionCtx: connectionCtx,
|
||||
@ -98,6 +78,12 @@ export const useConnectionStore = create<ConnectionState>()(
|
||||
});
|
||||
return data;
|
||||
},
|
||||
clearConnection: (filter: (connection: Connection) => boolean) => {
|
||||
set((state) => ({
|
||||
...state,
|
||||
connectionList: state.connectionList.filter(filter),
|
||||
}));
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: "connection-storage",
|
||||
|
Reference in New Issue
Block a user