problems: show status icon
This commit is contained in:
19
src/panel-triggers/components/GFHeartIcon.tsx
Normal file
19
src/panel-triggers/components/GFHeartIcon.tsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
interface GFHeartIconProps {
|
||||||
|
status: 'critical' | 'warning' | 'online' | 'ok' | 'problem';
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function GFHeartIcon(props: GFHeartIconProps) {
|
||||||
|
const status = props.status;
|
||||||
|
const className = classNames("icon-gf", props.className,
|
||||||
|
{ "icon-gf-critical": status === 'critical' || status === 'problem' },
|
||||||
|
{ "icon-gf-warning": status === 'warning' },
|
||||||
|
{ "icon-gf-online": status === 'online' || status === 'ok' },
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<i className={className}></i>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import { ProblemsPanelOptions, Trigger, ZBXEvent, GFTimeRange, RTCell, ZBXTag, T
|
|||||||
import EventTag from './EventTag';
|
import EventTag from './EventTag';
|
||||||
import ProblemDetails from './ProblemDetails';
|
import ProblemDetails from './ProblemDetails';
|
||||||
import { AckProblemData } from './Modal';
|
import { AckProblemData } from './Modal';
|
||||||
|
import GFHeartIcon from './GFHeartIcon';
|
||||||
|
|
||||||
export interface ProblemListProps {
|
export interface ProblemListProps {
|
||||||
problems: Trigger[];
|
problems: Trigger[];
|
||||||
@@ -84,22 +85,32 @@ export class ProblemList extends PureComponent<ProblemListProps, ProblemListStat
|
|||||||
const timeColWidth = problems && problems.length ? problems[0].lastchange.length * 9 : 160;
|
const timeColWidth = problems && problems.length ? problems[0].lastchange.length * 9 : 160;
|
||||||
const highlightNewerThan = options.highlightNewEvents && options.highlightNewerThan;
|
const highlightNewerThan = options.highlightNewEvents && options.highlightNewerThan;
|
||||||
const statusCell = props => StatusCell(props, options.okEventColor, DEFAULT_PROBLEM_COLOR, highlightNewerThan);
|
const statusCell = props => StatusCell(props, options.okEventColor, DEFAULT_PROBLEM_COLOR, highlightNewerThan);
|
||||||
|
const statusIconCell = props => StatusIconCell(props, highlightNewerThan);
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{ Header: 'Host', accessor: 'host', show: options.hostField },
|
{ Header: 'Host', accessor: 'host', show: options.hostField },
|
||||||
{ Header: 'Host (Technical Name)', accessor: 'hostTechName', show: options.hostTechNameField },
|
{ Header: 'Host (Technical Name)', accessor: 'hostTechName', show: options.hostTechNameField },
|
||||||
{ Header: 'Host Groups', accessor: 'groups', show: options.hostGroups, Cell: GroupCell },
|
{ Header: 'Host Groups', accessor: 'groups', show: options.hostGroups, Cell: GroupCell },
|
||||||
{ Header: 'Proxy', accessor: 'proxy', show: options.hostProxy },
|
{ Header: 'Proxy', accessor: 'proxy', show: options.hostProxy },
|
||||||
{ Header: 'Severity', show: options.severityField, className: 'problem-severity', width: 120,
|
{
|
||||||
|
Header: 'Severity', show: options.severityField, className: 'problem-severity', width: 120,
|
||||||
accessor: problem => problem.priority,
|
accessor: problem => problem.priority,
|
||||||
id: 'severity',
|
id: 'severity',
|
||||||
Cell: props => SeverityCell(props, options.triggerSeverity),
|
Cell: props => SeverityCell(props, options.triggerSeverity),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Header: '', id: 'statusIcon', show: options.statusIcon, className: 'problem-status-icon', width: 50,
|
||||||
|
accessor: 'value',
|
||||||
|
Cell: statusIconCell,
|
||||||
|
},
|
||||||
{ Header: 'Status', accessor: 'value', show: options.statusField, width: 100, Cell: statusCell },
|
{ Header: 'Status', accessor: 'value', show: options.statusField, width: 100, Cell: statusCell },
|
||||||
{ Header: 'Problem', accessor: 'description', minWidth: 200, Cell: ProblemCell},
|
{ Header: 'Problem', accessor: 'description', minWidth: 200, Cell: ProblemCell},
|
||||||
{ Header: 'Tags', accessor: 'tags', show: options.showTags, className: 'problem-tags',
|
{
|
||||||
|
Header: 'Tags', accessor: 'tags', show: options.showTags, className: 'problem-tags',
|
||||||
Cell: props => <TagCell {...props} onTagClick={this.handleTagClick} />
|
Cell: props => <TagCell {...props} onTagClick={this.handleTagClick} />
|
||||||
},
|
},
|
||||||
{ Header: 'Time', className: 'last-change', width: timeColWidth,
|
{
|
||||||
|
Header: 'Time', className: 'last-change', width: timeColWidth,
|
||||||
accessor: 'lastchangeUnix',
|
accessor: 'lastchangeUnix',
|
||||||
id: 'lastchange',
|
id: 'lastchange',
|
||||||
Cell: row => row.original.lastchange,
|
Cell: row => row.original.lastchange,
|
||||||
@@ -171,7 +182,6 @@ const DEFAULT_OK_COLOR = 'rgb(56, 189, 113)';
|
|||||||
const DEFAULT_PROBLEM_COLOR = 'rgb(215, 0, 0)';
|
const DEFAULT_PROBLEM_COLOR = 'rgb(215, 0, 0)';
|
||||||
|
|
||||||
function StatusCell(props: RTCell<Trigger>, okColor = DEFAULT_OK_COLOR, problemColor = DEFAULT_PROBLEM_COLOR, highlightNewerThan?: string) {
|
function StatusCell(props: RTCell<Trigger>, okColor = DEFAULT_OK_COLOR, problemColor = DEFAULT_PROBLEM_COLOR, highlightNewerThan?: string) {
|
||||||
// console.log(props);
|
|
||||||
const status = props.value === '0' ? 'RESOLVED' : 'PROBLEM';
|
const status = props.value === '0' ? 'RESOLVED' : 'PROBLEM';
|
||||||
const color = props.value === '0' ? okColor : problemColor;
|
const color = props.value === '0' ? okColor : problemColor;
|
||||||
let newProblem = false;
|
let newProblem = false;
|
||||||
@@ -183,6 +193,20 @@ function StatusCell(props: RTCell<Trigger>, okColor = DEFAULT_OK_COLOR, problemC
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function StatusIconCell(props: RTCell<Trigger>, highlightNewerThan?: string) {
|
||||||
|
const status = props.value === '0' ? 'ok' : 'problem';
|
||||||
|
let newProblem = false;
|
||||||
|
if (highlightNewerThan) {
|
||||||
|
newProblem = isNewProblem(props.original, highlightNewerThan);
|
||||||
|
}
|
||||||
|
const className = classNames('zbx-problem-status-icon',
|
||||||
|
{ 'problem-status--new': newProblem },
|
||||||
|
{ 'zbx-problem': props.value === '1' },
|
||||||
|
{ 'zbx-ok': props.value === '0' },
|
||||||
|
);
|
||||||
|
return <GFHeartIcon status={status} className={className} />;
|
||||||
|
}
|
||||||
|
|
||||||
function GroupCell(props: RTCell<Trigger>) {
|
function GroupCell(props: RTCell<Trigger>) {
|
||||||
let groups = "";
|
let groups = "";
|
||||||
if (props.value && props.value.length) {
|
if (props.value && props.value.length) {
|
||||||
|
|||||||
@@ -37,6 +37,12 @@
|
|||||||
checked="ctrl.panel.statusField"
|
checked="ctrl.panel.statusField"
|
||||||
on-change="ctrl.render()">
|
on-change="ctrl.render()">
|
||||||
</gf-form-switch>
|
</gf-form-switch>
|
||||||
|
<gf-form-switch class="gf-form"
|
||||||
|
label-class="width-9"
|
||||||
|
label="Status Icon"
|
||||||
|
checked="ctrl.panel.statusIcon"
|
||||||
|
on-change="ctrl.render()">
|
||||||
|
</gf-form-switch>
|
||||||
<gf-form-switch class="gf-form"
|
<gf-form-switch class="gf-form"
|
||||||
label-class="width-9"
|
label-class="width-9"
|
||||||
label="Severity"
|
label="Severity"
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ export const PANEL_DEFAULTS = {
|
|||||||
hostProxy: false,
|
hostProxy: false,
|
||||||
showTags: true,
|
showTags: true,
|
||||||
statusField: true,
|
statusField: true,
|
||||||
|
statusIcon: false,
|
||||||
severityField: true,
|
severityField: true,
|
||||||
descriptionField: true,
|
descriptionField: true,
|
||||||
descriptionAtNewLine: false,
|
descriptionAtNewLine: false,
|
||||||
@@ -550,6 +551,48 @@ export class TriggerPanelCtrl extends PanelCtrl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getAlertIconClass(trigger) {
|
||||||
|
let iconClass = '';
|
||||||
|
if (trigger.value === '1') {
|
||||||
|
if (trigger.priority >= 3) {
|
||||||
|
iconClass = 'icon-gf-critical';
|
||||||
|
} else {
|
||||||
|
iconClass = 'icon-gf-warning';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
iconClass = 'icon-gf-online';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.panel.highlightNewEvents && this.isNewTrigger(trigger)) {
|
||||||
|
iconClass += ' zabbix-trigger--blinked';
|
||||||
|
}
|
||||||
|
return iconClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
getAlertIconClassBySeverity(triggerSeverity) {
|
||||||
|
let iconClass = 'icon-gf-warning';
|
||||||
|
if (triggerSeverity.priority >= 3) {
|
||||||
|
iconClass = 'icon-gf-critical';
|
||||||
|
}
|
||||||
|
return iconClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
getAlertStateClass(trigger) {
|
||||||
|
let statusClass = '';
|
||||||
|
|
||||||
|
if (trigger.value === '1') {
|
||||||
|
statusClass = 'alert-state-critical';
|
||||||
|
} else {
|
||||||
|
statusClass = 'alert-state-ok';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.panel.highlightNewEvents && this.isNewTrigger(trigger)) {
|
||||||
|
statusClass += ' zabbix-trigger--blinked';
|
||||||
|
}
|
||||||
|
|
||||||
|
return statusClass;
|
||||||
|
}
|
||||||
|
|
||||||
resetResizedColumns() {
|
resetResizedColumns() {
|
||||||
this.panel.resizedColumns = [];
|
this.panel.resizedColumns = [];
|
||||||
this.render();
|
this.render();
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ export interface ProblemsPanelOptions {
|
|||||||
hostProxy?: boolean;
|
hostProxy?: boolean;
|
||||||
showTags?: boolean;
|
showTags?: boolean;
|
||||||
statusField?: boolean;
|
statusField?: boolean;
|
||||||
|
statusIcon?: boolean;
|
||||||
severityField?: boolean;
|
severityField?: boolean;
|
||||||
descriptionField?: boolean;
|
descriptionField?: boolean;
|
||||||
descriptionAtNewLine?: boolean;
|
descriptionAtNewLine?: boolean;
|
||||||
|
|||||||
@@ -66,6 +66,7 @@
|
|||||||
.rt-tr {
|
.rt-tr {
|
||||||
.rt-td {
|
.rt-td {
|
||||||
border: 0;
|
border: 0;
|
||||||
|
transition: 0s;
|
||||||
}
|
}
|
||||||
|
|
||||||
// &:hover {
|
// &:hover {
|
||||||
@@ -171,6 +172,26 @@
|
|||||||
&.last-change {
|
&.last-change {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.problem-status-icon {
|
||||||
|
padding: 0;
|
||||||
|
margin-top: 0;
|
||||||
|
font-size: 1.5em;
|
||||||
|
|
||||||
|
i {
|
||||||
|
// margin: 0 1.2em;
|
||||||
|
width: 100%;
|
||||||
|
padding-left: 0.6em;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&.zbx-problem {
|
||||||
|
color: $problem-icon-problem-color;
|
||||||
|
}
|
||||||
|
&.zbx-ok {
|
||||||
|
color: $problem-icon-ok-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.comments-icon {
|
.comments-icon {
|
||||||
|
|||||||
@@ -29,4 +29,7 @@ $problem-event-core: #000000;
|
|||||||
$problem-event-ok-color: #38bd71;
|
$problem-event-ok-color: #38bd71;
|
||||||
$problem-event-problem-color: #d70000;
|
$problem-event-problem-color: #d70000;
|
||||||
|
|
||||||
|
$problem-icon-problem-color: rgb(163, 16, 0);
|
||||||
|
$problem-icon-ok-color: #629e51;
|
||||||
|
|
||||||
$problem-container-shadow: rgba($gray-2, 0.2)
|
$problem-container-shadow: rgba($gray-2, 0.2)
|
||||||
|
|||||||
@@ -29,4 +29,7 @@ $problem-event-core: $gray-6;
|
|||||||
$problem-event-ok-color: #2baf63;
|
$problem-event-ok-color: #2baf63;
|
||||||
$problem-event-problem-color: #d70000;
|
$problem-event-problem-color: #d70000;
|
||||||
|
|
||||||
|
$problem-icon-problem-color: rgb(163, 16, 0);
|
||||||
|
$problem-icon-ok-color: #629e51;
|
||||||
|
|
||||||
$problem-container-shadow: rgba($gray-2, 0.5)
|
$problem-container-shadow: rgba($gray-2, 0.5)
|
||||||
|
|||||||
Reference in New Issue
Block a user