From cef2e98f944fc1d5040069e9258abcb9777e04cb Mon Sep 17 00:00:00 2001 From: Alex P Date: Wed, 13 Jun 2018 10:51:58 -0700 Subject: [PATCH 1/3] Introduce code mirror mode and theme for InfluxQL --- ui/src/external/codemirror.js | 9 ++- ui/src/shared/constants/codeMirrorModes.ts | 77 +++++++++++++++++++ .../components/code-mirror/_influxql.scss | 42 ++++++++++ .../style/components/code-mirror/theme.scss | 1 + 4 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 ui/src/style/components/code-mirror/_influxql.scss diff --git a/ui/src/external/codemirror.js b/ui/src/external/codemirror.js index b726aed57f..2475e8e72d 100644 --- a/ui/src/external/codemirror.js +++ b/ui/src/external/codemirror.js @@ -1,4 +1,8 @@ -import {modeFlux, modeTickscript} from 'src/shared/constants/codeMirrorModes' +import { + modeFlux, + modeTickscript, + modeInfluxQL, +} from 'src/shared/constants/codeMirrorModes' import 'codemirror/addon/hint/show-hint' /* eslint-disable */ @@ -314,4 +318,5 @@ function indentFunction(states, meta) { // Modes CodeMirror.defineSimpleMode('flux', modeFlux) -CodeMirror.defineSimpleMode('tickscript', modeTickscript) \ No newline at end of file +CodeMirror.defineSimpleMode('tickscript', modeTickscript) +CodeMirror.defineSimpleMode('influxQL', modeInfluxQL) \ No newline at end of file diff --git a/ui/src/shared/constants/codeMirrorModes.ts b/ui/src/shared/constants/codeMirrorModes.ts index 5d6d7e0d10..0c2bd40977 100644 --- a/ui/src/shared/constants/codeMirrorModes.ts +++ b/ui/src/shared/constants/codeMirrorModes.ts @@ -174,3 +174,80 @@ export const modeTickscript = { lineComment: '//', }, } + +export const modeInfluxQL = { + // The start state contains the rules that are intially used + start: [ + // The regex matches the token, the token property contains the type + { + regex: /"(?:[^\\]|\\.)*?(?:"|$)/, + token: 'string.double', + }, + { + regex: /'(?:[^\\]|\\.)*?(?:'|$)/, + token: 'string.single', + }, + { + regex: /(function)(\s+)([a-z$][\w$]*)/, + token: ['keyword', null, 'variable-2'], + }, + // Rules are matched in the order in which they appear, so there is + // no ambiguity between this one and the one above + { + regex: /(SELECT\s|AS\s|FROM\s|WHERE\s|GROUP\sBY\s)/i, + token: 'clause', + }, + { + regex: /FILL(?=[(])/i, + token: 'clause', + }, + { + regex: /(CREATE\s|SHOW\s|DROP\s)/i, + token: 'meta', + }, + { + regex: /0x[a-f\d]+|[-+]?(?:\.\d+|\d+\.?\d*)(?:e[-+]?\d+)?/i, + token: 'number', + }, + { + regex: /[:](interval|dashboardTime|dashboardUpper)[:]/, + token: 'temp-system', + }, + { + regex: /[:]\w+[:]/, + token: 'temp-var', + }, + { + regex: /now[(][)]\s\S\s\S+/, + token: 'now', + }, + { + regex: /[-+\/*=~<>!]+/, + token: 'operator', + }, + { + regex: /(NULL)/i, + token: 'null', + }, + ], + // The multi-line comment state. + comment: [ + { + regex: /.*?\*\//, + token: 'comment', + next: 'start', + }, + { + regex: /.*/, + token: 'comment', + }, + ], + // The meta property contains global information about the mode. It + // can contain properties like lineComment, which are supported by + // all modes, and also directives like dontIndentStates, which are + // specific to simple modes. + meta: { + dontIndentStates: ['comment'], + lineComment: '//', + }, +} diff --git a/ui/src/style/components/code-mirror/_influxql.scss b/ui/src/style/components/code-mirror/_influxql.scss new file mode 100644 index 0000000000..4f55441c77 --- /dev/null +++ b/ui/src/style/components/code-mirror/_influxql.scss @@ -0,0 +1,42 @@ +/* + CodeMirror "InfluxQL" Theme + ------------------------------------------------------------------------------ + Intended for use with the influxQL CodeMirror Mode +*/ + +.cm-s-influxql { + color: $g11-sidewalk; + font-weight: 600; + + .cm-clause { + color: $c-pool; + } + .cm-meta { + color: $c-honeydew; + } + .cm-string { + color: $g15-platinum; + } + .cm-comment { + color: $g8-storm; + } + .cm-number { + color: $c-pineapple; + } + .cm-operator { + color: $c-pool; + } + .cm-temp-var { + color: $c-comet; + } + .cm-temp-system { + color: #ff4d9e ; + } + .cm-now { + color: $c-pineapple; + } + .cm-null { + color: $g8-storm; + font-style: italic; + } +} diff --git a/ui/src/style/components/code-mirror/theme.scss b/ui/src/style/components/code-mirror/theme.scss index 3e1580b170..29f46e6793 100644 --- a/ui/src/style/components/code-mirror/theme.scss +++ b/ui/src/style/components/code-mirror/theme.scss @@ -90,4 +90,5 @@ div.CodeMirror-selected, */ @import 'time-machine'; @import 'tickscript'; +@import 'influxql'; @import 'hints'; From d94898b8fc675ca1d114d8cf4d7246ee0bc4c192 Mon Sep 17 00:00:00 2001 From: Alex P Date: Wed, 13 Jun 2018 10:52:33 -0700 Subject: [PATCH 2/3] Replace textarea in DE query editor with code mirror editor --- .../data_explorer/components/QueryEditor.tsx | 119 ++++++++++++------ ui/src/style/components/query-editor.scss | 42 ++----- 2 files changed, 93 insertions(+), 68 deletions(-) diff --git a/ui/src/data_explorer/components/QueryEditor.tsx b/ui/src/data_explorer/components/QueryEditor.tsx index 0f64bdec84..67a3a9340a 100644 --- a/ui/src/data_explorer/components/QueryEditor.tsx +++ b/ui/src/data_explorer/components/QueryEditor.tsx @@ -1,10 +1,14 @@ -import React, {PureComponent, KeyboardEvent} from 'react' +import React, {PureComponent} from 'react' +import {Controlled as ReactCodeMirror, IInstance} from 'react-codemirror2' +import {EditorChange} from 'codemirror' import Dropdown from 'src/shared/components/Dropdown' +import classnames from 'classnames' import {QUERY_TEMPLATES, QueryTemplate} from 'src/data_explorer/constants' import QueryStatus from 'src/shared/components/QueryStatus' import {ErrorHandling} from 'src/shared/decorators/errors' import {QueryConfig} from 'src/types' +import 'src/external/codemirror' interface Props { query: string @@ -14,19 +18,17 @@ interface Props { interface State { value: string + focused: boolean } @ErrorHandling class QueryEditor extends PureComponent { - private editor: React.RefObject - constructor(props) { super(props) this.state = { value: this.props.query, + focused: false, } - - this.editor = React.createRef() } public componentWillReceiveProps(nextProps: Props) { @@ -41,21 +43,34 @@ class QueryEditor extends PureComponent { } = this.props const {value} = this.state + const options = { + tabIndex: 1, + mode: 'influxQL', + readonly: false, + lineNumbers: false, + autoRefresh: true, + theme: 'influxql', + completeSingle: false, + lineWrapping: true, + } + return (
-