github.com/grafana/pyroscope@v1.18.0/public/app/components/DateRangePicker.tsx (about)

     1  import React, { useState } from 'react';
     2  
     3  import { useAppDispatch, useAppSelector } from '@pyroscope/redux/hooks';
     4  import {
     5    setDateRange,
     6    selectContinuousState,
     7  } from '@pyroscope/redux/reducers/continuous';
     8  import cx from 'classnames';
     9  import Button from '@pyroscope/ui/Button';
    10  import { readableRange } from '@pyroscope/util/formatDate';
    11  import { faClock } from '@fortawesome/free-solid-svg-icons/faClock';
    12  import OutsideClickHandler from 'react-outside-click-handler';
    13  import useTimeZone from '@pyroscope/hooks/timeZone.hook';
    14  import CustomDatePicker from './CustomDatePicker';
    15  import CheckIcon from './CheckIcon';
    16  
    17  const defaultPresets = [
    18    [
    19      { label: 'Last 5 minutes', from: 'now-5m', until: 'now' },
    20      { label: 'Last 15 minutes', from: 'now-15m', until: 'now' },
    21      { label: 'Last 30 minutes', from: 'now-30m', until: 'now' },
    22      { label: 'Last 1 hour', from: 'now-1h', until: 'now' },
    23      { label: 'Last 3 hours', from: 'now-3h', until: 'now' },
    24      { label: 'Last 6 hours', from: 'now-6h', until: 'now' },
    25      { label: 'Last 12 hours', from: 'now-12h', until: 'now' },
    26      { label: 'Last 24 hours', from: 'now-24h', until: 'now' },
    27    ],
    28    [
    29      { label: 'Last 2 days', from: 'now-2d', until: 'now' },
    30      { label: 'Last 7 days', from: 'now-7d', until: 'now' },
    31      { label: 'Last 30 days', from: 'now-30d', until: 'now' },
    32      { label: 'Last 90 days', from: 'now-90d', until: 'now' },
    33    ],
    34  ];
    35  
    36  function findPreset(from: string, until = 'now') {
    37    return defaultPresets
    38      .flat()
    39      .filter((a) => a.until === until)
    40      .find((a) => from === a.from);
    41  }
    42  
    43  function dateToLabel(from: string, until: string, offsetInMinutes: number) {
    44    const preset = findPreset(from, until);
    45  
    46    if (preset) {
    47      return preset.label;
    48    }
    49  
    50    return readableRange(from, until, offsetInMinutes);
    51  }
    52  
    53  function DateRangePicker() {
    54    const dispatch = useAppDispatch();
    55    const { offset } = useTimeZone();
    56    const { from, until } = useAppSelector(selectContinuousState);
    57    const [opened, setOpened] = useState(false);
    58  
    59    const toggleDropdown = () => {
    60      setOpened(!opened);
    61    };
    62  
    63    const hideDropdown = () => {
    64      setOpened(false);
    65    };
    66    const selectPreset = ({ from, until }: { from: string; until: string }) => {
    67      dispatch(setDateRange({ from, until }));
    68      setOpened(false);
    69    };
    70  
    71    const isPresetSelected = (preset: (typeof defaultPresets)[0][0]) => {
    72      return preset.label === dateToLabel(from, until, offset);
    73    };
    74  
    75    const handleChangeDataRange = (from: string, until: string) => {
    76      dispatch(setDateRange({ from, until }));
    77    };
    78  
    79    return (
    80      <div className={opened ? 'drp-container opened' : 'drp-container'}>
    81        <OutsideClickHandler onOutsideClick={hideDropdown}>
    82          <Button
    83            data-testid="time-dropdown-button"
    84            icon={faClock}
    85            onClick={toggleDropdown}
    86          >
    87            {dateToLabel(from, until, offset)}
    88          </Button>
    89          <div className="drp-dropdown">
    90            <div className="drp-quick-presets">
    91              <h4>Quick Presets</h4>
    92              <div className="drp-presets">
    93                {defaultPresets.map((arr, i) => (
    94                  <div key={`preset-${i + 1}`} className="drp-preset-column">
    95                    {arr.map((x) => (
    96                      <button
    97                        type="button"
    98                        className={cx(
    99                          'drp-preset',
   100                          isPresetSelected(x) && 'active'
   101                        )}
   102                        key={x.label}
   103                        onClick={() => selectPreset(x)}
   104                      >
   105                        {x.label}
   106                        {isPresetSelected(x) ? <CheckIcon /> : false}
   107                      </button>
   108                    ))}
   109                  </div>
   110                ))}
   111              </div>
   112            </div>
   113            <CustomDatePicker
   114              from={from}
   115              until={until}
   116              onSubmit={handleChangeDataRange}
   117            />
   118          </div>
   119        </OutsideClickHandler>
   120      </div>
   121    );
   122  }
   123  
   124  export default DateRangePicker;