Add line specific error text
parent
0a0af981d9
commit
206496c656
|
@ -9,6 +9,7 @@ import {
|
||||||
OnChangeScript,
|
OnChangeScript,
|
||||||
OnSubmitScript,
|
OnSubmitScript,
|
||||||
FlatBody,
|
FlatBody,
|
||||||
|
Status,
|
||||||
} from 'src/types/ifql'
|
} from 'src/types/ifql'
|
||||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||||
import {HANDLE_VERTICAL, HANDLE_HORIZONTAL} from 'src/shared/constants'
|
import {HANDLE_VERTICAL, HANDLE_HORIZONTAL} from 'src/shared/constants'
|
||||||
|
@ -17,6 +18,7 @@ interface Props {
|
||||||
data: string
|
data: string
|
||||||
script: string
|
script: string
|
||||||
body: Body[]
|
body: Body[]
|
||||||
|
status: Status
|
||||||
suggestions: Suggestion[]
|
suggestions: Suggestion[]
|
||||||
onChangeScript: OnChangeScript
|
onChangeScript: OnChangeScript
|
||||||
onSubmitScript: OnSubmitScript
|
onSubmitScript: OnSubmitScript
|
||||||
|
@ -63,6 +65,7 @@ class TimeMachine extends PureComponent<Props> {
|
||||||
const {
|
const {
|
||||||
body,
|
body,
|
||||||
script,
|
script,
|
||||||
|
status,
|
||||||
suggestions,
|
suggestions,
|
||||||
onChangeScript,
|
onChangeScript,
|
||||||
onSubmitScript,
|
onSubmitScript,
|
||||||
|
@ -78,6 +81,7 @@ class TimeMachine extends PureComponent<Props> {
|
||||||
menuOptions: [{action: onSubmitScript, text: 'Analyze'}],
|
menuOptions: [{action: onSubmitScript, text: 'Analyze'}],
|
||||||
render: visibility => (
|
render: visibility => (
|
||||||
<TimeMachineEditor
|
<TimeMachineEditor
|
||||||
|
status={status}
|
||||||
script={script}
|
script={script}
|
||||||
onChangeScript={onChangeScript}
|
onChangeScript={onChangeScript}
|
||||||
visibility={visibility}
|
visibility={visibility}
|
||||||
|
|
|
@ -6,10 +6,16 @@ import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||||
import {OnChangeScript} from 'src/types/ifql'
|
import {OnChangeScript} from 'src/types/ifql'
|
||||||
import {editor} from 'src/ifql/constants'
|
import {editor} from 'src/ifql/constants'
|
||||||
|
|
||||||
|
interface Status {
|
||||||
|
type: string
|
||||||
|
text: string
|
||||||
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
script: string
|
script: string
|
||||||
onChangeScript: OnChangeScript
|
|
||||||
visibility: string
|
visibility: string
|
||||||
|
status: Status
|
||||||
|
onChangeScript: OnChangeScript
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EditorInstance extends IInstance {
|
interface EditorInstance extends IInstance {
|
||||||
|
@ -19,12 +25,21 @@ interface EditorInstance extends IInstance {
|
||||||
@ErrorHandling
|
@ErrorHandling
|
||||||
class TimeMachineEditor extends PureComponent<Props> {
|
class TimeMachineEditor extends PureComponent<Props> {
|
||||||
private editor: EditorInstance
|
private editor: EditorInstance
|
||||||
|
private prevKey: string
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props)
|
super(props)
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentDidUpdate(prevProps) {
|
public componentDidUpdate(prevProps) {
|
||||||
|
if (this.props.status.type === 'error') {
|
||||||
|
this.makeError()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.props.status.type !== 'error') {
|
||||||
|
this.editor.clearGutter('error-gutter')
|
||||||
|
}
|
||||||
|
|
||||||
if (prevProps.visibility === this.props.visibility) {
|
if (prevProps.visibility === this.props.visibility) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -45,6 +60,7 @@ class TimeMachineEditor extends PureComponent<Props> {
|
||||||
extraKeys: {'Ctrl-Space': 'autocomplete'},
|
extraKeys: {'Ctrl-Space': 'autocomplete'},
|
||||||
completeSingle: false,
|
completeSingle: false,
|
||||||
autoRefresh: true,
|
autoRefresh: true,
|
||||||
|
gutters: ['error-gutter'],
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -63,6 +79,25 @@ class TimeMachineEditor extends PureComponent<Props> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private makeError(): void {
|
||||||
|
const {status} = this.props
|
||||||
|
this.editor.clearGutter('error-gutter')
|
||||||
|
const span = document.createElement('span')
|
||||||
|
span.className = 'icon stop error-warning'
|
||||||
|
span.title = status.text
|
||||||
|
const lineNumber = this.statusLine
|
||||||
|
this.editor.setGutterMarker(lineNumber - 1, 'error-gutter', span)
|
||||||
|
this.editor.refresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
private get statusLine(): number {
|
||||||
|
const {status} = this.props
|
||||||
|
const numbers = status.text.split(' ')[0]
|
||||||
|
const [lineNumber] = numbers.split(':')
|
||||||
|
|
||||||
|
return Number(lineNumber)
|
||||||
|
}
|
||||||
|
|
||||||
private handleMount = (instance: EditorInstance) => {
|
private handleMount = (instance: EditorInstance) => {
|
||||||
instance.refresh() // required to for proper line height on mount
|
instance.refresh() // required to for proper line height on mount
|
||||||
this.editor = instance
|
this.editor = instance
|
||||||
|
|
|
@ -13,6 +13,11 @@ import {getSuggestions, getAST, getTimeSeries} from 'src/ifql/apis'
|
||||||
import * as argTypes from 'src/ifql/constants/argumentTypes'
|
import * as argTypes from 'src/ifql/constants/argumentTypes'
|
||||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||||
|
|
||||||
|
interface Status {
|
||||||
|
type: string
|
||||||
|
text: string
|
||||||
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
links: Links
|
links: Links
|
||||||
}
|
}
|
||||||
|
@ -27,6 +32,7 @@ interface State {
|
||||||
script: string
|
script: string
|
||||||
data: string
|
data: string
|
||||||
suggestions: Suggestion[]
|
suggestions: Suggestion[]
|
||||||
|
status: Status
|
||||||
}
|
}
|
||||||
|
|
||||||
export const IFQLContext = React.createContext()
|
export const IFQLContext = React.createContext()
|
||||||
|
@ -42,6 +48,10 @@ export class IFQLPage extends PureComponent<Props, State> {
|
||||||
suggestions: [],
|
suggestions: [],
|
||||||
script: `fil = (r) => r._measurement == "cpu"
|
script: `fil = (r) => r._measurement == "cpu"
|
||||||
tele = from(db: "telegraf") |> filter(fn: fil) |> range(start: -1m) |> sum()`,
|
tele = from(db: "telegraf") |> filter(fn: fil) |> range(start: -1m) |> sum()`,
|
||||||
|
status: {
|
||||||
|
type: 'none',
|
||||||
|
text: '',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +69,7 @@ export class IFQLPage extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const {suggestions, script, data, body} = this.state
|
const {suggestions, script, data, body, status} = this.state
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IFQLContext.Provider value={this.handlers}>
|
<IFQLContext.Provider value={this.handlers}>
|
||||||
|
@ -84,6 +94,7 @@ export class IFQLPage extends PureComponent<Props, State> {
|
||||||
data={data}
|
data={data}
|
||||||
body={body}
|
body={body}
|
||||||
script={script}
|
script={script}
|
||||||
|
status={status}
|
||||||
suggestions={suggestions}
|
suggestions={suggestions}
|
||||||
onChangeScript={this.handleChangeScript}
|
onChangeScript={this.handleChangeScript}
|
||||||
onSubmitScript={this.handleSubmitScript}
|
onSubmitScript={this.handleSubmitScript}
|
||||||
|
@ -333,8 +344,13 @@ export class IFQLPage extends PureComponent<Props, State> {
|
||||||
try {
|
try {
|
||||||
const ast = await getAST({url: links.ast, body: script})
|
const ast = await getAST({url: links.ast, body: script})
|
||||||
const body = bodyNodes(ast, this.state.suggestions)
|
const body = bodyNodes(ast, this.state.suggestions)
|
||||||
this.setState({ast, script, body})
|
const status = {type: 'success', text: ''}
|
||||||
|
this.setState({ast, script, body, status})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
const s = error.data.slice(0, -5) // There is a null newline at the end of these responses
|
||||||
|
const data = JSON.parse(s)
|
||||||
|
const status = {type: 'error', text: `${data.message}`}
|
||||||
|
this.setState({status})
|
||||||
return console.error('Could not parse AST', error)
|
return console.error('Could not parse AST', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,3 +19,8 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.error-warning {
|
||||||
|
color: $c-dreamsicle;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
|
@ -10,6 +10,11 @@ export type OnGenerateScript = (script: string) => void
|
||||||
export type OnChangeScript = (script: string) => void
|
export type OnChangeScript = (script: string) => void
|
||||||
export type OnSubmitScript = () => void
|
export type OnSubmitScript = () => void
|
||||||
|
|
||||||
|
export interface Status {
|
||||||
|
type: string
|
||||||
|
text: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface Handlers {
|
export interface Handlers {
|
||||||
onAddNode: OnAddNode
|
onAddNode: OnAddNode
|
||||||
onChangeArg: OnChangeArg
|
onChangeArg: OnChangeArg
|
||||||
|
|
Loading…
Reference in New Issue