1
+ import React , { useContext , useState } from "react"
2
+ import { Tab } from "../../data/models"
3
+ import { selectDBConnection } from "../../redux/dbConnectionSlice"
4
+ import { useAppDispatch , useAppSelector } from "../../redux/hooks"
5
+ import TabContext from "../layouts/tabcontext"
6
+ import styles from './gensql.module.scss'
7
+ import eventService from "../../events/eventService"
8
+ import { duotoneLight } from '@uiw/codemirror-theme-duotone'
9
+ import { toast } from "react-hot-toast"
10
+ import ReactCodeMirror from "@uiw/react-codemirror"
11
+ import { sql } from '@codemirror/lang-sql'
12
+ import { TabType } from "../../data/defaults"
13
+ import { createTab } from "../../redux/tabsSlice"
14
+
15
+ type DBGenSQLPropType = {
16
+ }
17
+
18
+ const DBGenSQLFragment = ( { } : DBGenSQLPropType ) => {
19
+
20
+ const dispatch = useAppDispatch ( )
21
+
22
+ const currentTab : Tab = useContext ( TabContext ) !
23
+
24
+ const [ inputValue , setInputValue ] = useState < string > ( '' )
25
+ const [ generating , setGenerating ] = useState < boolean > ( false )
26
+ const [ outputValue , setOutputValue ] = useState < string | undefined > ( )
27
+
28
+ const dbConnection = useAppSelector ( selectDBConnection )
29
+
30
+ const onChange = React . useCallback ( ( value : any ) => {
31
+ setOutputValue ( value )
32
+ } , [ ] )
33
+
34
+ const runGenerateSQL = async ( ) => {
35
+ if ( generating ) {
36
+ return
37
+ }
38
+ setGenerating ( true )
39
+ const result = await eventService . runGenerateSQL ( dbConnection ! . id , inputValue )
40
+ if ( result . success )
41
+ setOutputValue ( result . data )
42
+ else
43
+ toast . error ( result . error ! )
44
+ setGenerating ( false )
45
+ }
46
+
47
+ const openInQueryEditor = ( ) => {
48
+ dispatch ( createTab ( { dbConnId : dbConnection ! . id , tabType : TabType . QUERY , metadata : { queryId : "new" , query : outputValue } } ) )
49
+ }
50
+
51
+ const copyToClipboard = ( ) => {
52
+ navigator . clipboard . writeText ( outputValue ! )
53
+ toast . success ( "copied" )
54
+ }
55
+
56
+ return < div className = { styles . console + " " + ( currentTab . isActive ? "db-tab-active" : "db-tab" ) } >
57
+ < div className = { "control" + ( generating ? " is-loading" : "" ) } >
58
+ < textarea
59
+ value = { inputValue }
60
+ className = "textarea"
61
+ placeholder = "Enter prompt to generate SQL"
62
+ onChange = { ( e : React . ChangeEvent < HTMLTextAreaElement > ) => { setInputValue ( e . target . value ) } }
63
+ />
64
+ </ div >
65
+ < br />
66
+ < div className = "control" >
67
+ { ! generating && < button className = { "button" + ( outputValue === undefined ? " is-primary" : "" ) } onClick = { runGenerateSQL } >
68
+ < span className = "icon is-small" >
69
+ < i className = "fas fa-play-circle" aria-hidden = "true" > </ i >
70
+ </ span >
71
+ Generate
72
+ </ button > }
73
+ { generating && < button className = "button is-primary is-loading" > Running</ button > }
74
+ </ div >
75
+ { outputValue !== undefined && < >
76
+ < br /> < br />
77
+ < ReactCodeMirror
78
+ value = { outputValue }
79
+ extensions = { [ sql ( ) ] }
80
+ theme = { duotoneLight }
81
+ height = { "auto" }
82
+ minHeight = "80px"
83
+ placeholder = { "Generated SQL" }
84
+ basicSetup = { {
85
+ autocompletion : false ,
86
+ highlightActiveLine : false ,
87
+ } }
88
+ onChange = { onChange }
89
+ />
90
+ < br />
91
+ < div className = "buttons" >
92
+ < button className = "button is-primary" onClick = { openInQueryEditor } >
93
+ < span className = "icon is-small" >
94
+ < i className = "fas fa-edit" aria-hidden = "true" > </ i >
95
+ </ span >
96
+ Open in Query Editor
97
+ </ button >
98
+ < button className = "button" onClick = { copyToClipboard } >
99
+ < span className = "icon is-small" >
100
+ < i className = "fas fa-copy" aria-hidden = "true" > </ i >
101
+ </ span >
102
+ Copy to clipboard
103
+ </ button >
104
+ </ div >
105
+ </ > }
106
+ </ div >
107
+ }
108
+
109
+ export default DBGenSQLFragment
0 commit comments