mirror of
https://github.com/grafana/grafana.git
synced 2025-01-08 07:03:11 -06:00
feat(query parts): refactoring query part component to support actions
This commit is contained in:
parent
46ea3ed971
commit
befca9bb2f
@ -5,33 +5,34 @@ import $ from 'jquery';
|
|||||||
import coreModule from 'app/core/core_module';
|
import coreModule from 'app/core/core_module';
|
||||||
|
|
||||||
var template = `
|
var template = `
|
||||||
<div class="tight-form-func-controls">
|
<div class="dropdown cascade-open">
|
||||||
<span class="pointer fa fa-remove" ng-click="removeActionInternal()"></span>
|
<a ng-click="showActionsMenu()" class="query-part-name pointer dropdown-toggle" data-toggle="dropdown">{{part.def.type}}</a>
|
||||||
</div>
|
|
||||||
|
|
||||||
<a ng-click="toggleControls()" class="query-part-name">{{part.def.type}}</a>
|
|
||||||
<span>(</span><span class="query-part-parameters"></span><span>)</span>
|
<span>(</span><span class="query-part-parameters"></span><span>)</span>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li ng-repeat="action in partActions">
|
||||||
|
<a ng-click="triggerPartAction(action)">{{action.text}}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
export function queryPartEditorDirective($compile, templateSrv) {
|
export function queryPartEditorDirective($compile, templateSrv) {
|
||||||
|
|
||||||
var paramTemplate = '<input type="text" style="display:none"' +
|
var paramTemplate = '<input type="text" class="hide input-mini tight-form-func-param"></input>';
|
||||||
' class="input-mini tight-form-func-param"></input>';
|
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
template: template,
|
template: template,
|
||||||
scope: {
|
scope: {
|
||||||
part: "=",
|
part: "=",
|
||||||
removeAction: "&",
|
handleEvent: "&",
|
||||||
partUpdated: "&",
|
|
||||||
getOptions: "&",
|
|
||||||
},
|
},
|
||||||
link: function postLink($scope, elem) {
|
link: function postLink($scope, elem) {
|
||||||
var part = $scope.part;
|
var part = $scope.part;
|
||||||
var partDef = part.def;
|
var partDef = part.def;
|
||||||
var $paramsContainer = elem.find('.query-part-parameters');
|
var $paramsContainer = elem.find('.query-part-parameters');
|
||||||
var $controlsContainer = elem.find('.tight-form-func-controls');
|
|
||||||
|
$scope.partActions = [];
|
||||||
|
|
||||||
function clickFuncParam(paramIndex) {
|
function clickFuncParam(paramIndex) {
|
||||||
/*jshint validthis:true */
|
/*jshint validthis:true */
|
||||||
@ -91,7 +92,7 @@ export function queryPartEditorDirective($compile, templateSrv) {
|
|||||||
if (param.options) { return param.options; }
|
if (param.options) { return param.options; }
|
||||||
|
|
||||||
$scope.$apply(function() {
|
$scope.$apply(function() {
|
||||||
$scope.getOptions().then(function(result) {
|
$scope.handleEvent({$event: {name: 'get-param-options'}}).then(function(result) {
|
||||||
var dynamicOptions = _.map(result, function(op) { return op.value; });
|
var dynamicOptions = _.map(result, function(op) { return op.value; });
|
||||||
callback(dynamicOptions);
|
callback(dynamicOptions);
|
||||||
});
|
});
|
||||||
@ -124,24 +125,16 @@ export function queryPartEditorDirective($compile, templateSrv) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.toggleControls = function() {
|
$scope.showActionsMenu = function() {
|
||||||
var targetDiv = elem.closest('.tight-form');
|
if ($scope.partActions.length === 0) {
|
||||||
|
$scope.handleEvent({$event: {name: 'get-part-actions'}}).then(res => {
|
||||||
if (elem.hasClass('show-function-controls')) {
|
$scope.partActions = res;
|
||||||
elem.removeClass('show-function-controls');
|
});
|
||||||
targetDiv.removeClass('has-open-function');
|
|
||||||
$controlsContainer.hide();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elem.addClass('show-function-controls');
|
|
||||||
targetDiv.addClass('has-open-function');
|
|
||||||
$controlsContainer.show();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.removeActionInternal = function() {
|
$scope.triggerPartAction = function(action) {
|
||||||
$scope.toggleControls();
|
$scope.handleEvent({$event: {name: 'action-' + action.value}});
|
||||||
$scope.removeAction();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function addElementsAndCompile() {
|
function addElementsAndCompile() {
|
||||||
|
@ -25,12 +25,6 @@ var alertQueryDef = new QueryPartDef({
|
|||||||
defaultParams: ['#A', '5m', 'now', 'avg']
|
defaultParams: ['#A', '5m', 'now', 'avg']
|
||||||
});
|
});
|
||||||
|
|
||||||
var reducerAvgDef = new QueryPartDef({
|
|
||||||
type: 'avg',
|
|
||||||
params: [],
|
|
||||||
defaultParams: []
|
|
||||||
});
|
|
||||||
|
|
||||||
var conditionTypes = [
|
var conditionTypes = [
|
||||||
{text: 'Query', value: 'query'},
|
{text: 'Query', value: 'query'},
|
||||||
];
|
];
|
||||||
@ -43,6 +37,19 @@ var evalFunctions = [
|
|||||||
{text: 'HAS NO VALUE' , value: 'no_value'}
|
{text: 'HAS NO VALUE' , value: 'no_value'}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
var reducerTypes = [
|
||||||
|
{text: 'avg()', value: 'avg'},
|
||||||
|
{text: 'min()', value: 'min'},
|
||||||
|
{text: 'max()', value: 'max'},
|
||||||
|
{text: 'sum()' , value: 'sum'},
|
||||||
|
{text: 'count()', value: 'count'},
|
||||||
|
];
|
||||||
|
|
||||||
|
function createReducerPart(model) {
|
||||||
|
var def = new QueryPartDef({type: model.type, defaultParams: []});
|
||||||
|
return new QueryPart(model, def);
|
||||||
|
}
|
||||||
|
|
||||||
var severityLevels = [
|
var severityLevels = [
|
||||||
{text: 'Critical', value: 'critical'},
|
{text: 'Critical', value: 'critical'},
|
||||||
{text: 'Warning', value: 'warning'},
|
{text: 'Warning', value: 'warning'},
|
||||||
@ -50,9 +57,10 @@ var severityLevels = [
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
alertQueryDef: alertQueryDef,
|
alertQueryDef: alertQueryDef,
|
||||||
reducerAvgDef: reducerAvgDef,
|
|
||||||
getSeverityIconClass: getSeverityIconClass,
|
getSeverityIconClass: getSeverityIconClass,
|
||||||
conditionTypes: conditionTypes,
|
conditionTypes: conditionTypes,
|
||||||
evalFunctions: evalFunctions,
|
evalFunctions: evalFunctions,
|
||||||
severityLevels: severityLevels,
|
severityLevels: severityLevels,
|
||||||
|
reducerTypes: reducerTypes,
|
||||||
|
createReducerPart: createReducerPart,
|
||||||
};
|
};
|
||||||
|
@ -16,6 +16,7 @@ export class AlertTabCtrl {
|
|||||||
conditionModels: any;
|
conditionModels: any;
|
||||||
evalFunctions: any;
|
evalFunctions: any;
|
||||||
severityLevels: any;
|
severityLevels: any;
|
||||||
|
reducerTypes: any;
|
||||||
addNotificationSegment;
|
addNotificationSegment;
|
||||||
notifications;
|
notifications;
|
||||||
alertNotifications;
|
alertNotifications;
|
||||||
@ -29,6 +30,7 @@ export class AlertTabCtrl {
|
|||||||
this.evalFunctions = alertDef.evalFunctions;
|
this.evalFunctions = alertDef.evalFunctions;
|
||||||
this.conditionTypes = alertDef.conditionTypes;
|
this.conditionTypes = alertDef.conditionTypes;
|
||||||
this.severityLevels = alertDef.severityLevels;
|
this.severityLevels = alertDef.severityLevels;
|
||||||
|
this.reducerTypes = alertDef.reducerTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
$onInit() {
|
$onInit() {
|
||||||
@ -148,7 +150,7 @@ export class AlertTabCtrl {
|
|||||||
var cm: any = {source: source, type: source.type};
|
var cm: any = {source: source, type: source.type};
|
||||||
|
|
||||||
cm.queryPart = new QueryPart(source.query, alertDef.alertQueryDef);
|
cm.queryPart = new QueryPart(source.query, alertDef.alertQueryDef);
|
||||||
cm.reducerPart = new QueryPart({params: []}, alertDef.reducerAvgDef);
|
cm.reducerPart = alertDef.createReducerPart(source.reducer);
|
||||||
cm.evaluator = source.evaluator;
|
cm.evaluator = source.evaluator;
|
||||||
|
|
||||||
return cm;
|
return cm;
|
||||||
@ -157,6 +159,11 @@ export class AlertTabCtrl {
|
|||||||
queryPartUpdated(conditionModel) {
|
queryPartUpdated(conditionModel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
changeReducerType(conditionModel, value) {
|
||||||
|
conditionModel.source.reducer.type = value;
|
||||||
|
conditionModel.reducerPart = alertDef.createReducerPart(conditionModel.source.reducer);
|
||||||
|
}
|
||||||
|
|
||||||
addCondition(type) {
|
addCondition(type) {
|
||||||
var condition = this.buildDefaultCondition();
|
var condition = this.buildDefaultCondition();
|
||||||
// add to persited model
|
// add to persited model
|
||||||
|
@ -55,6 +55,13 @@
|
|||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<span class="gf-form-label">Reducer</span>
|
<span class="gf-form-label">Reducer</span>
|
||||||
<query-part-editor class="gf-form-label query-part" part="conditionModel.reducerPart" part-updated="ctrl.reducerPartUpdated(conditionModel)">
|
<query-part-editor class="gf-form-label query-part" part="conditionModel.reducerPart" part-updated="ctrl.reducerPartUpdated(conditionModel)">
|
||||||
|
<query-part-editor-actions>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li ng-repeat="reducer in ctrl.reducerTypes">
|
||||||
|
<a ng-click="ctrl.changeReducerType(conditionModel, reducer.value)" ng-hide="reducer.value === conditionModel.reducerPart.def.type">{{reducer.text}}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</query-part-editor-actions>
|
||||||
</query-part-editor>
|
</query-part-editor>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
|
@ -35,12 +35,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gf-form" ng-repeat="part in selectParts">
|
<div class="gf-form" ng-repeat="part in selectParts">
|
||||||
<query-part-editor
|
<query-part-editor class="gf-form-label query-part" part="part" handle-event="ctrl.handleSelectPartEvent(selectParts, part, $event)">
|
||||||
class="gf-form-label query-part"
|
|
||||||
part="part"
|
|
||||||
remove-action="ctrl.removeSelectPart(selectParts, part)"
|
|
||||||
part-updated="ctrl.selectPartUpdated(selectParts, part)"
|
|
||||||
get-options="ctrl.getPartOptions(part)">
|
|
||||||
</query-part-editor>
|
</query-part-editor>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -117,8 +117,24 @@ export class InfluxQueryCtrl extends QueryCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeSelectPart(selectParts, part) {
|
removeSelectPart(selectParts, part) {
|
||||||
this.queryModel.removeSelectPart(selectParts, part);
|
}
|
||||||
this.panelCtrl.refresh();
|
|
||||||
|
handleSelectPartEvent(selectParts, part, evt) {
|
||||||
|
switch (evt.name) {
|
||||||
|
case "get-param-options": {
|
||||||
|
var fieldsQuery = this.queryBuilder.buildExploreQuery('FIELDS');
|
||||||
|
return this.datasource.metricFindQuery(fieldsQuery)
|
||||||
|
.then(this.transformToSegments(true))
|
||||||
|
.catch(this.handleQueryError.bind(this));
|
||||||
|
}
|
||||||
|
case "action-remove-part": {
|
||||||
|
this.queryModel.removeSelectPart(selectParts, part);
|
||||||
|
this.panelCtrl.refresh();
|
||||||
|
}
|
||||||
|
case "get-part-actions": {
|
||||||
|
return this.$q.when([{text: 'Remove', value: 'remove-part'}]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
selectPartUpdated() {
|
selectPartUpdated() {
|
||||||
|
@ -140,6 +140,12 @@
|
|||||||
& > .dropdown-menu {
|
& > .dropdown-menu {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.cascade-open {
|
||||||
|
.dropdown-menu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backdrop to catch body clicks on mobile, etc.
|
// Backdrop to catch body clicks on mobile, etc.
|
||||||
|
Loading…
Reference in New Issue
Block a user