import React, { PureComponent, CSSProperties } from 'react'; import classNames from 'classnames'; import _ from 'lodash'; import moment from 'moment'; import { isNewProblem, formatLastChange } from '../../utils'; import { ProblemsPanelOptions, ZBXTrigger, TriggerSeverity, 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; panelOptions: ProblemsPanelOptions; onTagClick?: (tag: ZBXTag, datasource: string, ctrlKey?: boolean, shiftKey?: boolean) => void; onProblemAck?: (problem: ZBXTrigger, data: AckProblemData) => Promise | any; } interface AlertCardState { showAckDialog: boolean; } export default class AlertCard extends PureComponent { constructor(props) { super(props); this.state = { showAckDialog: false }; } handleTagClick = (tag: ZBXTag, ctrlKey?: boolean, shiftKey?: boolean) => { if (this.props.onTagClick) { this.props.onTagClick(tag, this.props.problem.datasource, ctrlKey, shiftKey); } } ackProblem = (data: AckProblemData) => { const problem = this.props.problem; return this.props.onProblemAck(problem, data).then(result => { this.closeAckDialog(); }).catch(err => { console.log(err); this.closeAckDialog(); }); } showAckDialog = () => { const problem = this.props.problem; if (problem.showAckButton) { this.setState({ showAckDialog: true }); } } closeAckDialog = () => { this.setState({ showAckDialog: false }); } render() { const { problem, panelOptions } = this.props; const showDatasourceName = panelOptions.targets && panelOptions.targets.length > 1; const cardClass = classNames('alert-rule-item', 'zbx-trigger-card', { 'zbx-trigger-highlighted': panelOptions.highlightBackground }); const descriptionClass = classNames('alert-rule-item__text', { 'zbx-description--newline': panelOptions.descriptionAtNewLine }); let severityDesc: TriggerSeverity; severityDesc = _.find(panelOptions.triggerSeverity, s => s.priority === Number(problem.priority)); if (problem.lastEvent?.severity) { severityDesc = _.find(panelOptions.triggerSeverity, s => s.priority === Number(problem.lastEvent.severity)); } const lastchange = formatLastChange(problem.lastchangeUnix, panelOptions.customLastChangeFormat && panelOptions.lastChangeFormat); const age = moment.unix(problem.lastchangeUnix).fromNow(true); let newProblem = false; if (panelOptions.highlightNewerThan) { newProblem = isNewProblem(problem, panelOptions.highlightNewerThan); } const blink = panelOptions.highlightNewEvents && newProblem; let problemColor: string; if (problem.value === '0') { problemColor = panelOptions.okEventColor; } else if (panelOptions.markAckEvents && problem.lastEvent?.acknowledged === "1") { problemColor = panelOptions.ackEventColor; } else { problemColor = severityDesc.color; } const cardStyle: CSSProperties = {}; if (panelOptions.highlightBackground) { cardStyle.backgroundColor = problemColor; } return (
  • {problem.description} {(panelOptions.hostField || panelOptions.hostTechNameField) && ( )} {panelOptions.hostGroups && } {panelOptions.showTags && ( {problem.tags && problem.tags.map(tag => )} )}
    {panelOptions.statusField && } {panelOptions.severityField && ( )} {panelOptions.ageField && "for " + age} {panelOptions.descriptionField && !panelOptions.descriptionAtNewLine && ( )}
    {panelOptions.descriptionField && panelOptions.descriptionAtNewLine && (
    )}
    {showDatasourceName && (
    {problem.datasource}
    )}
    {lastchange || "last change unknown"}
    {problem.url && } {problem.state === '1' && ( )} {problem.lastEvent && ( )}
  • ); } } interface AlertHostProps { problem: ZBXTrigger; panelOptions: ProblemsPanelOptions; } function AlertHost(props: AlertHostProps) { const problem = props.problem; const panel = props.panelOptions; let host = ""; if (panel.hostField && panel.hostTechNameField) { host = `${problem.host} (${problem.hostTechName})`; } else if (panel.hostField || panel.hostTechNameField) { host = panel.hostField ? problem.host : problem.hostTechName; } if (panel.hostProxy && problem.proxy) { host = `${problem.proxy}: ${host}`; } return ( {problem.maintenance && } {host} ); } interface AlertGroupProps { problem: ZBXTrigger; panelOptions: ProblemsPanelOptions; } function AlertGroup(props: AlertGroupProps) { const problem = props.problem; const panel = props.panelOptions; let groupNames = ""; if (panel.hostGroups) { const groups = _.map(problem.groups, 'name').join(', '); groupNames += `[ ${groups} ]`; } return ( {groupNames} ); } const DEFAULT_OK_COLOR = 'rgb(56, 189, 113)'; const DEFAULT_PROBLEM_COLOR = 'rgb(215, 0, 0)'; function AlertStatus(props) { const { problem, okColor, problemColor, blink } = props; const status = problem.value === '0' ? 'RESOLVED' : 'PROBLEM'; const color = problem.value === '0' ? okColor || DEFAULT_OK_COLOR : problemColor || DEFAULT_PROBLEM_COLOR; const className = classNames( 'zbx-trigger-state', { 'alert-state-critical': problem.value === '1' }, { 'alert-state-ok': problem.value === '0' }, { 'zabbix-trigger--blinked': blink } ); return ( {status} ); } function AlertSeverity(props) { const { severityDesc, highlightBackground, blink } = props; const className = classNames('zbx-trigger-severity', { 'zabbix-trigger--blinked': blink }); const style: CSSProperties = {}; if (!highlightBackground) { style.color = severityDesc.color; } return ( {severityDesc.severity} ); } interface AlertAcknowledgesButtonProps { problem: ZBXTrigger; onClick: (event?) => void; } class AlertAcknowledgesButton extends PureComponent { handleClick = (event) => { this.props.onClick(event); } renderTooltipContent = () => { return ; } render() { const { problem } = this.props; let content = null; if (problem.acknowledges && problem.acknowledges.length) { content = ( ); } else if (problem.showAckButton) { content = ( ); } return content; } }