Commit a0b9dcad by Torkel Ödegaard

alert: alerting annotation improvements, fixes #8421

parent 370db822
...@@ -41,6 +41,7 @@ func GetAnnotations(c *middleware.Context) Response { ...@@ -41,6 +41,7 @@ func GetAnnotations(c *middleware.Context) Response {
Title: item.Title, Title: item.Title,
PanelId: item.PanelId, PanelId: item.PanelId,
RegionId: item.RegionId, RegionId: item.RegionId,
Type: string(item.Type),
}) })
} }
......
...@@ -13,6 +13,7 @@ type Annotation struct { ...@@ -13,6 +13,7 @@ type Annotation struct {
Text string `json:"text"` Text string `json:"text"`
Metric string `json:"metric"` Metric string `json:"metric"`
RegionId int64 `json:"regionId"` RegionId int64 `json:"regionId"`
Type string `json:"type"`
Data *simplejson.Json `json:"data"` Data *simplejson.Json `json:"data"`
} }
......
///<reference path="../headers/common.d.ts" /> ///<reference path="../headers/common.d.ts" />
///<reference path="./mod_defs.d.ts" /> ///<reference path="./mod_defs.d.ts" />
import "./directives/annotation_tooltip";
import "./directives/dash_class"; import "./directives/dash_class";
import "./directives/confirm_click"; import "./directives/confirm_click";
import "./directives/dash_edit_link"; import "./directives/dash_edit_link";
......
...@@ -91,17 +91,9 @@ function getStateDisplayModel(state) { ...@@ -91,17 +91,9 @@ function getStateDisplayModel(state) {
stateClass: 'alert-state-warning' stateClass: 'alert-state-warning'
}; };
} }
case 'execution_error': {
return {
text: 'EXECUTION ERROR',
iconClass: 'icon-gf icon-gf-critical',
stateClass: 'alert-state-critical'
};
}
case 'paused': { case 'paused': {
return { return {
text: 'paused', text: 'PAUSED',
iconClass: "fa fa-pause", iconClass: "fa fa-pause",
stateClass: 'alert-state-paused' stateClass: 'alert-state-paused'
}; };
......
...@@ -3,10 +3,12 @@ import {AnnotationsSrv} from './annotations_srv'; ...@@ -3,10 +3,12 @@ import {AnnotationsSrv} from './annotations_srv';
import {eventEditor} from './event_editor'; import {eventEditor} from './event_editor';
import {EventManager} from './event_manager'; import {EventManager} from './event_manager';
import {AnnotationEvent} from './event'; import {AnnotationEvent} from './event';
import {annotationTooltipDirective} from './annotation_tooltip';
export { export {
AnnotationsSrv, AnnotationsSrv,
eventEditor, eventEditor,
EventManager, EventManager,
AnnotationEvent, AnnotationEvent,
annotationTooltipDirective,
}; };
define([ ///<reference path="../../headers/common.d.ts" />
'jquery',
'lodash', import angular from 'angular';
'../core_module', import _ from 'lodash';
], import $ from 'jquery';
function ($, _, coreModule) { import coreModule from 'app/core/core_module';
'use strict'; import alertDef from '../alerting/alert_def';
coreModule.default.directive('annotationTooltip', function($sanitize, dashboardSrv, $compile) { /** @ngInject **/
export function annotationTooltipDirective($sanitize, dashboardSrv, $compile) {
function sanitizeString(str) {
try { function sanitizeString(str) {
return $sanitize(str); try {
} return $sanitize(str);
catch(err) { } catch (err) {
console.log('Could not sanitize annotation string, html escaping instead'); console.log('Could not sanitize annotation string, html escaping instead');
return _.escape(str); return _.escape(str);
}
} }
}
return { return {
link: function (scope, element) { restrict: 'E',
var event = scope.event; scope: {
var title = sanitizeString(event.title); "event": "=",
var dashboard = dashboardSrv.getCurrent(); },
var time = '<i>' + dashboard.formatDate(event.min) + '</i>'; link: function(scope, element) {
var event = scope.event;
var title = event.title;
var text = event.text;
var dashboard = dashboardSrv.getCurrent();
var tooltip = '<div class="graph-annotation">'; var tooltip = '<div class="graph-annotation">';
tooltip += '<div class="graph-annotation-title">' + title + "</div>"; var titleStateClass = '';
if (event.text) { if (event.source.name === 'panel-alert') {
var text = sanitizeString(event.text); var stateModel = alertDef.getStateDisplayModel(event.newState);
tooltip += text.replace(/\n/g, '<br>') + '<br>'; titleStateClass = stateModel.stateClass;
} title = `<i class="icon-gf ${stateModel.iconClass}"></i> ${stateModel.text}`;
text = alertDef.getAlertAnnotationInfo(event);
}
var tags = event.tags; tooltip += `
if (_.isString(event.tags)) { <div class="graph-annotation-header">
tags = event.tags.split(','); <span class="graph-annotation-title ${titleStateClass}">${sanitizeString(title)}</span>
if (tags.length === 1) { <span class="graph-annotation-time">${dashboard.formatDate(event.min)}</span>
tags = event.tags.split(' '); </div>
} `;
}
if (tags && tags.length) { tooltip += '<div class="graph-annotation-body">';
scope.tags = tags;
tooltip += '<span class="label label-tag small" ng-repeat="tag in tags" tag-color-from-name="tag">{{tag}}</span><br/>';
}
tooltip += '<div class="graph-annotation-time">' + time + '</div>' ; if (text) {
tooltip += "</div>"; tooltip += sanitizeString(text).replace(/\n/g, '<br>') + '<br>';
}
var $tooltip = $(tooltip); var tags = event.tags;
$tooltip.appendTo(element); if (_.isString(event.tags)) {
tags = event.tags.split(',');
if (tags.length === 1) {
tags = event.tags.split(' ');
}
}
$compile(element.contents())(scope); if (tags && tags.length) {
scope.tags = tags;
tooltip += '<span class="label label-tag small" ng-repeat="tag in tags" tag-color-from-name="tag">{{tag}}</span><br/>';
} }
};
});
}); tooltip += "</div>";
var $tooltip = $(tooltip);
$tooltip.appendTo(element);
$compile(element.contents())(scope);
}
};
}
coreModule.directive('annotationTooltip', annotationTooltipDirective);
...@@ -73,6 +73,8 @@ export class AnnotationsSrv { ...@@ -73,6 +73,8 @@ export class AnnotationsSrv {
panelId: panel.id, panelId: panel.id,
dashboardId: dashboard.id, dashboardId: dashboard.id,
}).then(results => { }).then(results => {
// this built in annotation source name `panel-alert` is used in annotation tooltip
// to know that this annotation is from panel alert
return this.translateQueryResult({iconColor: '#AA0000', name: 'panel-alert'}, results); return this.translateQueryResult({iconColor: '#AA0000', name: 'panel-alert'}, results);
}); });
} }
......
...@@ -10,7 +10,7 @@ function ($, _, angular, Drop) { ...@@ -10,7 +10,7 @@ function ($, _, angular, Drop) {
function createAnnotationToolip(element, event) { function createAnnotationToolip(element, event) {
var injector = angular.element(document).injector(); var injector = angular.element(document).injector();
var content = document.createElement('div'); var content = document.createElement('div');
content.innerHTML = '<annotation-tooltip></annotation-tooltip>'; content.innerHTML = '<annotation-tooltip event="event"></annotation-tooltip>';
injector.invoke(["$compile", "$rootScope", function($compile, $rootScope) { injector.invoke(["$compile", "$rootScope", function($compile, $rootScope) {
var tmpScope = $rootScope.$new(true); var tmpScope = $rootScope.$new(true);
...@@ -24,7 +24,7 @@ function ($, _, angular, Drop) { ...@@ -24,7 +24,7 @@ function ($, _, angular, Drop) {
target: element[0], target: element[0],
content: content, content: content,
position: "bottom center", position: "bottom center",
classes: 'drop-popover', classes: 'drop-popover drop-popover--annotation',
openOn: 'hover', openOn: 'hover',
hoverCloseDelay: 200, hoverCloseDelay: 200,
tetherOptions: { tetherOptions: {
......
...@@ -56,3 +56,9 @@ $easing: cubic-bezier(0, 0, 0.265, 1.00); ...@@ -56,3 +56,9 @@ $easing: cubic-bezier(0, 0, 0.265, 1.00);
max-width: none; max-width: none;
} }
} }
.drop-element.drop-popover--annotation {
.drop-content {
padding: 0;
}
}
...@@ -287,10 +287,29 @@ ...@@ -287,10 +287,29 @@
margin-top: 8px; margin-top: 8px;
} }
.graph-annotation-header {
background-color: $input-label-bg;
padding: 0.40rem 0.65rem;
}
.graph-annotation-title { .graph-annotation-title {
font-weight: $font-weight-semi-bold; font-weight: $font-weight-semi-bold;
padding-right: $spacer;
position: relative;
top: 2px;
}
.graph-annotation-time {
color: $text-muted;
font-style: italic;
font-weight: normal;
display: inline-block;
position: relative; position: relative;
top: -0.4rem; top: 1px;
}
.graph-annotation-body {
padding: 0.65rem;
} }
a { a {
...@@ -298,11 +317,6 @@ ...@@ -298,11 +317,6 @@
text-decoration: underline; text-decoration: underline;
} }
.graph-annotation-time {
position: relative;
text-align: center;
top: 0.6rem;
}
} }
.left-yaxis-label { .left-yaxis-label {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment