Merge branch 'master' into alerting_definitions
This commit is contained in:
@@ -14,6 +14,15 @@
|
||||
* **Singlestat**: Fixes prefix an postfix for gauges, fixes [#4812](https://github.com/grafana/grafana/issues/4812)
|
||||
* **Singlestat**: Fixes auto-refresh on change for some options, fixes [#4809](https://github.com/grafana/grafana/issues/4809)
|
||||
|
||||
### Breaking changes
|
||||
**Data Source Query Editors**: Issue [#3900](https://github.com/grafana/grafana/issues/3900)
|
||||
|
||||
Query editors have been updated to use the new form styles. External data source plugins needs to be
|
||||
updated to work. Sorry to introduce breaking change this late in beta phase. We wanted to get this change
|
||||
in before 3.0 stable is released so we don't have to break data sources in next release (3.1). If you are
|
||||
a data source plugin author and want help for how the new form styles work please ask for help in
|
||||
slack channel (link to slack channel in readme).
|
||||
|
||||
# 3.0.0-beta5 (2016-04-15)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
@@ -11,11 +11,6 @@ export function infoPopover() {
|
||||
template: '<i class="fa fa-info-circle"></i>',
|
||||
transclude: true,
|
||||
link: function(scope, elem, attrs, ctrl, transclude) {
|
||||
// var inputElem = elem.prev();
|
||||
// if (inputElem.length === 0) {
|
||||
// console.log('Failed to find input element for popover');
|
||||
// return;
|
||||
// }
|
||||
|
||||
var offset = attrs.offset || '0 -10px';
|
||||
var position = attrs.position || 'right middle';
|
||||
|
||||
@@ -9,10 +9,10 @@ function (_, $, coreModule) {
|
||||
coreModule.default.directive('dropdownTypeahead', function($compile) {
|
||||
|
||||
var inputTemplate = '<input type="text"'+
|
||||
' class="tight-form-input input-medium tight-form-input"' +
|
||||
' class="gf-form-input input-medium tight-form-input"' +
|
||||
' spellcheck="false" style="display:none"></input>';
|
||||
|
||||
var buttonTemplate = '<a class="tight-form-item tight-form-func dropdown-toggle"' +
|
||||
var buttonTemplate = '<a class="gf-form-label tight-form-func dropdown-toggle"' +
|
||||
' tabindex="1" gf-dropdown="menuItems" data-toggle="dropdown"' +
|
||||
' data-placement="top"><i class="fa fa-plus"></i></a>';
|
||||
|
||||
|
||||
@@ -8,10 +8,13 @@ function (_, $, coreModule) {
|
||||
|
||||
coreModule.default.directive('metricSegment', function($compile, $sce) {
|
||||
var inputTemplate = '<input type="text" data-provide="typeahead" ' +
|
||||
' class="tight-form-clear-input input-medium"' +
|
||||
' class="gf-form-input input-medium"' +
|
||||
' spellcheck="false" style="display:none"></input>';
|
||||
|
||||
var buttonTemplate = '<a class="tight-form-item" ng-class="segment.cssClass" ' +
|
||||
var linkTemplate = '<a class="gf-form-label" ng-class="segment.cssClass" ' +
|
||||
'tabindex="1" give-focus="segment.focus" ng-bind-html="segment.html"></a>';
|
||||
|
||||
var selectTemplate = '<a class="gf-form-input gf-form-input--dropdown" ng-class="segment.cssClass" ' +
|
||||
'tabindex="1" give-focus="segment.focus" ng-bind-html="segment.html"></a>';
|
||||
|
||||
return {
|
||||
@@ -20,9 +23,9 @@ function (_, $, coreModule) {
|
||||
getOptions: "&",
|
||||
onChange: "&",
|
||||
},
|
||||
link: function($scope, elem) {
|
||||
link: function($scope, elem, attrs) {
|
||||
var $input = $(inputTemplate);
|
||||
var $button = $(buttonTemplate);
|
||||
var $button = $(attrs.styleMode === 'select' ? selectTemplate : linkTemplate);
|
||||
var segment = $scope.segment;
|
||||
var options = null;
|
||||
var cancelBlur = null;
|
||||
|
||||
@@ -25,7 +25,6 @@ export class ContextSrv {
|
||||
isGrafanaAdmin: any;
|
||||
isEditor: any;
|
||||
sidemenu: any;
|
||||
lightTheme: any;
|
||||
|
||||
constructor() {
|
||||
this.pinned = store.getBool('grafana.sidemenu.pinned', false);
|
||||
@@ -41,7 +40,6 @@ export class ContextSrv {
|
||||
}
|
||||
|
||||
this.version = config.buildInfo.version;
|
||||
this.lightTheme = false;
|
||||
this.user = new User();
|
||||
this.isSignedIn = this.user.isSignedIn;
|
||||
this.isGrafanaAdmin = this.user.isGrafanaAdmin;
|
||||
|
||||
@@ -5,4 +5,5 @@ define([
|
||||
'./query_ctrl',
|
||||
'./panel_editor_tab',
|
||||
'./query_editor_row',
|
||||
'./metrics_ds_selector',
|
||||
], function () {});
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
///<reference path="../../headers/common.d.ts" />
|
||||
|
||||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
|
||||
var module = angular.module('grafana.directives');
|
||||
|
||||
var template = `
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">
|
||||
<i class="icon-gf icon-gf-datasource"></i>
|
||||
</label>
|
||||
<label class="gf-form-label">
|
||||
Panel data source
|
||||
</label>
|
||||
|
||||
<metric-segment segment="ctrl.dsSegment" style-mode="select"
|
||||
get-options="ctrl.getOptions()"
|
||||
on-change="ctrl.datasourceChanged()"></metric-segment>
|
||||
</div>
|
||||
|
||||
<div class="gf-form gf-form--offset-1">
|
||||
<button class="btn btn-inverse gf-form-btn" ng-click="ctrl.addDataQuery()" ng-hide="ctrl.current.meta.mixed">
|
||||
<i class="fa fa-plus"></i>
|
||||
Add query
|
||||
</button>
|
||||
|
||||
<div class="dropdown" ng-if="ctrl.current.meta.mixed">
|
||||
<button class="btn btn-inverse dropdown-toggle gf-form-btn" data-toggle="dropdown">
|
||||
Add Query <span class="fa fa-caret-down"></span>
|
||||
</button>
|
||||
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li ng-repeat="datasource in ctrl.datasources" role="menuitem" ng-hide="datasource.meta.builtIn">
|
||||
<a ng-click="ctrl.addDataQuery(datasource);">{{datasource.name}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
||||
export class MetricsDsSelectorCtrl {
|
||||
dsSegment: any;
|
||||
dsName: string;
|
||||
panelCtrl: any;
|
||||
datasources: any[];
|
||||
current: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private uiSegmentSrv, datasourceSrv) {
|
||||
this.datasources = datasourceSrv.getMetricSources();
|
||||
|
||||
var dsValue = this.panelCtrl.panel.datasource || null;
|
||||
|
||||
for (let ds of this.datasources) {
|
||||
if (ds.value === dsValue) {
|
||||
this.current = ds;
|
||||
}
|
||||
}
|
||||
|
||||
this.dsSegment = uiSegmentSrv.newSegment(this.current.name);
|
||||
}
|
||||
|
||||
getOptions() {
|
||||
return Promise.resolve(this.datasources.map(value => {
|
||||
return this.uiSegmentSrv.newSegment(value.name);
|
||||
}));
|
||||
}
|
||||
|
||||
datasourceChanged() {
|
||||
var ds = _.findWhere(this.datasources, {name: this.dsSegment.value});
|
||||
if (ds) {
|
||||
this.current = ds;
|
||||
this.panelCtrl.setDatasource(ds);
|
||||
}
|
||||
}
|
||||
|
||||
addDataQuery(datasource) {
|
||||
var target: any = {isNew: true};
|
||||
|
||||
if (datasource) {
|
||||
target.datasource = datasource.name;
|
||||
}
|
||||
|
||||
this.panelCtrl.panel.targets.push(target);
|
||||
}
|
||||
}
|
||||
|
||||
module.directive('metricsDsSelector', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: template,
|
||||
controller: MetricsDsSelectorCtrl,
|
||||
bindToController: true,
|
||||
controllerAs: 'ctrl',
|
||||
transclude: true,
|
||||
scope: {
|
||||
panelCtrl: "="
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -27,7 +27,6 @@ class MetricsPanelCtrl extends PanelCtrl {
|
||||
resolution: any;
|
||||
timeInfo: any;
|
||||
skipDataOnInit: boolean;
|
||||
datasources: any[];
|
||||
dataStream: any;
|
||||
dataSubscription: any;
|
||||
|
||||
@@ -52,7 +51,6 @@ class MetricsPanelCtrl extends PanelCtrl {
|
||||
private onInitMetricsPanelEditMode() {
|
||||
this.addEditorTab('Metrics', 'public/app/partials/metrics.html');
|
||||
this.addEditorTab('Time range', 'public/app/features/panel/partials/panelTime.html');
|
||||
this.datasources = this.datasourceSrv.getMetricSources();
|
||||
}
|
||||
|
||||
private onMetricsPanelRefresh() {
|
||||
@@ -249,16 +247,6 @@ class MetricsPanelCtrl extends PanelCtrl {
|
||||
this.datasource = null;
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
addDataQuery(datasource) {
|
||||
var target: any = {};
|
||||
|
||||
if (datasource) {
|
||||
target.datasource = datasource.name;
|
||||
}
|
||||
|
||||
this.panel.targets.push(target);
|
||||
}
|
||||
}
|
||||
|
||||
export {MetricsPanelCtrl};
|
||||
|
||||
@@ -1,4 +1,63 @@
|
||||
<div class="tight-form">
|
||||
|
||||
<div class="gf-form-query">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label gf-form-query-letter-cell">
|
||||
<a class="pointer" tabindex="1" ng-click="ctrl.toggleCollapse()">
|
||||
<span ng-class="{muted: !ctrl.canCollapse}" class="gf-form-query-letter-cell-carret">
|
||||
<i class="fa fa-caret-down" ng-hide="ctrl.collapsed"></i>
|
||||
<i class="fa fa-caret-right" ng-show="ctrl.collapsed"></i>
|
||||
</span>
|
||||
<span class="gf-form-query-letter-cell-letter">{{ctrl.target.refId}}</span>
|
||||
<em class="gf-form-query-letter-cell-ds" ng-show="ctrl.target.datasource">({{ctrl.target.datasource}})</em>
|
||||
</a>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-query-content gf-form-query-content--collapsed" ng-if="ctrl.collapsed">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label pointer gf-form-label--grow" ng-click="ctrl.toggleCollapse()">
|
||||
{{ctrl.collapsedText}}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-transclude class="gf-form-query-content" ng-if="!ctrl.collapsed">
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label dropdown">
|
||||
<a class="pointer dropdown-toggle" data-toggle="dropdown" tabindex="1">
|
||||
<i class="fa fa-bars"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu pull-right" role="menu">
|
||||
<li role="menuitem" ng-if="ctrl.hasTextEditMode">
|
||||
<a tabindex="1" ng-click="ctrl.toggleEditorMode()">Toggle Edit Mode</a>
|
||||
</li>
|
||||
<li role="menuitem">
|
||||
<a tabindex="1" ng-click="ctrl.duplicateQuery()">Duplicate</a>
|
||||
</li>
|
||||
<li role="menuitem">
|
||||
<a tabindex="1" ng-click="ctrl.moveQuery(-1)">Move up</a>
|
||||
</li>
|
||||
<li role="menuitem">
|
||||
<a tabindex="1" ng-click="ctrl.moveQuery(1)">Move down</a>
|
||||
</li>
|
||||
</ul>
|
||||
</label>
|
||||
<label class="gf-form-label">
|
||||
<a ng-click="ctrl.toggleHideQuery()" role="menuitem">
|
||||
<i class="fa fa-eye"></i>
|
||||
</a>
|
||||
</label>
|
||||
<label class="gf-form-label">
|
||||
<a class="pointer" tabindex="1" ng-click="ctrl.removeQuery(ctrl.target)">
|
||||
<i class="fa fa-trash"></i>
|
||||
</a>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tight-form" ng-if="false">
|
||||
<ul class="tight-form-list pull-right">
|
||||
<li ng-show="ctrl.error" class="tight-form-item">
|
||||
<a bs-tooltip="ctrl.error" style="color: rgb(229, 189, 28)" role="menuitem">
|
||||
|
||||
@@ -13,45 +13,11 @@ export class QueryCtrl {
|
||||
|
||||
constructor(public $scope, private $injector) {
|
||||
this.panel = this.panelCtrl.panel;
|
||||
|
||||
if (!this.target.refId) {
|
||||
this.target.refId = this.getNextQueryLetter();
|
||||
}
|
||||
}
|
||||
|
||||
getNextQueryLetter() {
|
||||
var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
|
||||
return _.find(letters, refId => {
|
||||
return _.every(this.panel.targets, function(other) {
|
||||
return other.refId !== refId;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
removeQuery() {
|
||||
this.panel.targets = _.without(this.panel.targets, this.target);
|
||||
this.panelCtrl.refresh();
|
||||
};
|
||||
|
||||
duplicateQuery() {
|
||||
var clone = angular.copy(this.target);
|
||||
clone.refId = this.getNextQueryLetter();
|
||||
this.panel.targets.push(clone);
|
||||
}
|
||||
|
||||
moveQuery(direction) {
|
||||
var index = _.indexOf(this.panel.targets, this.target);
|
||||
_.move(this.panel.targets, index, index + direction);
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.panelCtrl.refresh();
|
||||
}
|
||||
|
||||
toggleHideQuery() {
|
||||
this.target.hide = !this.target.hide;
|
||||
this.panelCtrl.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,115 @@
|
||||
///<reference path="../../headers/common.d.ts" />
|
||||
|
||||
import angular from 'angular';
|
||||
import $ from 'jquery';
|
||||
import _ from 'lodash';
|
||||
|
||||
var module = angular.module('grafana.directives');
|
||||
|
||||
export class QueryRowCtrl {
|
||||
collapsedText: string;
|
||||
canCollapse: boolean;
|
||||
getCollapsedText: any;
|
||||
target: any;
|
||||
queryCtrl: any;
|
||||
panelCtrl: any;
|
||||
panel: any;
|
||||
collapsed: any;
|
||||
|
||||
constructor() {
|
||||
this.panelCtrl = this.queryCtrl.panelCtrl;
|
||||
this.target = this.queryCtrl.target;
|
||||
this.panel = this.panelCtrl.panel;
|
||||
|
||||
if (!this.target.refId) {
|
||||
this.target.refId = this.getNextQueryLetter();
|
||||
}
|
||||
|
||||
this.toggleCollapse(true);
|
||||
if (this.target.isNew) {
|
||||
delete this.target.isNew;
|
||||
this.toggleCollapse(false);
|
||||
}
|
||||
}
|
||||
|
||||
toggleHideQuery() {
|
||||
this.target.hide = !this.target.hide;
|
||||
this.panelCtrl.refresh();
|
||||
}
|
||||
|
||||
getNextQueryLetter() {
|
||||
var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
|
||||
return _.find(letters, refId => {
|
||||
return _.every(this.panel.targets, function(other) {
|
||||
return other.refId !== refId;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
toggleCollapse(init) {
|
||||
if (!this.canCollapse) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.panelCtrl.__collapsedQueryCache) {
|
||||
this.panelCtrl.__collapsedQueryCache = {};
|
||||
}
|
||||
|
||||
if (init) {
|
||||
this.collapsed = this.panelCtrl.__collapsedQueryCache[this.target.refId] !== false;
|
||||
} else {
|
||||
this.collapsed = !this.collapsed;
|
||||
this.panelCtrl.__collapsedQueryCache[this.target.refId] = this.collapsed;
|
||||
}
|
||||
|
||||
try {
|
||||
this.collapsedText = this.queryCtrl.getCollapsedText();
|
||||
} catch (e) {
|
||||
var err = e.message || e.toString();
|
||||
this.collapsedText = 'Error: ' + err;
|
||||
}
|
||||
}
|
||||
|
||||
toggleEditorMode() {
|
||||
if (this.canCollapse && this.collapsed) {
|
||||
this.collapsed = false;
|
||||
}
|
||||
|
||||
this.queryCtrl.toggleEditorMode();
|
||||
}
|
||||
|
||||
removeQuery() {
|
||||
delete this.panelCtrl.__collapsedQueryCache[this.target.refId];
|
||||
this.panel.targets = _.without(this.panel.targets, this.target);
|
||||
this.panelCtrl.refresh();
|
||||
}
|
||||
|
||||
duplicateQuery() {
|
||||
var clone = angular.copy(this.target);
|
||||
clone.refId = this.getNextQueryLetter();
|
||||
this.panel.targets.push(clone);
|
||||
}
|
||||
|
||||
moveQuery(direction) {
|
||||
var index = _.indexOf(this.panel.targets, this.target);
|
||||
_.move(this.panel.targets, index, index + direction);
|
||||
}
|
||||
}
|
||||
|
||||
/** @ngInject **/
|
||||
function queryEditorRowDirective() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
controller: QueryRowCtrl,
|
||||
bindToController: true,
|
||||
controllerAs: "ctrl",
|
||||
templateUrl: 'public/app/features/panel/partials/query_editor_row.html',
|
||||
transclude: true,
|
||||
scope: {ctrl: "="},
|
||||
scope: {
|
||||
queryCtrl: "=",
|
||||
canCollapse: "=",
|
||||
hasTextEditMode: "=",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,56 +1,19 @@
|
||||
<div class="editor-row">
|
||||
|
||||
<div class="tight-form-container">
|
||||
<div ng-repeat="target in ctrl.panel.targets" ng-class="{'tight-form-disabled': target.hide}">
|
||||
<rebuild-on-change property="ctrl.panel.datasource || target.datasource" show-null="true">
|
||||
<plugin-component type="query-ctrl">
|
||||
</plugin-component>
|
||||
</rebuild-on-change>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin: 20px 0 0 0">
|
||||
<button class="btn btn-inverse" ng-click="ctrl.addDataQuery()" ng-hide="ctrl.datasource.meta.mixed">
|
||||
<i class="fa fa-plus"></i>
|
||||
Query
|
||||
</button>
|
||||
|
||||
<div class="dropdown" ng-if="ctrl.datasource.meta.mixed">
|
||||
<button class="btn btn-inverse dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="fa fa-plus"></i>
|
||||
Query <span class="caret"></span>
|
||||
</button>
|
||||
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li ng-repeat="datasource in ctrl.datasources" role="menuitem" ng-hide="datasource.meta.builtIn">
|
||||
<a ng-click="ctrl.addDataQuery(datasource);">{{datasource.name}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<rebuild-on-change property="ctrl.panel.datasource" show-null="true">
|
||||
<plugin-component type="query-options-ctrl">
|
||||
</plugin-component>
|
||||
</rebuild-on-change>
|
||||
|
||||
<div class="query-editor-rows gf-form-group">
|
||||
<div ng-repeat="target in ctrl.panel.targets" ng-class="{'gf-form-disabled': target.hide}">
|
||||
<rebuild-on-change property="ctrl.panel.datasource || target.datasource" show-null="true">
|
||||
<plugin-component type="query-ctrl">
|
||||
</plugin-component>
|
||||
</rebuild-on-change>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="editor-row">
|
||||
<metrics-ds-selector panel-ctrl="ctrl"></metrics-ds-selector>
|
||||
|
||||
<div class="pull-right dropdown" style="margin-right: 10px;">
|
||||
<button class="btn btn-inverse dropdown-toggle" data-toggle="dropdown" bs-tooltip="'Datasource'">
|
||||
<i class="fa fa-database"></i>
|
||||
{{ctrl.datasource.name}} <span class="caret"></span>
|
||||
</button>
|
||||
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li ng-repeat="datasource in ctrl.datasources" role="menuitem">
|
||||
<a ng-click="ctrl.setDatasource(datasource);">{{datasource.name}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
<div class="gf-form-group">
|
||||
<rebuild-on-change property="ctrl.panel.datasource" show-null="true">
|
||||
<plugin-component type="query-options-ctrl">
|
||||
</plugin-component>
|
||||
</rebuild-on-change>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<query-editor-row ctrl="ctrl">
|
||||
<query-editor-row query-ctrl="ctrl" can-collapse="false">
|
||||
<cloudwatch-query-parameter target="ctrl.target" datasource="ctrl.datasource" on-change="ctrl.refresh()"></cloudwatch-query-parameter>
|
||||
</query-editor-row>
|
||||
|
||||
<cloudwatch-query-parameter target="ctrl.target" datasource="ctrl.datasource" on-change="ctrl.refresh()"></cloudwatch-query-parameter>
|
||||
|
||||
@@ -1,58 +1,59 @@
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list" role="menu">
|
||||
<li class="tight-form-item query-keyword tight-form-align" style="width: 100px">
|
||||
Metric
|
||||
</li>
|
||||
<li>
|
||||
<metric-segment segment="regionSegment" get-options="getRegions()" on-change="regionChanged()"></metric-segment>
|
||||
</li>
|
||||
<li>
|
||||
<metric-segment segment="namespaceSegment" get-options="getNamespaces()" on-change="namespaceChanged()"></metric-segment>
|
||||
</li>
|
||||
<li>
|
||||
<metric-segment segment="metricSegment" get-options="getMetrics()" on-change="metricChanged()"></metric-segment>
|
||||
</li>
|
||||
<li class="tight-form-item query-keyword">
|
||||
Stats
|
||||
</li>
|
||||
<li ng-repeat="segment in statSegments">
|
||||
<metric-segment segment="segment" get-options="getStatSegments(segment, $index)" on-change="statSegmentChanged(segment, $index)"></metric-segment>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">Metric</label>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
<metric-segment segment="regionSegment" get-options="getRegions()" on-change="regionChanged()"></metric-segment>
|
||||
<metric-segment segment="namespaceSegment" get-options="getNamespaces()" on-change="namespaceChanged()"></metric-segment>
|
||||
<metric-segment segment="metricSegment" get-options="getMetrics()" on-change="metricChanged()"></metric-segment>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword">Stats</label>
|
||||
</div>
|
||||
|
||||
<div class="gf-form" ng-repeat="segment in statSegments">
|
||||
<metric-segment segment="segment" get-options="getStatSegments(segment, $index)" on-change="statSegmentChanged(segment, $index)"></metric-segment>
|
||||
</div>
|
||||
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list" role="menu">
|
||||
<li class="tight-form-item query-keyword tight-form-align" style="width: 100px">
|
||||
Dimensions
|
||||
</li>
|
||||
<li ng-repeat="segment in dimSegments">
|
||||
<metric-segment segment="segment" get-options="getDimSegments(segment, $index)" on-change="dimSegmentChanged(segment, $index)"></metric-segment>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">Dimensions</label>
|
||||
<metric-segment ng-repeat="segment in dimSegments" segment="segment" get-options="getDimSegments(segment, $index)" on-change="dimSegmentChanged(segment, $index)"></metric-segment>
|
||||
</div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list" role="menu">
|
||||
<li class="tight-form-item query-keyword tight-form-align" style="width: 100px">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">
|
||||
Period
|
||||
<tip>Interval between points in seconds</tip>
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="input-mini tight-form-input" ng-model="target.period" spellcheck='false' placeholder="auto" ng-model-onblur ng-change="onChange()" />
|
||||
</li>
|
||||
<li class="tight-form-item query-keyword">
|
||||
Alias
|
||||
<tip>{{metric}} {{stat}} {{namespace}} {{region}} {{DIMENSION_NAME}}</tip>
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="input-xlarge tight-form-input" ng-model="target.alias" spellcheck='false' ng-model-onblur ng-change="onChange()">
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
<info-popover mode="right-normal">Interval between points in seconds</info-popover>
|
||||
</label>
|
||||
<input type="text" class="gf-form-input" ng-model="target.period" spellcheck='false' placeholder="auto" ng-model-onblur ng-change="onChange()" />
|
||||
</div>
|
||||
<div class="gf-form max-width-30">
|
||||
<label class="gf-form-label query-keyword width-7">Alias</label>
|
||||
<input type="text" class="gf-form-input" ng-model="target.alias" spellcheck='false' ng-model-onblur ng-change="onChange()">
|
||||
<info-popover mode="right-absolute">
|
||||
Alias replacement variables:
|
||||
<ul ng-non-bindable>
|
||||
<li>{{metric}}</li>
|
||||
<li>{{stat}}</li>
|
||||
<li>{{namespace}}</li>
|
||||
<li>{{region}}</li>
|
||||
<li>{{DIMENSION_NAME}}</li>
|
||||
</ul>
|
||||
</info-popover>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,131 +1,89 @@
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item query-keyword tight-form-align" style="width: 75px;">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">
|
||||
<span ng-show="isFirst">Group by</span>
|
||||
<span ng-hide="isFirst">Then by</span>
|
||||
</li>
|
||||
<li>
|
||||
<metric-segment-model property="agg.type" options="bucketAggTypes" on-change="onTypeChanged()" custom="false" css-class="tight-form-item-large"></metric-segment-model>
|
||||
</li>
|
||||
<li ng-if="agg.field">
|
||||
<metric-segment-model property="agg.field" get-options="getFieldsInternal()" on-change="onChange()" css-class="tight-form-item-xxlarge"></metric-segment>
|
||||
</li>
|
||||
<li ng-if="!agg.field">
|
||||
<span class="tight-form-item tight-form-item-xxlarge"> </span>
|
||||
</li>
|
||||
<li class="tight-form-item last" ng-if="settingsLinkText">
|
||||
</label>
|
||||
|
||||
<metric-segment-model property="agg.type" options="bucketAggTypes" on-change="onTypeChanged()" custom="false" css-class="width-10"></metric-segment-model>
|
||||
<metric-segment-model ng-if="agg.field" property="agg.field" get-options="getFieldsInternal()" on-change="onChange()" css-class="width-12"></metric-segment>
|
||||
</div>
|
||||
|
||||
<div class="gf-form gf-form--grow">
|
||||
<label class="gf-form-label gf-form-label--grow">
|
||||
<a ng-click="toggleOptions()">
|
||||
<i class="fa fa-caret-down" ng-show="showOptions"></i>
|
||||
<i class="fa fa-caret-right" ng-hide="showOptions"></i>
|
||||
{{settingsLinkText}}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<ul class="tight-form-list pull-right">
|
||||
<li class="tight-form-item last" ng-if="isFirst">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label" ng-if="isFirst">
|
||||
<a class="pointer" ng-click="addBucketAgg()"><i class="fa fa-plus"></i></a>
|
||||
</li>
|
||||
<li class="tight-form-item last">
|
||||
</label>
|
||||
<label class="gf-form-label">
|
||||
<a class="pointer" ng-click="removeBucketAgg()"><i class="fa fa-minus"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tight-form" ng-if="showOptions">
|
||||
<div class="tight-form-inner-box" ng-if="agg.type === 'date_histogram'">
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 170px">
|
||||
Interval
|
||||
</li>
|
||||
<li>
|
||||
<metric-segment-model property="agg.settings.interval" get-options="getIntervalOptions()" on-change="onChangeInternal()" css-class="last" custom="true"></metric-segment-model>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
<div class="gf-form-group" ng-if="showOptions">
|
||||
<div ng-if="agg.type === 'date_histogram'">
|
||||
<div class="gf-form offset-width-7">
|
||||
<label class="gf-form-label width-10">Interval</label>
|
||||
<metric-segment-model property="agg.settings.interval" get-options="getIntervalOptions()" on-change="onChangeInternal()" css-class="width-12" custom="true"></metric-segment-model>
|
||||
</div>
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 170px">
|
||||
Min Doc Count
|
||||
</li>
|
||||
<li>
|
||||
<input type="number" class="tight-form-input" ng-model="agg.settings.min_doc_count" ng-blur="onChangeInternal()">
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div class="gf-form offset-width-7">
|
||||
<label class="gf-form-label width-10">Min Doc Count</label>
|
||||
<input type="number" class="gf-form-input max-width-12" ng-model="agg.settings.min_doc_count" ng-blur="onChangeInternal()">
|
||||
</div>
|
||||
<div class="tight-form last">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 170px">
|
||||
Trim edges points
|
||||
</li>
|
||||
<li>
|
||||
<input class="tight-form-input" type="number" ng-model="agg.settings.trimEdges" ng-change="onChangeInternal()">
|
||||
</li>
|
||||
<li class="tight-form-item last">
|
||||
<i class="fa fa-question-circle" bs-tooltip="'Trim the edges on the timeseries x datapoints'" data-placement="right"></i>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div class="gf-form offset-width-7">
|
||||
<label class="gf-form-label width-10">
|
||||
Trim edges
|
||||
<info-popover mode="right-normal">
|
||||
Trim the edges on the timeseries datapoints
|
||||
</info-popover>
|
||||
</label>
|
||||
<input class="gf-form-input max-width-12" type="number" ng-model="agg.settings.trimEdges" ng-change="onChangeInternal()">
|
||||
</div>
|
||||
</div>
|
||||
<div class="tight-form-inner-box" ng-if="agg.type === 'terms'">
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 60px">
|
||||
Order
|
||||
</li>
|
||||
<li>
|
||||
<metric-segment-model property="agg.settings.order" options="orderOptions" on-change="onChangeInternal()" css-class="last"></metric-segment-model>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div ng-if="agg.type === 'terms'">
|
||||
<div class="gf-form offset-width-7">
|
||||
<label class="gf-form-label">Order</label>
|
||||
<metric-segment-model property="agg.settings.order" options="orderOptions" on-change="onChangeInternal()" css-class="width-12"></metric-segment-model>
|
||||
</div>
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 60px">
|
||||
Size
|
||||
</li>
|
||||
<li>
|
||||
<metric-segment-model property="agg.settings.size" options="sizeOptions" on-change="onChangeInternal()" css-class="last"></metric-segment-model>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div class="gf-form offset-width-7">
|
||||
<label class="gf-form-label width-10">Size</label>
|
||||
<metric-segment-model property="agg.settings.size" options="sizeOptions" on-change="onChangeInternal()" css-class="width-12"></metric-segment-model>
|
||||
</div>
|
||||
<div class="tight-form last">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 60px">
|
||||
Order By
|
||||
</li>
|
||||
<li>
|
||||
<metric-segment-model property="agg.settings.orderBy" options="orderByOptions" on-change="onChangeInternal()" css-class="last"></metric-segment-model>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div class="gf-form offset-width-7">
|
||||
<label class="gf-form-label width-10">Order By</label>
|
||||
<metric-segment-model property="agg.settings.orderBy" options="orderByOptions" on-change="onChangeInternal()" css-class="width-12"></metric-segment-model>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tight-form-inner-box" ng-if="agg.type === 'filters'">
|
||||
<div class="tight-form" ng-repeat="filter in agg.settings.filters" ng-class="{last: $last}">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px">
|
||||
Query {{$index + 1}}
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="tight-form-input input-large" ng-model="filter.query" spellcheck='false' placeholder="Lucene query" ng-blur="onChangeInternal()">
|
||||
</li>
|
||||
<li class="tight-form-item last" ng-if="$first">
|
||||
|
||||
<div ng-if="agg.type === 'filters'">
|
||||
<div class="gf-form-inline" ng-repeat="filter in agg.settings.filters" ng-class="{last: $last}">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-item width-10">Query {{$index + 1}}</label>
|
||||
<input type="text" class="gf-form-input max-width-12" ng-model="filter.query" spellcheck='false' placeholder="Lucene query" ng-blur="onChangeInternal()">
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label" ng-if="$first">
|
||||
<a class="pointer" ng-click="addFiltersQuery()"><i class="fa fa-plus"></i></a>
|
||||
</li>
|
||||
<li class="tight-form-item last" ng-if="!$first">
|
||||
</label>
|
||||
<label class="gf-form-label" ng-if="!$first">
|
||||
<a class="pointer" ng-click="removeFiltersQuery(filter)"><i class="fa fa-minus"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,138 +1,82 @@
|
||||
<div class="tight-form" ng-class="{'tight-form-disabled': agg.hide}">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item query-keyword tight-form-align" style="width: 75px;">
|
||||
<div class="gf-form-inline" ng-class="{'gf-form-disabled': agg.hide}">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">
|
||||
Metric
|
||||
|
||||
<a ng-click="toggleShowMetric()" bs-tooltip="'Click to toggle show / hide metric'">
|
||||
<i class="fa fa-eye" ng-hide="agg.hide"></i>
|
||||
<i class="fa fa-eye-slash" ng-show="agg.hide"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<metric-segment-model property="agg.type" options="metricAggTypes" on-change="onTypeChange()" custom="false" css-class="tight-form-item-large"></metric-segment-model>
|
||||
</li>
|
||||
<li ng-if="aggDef.requiresField">
|
||||
<metric-segment-model property="agg.field" get-options="getFieldsInternal()" on-change="onChange()" css-class="tight-form-item-xxlarge"></metric-segment-model>
|
||||
</li>
|
||||
<li ng-if="aggDef.isPipelineAgg">
|
||||
<metric-segment-model property="agg.pipelineAgg" options="pipelineAggOptions" on-change="onChangeInternal()" custom="false" css-class="tight-form-item-xxlarge"></metric-segment-model>
|
||||
</li>
|
||||
<li class="tight-form-item last" ng-if="settingsLinkText">
|
||||
<a ng-click="toggleOptions()">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<metric-segment-model property="agg.type" options="metricAggTypes" on-change="onTypeChange()" custom="false" css-class="width-10"></metric-segment-model>
|
||||
<metric-segment-model ng-if="aggDef.requiresField" property="agg.field" get-options="getFieldsInternal()" on-change="onChange()" css-class="width-12"></metric-segment-model>
|
||||
<metric-segment-model ng-if="aggDef.isPipelineAgg" property="agg.pipelineAgg" options="pipelineAggOptions" on-change="onChangeInternal()" custom="false" css-class="width-12"></metric-segment-model>
|
||||
</div>
|
||||
|
||||
<div class="gf-form gf-form--grow">
|
||||
<label class="gf-form-label gf-form-label--grow">
|
||||
<a ng-click="toggleOptions()" ng-if="settingsLinkText">
|
||||
<i class="fa fa-caret-down" ng-show="showOptions"></i>
|
||||
<i class="fa fa-caret-right" ng-hide="showOptions"></i>
|
||||
{{settingsLinkText}}
|
||||
{{settingsLinkText}}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<ul class="tight-form-list pull-right">
|
||||
<li class="tight-form-item last" ng-if="isFirst">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label" ng-if="isFirst">
|
||||
<a class="pointer" ng-click="addMetricAgg()"><i class="fa fa-plus"></i></a>
|
||||
</li>
|
||||
<li class="tight-form-item last" ng-if="!isSingle">
|
||||
</label>
|
||||
<label class="gf-form-label" ng-if="!isSingle">
|
||||
<a class="pointer" ng-click="removeMetricAgg()"><i class="fa fa-minus"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tight-form" ng-if="showOptions">
|
||||
<div class="tight-form-inner-box tight-form-container">
|
||||
<div class="tight-form" ng-if="agg.type === 'derivative'">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 75px;">
|
||||
Unit
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="input-medium tight-form-input last" ng-model="agg.settings.unit" ng-blur="onChangeInternal()" spellcheck='false'>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="gf-form-group" ng-if="showOptions">
|
||||
|
||||
<div class="gf-form offset-width-7" ng-if="agg.type === 'derivative'">
|
||||
<label class="gf-form-label width-10">Unit</label>
|
||||
<input type="text" class="gf-form-input max-width-12" ng-model="agg.settings.unit" ng-blur="onChangeInternal()" spellcheck='false'>
|
||||
</div>
|
||||
|
||||
<div class="gf-form offset-width-7" ng-if="agg.type === 'moving_avg'">
|
||||
<label class="gf-form-label width-10">Window</label>
|
||||
<input type="number" class="gf-form-input max-width-12" ng-model="agg.settings.window" ng-blur="onChangeInternal()" spellcheck='false'>
|
||||
</div>
|
||||
|
||||
<div class="gf-form offset-width-7" ng-if="agg.type === 'moving_avg'">
|
||||
<label class="gf-form-label width-10">Model</label>
|
||||
<input type="text" class="gf-form-input max-width-12" ng-change="onChangeInternal()" ng-model="agg.settings.model" blur="onChange()" spellcheck='false'>
|
||||
</div>
|
||||
|
||||
<div class="gf-form offset-width-7" ng-if="agg.type === 'percentiles'">
|
||||
<label class="gf-form-label width-10">Percentiles</label>
|
||||
<input type="text" class="gf-form-input max-width-12" ng-model="agg.settings.percents" array-join ng-blur="onChange()"></input>
|
||||
</div>
|
||||
|
||||
<div class="tight-form" ng-if="agg.type === 'moving_avg'">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 75px;">
|
||||
Window
|
||||
</li>
|
||||
<li>
|
||||
<input type="number" class="input-medium tight-form-input last" ng-model="agg.settings.window" ng-blur="onChangeInternal()" spellcheck='false'>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form" ng-if="agg.type === 'moving_avg'">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 75px;">
|
||||
Model
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="input-medium tight-form-input last" ng-change="onChangeInternal()" ng-model="agg.settings.model" blur="onChange()" spellcheck='false'>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form last" ng-if="agg.type === 'percentiles'">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item">
|
||||
Percentiles
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="input-xlarge tight-form-input last" ng-model="agg.settings.percents" array-join ng-blur="onChange()"></input>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div ng-if="agg.type === 'extended_stats'">
|
||||
<div class="tight-form" ng-repeat="stat in extendedStats">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px">
|
||||
{{stat.text}}
|
||||
</li>
|
||||
<li class="tight-form-item last">
|
||||
<editor-checkbox text="" model="agg.meta.{{stat.value}}" change="onChange()"></editor-checkbox>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tight-form" ng-if="agg.type === 'extended_stats'">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px">
|
||||
Sigma
|
||||
</li>
|
||||
<li>
|
||||
<input type="number" class="input-mini tight-form-input last" placeholder="3" ng-model="agg.settings.sigma" ng-blur="onChange()"></input>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div ng-if="agg.type === 'extended_stats'">
|
||||
<gf-form-switch ng-repeat="stat in extendedStats" class="gf-form offset-width-7" label="{{stat.text}}" label-class="width-10" checked="agg.meta[stat.value]" on-change="onChangeInternal()"></gf-form-switch>
|
||||
|
||||
<div class="tight-form" ng-if="aggDef.supportsInlineScript">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px;">
|
||||
Script
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="input-medium tight-form-input last" empty-to-null ng-model="agg.inlineScript" ng-blur="onChangeInternal()" spellcheck='false' placeholder="_value * 1">
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
<div class="gf-form offset-width-7">
|
||||
<label class="gf-form-label width-10">Sigma</label>
|
||||
<input type="number" class="gf-form-input max-width-12" placeholder="3" ng-model="agg.settings.sigma" ng-blur="onChange()"></input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tight-form" ng-if="aggDef.supportsMissing">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px;">
|
||||
Missing
|
||||
<tip>The missing parameter defines how documents that are missing a value should be treated. By default they will be ignored but it is also possible to treat them as if they had a value</tip>
|
||||
</li>
|
||||
<li>
|
||||
<input type="number" class="input-medium tight-form-input last" empty-to-null ng-model="agg.settings.missing" ng-blur="onChangeInternal()" spellcheck='false'>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="gf-form offset-width-7" ng-if="aggDef.supportsInlineScript">
|
||||
<label class="gf-form-label width-10">Script</label>
|
||||
<input type="text" class="gf-form-input max-width-12" empty-to-null ng-model="agg.inlineScript" ng-blur="onChangeInternal()" spellcheck='false' placeholder="_value * 1">
|
||||
</div>
|
||||
|
||||
<div class="gf-form offset-width-7" ng-if="aggDef.supportsMissing">
|
||||
<label class="gf-form-label width-10">
|
||||
Missing
|
||||
<tip>The missing parameter defines how documents that are missing a value should be treated. By default they will be ignored but it is also possible to treat them as if they had a value</tip>
|
||||
</label>
|
||||
<input type="number" class="gf-form-input max-width-12" empty-to-null ng-model="agg.settings.missing" ng-blur="onChangeInternal()" spellcheck='false'>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,32 +1,31 @@
|
||||
<query-editor-row ctrl="ctrl">
|
||||
<li class="tight-form-item query-keyword" style="width: 75px">
|
||||
Query
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="tight-form-input" style="width: 345px;" ng-model="ctrl.target.query" spellcheck='false' placeholder="Lucene query" ng-blur="ctrl.refresh()">
|
||||
</li>
|
||||
<li class="tight-form-item query-keyword">
|
||||
Alias
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="tight-form-input" style="width: 200px;" ng-model="ctrl.target.alias" spellcheck='false' placeholder="alias patterns (empty = auto)" ng-blur="ctrl.refresh()">
|
||||
</li>
|
||||
<query-editor-row query-ctrl="ctrl" can-collapse="true">
|
||||
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form gf-form--grow">
|
||||
<label class="gf-form-label query-keyword width-7">Query</label>
|
||||
<input type="text" class="gf-form-input" ng-model="ctrl.target.query" spellcheck='false' placeholder="Lucene query" ng-blur="ctrl.refresh()">
|
||||
</div>
|
||||
<div class="gf-form max-width-15">
|
||||
<label class="gf-form-label query-keyword">Alias</label>
|
||||
<input type="text" class="gf-form-input" ng-model="ctrl.target.alias" spellcheck='false' placeholder="alias patterns" ng-blur="ctrl.refresh()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="agg in ctrl.target.metrics">
|
||||
<elastic-metric-agg
|
||||
target="ctrl.target" index="$index"
|
||||
get-fields="ctrl.getFields($fieldType)"
|
||||
on-change="ctrl.queryUpdated()"
|
||||
es-version="ctrl.esVersion">
|
||||
</elastic-metric-agg>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="agg in ctrl.target.bucketAggs">
|
||||
<elastic-bucket-agg
|
||||
target="ctrl.target" index="$index"
|
||||
get-fields="ctrl.getFields($fieldType)"
|
||||
on-change="ctrl.queryUpdated()">
|
||||
</elastic-bucket-agg>
|
||||
</div>
|
||||
|
||||
</query-editor-row>
|
||||
|
||||
<div ng-repeat="agg in ctrl.target.metrics">
|
||||
<elastic-metric-agg
|
||||
target="ctrl.target" index="$index"
|
||||
get-fields="ctrl.getFields($fieldType)"
|
||||
on-change="ctrl.queryUpdated()"
|
||||
es-version="ctrl.esVersion">
|
||||
</elastic-metric-agg>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="agg in ctrl.target.bucketAggs">
|
||||
<elastic-bucket-agg
|
||||
target="ctrl.target" index="$index"
|
||||
get-fields="ctrl.getFields($fieldType)"
|
||||
on-change="ctrl.queryUpdated()">
|
||||
</elastic-bucket-agg>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import './metric_agg';
|
||||
|
||||
import angular from 'angular';
|
||||
import _ from 'lodash';
|
||||
import queryDef from './query_def';
|
||||
import {QueryCtrl} from 'app/plugins/sdk';
|
||||
|
||||
export class ElasticQueryCtrl extends QueryCtrl {
|
||||
@@ -38,6 +39,48 @@ export class ElasticQueryCtrl extends QueryCtrl {
|
||||
this.$rootScope.appEvent('elastic-query-updated');
|
||||
}
|
||||
|
||||
getCollapsedText() {
|
||||
var metricAggs = this.target.metrics;
|
||||
var bucketAggs = this.target.bucketAggs;
|
||||
var metricAggTypes = queryDef.getMetricAggTypes(this.esVersion);
|
||||
var bucketAggTypes = queryDef.bucketAggTypes;
|
||||
var text = '';
|
||||
|
||||
if (this.target.query) {
|
||||
text += 'Query: ' + this.target.query + ', ';
|
||||
}
|
||||
|
||||
text += 'Metrics: ';
|
||||
|
||||
_.each(metricAggs, (metric, index) => {
|
||||
var aggDef = _.findWhere(metricAggTypes, {value: metric.type});
|
||||
text += aggDef.text + '(';
|
||||
if (aggDef.requiresField) {
|
||||
text += metric.field;
|
||||
}
|
||||
text += '), ';
|
||||
});
|
||||
|
||||
_.each(bucketAggs, (bucketAgg, index) => {
|
||||
if (index === 0) {
|
||||
text += ' Group by: ';
|
||||
}
|
||||
|
||||
var aggDef = _.findWhere(bucketAggTypes, {value: bucketAgg.type});
|
||||
text += aggDef.text + '(';
|
||||
if (aggDef.requiresField) {
|
||||
text += bucketAgg.field;
|
||||
}
|
||||
text += '), ';
|
||||
});
|
||||
|
||||
if (this.target.alias) {
|
||||
text += 'Alias: ' + this.target.alias;
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
handleQueryError(err) {
|
||||
this.error = err.message || 'Failed to issue metric query';
|
||||
return [];
|
||||
|
||||
@@ -20,9 +20,9 @@ function (_) {
|
||||
],
|
||||
|
||||
bucketAggTypes: [
|
||||
{text: "Terms", value: 'terms' },
|
||||
{text: "Terms", value: 'terms', requiresField: true},
|
||||
{text: "Filters", value: 'filters' },
|
||||
{text: "Date Histogram", value: 'date_histogram' },
|
||||
{text: "Date Histogram", value: 'date_histogram', requiresField: true},
|
||||
],
|
||||
|
||||
orderByOptions: [
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<query-editor-row ctrl="ctrl">
|
||||
<li class="tight-form-item">
|
||||
Test metric (fake data source)
|
||||
</li>
|
||||
<query-editor-row query-ctrl="ctrl" can-collapse="false">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">Test metric (fake data source)</label>
|
||||
</div>
|
||||
</div>
|
||||
</query-editor-row>
|
||||
|
||||
@@ -11,10 +11,10 @@ function (angular, _, $, gfunc) {
|
||||
.module('grafana.directives')
|
||||
.directive('graphiteAddFunc', function($compile) {
|
||||
var inputTemplate = '<input type="text"'+
|
||||
' class="tight-form-input input-medium tight-form-input"' +
|
||||
' class="gf-form-input"' +
|
||||
' spellcheck="false" style="display:none"></input>';
|
||||
|
||||
var buttonTemplate = '<a class="tight-form-item tight-form-func dropdown-toggle"' +
|
||||
var buttonTemplate = '<a class="gf-form-label query-part dropdown-toggle"' +
|
||||
' tabindex="1" gf-dropdown="functionMenu" data-toggle="dropdown">' +
|
||||
'<i class="fa fa-plus"></i></a>';
|
||||
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
<query-editor-row ctrl="ctrl">
|
||||
<query-editor-row query-ctrl="ctrl" has-text-edit-mode="true">
|
||||
|
||||
<li class="tight-form-flex-wrapper" ng-show="ctrl.target.textEditor">
|
||||
<input type="text" class="tight-form-clear-input" style="width: 100%;" ng-model="ctrl.target.target" give-focus="ctrl.target.textEditor" spellcheck='false' ng-model-onblur ng-change="ctrl.targetTextChanged()"></input>
|
||||
</li>
|
||||
<div class="gf-form" ng-show="ctrl.target.textEditor">
|
||||
<input type="text" class="gf-form-input" ng-model="ctrl.target.target" spellcheck="false" ng-blur="ctrl.refresh()"></input>
|
||||
</div>
|
||||
|
||||
<li ng-hide-start="ctrl.target.textEditor"></li>
|
||||
<div ng-hide="ctrl.target.textEditor">
|
||||
<div class="gf-form-inline">
|
||||
<div ng-repeat="segment in ctrl.segments" role="menuitem" class="gf-form">
|
||||
<metric-segment segment="segment" get-options="ctrl.getAltSegments($index)" on-change="ctrl.segmentValueChanged(segment, $index)"></metric-segment>
|
||||
</div>
|
||||
|
||||
<li ng-repeat="segment in ctrl.segments" role="menuitem">
|
||||
<metric-segment segment="segment" get-options="ctrl.getAltSegments($index)" on-change="ctrl.segmentValueChanged(segment, $index)"></metric-segment>
|
||||
</li>
|
||||
<li ng-repeat="func in ctrl.functions">
|
||||
<span graphite-func-editor class="tight-form-item tight-form-func">
|
||||
</span>
|
||||
</li>
|
||||
<li class="dropdown" graphite-add-func>
|
||||
</li>
|
||||
<div ng-repeat="func in ctrl.functions" class="gf-form">
|
||||
<span graphite-func-editor class="gf-form-label query-part"></span>
|
||||
</div>
|
||||
|
||||
<li ng-hide-end></li>
|
||||
<div class="gf-form dropdown">
|
||||
<span graphite-add-func></span>
|
||||
</div>
|
||||
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</query-editor-row>
|
||||
|
||||
@@ -164,7 +164,7 @@ export default class InfluxQuery {
|
||||
|
||||
getMeasurementAndPolicy(interpolate) {
|
||||
var policy = this.target.policy;
|
||||
var measurement = this.target.measurement;
|
||||
var measurement = this.target.measurement || 'measurement';
|
||||
|
||||
if (!measurement.match('^/.*/')) {
|
||||
measurement = '"' + measurement+ '"';
|
||||
@@ -192,10 +192,6 @@ export default class InfluxQuery {
|
||||
}
|
||||
}
|
||||
|
||||
if (!target.measurement) {
|
||||
throw {message: "Metric measurement is missing"};
|
||||
}
|
||||
|
||||
var query = 'SELECT ';
|
||||
var i, y;
|
||||
for (i = 0; i < this.selectModels.length; i++) {
|
||||
|
||||
@@ -1,73 +1,96 @@
|
||||
<query-editor-row ctrl="ctrl">
|
||||
<ul class="tight-form-list" ng-hide="ctrl.target.rawQuery">
|
||||
<li class="tight-form-item query-keyword" style="width: 75px">
|
||||
FROM
|
||||
</li>
|
||||
<li>
|
||||
<query-editor-row query-ctrl="ctrl" can-collapse="true" has-text-edit-mode="true">
|
||||
|
||||
<div class="gf-form" ng-if="ctrl.target.rawQuery">
|
||||
<input type="text" class="gf-form-input" ng-model="ctrl.target.query" spellcheck="false" ng-blur="ctrl.refresh()"></input>
|
||||
</div>
|
||||
|
||||
<div ng-if="!ctrl.target.rawQuery">
|
||||
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">FROM</label>
|
||||
|
||||
<metric-segment segment="ctrl.policySegment" get-options="ctrl.getPolicySegments()" on-change="ctrl.policyChanged()"></metric-segment>
|
||||
</li>
|
||||
<li>
|
||||
<metric-segment segment="ctrl.measurementSegment" get-options="ctrl.getMeasurements()" on-change="ctrl.measurementChanged()"></metric-segment>
|
||||
</li>
|
||||
<li class="tight-form-item query-keyword" style="padding-left: 15px; padding-right: 15px;">
|
||||
WHERE
|
||||
</li>
|
||||
<li ng-repeat="segment in ctrl.tagSegments">
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword">WHERE</label>
|
||||
</div>
|
||||
|
||||
<div class="gf-form" ng-repeat="segment in ctrl.tagSegments">
|
||||
<metric-segment segment="segment" get-options="ctrl.getTagsOrValues(segment, $index)" on-change="ctrl.tagSegmentUpdated(segment, $index)"></metric-segment>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="tight-form-flex-wrapper" ng-show="ctrl.target.rawQuery">
|
||||
<input type="text" class="tight-form-clear-input" ng-model="ctrl.target.query" spellcheck="false" style="width: 100%;" ng-blur="ctrl.refresh()"></input>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-inline" ng-repeat="selectParts in ctrl.queryModel.selectModels">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">
|
||||
<span ng-show="$index === 0">SELECT</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="gf-form" ng-repeat="part in selectParts">
|
||||
<influx-query-part-editor
|
||||
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)">
|
||||
</influx-query-part-editor>
|
||||
</div>
|
||||
|
||||
<div class="gf-form">
|
||||
<label class="dropdown"
|
||||
dropdown-typeahead="ctrl.selectMenu"
|
||||
dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item, $subItem)">
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">
|
||||
<span>GROUP BY</span>
|
||||
</label>
|
||||
|
||||
<influx-query-part-editor
|
||||
ng-repeat="part in ctrl.queryModel.groupByParts"
|
||||
part="part"
|
||||
class="gf-form-label query-part"
|
||||
remove-action="ctrl.removeGroupByPart(part, $index)" part-updated="ctrl.refresh();" get-options="ctrl.getPartOptions(part)">
|
||||
</influx-query-part-editor>
|
||||
</div>
|
||||
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form max-width-30">
|
||||
<label class="gf-form-label query-keyword width-7">ALIAS BY</label>
|
||||
<input type="text" class="gf-form-input" ng-model="ctrl.target.alias" spellcheck='false' placeholder="Naming pattern" ng-blur="ctrl.refresh()">
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">Format as</label>
|
||||
<div class="gf-form-select-wrapper">
|
||||
<select class="gf-form-input gf-size-auto" ng-model="ctrl.target.resultFormat" ng-options="f.value as f.text for f in ctrl.resultFormats" ng-change="ctrl.refresh()"></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</query-editor-row>
|
||||
|
||||
<div ng-hide="ctrl.target.rawQuery">
|
||||
<div class="tight-form" ng-repeat="selectParts in ctrl.queryModel.selectModels">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item query-keyword tight-form-align" style="width: 75px;">
|
||||
<span ng-show="$index === 0">SELECT</span>
|
||||
</li>
|
||||
<li ng-repeat="part in selectParts">
|
||||
<influx-query-part-editor part="part" class="tight-form-item tight-form-func" remove-action="ctrl.removeSelectPart(selectParts, part)" part-updated="ctrl.selectPartUpdated(selectParts, part)" get-options="ctrl.getPartOptions(part)"></influx-query-part-editor>
|
||||
</li>
|
||||
<li class="dropdown" dropdown-typeahead="ctrl.selectMenu" dropdown-typeahead-on-select="ctrl.addSelectPart(selectParts, $item, $subItem)">
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item query-keyword tight-form-align" style="width: 75px;">
|
||||
<span>GROUP BY</span>
|
||||
</li>
|
||||
<li ng-repeat="part in ctrl.queryModel.groupByParts">
|
||||
<influx-query-part-editor part="part" class="tight-form-item tight-form-func" remove-action="ctrl.removeGroupByPart(part, $index)" part-updated="ctrl.refresh();" get-options="ctrl.getPartOptions(part)"></influx-query-part-editor>
|
||||
</li>
|
||||
<li>
|
||||
<metric-segment segment="ctrl.groupBySegment" get-options="ctrl.getGroupByOptions()" on-change="ctrl.groupByAction(part, $index)"></metric-segment>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item query-keyword tight-form-align" style="width: 75px;">
|
||||
ALIAS BY
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="tight-form-clear-input input-xlarge" ng-model="ctrl.target.alias" spellcheck='false' placeholder="Naming pattern" ng-blur="ctrl.refresh()">
|
||||
</li>
|
||||
<li class="tight-form-item">
|
||||
Format as
|
||||
</li>
|
||||
<li>
|
||||
<select class="input-small tight-form-input" style="width: 104px" ng-model="ctrl.target.resultFormat" ng-options="f.value as f.text for f in ctrl.resultFormats" ng-change="ctrl.refresh()"></select>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
</section>
|
||||
|
||||
<div class="editor-row">
|
||||
<div class="pull-left" style="margin-top: 30px;">
|
||||
<div class="pull-left">
|
||||
|
||||
<div class="grafana-info-box span6" ng-if="ctrl.panelCtrl.editorHelpIndex === 1">
|
||||
<h5>Alias patterns</h5>
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
<span class="pointer fa fa-remove" ng-click="removeActionInternal()" ></span>
|
||||
</div>
|
||||
|
||||
<a ng-click="toggleControls()">{{part.def.type}}</a><span>(</span><span class="query-part-parameters"></span><span>)</span>
|
||||
<a ng-click="toggleControls()" class="query-part-name">{{part.def.type}}</a><span>(</span><span class="query-part-parameters"></span><span>)</span>
|
||||
|
||||
@@ -23,6 +23,7 @@ export class InfluxQueryCtrl extends QueryCtrl {
|
||||
measurementSegment: any;
|
||||
removeTagFilterSegment: any;
|
||||
|
||||
|
||||
/** @ngInject **/
|
||||
constructor($scope, $injector, private templateSrv, private $q, private uiSegmentSrv) {
|
||||
super($scope, $injector);
|
||||
@@ -154,7 +155,11 @@ export class InfluxQueryCtrl extends QueryCtrl {
|
||||
}
|
||||
|
||||
toggleEditorMode() {
|
||||
this.target.query = this.queryModel.render(false);
|
||||
try {
|
||||
this.target.query = this.queryModel.render(false);
|
||||
} catch (err) {
|
||||
console.log('query render error');
|
||||
}
|
||||
this.target.rawQuery = !this.target.rawQuery;
|
||||
}
|
||||
|
||||
@@ -316,5 +321,9 @@ export class InfluxQueryCtrl extends QueryCtrl {
|
||||
return '=';
|
||||
}
|
||||
}
|
||||
|
||||
getCollapsedText() {
|
||||
return this.queryModel.render(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,223 +1,253 @@
|
||||
<query-editor-row ctrl="ctrl">
|
||||
<li class="tight-form-item query-keyword" style="width: 100px">
|
||||
Metric
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="input-large tight-form-input" ng-model="ctrl.target.metric"
|
||||
spellcheck='false' bs-typeahead="ctrl.suggestMetrics" placeholder="metric name" data-min-length=0 data-items=100
|
||||
ng-blur="ctrl.targetBlur()">
|
||||
</input>
|
||||
<a bs-tooltip="ctrl.errors.metric" style="color: rgb(229, 189, 28)" ng-show="ctrl.errors.metric">
|
||||
<i class="fa fa-warning"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="tight-form-item query-keyword">
|
||||
Aggregator
|
||||
</li>
|
||||
<li>
|
||||
<select ng-model="ctrl.target.aggregator" class="tight-form-input input-small"
|
||||
ng-options="agg for agg in ctrl.aggregators"
|
||||
ng-change="ctrl.targetBlur()">
|
||||
</select>
|
||||
<a bs-tooltip="ctrl.errors.aggregator" style="color: rgb(229, 189, 28)" ng-show="ctrl.errors.aggregator">
|
||||
<i class="fa fa-warning"></i>
|
||||
</a>
|
||||
</li>
|
||||
<query-editor-row query-ctrl="ctrl" can-collapse="false">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form max-width-25">
|
||||
<label class="gf-form-label query-keyword width-8">
|
||||
Metric
|
||||
<label class="gf-form-label" bs-tooltip="ctrl.errors.metric" style="color: rgb(229, 189, 28)" ng-show="ctrl.errors.metric">
|
||||
<i class="fa fa-warning"></i>
|
||||
</label>
|
||||
</label>
|
||||
<input type="text" class="gf-form-input" ng-model="ctrl.target.metric"
|
||||
spellcheck='false' bs-typeahead="ctrl.suggestMetrics" placeholder="metric name" data-min-length=0 data-items=100
|
||||
ng-blur="ctrl.targetBlur()">
|
||||
</input>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword">
|
||||
Aggregator
|
||||
<a bs-tooltip="ctrl.errors.aggregator" style="color: rgb(229, 189, 28)" ng-show="ctrl.errors.aggregator">
|
||||
<i class="fa fa-warning"></i>
|
||||
</a>
|
||||
</label>
|
||||
<div class="gf-form-select-wrapper max-width-15">
|
||||
<select ng-model="ctrl.target.aggregator" class="gf-form-input"
|
||||
ng-options="agg for agg in ctrl.aggregators"
|
||||
ng-change="ctrl.targetBlur()">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gf-form max-width-20">
|
||||
<label class="gf-form-label query-keyword width-6">
|
||||
Alias:
|
||||
<info-popover mode="right-normal">
|
||||
Use patterns like $tag_tagname to replace part of the alias for a tag value
|
||||
</info-popover>
|
||||
</label>
|
||||
<input type="text" class="gf-form-input"
|
||||
ng-model="ctrl.target.alias"
|
||||
spellcheck='false'
|
||||
placeholder="series alias"
|
||||
data-min-length=0 data-items=100
|
||||
ng-blur="ctrl.targetBlur()"></input>
|
||||
</div>
|
||||
|
||||
<li class="tight-form-item query-keyword">
|
||||
Alias:
|
||||
<tip>Use patterns like $tag_tagname to replace part of the alias for a tag value</tip>
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="tight-form-input input-large"
|
||||
ng-model="ctrl.target.alias"
|
||||
spellcheck='false'
|
||||
placeholder="series alias"
|
||||
data-min-length=0 data-items=100
|
||||
ng-blur="ctrl.targetBlur()"></input>
|
||||
</li>
|
||||
</query-editor-row>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list" role="menu">
|
||||
<li class="tight-form-item tight-form-align query-keyword" style="width: 100px">
|
||||
Down sample
|
||||
</li>
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form max-width-25">
|
||||
<label class="gf-form-label query-keyword width-8">Down sample</label>
|
||||
<input type="text" class="gf-form-input"
|
||||
ng-model="ctrl.target.downsampleInterval"
|
||||
ng-model-onblur
|
||||
ng-change="ctrl.targetBlur()"
|
||||
placeholder="interval"></input>
|
||||
<info-popover mode="right-absolute">
|
||||
blank for auto, or for example <code>1m</code>
|
||||
</info-popover>
|
||||
</div>
|
||||
|
||||
<li>
|
||||
<input type="text" class="input-large tight-form-input"
|
||||
ng-model="ctrl.target.downsampleInterval"
|
||||
ng-model-onblur
|
||||
ng-change="ctrl.targetBlur()"
|
||||
placeholder="interval (empty = auto)"></input>
|
||||
</li>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword">Aggregator</label>
|
||||
<div class="gf-form-select-wrapper">
|
||||
<select ng-model="ctrl.target.downsampleAggregator" class="gf-form-input"
|
||||
ng-options="agg for agg in ctrl.aggregators"
|
||||
ng-change="ctrl.targetBlur()">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<li class="tight-form-item query-keyword">
|
||||
Aggregator
|
||||
</li>
|
||||
<div class="gf-form" ng-if="ctrl.tsdbVersion == 2">
|
||||
<label class="gf-form-label query-keyword width-6">Fill</label>
|
||||
<div class="gf-form-select-wrapper">
|
||||
<select ng-model="ctrl.target.downsampleFillPolicy" class="gf-form-input"
|
||||
ng-options="agg for agg in ctrl.fillPolicies"
|
||||
ng-change="ctrl.targetBlur()">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<li>
|
||||
<select ng-model="ctrl.target.downsampleAggregator" class="tight-form-input input-small"
|
||||
ng-options="agg for agg in ctrl.aggregators"
|
||||
ng-change="ctrl.targetBlur()">
|
||||
</select>
|
||||
</li>
|
||||
<gf-form-switch class="gf-form"
|
||||
label="Disable downsampling"
|
||||
checked="ctrl.target.disableDownsampling"
|
||||
on-change="ctrl.targetBlur()">
|
||||
</gf-form-switch>
|
||||
|
||||
<li class="tight-form-item query-keyword" style="width: 59px" ng-if="ctrl.tsdbVersion == 2">
|
||||
Fill
|
||||
</li>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<li ng-if="ctrl.tsdbVersion == 2">
|
||||
<select ng-model="ctrl.target.downsampleFillPolicy" class="tight-form-input input-small"
|
||||
ng-options="agg for agg in ctrl.fillPolicies"
|
||||
ng-change="ctrl.targetBlur()">
|
||||
</select>
|
||||
</li>
|
||||
<div class="gf-form-inline" ng-if="ctrl.tsdbVersion == 2">
|
||||
<div class="gf-form">
|
||||
|
||||
<li class="tight-form-item query-keyword">
|
||||
Disable downsampling <editor-checkbox text="" model="ctrl.target.disableDownsampling" change="ctrl.targetBlur()"></editor-checkbox>
|
||||
</li>
|
||||
<label class="gf-form-label query-keyword width-8">
|
||||
Filters
|
||||
<info-popover mode="right-normal">
|
||||
Filters does not work with tags, either of the two will work but not both.
|
||||
</info-popover>
|
||||
</label>
|
||||
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div ng-repeat="fil in ctrl.target.filters track by $index" class="gf-form-label">
|
||||
{{fil.tagk}} = {{fil.type}}({{fil.filter}}) , groupBy = {{fil.groupBy}}
|
||||
<a ng-click="ctrl.editFilter(fil, $index)">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
<a ng-click="ctrl.removeFilter($index)">
|
||||
<i class="fa fa-remove"></i>
|
||||
</a>
|
||||
</div>
|
||||
<label class="gf-form-label query-keyword" ng-hide="ctrl.addFilterMode">
|
||||
<a ng-click="ctrl.addFilter()">
|
||||
<i class="fa fa-plus"></i>
|
||||
</a>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="tight-form" ng-if="ctrl.tsdbVersion == 2">
|
||||
<ul class="tight-form-list" role="menu">
|
||||
<li class="tight-form-item tight-form-align query-keyword" style="width: 100px">
|
||||
Filters
|
||||
<tip ng-if="ctrl.tsdbVersion == 2">Filters does not work with tags, either of the two will work but not both.</tip>
|
||||
</li>
|
||||
<li ng-repeat="fil in ctrl.target.filters track by $index" class="tight-form-item">
|
||||
{{fil.tagk}} = {{fil.type}}({{fil.filter}}) , groupBy = {{fil.groupBy}}
|
||||
<a ng-click="ctrl.editFilter(fil, $index)">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
<a ng-click="ctrl.removeFilter($index)">
|
||||
<i class="fa fa-remove"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="tight-form-item query-keyword" ng-hide="ctrl.addFilterMode">
|
||||
<a ng-click="ctrl.addFilter()">
|
||||
<i class="fa fa-plus"></i>
|
||||
</a>
|
||||
</li>
|
||||
<div class="gf-form-inline" ng-show="ctrl.addFilterMode">
|
||||
<div class="gf-form">
|
||||
<input type="text" class="gf-form-input" spellcheck='false'
|
||||
bs-typeahead="ctrl.suggestTagKeys" data-min-length=0 data-items=100
|
||||
ng-model="ctrl.target.currentFilterKey" placeholder="key">
|
||||
</input>
|
||||
</div>
|
||||
|
||||
<li class="query-keyword" ng-show="ctrl.addFilterMode">
|
||||
<input type="text" class="input-small tight-form-input" spellcheck='false'
|
||||
bs-typeahead="ctrl.suggestTagKeys" data-min-length=0 data-items=100
|
||||
ng-model="ctrl.target.currentFilterKey" placeholder="key"></input>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">Type</label>
|
||||
<div class="gf-form-select-wrapper">
|
||||
<select ng-model="ctrl.target.currentFilterType" class="gf-form-input" ng-options="filType for filType in ctrl.filterTypes">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Type <select ng-model="ctrl.target.currentFilterType"
|
||||
class="tight-form-input input-small"
|
||||
ng-options="filType for filType in ctrl.filterTypes">
|
||||
</select>
|
||||
|
||||
<input type="text" class="input-small tight-form-input"
|
||||
spellcheck='false' bs-typeahead="ctrl.suggestTagValues"
|
||||
data-min-length=0 data-items=100 ng-model="ctrl.target.currentFilterValue" placeholder="filter">
|
||||
</input>
|
||||
<div class="gf-form">
|
||||
<input type="text" class="gf-form-input" spellcheck='false' bs-typeahead="ctrl.suggestTagValues" data-min-length=0 data-items=100 ng-model="ctrl.target.currentFilterValue" placeholder="filter">
|
||||
</input>
|
||||
</div>
|
||||
|
||||
groupBy <editor-checkbox text="" model="ctrl.target.currentFilterGroupBy"></editor-checkbox>
|
||||
<gf-form-switch class="gf-form" label="Group by" checked="ctrl.target.currentFilterGroupBy" on-change="ctrl.targetBlur()">
|
||||
</gf-form-switch>
|
||||
|
||||
<a bs-tooltip="ctrl.errors.filters"
|
||||
style="color: rgb(229, 189, 28)"
|
||||
ng-show="ctrl.errors.filters">
|
||||
<i class="fa fa-warning"></i>
|
||||
</a>
|
||||
|
||||
<a ng-click="ctrl.addFilter()" ng-hide="ctrl.errors.filters">
|
||||
add filter
|
||||
</a>
|
||||
<a ng-click="ctrl.closeAddFilterMode()">
|
||||
<i class="fa fa-remove"></i>
|
||||
</a>
|
||||
<div class="gf-form" ng-show="ctrl.addFilterMode">
|
||||
<label class="gf-form-label" ng-show="ctrl.errors.filters">
|
||||
<a bs-tooltip="ctrl.errors.filters" style="color: rgb(229, 189, 28)" >
|
||||
<i class="fa fa-warning"></i>
|
||||
</a>
|
||||
</label>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<label class="gf-form-label">
|
||||
<a ng-click="ctrl.addFilter()" ng-hide="ctrl.errors.filters">add filter</a>
|
||||
<a ng-click="ctrl.closeAddFilterMode()">
|
||||
<i class="fa fa-remove"></i>
|
||||
</a>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list" role="menu">
|
||||
<li class="tight-form-item tight-form-align query-keyword" style="width: 100px">
|
||||
Tags
|
||||
<tip ng-if="ctrl.tsdbVersion == 2">Please use filters, tags are deprecated in opentsdb 2.2</tip>
|
||||
</li>
|
||||
<li ng-repeat="(key, value) in ctrl.target.tags track by $index" class="tight-form-item">
|
||||
{{key}} = {{value}}
|
||||
<a ng-click="ctrl.editTag(key, value)">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
<a ng-click="ctrl.removeTag(key)">
|
||||
<i class="fa fa-remove"></i>
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
|
||||
<li class="tight-form-item query-keyword" ng-hide="ctrl.addTagMode">
|
||||
<a ng-click="ctrl.addTag()">
|
||||
<i class="fa fa-plus"></i>
|
||||
</a>
|
||||
</li>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<li ng-show="ctrl.addTagMode">
|
||||
<input type="text" class="input-small tight-form-input" spellcheck='false'
|
||||
bs-typeahead="ctrl.suggestTagKeys" data-min-length=0 data-items=100
|
||||
ng-model="ctrl.target.currentTagKey" placeholder="key"></input>
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-8">
|
||||
Tags
|
||||
<info-popover mode="right-normal" ng-if="ctrl.tsdbVersion == 2">
|
||||
Please use filters, tags are deprecated in opentsdb 2.2
|
||||
</info-popover>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<input type="text" class="input-small tight-form-input"
|
||||
spellcheck='false' bs-typeahead="ctrl.suggestTagValues"
|
||||
data-min-length=0 data-items=100 ng-model="ctrl.target.currentTagValue" placeholder="value">
|
||||
<div class="gf-form" ng-repeat="(key, value) in ctrl.target.tags track by $index" class="gf-form">
|
||||
<label class="gf-form-label">
|
||||
{{key}} = {{value}}
|
||||
<a ng-click="ctrl.editTag(key, value)">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
<a ng-click="ctrl.removeTag(key)">
|
||||
<i class="fa fa-remove"></i>
|
||||
</a>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="gf-form" ng-hide="ctrl.addTagMode">
|
||||
<label class="gf-form-label query-keyword">
|
||||
<a ng-click="ctrl.addTag()"><i class="fa fa-plus"></i></a>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="gf-form" ng-show="ctrl.addTagMode">
|
||||
<input type="text"
|
||||
class="gf-form-input" spellcheck='false'
|
||||
bs-typeahead="ctrl.suggestTagKeys" data-min-length=0 data-items=100
|
||||
ng-model="ctrl.target.currentTagKey" placeholder="key">
|
||||
</input>
|
||||
|
||||
<a bs-tooltip="ctrl.errors.tags"
|
||||
style="color: rgb(229, 189, 28)"
|
||||
ng-show="ctrl.errors.tags">
|
||||
<i class="fa fa-warning"></i>
|
||||
</a>
|
||||
<input type="text" class="gf-form-input"
|
||||
spellcheck='false' bs-typeahead="ctrl.suggestTagValues"
|
||||
data-min-length=0 data-items=100 ng-model="ctrl.target.currentTagValue" placeholder="value">
|
||||
</input>
|
||||
|
||||
<a ng-click="ctrl.addTag()" ng-hide="ctrl.errors.tags">
|
||||
add tag
|
||||
</a>
|
||||
<a ng-click="ctrl.closeAddTagMode()">
|
||||
<i class="fa fa-remove"></i>
|
||||
</a>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<label class="gf-form-label" ng-show="ctrl.errors.tags">
|
||||
<a bs-tooltip="ctrl.errors.tags" style="color: rgb(229, 189, 28)" >
|
||||
<i class="fa fa-warning"></i>
|
||||
</a>
|
||||
</label>
|
||||
<label class="gf-form-label" >
|
||||
<a ng-click="ctrl.addTag()" ng-hide="ctrl.errors.tags">add tag</a>
|
||||
<a ng-click="ctrl.closeAddTagMode()"><i class="fa fa-remove"></i></a>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list" role="menu">
|
||||
<li class="tight-form-item tight-form-align query-keyword" style="width: 100px">
|
||||
Rate <editor-checkbox text="" model="ctrl.target.shouldComputeRate" change="ctrl.targetBlur()"></editor-checkbox>
|
||||
</li>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<li class="tight-form-item query-keyword" ng-hide="!ctrl.target.shouldComputeRate">
|
||||
Counter <editor-checkbox text="" model="ctrl.target.isCounter" change="ctrl.targetBlur()"></editor-checkbox>
|
||||
</li>
|
||||
<div class="gf-form-inline">
|
||||
<gf-form-switch class="gf-form" label="Rate" label-class="width-8 query-keyword" checked="ctrl.target.shouldComputeRate" on-change="ctrl.targetBlur()">
|
||||
</gf-form-switch>
|
||||
|
||||
<li class="tight-form-item query-keyword" ng-hide="!ctrl.target.isCounter || !ctrl.target.shouldComputeRate">
|
||||
Counter Max:
|
||||
</li>
|
||||
<gf-form-switch ng-hide="!ctrl.target.shouldComputeRate"
|
||||
class="gf-form" label="Counter" checked="ctrl.target.isCounter" on-change="ctrl.targetBlur()">
|
||||
</gf-form-switch>
|
||||
|
||||
<li ng-hide="!ctrl.target.isCounter || !ctrl.target.shouldComputeRate">
|
||||
<input type="text" class="tight-form-input input-small" ng-disabled="!ctrl.target.shouldComputeRate"
|
||||
ng-model="ctrl.target.counterMax" spellcheck='false'
|
||||
placeholder="max value" ng-model-onblur
|
||||
ng-blur="ctrl.targetBlur()"></input>
|
||||
</li>
|
||||
<li class="tight-form-item query-keyword" ng-hide="!ctrl.target.isCounter || !ctrl.target.shouldComputeRate">
|
||||
Reset Value:
|
||||
</li>
|
||||
<li ng-hide="!ctrl.target.isCounter || !ctrl.target.shouldComputeRate">
|
||||
<input type="text" class="tight-form-input input-small" ng-disabled="!ctrl.target.shouldComputeRate"
|
||||
ng-model="ctrl.target.counterResetValue" spellcheck='false'
|
||||
placeholder="reset value" ng-model-onblur
|
||||
ng-blur="ctrl.targetBlur()"></input>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="gf-form" ng-hide="!ctrl.target.isCounter || !ctrl.target.shouldComputeRate">
|
||||
<label class="gf-form-label">Counter Max</label>
|
||||
<input type="text" class="gf-form-input"
|
||||
ng-disabled="!ctrl.target.shouldComputeRate"
|
||||
ng-model="ctrl.target.counterMax" spellcheck='false'
|
||||
placeholder="max value" ng-model-onblur
|
||||
ng-blur="ctrl.targetBlur()">
|
||||
</input>
|
||||
|
||||
<label class="gf-form-label">Reset Value</label>
|
||||
<input type="text" class="tight-form-input input-small"
|
||||
ng-disabled="!ctrl.target.shouldComputeRate"
|
||||
ng-model="ctrl.target.counterResetValue" spellcheck='false'
|
||||
placeholder="reset value" ng-model-onblur
|
||||
ng-blur="ctrl.targetBlur()">
|
||||
</input>
|
||||
</div>
|
||||
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
</query-editor-row>
|
||||
|
||||
|
||||
@@ -1,80 +1,54 @@
|
||||
<query-editor-row ctrl="ctrl">
|
||||
<li class="tight-form-item" style="width: 94px">
|
||||
Query
|
||||
</li>
|
||||
<li>
|
||||
<input type="text"
|
||||
class="input-xxlarge tight-form-input"
|
||||
ng-model="ctrl.target.expr"
|
||||
spellcheck='false'
|
||||
placeholder="query expression"
|
||||
data-min-length=0 data-items=100
|
||||
ng-model-onblur
|
||||
ng-change="ctrl.refreshMetricData()">
|
||||
</li>
|
||||
<li class="tight-form-item">
|
||||
Metric
|
||||
</li>
|
||||
<li>
|
||||
<input type="text"
|
||||
class="input-medium tight-form-input"
|
||||
ng-model="ctrl.target.metric"
|
||||
spellcheck='false'
|
||||
bs-typeahead="ctrl.suggestMetrics"
|
||||
placeholder="metric name"
|
||||
data-min-length=0 data-items=100>
|
||||
</li>
|
||||
</query-editor-row>
|
||||
<query-editor-row query-ctrl="ctrl" can-collapse="false">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form gf-form--grow">
|
||||
<label class="gf-form-label width-8">Query</label>
|
||||
<input type="text" class="gf-form-input" ng-model="ctrl.target.expr" spellcheck='false' placeholder="query expression" data-min-length=0 data-items=100 ng-model-onblur ng-change="ctrl.refreshMetricData()">
|
||||
</div>
|
||||
<div class="gf-form max-width-22">
|
||||
<label class="gf-form-label">Metric lookup</label>
|
||||
<input type="text" class="gf-form-input" ng-model="ctrl.target.metric" spellcheck='false' bs-typeahead="ctrl.suggestMetrics" placeholder="metric name" data-min-length=0 data-items=100>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list" role="menu">
|
||||
<li class="tight-form-item tight-form-align" style="width: 94px">
|
||||
Legend format
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="tight-form-input input-xxlarge" ng-model="ctrl.target.legendFormat"
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form max-width-26">
|
||||
<label class="gf-form-label width-8">Legend format</label>
|
||||
<input type="text" class="gf-form-input" ng-model="ctrl.target.legendFormat"
|
||||
spellcheck='false' placeholder="legend format" data-min-length=0 data-items=1000
|
||||
ng-model-onblur ng-change="ctrl.refreshMetricData()">
|
||||
</input>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label width-5">Step</label>
|
||||
<input type="text" class="gf-form-input max-width-5" ng-model="ctrl.target.interval"
|
||||
data-placement="right"
|
||||
spellcheck='false'
|
||||
placeholder="{{ctrl.panelCtrl.interval}}"
|
||||
data-min-length=0 data-items=100
|
||||
ng-model-onblur
|
||||
ng-change="ctrl.refreshMetricData()"/>
|
||||
<info-popover mode="right-absolute">
|
||||
Leave blank for auto handling based on time range and panel width
|
||||
</info-popover>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">Resolution</label>
|
||||
<div class="gf-form-select-wrapper max-width-15">
|
||||
<select ng-model="ctrl.target.intervalFactor" class="gf-form-input"
|
||||
ng-options="r.factor as r.label for r in ctrl.resolutions"
|
||||
ng-change="ctrl.refreshMetricData()">
|
||||
</select>
|
||||
</div>
|
||||
<label class="gf-form-label">
|
||||
<a href="{{ctrl.linkToPrometheus}}" target="_blank" bs-tooltip="'Link to Graph in Prometheus'">
|
||||
<i class="fa fa-share-square-o"></i>
|
||||
</a>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list" role="menu">
|
||||
<li class="tight-form-item tight-form-align" style="width: 94px">
|
||||
Step
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="input-mini tight-form-input" ng-model="ctrl.target.interval"
|
||||
bs-tooltip="'Leave blank for auto handling based on time range and panel width'"
|
||||
data-placement="right"
|
||||
spellcheck='false'
|
||||
placeholder="{{ctrl.panelCtrl.interval}}"
|
||||
data-min-length=0 data-items=100
|
||||
ng-model-onblur
|
||||
ng-change="ctrl.refreshMetricData()"
|
||||
/>
|
||||
</input>
|
||||
</li>
|
||||
|
||||
<li class="tight-form-item">
|
||||
Resolution
|
||||
</li>
|
||||
<li>
|
||||
<select ng-model="ctrl.target.intervalFactor" class="tight-form-input input-mini"
|
||||
ng-options="r.factor as r.label for r in ctrl.resolutions"
|
||||
ng-change="ctrl.refreshMetricData()">
|
||||
</select>
|
||||
</li>
|
||||
<li class="tight-form-item">
|
||||
<a href="{{ctrl.linkToPrometheus}}" target="_blank" bs-tooltip="'Link to Graph in Prometheus'">
|
||||
<i class="fa fa-share-square-o"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</query-editor-row>
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
@import "components/drop";
|
||||
@import "components/query_editor";
|
||||
@import "components/tabbed_view";
|
||||
@import "components/query_part";
|
||||
|
||||
// PAGES
|
||||
@import "pages/login";
|
||||
|
||||
@@ -67,8 +67,8 @@ $page-gradient: linear-gradient(60deg, transparent 70%, darken($page-bg, 4%) 98%
|
||||
|
||||
// Links
|
||||
// -------------------------
|
||||
$link-color: darken($white,11%);
|
||||
$link-color-disabled: darken($link-color,30%);
|
||||
$link-color: darken($white, 11%);
|
||||
$link-color-disabled: darken($link-color, 30%);
|
||||
$link-hover-color: $white;
|
||||
$external-link-color: $blue;
|
||||
|
||||
@@ -76,7 +76,7 @@ $external-link-color: $blue;
|
||||
// -------------------------
|
||||
$headings-color: darken($white,11%);
|
||||
$abbr-border-color: $gray-3 !default;
|
||||
$text-muted: darken($link-color,30%);
|
||||
$text-muted: $text-color-weak;
|
||||
|
||||
$blockquote-small-color: $gray-3 !default;
|
||||
$blockquote-border-color: $gray-4 !default;
|
||||
|
||||
@@ -82,7 +82,7 @@ $external-link-color: $blue;
|
||||
// -------------------------
|
||||
$headings-color: $text-color;
|
||||
$abbr-border-color: $gray-2 !default;
|
||||
$text-muted: darken($link-color,30%);
|
||||
$text-muted: $text-color-weak;
|
||||
|
||||
$blockquote-small-color: $gray-2 !default;
|
||||
$blockquote-border-color: $gray-3 !default;
|
||||
|
||||
@@ -27,9 +27,9 @@ em { font-style: italic; color: $headings-color; }
|
||||
cite { font-style: normal; }
|
||||
|
||||
// Utility classes
|
||||
.muted { color: $gray-2; }
|
||||
.muted { color: $text-muted; }
|
||||
a.muted:hover,
|
||||
a.muted:focus { color: darken($gray-2, 10%); }
|
||||
a.muted:focus { color: darken($text-muted, 10%); }
|
||||
|
||||
.text-warning { color: $state-warning-text; }
|
||||
a.text-warning:hover,
|
||||
@@ -118,6 +118,10 @@ small,
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.small-xs {
|
||||
font-size: $font-size-xs;
|
||||
}
|
||||
|
||||
mark,
|
||||
.mark {
|
||||
padding: .2em;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
$popover-arrow-size: 1rem;
|
||||
$popover-arrow-size: 0.7rem;
|
||||
$color: inherit;
|
||||
$backgroundColor: $btn-secondary-bg;
|
||||
$color: $text-color;
|
||||
|
||||
@@ -8,8 +8,22 @@ $gf-form-margin: 0.25rem;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
|
||||
.cr1 {
|
||||
margin-left: 8px;
|
||||
&--offset-1 {
|
||||
margin-left: $spacer;
|
||||
}
|
||||
|
||||
&--grow {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.gf-form-disabled {
|
||||
color: $text-color-weak;
|
||||
|
||||
.query-keyword,
|
||||
a,
|
||||
.gf-form-input {
|
||||
color: $text-color-weak;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,10 +36,6 @@ $gf-form-margin: 0.25rem;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
align-content: flex-start;
|
||||
|
||||
.gf-form-flex {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.gf-form-button-row {
|
||||
@@ -48,6 +58,12 @@ $gf-form-margin: 0.25rem;
|
||||
|
||||
border: $input-btn-border-width solid transparent;
|
||||
@include border-radius($label-border-radius-sm);
|
||||
|
||||
|
||||
&--grow {
|
||||
flex-grow: 1;
|
||||
min-height: 2.70rem;
|
||||
}
|
||||
}
|
||||
|
||||
.gf-form-checkbox {
|
||||
@@ -107,6 +123,21 @@ $gf-form-margin: 0.25rem;
|
||||
}
|
||||
|
||||
&.gf-size-auto { width: auto; }
|
||||
|
||||
&--dropdown {
|
||||
padding-right: $input-padding-x*2;
|
||||
|
||||
&:after {
|
||||
position: absolute;
|
||||
top: 35%;
|
||||
right: $input-padding-x/2;
|
||||
background-color: transparent;
|
||||
color: $input-color;
|
||||
font: normal normal normal $font-size-sm/1 FontAwesome;
|
||||
content: '\f0d7';
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.gf-form-select-wrapper {
|
||||
@@ -152,9 +183,11 @@ $gf-form-margin: 0.25rem;
|
||||
}
|
||||
|
||||
.gf-form-btn {
|
||||
margin-right: $gf-form-margin;
|
||||
padding: $input-padding-y $input-padding-x;
|
||||
margin-right: $gf-form-margin;
|
||||
line-height: $input-line-height;
|
||||
font-size: $font-size-sm;
|
||||
|
||||
flex-shrink: 0;
|
||||
flex-grow: 0;
|
||||
}
|
||||
@@ -209,4 +242,3 @@ $gf-form-margin: 0.25rem;
|
||||
select.gf-form-input ~ .gf-form-help-icon {
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,13 +4,66 @@
|
||||
}
|
||||
|
||||
.query-segment-key {
|
||||
border-right: none;
|
||||
padding-right: 1px;
|
||||
//border-right: none;
|
||||
//padding-right: 1px;
|
||||
}
|
||||
|
||||
.query-segment-operator {
|
||||
padding-right: 1px;
|
||||
border-right: none;
|
||||
//padding-right: 1px;
|
||||
//border-right: none;
|
||||
color: $orange;
|
||||
}
|
||||
|
||||
.gf-form-query {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-content: flex-start;
|
||||
align-items: flex-start;
|
||||
|
||||
.gf-form,
|
||||
.gf-form-filler {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.gf-form-switch,
|
||||
.gf-form-switch label,
|
||||
.gf-form-input,
|
||||
.gf-form-select-wrapper,
|
||||
.gf-form-filler,
|
||||
.gf-form-label {
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.gf-form-query-content {
|
||||
flex-grow: 2;
|
||||
|
||||
&--collapsed {
|
||||
overflow: hidden;
|
||||
|
||||
.gf-form-label {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.gf-form-query-letter-cell {
|
||||
.gf-form-query-letter-cell-carret {
|
||||
display: inline-block;
|
||||
width: 0.7rem;
|
||||
position: relative;
|
||||
left: -2px;
|
||||
}
|
||||
.gf-form-query-letter-cell-letter {
|
||||
font-weight: bold;
|
||||
color: $blue;
|
||||
}
|
||||
.gf-form-query-letter-cell-ds {
|
||||
color: $text-color-weak;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
.query-part {
|
||||
background-color: $input-bg !important;
|
||||
|
||||
&.show-function-controls {
|
||||
padding-top: 5px;
|
||||
min-width: 100px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
font-family: inherit;
|
||||
background: $theme-bg;
|
||||
color: $theme-color;
|
||||
padding: $spacer;
|
||||
padding: 0.65rem;
|
||||
font-size: $font-size-sm;
|
||||
max-width: 20rem;
|
||||
|
||||
|
||||
@@ -61,13 +61,14 @@ button.close {
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
// Visibility
|
||||
.invisible {
|
||||
visibility: hidden;
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
// For Affix plugin
|
||||
|
||||
@@ -17,3 +17,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
@for $i from 1 through 30 {
|
||||
.offset-width-#{$i} {
|
||||
margin-left: ($spacer * $i) !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user