import React, { ChangeEvent, FC, Fragment, useEffect, useState } from 'react'; import { Badge, Col, Row } from 'reactstrap'; import CollapsibleAlertPanel from './CollapsibleAlertPanel'; import Checkbox from '../../components/Checkbox'; import { isPresent } from '../../utils'; import { Rule } from '../../types/types'; import { useLocalStorage } from '../../hooks/useLocalStorage'; import CustomInfiniteScroll, { InfiniteScrollItemsProps } from '../../components/CustomInfiniteScroll'; import { KVSearch } from '@nexucis/kvsearch'; import SearchBar from '../../components/SearchBar'; // eslint-disable-next-line @typescript-eslint/no-explicit-any export type RuleState = keyof RuleStatus; export interface RuleStatus { firing: T; pending: T; inactive: T; } export interface AlertsProps { groups?: RuleGroup[]; statsCount: RuleStatus; } export interface Alert { labels: Record; state: RuleState; value: string; annotations: Record; activeAt: string; } interface RuleGroup { name: string; file: string; rules: Rule[]; interval: number; } const kvSearchRule = new KVSearch({ shouldSort: true, indexedKeys: ['name', 'labels', ['labels', /.*/]], }); const stateColorTuples: Array<[RuleState, 'success' | 'warning' | 'danger']> = [ ['inactive', 'success'], ['pending', 'warning'], ['firing', 'danger'], ]; function GroupContent(showAnnotations: boolean) { const Content: FC> = ({ items }) => { return ( <> {items.map((rule, j) => ( ))} ); }; return Content; } const AlertsContent: FC = ({ groups = [], statsCount }) => { const [groupList, setGroupList] = useState(groups); const [filteredList, setFilteredList] = useState(groups); const [filter, setFilter] = useLocalStorage('alerts-status-filter', { firing: true, pending: true, inactive: true, }); const [showAnnotations, setShowAnnotations] = useLocalStorage('alerts-annotations-status', { checked: false }); const toggleFilter = (ruleState: RuleState) => () => { setFilter({ ...filter, [ruleState]: !filter[ruleState], }); }; const handleSearchChange = (e: ChangeEvent) => { if (e.target.value !== '') { const pattern = e.target.value.trim(); const result: RuleGroup[] = []; for (const group of groups) { const ruleFilterList = kvSearchRule.filter(pattern, group.rules); if (ruleFilterList.length > 0) { result.push({ file: group.file, name: group.name, interval: group.interval, rules: ruleFilterList.map((value) => value.original as unknown as Rule), }); } } setGroupList(result); } else { setGroupList(groups); } }; useEffect(() => { const result: RuleGroup[] = []; for (const group of groupList) { const newGroup = { file: group.file, name: group.name, interval: group.interval, rules: group.rules.filter((value) => filter[value.state]), }; if (newGroup.rules.length > 0) { result.push(newGroup); } } setFilteredList(result); }, [groupList, filter]); return ( <> {stateColorTuples.map(([state, color]) => { return ( {state} ({statsCount[state]}) ); })} setShowAnnotations({ checked: target.checked })} > Show annotations {filteredList.map((group, i) => ( {group.file} > {group.name} ))} ); }; interface GroupInfoProps { rules: Rule[]; } export const GroupInfo: FC = ({ rules, children }) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const statesCounter = rules.reduce( (acc, r) => { return { ...acc, [r.state]: acc[r.state] + r.alerts.length, }; }, { firing: 0, pending: 0, } ); return (
{children}
{isPresent(statesCounter.inactive) && inactive} {statesCounter.pending > 0 && pending ({statesCounter.pending})} {statesCounter.firing > 0 && firing ({statesCounter.firing})}
); }; AlertsContent.displayName = 'Alerts'; export default AlertsContent;