problems: refactor

This commit is contained in:
Alexander Zobnin
2019-02-11 14:26:39 +03:00
parent 12ccba0187
commit 410de2dc6b
6 changed files with 87 additions and 295 deletions

View File

@@ -1,118 +0,0 @@
import $ from 'jquery';
import angular from 'angular';
import Drop from 'tether-drop';
angular
.module('grafana.directives')
.directive('ackTooltip',
/** @ngInject */
function($sanitize, $compile) {
let buttonTemplate = '<a bs-tooltip="\'Acknowledges ({{trigger.acknowledges.length}})\'"' +
'<i ng-class="' +
"{'fa fa-comments': trigger.acknowledges.length, " +
"'fa fa-comments-o': !trigger.acknowledges.length, " +
'}"></i></a>';
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 = '<div>';
if (acknowledges && acknowledges.length) {
tooltip += '<table class="table"><thead><tr>' +
'<th class="ack-time">Time</th>' +
'<th class="ack-user">User</th>' +
'<th class="ack-comments">Comments</th>' +
'</tr></thead><tbody>';
for (let ack of acknowledges) {
tooltip += '<tr><td>' + ack.time + '</td>' +
'<td>' + ack.user + '</td>' +
'<td>' + ack.message + '</td></tr>';
}
tooltip += '</tbody></table>';
} else {
tooltip += 'Add acknowledge';
}
let addAckButtonTemplate = '<div class="ack-add-button">' +
'<button id="add-acknowledge-btn"' +
'class="btn btn-mini btn-inverse gf-form-button">' +
'<i class="fa fa-plus"></i>' +
'</button></div>';
tooltip += addAckButtonTemplate;
tooltip += '</div>';
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 = '<div class="ack-input-group">' +
'<input type="text" id="ack-message">' +
'<button id="send-ack-button"' +
'class="btn btn-mini btn-inverse gf-form-button">' +
'Acknowledge </button>' +
'<button id="cancel-ack-button"' +
'class="btn btn-mini btn-inverse gf-form-button">' +
'Cancel' +
'</button></input></div>';
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() {
try {
drop.destroy();
} catch (err) {
console.log('drop.destroy() error: ', err.message);
}
});
}
});
$compile(element.contents())(scope);
}
};
});

View File

@@ -0,0 +1,47 @@
import React, { PureComponent } from 'react';
import { ZBXTrigger } from 'panel-triggers/types';
interface AlertAcknowledgesProps {
problem: ZBXTrigger;
onClick: (event?) => void;
}
export default class AlertAcknowledges extends PureComponent<AlertAcknowledgesProps> {
handleClick = (event) => {
this.props.onClick(event);
}
render() {
const { problem } = this.props;
const ackRows = problem.acknowledges && problem.acknowledges.map(ack => {
return (
<tr key={ack.acknowledgeid}>
<td>{ack.time}</td>
<td>{ack.user}</td>
<td>{ack.message}</td>
</tr>
);
});
return (
<div className="ack-tooltip">
<table className="table">
<thead>
<tr>
<th className="ack-time">Time</th>
<th className="ack-user">User</th>
<th className="ack-comments">Comments</th>
</tr>
</thead>
<tbody>
{ackRows}
</tbody>
</table>
<div className="ack-add-button">
<button id="add-acknowledge-btn" className="btn btn-mini btn-inverse gf-form-button" onClick={this.handleClick}>
<i className="fa fa-plus"></i>
</button>
</div>
</div>
);
}
}

View File

@@ -7,6 +7,8 @@ import { ProblemsPanelOptions, ZBXTrigger, ZBXTag } from '../../types';
import { AckProblemData, Modal } from '.././Modal';
import EventTag from '../EventTag';
import Tooltip from '.././Tooltip/Tooltip';
import AlertAcknowledges from './AlertAcknowledges';
import AlertIcon from './AlertIcon';
interface AlertCardProps {
problem: ZBXTrigger;
@@ -153,40 +155,6 @@ export default class AlertCard extends PureComponent<AlertCardProps, AlertCardSt
}
}
interface AlertIconProps {
problem: ZBXTrigger;
color: string;
blink?: boolean;
highlightBackground?: boolean;
}
function AlertIcon(props: AlertIconProps) {
const { problem, color, blink, highlightBackground } = props;
const priority = Number(problem.priority);
let iconClass = '';
if (problem.value === '1') {
if (priority >= 3) {
iconClass = 'icon-gf-critical';
} else {
iconClass = 'icon-gf-warning';
}
} else {
iconClass = 'icon-gf-online';
}
const className = classNames('icon-gf', iconClass, { 'zabbix-trigger--blinked': blink });
const style: CSSProperties = {};
if (!highlightBackground) {
style.color = color;
}
return (
<div className="alert-rule-item__icon" style={style}>
<i className={className}></i>
</div>
);
}
interface AlertHostProps {
problem: ZBXTrigger;
panelOptions: ProblemsPanelOptions;
@@ -293,48 +261,3 @@ class AlertAcknowledgesButton extends PureComponent<AlertAcknowledgesButtonProps
);
}
}
interface AlertAcknowledgesProps {
problem: ZBXTrigger;
onClick: (event?) => void;
}
class AlertAcknowledges extends PureComponent<AlertAcknowledgesProps> {
handleClick = (event) => {
this.props.onClick(event);
}
render() {
const { problem } = this.props;
const ackRows = problem.acknowledges && problem.acknowledges.map(ack => {
return (
<tr key={ack.acknowledgeid}>
<td>{ack.time}</td>
<td>{ack.user}</td>
<td>{ack.message}</td>
</tr>
);
});
return (
<div className="ack-tooltip">
<table className="table">
<thead>
<tr>
<th className="ack-time">Time</th>
<th className="ack-user">User</th>
<th className="ack-comments">Comments</th>
</tr>
</thead>
<tbody>
{ackRows}
</tbody>
</table>
<div className="ack-add-button">
<button id="add-acknowledge-btn" className="btn btn-mini btn-inverse gf-form-button" onClick={this.handleClick}>
<i className="fa fa-plus"></i>
</button>
</div>
</div>
);
}
}

View File

@@ -0,0 +1,37 @@
import React, { CSSProperties } from 'react';
import classNames from 'classnames';
import { ZBXTrigger } from 'panel-triggers/types';
interface AlertIconProps {
problem: ZBXTrigger;
color: string;
blink?: boolean;
highlightBackground?: boolean;
}
export default function AlertIcon(props: AlertIconProps) {
const { problem, color, blink, highlightBackground } = props;
const priority = Number(problem.priority);
let iconClass = '';
if (problem.value === '1') {
if (priority >= 3) {
iconClass = 'icon-gf-critical';
} else {
iconClass = 'icon-gf-warning';
}
} else {
iconClass = 'icon-gf-online';
}
const className = classNames('icon-gf', iconClass, { 'zabbix-trigger--blinked': blink });
const style: CSSProperties = {};
if (!highlightBackground) {
style.color = color;
}
return (
<div className="alert-rule-item__icon" style={style}>
<i className={className}></i>
</div>
);
}

View File

@@ -14,7 +14,6 @@
import {TriggerPanelCtrl} from './triggers_panel_ctrl';
import {loadPluginCss} from 'grafana/app/plugins/sdk';
import './datasource-selector.directive';
import './ack-tooltip.directive';
loadPluginCss({
dark: 'plugins/alexanderzobnin-zabbix-app/css/grafana-zabbix.dark.css',

View File

@@ -1,97 +1 @@
<div class="triggers-panel-container">
<div class="triggers-panel-scroll">
<section class="card-section card-list-layout-list">
<ol class="alert-rule-list">
<!-- Trigger list item -->
<li class="alert-rule-item zbx-trigger-card" ng-repeat="trigger in ctrl.currentTriggersPage"
ng-class="{'zbx-trigger-highlighted': ctrl.panel.highlightBackground}"
ng-style="ctrl.panel.highlightBackground && {background: ctrl.getBackground(trigger)}">
<!-- Heart icon -->
<div class="alert-rule-item__icon" ng-style="!ctrl.panel.highlightBackground && {color: trigger.color}">
<i class="icon-gf" ng-class="ctrl.getAlertIconClass(trigger)"></i>
</div>
<div class="alert-rule-item__body">
<div class="alert-rule-item__header">
<p class="alert-rule-item__name">
<span class="zabbix-trigger-name">{{trigger.description}}</span>
<span class="zabbix-hostname" ng-if="ctrl.panel.hostField || ctrl.panel.hostTechNameField">
<i ng-if="trigger.maintenance" class="fa fa-wrench zbx-maintenance-icon"></i>
{{ ctrl.formatHostName(trigger) }}
</span>
<span class="zabbix-hostname" ng-if="ctrl.panel.hostGroups">
{{ ctrl.formatHostGroups(trigger) }}
</span>
<span class="zbx-trigger-tags" ng-if="ctrl.panel.showTags && trigger.tags">
<span ng-repeat="tag in trigger.tags" ng-click="ctrl.addTagFilter(tag, trigger.datasource)"
tag-color-from-name="tag.tag+tag.value" class="label label-tag zbx-tag">
{{tag.tag}}: {{tag.value}}
</span>
</span>
</p>
<div class="alert-rule-item__text">
<span ng-if="ctrl.panel.statusField" class="zbx-trigger-state"
ng-class="ctrl.getAlertStateClass(trigger)">
{{ctrl.triggerStatusMap[trigger.value]}}
</span>
<span ng-if="ctrl.panel.severityField" class="zbx-trigger-severity"
ng-class="ctrl.getAlertStateClass(trigger)"
ng-style="!ctrl.panel.highlightBackground && {color: trigger.color}">
{{trigger.severity}}
</span>
<span class="alert-rule-item__time">
{{trigger.age && "for " + trigger.age}}
</span>
<span class="zbx-description"
ng-if="ctrl.panel.descriptionField && !ctrl.panel.descriptionAtNewLine"
ng-bind-html="trigger.comments">
</span>
</div>
<!-- If description at the new line -->
<div class="alert-rule-item__text"
ng-if="trigger.comments && ctrl.panel.descriptionField && ctrl.panel.descriptionAtNewLine">
<span class="alert-rule-item__info zbx-description zbx-description--newline"
ng-bind-html="trigger.comments">
</span>
</div>
</div>
</div>
<!-- Datasource name -->
<div class="alert-rule-item__time zabbix-trigger-source" ng-if="ctrl.panel.datasources.length > 1">
<span>
<i class="fa fa-database"></i>
{{trigger.datasource}}
</span>
</div>
<div class="alert-rule-item__time zbx-trigger-lastchange">
<span>{{trigger.lastchange || "last change unknown"}}</span>
<div class="trigger-info-block zbx-status-icons">
<a ng-if="trigger.url" href="{{trigger.url}}" target="_blank">
<i class="fa fa-external-link"></i>
</a>
<span ng-if="trigger.state === '1'" bs-tooltip="'{{trigger.error}}'">
<i class="fa fa-question-circle"></i>
</span>
<ack-tooltip ng-if="trigger.lastEvent" ack="trigger.acknowledges" trigger="trigger"
on-ack="ctrl.acknowledgeTrigger" context="ctrl">
</ack-tooltip>
</div>
</div>
</li>
</ol>
</section>
</div>
</div>
<div class="triggers-panel-footer"></div>
<div class="triggers-panel-container"></div>