1
import React, { FC, useState, Fragment } from 'react';
2
import { Link } from 'react-router-dom';
3
import { Alert, Collapse, Table, Badge } from 'reactstrap';
4
import { RuleStatus } from './AlertContents';
5
import { Rule } from '../../types/types';
6
import { faChevronDown, faChevronRight } from '@fortawesome/free-solid-svg-icons';
7
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
8
import { createExpressionLink, parsePrometheusFloat, formatDuration } from '../../utils/index';
10
interface CollapsibleAlertPanelProps {
12
showAnnotations: boolean;
15
const alertColors: RuleStatus<string> = {
21
const CollapsibleAlertPanel: FC<CollapsibleAlertPanelProps> = ({ rule, showAnnotations }) => {
22
const [open, toggle] = useState(false);
26
<Alert fade={false} onClick={() => toggle(!open)} color={alertColors[rule.state]} style={{ cursor: 'pointer' }}>
27
<FontAwesomeIcon icon={open ? faChevronDown : faChevronRight} fixedWidth />
28
<strong>{rule.name}</strong> ({`${rule.alerts.length} active`})
30
<Collapse isOpen={open} className="mb-2">
33
<pre className="alert-cell">
36
name: <Link to={createExpressionLink(`ALERTS{alertname="${rule.name}"}`)}>{rule.name}</Link>
39
expr: <Link to={createExpressionLink(rule.query)}>{rule.query}</Link>
41
{rule.duration > 0 && (
43
<div>for: {formatDuration(rule.duration * 1000)}</div>
46
{rule.keepFiringFor > 0 && (
48
<div>keep_firing_for: {formatDuration(rule.keepFiringFor * 1000)}</div>
51
{rule.labels && Object.keys(rule.labels).length > 0 && (
54
{Object.entries(rule.labels).map(([key, value]) => (
55
<div className="ml-4" key={key}>
61
{rule.annotations && Object.keys(rule.annotations).length > 0 && (
63
<div>annotations:</div>
64
{Object.entries(rule.annotations).map(([key, value]) => (
65
<div className="ml-4" key={key}>
73
{rule.alerts.length > 0 && (
74
<Table bordered size="sm">
84
{rule.alerts.map((alert, i) => {
88
<td style={{ verticalAlign: 'middle' }}>
89
{Object.entries(alert.labels).map(([k, v], j) => {
91
<Badge key={j} color="primary" className="mr-1">
99
<Badge color={alertColors[alert.state] + ' text-uppercase'} className="px-3 mr-1">
102
{alert.keepFiringSince && (
103
<Badge color="secondary" className="px-3">
109
<td>{alert.activeAt}</td>
110
<td>{parsePrometheusFloat(alert.value)}</td>
112
{showAnnotations && <Annotations annotations={alert.annotations} />}
126
interface AnnotationsProps {
127
annotations: Record<string, string>;
130
export const Annotations: FC<AnnotationsProps> = ({ annotations }) => {
135
<h5 className="font-weight-bold">Annotations</h5>
140
{Object.entries(annotations).map(([k, v], i) => {
154
export default CollapsibleAlertPanel;