import React, { PureComponent } from 'react'; import ReactTable from 'react-table'; import * as utils from '../../datasource-zabbix/utils'; import { ProblemsPanelOptions, Trigger, ZBXEvent, GFTimeRange, RTCell } from '../types'; import EventTag from './EventTag'; import ProblemDetails from './ProblemDetails'; import { AckProblemData } from './Modal'; export interface ProblemListProps { problems: Trigger[]; panelOptions: ProblemsPanelOptions; loading?: boolean; timeRange?: GFTimeRange; getProblemEvents: (ids: string[]) => ZBXEvent[]; onProblemAck: (problem: Trigger, data: AckProblemData) => void; } interface ProblemListState { expanded: any; page: number; } export class ProblemList extends PureComponent { rootWidth: number; rootRef: any; constructor(props) { super(props); this.state = { expanded: {}, page: 0, }; } setRootRef = ref => { this.rootRef = ref; } handleProblemAck = (problem: Trigger, data: AckProblemData) => { return this.props.onProblemAck(problem, data); } buildColumns() { const result = []; const options = this.props.panelOptions; const problems = this.props.problems; const timeColWidth = problems && problems.length ? problems[0].lastchange.length * 9 : 160; const highlightNewerThan = options.highlightNewEvents && options.highlightNewerThan; const statusCell = props => StatusCell(props, options.okEventColor, DEFAULT_PROBLEM_COLOR, highlightNewerThan); const columns = [ { Header: 'Host', accessor: 'host', show: options.hostField }, { Header: 'Host (Technical Name)', accessor: 'hostTechName', show: options.hostTechNameField }, { Header: 'Host Groups', accessor: 'groups', show: options.hostGroups, Cell: GroupCell }, { Header: 'Proxy', accessor: 'proxy', show: options.hostProxy }, { Header: 'Severity', show: options.severityField, className: 'problem-severity', width: 120, accessor: problem => problem.priority, id: 'severity', Cell: SeverityCell, }, { Header: 'Status', accessor: 'value', show: options.statusField, width: 100, Cell: statusCell }, { Header: 'Problem', accessor: 'description', minWidth: 200, Cell: ProblemCell}, { Header: 'Tags', accessor: 'tags', show: options.showTags, className: 'problem-tags', Cell: TagCell }, { Header: 'Time', className: 'last-change', width: timeColWidth, accessor: 'lastchangeUnix', id: 'lastchange', Cell: row => row.original.lastchange, }, { Header: 'Details', className: 'custom-expander', width: 60, expander: true, Expander: CustomExpander }, ]; for (const column of columns) { if (column.show || column.show === undefined) { delete column.show; result.push(column); } } return result; } getExpandedPage = (page: number) => { return this.state.expanded[page] || {}; } handleExpandedChange = expanded => { const nextExpanded = {...this.state.expanded}; nextExpanded[this.state.page] = expanded; this.setState({ expanded: nextExpanded }); } render() { // console.log(this.props.problems); const columns = this.buildColumns(); this.rootWidth = this.rootRef && this.rootRef.clientWidth; return (
} expanded={this.getExpandedPage(this.state.page)} onExpandedChange={this.handleExpandedChange} onPageChange={page => this.setState({ page })} />
); } } function SeverityCell(props: RTCell) { return (
{props.original.severity}
); } const DEFAULT_OK_COLOR = 'rgb(56, 189, 113)'; const DEFAULT_PROBLEM_COLOR = 'rgb(215, 0, 0)'; function StatusCell(props: RTCell, okColor = DEFAULT_OK_COLOR, problemColor = DEFAULT_PROBLEM_COLOR, highlightNewerThan?: string) { // console.log(props); const status = props.value === '0' ? 'RESOLVED' : 'PROBLEM'; const color = props.value === '0' ? okColor : problemColor; let newProblem = false; if (highlightNewerThan) { newProblem = isNewProblem(props.original, highlightNewerThan); } return ( {status} ); } function GroupCell(props: RTCell) { let groups = ""; if (props.value && props.value.length) { groups = props.value.map(g => g.name).join(', '); } return ( {groups} ); } function ProblemCell(props: RTCell) { const comments = props.original.comments; return (
{props.value} {/* {comments && } */}
); } function TagCell(props: RTCell) { const tags = props.value || []; return [ tags.map(tag => ) ]; } function CustomExpander(props: RTCell) { return ( ); } function isNewProblem(problem: Trigger, highlightNewerThan: string): boolean { try { const highlightIntervalMs = utils.parseInterval(highlightNewerThan); const durationSec = (Date.now() - problem.lastchangeUnix * 1000); return durationSec < highlightIntervalMs; } catch (e) { return false; } }