fix: update values for default timezone selector (#17124)

* update values for default timezone selector

* fix casing and comment

* Update TimezoneSelector.test.tsx
This commit is contained in:
Elizabeth Thompson 2021-10-18 09:39:20 -07:00 committed by GitHub
parent 2ad9101d1e
commit ae4ced8da6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 15 deletions

View File

@ -18,14 +18,18 @@
*/ */
import React from 'react'; import React from 'react';
import moment from 'moment-timezone'; import moment from 'moment-timezone';
import { render } from 'spec/helpers/testing-library'; import { render, screen } from 'spec/helpers/testing-library';
import userEvent from '@testing-library/user-event';
import TimezoneSelector from './index'; import TimezoneSelector from './index';
describe('TimezoneSelector', () => { describe('TimezoneSelector', () => {
let timezone: string; let timezone: string | undefined;
const onTimezoneChange = jest.fn(zone => { const onTimezoneChange = jest.fn(zone => {
timezone = zone; timezone = zone;
}); });
beforeEach(() => {
timezone = undefined;
});
it('renders a TimezoneSelector with a default if undefined', () => { it('renders a TimezoneSelector with a default if undefined', () => {
jest.spyOn(moment.tz, 'guess').mockReturnValue('America/New_York'); jest.spyOn(moment.tz, 'guess').mockReturnValue('America/New_York');
render( render(
@ -36,6 +40,27 @@ describe('TimezoneSelector', () => {
); );
expect(onTimezoneChange).toHaveBeenCalledWith('America/Nassau'); expect(onTimezoneChange).toHaveBeenCalledWith('America/Nassau');
}); });
it('should properly select values from the offsetsToName map', async () => {
jest.spyOn(moment.tz, 'guess').mockReturnValue('America/New_York');
render(
<TimezoneSelector
onTimezoneChange={onTimezoneChange}
timezone={timezone}
/>,
);
const select = screen.getByRole('combobox', {
name: 'Timezone selector',
});
expect(select).toBeInTheDocument();
userEvent.click(select);
const selection = await screen.findByTitle(
'GMT -06:00 (Mountain Daylight Time)',
);
expect(selection).toBeInTheDocument();
userEvent.click(selection);
expect(selection).toBeVisible();
});
it('renders a TimezoneSelector with the closest value if passed in', async () => { it('renders a TimezoneSelector with the closest value if passed in', async () => {
render( render(
<TimezoneSelector <TimezoneSelector

View File

@ -17,12 +17,16 @@
* under the License. * under the License.
*/ */
import React, { useEffect, useRef } from 'react'; import React, { useEffect, useRef, useCallback } from 'react';
import moment from 'moment-timezone'; import moment from 'moment-timezone';
import { t } from '@superset-ui/core'; import { t } from '@superset-ui/core';
import { Select } from 'src/components'; import { Select } from 'src/components';
const DEFAULT_TIMEZONE = 'GMT Standard Time'; const DEFAULT_TIMEZONE = {
name: 'GMT Standard Time',
value: 'Africa/Abidjan', // timezones are deduped by the first alphabetical value
};
const MIN_SELECT_WIDTH = '400px'; const MIN_SELECT_WIDTH = '400px';
const offsetsToName = { const offsetsToName = {
@ -37,7 +41,7 @@ const offsetsToName = {
'-540-480': ['Alaska Standard Time', 'Alaska Daylight Time'], '-540-480': ['Alaska Standard Time', 'Alaska Daylight Time'],
'-600-600': ['Hawaii Standard Time', 'Hawaii Daylight Time'], '-600-600': ['Hawaii Standard Time', 'Hawaii Daylight Time'],
'60120': ['Central European Time', 'Central European Daylight Time'], '60120': ['Central European Time', 'Central European Daylight Time'],
'00': [DEFAULT_TIMEZONE, DEFAULT_TIMEZONE], '00': [DEFAULT_TIMEZONE.name, DEFAULT_TIMEZONE.name],
'060': ['GMT Standard Time - London', 'British Summer Time'], '060': ['GMT Standard Time - London', 'British Summer Time'],
}; };
@ -96,28 +100,31 @@ const TimezoneSelector = ({ onTimezoneChange, timezone }: TimezoneProps) => {
const prevTimezone = useRef(timezone); const prevTimezone = useRef(timezone);
const matchTimezoneToOptions = (timezone: string) => const matchTimezoneToOptions = (timezone: string) =>
TIMEZONE_OPTIONS.find(option => option.offsets === getOffsetKey(timezone)) TIMEZONE_OPTIONS.find(option => option.offsets === getOffsetKey(timezone))
?.value || DEFAULT_TIMEZONE; ?.value || DEFAULT_TIMEZONE.value;
const updateTimezone = (tz: string) => { const updateTimezone = useCallback(
// update the ref to track changes (tz: string) => {
prevTimezone.current = tz; // update the ref to track changes
// the parent component contains the state for the value prevTimezone.current = tz;
onTimezoneChange(tz); // the parent component contains the state for the value
}; onTimezoneChange(tz);
},
[onTimezoneChange],
);
useEffect(() => { useEffect(() => {
const updatedTz = matchTimezoneToOptions(timezone || moment.tz.guess()); const updatedTz = matchTimezoneToOptions(timezone || moment.tz.guess());
if (prevTimezone.current !== updatedTz) { if (prevTimezone.current !== updatedTz) {
updateTimezone(updatedTz); updateTimezone(updatedTz);
} }
}, [timezone]); }, [timezone, updateTimezone]);
return ( return (
<Select <Select
ariaLabel={t('Timezone')} ariaLabel={t('Timezone selector')}
css={{ minWidth: MIN_SELECT_WIDTH }} // smallest size for current values css={{ minWidth: MIN_SELECT_WIDTH }} // smallest size for current values
onChange={onTimezoneChange} onChange={onTimezoneChange}
value={timezone || DEFAULT_TIMEZONE} value={timezone || DEFAULT_TIMEZONE.value}
options={TIMEZONE_OPTIONS} options={TIMEZONE_OPTIONS}
/> />
); );