import { css } from '@emotion/css'; import React, { FC, useMemo, useState } from 'react'; import { useDispatch } from 'react-redux'; import { GrafanaTheme2 } from '@grafana/data'; import { IconButton, LinkButton, Link, useStyles2, ConfirmModal } from '@grafana/ui'; import { contextSrv } from 'app/core/services/context_srv'; import { AlertManagerCortexConfig, MuteTimeInterval, TimeInterval } from 'app/plugins/datasource/alertmanager/types'; import { Authorize } from '../../components/Authorize'; import { useUnifiedAlertingSelector } from '../../hooks/useUnifiedAlertingSelector'; import { deleteMuteTimingAction } from '../../state/actions'; import { getNotificationsPermissions } from '../../utils/access-control'; import { getTimeString, getWeekdayString, getDaysOfMonthString, getMonthsString, getYearsString, } from '../../utils/alertmanager'; import { makeAMLink } from '../../utils/misc'; import { AsyncRequestState, initialAsyncRequestState } from '../../utils/redux'; import { DynamicTable, DynamicTableItemProps, DynamicTableColumnProps } from '../DynamicTable'; import { EmptyAreaWithCTA } from '../EmptyAreaWithCTA'; interface Props { alertManagerSourceName: string; muteTimingNames?: string[]; hideActions?: boolean; } export const MuteTimingsTable: FC = ({ alertManagerSourceName, muteTimingNames, hideActions }) => { const styles = useStyles2(getStyles); const dispatch = useDispatch(); const permissions = getNotificationsPermissions(alertManagerSourceName); const amConfigs = useUnifiedAlertingSelector((state) => state.amConfigs); const [muteTimingName, setMuteTimingName] = useState(''); const { result }: AsyncRequestState = (alertManagerSourceName && amConfigs[alertManagerSourceName]) || initialAsyncRequestState; const items = useMemo((): Array> => { const muteTimings = result?.alertmanager_config?.mute_time_intervals ?? []; return muteTimings .filter(({ name }) => (muteTimingNames ? muteTimingNames.includes(name) : true)) .map((mute) => { return { id: mute.name, data: mute, }; }); }, [result?.alertmanager_config?.mute_time_intervals, muteTimingNames]); const columns = useColumns(alertManagerSourceName, hideActions, setMuteTimingName); return (
{!hideActions &&
Mute timings
} {!hideActions && (

Mute timings are a named interval of time that may be referenced in the notification policy tree to mute particular notification policies for specific times of the day.

)} {!hideActions && items.length > 0 && ( New mute timing )} {items.length > 0 ? ( ) : !hideActions ? ( ) : (

No mute timings configured

)} {!hideActions && ( dispatch(deleteMuteTimingAction(alertManagerSourceName, muteTimingName))} onDismiss={() => setMuteTimingName('')} /> )}
); }; function useColumns(alertManagerSourceName: string, hideActions = false, setMuteTimingName: (name: string) => void) { const permissions = getNotificationsPermissions(alertManagerSourceName); const userHasEditPermissions = contextSrv.hasPermission(permissions.update); const userHasDeletePermissions = contextSrv.hasPermission(permissions.delete); const showActions = !hideActions && (userHasEditPermissions || userHasDeletePermissions); return useMemo((): Array> => { const columns: Array> = [ { id: 'name', label: 'Name', renderCell: function renderName({ data }) { return data.name; }, size: '250px', }, { id: 'timeRange', label: 'Time range', renderCell: ({ data }) => renderTimeIntervals(data.time_intervals), }, ]; if (showActions) { columns.push({ id: 'actions', label: 'Actions', renderCell: function renderActions({ data }) { return (
setMuteTimingName(data.name)} />
); }, size: '100px', }); } return columns; }, [alertManagerSourceName, setMuteTimingName, showActions, permissions]); } function renderTimeIntervals(timeIntervals: TimeInterval[]) { return timeIntervals.map((interval, index) => { const { times, weekdays, days_of_month, months, years } = interval; const timeString = getTimeString(times); const weekdayString = getWeekdayString(weekdays); const daysString = getDaysOfMonthString(days_of_month); const monthsString = getMonthsString(months); const yearsString = getYearsString(years); return ( {`${timeString} ${weekdayString}`}
{[daysString, monthsString, yearsString].join(' | ')}
); }); } const getStyles = (theme: GrafanaTheme2) => ({ container: css` display: flex; flex-flow: column nowrap; `, addMuteButton: css` margin-bottom: ${theme.spacing(2)}; align-self: flex-end; `, });