1
1
import React , { Component } from 'react' ;
2
2
import PropTypes from 'prop-types' ;
3
3
import { Row , Col , Button } from 'react-bootstrap' ;
4
+ import { Controlled as CodeMirror } from 'react-codemirror2' ;
5
+
6
+ import 'codemirror/lib/codemirror.css' ;
7
+ import 'codemirror/mode/sql/sql' ;
8
+ import 'codemirror/addon/display/placeholder' ;
9
+ import 'codemirror/addon/edit/matchbrackets' ;
10
+ import 'codemirror/addon/hint/show-hint.css' ;
11
+ import 'codemirror/addon/hint/show-hint' ;
12
+ import 'codemirror/addon/hint/sql-hint' ;
13
+
4
14
import './QueryBox.less' ;
5
15
6
16
class QueryBox extends Component {
17
+ constructor ( props ) {
18
+ super ( props ) ;
19
+
20
+ this . state = {
21
+ schema : undefined ,
22
+ codeMirrorTables : { }
23
+ } ;
24
+ }
25
+
26
+ static getDerivedStateFromProps ( nextProps , prevState ) {
27
+ if ( nextProps . schema === prevState . schema ) {
28
+ return null ;
29
+ }
30
+
31
+ return {
32
+ schema : nextProps . schema ,
33
+ codeMirrorTables : QueryBox . schemaToCodeMirror ( nextProps . schema )
34
+ } ;
35
+ }
36
+
37
+ static schemaToCodeMirror ( schema ) {
38
+ if ( ! schema ) {
39
+ return { } ;
40
+ }
41
+
42
+ return schema . reduce (
43
+ ( prevVal , currVal ) => ( {
44
+ ...prevVal ,
45
+ [ currVal . table ] : currVal . columns . map ( col => col . name )
46
+ } ) ,
47
+ { }
48
+ ) ;
49
+ }
50
+
7
51
render ( ) {
52
+ const { codeMirrorTables } = this . state ;
53
+
54
+ const options = {
55
+ mode : 'text/x-mariadb' ,
56
+ smartIndent : true ,
57
+ lineNumbers : true ,
58
+ matchBrackets : true ,
59
+ autofocus : true ,
60
+ placeholder : 'Enter an SQL query' ,
61
+ extraKeys : {
62
+ 'Ctrl-Space' : 'autocomplete' ,
63
+ 'Ctrl-Enter' : ( ) => this . props . handleSubmit ( )
64
+ } ,
65
+ hintOptions : {
66
+ tables : codeMirrorTables
67
+ }
68
+ } ;
69
+
8
70
return (
9
71
< div className = "query-box" >
10
72
< Row >
11
73
< Col xs = { 12 } >
12
- < textarea
13
- autoFocus = "true"
14
- rows = "7"
15
- placeholder = "Enter an SQL query"
74
+ < CodeMirror
16
75
value = { this . props . sql }
17
- onChange = { e => this . props . handleTextChange ( e . target . value ) }
76
+ options = { options }
77
+ onBeforeChange = { ( editor , data , value ) => {
78
+ this . props . handleTextChange ( value ) ;
79
+ } }
18
80
/>
19
81
</ Col >
20
82
</ Row >
@@ -36,6 +98,17 @@ class QueryBox extends Component {
36
98
37
99
QueryBox . propTypes = {
38
100
sql : PropTypes . string . isRequired ,
101
+ schema : PropTypes . arrayOf (
102
+ PropTypes . shape ( {
103
+ table : PropTypes . string . isRequired ,
104
+ columns : PropTypes . arrayOf (
105
+ PropTypes . shape ( {
106
+ name : PropTypes . string . isRequired ,
107
+ type : PropTypes . string . isRequired
108
+ } )
109
+ ) . isRequired
110
+ } )
111
+ ) ,
39
112
enabled : PropTypes . bool ,
40
113
handleTextChange : PropTypes . func . isRequired ,
41
114
handleSubmit : PropTypes . func . isRequired
0 commit comments