Remove template variable logic from DataExplorer

pull/1855/head
Andrew Watkins 2017-08-11 14:38:55 -07:00
parent c83254de88
commit 246857eadd
1 changed files with 8 additions and 167 deletions

View File

@ -1,39 +1,19 @@
import React, {PropTypes, Component} from 'react' import React, {PropTypes, Component} from 'react'
import _ from 'lodash'
import Dropdown from 'shared/components/Dropdown' import Dropdown from 'shared/components/Dropdown'
import {QUERY_TEMPLATES} from 'src/data_explorer/constants' import {QUERY_TEMPLATES} from 'src/data_explorer/constants'
import QueryStatus from 'shared/components/QueryStatus' import QueryStatus from 'shared/components/QueryStatus'
import {
MATCH_INCOMPLETE_TEMPLATES,
applyMasks,
insertTempVar,
unMask,
} from 'src/dashboards/constants'
class QueryEditor extends Component { class QueryEditor extends Component {
constructor(props) { constructor(props) {
super(props) super(props)
this.state = { this.state = {
value: this.props.query, value: this.props.query,
isTemplating: false,
selectedTemplate: {
tempVar: _.get(this.props.templates, ['0', 'tempVar'], ''),
},
filteredTemplates: this.props.templates,
} }
this.handleKeyDown = ::this.handleKeyDown this.handleKeyDown = ::this.handleKeyDown
this.handleChange = ::this.handleChange this.handleChange = ::this.handleChange
this.handleUpdate = ::this.handleUpdate this.handleUpdate = ::this.handleUpdate
this.handleChooseTemplate = ::this.handleChooseTemplate
this.handleCloseDrawer = ::this.handleCloseDrawer
this.findTempVar = ::this.findTempVar
this.handleTemplateReplace = ::this.handleTemplateReplace
this.handleMouseOverTempVar = ::this.handleMouseOverTempVar
this.handleClickTempVar = ::this.handleClickTempVar
this.closeDrawer = ::this.closeDrawer
} }
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
@ -42,170 +22,31 @@ class QueryEditor extends Component {
} }
} }
handleCloseDrawer() {
this.setState({isTemplating: false})
}
handleMouseOverTempVar(template) {
this.handleTemplateReplace(template)
}
handleClickTempVar(template) {
// Clicking a tempVar does the same thing as hitting 'Enter'
this.handleTemplateReplace(template, true)
this.closeDrawer()
}
closeDrawer() {
this.setState({
isTemplating: false,
selectedTemplate: {
tempVar: _.get(this.props.templates, ['0', 'tempVar'], ''),
},
})
}
handleKeyDown(e) { handleKeyDown(e) {
const {isTemplating, value} = this.state const {value} = this.state
if (isTemplating) { if (e.key === 'Escape') {
switch (e.key) {
case 'Tab':
case 'ArrowRight':
case 'ArrowDown':
e.preventDefault()
return this.handleTemplateReplace(this.findTempVar('next'))
case 'ArrowLeft':
case 'ArrowUp':
e.preventDefault()
return this.handleTemplateReplace(this.findTempVar('previous'))
case 'Enter':
e.preventDefault()
this.handleTemplateReplace(this.state.selectedTemplate, true)
return this.closeDrawer()
case 'Escape':
e.preventDefault()
return this.closeDrawer()
}
} else if (e.key === 'Escape') {
e.preventDefault() e.preventDefault()
this.setState({value, isTemplating: false}) this.setState({value})
} else if (e.key === 'Enter') { }
if (e.key === 'Enter') {
e.preventDefault() e.preventDefault()
this.handleUpdate() this.handleUpdate()
} }
} }
handleTemplateReplace(selectedTemplate, replaceWholeTemplate) {
const {selectionStart, value} = this.editor
const {tempVar} = selectedTemplate
const newTempVar = replaceWholeTemplate
? tempVar
: tempVar.substring(0, tempVar.length - 1)
// mask matches that will confuse our regex
const masked = applyMasks(value)
const matched = masked.match(MATCH_INCOMPLETE_TEMPLATES)
let templatedValue
if (matched) {
templatedValue = insertTempVar(masked, newTempVar)
templatedValue = unMask(templatedValue)
}
const enterModifier = replaceWholeTemplate ? 0 : -1
const diffInLength =
tempVar.length - _.get(matched, '0', []).length + enterModifier
this.setState({value: templatedValue, selectedTemplate}, () =>
this.editor.setSelectionRange(
selectionStart + diffInLength,
selectionStart + diffInLength
)
)
}
findTempVar(direction) {
const {filteredTemplates: templates} = this.state
const {selectedTemplate} = this.state
const i = _.findIndex(templates, selectedTemplate)
const lastIndex = templates.length - 1
if (i >= 0) {
if (direction === 'next') {
return templates[(i + 1) % templates.length]
}
if (direction === 'previous') {
if (i === 0) {
return templates[lastIndex]
}
return templates[i - 1]
}
}
return templates[0]
}
handleChange() { handleChange() {
const {templates} = this.props this.setState({value: this.editor.value})
const {selectedTemplate} = this.state
const value = this.editor.value
// mask matches that will confuse our regex
const masked = applyMasks(value)
const matched = masked.match(MATCH_INCOMPLETE_TEMPLATES)
if (matched && !_.isEmpty(templates)) {
// maintain cursor poition
const start = this.editor.selectionStart
const end = this.editor.selectionEnd
const filterText = matched[0].substr(1).toLowerCase()
const filteredTemplates = templates.filter(t =>
t.tempVar.toLowerCase().includes(filterText)
)
const found = filteredTemplates.find(
t => t.tempVar === selectedTemplate && selectedTemplate.tempVar
)
const newTemplate = found ? found : filteredTemplates[0]
this.setState({
isTemplating: true,
selectedTemplate: newTemplate,
filteredTemplates,
value,
})
this.editor.setSelectionRange(start, end)
} else {
this.setState({isTemplating: false, value})
}
} }
handleUpdate() { handleUpdate() {
this.props.onUpdate(this.state.value) this.props.onUpdate(this.state.value)
} }
handleChooseTemplate(template) {
this.setState({value: template.query})
}
handleSelectTempVar(tempVar) {
this.setState({selectedTemplate: tempVar})
}
render() { render() {
const {config: {status}} = this.props const {config: {status}} = this.props
const { const {value} = this.state
value,
isTemplating,
selectedTemplate,
filteredTemplates,
} = this.state
return ( return (
<div className="query-editor"> <div className="query-editor">