Alerting: Fix RelativeTimeRangePicker (#60016)

This commit is contained in:
Konrad Lalik 2022-12-12 13:27:02 +01:00 committed by GitHub
parent 1758ddd457
commit d7b4a017d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,5 +1,6 @@
import { css, cx } from '@emotion/css';
import React, { FormEvent, useCallback, useState } from 'react';
import { usePopper } from 'react-popper';
import { RelativeTimeRange, GrafanaTheme2, TimeOption } from '@grafana/data';
@ -11,6 +12,7 @@ import CustomScrollbar from '../../CustomScrollbar/CustomScrollbar';
import { Field } from '../../Forms/Field';
import { Icon } from '../../Icon/Icon';
import { getInputStyles, Input } from '../../Input/Input';
import { Portal } from '../../Portal/Portal';
import { Tooltip } from '../../Tooltip/Tooltip';
import { TimePickerTitle } from '../TimeRangePicker/TimePickerTitle';
import { TimeRangeList } from '../TimeRangePicker/TimeRangeList';
@ -50,6 +52,12 @@ export function RelativeTimeRangePicker(props: RelativeTimeRangePickerProps) {
const [from, setFrom] = useState<InputState>({ value: timeOption.from, validation: isRangeValid(timeOption.from) });
const [to, setTo] = useState<InputState>({ value: timeOption.to, validation: isRangeValid(timeOption.to) });
const [markerElement, setMarkerElement] = useState<HTMLDivElement | null>(null);
const [selectorElement, setSelectorElement] = useState<HTMLDivElement | null>(null);
const popper = usePopper(markerElement, selectorElement, {
placement: 'auto-start',
});
const styles = useStyles2(getStyles(from.validation.errorMessage, to.validation.errorMessage));
const onChangeTimeOption = (option: TimeOption) => {
@ -94,7 +102,7 @@ export function RelativeTimeRangePicker(props: RelativeTimeRangePickerProps) {
};
return (
<div className={styles.container}>
<div className={styles.container} ref={setMarkerElement}>
<button className={styles.pickerInput} onClick={onOpen}>
<span className={styles.clockIcon}>
<Icon name="clock-nine" />
@ -107,52 +115,59 @@ export function RelativeTimeRangePicker(props: RelativeTimeRangePickerProps) {
</span>
</button>
{isOpen && (
<ClickOutsideWrapper includeButtonPress={false} onClick={onClose}>
<div className={styles.content}>
<div className={styles.body}>
<CustomScrollbar className={styles.leftSide} hideHorizontalTrack>
<TimeRangeList
title={t('time-picker.time-range.example-title', 'Example time ranges')}
options={validOptions}
onChange={onChangeTimeOption}
value={timeOption}
/>
</CustomScrollbar>
<div className={styles.rightSide}>
<div className={styles.title}>
<TimePickerTitle>
<Tooltip content={<TooltipContent />} placement="bottom" theme="info">
<div>
<Trans i18nKey="time-picker.time-range.specify">
Specify time range <Icon name="info-circle" />
</Trans>
</div>
</Tooltip>
</TimePickerTitle>
<Portal>
<ClickOutsideWrapper includeButtonPress={false} onClick={onClose}>
<div
className={styles.content}
ref={setSelectorElement}
style={popper.styles.popper}
{...popper.attributes}
>
<div className={styles.body}>
<CustomScrollbar className={styles.leftSide} hideHorizontalTrack>
<TimeRangeList
title={t('time-picker.time-range.example-title', 'Example time ranges')}
options={validOptions}
onChange={onChangeTimeOption}
value={timeOption}
/>
</CustomScrollbar>
<div className={styles.rightSide}>
<div className={styles.title}>
<TimePickerTitle>
<Tooltip content={<TooltipContent />} placement="bottom" theme="info">
<div>
<Trans i18nKey="time-picker.time-range.specify">
Specify time range <Icon name="info-circle" />
</Trans>
</div>
</Tooltip>
</TimePickerTitle>
</div>
<Field label="From" invalid={!from.validation.isValid} error={from.validation.errorMessage}>
<Input
onClick={(event) => event.stopPropagation()}
onBlur={() => setFrom({ ...from, validation: isRangeValid(from.value) })}
onChange={(event) => setFrom({ ...from, value: event.currentTarget.value })}
value={from.value}
/>
</Field>
<Field label="To" invalid={!to.validation.isValid} error={to.validation.errorMessage}>
<Input
onClick={(event) => event.stopPropagation()}
onBlur={() => setTo({ ...to, validation: isRangeValid(to.value) })}
onChange={(event) => setTo({ ...to, value: event.currentTarget.value })}
value={to.value}
/>
</Field>
<Button aria-label="TimePicker submit button" onClick={onApply}>
Apply time range
</Button>
</div>
<Field label="From" invalid={!from.validation.isValid} error={from.validation.errorMessage}>
<Input
onClick={(event) => event.stopPropagation()}
onBlur={() => setFrom({ ...from, validation: isRangeValid(from.value) })}
onChange={(event) => setFrom({ ...from, value: event.currentTarget.value })}
value={from.value}
/>
</Field>
<Field label="To" invalid={!to.validation.isValid} error={to.validation.errorMessage}>
<Input
onClick={(event) => event.stopPropagation()}
onBlur={() => setTo({ ...to, validation: isRangeValid(to.value) })}
onChange={(event) => setTo({ ...to, value: event.currentTarget.value })}
value={to.value}
/>
</Field>
<Button aria-label="TimePicker submit button" onClick={onApply}>
Apply time range
</Button>
</div>
</div>
</div>
</ClickOutsideWrapper>
</ClickOutsideWrapper>
</Portal>
)}
</div>
);