import { cloneDeep, head } from "lodash-es"; import { useEffect, useState } from "react"; import { createPortal } from "react-dom"; import { toast } from "react-hot-toast"; import { testConnection, useConnectionStore } from "@/store"; import { Connection, Engine } from "@/types"; import Icon from "./Icon"; import DataStorageBanner from "./DataStorageBanner"; import ActionConfirmModal from "./ActionConfirmModal"; interface Props { show: boolean; connection?: Connection; close: () => void; } const defaultConnection: Connection = { id: "", title: "", engineType: Engine.MySQL, host: "", port: "", username: "", password: "", }; const CreateConnectionModal = (props: Props) => { const { show, connection: editConnection, close } = props; const connectionStore = useConnectionStore(); const [connection, setConnection] = useState(defaultConnection); const [showDeleteConnectionModal, setShowDeleteConnectionModal] = useState(false); const [isRequesting, setIsRequesting] = useState(false); const showDatabaseField = connection.engineType === Engine.PostgreSQL; const isEditing = editConnection !== undefined; useEffect(() => { if (show) { setConnection(isEditing ? editConnection : defaultConnection); setIsRequesting(false); setShowDeleteConnectionModal(false); } }, [show]); const setPartialConnection = (state: Partial) => { setConnection({ ...connection, ...state, }); }; const handleCreateConnection = async () => { if (isRequesting) { return; } setIsRequesting(true); const tempConnection = cloneDeep(connection); if (!showDatabaseField) { tempConnection.database = undefined; } try { await testConnection(tempConnection); } catch (error) { setIsRequesting(false); toast.error("Failed to test connection, please check your connection settings"); return; } try { let connection: Connection; if (isEditing) { connectionStore.updateConnection(tempConnection.id, tempConnection); connection = tempConnection; } else { connection = connectionStore.createConnection(tempConnection); } // Set the created connection as the current connection. const databaseList = await connectionStore.getOrFetchDatabaseList(connection, true); connectionStore.setCurrentConnectionCtx({ connection: connection, database: head(databaseList), }); } catch (error) { console.error(error); setIsRequesting(false); toast.error("Failed to create connection"); return; } setIsRequesting(false); close(); }; const handleDeleteConnection = () => { connectionStore.clearConnection((item) => item.id !== connection.id); if (connectionStore.currentConnectionCtx?.connection.id === connection.id) { connectionStore.setCurrentConnectionCtx(undefined); } close(); }; return ( <>

{isEditing ? "Edit Connection" : "Create Connection"}

setPartialConnection({ host: e.target.value })} />
setPartialConnection({ port: e.target.value })} />
{showDatabaseField && (
setPartialConnection({ database: e.target.value })} />
)}
setPartialConnection({ username: e.target.value })} />
setPartialConnection({ password: e.target.value })} />
{isEditing && ( )}
{showDeleteConnectionModal && createPortal( setShowDeleteConnectionModal(false)} confirm={() => handleDeleteConnection()} />, document.body )} ); }; export default CreateConnectionModal;