1
- import { merge , uniqBy } from 'lodash' ;
2
- import React , { CSSProperties } from 'react' ;
1
+ import { isEqual , uniqBy } from 'lodash' ;
2
+ import React , { CSSProperties , FC , useEffect , useRef } from 'react' ;
3
3
// eslint-disable-next-line no-restricted-imports
4
4
import { useDispatch , useSelector } from 'react-redux' ;
5
5
6
- import { t } from '@grafana/ui/src/utils/i18n' ;
7
- import appEvents from 'app/core/app_events' ;
8
- import { TimeRange , isDateTime , rangeUtil , AppEvents } from '@grafana/data' ;
6
+ import { TimeRange , isDateTime , rangeUtil } from '@grafana/data' ;
9
7
import { TimeRangePickerProps , TimeRangePicker , useTheme2 } from '@grafana/ui' ;
10
8
import { FnGlobalState , updatePartialFnStates } from 'app/core/reducers/fn-slice' ;
11
9
import { StoreState } from 'app/types' ;
@@ -25,51 +23,66 @@ interface TimePickerHistoryItem {
25
23
// We should only be storing TimePickerHistoryItem, but in the past we also stored TimeRange
26
24
type LSTimePickerHistoryItem = TimePickerHistoryItem | TimeRange ;
27
25
28
- export const TimePickerWithHistory = ( props : Props ) => {
29
26
const FnText : React . FC = ( ) => {
30
27
const { FNDashboard } = useSelector < StoreState , FnGlobalState > ( ( { fnGlobalState } ) => fnGlobalState ) ;
31
28
const theme = useTheme2 ( ) ;
32
29
33
30
const FN_TEXT_STYLE : CSSProperties = { fontWeight : 700 , fontSize : 14 , marginLeft : 8 } ;
34
31
35
- return < > { FNDashboard ? < span style = { { ...FN_TEXT_STYLE , color : theme . colors . warning . main } } > UTC</ span > : '' } </ > ;
32
+ return < > { FNDashboard ? < span style = { { ...FN_TEXT_STYLE , color : theme . colors . primary . main } } > UTC</ span > : '' } </ > ;
36
33
} ;
37
34
38
- export const TimePickerWithHistory : React . FC < Props > = ( props ) => {
35
+ export const TimePickerWithHistory : FC < Props > = ( props ) => (
36
+ < LocalStorageValueProvider < LSTimePickerHistoryItem [ ] > storageKey = { LOCAL_STORAGE_KEY } defaultValue = { [ ] } >
37
+ { ( rawValues , onSaveToStore ) => {
38
+ return < Picker rawValues = { rawValues } onSaveToStore = { onSaveToStore } pickerProps = { props } /> ;
39
+ } }
40
+ </ LocalStorageValueProvider >
41
+ ) ;
42
+
43
+ export interface PickerProps {
44
+ rawValues : LSTimePickerHistoryItem [ ] ;
45
+ onSaveToStore : ( value : LSTimePickerHistoryItem [ ] ) => void ;
46
+ pickerProps : Props ;
47
+ }
48
+
49
+ export const Picker : FC < PickerProps > = ( { rawValues, onSaveToStore, pickerProps } ) => {
39
50
const { fnGlobalTimeRange } = useSelector < StoreState , FnGlobalState > ( ( { fnGlobalState } ) => fnGlobalState ) ;
40
51
const dispatch = useDispatch ( ) ;
41
52
42
- return (
43
- < LocalStorageValueProvider < LSTimePickerHistoryItem [ ] > storageKey = { LOCAL_STORAGE_KEY } defaultValue = { [ ] } >
44
- { ( rawValues , onSaveToStore ) => {
45
- const values = migrateHistory ( rawValues ) ;
46
- const history = deserializeHistory ( values ) ;
47
-
48
- return (
49
- < TimeRangePicker
50
- { ...props }
51
- history = { history }
52
- { ...merge ( { } , props , { value : fnGlobalTimeRange || props . value } ) }
53
- onChange = { ( value ) => {
54
- dispatch (
55
- updatePartialFnStates ( {
56
- fnGlobalTimeRange : value ,
57
- } )
58
- ) ;
59
- onAppendToHistory ( value , values , onSaveToStore ) ;
60
- props . onChange ( value ) ;
61
- } }
62
- onError = { ( error ?: string ) =>
63
- appEvents . emit ( AppEvents . alertError , [
64
- t ( 'time-picker.copy-paste.default-error-title' , 'Invalid time range' ) ,
65
- t ( 'time-picker.copy-paste.default-error-message' , `{{error}} is not a valid time range` , { error } ) ,
66
- ] )
67
- }
68
- fnText = { < FnText /> }
69
- />
53
+ const values = migrateHistory ( rawValues ) ;
54
+ const history = deserializeHistory ( values ) ;
55
+
56
+ const didMountRef = useRef ( false ) ;
57
+ useEffect ( ( ) => {
58
+ /* The condition below skips the first run of useeffect that happens when this component gets mounted */
59
+ if ( didMountRef . current ) {
60
+ /* If the current timerange value has changed, update fnGlobalTimeRange */
61
+ if ( ! isEqual ( fnGlobalTimeRange ?. raw , pickerProps . value . raw ) ) {
62
+ dispatch (
63
+ updatePartialFnStates ( {
64
+ fnGlobalTimeRange : pickerProps . value ,
65
+ } )
70
66
) ;
67
+ }
68
+ } else if ( fnGlobalTimeRange && ! isEqual ( fnGlobalTimeRange . raw , pickerProps . value . raw ) ) {
69
+ /* If fnGlobalTimeRange exists in the initial render, set the time as that */
70
+ pickerProps . onChange ( fnGlobalTimeRange ) ;
71
+ }
72
+
73
+ didMountRef . current = true ;
74
+ } , [ dispatch , fnGlobalTimeRange , pickerProps ] ) ;
75
+
76
+ return (
77
+ < TimeRangePicker
78
+ { ...pickerProps }
79
+ history = { history }
80
+ onChange = { ( value ) => {
81
+ onAppendToHistory ( value , values , onSaveToStore ) ;
82
+ pickerProps . onChange ( value ) ;
71
83
} }
72
- </ LocalStorageValueProvider >
84
+ fnText = { < FnText /> }
85
+ />
73
86
) ;
74
87
} ;
75
88
0 commit comments