import { css } from '@emotion/css'; import { useFieldArray, useFormContext } from 'react-hook-form'; import { GrafanaTheme2 } from '@grafana/data'; import { Button, Field, Icon, IconButton, InlineField, InlineFieldRow, Input, Tooltip, useStyles2 } from '@grafana/ui'; import { MuteTimingFields } from '../../types/mute-timing-form'; import ConditionalWrap from '../ConditionalWrap'; import { isValidStartAndEndTime, isvalidTimeFormat } from './util'; interface Props { intervalIndex: number; } const INVALID_FORMAT_MESSAGE = 'Times must be between 00:00 and 24:00 UTC'; export const MuteTimingTimeRange = ({ intervalIndex }: Props) => { const styles = useStyles2(getStyles); const { register, formState, getValues, watch } = useFormContext(); const isDisabled = watch(`time_intervals.${intervalIndex}.disable`); const { fields: timeRanges, append: addTimeRange, remove: removeTimeRange, } = useFieldArray({ name: `time_intervals.${intervalIndex}.times`, }); const formErrors = formState.errors.time_intervals?.[intervalIndex]; const timeRangeInvalid = formErrors?.times?.some?.((value) => value?.start_time || value?.end_time) ?? false; return (
<> {timeRanges.map((timeRange, index) => { const timeRangeErrors = formErrors?.times?.[index]; const startTimeKey = `time_intervals.${intervalIndex}.times.${index}.start_time`; const endTimeKey = `time_intervals.${intervalIndex}.times.${index}.end_time`; const getStartAndEndTime = (): [string | undefined, string | undefined] => { // @ts-ignore react-hook-form doesn't handle nested field arrays well const startTime: string = getValues(startTimeKey); // @ts-ignore react-hook-form doesn't handle nested field arrays well const endTime: string = getValues(endTimeKey); return [startTime, endTime]; }; return (
{ const validFormat = isvalidTimeFormat(input); if (!validFormat) { return INVALID_FORMAT_MESSAGE; } const [startTime, endTime] = getStartAndEndTime(); if (isValidStartAndEndTime(startTime, endTime)) { return; } else { return 'Start time must be before end time'; } }, })} className={styles.timeRangeInput} maxLength={5} readOnly={isDisabled} suffix={} // @ts-ignore react-hook-form doesn't handle nested field arrays well defaultValue={timeRange.start_time} placeholder="HH:mm" data-testid="mute-timing-starts-at" /> { const validFormat = isvalidTimeFormat(input); if (!validFormat) { return INVALID_FORMAT_MESSAGE; } const [startTime, endTime] = getStartAndEndTime(); if (isValidStartAndEndTime(startTime, endTime)) { return; } else { return 'End time must be after start time'; } }, })} className={styles.timeRangeInput} maxLength={5} readOnly={isDisabled} suffix={} // @ts-ignore react-hook-form doesn't handle nested field arrays well defaultValue={timeRange.end_time} placeholder="HH:mm" data-testid="mute-timing-ends-at" /> { e.preventDefault(); removeTimeRange(index); }} tooltip="Remove time range" />
); })}
( {children} )} >
); }; const getStyles = (theme: GrafanaTheme2) => ({ field: css({ marginBottom: 0, }), timeRange: css({ marginBottom: theme.spacing(1), }), timeRangeInput: css({ width: '90px', }), deleteTimeRange: css({ margin: `${theme.spacing(1)} 0 0 ${theme.spacing(0.5)}`, }), addTimeRange: css({ marginBottom: theme.spacing(2), }), });