Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: Remove antd-with-locales import #29788

Merged
merged 4 commits into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
405 changes: 332 additions & 73 deletions superset-frontend/package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions superset-frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -232,14 +232,14 @@
"@storybook/addon-essentials": "8.1.11",
"@storybook/addon-links": "8.1.11",
"@storybook/addon-mdx-gfm": "8.1.11",
"@storybook/preview-api": "8.1.11",
"@storybook/components": "8.1.11",
"@storybook/preview-api": "8.1.11",
"@storybook/react": "8.1.11",
"@storybook/react-webpack5": "8.1.11",
"@svgr/webpack": "^8.1.0",
"@testing-library/dom": "^7.29.4",
"@testing-library/dom": "^8.20.1",
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "^11.2.0",
"@testing-library/react": "^12.1.5",
"@testing-library/react-hooks": "^5.1.3",
"@testing-library/user-event": "^12.7.0",
"@types/classnames": "^2.2.10",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@
"@ant-design/icons": "^5.0.1",
"@emotion/react": "^11.4.1",
"@superset-ui/core": "*",
"@testing-library/dom": "^7.29.4",
"@testing-library/dom": "^8.20.1",
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "^11.2.0",
"@testing-library/react": "^12.1.5",
"@testing-library/react-hooks": "^5.0.3",
"@testing-library/user-event": "^12.7.0",
"ace-builds": "^1.4.14",
Expand Down
4 changes: 2 additions & 2 deletions superset-frontend/packages/superset-ui-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@
"@emotion/cache": "^11.4.0",
"@emotion/react": "^11.4.1",
"@emotion/styled": "^11.3.0",
"@testing-library/dom": "^7.29.4",
"@testing-library/dom": "^8.20.1",
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "^11.2.0",
"@testing-library/react": "^12.1.5",
"@testing-library/user-event": "^12.7.0",
"@types/react": "*",
"@types/react-loadable": "*",
Expand Down
4 changes: 2 additions & 2 deletions superset-frontend/plugins/plugin-chart-table/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@
"@ant-design/icons": "^5.0.1",
"@superset-ui/chart-controls": "*",
"@superset-ui/core": "*",
"@testing-library/dom": "^7.29.4",
"@testing-library/dom": "^8.20.1",
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "^11.2.0",
"@testing-library/react": "^12.1.5",
"@testing-library/react-hooks": "^5.0.3",
"@testing-library/user-event": "^12.7.0",
"@types/classnames": "*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@
* specific language governing permissions and limitations
* under the License.
*/
import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { t, customTimeRangeDecode } from '@superset-ui/core';
import type { PickerLocale } from 'antd/lib/date-picker/generatePicker';
import { Moment } from 'moment';
import { isInteger } from 'lodash';
// @ts-ignore
import { locales } from 'antd/dist/antd-with-locales';
import { t, customTimeRangeDecode } from '@superset-ui/core';
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
import { Col, Row } from 'src/components';
import { InputNumber } from 'src/components/Input';
import { DatePicker } from 'src/components/DatePicker';
import { Radio } from 'src/components/Radio';
import Select from 'src/components/Select/Select';
import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
import {
SINCE_GRAIN_OPTIONS,
SINCE_MODE_OPTIONS,
Expand All @@ -44,9 +44,13 @@ import {
FrameComponentProps,
} from 'src/explore/components/controls/DateFilterControl/types';
import { ExplorePageState } from 'src/explore/types';
import Loading from 'src/components/Loading';

export function CustomFrame(props: FrameComponentProps) {
const { customRange, matchedFlag } = customTimeRangeDecode(props.value);
const [datePickerLocale, setDatePickerLocale] = useState<
PickerLocale | undefined | null
>(null);
if (!matchedFlag) {
props.onChange(customTimeRangeEncode(customRange));
}
Expand Down Expand Up @@ -112,11 +116,27 @@ export function CustomFrame(props: FrameComponentProps) {
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;
useEffect(() => {
if (datePickerLocale === null) {
if (localFromFlaskBabel && LOCALE_MAPPING[localFromFlaskBabel]) {
LOCALE_MAPPING[localFromFlaskBabel]()
.then((locale: { default: PickerLocale }) =>
setDatePickerLocale(locale.default),
)
.catch(() => setDatePickerLocale(undefined));
} else {
setDatePickerLocale(undefined);
}
}
}, [datePickerLocale, localFromFlaskBabel]);

if (datePickerLocale === null) {
return <Loading position="inline-centered" />;
}

return (
<div data-test="custom-frame">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import configureStore from 'redux-mock-store';
import { render, screen } from 'spec/helpers/testing-library';
import {
render,
screen,
waitForElementToBeRemoved,
waitFor,
} from 'spec/helpers/testing-library';
import userEvent from '@testing-library/user-event';
import { CustomFrame } from '../components';

Expand All @@ -44,12 +49,14 @@ const emptyStore = mockStore({});
// case when common.locale is populated with invalid locale
const invalidStore = mockStore({ common: { locale: 'invalid_locale' } });

test('renders with default props', () => {
test('renders with default props', async () => {
render(
<Provider store={store}>
<CustomFrame onChange={jest.fn()} value={emptyValue} />
</Provider>,
);
expect(screen.getByLabelText('Loading')).toBeVisible();
await waitForElementToBeRemoved(() => screen.queryByLabelText('Loading'));
expect(screen.getByText('Configure custom time range')).toBeInTheDocument();
expect(screen.getByText('Relative Date/Time')).toBeInTheDocument();
expect(screen.getByRole('spinbutton')).toBeInTheDocument();
Expand Down Expand Up @@ -106,88 +113,96 @@ test('renders since and until with specific date/time with invalid locale', () =
expect(screen.getAllByRole('img', { name: 'calendar' }).length).toBe(2);
});

test('renders since and until with specific date/time', () => {
test('renders since and until with specific date/time', async () => {
render(
<Provider store={store}>
<CustomFrame onChange={jest.fn()} value={specificValue} />
</Provider>,
);
await waitForElementToBeRemoved(() => screen.queryByLabelText('Loading'));
expect(screen.getAllByText('Specific Date/Time').length).toBe(2);
expect(screen.getAllByRole('img', { name: 'calendar' }).length).toBe(2);
});

test('renders since and until with relative date/time', () => {
test('renders since and until with relative date/time', async () => {
render(
<Provider store={store}>
<CustomFrame onChange={jest.fn()} value={relativeNowValue} />
</Provider>,
);
await waitForElementToBeRemoved(() => screen.queryByLabelText('Loading'));
expect(screen.getAllByText('Relative Date/Time').length).toBe(2);
expect(screen.getAllByRole('spinbutton').length).toBe(2);
expect(screen.getByText('Days Before')).toBeInTheDocument();
expect(screen.getByText('Days After')).toBeInTheDocument();
});

test('renders since and until with Now option', () => {
test('renders since and until with Now option', async () => {
render(
<Provider store={store}>
<CustomFrame onChange={jest.fn()} value={nowValue} />
</Provider>,
);
await waitForElementToBeRemoved(() => screen.queryByLabelText('Loading'));
expect(screen.getAllByText('Now').length).toBe(2);
});

test('renders since and until with Midnight option', () => {
test('renders since and until with Midnight option', async () => {
render(
<Provider store={store}>
<CustomFrame onChange={jest.fn()} value={todayValue} />
</Provider>,
);
await waitForElementToBeRemoved(() => screen.queryByLabelText('Loading'));
expect(screen.getAllByText('Midnight').length).toBe(2);
});

test('renders anchor with now option', () => {
test('renders anchor with now option', async () => {
render(
<Provider store={store}>
<CustomFrame onChange={jest.fn()} value={relativeNowValue} />
</Provider>,
);
await waitForElementToBeRemoved(() => screen.queryByLabelText('Loading'));
expect(screen.getByText('Anchor to')).toBeInTheDocument();
expect(screen.getByRole('radio', { name: 'NOW' })).toBeInTheDocument();
expect(screen.getByRole('radio', { name: 'Date/Time' })).toBeInTheDocument();
expect(screen.queryByPlaceholderText('Select date')).not.toBeInTheDocument();
});

test('renders anchor with date/time option', () => {
test('renders anchor with date/time option', async () => {
render(
<Provider store={store}>
<CustomFrame onChange={jest.fn()} value={relativeTodayValue} />
</Provider>,
);
await waitForElementToBeRemoved(() => screen.queryByLabelText('Loading'));
expect(screen.getByText('Anchor to')).toBeInTheDocument();
expect(screen.getByRole('radio', { name: 'NOW' })).toBeInTheDocument();
expect(screen.getByRole('radio', { name: 'Date/Time' })).toBeInTheDocument();
expect(screen.getByPlaceholderText('Select date')).toBeInTheDocument();
});

test('triggers onChange when the anchor changes', () => {
test('triggers onChange when the anchor changes', async () => {
const onChange = jest.fn();
render(
<Provider store={store}>
<CustomFrame onChange={onChange} value={relativeNowValue} />
</Provider>,
);
await waitForElementToBeRemoved(() => screen.queryByLabelText('Loading'));
userEvent.click(screen.getByRole('radio', { name: 'Date/Time' }));
expect(onChange).toHaveBeenCalled();
});

test('triggers onChange when the value changes', () => {
test('triggers onChange when the value changes', async () => {
const onChange = jest.fn();
render(
<Provider store={store}>
<CustomFrame onChange={onChange} value={emptyValue} />
</Provider>,
);
await waitForElementToBeRemoved(() => screen.queryByLabelText('Loading'));
userEvent.click(screen.getByRole('img', { name: 'up' }));
expect(onChange).toHaveBeenCalled();
});
Expand All @@ -199,6 +214,7 @@ test('triggers onChange when the mode changes', async () => {
<CustomFrame onChange={onChange} value={todayNowValue} />
</Provider>,
);
await waitForElementToBeRemoved(() => screen.queryByLabelText('Loading'));
userEvent.click(screen.getByTitle('Midnight'));
expect(await screen.findByTitle('Relative Date/Time')).toBeInTheDocument();
userEvent.click(screen.getByTitle('Relative Date/Time'));
Expand All @@ -207,7 +223,7 @@ test('triggers onChange when the mode changes', async () => {
await screen.findByText('Configure custom time range'),
).toBeInTheDocument();
userEvent.click(screen.getAllByTitle('Specific Date/Time')[1]);
expect(onChange).toHaveBeenCalledTimes(2);
await waitFor(() => expect(onChange).toHaveBeenCalledTimes(2));
});

test('triggers onChange when the grain changes', async () => {
Expand All @@ -217,13 +233,14 @@ test('triggers onChange when the grain changes', async () => {
<CustomFrame onChange={onChange} value={relativeNowValue} />
</Provider>,
);
await waitForElementToBeRemoved(() => screen.queryByLabelText('Loading'));
userEvent.click(screen.getByText('Days Before'));
expect(await screen.findByText('Weeks Before')).toBeInTheDocument();
userEvent.click(screen.getByText('Weeks Before'));
userEvent.click(screen.getByText('Days After'));
expect(await screen.findByText('Weeks After')).toBeInTheDocument();
userEvent.click(screen.getByText('Weeks After'));
expect(onChange).toHaveBeenCalledTimes(2);
await waitFor(() => expect(onChange).toHaveBeenCalledTimes(2));
});

test('triggers onChange when the date changes', async () => {
Expand All @@ -233,6 +250,7 @@ test('triggers onChange when the date changes', async () => {
<CustomFrame onChange={onChange} value={specificValue} />
</Provider>,
);
await waitForElementToBeRemoved(() => screen.queryByLabelText('Loading'));
const inputs = screen.getAllByPlaceholderText('Select date');
userEvent.click(inputs[0]);
userEvent.click(screen.getAllByText('Now')[0]);
Expand All @@ -241,7 +259,7 @@ test('triggers onChange when the date changes', async () => {
expect(onChange).toHaveBeenCalledTimes(2);
});

test('should translate Date Picker', () => {
test('should translate Date Picker', async () => {
const onChange = jest.fn();
const store = mockStore({
common: { locale: 'fr' },
Expand All @@ -251,6 +269,7 @@ test('should translate Date Picker', () => {
<CustomFrame onChange={onChange} value={specificValue} />
</Provider>,
);
await waitForElementToBeRemoved(() => screen.queryByLabelText('Loading'));
userEvent.click(screen.getAllByRole('img', { name: 'calendar' })[0]);
expect(screen.getByText('2021')).toBeInTheDocument();
expect(screen.getByText('lu')).toBeInTheDocument();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,20 +139,20 @@ export const SEVEN_DAYS_AGO = moment()
export const MIDNIGHT = moment().utc().startOf('day').format(MOMENT_FORMAT);

export const LOCALE_MAPPING = {
en: 'en_US',
fr: 'fr_FR',
es: 'es_ES',
it: 'it_IT',
zh: 'zh_CN',
ja: 'ja_JP',
de: 'de_DE',
pt: 'pt_PT',
pt_BR: 'pt_BR',
ru: 'ru_RU',
ko: 'ko_KR',
sk: 'sk_SK',
sl: 'sl_SI',
nl: 'nl_NL',
en: () => import('antd/lib/date-picker/locale/en_US'),
fr: () => import('antd/lib/date-picker/locale/fr_FR'),
es: () => import('antd/lib/date-picker/locale/es_ES'),
it: () => import('antd/lib/date-picker/locale/it_IT'),
zh: () => import('antd/lib/date-picker/locale/zh_CN'),
ja: () => import('antd/lib/date-picker/locale/ja_JP'),
de: () => import('antd/lib/date-picker/locale/de_DE'),
pt: () => import('antd/lib/date-picker/locale/pt_PT'),
pt_BR: () => import('antd/lib/date-picker/locale/pt_BR'),
ru: () => import('antd/lib/date-picker/locale/ru_RU'),
ko: () => import('antd/lib/date-picker/locale/ko_KR'),
sk: () => import('antd/lib/date-picker/locale/sk_SK'),
sl: () => import('antd/lib/date-picker/locale/sl_SI'),
nl: () => import('antd/lib/date-picker/locale/nl_NL'),
};

export enum DateFilterTestKey {
Expand Down
Loading