Add back timezone when not using utc picker
This commit is contained in:
parent
7413483266
commit
9e22385e8d
@ -12,7 +12,12 @@ import Field from '@staticcms/core/components/common/field/Field';
|
||||
import TextField from '@staticcms/core/components/common/text-field/TextField';
|
||||
import { isNotEmpty } from '@staticcms/core/lib/util/string.util';
|
||||
import NowButton from './components/NowButton';
|
||||
import { DEFAULT_DATETIME_FORMAT, DEFAULT_DATE_FORMAT, DEFAULT_TIME_FORMAT } from './constants';
|
||||
import {
|
||||
DEFAULT_DATETIME_FORMAT,
|
||||
DEFAULT_DATE_FORMAT,
|
||||
DEFAULT_TIMEZONE_FORMAT,
|
||||
DEFAULT_TIME_FORMAT,
|
||||
} from './constants';
|
||||
import { localToUTC } from './utc.util';
|
||||
|
||||
import type { TextFieldProps as MuiTextFieldProps } from '@mui/material/TextField';
|
||||
@ -58,6 +63,11 @@ const DateTimeControl: FC<WidgetControlProps<string, DateTimeField>> = ({
|
||||
setOpen(false);
|
||||
}, []);
|
||||
|
||||
const timezoneExtra = useMemo(
|
||||
() => (field.picker_utc ? '' : DEFAULT_TIMEZONE_FORMAT),
|
||||
[field.picker_utc],
|
||||
);
|
||||
|
||||
const { format, dateFormat, timeFormat } = useMemo(() => {
|
||||
// dateFormat and timeFormat are strictly for modifying input field with the date/time pickers
|
||||
const dateFormat: string | boolean = field.date_format ?? true;
|
||||
@ -68,9 +78,9 @@ const DateTimeControl: FC<WidgetControlProps<string, DateTimeField>> = ({
|
||||
if (timeFormat === false) {
|
||||
finalFormat = field.format ?? DEFAULT_DATE_FORMAT;
|
||||
} else if (dateFormat === false) {
|
||||
finalFormat = field.format ?? DEFAULT_TIME_FORMAT;
|
||||
finalFormat = field.format ?? `${DEFAULT_TIME_FORMAT}${timezoneExtra}`;
|
||||
} else {
|
||||
finalFormat = field.format ?? DEFAULT_DATETIME_FORMAT;
|
||||
finalFormat = field.format ?? `${DEFAULT_DATETIME_FORMAT}${timezoneExtra}`;
|
||||
}
|
||||
|
||||
return {
|
||||
@ -78,7 +88,7 @@ const DateTimeControl: FC<WidgetControlProps<string, DateTimeField>> = ({
|
||||
dateFormat,
|
||||
timeFormat,
|
||||
};
|
||||
}, [field.date_format, field.format, field.time_format]);
|
||||
}, [field.date_format, field.format, field.time_format, timezoneExtra]);
|
||||
|
||||
const inputFormat = useMemo(() => {
|
||||
if (typeof dateFormat === 'string' || typeof timeFormat === 'string') {
|
||||
@ -92,7 +102,7 @@ const DateTimeControl: FC<WidgetControlProps<string, DateTimeField>> = ({
|
||||
if (typeof timeFormat === 'string' && isNotEmpty(timeFormat)) {
|
||||
formatParts.push(timeFormat);
|
||||
} else if (timeFormat !== false) {
|
||||
formatParts.push(DEFAULT_TIME_FORMAT);
|
||||
formatParts.push(`${DEFAULT_TIME_FORMAT}${timezoneExtra}`);
|
||||
}
|
||||
|
||||
if (formatParts.length > 0) {
|
||||
@ -105,11 +115,11 @@ const DateTimeControl: FC<WidgetControlProps<string, DateTimeField>> = ({
|
||||
}
|
||||
|
||||
if (dateFormat === false) {
|
||||
return format ?? DEFAULT_TIME_FORMAT;
|
||||
return format ?? `${DEFAULT_TIME_FORMAT}${timezoneExtra}`;
|
||||
}
|
||||
|
||||
return format ?? DEFAULT_DATETIME_FORMAT;
|
||||
}, [dateFormat, format, timeFormat]);
|
||||
return format ?? `${DEFAULT_DATETIME_FORMAT}${timezoneExtra}`;
|
||||
}, [dateFormat, format, timeFormat, timezoneExtra]);
|
||||
|
||||
const defaultValue = useMemo(() => {
|
||||
const today = field.picker_utc ? localToUTC(new Date()) : new Date();
|
||||
|
@ -202,7 +202,7 @@ describe(DateTimeControl.name, () => {
|
||||
|
||||
const inputWrapper = getByTestId('date-time-input');
|
||||
const input = inputWrapper.getElementsByTagName('input')[0];
|
||||
expect(input).toHaveValue('2023-02-12T10:15:35.000');
|
||||
expect(input).toHaveValue('2023-02-12T10:15:35.000-10:00');
|
||||
});
|
||||
|
||||
it('should use default if provided', () => {
|
||||
@ -210,39 +210,39 @@ describe(DateTimeControl.name, () => {
|
||||
label: 'I am a label',
|
||||
field: {
|
||||
...mockDateTimeField,
|
||||
default: '2023-01-10T06:23:15.000',
|
||||
default: '2023-01-10T06:23:15.000-10:00',
|
||||
},
|
||||
});
|
||||
|
||||
const inputWrapper = getByTestId('date-time-input');
|
||||
const input = inputWrapper.getElementsByTagName('input')[0];
|
||||
expect(input).toHaveValue('2023-01-10T06:23:15.000');
|
||||
expect(input).toHaveValue('2023-01-10T06:23:15.000-10:00');
|
||||
});
|
||||
|
||||
it('should only use prop value as initial value', async () => {
|
||||
const { rerender, getByTestId } = renderControl({ value: '2023-02-12T10:15:35.000' });
|
||||
const { rerender, getByTestId } = renderControl({ value: '2023-02-12T10:15:35.000-10:00' });
|
||||
|
||||
const inputWrapper = getByTestId('date-time-input');
|
||||
const input = inputWrapper.getElementsByTagName('input')[0];
|
||||
expect(input).toHaveValue('2023-02-12T10:15:35.000');
|
||||
expect(input).toHaveValue('2023-02-12T10:15:35.000-10:00');
|
||||
|
||||
rerender({ value: '2023-02-18T14:37:02.000' });
|
||||
expect(input).toHaveValue('2023-02-12T10:15:35.000');
|
||||
rerender({ value: '2023-02-18T14:37:02.000-10:00' });
|
||||
expect(input).toHaveValue('2023-02-12T10:15:35.000-10:00');
|
||||
});
|
||||
|
||||
it('should use prop value exclusively if field is i18n duplicate', async () => {
|
||||
const { rerender, getByTestId } = renderControl({
|
||||
field: { ...mockDateTimeField, i18n: 'duplicate' },
|
||||
duplicate: true,
|
||||
value: '2023-02-12T10:15:35.000',
|
||||
value: '2023-02-12T10:15:35.000-10:00',
|
||||
});
|
||||
|
||||
const inputWrapper = getByTestId('date-time-input');
|
||||
const input = inputWrapper.getElementsByTagName('input')[0];
|
||||
expect(input).toHaveValue('2023-02-12T10:15:35.000');
|
||||
expect(input).toHaveValue('2023-02-12T10:15:35.000-10:00');
|
||||
|
||||
rerender({ value: '2023-02-18T14:37:02.000' });
|
||||
expect(input).toHaveValue('2023-02-18T14:37:02.000');
|
||||
rerender({ value: '2023-02-18T14:37:02.000-10:00' });
|
||||
expect(input).toHaveValue('2023-02-18T14:37:02.000-10:00');
|
||||
});
|
||||
|
||||
it('should disable input and now button if disabled', () => {
|
||||
@ -297,7 +297,7 @@ describe(DateTimeControl.name, () => {
|
||||
await userEventActions.click(days[0]);
|
||||
});
|
||||
|
||||
expect(onChange).toHaveBeenLastCalledWith('2023-02-01T10:15:35.000');
|
||||
expect(onChange).toHaveBeenLastCalledWith('2023-02-01T10:15:35.000-10:00');
|
||||
|
||||
const hours = document.querySelectorAll('.MuiClockNumber-root');
|
||||
expect(hours.length).toBe(12);
|
||||
@ -312,7 +312,7 @@ describe(DateTimeControl.name, () => {
|
||||
fireEvent.touchEnd(square!, hourClockEvent);
|
||||
});
|
||||
|
||||
expect(onChange).toHaveBeenLastCalledWith('2023-02-01T01:15:35.000');
|
||||
expect(onChange).toHaveBeenLastCalledWith('2023-02-01T01:15:35.000-10:00');
|
||||
|
||||
const minutes = document.querySelectorAll('.MuiClockNumber-root');
|
||||
expect(minutes.length).toBe(12);
|
||||
@ -324,7 +324,7 @@ describe(DateTimeControl.name, () => {
|
||||
fireEvent.touchEnd(square!, minuteClockEvent);
|
||||
});
|
||||
|
||||
expect(onChange).toHaveBeenLastCalledWith('2023-02-01T01:05:35.000');
|
||||
expect(onChange).toHaveBeenLastCalledWith('2023-02-01T01:05:35.000-10:00');
|
||||
});
|
||||
|
||||
it('should set value to current date and time when now button is clicked', async () => {
|
||||
@ -337,20 +337,20 @@ describe(DateTimeControl.name, () => {
|
||||
|
||||
const inputWrapper = getByTestId('date-time-input');
|
||||
const input = inputWrapper.getElementsByTagName('input')[0];
|
||||
expect(input).toHaveValue('2023-02-12T10:15:35.000');
|
||||
expect(input).toHaveValue('2023-02-12T10:15:35.000-10:00');
|
||||
|
||||
await selectDateTime(getByTestId, 1, 2, 20, 'am');
|
||||
|
||||
expect(onChange).toHaveBeenLastCalledWith('2023-02-01T02:20:35.000');
|
||||
expect(input).toHaveValue('2023-02-01T02:20:35.000');
|
||||
expect(onChange).toHaveBeenLastCalledWith('2023-02-01T02:20:35.000-10:00');
|
||||
expect(input).toHaveValue('2023-02-01T02:20:35.000-10:00');
|
||||
|
||||
await act(async () => {
|
||||
const nowButton = getByTestId('datetime-now');
|
||||
await userEventActions.click(nowButton);
|
||||
});
|
||||
|
||||
expect(onChange).toHaveBeenLastCalledWith('2023-02-12T10:15:36.000'); // Testing framework moves the time forward by a second by this point
|
||||
expect(input).toHaveValue('2023-02-12T10:15:36.000');
|
||||
expect(onChange).toHaveBeenLastCalledWith('2023-02-12T10:15:36.000-10:00'); // Testing framework moves the time forward by a second by this point
|
||||
expect(input).toHaveValue('2023-02-12T10:15:36.000-10:00');
|
||||
});
|
||||
|
||||
describe('format', () => {
|
||||
@ -368,12 +368,12 @@ describe(DateTimeControl.name, () => {
|
||||
|
||||
const inputWrapper = getByTestId('date-time-input');
|
||||
const input = inputWrapper.getElementsByTagName('input')[0];
|
||||
expect(input).toHaveValue('02/12/2023 10:15:35.000');
|
||||
expect(input).toHaveValue('02/12/2023 10:15:35.000-10:00');
|
||||
|
||||
await selectDateTime(getByTestId, 1, 2, 20, 'am');
|
||||
|
||||
expect(onChange).toHaveBeenLastCalledWith('2023-02-01T02:20:35.000');
|
||||
expect(input).toHaveValue('02/01/2023 02:20:35.000');
|
||||
expect(onChange).toHaveBeenLastCalledWith('2023-02-01T02:20:35.000-10:00');
|
||||
expect(input).toHaveValue('02/01/2023 02:20:35.000-10:00');
|
||||
});
|
||||
|
||||
it('uses custom time display format', async () => {
|
||||
@ -394,7 +394,7 @@ describe(DateTimeControl.name, () => {
|
||||
|
||||
await selectDateTime(getByTestId, 1, 2, 20, 'am');
|
||||
|
||||
expect(onChange).toHaveBeenLastCalledWith('2023-02-01T02:20:35.000');
|
||||
expect(onChange).toHaveBeenLastCalledWith('2023-02-01T02:20:35.000-10:00');
|
||||
expect(input).toHaveValue('2023-02-01 02:20 am');
|
||||
});
|
||||
|
||||
@ -417,7 +417,7 @@ describe(DateTimeControl.name, () => {
|
||||
|
||||
await selectDateTime(getByTestId, 1, 2, 20, 'am');
|
||||
|
||||
expect(onChange).toHaveBeenLastCalledWith('2023-02-01T02:20:35.000');
|
||||
expect(onChange).toHaveBeenLastCalledWith('2023-02-01T02:20:35.000-10:00');
|
||||
expect(input).toHaveValue('02/01/2023 02:20 am');
|
||||
});
|
||||
|
||||
@ -479,7 +479,7 @@ describe(DateTimeControl.name, () => {
|
||||
|
||||
const inputWrapper = getByTestId('date-time-input');
|
||||
const input = inputWrapper.getElementsByTagName('input')[0];
|
||||
expect(input).toHaveValue('2023-02-12T15:15:35.000');
|
||||
expect(input).toHaveValue('2023-02-12T20:15:35.000');
|
||||
});
|
||||
|
||||
it('should use default if provided (assuming default is already in UTC)', () => {
|
||||
@ -741,7 +741,7 @@ describe(DateTimeControl.name, () => {
|
||||
|
||||
const inputWrapper = getByTestId('time-input');
|
||||
const input = inputWrapper.getElementsByTagName('input')[0];
|
||||
expect(input).toHaveValue('10:15:35.000');
|
||||
expect(input).toHaveValue('10:15:35.000-10:00');
|
||||
});
|
||||
|
||||
it('should use default if provided', () => {
|
||||
@ -749,43 +749,43 @@ describe(DateTimeControl.name, () => {
|
||||
label: 'I am a label',
|
||||
field: {
|
||||
...mockTimeField,
|
||||
default: '06:23:15.000',
|
||||
default: '06:23:15.000-10:00',
|
||||
},
|
||||
});
|
||||
|
||||
const inputWrapper = getByTestId('time-input');
|
||||
const input = inputWrapper.getElementsByTagName('input')[0];
|
||||
expect(input).toHaveValue('06:23:15.000');
|
||||
expect(input).toHaveValue('06:23:15.000-10:00');
|
||||
});
|
||||
|
||||
it('should only use prop value as initial value', async () => {
|
||||
const { rerender, getByTestId } = renderControl({
|
||||
field: mockTimeField,
|
||||
value: '10:15:35.000',
|
||||
value: '10:15:35.000-10:00',
|
||||
});
|
||||
|
||||
const inputWrapper = getByTestId('time-input');
|
||||
const input = inputWrapper.getElementsByTagName('input')[0];
|
||||
expect(input).toHaveValue('10:15:35.000');
|
||||
expect(input).toHaveValue('10:15:35.000-10:00');
|
||||
|
||||
rerender({ value: '14:37:02.000' });
|
||||
expect(input).toHaveValue('10:15:35.000');
|
||||
rerender({ value: '14:37:02.000-10:00' });
|
||||
expect(input).toHaveValue('10:15:35.000-10:00');
|
||||
});
|
||||
|
||||
it('should use prop value exclusively if field is i18n duplicate', async () => {
|
||||
const { rerender, getByTestId } = renderControl({
|
||||
field: { ...mockTimeField, i18n: 'duplicate' },
|
||||
duplicate: true,
|
||||
value: '10:15:35.000',
|
||||
value: '10:15:35.000-10:00',
|
||||
});
|
||||
|
||||
const inputWrapper = getByTestId('time-input');
|
||||
const input = inputWrapper.getElementsByTagName('input')[0];
|
||||
|
||||
expect(input).toHaveValue('10:15:35.000');
|
||||
expect(input).toHaveValue('10:15:35.000-10:00');
|
||||
|
||||
rerender({ value: '14:37:02.000' });
|
||||
expect(input).toHaveValue('14:37:02.000');
|
||||
rerender({ value: '14:37:02.000-10:00' });
|
||||
expect(input).toHaveValue('14:37:02.000-10:00');
|
||||
});
|
||||
|
||||
it('should disable input and now button if disabled', () => {
|
||||
@ -850,7 +850,7 @@ describe(DateTimeControl.name, () => {
|
||||
fireEvent.touchEnd(square!, hourClockEvent);
|
||||
});
|
||||
|
||||
expect(onChange).toHaveBeenLastCalledWith('01:15:35.000');
|
||||
expect(onChange).toHaveBeenLastCalledWith('01:15:35.000-10:00');
|
||||
|
||||
const minutes = document.querySelectorAll('.MuiClockNumber-root');
|
||||
expect(minutes.length).toBe(12);
|
||||
@ -862,7 +862,7 @@ describe(DateTimeControl.name, () => {
|
||||
fireEvent.touchEnd(square!, minuteClockEvent);
|
||||
});
|
||||
|
||||
expect(onChange).toHaveBeenLastCalledWith('01:05:35.000');
|
||||
expect(onChange).toHaveBeenLastCalledWith('01:05:35.000-10:00');
|
||||
});
|
||||
|
||||
it('should set value to current time when now button is clicked', async () => {
|
||||
@ -876,20 +876,20 @@ describe(DateTimeControl.name, () => {
|
||||
|
||||
const inputWrapper = getByTestId('time-input');
|
||||
const input = inputWrapper.getElementsByTagName('input')[0];
|
||||
expect(input).toHaveValue('10:15:35.000');
|
||||
expect(input).toHaveValue('10:15:35.000-10:00');
|
||||
|
||||
await selectTime(getByTestId, 2, 20, 'am');
|
||||
|
||||
expect(onChange).toHaveBeenLastCalledWith('02:20:35.000');
|
||||
expect(input).toHaveValue('02:20:35.000');
|
||||
expect(onChange).toHaveBeenLastCalledWith('02:20:35.000-10:00');
|
||||
expect(input).toHaveValue('02:20:35.000-10:00');
|
||||
|
||||
await act(async () => {
|
||||
const nowButton = getByTestId('datetime-now');
|
||||
await userEventActions.click(nowButton);
|
||||
});
|
||||
|
||||
expect(onChange).toHaveBeenLastCalledWith('10:15:36.000'); // Testing framework moves the time forward by a second by this point
|
||||
expect(input).toHaveValue('10:15:36.000');
|
||||
expect(onChange).toHaveBeenLastCalledWith('10:15:36.000-10:00'); // Testing framework moves the time forward by a second by this point
|
||||
expect(input).toHaveValue('10:15:36.000-10:00');
|
||||
});
|
||||
|
||||
describe('format', () => {
|
||||
@ -911,7 +911,7 @@ describe(DateTimeControl.name, () => {
|
||||
|
||||
await selectTime(getByTestId, 2, 20, 'am');
|
||||
|
||||
expect(onChange).toHaveBeenLastCalledWith('02:20:35.000');
|
||||
expect(onChange).toHaveBeenLastCalledWith('02:20:35.000-10:00');
|
||||
expect(input).toHaveValue('02:20 am');
|
||||
});
|
||||
|
||||
@ -972,7 +972,7 @@ describe(DateTimeControl.name, () => {
|
||||
|
||||
const inputWrapper = getByTestId('time-input');
|
||||
const input = inputWrapper.getElementsByTagName('input')[0];
|
||||
expect(input).toHaveValue('15:15:35.000');
|
||||
expect(input).toHaveValue('20:15:35.000');
|
||||
});
|
||||
|
||||
it('should use default if provided (assuming default is already in UTC)', () => {
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { localToUTC, utcToLocal } from '../utc.util';
|
||||
|
||||
describe('utc util', () => {
|
||||
it('converts local (EST) to UTC', () => {
|
||||
it('converts local (Hawaii time) to UTC', () => {
|
||||
expect(localToUTC(new Date(2023, 1, 12, 10, 5, 35)).toString()).toEqual(
|
||||
'Sun Feb 12 2023 15:05:35 GMT-0500 (Eastern Standard Time)',
|
||||
'Sun Feb 12 2023 20:05:35 GMT-1000 (Hawaii-Aleutian Standard Time)',
|
||||
);
|
||||
});
|
||||
|
||||
it('converts UTC to local (EST)', () => {
|
||||
it('converts UTC to local (Hawaii time)', () => {
|
||||
expect(utcToLocal(new Date(2023, 1, 12, 15, 5, 35)).toString()).toEqual(
|
||||
'Sun Feb 12 2023 10:05:35 GMT-0500 (Eastern Standard Time)',
|
||||
'Sun Feb 12 2023 05:05:35 GMT-1000 (Hawaii-Aleutian Standard Time)',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -1,3 +1,4 @@
|
||||
export const DEFAULT_DATE_FORMAT = 'yyyy-MM-dd';
|
||||
export const DEFAULT_TIME_FORMAT = 'HH:mm:ss.SSS';
|
||||
export const DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS";
|
||||
export const DEFAULT_TIMEZONE_FORMAT = "XXX";
|
||||
|
@ -1,3 +1,3 @@
|
||||
module.exports = async () => {
|
||||
process.env.TZ = 'America/New_York';
|
||||
process.env.TZ = 'US/Hawaii';
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user