mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
azuremonitor: adds macros to slate intellisense
and adds tab as well as enter key for autocomplete
This commit is contained in:
parent
a1609a8d53
commit
2d3e02d58b
@ -1,11 +1,9 @@
|
||||
import KustoQueryField from './KustoQueryField';
|
||||
import Kusto from './kusto';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import React, { Component } from 'react';
|
||||
import coreModule from 'app/core/core_module';
|
||||
|
||||
|
||||
|
||||
class Editor extends Component<any, any> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@ -37,7 +35,7 @@ class Editor extends Component<any, any> {
|
||||
const { edited, query } = this.state;
|
||||
|
||||
return (
|
||||
<div className="gf-form-input" style={{height: 'auto'}}>
|
||||
<div className="gf-form-input" style={{ height: 'auto' }}>
|
||||
<KustoQueryField
|
||||
initialQuery={edited ? null : query}
|
||||
onPressEnter={this.onPressEnter}
|
||||
|
@ -24,27 +24,53 @@ export const FUNCTIONS = [
|
||||
{ text: 'min', display: 'min()', hint: '' },
|
||||
{ text: 'max', display: 'max()', hint: '' },
|
||||
{ text: 'avg', display: 'avg()', hint: '' },
|
||||
{
|
||||
text: '$__timeFilter',
|
||||
display: '$__timeFilter()',
|
||||
hint: 'Macro that uses the selected timerange in Grafana to filter the query.',
|
||||
},
|
||||
{
|
||||
text: '$__escapeMulti',
|
||||
display: '$__escapeMulti()',
|
||||
hint: 'Macro to escape multi-value template variables that contain illegal characters.',
|
||||
},
|
||||
{ text: '$__contains', display: '$__contains()', hint: 'Macro for multi-value template variables.' },
|
||||
];
|
||||
|
||||
export const KEYWORDS = [
|
||||
'by', 'on', 'contains', 'notcontains', 'containscs', 'notcontainscs', 'startswith', 'has', 'matches', 'regex', 'true',
|
||||
'false', 'and', 'or', 'typeof', 'int', 'string', 'date', 'datetime', 'time', 'long', 'real', 'boolean', 'bool',
|
||||
'by',
|
||||
'on',
|
||||
'contains',
|
||||
'notcontains',
|
||||
'containscs',
|
||||
'notcontainscs',
|
||||
'startswith',
|
||||
'has',
|
||||
'matches',
|
||||
'regex',
|
||||
'true',
|
||||
'false',
|
||||
'and',
|
||||
'or',
|
||||
'typeof',
|
||||
'int',
|
||||
'string',
|
||||
'date',
|
||||
'datetime',
|
||||
'time',
|
||||
'long',
|
||||
'real',
|
||||
'boolean',
|
||||
'bool',
|
||||
// add some more keywords
|
||||
'where', 'order'
|
||||
'where',
|
||||
'order',
|
||||
];
|
||||
|
||||
// Kusto operators
|
||||
// export const OPERATORS = ['+', '-', '*', '/', '>', '<', '==', '<>', '<=', '>=', '~', '!~'];
|
||||
|
||||
export const DURATION = [
|
||||
'SECONDS',
|
||||
'MINUTES',
|
||||
'HOURS',
|
||||
'DAYS',
|
||||
'WEEKS',
|
||||
'MONTHS',
|
||||
'YEARS'
|
||||
];
|
||||
export const DURATION = ['SECONDS', 'MINUTES', 'HOURS', 'DAYS', 'WEEKS', 'MONTHS', 'YEARS'];
|
||||
|
||||
const tokenizer = {
|
||||
comment: {
|
||||
@ -70,7 +96,7 @@ const tokenizer = {
|
||||
number: /\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,
|
||||
operator: /-|\+|\*|\/|>|<|==|<=?|>=?|<>|!~|~|=|\|/,
|
||||
punctuation: /[{};(),.:]/,
|
||||
variable: /(\[\[(.+?)\]\])|(\$(.+?))\b/
|
||||
variable: /(\[\[(.+?)\]\])|(\$(.+?))\b/,
|
||||
};
|
||||
|
||||
tokenizer['function-context'].inside = {
|
||||
|
@ -17,7 +17,6 @@ import ReactDOM from 'react-dom';
|
||||
import React from 'react';
|
||||
import _ from 'lodash';
|
||||
|
||||
|
||||
function flattenSuggestions(s) {
|
||||
return s ? s.reduce((acc, g) => acc.concat(g.items), []) : [];
|
||||
}
|
||||
@ -107,14 +106,14 @@ class QueryField extends React.Component<any, any> {
|
||||
});
|
||||
|
||||
window.requestAnimationFrame(this.onTypeahead);
|
||||
}
|
||||
};
|
||||
|
||||
request = (url?) => {
|
||||
if (this.props.request) {
|
||||
return this.props.request(url);
|
||||
}
|
||||
return fetch(url);
|
||||
}
|
||||
};
|
||||
|
||||
onChangeQuery = () => {
|
||||
// Send text change to parent
|
||||
@ -122,7 +121,7 @@ class QueryField extends React.Component<any, any> {
|
||||
if (onQueryChange) {
|
||||
onQueryChange(Plain.serialize(this.state.value));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onKeyDown = (event, change) => {
|
||||
const { typeaheadIndex, suggestions } = this.state;
|
||||
@ -147,6 +146,7 @@ class QueryField extends React.Component<any, any> {
|
||||
break;
|
||||
}
|
||||
|
||||
case 'Tab':
|
||||
case 'Enter': {
|
||||
if (this.menuEl) {
|
||||
// Dont blur input
|
||||
@ -191,13 +191,15 @@ class QueryField extends React.Component<any, any> {
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
onTypeahead = (change?, item?) => {
|
||||
return change || this.state.value.change();
|
||||
}
|
||||
};
|
||||
|
||||
applyTypeahead(change?, suggestion?): { value: object } { return { value: {} }; }
|
||||
applyTypeahead(change?, suggestion?): { value: object } {
|
||||
return { value: {} };
|
||||
}
|
||||
|
||||
resetTypeahead = () => {
|
||||
this.setState({
|
||||
@ -206,7 +208,7 @@ class QueryField extends React.Component<any, any> {
|
||||
typeaheadPrefix: '',
|
||||
typeaheadContext: null,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handleBlur = () => {
|
||||
const { onBlur } = this.props;
|
||||
@ -216,14 +218,14 @@ class QueryField extends React.Component<any, any> {
|
||||
if (onBlur) {
|
||||
onBlur();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleFocus = () => {
|
||||
const { onFocus } = this.props;
|
||||
if (onFocus) {
|
||||
onFocus();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onClickItem = item => {
|
||||
const { suggestions } = this.state;
|
||||
@ -241,7 +243,7 @@ class QueryField extends React.Component<any, any> {
|
||||
// Manually triggering change
|
||||
const change = this.applyTypeahead(this.state.value.change(), suggestion);
|
||||
this.onChange(change);
|
||||
}
|
||||
};
|
||||
|
||||
updateMenu = () => {
|
||||
const { suggestions } = this.state;
|
||||
@ -275,11 +277,11 @@ class QueryField extends React.Component<any, any> {
|
||||
menu.style.left = `${rect.left + scrollX - 2}px`;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
menuRef = el => {
|
||||
this.menuEl = el;
|
||||
}
|
||||
};
|
||||
|
||||
renderMenu = () => {
|
||||
const { portalPrefix } = this.props;
|
||||
@ -308,7 +310,7 @@ class QueryField extends React.Component<any, any> {
|
||||
/>
|
||||
</Portal>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
|
Loading…
Reference in New Issue
Block a user