فهرست منبع

feat(thresholds): lots of progress on thresholds

Torkel Ödegaard 9 سال پیش
والد
کامیت
89ca15f3a1

+ 28 - 23
public/app/features/alerting/alert_tab_ctrl.ts

@@ -76,26 +76,6 @@ export class AlertTabCtrl {
     }));
   }
 
-  evaluatorTypeChanged(evaluator) {
-    // ensure params array is correct length
-    switch (evaluator.type) {
-      case "lt":
-      case "gt": {
-        evaluator.params = [evaluator.params[0]];
-        break;
-      }
-      case "within_range":
-      case "outside_range": {
-        evaluator.params = [evaluator.params[0], evaluator.params[1]];
-        break;
-      }
-      case "no_value": {
-        evaluator.params = [];
-      }
-    }
-
-    this.thresholdUpdated();
-  }
 
   notificationAdded() {
     var model = _.findWhere(this.notifications, {name: this.addNotificationSegment.value});
@@ -200,10 +180,35 @@ export class AlertTabCtrl {
     this.initModel();
   }
 
-  thresholdUpdated() {
-    if (ThresholdMapper.alertToGraphThresholds(this.panel)) {
-      this.panelCtrl.render();
+  evaluatorParamsChanged() {
+    ThresholdMapper.alertToGraphThresholds(this.panel);
+    this.panelCtrl.render();
+  }
+
+  severityChanged() {
+    ThresholdMapper.alertToGraphThresholds(this.panel);
+    this.panelCtrl.render();
+  }
+
+  evaluatorTypeChanged(evaluator) {
+    // ensure params array is correct length
+    switch (evaluator.type) {
+      case "lt":
+      case "gt": {
+        evaluator.params = [evaluator.params[0]];
+        break;
+      }
+      case "within_range":
+      case "outside_range": {
+        evaluator.params = [evaluator.params[0], evaluator.params[1]];
+        break;
+      }
+      case "no_value": {
+        evaluator.params = [];
+      }
     }
+
+    this.evaluatorParamsChanged();
   }
 
   test() {

+ 3 - 3
public/app/features/alerting/partials/alert_tab.html

@@ -34,7 +34,7 @@
 					<div class="gf-form">
 						<span class="gf-form-label">Severity</span>
 						<div class="gf-form-select-wrapper width-13">
-							<select class="gf-form-input" ng-model="ctrl.alert.severity" ng-options="f.value as f.text for f in ctrl.severityLevels">
+							<select class="gf-form-input" ng-model="ctrl.alert.severity" ng-options="f.value as f.text for f in ctrl.severityLevels" ng-change="ctrl.severityChanged()">
 							</select>
 						</div>
 					</div>
@@ -59,9 +59,9 @@
 					</div>
 					<div class="gf-form">
 						<metric-segment-model property="conditionModel.evaluator.type" options="ctrl.evalFunctions" custom="false" css-class="query-keyword" on-change="ctrl.evaluatorTypeChanged(conditionModel.evaluator)"></metric-segment-model>
-						<input class="gf-form-input max-width-7" type="number" ng-hide="conditionModel.evaluator.params.length === 0" ng-model="conditionModel.evaluator.params[0]" ng-change="ctrl.thresholdUpdated()"></input>
+						<input class="gf-form-input max-width-7" type="number" ng-hide="conditionModel.evaluator.params.length === 0" ng-model="conditionModel.evaluator.params[0]" ng-change="ctrl.evaluatorParamsChanged()"></input>
             <label class="gf-form-label query-keyword" ng-show="conditionModel.evaluator.params.length === 2">TO</label>
-						<input class="gf-form-input max-width-7" type="number" ng-if="conditionModel.evaluator.params.length === 2" ng-model="conditionModel.evaluator.params[1]" ng-change="ctrl.thresholdUpdated()"></input>
+						<input class="gf-form-input max-width-7" type="number" ng-if="conditionModel.evaluator.params.length === 2" ng-model="conditionModel.evaluator.params[1]" ng-change="ctrl.evaluatorParamsChanged()"></input>
 					</div>
 					<div class="gf-form">
 						<label class="gf-form-label">

+ 3 - 15
public/app/plugins/panel/graph/graph.js

@@ -37,7 +37,7 @@ function (angular, $, moment, _, kbn, GraphTooltip, thresholds) {
         var legendSideLastValue = null;
         var rootScope = scope.$root;
         var panelWidth = 0;
-        var thresholdControls;
+        var thresholdControls = new ThresholdControls(ctrl);
 
         rootScope.onAppEvent('setCrosshair', function(event, info) {
           // do not need to to this if event is from this panel
@@ -161,9 +161,7 @@ function (angular, $, moment, _, kbn, GraphTooltip, thresholds) {
             rightLabel[0].style.marginTop = (getLabelWidth(panel.yaxes[1].label, rightLabel) / 2) + 'px';
           }
 
-          if (thresholdControls) {
-            thresholdControls.draw(plot);
-          }
+          thresholdControls.draw(plot);
         }
 
         function processOffsetHook(plot, gridMargin) {
@@ -182,17 +180,7 @@ function (angular, $, moment, _, kbn, GraphTooltip, thresholds) {
           }
 
           // give space to alert editing
-          if (ctrl.editingThresholds) {
-            if (!thresholdControls) {
-              var thresholdMargin = panel.thresholds.length > 1 ? '220px' : '110px';
-              elem.css('margin-right', thresholdMargin);
-              thresholdControls = new ThresholdControls(ctrl);
-            }
-          } else if (thresholdControls) {
-            elem.css('margin-right', '0');
-            thresholdControls.cleanUp();
-            thresholdControls = null;
-          }
+          thresholdControls.prepare(elem);
 
           var stack = panel.stack ? true : null;
 

+ 1 - 1
public/app/plugins/panel/graph/module.ts

@@ -328,7 +328,7 @@ class GraphCtrl extends MetricsPanelCtrl {
   }
 
   addThreshold() {
-    this.panel.thresholds.push({value: undefined, color: "rgba(255,0,0,0.2)"});
+    this.panel.thresholds.push({value: undefined, colorMode: "critical", op: 'gt', fill: true, line: true});
   }
 
   removeThreshold(index) {

+ 50 - 29
public/app/plugins/panel/graph/thresholds.ts

@@ -9,26 +9,25 @@ export class ThresholdControls {
   placeholder: any;
   height: any;
   thresholds: any;
+  needsCleanup: boolean;
 
-  constructor(private panelCtrl) {
-    this.thresholds = this.panelCtrl.panel.thresholds;
-  }
+  constructor(private panelCtrl) {}
 
- getHandleInnerHtml(handleName, op, value) {
-    if (op === '>') { op = '&gt;'; }
-    if (op === '<') { op = '&lt;'; }
+  getHandleHtml(handleIndex, model, valueStr) {
+    var colorClass = 'crit';
+    if (model.colorMode === 'warning') {
+      colorClass = 'warn';
+    }
 
-    return `
-    <div class="alert-handle-line">
+    return `<div class="alert-handle-wrapper alert-handle-wrapper--T${handleIndex}">
+    <div class="alert-handle-line alert-handle-line--${colorClass}">
+    </div>
+    <div class="alert-handle" data-handle-index="${handleIndex}">
+    <i class="icon-gf icon-gf-${colorClass} alert-icon-${colorClass}"></i>
+    <span class="alert-handle-value">${valueStr}</span>
     </div>
-    <div class="alert-handle">
-      ${op} ${value}
     </div>`;
-  }
 
-  getFullHandleHtml(handleName, op, value) {
-    var innerTemplate = this.getHandleInnerHtml(handleName, op, value);
-    return `<div class="alert-handle-wrapper alert-handle-wrapper--${handleName}">${innerTemplate}</div>`;
   }
 
   setupDragging(handleElem, threshold, handleIndex) {
@@ -78,15 +77,18 @@ export class ThresholdControls {
     });
   }
 
+  initDragging(evt) {
+    var handleIndex = $(evt.currentTarget).data("handleIndex");
+    console.log('alert handle index', handleIndex);
+  }
+
   cleanUp() {
-    if (this.placeholder) {
-      this.placeholder.find(".alert-handle-wrapper").remove();
-    }
+    this.placeholder.find(".alert-handle-wrapper").remove();
+    this.needsCleanup = false;
   }
 
-  renderHandle(handleIndex, model, defaultHandleTopPos) {
-    var handleName = 'T' + (handleIndex+1);
-    var handleElem = this.placeholder.find(`.alert-handle-wrapper--${handleName}`);
+  renderHandle(handleIndex, defaultHandleTopPos) {
+    var model = this.thresholds[handleIndex];
     var value = model.value;
     var valueStr = value;
     var handleTopPos = 0;
@@ -100,29 +102,48 @@ export class ThresholdControls {
       handleTopPos = Math.min(Math.max(valueCanvasPos.top, 0), this.height) - 6;
     }
 
-    if (handleElem.length === 0) {
-      handleElem = $(this.getFullHandleHtml(handleName, model.op, valueStr));
-      this.placeholder.append(handleElem);
-      this.setupDragging(handleElem, model, handleIndex);
-    } else {
-      handleElem.html(this.getHandleInnerHtml(handleName, model.op, valueStr));
-    }
+    var handleElem = $(this.getHandleHtml(handleIndex, model, valueStr));
+    this.placeholder.append(handleElem);
 
     handleElem.toggleClass('alert-handle-wrapper--no-value', valueStr === '');
     handleElem.css({top: handleTopPos});
   }
 
+  prepare(elem) {
+    if (this.panelCtrl.editingThresholds) {
+      var thresholdMargin = this.panelCtrl.panel.thresholds.length > 1 ? '220px' : '110px';
+      elem.css('margin-right', thresholdMargin);
+    } else if (this.needsCleanup) {
+      elem.css('margin-right', '0');
+    }
+  }
+
   draw(plot) {
+    this.thresholds = this.panelCtrl.panel.thresholds;
     this.plot = plot;
     this.placeholder = plot.getPlaceholder();
+
+    if (this.needsCleanup) {
+      this.cleanUp();
+    }
+
+    // if no thresholds or not editing alerts skip rendering handles
+    if (this.thresholds.length === 0 || !this.panelCtrl.editingThresholds) {
+      return;
+    }
+
     this.height = plot.height();
 
     if (this.thresholds.length > 0) {
-      this.renderHandle(0, this.thresholds[0], 10);
+      this.renderHandle(0, 10);
     }
     if (this.thresholds.length > 1) {
-      this.renderHandle(1, this.thresholds[1], this.height-30);
+      this.renderHandle(1, this.height-30);
     }
+
+    this.placeholder.off('mousedown', '.alert-handle');
+    this.placeholder.on('mousedown', '.alert-handle', this.initDragging.bind(this));
+    this.needsCleanup = true;
   }
 }
 

+ 6 - 4
public/sass/_variables.dark.scss

@@ -90,12 +90,12 @@ $component-active-bg:    $brand-primary !default;
 // Panel
 // -------------------------
 $panel-bg: 				 $dark-2;
-$panel-border: 			 solid 1px $dark-3;
+$panel-border:  	 solid 1px $dark-3;
 
-$divider-border-color:  #555;
+$divider-border-color:        #555;
 
 // Graphite Target Editor
-$tight-form-border:     #050505;
+$tight-form-border:   #050505;
 $tight-form-bg:     	$dark-3;
 
 $tight-form-func-bg: 		    #333;
@@ -152,6 +152,9 @@ $btn-link-color:              $gray-3;
 
 $iconContainerBackground:	    $black;
 
+$btn-divider-left:   $dark-5;
+$btn-divider-right:  $dark-1;
+
 // Forms
 // -------------------------
 $input-bg:                       $dark-4;
@@ -185,7 +188,6 @@ $dropdownLinkColorActive:       $white;
 $dropdownLinkBackgroundActive:  $dark-4;
 $dropdownLinkBackgroundHover:   $dark-4;
 
-
 // COMPONENT VARIABLES
 // --------------------------------------------------
 

+ 4 - 1
public/sass/_variables.light.scss

@@ -99,7 +99,7 @@ $component-active-bg:    $brand-primary !default;
 $panel-bg: 		  $gray-7;
 $panel-border:  solid 1px $gray-6;
 
-$divider-border-color:	$gray-2;
+$divider-border-color:	      $gray-2;
 
 // Graphite Target Editor
 $tight-form-border:   $gray-4;
@@ -157,6 +157,9 @@ $btn-inverse-text-color:  $dark-4;
 
 $btn-link-color: $gray-1;
 
+$btn-divider-left:   $dark-5;
+$btn-divider-right:  $dark-1;
+
 $iconContainerBackground: $white;
 
 // Forms

+ 35 - 23
public/sass/components/_panel_graph.scss

@@ -323,53 +323,50 @@
     z-index: 10;
     position: relative;
     float: right;
-    padding: 0.4rem 0.6rem 0.4rem 0.4rem;
-    background-color: $btn-inverse-bg;
-    box-shadow: $search-shadow;
-    cursor: row-resize;
+    box-shadow: $card-shadow;
+    background: $card-background;
+    cursor: move;
     width: 100px;
     font-size: $font-size-sm;
-    box-shadow: 4px 4px 3px 0px $body-bg;
     border-radius: 4px;
-    border-width: 0 1px 1px 0;
-    border-style: solid;
-    border-color: $black;
     text-align: left;
     color: $text-muted;
 
+    &:hover {
+      background-color: $btn-inverse-bg-hl;
+    }
+
     .icon-gf {
-      font-size: 17px;
+      font-size: 14px;
       position: relative;
       top: 0px;
       float: left;
+      border-right: 1px solid $btn-divider-left;
+      padding: 0.5rem 0.3rem 0.4rem 0.4rem;
     }
   }
 
-  .alert-handle-line {
-    float: left;
-    height: 2px;
-    margin-top: 13px;
-    z-index: 0;
-    position: relative;
+  .alert-handle-value {
+    border-left: 1px solid $btn-divider-right;
+    padding: 0.5rem;
+    line-height: 2rem;
   }
 
-  &--T2 {
+  &--T1 {
     right: -222px;
-    width: 238px;
+    width: 245px;
 
     .alert-handle-line {
-      width: 138px;
-      background-color: $warn;
+      width: 145px;
     }
   }
 
-  &--T1{
+  &--T0{
     right: -105px;
-    width: 123px;
+    width: 128px;
 
     .alert-handle-line {
-      width: 23px;
-      background-color: $critical;
+      width: 28px;
     }
   }
 
@@ -378,4 +375,19 @@
       display: none;
     }
   }
+
+  .alert-handle-line {
+    float: left;
+    height: 2px;
+    margin-top: 13px;
+    z-index: 0;
+    position: relative;
+
+    &--crit {
+      background-color: rgba(237, 46, 24, 0.60);
+    }
+    &--warn {
+      background-color: rgba(247, 149, 32, 0.60);
+    }
+  }
 }