From c206cb0c827144e027de7afa337154a669d6fdc2 Mon Sep 17 00:00:00 2001 From: Spikatrix <12792882+Spikatrix@users.noreply.github.com> Date: Mon, 19 Jun 2023 08:02:11 +0000 Subject: [PATCH] Pull latest time range changes from upstream grafana --- .../grafana-data/src/datetime/rangeutil.ts | 11 +++-- .../TimeRangePicker/TimePickerContent.tsx | 2 +- .../TimePicker/TimePickerWithHistory.tsx | 41 +++++++++++-------- 3 files changed, 32 insertions(+), 22 deletions(-) diff --git a/packages/grafana-data/src/datetime/rangeutil.ts b/packages/grafana-data/src/datetime/rangeutil.ts index 626780d7f25ba..29e4d820cc37e 100644 --- a/packages/grafana-data/src/datetime/rangeutil.ts +++ b/packages/grafana-data/src/datetime/rangeutil.ts @@ -198,9 +198,14 @@ export const describeTimeRangeAbbreviation = (range: TimeRange, timeZone?: TimeZ return parsed ? timeZoneAbbrevation(parsed, { timeZone }) : ''; }; -export const convertRawToRange = (raw: RawTimeRange, timeZone?: TimeZone, fiscalYearStartMonth?: number): TimeRange => { - const from = dateTimeParse(raw.from, { roundUp: false, timeZone, fiscalYearStartMonth }); - const to = dateTimeParse(raw.to, { roundUp: true, timeZone, fiscalYearStartMonth }); +export const convertRawToRange = ( + raw: RawTimeRange, + timeZone?: TimeZone, + fiscalYearStartMonth?: number, + format?: string +): TimeRange => { + const from = dateTimeParse(raw.from, { roundUp: false, timeZone, fiscalYearStartMonth, format }); + const to = dateTimeParse(raw.to, { roundUp: true, timeZone, fiscalYearStartMonth, format }); if (dateMath.isMathString(raw.from) || dateMath.isMathString(raw.to)) { return { from, to, raw }; diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx index 4ecf267bbc239..6c97fd51e49d5 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx @@ -288,7 +288,7 @@ const getStyles = stylesFactory((theme: GrafanaTheme2, isReversed, hideQuickRang flex-direction: column; border-right: ${isReversed ? 'none' : `1px solid ${theme.colors.border.weak}`}; width: ${!hideQuickRanges ? '50%' : '100%'}; - overflow: hidden; + overflow: auto; order: ${isReversed ? 1 : 0}; `, rightSide: css` diff --git a/public/app/core/components/TimePicker/TimePickerWithHistory.tsx b/public/app/core/components/TimePicker/TimePickerWithHistory.tsx index c75b527ca840c..f5bd5f52211e7 100644 --- a/public/app/core/components/TimePicker/TimePickerWithHistory.tsx +++ b/public/app/core/components/TimePicker/TimePickerWithHistory.tsx @@ -3,7 +3,7 @@ import React, { CSSProperties, FC, useEffect, useRef } from 'react'; // eslint-disable-next-line no-restricted-imports import { useDispatch, useSelector } from 'react-redux'; -import { TimeRange, isDateTime, rangeUtil, TimeZone, toUtc } from '@grafana/data'; +import { TimeRange, isDateTime, rangeUtil } from '@grafana/data'; import { TimeRangePickerProps, TimeRangePicker, useTheme2 } from '@grafana/ui'; import { FnGlobalState, updatePartialFnStates } from 'app/core/reducers/fn-slice'; import { StoreState } from 'app/types'; @@ -14,6 +14,15 @@ const LOCAL_STORAGE_KEY = 'grafana.dashboard.timepicker.history'; interface Props extends Omit {} +// Simplified object to store in local storage +interface TimePickerHistoryItem { + from: string; + to: string; +} + +// We should only be storing TimePickerHistoryItem, but in the past we also stored TimeRange +type LSTimePickerHistoryItem = TimePickerHistoryItem | TimeRange; + const FnText: React.FC = () => { const { FNDashboard } = useSelector(({ fnGlobalState }) => fnGlobalState); const theme = useTheme2(); @@ -24,23 +33,26 @@ const FnText: React.FC = () => { }; export const TimePickerWithHistory: FC = (props) => ( - storageKey={LOCAL_STORAGE_KEY} defaultValue={[]}> - {(values, onSaveToStore) => { - return ; + storageKey={LOCAL_STORAGE_KEY} defaultValue={[]}> + {(rawValues, onSaveToStore) => { + return ; }} ); export interface PickerProps { - values: TimeRange[]; - onSaveToStore: (value: TimeRange[]) => void; + rawValues: LSTimePickerHistoryItem[]; + onSaveToStore: (value: LSTimePickerHistoryItem[]) => void; pickerProps: Props; } -export const Picker: FC = ({ values, onSaveToStore, pickerProps }) => { +export const Picker: FC = ({ rawValues, onSaveToStore, pickerProps }) => { const { fnGlobalTimeRange } = useSelector(({ fnGlobalState }) => fnGlobalState); const dispatch = useDispatch(); + const values = migrateHistory(rawValues); + const history = deserializeHistory(values); + const didMountRef = useRef(false); useEffect(() => { /* The condition below skips the first run of useeffect that happens when this component gets mounted */ @@ -62,7 +74,7 @@ export const Picker: FC = ({ values, onSaveToStore, pickerProps }) { onAppendToHistory(value, values, onSaveToStore); pickerProps.onChange(value); @@ -72,16 +84,9 @@ export const Picker: FC = ({ values, onSaveToStore, pickerProps }) ); }; -function convertIfJson(history: TimeRange[]): TimeRange[] { - return history.map((time) => { - if (isDateTime(time.from)) { - return time; - } - }); -} - -function deserializeHistory(values: TimePickerHistoryItem[], timeZone: TimeZone | undefined): TimeRange[] { - return values.map((item) => rangeUtil.convertRawToRange(item, timeZone)); +function deserializeHistory(values: TimePickerHistoryItem[]): TimeRange[] { + // The history is saved in UTC and with the default date format, so we need to pass those values to the convertRawToRange + return values.map((item) => rangeUtil.convertRawToRange(item, 'utc', undefined, 'YYYY-MM-DD HH:mm:ss')); } function migrateHistory(values: LSTimePickerHistoryItem[]): TimePickerHistoryItem[] {