@@ -4,7 +4,9 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } f
44import { Button } from "./ui/button"
55import { Input } from "./ui/input"
66import { Label } from "./ui/label"
7+ import { Loader2 , CheckCircle2 , XCircle } from "lucide-react"
78import { DRIVER_CONFIGS } from "@/lib/database-driver"
9+ import { pgsqlTestConnection } from "@/tauri"
810import type { DriverType , ProjectDetails } from "@/types"
911
1012interface ConnectionModalProps {
@@ -75,6 +77,8 @@ export function ConnectionModal({ open, onOpenChange, onSave, editData }: Connec
7577 const [ formData , setFormData ] = useState < Omit < ConnectionConfig , "id" > > ( defaultForm )
7678 const [ connString , setConnString ] = useState ( "" )
7779 const [ connStringError , setConnStringError ] = useState ( false )
80+ const [ testing , setTesting ] = useState ( false )
81+ const [ testResult , setTestResult ] = useState < { ok : boolean ; message : string } | null > ( null )
7882
7983 useEffect ( ( ) => {
8084 if ( open && editData ) {
@@ -96,10 +100,12 @@ export function ConnectionModal({ open, onOpenChange, onSave, editData }: Connec
96100 } )
97101 setConnString ( "" )
98102 setConnStringError ( false )
103+ setTestResult ( null )
99104 } else if ( open && ! editData ) {
100105 setFormData ( defaultForm )
101106 setConnString ( "" )
102107 setConnStringError ( false )
108+ setTestResult ( null )
103109 }
104110 } , [ open , editData ] )
105111
@@ -117,6 +123,28 @@ export function ConnectionModal({ open, onOpenChange, onSave, editData }: Connec
117123
118124 const isEditing = ! ! editData
119125
126+ const handleTestConnection = async ( ) => {
127+ setTesting ( true )
128+ setTestResult ( null )
129+ try {
130+ const key : [ string , string , string , string , string , string ] = [
131+ formData . username ,
132+ formData . password ,
133+ formData . database ,
134+ formData . host ,
135+ formData . port ,
136+ formData . ssl ? "true" : "false" ,
137+ ]
138+ const version = await pgsqlTestConnection ( key )
139+ setTestResult ( { ok : true , message : version } )
140+ } catch ( err : unknown ) {
141+ const msg = err instanceof Error ? err . message : String ( err )
142+ setTestResult ( { ok : false , message : msg } )
143+ } finally {
144+ setTesting ( false )
145+ }
146+ }
147+
120148 const handleSubmit = ( e : React . FormEvent ) => {
121149 e . preventDefault ( )
122150 const connection : ConnectionConfig = {
@@ -341,13 +369,42 @@ export function ConnectionModal({ open, onOpenChange, onSave, editData }: Connec
341369 ) }
342370 </ div >
343371
344- < div className = "flex justify-end gap-2 pt-4" >
345- < Button type = "button" variant = "ghost" onClick = { ( ) => onOpenChange ( false ) } className = "font-mono text-xs" >
346- Cancel
347- </ Button >
348- < Button type = "submit" variant = "gradient" className = "font-mono text-xs" >
349- { isEditing ? "Save Changes" : "Connect" }
372+ { testResult && (
373+ < div
374+ className = { `flex items-start gap-2 rounded-lg border px-3 py-2 text-xs font-mono ${
375+ testResult . ok
376+ ? "border-emerald-500/30 bg-emerald-500/5 text-emerald-500"
377+ : "border-destructive/30 bg-destructive/5 text-destructive"
378+ } `}
379+ >
380+ { testResult . ok ? (
381+ < CheckCircle2 className = "h-3.5 w-3.5 shrink-0 mt-0.5" />
382+ ) : (
383+ < XCircle className = "h-3.5 w-3.5 shrink-0 mt-0.5" />
384+ ) }
385+ < span className = "break-all" > { testResult . message } </ span >
386+ </ div >
387+ ) }
388+
389+ < div className = "flex justify-between pt-4" >
390+ < Button
391+ type = "button"
392+ variant = "outline"
393+ onClick = { ( ) => void handleTestConnection ( ) }
394+ disabled = { testing || ! formData . host || ! formData . database }
395+ className = "font-mono text-xs"
396+ >
397+ { testing && < Loader2 className = "h-3 w-3 animate-spin mr-1.5" /> }
398+ Test Connection
350399 </ Button >
400+ < div className = "flex gap-2" >
401+ < Button type = "button" variant = "ghost" onClick = { ( ) => onOpenChange ( false ) } className = "font-mono text-xs" >
402+ Cancel
403+ </ Button >
404+ < Button type = "submit" variant = "gradient" className = "font-mono text-xs" >
405+ { isEditing ? "Save Changes" : "Connect" }
406+ </ Button >
407+ </ div >
351408 </ div >
352409 </ form >
353410 </ DialogContent >
0 commit comments