diff --git a/src/datasource-zabbix/zabbixAPI.service.js b/src/datasource-zabbix/zabbixAPI.service.js
index f8dd3f1..523f8a1 100644
--- a/src/datasource-zabbix/zabbixAPI.service.js
+++ b/src/datasource-zabbix/zabbixAPI.service.js
@@ -47,7 +47,6 @@ function ZabbixAPIService($q, alertSrv, zabbixAPICoreService) {
},
// Handle API errors
function(error) {
- console.log('Zabbix error: '+error.data);
if (isNotAuthorized(error.data)) {
return self.loginOnce().then(
function() {
@@ -114,12 +113,14 @@ function ZabbixAPIService($q, alertSrv, zabbixAPICoreService) {
////////////////////////////////
// Zabbix API method wrappers //
////////////////////////////////
- acknowledgeEvent(eventid,message){
+
+ acknowledgeEvent(eventid, message) {
var params = {
- eventids:eventid,
- message:message
+ eventids: eventid,
+ message: message
};
- return this.request('event.acknowledge',params);
+
+ return this.request('event.acknowledge', params);
}
getGroups() {
diff --git a/src/panel-triggers/ack-tooltip.directive.js b/src/panel-triggers/ack-tooltip.directive.js
new file mode 100644
index 0000000..3622db4
--- /dev/null
+++ b/src/panel-triggers/ack-tooltip.directive.js
@@ -0,0 +1,113 @@
+import angular from 'angular';
+import $ from 'jquery';
+import Drop from 'tether-drop';
+
+/** @ngInject */
+angular
+ .module('grafana.directives')
+ .directive('ackTooltip', function($sanitize, $compile) {
+ let buttonTemplate = '';
+
+ return {
+ scope: {
+ ack: "=",
+ trigger: "=",
+ onAck: "=",
+ context: "="
+ },
+ link: function(scope, element) {
+ let acknowledges = scope.ack;
+ let $button = $(buttonTemplate);
+ $button.appendTo(element);
+
+ $button.click(function() {
+ let tooltip = '
';
+
+ if (acknowledges && acknowledges.length) {
+ tooltip += '
' +
+ '| Time | ' +
+ 'User | ' +
+ '' +
+ '
';
+ for (let ack of acknowledges) {
+ tooltip += '| ' + ack.time + ' | ' +
+ '' + ack.user + ' | ' +
+ '' + ack.message + ' |
';
+ }
+ tooltip += '
';
+ } else {
+ tooltip += 'Add acknowledge';
+ }
+
+ let addAckButtonTemplate = '
' +
+ '
';
+ tooltip += addAckButtonTemplate;
+ tooltip += '
';
+
+ let drop = new Drop({
+ target: element[0],
+ content: tooltip,
+ position: "bottom left",
+ classes: 'drop-popover ack-tooltip',
+ openOn: 'hover',
+ hoverCloseDelay: 500,
+ tetherOptions: {
+ constraints: [{to: 'window', pin: true, attachment: "both"}]
+ }
+ });
+
+ drop.open();
+ drop.on('close', closeDrop);
+
+ $('#add-acknowledge-btn').on('click', onAddAckButtonClick);
+
+ function onAddAckButtonClick() {
+ let inputTemplate = '' +
+ '' +
+ '' +
+ '
';
+
+ let $input = $(inputTemplate);
+ let $addAckButton = $('.ack-tooltip .ack-add-button');
+ $addAckButton.replaceWith($input);
+ $('.ack-tooltip #cancel-ack-button').on('click', onAckCancelButtonClick);
+ $('.ack-tooltip #send-ack-button').on('click', onAckSendlButtonClick);
+ }
+
+ function onAckCancelButtonClick() {
+ $('.ack-tooltip .ack-input-group').replaceWith(addAckButtonTemplate);
+ $('#add-acknowledge-btn').on('click', onAddAckButtonClick);
+ }
+
+ function onAckSendlButtonClick() {
+ let message = $('.ack-tooltip #ack-message')[0].value;
+ let onAck = scope.onAck.bind(scope.context);
+ onAck(scope.trigger, message).then(() => {
+ closeDrop();
+ });
+ }
+
+ function closeDrop() {
+ setTimeout(function() {
+ drop.destroy();
+ });
+ }
+
+ });
+
+ $compile(element.contents())(scope);
+ }
+ };
+ });
diff --git a/src/panel-triggers/module.html b/src/panel-triggers/module.html
index e16046e..5c28e5f 100644
--- a/src/panel-triggers/module.html
+++ b/src/panel-triggers/module.html
@@ -31,21 +31,25 @@
+
|
{{trigger.host}}
|
+
{{ctrl.triggerStatusMap[trigger.value]}}
|
+
{{trigger.severity}}
|
+
{{trigger.description}}
@@ -68,52 +72,16 @@
{{trigger.comments}}
-
-
-
|
+
{{trigger.lastchange}}
|
+
{{trigger.age}}
|
+
@@ -130,20 +98,12 @@
-
-
-
-
-
-
-
-
+
+
|
diff --git a/src/panel-triggers/module.js b/src/panel-triggers/module.js
index 1d952c9..51718b5 100644
--- a/src/panel-triggers/module.js
+++ b/src/panel-triggers/module.js
@@ -16,6 +16,7 @@ import moment from 'moment';
import * as utils from '../datasource-zabbix/utils';
import {MetricsPanelCtrl} from 'app/plugins/sdk';
import {triggerPanelEditor} from './editor';
+import './ack-tooltip.directive';
import './css/panel_triggers.css!';
var defaultSeverity = [
@@ -59,7 +60,7 @@ var defaultTimeFormat = "DD MMM YYYY HH:mm:ss";
class TriggerPanelCtrl extends MetricsPanelCtrl {
/** @ngInject */
- constructor($scope, $injector, $q, $element, datasourceSrv, templateSrv,contextSrv) {
+ constructor($scope, $injector, $q, $element, datasourceSrv, templateSrv, contextSrv) {
super($scope, $injector);
this.datasourceSrv = datasourceSrv;
this.templateSrv = templateSrv;
@@ -123,11 +124,11 @@ class TriggerPanelCtrl extends MetricsPanelCtrl {
showEvents)
.then(triggers => {
return _.map(triggers, trigger => {
- var triggerObj = trigger;
+ let triggerObj = trigger;
// Format last change and age
trigger.lastchangeUnix = Number(trigger.lastchange);
- var timestamp = moment.unix(trigger.lastchangeUnix);
+ let timestamp = moment.unix(trigger.lastchangeUnix);
if (self.panel.customLastChangeFormat) {
// User defined format
triggerObj.lastchange = timestamp.format(self.panel.lastChangeFormat);
@@ -172,8 +173,12 @@ class TriggerPanelCtrl extends MetricsPanelCtrl {
if (event) {
trigger.acknowledges = _.map(event.acknowledges, ack => {
- var time = new Date(+ack.clock * 1000);
- ack.time = time.toLocaleString();
+ let timestamp = moment.unix(ack.clock);
+ if (self.panel.customLastChangeFormat) {
+ ack.time = timestamp.format(self.panel.lastChangeFormat);
+ } else {
+ ack.time = timestamp.format(self.defaultTimeFormat);
+ }
ack.user = ack.alias + ' (' + ack.name + ' ' + ack.surname + ')';
return ack;
});
@@ -225,41 +230,15 @@ class TriggerPanelCtrl extends MetricsPanelCtrl {
trigger.showComment = !trigger.showComment;
}
- switchAcknowledges(trigger) {
- trigger.showAcknowledges = !trigger.showAcknowledges;
- }
- addAcknowledgeMessage(trigger){
- trigger.showAcknowledges = true;
- trigger.newAct={
- time:new Date(),
- user:this.contextSrv.user.name+'(Grafana)',
- eventid:trigger.lastEvent.eventid,
- message:''
- };
- }
- acknowledgeTrigger($event,trigger,newAct){
- if($event.keyCode!=13) return;
- if(newAct.message.trim() === ""){
- delete trigger.newAct;
- trigger.showAcknowledges = false;
- return;
- }
- this.datasourceSrv.get(this.panel.datasource).then(datasource => {
- var zabbix = datasource.zabbixAPI;
- zabbix.acknowledgeEvent(newAct.eventid,newAct.user+': '+newAct.message)
- .then(rs=>{
- zabbix.getAcknowledges(rs.eventids).then(events => {
- _.each(events, event => {
- trigger.acknowledges = _.map(event.acknowledges, ack => {
- var time = new Date(+ack.clock * 1000);
- ack.time = time.toLocaleString();
- ack.user = ack.alias + ' (' + ack.name + ' ' + ack.surname + ')';
- return ack;
- });
- });
- delete trigger.newAct;
- console.log('event id '+ rs.eventids.join() + ' new message added: ' + ack.message );
- });
+ acknowledgeTrigger(trigger, message) {
+ let self = this;
+ let eventid = trigger.lastEvent.eventid;
+ let grafana_user = this.contextSrv.user.name;
+ let ack_message = grafana_user + ' (Grafana): ' + message;
+ return this.datasourceSrv.get(this.panel.datasource).then(datasource => {
+ let zabbix = datasource.zabbixAPI;
+ return zabbix.acknowledgeEvent(eventid, ack_message).then(() => {
+ self.refresh();
});
});
}
diff --git a/src/panel-triggers/sass/panel_triggers.scss b/src/panel-triggers/sass/panel_triggers.scss
index 478f7dd..156c5dc 100644
--- a/src/panel-triggers/sass/panel_triggers.scss
+++ b/src/panel-triggers/sass/panel_triggers.scss
@@ -106,3 +106,37 @@ $grafanaListAccent: lighten($dark-2, 2%);
height: 0px;
line-height: 0px;
}
+
+.ack-tooltip {
+ .drop-content {
+ // Rewrite tooltip width
+ max-width: 70rem !important;
+ min-width: 30rem !important;
+ }
+
+ .ack-comments {
+ width: 60%;
+ }
+
+ .ack-add-button {
+ padding-top: 1rem;
+ }
+
+ table td, th {
+ padding-right: 1rem;
+ }
+
+ .ack-input-group {
+ padding-top: 1rem;
+
+ input {
+ border: 1px solid;
+ border-radius: 2px;
+ width: 50%;
+ }
+
+ button {
+ margin-left: 1rem;
+ }
+ }
+}