1
- import React , { useContext , useEffect } from 'react'
1
+ import React , { useContext , useEffect , useRef } from 'react'
2
2
import { useSelector } from 'react-redux'
3
- import { findIndex } from 'lodash'
4
- import { decode } from 'html-entities'
3
+ import { compact , findIndex } from 'lodash'
5
4
import cx from 'classnames'
6
5
import { EuiButtonIcon , EuiText , EuiToolTip } from '@elastic/eui'
7
6
import * as monacoEditor from 'monaco-editor/esm/vs/editor/editor.api'
8
7
import MonacoEditor from 'react-monaco-editor'
9
- import { useParams } from 'react-router-dom'
10
8
11
9
import {
12
10
Theme ,
@@ -15,17 +13,17 @@ import {
15
13
KEYBOARD_SHORTCUTS ,
16
14
} from 'uiSrc/constants'
17
15
import {
18
- getMultiCommands ,
16
+ decoration ,
17
+ geMonacoAction ,
19
18
getRedisCompletionProvider ,
20
19
getRedisMonarchTokensProvider ,
21
- removeMonacoComments ,
22
- splitMonacoValuePerLines
20
+ MonacoAction ,
21
+ Nullable ,
22
+ toModelDeltaDecoration
23
23
} from 'uiSrc/utils'
24
- import { ThemeContext } from 'uiSrc/contexts/themeContext'
25
- import { WBQueryType } from 'uiSrc/pages/workbench/constants'
26
24
import { KeyboardShortcut } from 'uiSrc/components'
25
+ import { ThemeContext } from 'uiSrc/contexts/themeContext'
27
26
import { appRedisCommandsSelector } from 'uiSrc/slices/app/redis-commands'
28
- import { sendEventTelemetry , TelemetryEvent } from 'uiSrc/telemetry'
29
27
30
28
import styles from './styles.module.scss'
31
29
@@ -34,20 +32,26 @@ export interface Props {
34
32
loading : boolean ;
35
33
setQueryEl : Function ;
36
34
setQuery : ( script : string ) => void ;
37
- onSubmit : ( query ?: string , historyId ?: number , type ?: WBQueryType ) => void ;
35
+ onSubmit : ( query ?: string ) => void ;
38
36
onKeyDown ?: ( e : React . KeyboardEvent , script : string ) => void ;
39
37
}
40
38
39
+ interface IEditorMount {
40
+ editor : monacoEditor . editor . IStandaloneCodeEditor
41
+ monaco : typeof monacoEditor
42
+ }
43
+
44
+ let decorations : string [ ] = [ ]
45
+
41
46
const Query = ( props : Props ) => {
42
47
const { query = '' , setQuery, onKeyDown, onSubmit, setQueryEl } = props
43
- const { instanceId = '' } = useParams < { instanceId : string } > ( )
44
48
45
49
const {
46
50
commandsArray : REDIS_COMMANDS_ARRAY ,
47
51
spec : REDIS_COMMANDS_SPEC
48
52
} = useSelector ( appRedisCommandsSelector )
49
- const editorRef = React . createRef < MonacoEditor > ( )
50
53
const { theme } = useContext ( ThemeContext )
54
+ const monacoObjects = useRef < Nullable < IEditorMount > > ( null )
51
55
let disposeCompletionItemProvider = ( ) => { }
52
56
53
57
useEffect ( ( ) =>
@@ -57,6 +61,27 @@ const Query = (props: Props) => {
57
61
} ,
58
62
[ ] )
59
63
64
+ useEffect ( ( ) => {
65
+ if ( ! monacoObjects . current ) return
66
+ const commands = query . split ( '\n' )
67
+ const { monaco, editor } = monacoObjects . current
68
+ const notCommandRegEx = / ^ [ \s | / / ] /
69
+
70
+ const newDecorations = compact ( commands . map ( ( command , index ) => {
71
+ if ( ! command || notCommandRegEx . test ( command ) ) return null
72
+ const lineNumber = index + 1
73
+
74
+ return toModelDeltaDecoration (
75
+ decoration ( monaco , `decoration_${ lineNumber } ` , lineNumber , 1 , lineNumber , 1 )
76
+ )
77
+ } ) )
78
+
79
+ decorations = editor . deltaDecorations (
80
+ decorations ,
81
+ newDecorations
82
+ )
83
+ } , [ query ] )
84
+
60
85
const onChange = ( value : string = '' ) => {
61
86
setQuery ( value )
62
87
}
@@ -65,50 +90,21 @@ const Query = (props: Props) => {
65
90
onKeyDown ?.( e , query )
66
91
}
67
92
68
- const sendEventSubmitTelemetry = ( commandInit = query ) => {
69
- const eventData = ( ( ) => {
70
- const commands = splitMonacoValuePerLines ( commandInit )
71
-
72
- const [ commandLine , ...rest ] = commands . map ( ( command = '' ) => {
73
- const matchedCommand = REDIS_COMMANDS_ARRAY . find ( ( commandName ) =>
74
- command . toUpperCase ( ) . startsWith ( commandName ) )
75
- return matchedCommand ?? command . split ( ' ' ) ?. [ 0 ]
76
- } )
77
- const multiCommands = getMultiCommands ( rest )
78
-
79
- const command = removeMonacoComments ( decode ( [ commandLine , multiCommands ] . join ( '\n' ) ) . trim ( ) )
80
-
81
- return {
82
- command,
83
- databaseId : instanceId ,
84
- multiple : multiCommands ? 'Multiple' : 'Single'
85
- }
86
- } ) ( )
87
-
88
- sendEventTelemetry ( {
89
- event : TelemetryEvent . WORKBENCH_COMMAND_SUBMITTED ,
90
- eventData
91
- } )
92
- }
93
-
94
93
const handleSubmit = ( value ?: string ) => {
95
- sendEventSubmitTelemetry ( value )
96
-
97
94
onSubmit ( value )
98
95
}
99
96
100
97
const editorDidMount = (
101
98
editor : monacoEditor . editor . IStandaloneCodeEditor ,
102
99
monaco : typeof monacoEditor
103
100
) => {
101
+ monacoObjects . current = { editor, monaco }
102
+
104
103
editor . focus ( )
105
104
setQueryEl ( editor )
106
105
107
106
setupMonacoRedisLang ( monaco )
108
- editor . addCommand (
109
- monaco . KeyMod . CtrlCmd | monaco . KeyCode . Enter ,
110
- ( ) => handleSubmit ( editor . getValue ( ) )
111
- )
107
+ editor . addAction ( geMonacoAction ( MonacoAction . Submit , ( editor ) => handleSubmit ( editor . getValue ( ) ) , monaco ) )
112
108
}
113
109
114
110
const setupMonacoRedisLang = ( monaco : typeof monacoEditor ) => {
@@ -134,6 +130,8 @@ const Query = (props: Props) => {
134
130
padding : { top : 10 } ,
135
131
automaticLayout : true ,
136
132
formatOnPaste : false ,
133
+ glyphMargin : true ,
134
+ lineNumbersMinChars : 4
137
135
// fontFamily: 'Inconsolata',
138
136
// fontSize: 16,
139
137
// minimap: {
@@ -145,11 +143,11 @@ const Query = (props: Props) => {
145
143
< div className = { styles . container } onKeyDown = { handleKeyDown } role = "textbox" tabIndex = { 0 } >
146
144
< div className = { styles . input } data-testid = "query-input-container" >
147
145
< MonacoEditor
148
- ref = { editorRef }
149
146
language = { MonacoLanguage . Redis }
150
147
theme = { theme === Theme . Dark ? 'vs-dark' : 'vs-light' }
151
148
value = { query }
152
149
options = { options }
150
+ className = { `${ MonacoLanguage . Redis } -editor` }
153
151
onChange = { onChange }
154
152
editorDidMount = { editorDidMount }
155
153
/>
0 commit comments