forked from grafana/grafana
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathTimePickerWithHistory.tsx
100 lines (82 loc) · 3.05 KB
/
TimePickerWithHistory.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { merge } from 'lodash';
import React, { CSSProperties, FC, useEffect } from 'react';
// eslint-disable-next-line no-restricted-imports
import { useDispatch, useSelector } from 'react-redux';
import { TimeRange, isDateTime, toUtc } from '@grafana/data';
import { TimeRangePickerProps, TimeRangePicker, useTheme2 } from '@grafana/ui';
import { FnGlobalState, updatePartialFnStates } from 'app/core/reducers/fn-slice';
import { StoreState } from 'app/types';
import { LocalStorageValueProvider } from '../LocalStorageValueProvider';
const LOCAL_STORAGE_KEY = 'grafana.dashboard.timepicker.history';
interface Props extends Omit<TimeRangePickerProps, 'history' | 'theme'> {}
const FnText: React.FC = () => {
const { FNDashboard } = useSelector<StoreState, FnGlobalState>(({ fnGlobalState }) => fnGlobalState);
const theme = useTheme2();
const FN_TEXT_STYLE: CSSProperties = { fontWeight: 700, fontSize: 14, marginLeft: 8 };
return <>{FNDashboard ? <span style={{ ...FN_TEXT_STYLE, color: theme.colors.warning.main }}>UTC</span> : ''}</>;
};
export const TimePickerWithHistory: FC<Props> = (props) => (
<LocalStorageValueProvider<TimeRange[]> storageKey={LOCAL_STORAGE_KEY} defaultValue={[]}>
{(values, onSaveToStore) => {
return <Picker values={values} onSaveToStore={onSaveToStore} pickerProps={props} />;
}}
</LocalStorageValueProvider>
);
export interface PickerProps {
values: TimeRange[];
onSaveToStore: (value: TimeRange[]) => void;
pickerProps: Props;
}
export const Picker: FC<PickerProps> = ({ values, onSaveToStore, pickerProps }) => {
const { fnGlobalTimeRange } = useSelector<StoreState, FnGlobalState>(({ fnGlobalState }) => fnGlobalState);
const dispatch = useDispatch();
useEffect(() => {
if (!fnGlobalTimeRange) {
return;
}
onAppendToHistory(fnGlobalTimeRange, values, onSaveToStore);
pickerProps.onChange(fnGlobalTimeRange);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<TimeRangePicker
{...merge({}, pickerProps, { value: fnGlobalTimeRange || pickerProps.value })}
history={convertIfJson(values)}
onChange={(value) => {
dispatch(
updatePartialFnStates({
fnGlobalTimeRange: value,
})
);
onAppendToHistory(value, values, onSaveToStore);
pickerProps.onChange(value);
}}
fnText={<FnText />}
/>
);
};
function convertIfJson(history: TimeRange[]): TimeRange[] {
return history.map((time) => {
if (isDateTime(time.from)) {
return time;
}
return {
from: toUtc(time.from),
to: toUtc(time.to),
raw: time.raw,
};
});
}
function onAppendToHistory(toAppend: TimeRange, values: TimeRange[], onSaveToStore: (values: TimeRange[]) => void) {
if (!isAbsolute(toAppend)) {
return;
}
const toStore = limit([toAppend, ...values]);
onSaveToStore(toStore);
}
function isAbsolute(value: TimeRange): boolean {
return isDateTime(value.raw.from) || isDateTime(value.raw.to);
}
function limit(value: TimeRange[]): TimeRange[] {
return value.slice(0, 4);
}