Skip to content

Commit

Permalink
fix: update values for default timezone selector (#17124)
Browse files Browse the repository at this point in the history
* update values for default timezone selector

* fix casing and comment

* Update TimezoneSelector.test.tsx
  • Loading branch information
eschutho committed Oct 18, 2021
1 parent 2ad9101 commit ae4ced8
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@
*/
import React from 'react';
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';

describe('TimezoneSelector', () => {
let timezone: string;
let timezone: string | undefined;
const onTimezoneChange = jest.fn(zone => {
timezone = zone;
});
beforeEach(() => {
timezone = undefined;
});
it('renders a TimezoneSelector with a default if undefined', () => {
jest.spyOn(moment.tz, 'guess').mockReturnValue('America/New_York');
render(
Expand All @@ -36,6 +40,27 @@ describe('TimezoneSelector', () => {
);
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 () => {
render(
<TimezoneSelector
Expand Down
33 changes: 20 additions & 13 deletions superset-frontend/src/components/TimezoneSelector/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@
* under the License.
*/

import React, { useEffect, useRef } from 'react';
import React, { useEffect, useRef, useCallback } from 'react';
import moment from 'moment-timezone';
import { t } from '@superset-ui/core';
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 offsetsToName = {
Expand All @@ -37,7 +41,7 @@ const offsetsToName = {
'-540-480': ['Alaska Standard Time', 'Alaska Daylight Time'],
'-600-600': ['Hawaii Standard Time', 'Hawaii 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'],
};

Expand Down Expand Up @@ -96,28 +100,31 @@ const TimezoneSelector = ({ onTimezoneChange, timezone }: TimezoneProps) => {
const prevTimezone = useRef(timezone);
const matchTimezoneToOptions = (timezone: string) =>
TIMEZONE_OPTIONS.find(option => option.offsets === getOffsetKey(timezone))
?.value || DEFAULT_TIMEZONE;
?.value || DEFAULT_TIMEZONE.value;

const updateTimezone = (tz: string) => {
// update the ref to track changes
prevTimezone.current = tz;
// the parent component contains the state for the value
onTimezoneChange(tz);
};
const updateTimezone = useCallback(
(tz: string) => {
// update the ref to track changes
prevTimezone.current = tz;
// the parent component contains the state for the value
onTimezoneChange(tz);
},
[onTimezoneChange],
);

useEffect(() => {
const updatedTz = matchTimezoneToOptions(timezone || moment.tz.guess());
if (prevTimezone.current !== updatedTz) {
updateTimezone(updatedTz);
}
}, [timezone]);
}, [timezone, updateTimezone]);

return (
<Select
ariaLabel={t('Timezone')}
ariaLabel={t('Timezone selector')}
css={{ minWidth: MIN_SELECT_WIDTH }} // smallest size for current values
onChange={onTimezoneChange}
value={timezone || DEFAULT_TIMEZONE}
value={timezone || DEFAULT_TIMEZONE.value}
options={TIMEZONE_OPTIONS}
/>
);
Expand Down

0 comments on commit ae4ced8

Please sign in to comment.