소스 검색

feat(alertlist): basic alert list panel

ref #5981
bergquist 9 년 전
부모
커밋
d02f29fb02

+ 1 - 0
public/app/plugins/panel/alertlist/README.md

@@ -0,0 +1 @@
+# Alert List Panel - Native plugin

+ 12 - 0
public/app/plugins/panel/alertlist/editor.html

@@ -0,0 +1,12 @@
+<div>
+  <div class="section gf-form-group">
+    <h5 class="section-heading">Options</h5>
+    <div class="gf-form">
+      <span class="gf-form-label width-8">Show</span>
+      <div class="gf-form-select-wrapper max-width-15">
+         <select class="gf-form-input" ng-model="ctrl.panel.show" ng-options="f.value as f.text for f in ctrl.showOptions" ng-change="ctrl.onRender()"></select>
+      </div>
+    </div>
+
+  </div>
+</div>

+ 33 - 0
public/app/plugins/panel/alertlist/img/icn-singlestat-panel.svg

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 width="100px" height="100px" viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
+<g>
+	<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="32.3342" y1="95.7019" x2="32.3342" y2="5.2695">
+		<stop  offset="0" style="stop-color:#FFDE17"/>
+		<stop  offset="0.0803" style="stop-color:#FFD210"/>
+		<stop  offset="0.1774" style="stop-color:#FEC90D"/>
+		<stop  offset="0.2809" style="stop-color:#FDC70C"/>
+		<stop  offset="0.6685" style="stop-color:#F3903F"/>
+		<stop  offset="0.8876" style="stop-color:#ED683C"/>
+		<stop  offset="1" style="stop-color:#E93E3A"/>
+	</linearGradient>
+	<path style="fill:url(#SVGID_1_);" d="M48.173,57.757V39.825c0-1.302,1.055-2.357,2.357-2.357h9.691
+		c0.897,0,1.346-1.084,0.712-1.718L34.112,0.737c-0.982-0.982-2.574-0.982-3.556,0L3.735,35.75
+		c-0.634,0.634-0.185,1.718,0.712,1.718h9.691c1.302,0,2.357,1.055,2.357,2.357v17.932c0,0.958,0.776,1.734,1.734,1.734h28.21
+		C47.397,59.491,48.173,58.715,48.173,57.757z"/>
+	<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="67.6658" y1="94.1706" x2="67.6658" y2="3.7383">
+		<stop  offset="0" style="stop-color:#FFDE17"/>
+		<stop  offset="0.0803" style="stop-color:#FFD210"/>
+		<stop  offset="0.1774" style="stop-color:#FEC90D"/>
+		<stop  offset="0.2809" style="stop-color:#FDC70C"/>
+		<stop  offset="0.6685" style="stop-color:#F3903F"/>
+		<stop  offset="0.8876" style="stop-color:#ED683C"/>
+		<stop  offset="1" style="stop-color:#E93E3A"/>
+	</linearGradient>
+	<path style="fill:url(#SVGID_2_);" d="M95.553,62.532h-9.691c-1.302,0-2.357-1.055-2.357-2.357V42.243
+		c0-0.958-0.776-1.734-1.734-1.734h-28.21c-0.958,0-1.734,0.776-1.734,1.734v17.932c0,1.302-1.055,2.357-2.357,2.357h-9.691
+		c-0.897,0-1.346,1.084-0.712,1.718l26.821,35.013c0.982,0.982,2.574,0.982,3.556,0L96.265,64.25
+		C96.898,63.616,96.45,62.532,95.553,62.532z"/>
+</g>
+</svg>

+ 59 - 0
public/app/plugins/panel/alertlist/module.html

@@ -0,0 +1,59 @@
+<div class="panel-alert-list">
+  <section class="card-section card-list-layout-list" ng-if="ctrl.panel.show === 'current'">
+
+    <ol class="card-list" >
+      <li class="card-item-wrapper" ng-repeat="alert in ctrl.currentAlerts">
+        <div class="card-item card-item--alert">
+          <div class="card-item-header">
+            <div class="card-item-type">
+              <a class="card-item-cog" href="dashboard/{{alert.dashboardUri}}?panelId={{alert.panelId}}&fullscreen&edit&tab=alert" bs-tooltip="'Edit alert rule'">
+                <i class="icon-gf icon-gf-settings"></i>
+              </a>
+            </div>
+          </div>
+          <div class="card-item-body">
+            <div class="card-item-details">
+              <div class="card-item-name">
+                <a href="dashboard/{{alert.dashboardUri}}?panelId={{alert.panelId}}&fullscreen&edit&tab=alert">
+                  {{alert.name}}
+                </a>
+              </div>
+              <div class="card-item-sub-name">
+                <span class="alert-list-item-state {{alert.stateModel.stateClass}}">
+                  <i class="{{alert.stateModel.iconClass}}"></i>
+                  {{alert.stateModel.text}}
+                </span> for {{alert.newStateDateAgo}}
+              </div>
+              <div class="small muted" ng-show="alert.executionError">
+                {{alert.executionError}}
+              </div>
+            </div>
+          </div>
+        </div>
+      </li>
+    </ol>
+  </section>
+
+
+  <section class="card-section card-list-layout-list" ng-if="ctrl.panel.show === 'changes'">
+    <ol class="card-list" >
+      <li class="card-item-wrapper" ng-repeat="al in ctrl.alertHistory">
+        <div class="card-item card-item--alert">
+          <div class="card-item-body">
+            <div class="card-item-details">
+              <div class="card-item-sub-name">
+                <span class="alert-list-item-state {{al.stateModel.stateClass}}">
+                  <i class="{{al.stateModel.iconClass}}"></i>
+                  {{al.stateModel.text}}
+                </span> {{al.metrics}}
+              </div>
+              <div class="card-item-sub-name">
+                {{al.time}}
+              </div>
+            </div>
+          </div>
+        </div>
+      </li>
+    </ol>
+  </section>
+</div>

+ 75 - 0
public/app/plugins/panel/alertlist/module.ts

@@ -0,0 +1,75 @@
+///<reference path="../../../headers/common.d.ts" />
+
+import _ from 'lodash';
+import moment from 'moment';
+import alertDef from '../../../features/alerting/alert_def';
+import config from 'app/core/config';
+import {PanelCtrl} from 'app/plugins/sdk';
+
+class AlertListPanel extends PanelCtrl {
+  static templateUrl = 'module.html';
+
+  showOptions = [
+    {text: 'Current state', value: 'current'},
+    {text: 'State changes', value: 'changes'},
+  ];
+
+  currentAlerts: any = [];
+  alertHistory: any = [];
+  // Set and populate defaults
+  panelDefaults = {
+    show: 'current'
+  };
+
+  /** @ngInject */
+  constructor($scope, $injector, private $location, private backendSrv) {
+    super($scope, $injector);
+    _.defaults(this.panel, this.panelDefaults);
+
+    this.events.on('init-edit-mode', this.onInitEditMode.bind(this));
+    this.events.on('render',  this.onRender.bind(this));
+    this.events.on('refresh', this.onRender.bind(this));
+  }
+
+  onRender() {
+    if (this.panel.show === 'current') {
+      this.getCurrentAlertState();
+    }
+
+    if (this.panel.show === 'changes') {
+      this.getAlertHistory();
+    }
+  }
+
+  getAlertHistory() {
+    this.backendSrv.get(`/api/alert-history?dashboardId=32&panelId=1`)
+      .then(res => {
+        this.alertHistory = _.map(res, al => {
+          al.time = moment(al.timestamp).format('MMM D, YYYY HH:mm:ss');
+          al.stateModel = alertDef.getStateDisplayModel(al.newState);
+          return al;
+        });
+      });
+  }
+
+  getCurrentAlertState() {
+    this.backendSrv.get(`/api/alerts`)
+      .then(res => {
+        this.currentAlerts = _.map(res, al => {
+          al.stateModel = alertDef.getStateDisplayModel(al.state);
+          al.newStateDateAgo = moment(al.newStateDate).fromNow().replace(" ago", "");
+
+          return al;
+        });
+      });
+  }
+
+  onInitEditMode() {
+    this.addEditorTab('Options', 'public/app/plugins/panel/alertlist/editor.html');
+  }
+}
+
+export {
+  AlertListPanel,
+  AlertListPanel as PanelCtrl
+}

+ 16 - 0
public/app/plugins/panel/alertlist/plugin.json

@@ -0,0 +1,16 @@
+{
+  "type": "panel",
+  "name": "Alert List",
+  "id": "alertlist",
+
+  "info": {
+    "author": {
+      "name": "Grafana Project",
+      "url": "http://grafana.org"
+},
+    "logos": {
+      "small": "img/icn-singlestat-panel.svg",
+      "large": "img/icn-singlestat-panel.svg"
+    }
+  }
+}