// Libraries import React, { PureComponent, createRef } from 'react'; // Components import { ButtonSelect } from '../Select/ButtonSelect'; import { Tooltip } from '../Tooltip/Tooltip'; import { TimePickerPopover } from './TimePickerPopover'; import { ClickOutsideWrapper } from '../ClickOutsideWrapper/ClickOutsideWrapper'; // Utils & Services import { isDateTime } from '@grafana/data'; import { rangeUtil } from '@grafana/data'; import { rawToTimeRange } from './time'; // Types import { TimeRange, TimeOption, TimeZone, TIME_FORMAT } from '@grafana/data'; import { SelectOptionItem } from '../Select/Select'; export interface Props { value: TimeRange; selectOptions: TimeOption[]; timeZone?: TimeZone; onChange: (timeRange: TimeRange) => void; onMoveBackward: () => void; onMoveForward: () => void; onZoom: () => void; } export const defaultSelectOptions: TimeOption[] = [ { from: 'now-5m', to: 'now', display: 'Last 5 minutes', section: 3 }, { from: 'now-15m', to: 'now', display: 'Last 15 minutes', section: 3 }, { from: 'now-30m', to: 'now', display: 'Last 30 minutes', section: 3 }, { from: 'now-1h', to: 'now', display: 'Last 1 hour', section: 3 }, { from: 'now-3h', to: 'now', display: 'Last 3 hours', section: 3 }, { from: 'now-6h', to: 'now', display: 'Last 6 hours', section: 3 }, { from: 'now-12h', to: 'now', display: 'Last 12 hours', section: 3 }, { from: 'now-24h', to: 'now', display: 'Last 24 hours', section: 3 }, { from: 'now-2d', to: 'now', display: 'Last 2 days', section: 3 }, { from: 'now-7d', to: 'now', display: 'Last 7 days', section: 3 }, { from: 'now-30d', to: 'now', display: 'Last 30 days', section: 3 }, { from: 'now-90d', to: 'now', display: 'Last 90 days', section: 3 }, { from: 'now-6M', to: 'now', display: 'Last 6 months', section: 3 }, { from: 'now-1y', to: 'now', display: 'Last 1 year', section: 3 }, { from: 'now-2y', to: 'now', display: 'Last 2 years', section: 3 }, { from: 'now-5y', to: 'now', display: 'Last 5 years', section: 3 }, { from: 'now-1d/d', to: 'now-1d/d', display: 'Yesterday', section: 3 }, { from: 'now-2d/d', to: 'now-2d/d', display: 'Day before yesterday', section: 3 }, { from: 'now-7d/d', to: 'now-7d/d', display: 'This day last week', section: 3 }, { from: 'now-1w/w', to: 'now-1w/w', display: 'Previous week', section: 3 }, { from: 'now-1M/M', to: 'now-1M/M', display: 'Previous month', section: 3 }, { from: 'now-1y/y', to: 'now-1y/y', display: 'Previous year', section: 3 }, { from: 'now/d', to: 'now/d', display: 'Today', section: 3 }, { from: 'now/d', to: 'now', display: 'Today so far', section: 3 }, { from: 'now/w', to: 'now/w', display: 'This week', section: 3 }, { from: 'now/w', to: 'now', display: 'This week so far', section: 3 }, { from: 'now/M', to: 'now/M', display: 'This month', section: 3 }, { from: 'now/M', to: 'now', display: 'This month so far', section: 3 }, { from: 'now/y', to: 'now/y', display: 'This year', section: 3 }, { from: 'now/y', to: 'now', display: 'This year so far', section: 3 }, ]; const defaultZoomOutTooltip = () => { return ( <> Time range zoom out
CTRL+Z ); }; export interface State { isCustomOpen: boolean; } export class TimePicker extends PureComponent { pickerTriggerRef = createRef(); state: State = { isCustomOpen: false, }; mapTimeOptionsToSelectOptionItems = (selectOptions: TimeOption[]) => { const options = selectOptions.map(timeOption => { return { label: timeOption.display, value: timeOption, }; }); options.unshift({ label: 'Custom time range', value: { from: 'custom', to: 'custom', display: 'Custom', section: 1 }, }); return options; }; onSelectChanged = (item: SelectOptionItem) => { const { onChange, timeZone } = this.props; if (item.value && item.value.from === 'custom') { // this is to prevent the ClickOutsideWrapper from directly closing the popover setTimeout(() => { this.setState({ isCustomOpen: true }); }, 1); return; } if (item.value) { onChange(rawToTimeRange({ from: item.value.from, to: item.value.to }, timeZone)); } }; onCustomChange = (timeRange: TimeRange) => { const { onChange } = this.props; onChange(timeRange); this.setState({ isCustomOpen: false }); }; onCloseCustom = () => { this.setState({ isCustomOpen: false }); }; render() { const { selectOptions: selectTimeOptions, value, onMoveBackward, onMoveForward, onZoom, timeZone } = this.props; const { isCustomOpen } = this.state; const options = this.mapTimeOptionsToSelectOptionItems(selectTimeOptions); const currentOption = options.find(item => isTimeOptionEqualToTimeRange(item.value, value)); const rangeString = rangeUtil.describeTimeRange(value.raw); const label = ( <> {isCustomOpen && Custom time range} {!isCustomOpen && {rangeString}} {timeZone === 'utc' && UTC} ); const isAbsolute = isDateTime(value.raw.to); return (
{isAbsolute && ( )} } /> {isAbsolute && ( )} {isCustomOpen && ( )}
); } } const TimePickerTooltipContent = ({ timeRange }: { timeRange: TimeRange }) => ( <> {timeRange.from.format(TIME_FORMAT)}
to
{timeRange.to.format(TIME_FORMAT)} ); function isTimeOptionEqualToTimeRange(option: TimeOption, range: TimeRange): boolean { return range.raw.from === option.from && range.raw.to === option.to; }