azuremonitor: adds macros to slate intellisense

and adds tab as well as enter key for autocomplete
This commit is contained in:
Daniel Lee 2019-01-29 15:02:46 +01:00
parent a1609a8d53
commit 2d3e02d58b
3 changed files with 57 additions and 31 deletions

View File

@ -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}

View File

@ -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 = {

View File

@ -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 (