diff --git a/pkg/api/annotations.go b/pkg/api/annotations.go index a5211cfbec2..e07c77f1c1d 100644 --- a/pkg/api/annotations.go +++ b/pkg/api/annotations.go @@ -41,6 +41,7 @@ func GetAnnotations(c *middleware.Context) Response { Title: item.Title, PanelId: item.PanelId, RegionId: item.RegionId, + Type: string(item.Type), }) } diff --git a/pkg/api/dtos/annotations.go b/pkg/api/dtos/annotations.go index 7bf33618261..958fdff89ca 100644 --- a/pkg/api/dtos/annotations.go +++ b/pkg/api/dtos/annotations.go @@ -13,6 +13,7 @@ type Annotation struct { Text string `json:"text"` Metric string `json:"metric"` RegionId int64 `json:"regionId"` + Type string `json:"type"` Data *simplejson.Json `json:"data"` } diff --git a/public/app/core/core.ts b/public/app/core/core.ts index 4aa2e7eb64a..a3ddf38a3e3 100644 --- a/public/app/core/core.ts +++ b/public/app/core/core.ts @@ -1,7 +1,6 @@ /// /// -import "./directives/annotation_tooltip"; import "./directives/dash_class"; import "./directives/confirm_click"; import "./directives/dash_edit_link"; diff --git a/public/app/core/directives/annotation_tooltip.js b/public/app/core/directives/annotation_tooltip.js deleted file mode 100644 index 2d51c6b3494..00000000000 --- a/public/app/core/directives/annotation_tooltip.js +++ /dev/null @@ -1,60 +0,0 @@ -define([ - 'jquery', - 'lodash', - '../core_module', -], -function ($, _, coreModule) { - 'use strict'; - - coreModule.default.directive('annotationTooltip', function($sanitize, dashboardSrv, $compile) { - - function sanitizeString(str) { - try { - return $sanitize(str); - } - catch(err) { - console.log('Could not sanitize annotation string, html escaping instead'); - return _.escape(str); - } - } - - return { - link: function (scope, element) { - var event = scope.event; - var title = sanitizeString(event.title); - var dashboard = dashboardSrv.getCurrent(); - var time = '' + dashboard.formatDate(event.min) + ''; - - var tooltip = '
'; - tooltip += '
' + title + "
"; - - if (event.text) { - var text = sanitizeString(event.text); - tooltip += text.replace(/\n/g, '
') + '
'; - } - - var tags = event.tags; - if (_.isString(event.tags)) { - tags = event.tags.split(','); - if (tags.length === 1) { - tags = event.tags.split(' '); - } - } - - if (tags && tags.length) { - scope.tags = tags; - tooltip += '{{tag}}
'; - } - - tooltip += '
' + time + '
' ; - tooltip += "
"; - - var $tooltip = $(tooltip); - $tooltip.appendTo(element); - - $compile(element.contents())(scope); - } - }; - }); - -}); diff --git a/public/app/features/alerting/alert_def.ts b/public/app/features/alerting/alert_def.ts index dc5be8b41c4..d80c299ec6d 100644 --- a/public/app/features/alerting/alert_def.ts +++ b/public/app/features/alerting/alert_def.ts @@ -91,17 +91,9 @@ function getStateDisplayModel(state) { stateClass: 'alert-state-warning' }; } - case 'execution_error': { - return { - text: 'EXECUTION ERROR', - iconClass: 'icon-gf icon-gf-critical', - stateClass: 'alert-state-critical' - }; - } - case 'paused': { return { - text: 'paused', + text: 'PAUSED', iconClass: "fa fa-pause", stateClass: 'alert-state-paused' }; diff --git a/public/app/features/annotations/all.ts b/public/app/features/annotations/all.ts index 5f195928c7a..d4ef8bb41ed 100644 --- a/public/app/features/annotations/all.ts +++ b/public/app/features/annotations/all.ts @@ -3,10 +3,12 @@ import {AnnotationsSrv} from './annotations_srv'; import {eventEditor} from './event_editor'; import {EventManager} from './event_manager'; import {AnnotationEvent} from './event'; +import {annotationTooltipDirective} from './annotation_tooltip'; export { AnnotationsSrv, eventEditor, EventManager, AnnotationEvent, + annotationTooltipDirective, }; diff --git a/public/app/features/annotations/annotation_tooltip.ts b/public/app/features/annotations/annotation_tooltip.ts new file mode 100644 index 00000000000..50341286156 --- /dev/null +++ b/public/app/features/annotations/annotation_tooltip.ts @@ -0,0 +1,80 @@ +/// + +import angular from 'angular'; +import _ from 'lodash'; +import $ from 'jquery'; +import coreModule from 'app/core/core_module'; +import alertDef from '../alerting/alert_def'; + +/** @ngInject **/ +export function annotationTooltipDirective($sanitize, dashboardSrv, $compile) { + + function sanitizeString(str) { + try { + return $sanitize(str); + } catch (err) { + console.log('Could not sanitize annotation string, html escaping instead'); + return _.escape(str); + } + } + + return { + restrict: 'E', + scope: { + "event": "=", + }, + link: function(scope, element) { + var event = scope.event; + var title = event.title; + var text = event.text; + var dashboard = dashboardSrv.getCurrent(); + + var tooltip = '
'; + var titleStateClass = ''; + + if (event.source.name === 'panel-alert') { + var stateModel = alertDef.getStateDisplayModel(event.newState); + titleStateClass = stateModel.stateClass; + title = ` ${stateModel.text}`; + text = alertDef.getAlertAnnotationInfo(event); + } + + tooltip += ` +
+ ${sanitizeString(title)} + ${dashboard.formatDate(event.min)} +
+ `; + + tooltip += '
'; + + if (text) { + tooltip += sanitizeString(text).replace(/\n/g, '
') + '
'; + } + + var tags = event.tags; + if (_.isString(event.tags)) { + tags = event.tags.split(','); + if (tags.length === 1) { + tags = event.tags.split(' '); + } + } + + if (tags && tags.length) { + scope.tags = tags; + tooltip += '{{tag}}
'; + } + + tooltip += "
"; + + var $tooltip = $(tooltip); + $tooltip.appendTo(element); + + $compile(element.contents())(scope); + } + }; +} + + + +coreModule.directive('annotationTooltip', annotationTooltipDirective); diff --git a/public/app/features/annotations/annotations_srv.ts b/public/app/features/annotations/annotations_srv.ts index 873b3967616..a32ba7e72ad 100644 --- a/public/app/features/annotations/annotations_srv.ts +++ b/public/app/features/annotations/annotations_srv.ts @@ -73,6 +73,8 @@ export class AnnotationsSrv { panelId: panel.id, dashboardId: dashboard.id, }).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); }); } diff --git a/public/app/plugins/panel/graph/jquery.flot.events.js b/public/app/plugins/panel/graph/jquery.flot.events.js index b6091976849..3fc3db0d6d3 100644 --- a/public/app/plugins/panel/graph/jquery.flot.events.js +++ b/public/app/plugins/panel/graph/jquery.flot.events.js @@ -10,7 +10,7 @@ function ($, _, angular, Drop) { function createAnnotationToolip(element, event) { var injector = angular.element(document).injector(); var content = document.createElement('div'); - content.innerHTML = ''; + content.innerHTML = ''; injector.invoke(["$compile", "$rootScope", function($compile, $rootScope) { var tmpScope = $rootScope.$new(true); @@ -24,7 +24,7 @@ function ($, _, angular, Drop) { target: element[0], content: content, position: "bottom center", - classes: 'drop-popover', + classes: 'drop-popover drop-popover--annotation', openOn: 'hover', hoverCloseDelay: 200, tetherOptions: { diff --git a/public/sass/components/_drop.scss b/public/sass/components/_drop.scss index 6ed94c560a0..ae8ad806351 100644 --- a/public/sass/components/_drop.scss +++ b/public/sass/components/_drop.scss @@ -56,3 +56,9 @@ $easing: cubic-bezier(0, 0, 0.265, 1.00); max-width: none; } } + +.drop-element.drop-popover--annotation { + .drop-content { + padding: 0; + } +} diff --git a/public/sass/components/_panel_graph.scss b/public/sass/components/_panel_graph.scss index 11783692104..1283ea7c953 100644 --- a/public/sass/components/_panel_graph.scss +++ b/public/sass/components/_panel_graph.scss @@ -287,10 +287,29 @@ margin-top: 8px; } + .graph-annotation-header { + background-color: $input-label-bg; + padding: 0.40rem 0.65rem; + } + .graph-annotation-title { font-weight: $font-weight-semi-bold; + padding-right: $spacer; position: relative; - top: -0.4rem; + top: 2px; + } + + .graph-annotation-time { + color: $text-muted; + font-style: italic; + font-weight: normal; + display: inline-block; + position: relative; + top: 1px; + } + + .graph-annotation-body { + padding: 0.65rem; } a { @@ -298,11 +317,6 @@ text-decoration: underline; } - .graph-annotation-time { - position: relative; - text-align: center; - top: 0.6rem; - } } .left-yaxis-label {