Commit befca9bb by Torkel Ödegaard

feat(query parts): refactoring query part component to support actions

parent 46ea3ed9
...@@ -5,33 +5,34 @@ import $ from 'jquery'; ...@@ -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) { ...@@ -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) { ...@@ -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({ ...@@ -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 = [ ...@@ -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 = [ ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 { ...@@ -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 @@ ...@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment