diff --git a/public/app/core/components/query_part/query_part_editor.ts b/public/app/core/components/query_part/query_part_editor.ts
index f9122ee283b..91021b5f7c5 100644
--- a/public/app/core/components/query_part/query_part_editor.ts
+++ b/public/app/core/components/query_part/query_part_editor.ts
@@ -5,33 +5,34 @@ import $ from 'jquery';
import coreModule from 'app/core/core_module';
var template = `
-
+
{{part.def.type}}
()
+
`;
/** @ngInject */
export function queryPartEditorDirective($compile, templateSrv) {
- var paramTemplate = '
';
+ var paramTemplate = '
';
+
return {
restrict: 'E',
template: template,
scope: {
part: "=",
- removeAction: "&",
- partUpdated: "&",
- getOptions: "&",
+ handleEvent: "&",
},
link: function postLink($scope, elem) {
var part = $scope.part;
var partDef = part.def;
var $paramsContainer = elem.find('.query-part-parameters');
- var $controlsContainer = elem.find('.tight-form-func-controls');
+
+ $scope.partActions = [];
function clickFuncParam(paramIndex) {
/*jshint validthis:true */
@@ -91,7 +92,7 @@ export function queryPartEditorDirective($compile, templateSrv) {
if (param.options) { return param.options; }
$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; });
callback(dynamicOptions);
});
@@ -124,24 +125,16 @@ export function queryPartEditorDirective($compile, templateSrv) {
};
}
- $scope.toggleControls = function() {
- var targetDiv = elem.closest('.tight-form');
-
- if (elem.hasClass('show-function-controls')) {
- elem.removeClass('show-function-controls');
- targetDiv.removeClass('has-open-function');
- $controlsContainer.hide();
- return;
+ $scope.showActionsMenu = function() {
+ if ($scope.partActions.length === 0) {
+ $scope.handleEvent({$event: {name: 'get-part-actions'}}).then(res => {
+ $scope.partActions = res;
+ });
}
-
- elem.addClass('show-function-controls');
- targetDiv.addClass('has-open-function');
- $controlsContainer.show();
};
- $scope.removeActionInternal = function() {
- $scope.toggleControls();
- $scope.removeAction();
+ $scope.triggerPartAction = function(action) {
+ $scope.handleEvent({$event: {name: 'action-' + action.value}});
};
function addElementsAndCompile() {
diff --git a/public/app/features/alerting/alert_def.ts b/public/app/features/alerting/alert_def.ts
index 84c1bc7cb05..69f639d04c4 100644
--- a/public/app/features/alerting/alert_def.ts
+++ b/public/app/features/alerting/alert_def.ts
@@ -25,12 +25,6 @@ var alertQueryDef = new QueryPartDef({
defaultParams: ['#A', '5m', 'now', 'avg']
});
-var reducerAvgDef = new QueryPartDef({
- type: 'avg',
- params: [],
- defaultParams: []
-});
-
var conditionTypes = [
{text: 'Query', value: 'query'},
];
@@ -43,6 +37,19 @@ var evalFunctions = [
{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 = [
{text: 'Critical', value: 'critical'},
{text: 'Warning', value: 'warning'},
@@ -50,9 +57,10 @@ var severityLevels = [
export default {
alertQueryDef: alertQueryDef,
- reducerAvgDef: reducerAvgDef,
getSeverityIconClass: getSeverityIconClass,
conditionTypes: conditionTypes,
evalFunctions: evalFunctions,
severityLevels: severityLevels,
+ reducerTypes: reducerTypes,
+ createReducerPart: createReducerPart,
};
diff --git a/public/app/features/alerting/alert_tab_ctrl.ts b/public/app/features/alerting/alert_tab_ctrl.ts
index 217f67124ef..3ca46dd9fda 100644
--- a/public/app/features/alerting/alert_tab_ctrl.ts
+++ b/public/app/features/alerting/alert_tab_ctrl.ts
@@ -16,6 +16,7 @@ export class AlertTabCtrl {
conditionModels: any;
evalFunctions: any;
severityLevels: any;
+ reducerTypes: any;
addNotificationSegment;
notifications;
alertNotifications;
@@ -29,6 +30,7 @@ export class AlertTabCtrl {
this.evalFunctions = alertDef.evalFunctions;
this.conditionTypes = alertDef.conditionTypes;
this.severityLevels = alertDef.severityLevels;
+ this.reducerTypes = alertDef.reducerTypes;
}
$onInit() {
@@ -148,7 +150,7 @@ export class AlertTabCtrl {
var cm: any = {source: source, type: source.type};
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;
return cm;
@@ -157,6 +159,11 @@ export class AlertTabCtrl {
queryPartUpdated(conditionModel) {
}
+ changeReducerType(conditionModel, value) {
+ conditionModel.source.reducer.type = value;
+ conditionModel.reducerPart = alertDef.createReducerPart(conditionModel.source.reducer);
+ }
+
addCondition(type) {
var condition = this.buildDefaultCondition();
// add to persited model
diff --git a/public/app/features/alerting/partials/alert_tab.html b/public/app/features/alerting/partials/alert_tab.html
index e9f7e2aa556..65122b279f1 100644
--- a/public/app/features/alerting/partials/alert_tab.html
+++ b/public/app/features/alerting/partials/alert_tab.html
@@ -55,6 +55,13 @@
Reducer
+
+
+
diff --git a/public/app/plugins/datasource/influxdb/partials/query.editor.html b/public/app/plugins/datasource/influxdb/partials/query.editor.html
index 68b8ee60d98..53a2ac75ef4 100644
--- a/public/app/plugins/datasource/influxdb/partials/query.editor.html
+++ b/public/app/plugins/datasource/influxdb/partials/query.editor.html
@@ -35,12 +35,7 @@
-
+
diff --git a/public/app/plugins/datasource/influxdb/query_ctrl.ts b/public/app/plugins/datasource/influxdb/query_ctrl.ts
index 4cc07e9a64b..577902668dd 100644
--- a/public/app/plugins/datasource/influxdb/query_ctrl.ts
+++ b/public/app/plugins/datasource/influxdb/query_ctrl.ts
@@ -117,8 +117,24 @@ export class InfluxQueryCtrl extends QueryCtrl {
}
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() {
diff --git a/public/sass/components/_dropdown.scss b/public/sass/components/_dropdown.scss
index 3934fa69640..142910033b0 100644
--- a/public/sass/components/_dropdown.scss
+++ b/public/sass/components/_dropdown.scss
@@ -140,6 +140,12 @@
& > .dropdown-menu {
display: block;
}
+
+ &.cascade-open {
+ .dropdown-menu {
+ display: block;
+ }
+ }
}
// Backdrop to catch body clicks on mobile, etc.