From 5677400ba846ebe1446d369f5984299afda20cee Mon Sep 17 00:00:00 2001 From: Eric Briscoe Date: Thu, 13 Oct 2022 09:52:35 -0700 Subject: [PATCH] fix(CustomFrame): Resolves issue #21731 where date range in explore throws runtime error (#21776) --- .../components/CustomFrame.test.tsx | 54 +++++++++++++++++++ .../components/CustomFrame.tsx | 18 ++++--- 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/components/CustomFrame.test.tsx b/superset-frontend/src/explore/components/controls/DateFilterControl/components/CustomFrame.test.tsx index aa7da5fedfb57..5a26d728a725a 100644 --- a/superset-frontend/src/explore/components/controls/DateFilterControl/components/CustomFrame.test.tsx +++ b/superset-frontend/src/explore/components/controls/DateFilterControl/components/CustomFrame.test.tsx @@ -37,6 +37,12 @@ const store = mockStore({ common: { locale: 'en' }, }); +// case when common.locale is not populated +const emptyStore = mockStore({}); + +// case when common.locale is populated with invalid locale +const invalidStore = mockStore({ common: { locale: 'invalid_locale' } }); + test('renders with default props', () => { render( @@ -51,6 +57,54 @@ test('renders with default props', () => { expect(screen.getByRole('img', { name: 'calendar' })).toBeInTheDocument(); }); +test('renders with empty store', () => { + render( + + + , + ); + expect(screen.getByText('Configure custom time range')).toBeInTheDocument(); + expect(screen.getByText('Relative Date/Time')).toBeInTheDocument(); + expect(screen.getByRole('spinbutton')).toBeInTheDocument(); + expect(screen.getByText('Days Before')).toBeInTheDocument(); + expect(screen.getByText('Specific Date/Time')).toBeInTheDocument(); + expect(screen.getByRole('img', { name: 'calendar' })).toBeInTheDocument(); +}); + +test('renders since and until with specific date/time with default locale', () => { + render( + + + , + ); + expect(screen.getAllByText('Specific Date/Time').length).toBe(2); + expect(screen.getAllByRole('img', { name: 'calendar' }).length).toBe(2); +}); + +test('renders with invalid locale', () => { + render( + + + , + ); + expect(screen.getByText('Configure custom time range')).toBeInTheDocument(); + expect(screen.getByText('Relative Date/Time')).toBeInTheDocument(); + expect(screen.getByRole('spinbutton')).toBeInTheDocument(); + expect(screen.getByText('Days Before')).toBeInTheDocument(); + expect(screen.getByText('Specific Date/Time')).toBeInTheDocument(); + expect(screen.getByRole('img', { name: 'calendar' })).toBeInTheDocument(); +}); + +test('renders since and until with specific date/time with invalid locale', () => { + render( + + + , + ); + expect(screen.getAllByText('Specific Date/Time').length).toBe(2); + expect(screen.getAllByRole('img', { name: 'calendar' }).length).toBe(2); +}); + test('renders since and until with specific date/time', () => { render( diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/components/CustomFrame.tsx b/superset-frontend/src/explore/components/controls/DateFilterControl/components/CustomFrame.tsx index 7f22125945cac..a75f064dae2b5 100644 --- a/superset-frontend/src/explore/components/controls/DateFilterControl/components/CustomFrame.tsx +++ b/superset-frontend/src/explore/components/controls/DateFilterControl/components/CustomFrame.tsx @@ -110,9 +110,15 @@ export function CustomFrame(props: FrameComponentProps) { } } - const localFromFlaskBabel = - useSelector((state: ExplorePageState) => state.common.locale) || 'en'; - const currentLocale = locales[LOCALE_MAPPING[localFromFlaskBabel]].DatePicker; + // check if there is a locale defined for explore + const localFromFlaskBabel = useSelector( + (state: ExplorePageState) => state?.common?.locale, + ); + // An undefined datePickerLocale is acceptable if no match is found in the LOCALE_MAPPING[localFromFlaskBabel] lookup + // and will fall back to antd's default locale when the antd DataPicker's prop locale === undefined + // This also protects us from the case where state is populated with a locale that antd locales does not recognize + const datePickerLocale = + locales[LOCALE_MAPPING[localFromFlaskBabel]]?.DatePicker; return (
@@ -141,7 +147,7 @@ export function CustomFrame(props: FrameComponentProps) { onChange('sinceDatetime', datetime.format(MOMENT_FORMAT)) } allowClear={false} - locale={currentLocale} + locale={datePickerLocale} /> )} @@ -194,7 +200,7 @@ export function CustomFrame(props: FrameComponentProps) { onChange('untilDatetime', datetime.format(MOMENT_FORMAT)) } allowClear={false} - locale={currentLocale} + locale={datePickerLocale} /> )} @@ -252,7 +258,7 @@ export function CustomFrame(props: FrameComponentProps) { } allowClear={false} className="control-anchor-to-datetime" - locale={currentLocale} + locale={datePickerLocale} /> )}