mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Fix RelativeTimeRangePicker (#60016)
This commit is contained in:
parent
1758ddd457
commit
d7b4a017d2
@ -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>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user