This is an automated email from the ASF dual-hosted git repository.

yongjiezhao pushed a commit to branch add-translation-for-DatePicker
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 9ebf3c3c00ecc80aa4747e9113a055423d47ffa3
Author: Yongjie Zhao <[email protected]>
AuthorDate: Sat Sep 3 12:24:57 2022 +0800

    adding unit test, and get local from Redux store
---
 .../components/CustomFrame.test.tsx                | 101 ++++++++++++++++++---
 .../DateFilterControl/components/CustomFrame.tsx   |  41 +++------
 .../controls/DateFilterControl/utils/constants.ts  |  17 ++++
 superset-frontend/src/explore/types.ts             |   1 +
 4 files changed, 119 insertions(+), 41 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 6cb5c4f56c..aa7da5fedf 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
@@ -17,6 +17,9 @@
  * under the License.
  */
 import React from 'react';
+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 userEvent from '@testing-library/user-event';
 import { CustomFrame } from '.';
@@ -29,8 +32,17 @@ const specificValue = '2021-03-16T00:00:00 : 
2021-03-17T00:00:00';
 const relativeNowValue = `DATEADD(DATETIME("now"), -7, day) : 
DATEADD(DATETIME("now"), 7, day)`;
 const relativeTodayValue = `DATEADD(DATETIME("today"), -7, day) : 
DATEADD(DATETIME("today"), 7, day)`;
 
+const mockStore = configureStore([thunk]);
+const store = mockStore({
+  common: { locale: 'en' },
+});
+
 test('renders with default props', () => {
-  render(<CustomFrame onChange={jest.fn()} value={emptyValue} />);
+  render(
+    <Provider store={store}>
+      <CustomFrame onChange={jest.fn()} value={emptyValue} />
+    </Provider>,
+  );
   expect(screen.getByText('Configure custom time range')).toBeInTheDocument();
   expect(screen.getByText('Relative Date/Time')).toBeInTheDocument();
   expect(screen.getByRole('spinbutton')).toBeInTheDocument();
@@ -40,13 +52,21 @@ test('renders with default props', () => {
 });
 
 test('renders since and until with specific date/time', () => {
-  render(<CustomFrame onChange={jest.fn()} value={specificValue} />);
+  render(
+    <Provider store={store}>
+      <CustomFrame onChange={jest.fn()} value={specificValue} />
+    </Provider>,
+  );
   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', () => {
-  render(<CustomFrame onChange={jest.fn()} value={relativeNowValue} />);
+  render(
+    <Provider store={store}>
+      <CustomFrame onChange={jest.fn()} value={relativeNowValue} />
+    </Provider>,
+  );
   expect(screen.getAllByText('Relative Date/Time').length).toBe(2);
   expect(screen.getAllByRole('spinbutton').length).toBe(2);
   expect(screen.getByText('Days Before')).toBeInTheDocument();
@@ -54,17 +74,29 @@ test('renders since and until with relative date/time', () 
=> {
 });
 
 test('renders since and until with Now option', () => {
-  render(<CustomFrame onChange={jest.fn()} value={nowValue} />);
+  render(
+    <Provider store={store}>
+      <CustomFrame onChange={jest.fn()} value={nowValue} />
+    </Provider>,
+  );
   expect(screen.getAllByText('Now').length).toBe(2);
 });
 
 test('renders since and until with Midnight option', () => {
-  render(<CustomFrame onChange={jest.fn()} value={todayValue} />);
+  render(
+    <Provider store={store}>
+      <CustomFrame onChange={jest.fn()} value={todayValue} />
+    </Provider>,
+  );
   expect(screen.getAllByText('Midnight').length).toBe(2);
 });
 
 test('renders anchor with now option', () => {
-  render(<CustomFrame onChange={jest.fn()} value={relativeNowValue} />);
+  render(
+    <Provider store={store}>
+      <CustomFrame onChange={jest.fn()} value={relativeNowValue} />
+    </Provider>,
+  );
   expect(screen.getByText('Anchor to')).toBeInTheDocument();
   expect(screen.getByRole('radio', { name: 'NOW' })).toBeInTheDocument();
   expect(screen.getByRole('radio', { name: 'Date/Time' })).toBeInTheDocument();
@@ -72,7 +104,11 @@ test('renders anchor with now option', () => {
 });
 
 test('renders anchor with date/time option', () => {
-  render(<CustomFrame onChange={jest.fn()} value={relativeTodayValue} />);
+  render(
+    <Provider store={store}>
+      <CustomFrame onChange={jest.fn()} value={relativeTodayValue} />
+    </Provider>,
+  );
   expect(screen.getByText('Anchor to')).toBeInTheDocument();
   expect(screen.getByRole('radio', { name: 'NOW' })).toBeInTheDocument();
   expect(screen.getByRole('radio', { name: 'Date/Time' })).toBeInTheDocument();
@@ -81,21 +117,33 @@ test('renders anchor with date/time option', () => {
 
 test('triggers onChange when the anchor changes', () => {
   const onChange = jest.fn();
-  render(<CustomFrame onChange={onChange} value={relativeNowValue} />);
+  render(
+    <Provider store={store}>
+      <CustomFrame onChange={onChange} value={relativeNowValue} />
+    </Provider>,
+  );
   userEvent.click(screen.getByRole('radio', { name: 'Date/Time' }));
   expect(onChange).toHaveBeenCalled();
 });
 
 test('triggers onChange when the value changes', () => {
   const onChange = jest.fn();
-  render(<CustomFrame onChange={onChange} value={emptyValue} />);
+  render(
+    <Provider store={store}>
+      <CustomFrame onChange={onChange} value={emptyValue} />
+    </Provider>,
+  );
   userEvent.click(screen.getByRole('img', { name: 'up' }));
   expect(onChange).toHaveBeenCalled();
 });
 
 test('triggers onChange when the mode changes', () => {
   const onChange = jest.fn();
-  render(<CustomFrame onChange={onChange} value={todayNowValue} />);
+  render(
+    <Provider store={store}>
+      <CustomFrame onChange={onChange} value={todayNowValue} />
+    </Provider>,
+  );
   userEvent.click(screen.getByTitle('Midnight'));
   userEvent.click(screen.getByTitle('Relative Date/Time'));
   userEvent.click(screen.getAllByTitle('Now')[1]);
@@ -105,7 +153,11 @@ test('triggers onChange when the mode changes', () => {
 
 test('triggers onChange when the grain changes', async () => {
   const onChange = jest.fn();
-  render(<CustomFrame onChange={onChange} value={relativeNowValue} />);
+  render(
+    <Provider store={store}>
+      <CustomFrame onChange={onChange} value={relativeNowValue} />
+    </Provider>,
+  );
   userEvent.click(screen.getByText('Days Before'));
   userEvent.click(screen.getByText('Weeks Before'));
   userEvent.click(screen.getByText('Days After'));
@@ -115,7 +167,11 @@ test('triggers onChange when the grain changes', async () 
=> {
 
 test('triggers onChange when the date changes', async () => {
   const onChange = jest.fn();
-  render(<CustomFrame onChange={onChange} value={specificValue} />);
+  render(
+    <Provider store={store}>
+      <CustomFrame onChange={onChange} value={specificValue} />
+    </Provider>,
+  );
   const inputs = screen.getAllByPlaceholderText('Select date');
   userEvent.click(inputs[0]);
   userEvent.click(screen.getAllByText('Now')[0]);
@@ -123,3 +179,24 @@ test('triggers onChange when the date changes', async () 
=> {
   userEvent.click(screen.getAllByText('Now')[1]);
   expect(onChange).toHaveBeenCalledTimes(2);
 });
+
+test('should translate Date Picker', () => {
+  const onChange = jest.fn();
+  const store = mockStore({
+    common: { locale: 'fr' },
+  });
+  render(
+    <Provider store={store}>
+      <CustomFrame onChange={onChange} value={specificValue} />
+    </Provider>,
+  );
+  userEvent.click(screen.getAllByRole('img', { name: 'calendar' })[0]);
+  expect(screen.getByText('2021')).toBeInTheDocument();
+  expect(screen.getByText('lu')).toBeInTheDocument();
+  expect(screen.getByText('ma')).toBeInTheDocument();
+  expect(screen.getByText('me')).toBeInTheDocument();
+  expect(screen.getByText('je')).toBeInTheDocument();
+  expect(screen.getByText('ve')).toBeInTheDocument();
+  expect(screen.getByText('sa')).toBeInTheDocument();
+  expect(screen.getByText('di')).toBeInTheDocument();
+});
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 e55d3ad779..7f22125945 100644
--- 
a/superset-frontend/src/explore/components/controls/DateFilterControl/components/CustomFrame.tsx
+++ 
b/superset-frontend/src/explore/components/controls/DateFilterControl/components/CustomFrame.tsx
@@ -17,9 +17,12 @@
  * under the License.
  */
 import React from 'react';
+import { useSelector } from 'react-redux';
 import { t } from '@superset-ui/core';
 import { Moment } from 'moment';
 import { isInteger } from 'lodash';
+// @ts-ignore
+import { locales } from 'antd/dist/antd-with-locales';
 import { Col, Row } from 'src/components';
 import { InputNumber } from 'src/components/Input';
 import { DatePicker } from 'src/components/DatePicker';
@@ -36,39 +39,15 @@ import {
   customTimeRangeDecode,
   customTimeRangeEncode,
   dttmToMoment,
+  LOCALE_MAPPING,
 } from 'src/explore/components/controls/DateFilterControl/utils';
 import {
   CustomRangeKey,
   FrameComponentProps,
 } from 'src/explore/components/controls/DateFilterControl/types';
-// @ts-ignore
-import { locales } from 'antd/dist/antd-with-locales';
-import { bootstrapData } from 'src/preamble';
-
-const languages = {
-  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',
-};
+import { ExplorePageState } from 'src/explore/types';
 
 export function CustomFrame(props: FrameComponentProps) {
-  let localLanguage = languages[bootstrapData.common.locale];
-  if (localLanguage == null) {
-    localLanguage = 'en_US';
-  }
-  const localeFiltrer = locales[localLanguage].DatePicker;
-
   const { customRange, matchedFlag } = customTimeRangeDecode(props.value);
   if (!matchedFlag) {
     props.onChange(customTimeRangeEncode(customRange));
@@ -131,6 +110,10 @@ export function CustomFrame(props: FrameComponentProps) {
     }
   }
 
+  const localFromFlaskBabel =
+    useSelector((state: ExplorePageState) => state.common.locale) || 'en';
+  const currentLocale = 
locales[LOCALE_MAPPING[localFromFlaskBabel]].DatePicker;
+
   return (
     <div data-test="custom-frame">
       <div className="section-title">{t('Configure custom time range')}</div>
@@ -158,7 +141,7 @@ export function CustomFrame(props: FrameComponentProps) {
                   onChange('sinceDatetime', datetime.format(MOMENT_FORMAT))
                 }
                 allowClear={false}
-                locale={localeFiltrer}
+                locale={currentLocale}
               />
             </Row>
           )}
@@ -211,7 +194,7 @@ export function CustomFrame(props: FrameComponentProps) {
                   onChange('untilDatetime', datetime.format(MOMENT_FORMAT))
                 }
                 allowClear={false}
-                locale={localeFiltrer}
+                locale={currentLocale}
               />
             </Row>
           )}
@@ -269,7 +252,7 @@ export function CustomFrame(props: FrameComponentProps) {
                   }
                   allowClear={false}
                   className="control-anchor-to-datetime"
-                  locale={localeFiltrer}
+                  locale={currentLocale}
                 />
               </Col>
             )}
diff --git 
a/superset-frontend/src/explore/components/controls/DateFilterControl/utils/constants.ts
 
b/superset-frontend/src/explore/components/controls/DateFilterControl/utils/constants.ts
index 99dac1bdbe..ca4a1f344d 100644
--- 
a/superset-frontend/src/explore/components/controls/DateFilterControl/utils/constants.ts
+++ 
b/superset-frontend/src/explore/components/controls/DateFilterControl/utils/constants.ts
@@ -114,3 +114,20 @@ export const SEVEN_DAYS_AGO = moment()
   .subtract(7, 'days')
   .format(MOMENT_FORMAT);
 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',
+};
diff --git a/superset-frontend/src/explore/types.ts 
b/superset-frontend/src/explore/types.ts
index 8518f51097..ec92a0c1ea 100644
--- a/superset-frontend/src/explore/types.ts
+++ b/superset-frontend/src/explore/types.ts
@@ -83,6 +83,7 @@ export interface ExplorePageState {
   common: {
     flash_messages: string[];
     conf: JsonObject;
+    locale: string;
   };
   charts: { [key: number]: ChartState };
   datasources: { [key: string]: Dataset };

Reply via email to