Merge pull request #3817 from influxdata/tempvars/map-type-upload
Tempvars/map type uploadpull/10616/head
commit
fec39a1ca5
|
@ -97,7 +97,7 @@ message Template {
|
||||||
}
|
}
|
||||||
|
|
||||||
message TemplateValue {
|
message TemplateValue {
|
||||||
string type = 1; // Type can be tagKey, tagValue, fieldKey, csv, measurement, database, constant
|
string type = 1; // Type can be tagKey, tagValue, fieldKey, csv, map, measurement, database, constant
|
||||||
string value = 2; // Value is the specific value used to replace a template in an InfluxQL query
|
string value = 2; // Value is the specific value used to replace a template in an InfluxQL query
|
||||||
bool selected = 3; // Selected states that this variable has been picked to use for replacement
|
bool selected = 3; // Selected states that this variable has been picked to use for replacement
|
||||||
string key = 4; // Key is the key for a specific Value if the Template Type is map (optional)
|
string key = 4; // Key is the key for a specific Value if the Template Type is map (optional)
|
||||||
|
|
|
@ -159,7 +159,7 @@ type Range struct {
|
||||||
// TemplateValue is a value use to replace a template in an InfluxQL query
|
// TemplateValue is a value use to replace a template in an InfluxQL query
|
||||||
type TemplateValue struct {
|
type TemplateValue struct {
|
||||||
Value string `json:"value"` // Value is the specific value used to replace a template in an InfluxQL query
|
Value string `json:"value"` // Value is the specific value used to replace a template in an InfluxQL query
|
||||||
Type string `json:"type"` // Type can be tagKey, tagValue, fieldKey, csv, measurement, database, constant, influxql
|
Type string `json:"type"` // Type can be tagKey, tagValue, fieldKey, csv, map, measurement, database, constant, influxql
|
||||||
Selected bool `json:"selected"` // Selected states that this variable has been picked to use for replacement
|
Selected bool `json:"selected"` // Selected states that this variable has been picked to use for replacement
|
||||||
Key string `json:"key,omitempty"` // Key is the key for the Value if the Template Type is 'map'
|
Key string `json:"key,omitempty"` // Key is the key for the Value if the Template Type is 'map'
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ type TemplateID string
|
||||||
type Template struct {
|
type Template struct {
|
||||||
TemplateVar
|
TemplateVar
|
||||||
ID TemplateID `json:"id"` // ID is the unique ID associated with this template
|
ID TemplateID `json:"id"` // ID is the unique ID associated with this template
|
||||||
Type string `json:"type"` // Type can be fieldKeys, tagKeys, tagValues, CSV, constant, measurements, databases, map, influxql
|
Type string `json:"type"` // Type can be fieldKeys, tagKeys, tagValues, csv, constant, measurements, databases, map, influxql
|
||||||
Label string `json:"label"` // Label is a user-facing description of the Template
|
Label string `json:"label"` // Label is a user-facing description of the Template
|
||||||
Query *TemplateQuery `json:"query,omitempty"` // Query is used to generate the choices for a template
|
Query *TemplateQuery `json:"query,omitempty"` // Query is used to generate the choices for a template
|
||||||
}
|
}
|
||||||
|
|
|
@ -4179,7 +4179,7 @@
|
||||||
},
|
},
|
||||||
"type": {
|
"type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["csv", "tagKey", "tagValue", "fieldKey", "timeStamp"],
|
"enum": ["csv", "tagKey", "tagValue", "fieldKey", "timeStamp", "map"],
|
||||||
"description":
|
"description":
|
||||||
"The type will change the format of the output value. tagKey/fieldKey are double quoted; tagValue are single quoted; csv and timeStamp are not quoted."
|
"The type will change the format of the output value. tagKey/fieldKey are double quoted; tagValue are single quoted; csv and timeStamp are not quoted."
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,7 +22,7 @@ func ValidTemplateRequest(template *chronograf.Template) error {
|
||||||
switch v.Type {
|
switch v.Type {
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Unknown template variable type %s", v.Type)
|
return fmt.Errorf("Unknown template variable type %s", v.Type)
|
||||||
case "csv", "fieldKey", "tagKey", "tagValue", "measurement", "database", "constant", "influxql":
|
case "csv", "map", "fieldKey", "tagKey", "tagValue", "measurement", "database", "constant", "influxql":
|
||||||
}
|
}
|
||||||
|
|
||||||
if template.Type == "map" && v.Key == "" {
|
if template.Type == "map" && v.Key == "" {
|
||||||
|
|
|
@ -69,7 +69,7 @@ func TestValidTemplateRequest(t *testing.T) {
|
||||||
{
|
{
|
||||||
Key: "key",
|
Key: "key",
|
||||||
Value: "value",
|
Value: "value",
|
||||||
Type: "constant",
|
Type: "map",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -84,7 +84,7 @@ func TestValidTemplateRequest(t *testing.T) {
|
||||||
Values: []chronograf.TemplateValue{
|
Values: []chronograf.TemplateValue{
|
||||||
{
|
{
|
||||||
Value: "value",
|
Value: "value",
|
||||||
Type: "constant",
|
Type: "map",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -312,7 +312,10 @@ const removeUnselectedTemplateValues = (
|
||||||
'templates',
|
'templates',
|
||||||
[]
|
[]
|
||||||
).map(template => {
|
).map(template => {
|
||||||
if (template.type === TempVarsModels.TemplateType.CSV) {
|
if (
|
||||||
|
template.type === TempVarsModels.TemplateType.CSV ||
|
||||||
|
template.type === TempVarsModels.TemplateType.Map
|
||||||
|
) {
|
||||||
return template
|
return template
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -541,6 +541,12 @@ export const notifyInvalidTimeRangeValueInURLQuery = (): Notification => ({
|
||||||
message: `Invalid URL query value supplied for lower or upper time range.`,
|
message: `Invalid URL query value supplied for lower or upper time range.`,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const notifyInvalidMapType = (): Notification => ({
|
||||||
|
...defaultErrorNotification,
|
||||||
|
icon: 'cube',
|
||||||
|
message: `Template Variables of map type accept two comma separated values per line`,
|
||||||
|
})
|
||||||
|
|
||||||
export const notifyInvalidZoomedTimeRangeValueInURLQuery = (): Notification => ({
|
export const notifyInvalidZoomedTimeRangeValueInURLQuery = (): Notification => ({
|
||||||
...defaultErrorNotification,
|
...defaultErrorNotification,
|
||||||
icon: 'cube',
|
icon: 'cube',
|
||||||
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
import React, {PureComponent, ChangeEvent} from 'react'
|
||||||
|
import {getDeep} from 'src/utils/wrappers'
|
||||||
|
import Papa from 'papaparse'
|
||||||
|
import _ from 'lodash'
|
||||||
|
|
||||||
|
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||||
|
|
||||||
|
import TemplatePreviewList from 'src/tempVars/components/TemplatePreviewList'
|
||||||
|
import DragAndDrop from 'src/shared/components/DragAndDrop'
|
||||||
|
import {
|
||||||
|
notifyCSVUploadFailed,
|
||||||
|
notifyInvalidMapType,
|
||||||
|
} from 'src/shared/copy/notifications'
|
||||||
|
|
||||||
|
import {TemplateBuilderProps, TemplateValueType} from 'src/types'
|
||||||
|
import {trimAndRemoveQuotes} from 'src/tempVars/utils/parsing'
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
templateValuesString: string
|
||||||
|
}
|
||||||
|
|
||||||
|
@ErrorHandling
|
||||||
|
class MapTemplateBuilder extends PureComponent<TemplateBuilderProps, State> {
|
||||||
|
public constructor(props: TemplateBuilderProps) {
|
||||||
|
super(props)
|
||||||
|
const templateValues = props.template.values.map(v => v.value)
|
||||||
|
const templateKeys = props.template.values.map(v => v.key)
|
||||||
|
const templateValuesString = templateKeys
|
||||||
|
.map((v, i) => `${v}, ${templateValues[i]}`)
|
||||||
|
.join('\n')
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
templateValuesString,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
const {onUpdateDefaultTemplateValue, template} = this.props
|
||||||
|
const {templateValuesString} = this.state
|
||||||
|
const pluralizer = template.values.length === 1 ? '' : 's'
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="form-group col-xs-12">
|
||||||
|
<label>Upload a CSV File</label>
|
||||||
|
<DragAndDrop
|
||||||
|
submitText="Preview"
|
||||||
|
fileTypesToAccept={this.validFileExtension}
|
||||||
|
handleSubmit={this.handleUploadFile}
|
||||||
|
submitOnDrop={true}
|
||||||
|
compact={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="form-group col-xs-12">
|
||||||
|
<label>Comma Separated Values</label>
|
||||||
|
<div className="temp-builder--mq-controls">
|
||||||
|
<textarea
|
||||||
|
className="form-control input-sm"
|
||||||
|
value={templateValuesString}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
onBlur={this.handleBlur}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="form-group col-xs-12 temp-builder--results">
|
||||||
|
<p className="temp-builder--validation">
|
||||||
|
Mapping contains <strong>{template.values.length}</strong> key-value
|
||||||
|
pair{pluralizer}
|
||||||
|
</p>
|
||||||
|
{template.values.length > 0 && (
|
||||||
|
<TemplatePreviewList
|
||||||
|
items={template.values}
|
||||||
|
onUpdateDefaultTemplateValue={onUpdateDefaultTemplateValue}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleUploadFile = (
|
||||||
|
uploadContent: string,
|
||||||
|
fileName: string
|
||||||
|
): void => {
|
||||||
|
const {template, onUpdateTemplate} = this.props
|
||||||
|
|
||||||
|
const fileExtensionRegex = new RegExp(`${this.validFileExtension}$`)
|
||||||
|
if (!fileName.match(fileExtensionRegex)) {
|
||||||
|
this.props.notify(notifyCSVUploadFailed())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({templateValuesString: uploadContent})
|
||||||
|
|
||||||
|
const nextValues = this.constructValuesFromString(uploadContent)
|
||||||
|
|
||||||
|
onUpdateTemplate({...template, values: nextValues})
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleBlur = (): void => {
|
||||||
|
const {template, onUpdateTemplate} = this.props
|
||||||
|
const {templateValuesString} = this.state
|
||||||
|
|
||||||
|
const values = this.constructValuesFromString(templateValuesString)
|
||||||
|
|
||||||
|
onUpdateTemplate({...template, values})
|
||||||
|
}
|
||||||
|
|
||||||
|
private get validFileExtension(): string {
|
||||||
|
return '.csv'
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleChange = (e: ChangeEvent<HTMLTextAreaElement>): void => {
|
||||||
|
this.setState({templateValuesString: e.target.value})
|
||||||
|
}
|
||||||
|
|
||||||
|
private constructValuesFromString(templateValuesString) {
|
||||||
|
const {notify} = this.props
|
||||||
|
const parsedTVS = Papa.parse(templateValuesString)
|
||||||
|
const templateValuesData = getDeep<string[][]>(parsedTVS, 'data', [[]])
|
||||||
|
|
||||||
|
if (templateValuesData.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let arrayOfKeys = []
|
||||||
|
let values = []
|
||||||
|
_.forEach(templateValuesData, arr => {
|
||||||
|
if (arr.length === 2 || (arr.length === 3 && arr[2] === '')) {
|
||||||
|
const key = trimAndRemoveQuotes(arr[0])
|
||||||
|
const value = trimAndRemoveQuotes(arr[1])
|
||||||
|
|
||||||
|
if (!arrayOfKeys.includes(key) && key !== '') {
|
||||||
|
values = [
|
||||||
|
...values,
|
||||||
|
{
|
||||||
|
type: TemplateValueType.Map,
|
||||||
|
value,
|
||||||
|
key,
|
||||||
|
selected: false,
|
||||||
|
localSelected: false,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
arrayOfKeys = [...arrayOfKeys, key]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
notify(notifyInvalidMapType())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MapTemplateBuilder
|
|
@ -4,9 +4,9 @@ import Dropdown from 'src/shared/components/Dropdown'
|
||||||
import OverlayTechnology from 'src/reusable_ui/components/overlays/OverlayTechnology'
|
import OverlayTechnology from 'src/reusable_ui/components/overlays/OverlayTechnology'
|
||||||
import TemplateVariableEditor from 'src/tempVars/components/TemplateVariableEditor'
|
import TemplateVariableEditor from 'src/tempVars/components/TemplateVariableEditor'
|
||||||
import {calculateDropdownWidth} from 'src/dashboards/constants/templateControlBar'
|
import {calculateDropdownWidth} from 'src/dashboards/constants/templateControlBar'
|
||||||
import Authorized, {isUserAuthorized, EDITOR_ROLE} from 'src/auth/Authorized'
|
import Authorized, {EDITOR_ROLE} from 'src/auth/Authorized'
|
||||||
|
|
||||||
import {Template, Source} from 'src/types'
|
import {Template, Source, TemplateValueType} from 'src/types'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
template: Template
|
template: Template
|
||||||
|
@ -33,20 +33,15 @@ class TemplateControlDropdown extends PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const {
|
const {template, source, onPickTemplate, onCreateTemplate} = this.props
|
||||||
template,
|
|
||||||
isUsingAuth,
|
|
||||||
meRole,
|
|
||||||
source,
|
|
||||||
onPickTemplate,
|
|
||||||
onCreateTemplate,
|
|
||||||
} = this.props
|
|
||||||
const {isEditing} = this.state
|
const {isEditing} = this.state
|
||||||
|
|
||||||
const dropdownItems = template.values.map(value => ({
|
const dropdownItems = template.values.map(value => {
|
||||||
...value,
|
if (value.type === TemplateValueType.Map) {
|
||||||
text: value.value,
|
return {...value, text: value.key}
|
||||||
}))
|
}
|
||||||
|
return {...value, text: value.value}
|
||||||
|
})
|
||||||
|
|
||||||
const dropdownStyle = template.values.length
|
const dropdownStyle = template.values.length
|
||||||
? {minWidth: calculateDropdownWidth(template.values)}
|
? {minWidth: calculateDropdownWidth(template.values)}
|
||||||
|
@ -63,7 +58,6 @@ class TemplateControlDropdown extends PureComponent<Props, State> {
|
||||||
menuClass="dropdown-astronaut"
|
menuClass="dropdown-astronaut"
|
||||||
useAutoComplete={true}
|
useAutoComplete={true}
|
||||||
selected={localSelectedItem.text}
|
selected={localSelectedItem.text}
|
||||||
disabled={isUsingAuth && !isUserAuthorized(meRole, EDITOR_ROLE)}
|
|
||||||
onChoose={onPickTemplate(template.id)}
|
onChoose={onPickTemplate(template.id)}
|
||||||
/>
|
/>
|
||||||
<Authorized requiredRole={EDITOR_ROLE}>
|
<Authorized requiredRole={EDITOR_ROLE}>
|
||||||
|
|
|
@ -42,8 +42,8 @@ class TemplatePreviewList extends PureComponent<Props> {
|
||||||
private get resultsListHeight() {
|
private get resultsListHeight() {
|
||||||
const {items} = this.props
|
const {items} = this.props
|
||||||
const count = Math.min(items.length, RESULTS_TO_DISPLAY)
|
const count = Math.min(items.length, RESULTS_TO_DISPLAY)
|
||||||
|
const scrollOffset = count > RESULTS_TO_DISPLAY ? OFFSET : 0
|
||||||
return count * (LI_HEIGHT + LI_MARGIN_BOTTOM) - OFFSET
|
return count * (LI_HEIGHT + LI_MARGIN_BOTTOM) - scrollOffset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React, {PureComponent} from 'react'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import {TEMPLATE_PREVIEW_LIST_DIMENSIONS as DIMENSIONS} from 'src/tempVars/constants'
|
import {TEMPLATE_PREVIEW_LIST_DIMENSIONS as DIMENSIONS} from 'src/tempVars/constants'
|
||||||
|
|
||||||
import {TemplateValue} from 'src/types'
|
import {TemplateValue, TemplateValueType} from 'src/types'
|
||||||
|
|
||||||
const {LI_HEIGHT, LI_MARGIN_BOTTOM} = DIMENSIONS
|
const {LI_HEIGHT, LI_MARGIN_BOTTOM} = DIMENSIONS
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ class TemplatePreviewListItem extends PureComponent<Props> {
|
||||||
active: this.isDefault,
|
active: this.isDefault,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
|
{this.mapTempVarKey}
|
||||||
{item.value}
|
{item.value}
|
||||||
{this.defaultIndicator()}
|
{this.defaultIndicator()}
|
||||||
</li>
|
</li>
|
||||||
|
@ -38,6 +39,13 @@ class TemplatePreviewListItem extends PureComponent<Props> {
|
||||||
return this.props.item.selected
|
return this.props.item.selected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get mapTempVarKey(): string {
|
||||||
|
const {item} = this.props
|
||||||
|
if (item.type === TemplateValueType.Map) {
|
||||||
|
return `${item.key} -->`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private defaultIndicator(): JSX.Element {
|
private defaultIndicator(): JSX.Element {
|
||||||
if (this.isDefault) {
|
if (this.isDefault) {
|
||||||
return <div className="temp-builder--default">DEFAULT</div>
|
return <div className="temp-builder--default">DEFAULT</div>
|
||||||
|
|
|
@ -23,6 +23,7 @@ import {
|
||||||
|
|
||||||
import DatabasesTemplateBuilder from 'src/tempVars/components/DatabasesTemplateBuilder'
|
import DatabasesTemplateBuilder from 'src/tempVars/components/DatabasesTemplateBuilder'
|
||||||
import CSVTemplateBuilder from 'src/tempVars/components/CSVTemplateBuilder'
|
import CSVTemplateBuilder from 'src/tempVars/components/CSVTemplateBuilder'
|
||||||
|
import MapTemplateBuilder from 'src/tempVars/components/MapTemplateBuilder'
|
||||||
import MeasurementsTemplateBuilder from 'src/tempVars/components/MeasurementsTemplateBuilder'
|
import MeasurementsTemplateBuilder from 'src/tempVars/components/MeasurementsTemplateBuilder'
|
||||||
import FieldKeysTemplateBuilder from 'src/tempVars/components/FieldKeysTemplateBuilder'
|
import FieldKeysTemplateBuilder from 'src/tempVars/components/FieldKeysTemplateBuilder'
|
||||||
import TagKeysTemplateBuilder from 'src/tempVars/components/TagKeysTemplateBuilder'
|
import TagKeysTemplateBuilder from 'src/tempVars/components/TagKeysTemplateBuilder'
|
||||||
|
@ -66,6 +67,7 @@ interface State {
|
||||||
const TEMPLATE_BUILDERS = {
|
const TEMPLATE_BUILDERS = {
|
||||||
[TemplateType.Databases]: DatabasesTemplateBuilder,
|
[TemplateType.Databases]: DatabasesTemplateBuilder,
|
||||||
[TemplateType.CSV]: CSVTemplateBuilder,
|
[TemplateType.CSV]: CSVTemplateBuilder,
|
||||||
|
[TemplateType.Map]: MapTemplateBuilder,
|
||||||
[TemplateType.Measurements]: MeasurementsTemplateBuilder,
|
[TemplateType.Measurements]: MeasurementsTemplateBuilder,
|
||||||
[TemplateType.FieldKeys]: FieldKeysTemplateBuilder,
|
[TemplateType.FieldKeys]: FieldKeysTemplateBuilder,
|
||||||
[TemplateType.TagKeys]: TagKeysTemplateBuilder,
|
[TemplateType.TagKeys]: TagKeysTemplateBuilder,
|
||||||
|
|
|
@ -34,6 +34,10 @@ export const TEMPLATE_TYPES_LIST: TemplateTypesListItem[] = [
|
||||||
text: 'CSV',
|
text: 'CSV',
|
||||||
type: TemplateType.CSV,
|
type: TemplateType.CSV,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: 'Map',
|
||||||
|
type: TemplateType.Map,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
text: 'Custom Meta Query',
|
text: 'Custom Meta Query',
|
||||||
type: TemplateType.MetaQuery,
|
type: TemplateType.MetaQuery,
|
||||||
|
@ -42,6 +46,7 @@ export const TEMPLATE_TYPES_LIST: TemplateTypesListItem[] = [
|
||||||
|
|
||||||
export const TEMPLATE_VARIABLE_TYPES = {
|
export const TEMPLATE_VARIABLE_TYPES = {
|
||||||
[TemplateType.CSV]: TemplateValueType.CSV,
|
[TemplateType.CSV]: TemplateValueType.CSV,
|
||||||
|
[TemplateType.Map]: TemplateValueType.Map,
|
||||||
[TemplateType.Databases]: TemplateValueType.Database,
|
[TemplateType.Databases]: TemplateValueType.Database,
|
||||||
[TemplateType.Measurements]: TemplateValueType.Measurement,
|
[TemplateType.Measurements]: TemplateValueType.Measurement,
|
||||||
[TemplateType.FieldKeys]: TemplateValueType.FieldKey,
|
[TemplateType.FieldKeys]: TemplateValueType.FieldKey,
|
||||||
|
@ -106,6 +111,16 @@ export const DEFAULT_TEMPLATES: DefaultTemplates = {
|
||||||
query: {},
|
query: {},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
[TemplateType.Map]: () => {
|
||||||
|
return {
|
||||||
|
id: uuid.v4(),
|
||||||
|
tempVar: '',
|
||||||
|
values: [],
|
||||||
|
type: TemplateType.Map,
|
||||||
|
label: '',
|
||||||
|
query: {},
|
||||||
|
}
|
||||||
|
},
|
||||||
[TemplateType.TagKeys]: () => {
|
[TemplateType.TagKeys]: () => {
|
||||||
return {
|
return {
|
||||||
id: uuid.v4(),
|
id: uuid.v4(),
|
||||||
|
|
|
@ -89,6 +89,7 @@ const renderTemplate = (query: string, template: Template): string => {
|
||||||
case TemplateValueType.CSV:
|
case TemplateValueType.CSV:
|
||||||
case TemplateValueType.Constant:
|
case TemplateValueType.Constant:
|
||||||
case TemplateValueType.MetaQuery:
|
case TemplateValueType.MetaQuery:
|
||||||
|
case TemplateValueType.Map:
|
||||||
return replaceAll(q, tempVar, value)
|
return replaceAll(q, tempVar, value)
|
||||||
default:
|
default:
|
||||||
return query
|
return query
|
||||||
|
|
|
@ -8,6 +8,7 @@ export enum TemplateValueType {
|
||||||
Measurement = 'measurement',
|
Measurement = 'measurement',
|
||||||
TagValue = 'tagValue',
|
TagValue = 'tagValue',
|
||||||
CSV = 'csv',
|
CSV = 'csv',
|
||||||
|
Map = 'map',
|
||||||
Points = 'points',
|
Points = 'points',
|
||||||
Constant = 'constant',
|
Constant = 'constant',
|
||||||
MetaQuery = 'influxql',
|
MetaQuery = 'influxql',
|
||||||
|
@ -19,6 +20,7 @@ export interface TemplateValue {
|
||||||
type: TemplateValueType
|
type: TemplateValueType
|
||||||
selected: boolean
|
selected: boolean
|
||||||
localSelected: boolean
|
localSelected: boolean
|
||||||
|
key?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TemplateQuery {
|
export interface TemplateQuery {
|
||||||
|
@ -38,6 +40,7 @@ export enum TemplateType {
|
||||||
TagKeys = 'tagKeys',
|
TagKeys = 'tagKeys',
|
||||||
TagValues = 'tagValues',
|
TagValues = 'tagValues',
|
||||||
CSV = 'csv',
|
CSV = 'csv',
|
||||||
|
Map = 'map',
|
||||||
Databases = 'databases',
|
Databases = 'databases',
|
||||||
MetaQuery = 'influxql',
|
MetaQuery = 'influxql',
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue