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