Skip to content

Commit 3585ce9

Browse files
committed
RI-6049 separate timezone update from dateFormat update
1 parent 01a4791 commit 3585ce9

File tree

6 files changed

+335
-260
lines changed

6 files changed

+335
-260
lines changed

redisinsight/ui/src/pages/settings/components/general-settings/datetime-formatter/DateTimeFormatter.tsx

Lines changed: 11 additions & 222 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,22 @@
1-
import React, { ChangeEvent, useEffect, useMemo, useState } from 'react'
2-
import { useDispatch, useSelector } from 'react-redux'
3-
import { useFormik } from 'formik'
1+
import React, { useEffect, useState } from 'react'
2+
import { useSelector } from 'react-redux'
43
import {
5-
EuiButton,
6-
EuiFieldText,
74
EuiFlexGroup,
85
EuiFlexItem,
9-
EuiForm,
10-
EuiRadioGroup,
11-
EuiRadioGroupOption,
126
EuiSpacer,
13-
EuiSuperSelect,
147
EuiText,
158
EuiTitle,
16-
EuiToolTip
179
} from '@elastic/eui'
18-
import { checkDateTimeFormat, formatTimestamp } from 'uiSrc/utils'
19-
import { DATETIME_FORMATTER_DEFAULT, DatetimeRadioOption, TimezoneOption, dateTimeOptions, timezoneOptions } from 'uiSrc/constants'
20-
import { updateUserConfigSettingsAction, userSettingsConfigSelector } from 'uiSrc/slices/user/user-settings'
21-
import icheck from 'uiSrc/assets/img/icons/check.svg'
22-
import { TelemetryEvent, sendEventTelemetry } from 'uiSrc/telemetry'
10+
import { formatTimestamp } from 'uiSrc/utils'
11+
import { DATETIME_FORMATTER_DEFAULT, TimezoneOption } from 'uiSrc/constants'
12+
import { userSettingsConfigSelector } from 'uiSrc/slices/user/user-settings'
13+
import TimezoneForm from './components/timezone-form/TimezoneForm'
14+
import DatetimeForm from './components/datetime-form/DatetimeForm'
2315
import styles from './styles.module.scss'
2416

25-
interface InitialValuesType {
26-
format: string;
27-
customFormat: string;
28-
commonFormat: string;
29-
selectedRadioOption: DatetimeRadioOption;
30-
timezone: TimezoneOption;
31-
}
32-
3317
const DateTimeFormatter = () => {
34-
const [error, setError] = useState('')
3518
const [preview, setPreview] = useState('')
36-
const [saveFormatSucceed, setSaveFormatSucceed] = useState(false)
3719
const config = useSelector(userSettingsConfigSelector)
38-
const dispatch = useDispatch()
3920

4021
useEffect(() => {
4122
setPreview(formatTimestamp(
@@ -45,185 +26,8 @@ const DateTimeFormatter = () => {
4526
))
4627
}, [config?.dateFormat, config?.timezone])
4728

48-
const getInitialDateTime = (): InitialValuesType => {
49-
const format = config?.dateFormat || DATETIME_FORMATTER_DEFAULT
50-
const selectedRadioOption = dateTimeOptions.some((opt) => opt.value === format)
51-
? DatetimeRadioOption.Common
52-
: DatetimeRadioOption.Custom
53-
54-
return {
55-
selectedRadioOption,
56-
format,
57-
customFormat: selectedRadioOption === DatetimeRadioOption.Custom ? format : '',
58-
commonFormat: selectedRadioOption === DatetimeRadioOption.Common ? format : dateTimeOptions[0].value,
59-
timezone: config?.timezone || TimezoneOption.Local,
60-
}
61-
}
62-
63-
const getInitialValues = useMemo(() => getInitialDateTime(), [config])
64-
65-
const formik = useFormik({
66-
initialValues: getInitialValues,
67-
enableReinitialize: true,
68-
onSubmit: (values) => {
69-
submitForm(values)
70-
}
71-
})
72-
73-
const submitForm = async (values: InitialValuesType) => {
74-
if (checkDateTimeFormat(values.format, values.timezone).valid) {
75-
dispatch(
76-
updateUserConfigSettingsAction(
77-
{ dateFormat: values.format.trim(), timezone: values.timezone.trim() },
78-
() => {
79-
formik.setSubmitting(false)
80-
setSaveFormatSucceed(true)
81-
setTimeout(() => setSaveFormatSucceed(false), 5000)
82-
},
83-
() => {
84-
formik.setSubmitting(false)
85-
}
86-
)
87-
)
88-
} else {
89-
setError('This format is not supported.')
90-
formik.setSubmitting(false)
91-
}
92-
}
93-
94-
const showError = !!error || !formik.values.customFormat
95-
const getBtnIconType = () => (showError ? 'iInCircle' : (saveFormatSucceed ? icheck : undefined))
96-
97-
const handleFormatCheck = (format = formik.values.format, timezone = formik.values.timezone) => {
98-
const { valid, error: errorMsg } = checkDateTimeFormat(format, timezone)
99-
if (!valid) {
100-
setError(errorMsg || 'This format is not supported')
101-
setPreview('Invalid Format')
102-
} else {
103-
setError('')
104-
const newPreview = formatTimestamp(new Date(), format, timezone)
105-
setPreview(newPreview)
106-
}
107-
return valid
108-
}
109-
110-
const onRadioOptionChange = (id: string) => {
111-
formik.setFieldValue('selectedRadioOption', id)
112-
if (id === DatetimeRadioOption.Custom) {
113-
formik.setFieldValue('customFormat', formik.values.format)
114-
} else {
115-
formik.setFieldValue('format', formik.values.commonFormat)
116-
formik.handleSubmit()
117-
}
118-
}
119-
120-
const onTimezoneChange = (value: string) => {
121-
formik.setFieldValue('timezone', value)
122-
123-
sendEventTelemetry({
124-
event: TelemetryEvent.SETTINGS_TIME_ZONE_CHANGED,
125-
eventData: {
126-
currentTimezone: value,
127-
}
128-
})
129-
formik.handleSubmit()
130-
}
131-
132-
const onCustomFormatChange = (e: ChangeEvent<HTMLInputElement>) => {
133-
const { value } = e.target
134-
formik.setFieldValue('customFormat', value)
135-
formik.setFieldValue('format', value)
136-
handleFormatCheck(value)
137-
}
138-
139-
const onCommonFormatChange = (value: string) => {
140-
formik.setFieldValue('commonFormat', value)
141-
formik.setFieldValue('format', value)
142-
143-
sendEventTelemetry({
144-
event: TelemetryEvent.SETTINGS_DATE_TIME_FORMAT_CHANGED,
145-
eventData: {
146-
currentFormat: value,
147-
}
148-
})
149-
formik.handleSubmit()
150-
}
151-
152-
const onCustomFormatSubmit = () => {
153-
sendEventTelemetry({
154-
event: TelemetryEvent.SETTINGS_DATE_TIME_FORMAT_CHANGED,
155-
eventData: {
156-
currentFormat: formik.values.customFormat,
157-
}
158-
})
159-
160-
formik.handleSubmit()
161-
}
162-
163-
const dateTimeFormatOptions: EuiRadioGroupOption[] = [
164-
{
165-
id: DatetimeRadioOption.Common,
166-
label: (
167-
<div className={styles.radioLabelWrapper}>
168-
<div className={styles.radioLabelTextContainer}>
169-
<EuiText color="subdued" className={styles.radioLabelText}>Pre-selected formats</EuiText>
170-
</div>
171-
<EuiSuperSelect
172-
className={styles.datetimeInput}
173-
options={dateTimeOptions
174-
.map((option) => ({ ...option, 'data-test-subj': `date-option-${option.value}` }))}
175-
valueOfSelected={formik.values.commonFormat}
176-
onChange={(option) => onCommonFormatChange(option)}
177-
disabled={formik.values.selectedRadioOption !== DatetimeRadioOption.Common}
178-
data-test-subj="select-datetime"
179-
/>
180-
</div>
181-
),
182-
},
183-
{
184-
id: DatetimeRadioOption.Custom,
185-
label: (
186-
<div className={styles.radioLabelWrapper}>
187-
<div className={styles.radioLabelTextContainer}>
188-
<EuiText color="subdued" className={styles.radioLabelText}>Custom</EuiText>
189-
</div>
190-
{formik.values.selectedRadioOption === DatetimeRadioOption.Custom && (
191-
<>
192-
<EuiFieldText
193-
className={styles.datetimeInput}
194-
id="customFormat"
195-
name="customFormat"
196-
value={formik.values.customFormat}
197-
onChange={(e) => onCustomFormatChange(e)}
198-
data-testid="custom-datetime-input"
199-
/>
200-
<EuiToolTip
201-
position="top"
202-
anchorClassName="euiToolTip__btn-disabled"
203-
content={showError ? (error || 'This format is not supported') : null}
204-
>
205-
<EuiButton
206-
aria-label="Save"
207-
isLoading={formik.isSubmitting}
208-
color="secondary"
209-
fill
210-
size="m"
211-
className={styles.customBtn}
212-
onClick={onCustomFormatSubmit}
213-
data-testid="datetime-custom-btn"
214-
iconType={getBtnIconType()}
215-
disabled={showError}
216-
>Save
217-
</EuiButton>
218-
</EuiToolTip>
219-
</>
220-
)}
221-
</div>)
222-
}
223-
]
224-
22529
return (
226-
<EuiForm component="form" onSubmit={formik.handleSubmit} data-testid="format-timestamp-form">
30+
<>
22731
<EuiTitle size="xs">
22832
<h4>Date and Time Format</h4>
22933
</EuiTitle>
@@ -232,29 +36,14 @@ const DateTimeFormatter = () => {
23236
Specifies the date and time format to be used in Redis Insight:
23337
</EuiText>
23438
<EuiSpacer size="m" />
235-
<EuiRadioGroup
236-
options={dateTimeFormatOptions}
237-
className={styles.radios}
238-
name="radioDateTime"
239-
idSelected={formik.values.selectedRadioOption}
240-
onChange={(id) => onRadioOptionChange(id)}
241-
/>
39+
<DatetimeForm setPreview={setPreview} />
24240
<EuiSpacer size="m" />
24341
<EuiText className={styles.dateTimeSubtitle} color="subdued">Specifies the time zone to be used in Redis Insight:</EuiText>
24442
<EuiSpacer size="s" />
24543
<div>
24644
<EuiFlexGroup alignItems="center">
24745
<EuiFlexItem grow={1}>
248-
<div>
249-
<EuiSuperSelect
250-
className={styles.datetimeInput}
251-
options={timezoneOptions
252-
.map((option) => ({ ...option, 'data-test-subj': `zone-option-${option.value}` }))}
253-
valueOfSelected={formik.values.timezone}
254-
onChange={(option) => onTimezoneChange(option)}
255-
data-test-subj="select-timezone"
256-
/>
257-
</div>
46+
<TimezoneForm />
25847
</EuiFlexItem>
25948
<EuiFlexItem grow={2}>
26049
<div className={styles.previewContainer}>
@@ -265,7 +54,7 @@ const DateTimeFormatter = () => {
26554
</EuiFlexGroup>
26655
</div>
26756
<EuiSpacer size="l" />
268-
</EuiForm>
57+
</>
26958
)
27059
}
27160

0 commit comments

Comments
 (0)