diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index baee1bc5aa921..6104c12ba1661 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -394,10 +394,10 @@ from flask_babel import lazy_gettext as _ then wrap our translatable strings with it, e.g. `_('Translate me')`. During extraction, string literals passed to `_` will be added to the generated `.po` file for each language for later translation. At runtime, the `_` function will return the translation of the given string for the current language, or the given string itself if no translation is available. -In JavaScript, the technique is similar: we import `t` (simple translation), `tn` (translation containing a number), and `TCT` (translating entire React Components). +In JavaScript, the technique is similar: we import `t` (simple translation), `tn` (translation containing a number). ```javascript -import {t, tn, TCT} from locales; +import {t, tn } from '@superset-ui/translation'; ``` ### Enabling language selection diff --git a/superset/assets/package.json b/superset/assets/package.json index 8293e96e45e81..581af12433d94 100644 --- a/superset/assets/package.json +++ b/superset/assets/package.json @@ -52,6 +52,7 @@ "@data-ui/theme": "^0.0.62", "@data-ui/xy-chart": "^0.0.61", "@superset-ui/core": "^0.0.7", + "@superset-ui/translation": "^0.2.1", "@vx/legend": "^0.0.170", "@vx/responsive": "0.0.172", "@vx/scale": "^0.0.165", @@ -78,7 +79,6 @@ "geojson-extent": "^0.3.2", "geolib": "^2.0.24", "immutable": "^3.8.2", - "jed": "^1.1.1", "jquery": "3.1.1", "json-bigint": "^0.3.0", "lodash": "^4.17.11", @@ -97,7 +97,6 @@ "react-bootstrap": "^0.31.5", "react-bootstrap-dialog": "^0.10.0", "react-bootstrap-slider": "2.1.5", - "react-bootstrap-table": "^4.3.1", "react-color": "^2.13.8", "react-datetime": "^2.14.0", "react-dnd": "^2.5.4", @@ -126,7 +125,6 @@ "redux-undo": "^1.0.0-beta9-9-7", "reselect": "^4.0.0", "shortid": "^2.2.6", - "sprintf-js": "^1.1.1", "srcdoc-polyfill": "^1.0.0", "supercluster": "^4.1.1", "underscore": "^1.8.3", diff --git a/superset/assets/spec/helpers/shim.js b/superset/assets/spec/helpers/shim.js index 2884157a4cf13..a9c2fa91f6938 100644 --- a/superset/assets/spec/helpers/shim.js +++ b/superset/assets/spec/helpers/shim.js @@ -4,6 +4,7 @@ import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'; import jsdom from 'jsdom'; import { configure } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; +import { configure as configureTranslation } from '@superset-ui/translation'; import setupSupersetClient from './setupSupersetClient'; @@ -48,4 +49,5 @@ global.window.location = { href: 'about:blank' }; global.window.performance = { now: () => new Date().getTime() }; global.$ = require('jquery')(global.window); +configureTranslation(); setupSupersetClient(); diff --git a/superset/assets/spec/javascripts/modules/utils_spec.jsx b/superset/assets/spec/javascripts/modules/utils_spec.jsx index 46a73ec2974a0..d1566c2dda988 100644 --- a/superset/assets/spec/javascripts/modules/utils_spec.jsx +++ b/superset/assets/spec/javascripts/modules/utils_spec.jsx @@ -5,7 +5,6 @@ import { d3TimeFormatPreset, defaultNumberFormatter, mainMetric, - getClientErrorObject, } from '../../../src/modules/utils'; describe('utils', () => { @@ -98,44 +97,4 @@ describe('utils', () => { expect(mainMetric(metrics)).toBe('foo'); }); }); - - describe('getClientErrorObject', () => { - it('Returns a Promise', () => { - const response = getClientErrorObject('error'); - expect(response.constructor === Promise).toBe(true); - }); - - it('Returns a Promise that resolves to an object with an error key', () => { - const error = 'error'; - - return getClientErrorObject(error).then((errorObj) => { - expect(errorObj).toMatchObject({ error }); - }); - }); - - it('Handles Response that can be parsed as json', () => { - const jsonError = { something: 'something', error: 'Error message' }; - const jsonErrorString = JSON.stringify(jsonError); - - return getClientErrorObject(new Response(jsonErrorString)).then((errorObj) => { - expect(errorObj).toMatchObject(jsonError); - }); - }); - - it('Handles Response that can be parsed as text', () => { - const textError = 'Hello I am a text error'; - - return getClientErrorObject(new Response(textError)).then((errorObj) => { - expect(errorObj).toMatchObject({ error: textError }); - }); - }); - - it('Handles plain text as input', () => { - const error = 'error'; - - return getClientErrorObject(error).then((errorObj) => { - expect(errorObj).toMatchObject({ error }); - }); - }); - }); }); diff --git a/superset/assets/spec/javascripts/utils/getClientErrorObject_spec.js b/superset/assets/spec/javascripts/utils/getClientErrorObject_spec.js new file mode 100644 index 0000000000000..2f05021acbe1f --- /dev/null +++ b/superset/assets/spec/javascripts/utils/getClientErrorObject_spec.js @@ -0,0 +1,41 @@ +import getClientErrorObject from '../../../src/utils/getClientErrorObject'; + +describe('getClientErrorObject()', () => { + it('Returns a Promise', () => { + const response = getClientErrorObject('error'); + expect(response.constructor === Promise).toBe(true); + }); + + it('Returns a Promise that resolves to an object with an error key', () => { + const error = 'error'; + + return getClientErrorObject(error).then((errorObj) => { + expect(errorObj).toMatchObject({ error }); + }); + }); + + it('Handles Response that can be parsed as json', () => { + const jsonError = { something: 'something', error: 'Error message' }; + const jsonErrorString = JSON.stringify(jsonError); + + return getClientErrorObject(new Response(jsonErrorString)).then((errorObj) => { + expect(errorObj).toMatchObject(jsonError); + }); + }); + + it('Handles Response that can be parsed as text', () => { + const textError = 'Hello I am a text error'; + + return getClientErrorObject(new Response(textError)).then((errorObj) => { + expect(errorObj).toMatchObject({ error: textError }); + }); + }); + + it('Handles plain text as input', () => { + const error = 'error'; + + return getClientErrorObject(error).then((errorObj) => { + expect(errorObj).toMatchObject({ error }); + }); + }); +}); diff --git a/superset/assets/src/CRUD/CollectionTable.jsx b/superset/assets/src/CRUD/CollectionTable.jsx index 514f86660e957..f38c3d3e5b341 100644 --- a/superset/assets/src/CRUD/CollectionTable.jsx +++ b/superset/assets/src/CRUD/CollectionTable.jsx @@ -1,14 +1,12 @@ import React from 'react'; import PropTypes from 'prop-types'; import shortid from 'shortid'; - +import { t } from '@superset-ui/translation'; import Button from '../components/Button'; import Fieldset from './Fieldset'; import { recurseReactClone } from './utils'; import './styles.css'; -import { t } from '../locales'; - const propTypes = { collection: PropTypes.arrayOf(PropTypes.object).isRequired, itemGenerator: PropTypes.func, diff --git a/superset/assets/src/SqlLab/App.jsx b/superset/assets/src/SqlLab/App.jsx index 37be951f67bda..9e242c3bb024c 100644 --- a/superset/assets/src/SqlLab/App.jsx +++ b/superset/assets/src/SqlLab/App.jsx @@ -9,13 +9,13 @@ import getInitialState from './getInitialState'; import rootReducer from './reducers'; import { initEnhancer } from '../reduxUtils'; import App from './components/App'; -import { appSetup } from '../common'; +import setupApp from '../setup/setupApp'; import './main.less'; import '../../stylesheets/reactable-pagination.css'; import '../components/FilterableTable/FilterableTableStyles.css'; -appSetup(); +setupApp(); const appContainer = document.getElementById('app'); const bootstrapData = JSON.parse(appContainer.getAttribute('data-bootstrap')); diff --git a/superset/assets/src/SqlLab/actions.js b/superset/assets/src/SqlLab/actions.js index 6d2b6af1a8a71..e8690145c8bf2 100644 --- a/superset/assets/src/SqlLab/actions.js +++ b/superset/assets/src/SqlLab/actions.js @@ -1,15 +1,15 @@ import shortid from 'shortid'; import JSONbig from 'json-bigint'; +import { t } from '@superset-ui/translation'; import { SupersetClient } from '@superset-ui/core'; import { now } from '../modules/dates'; -import { t } from '../locales'; import { addSuccessToast as addSuccessToastAction, addDangerToast as addDangerToastAction, addInfoToast as addInfoToastAction, } from '../messageToasts/actions'; -import { COMMON_ERR_MESSAGES } from '../utils/common'; +import COMMON_ERR_MESSAGES from '../utils/errorMessages'; export const RESET_STATE = 'RESET_STATE'; export const ADD_QUERY_EDITOR = 'ADD_QUERY_EDITOR'; @@ -153,7 +153,7 @@ export function runQuery(query) { .catch((error) => { let message = error.error || error.statusText || t('Unknown error'); if (message.includes('CSRF token')) { - message = COMMON_ERR_MESSAGES.SESSION_TIMED_OUT; + message = t(COMMON_ERR_MESSAGES.SESSION_TIMED_OUT); } // @TODO how to verify link? dispatch(queryFailed(query, message, error.link)); diff --git a/superset/assets/src/SqlLab/components/ExploreResultsButton.jsx b/superset/assets/src/SqlLab/components/ExploreResultsButton.jsx index 329f73165780c..06cddbc5f1775 100644 --- a/superset/assets/src/SqlLab/components/ExploreResultsButton.jsx +++ b/superset/assets/src/SqlLab/components/ExploreResultsButton.jsx @@ -5,12 +5,12 @@ import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import { Alert } from 'react-bootstrap'; import Dialog from 'react-bootstrap-dialog'; +import { t } from '@superset-ui/translation'; import shortid from 'shortid'; import { exportChart } from '../../explore/exploreUtils'; import * as actions from '../actions'; import InfoTooltipWithTrigger from '../../components/InfoTooltipWithTrigger'; -import { t } from '../../locales'; import Button from '../../components/Button'; const propTypes = { diff --git a/superset/assets/src/SqlLab/components/HighlightedSql.jsx b/superset/assets/src/SqlLab/components/HighlightedSql.jsx index 119e8d3b53b31..0cce92dc62f4c 100644 --- a/superset/assets/src/SqlLab/components/HighlightedSql.jsx +++ b/superset/assets/src/SqlLab/components/HighlightedSql.jsx @@ -1,12 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; - import SyntaxHighlighter, { registerLanguage } from 'react-syntax-highlighter/dist/light'; import sql from 'react-syntax-highlighter/dist/languages/hljs/sql'; import github from 'react-syntax-highlighter/dist/styles/hljs/github'; +import { t } from '@superset-ui/translation'; import ModalTrigger from '../../components/ModalTrigger'; -import { t } from '../../locales'; registerLanguage('sql', sql); diff --git a/superset/assets/src/SqlLab/components/QueryHistory.jsx b/superset/assets/src/SqlLab/components/QueryHistory.jsx index 442bc4c41ac32..2c246e4e803e5 100644 --- a/superset/assets/src/SqlLab/components/QueryHistory.jsx +++ b/superset/assets/src/SqlLab/components/QueryHistory.jsx @@ -1,9 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Alert } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; import QueryTable from './QueryTable'; -import { t } from '../../locales'; const propTypes = { queries: PropTypes.array.isRequired, diff --git a/superset/assets/src/SqlLab/components/QuerySearch.jsx b/superset/assets/src/SqlLab/components/QuerySearch.jsx index 9e920295a0993..62d02556cc533 100644 --- a/superset/assets/src/SqlLab/components/QuerySearch.jsx +++ b/superset/assets/src/SqlLab/components/QuerySearch.jsx @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Button } from 'react-bootstrap'; import Select from 'react-select'; +import { t } from '@superset-ui/translation'; import { SupersetClient } from '@superset-ui/core'; import Loading from '../../components/Loading'; @@ -14,7 +15,6 @@ import { } from '../../modules/dates'; import { STATUS_OPTIONS, TIME_OPTIONS } from '../constants'; import AsyncSelect from '../../components/AsyncSelect'; -import { t } from '../../locales'; const propTypes = { actions: PropTypes.object.isRequired, diff --git a/superset/assets/src/SqlLab/components/QueryTable.jsx b/superset/assets/src/SqlLab/components/QueryTable.jsx index 9e539636e1251..c4dc6c8373791 100644 --- a/superset/assets/src/SqlLab/components/QueryTable.jsx +++ b/superset/assets/src/SqlLab/components/QueryTable.jsx @@ -1,9 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; - import moment from 'moment'; import { Table } from 'reactable'; import { Label, ProgressBar, Well } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; + import Link from './Link'; import ResultSet from './ResultSet'; import ModalTrigger from '../../components/ModalTrigger'; @@ -11,7 +12,6 @@ import HighlightedSql from './HighlightedSql'; import { fDuration } from '../../modules/dates'; import { storeQuery } from '../../utils/common'; import QueryStateLabel from './QueryStateLabel'; -import { t } from '../../locales'; const propTypes = { columns: PropTypes.array, diff --git a/superset/assets/src/SqlLab/components/ResultSet.jsx b/superset/assets/src/SqlLab/components/ResultSet.jsx index 6fa820057cce0..6b482e43127a9 100644 --- a/superset/assets/src/SqlLab/components/ResultSet.jsx +++ b/superset/assets/src/SqlLab/components/ResultSet.jsx @@ -2,13 +2,13 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Alert, Button, ButtonGroup, ProgressBar } from 'react-bootstrap'; import shortid from 'shortid'; +import { t } from '@superset-ui/translation'; import Loading from '../../components/Loading'; import ExploreResultsButton from './ExploreResultsButton'; import HighlightedSql from './HighlightedSql'; import FilterableTable from '../../components/FilterableTable/FilterableTable'; import QueryStateLabel from './QueryStateLabel'; -import { t } from '../../locales'; const propTypes = { actions: PropTypes.object, diff --git a/superset/assets/src/SqlLab/components/RunQueryActionButton.jsx b/superset/assets/src/SqlLab/components/RunQueryActionButton.jsx index dd1d8b0250616..a5b8daed46803 100644 --- a/superset/assets/src/SqlLab/components/RunQueryActionButton.jsx +++ b/superset/assets/src/SqlLab/components/RunQueryActionButton.jsx @@ -1,7 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { t } from '@superset-ui/translation'; + import Button from '../../components/Button'; -import { t } from '../../locales'; const propTypes = { allowAsync: PropTypes.bool.isRequired, diff --git a/superset/assets/src/SqlLab/components/SaveQuery.jsx b/superset/assets/src/SqlLab/components/SaveQuery.jsx index 007fd57bd04ca..8b2a28ca664cc 100644 --- a/superset/assets/src/SqlLab/components/SaveQuery.jsx +++ b/superset/assets/src/SqlLab/components/SaveQuery.jsx @@ -1,10 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FormControl, FormGroup, Row, Col } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; import Button from '../../components/Button'; import ModalTrigger from '../../components/ModalTrigger'; -import { t } from '../../locales'; const propTypes = { defaultLabel: PropTypes.string, diff --git a/superset/assets/src/SqlLab/components/ShareSqlLabQuery.jsx b/superset/assets/src/SqlLab/components/ShareSqlLabQuery.jsx index 55f8c8820dacc..f59129b29a8c7 100644 --- a/superset/assets/src/SqlLab/components/ShareSqlLabQuery.jsx +++ b/superset/assets/src/SqlLab/components/ShareSqlLabQuery.jsx @@ -1,12 +1,12 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Popover, OverlayTrigger } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; import Button from '../../components/Button'; import CopyToClipboard from '../../components/CopyToClipboard'; import { storeQuery } from '../../utils/common'; -import { getClientErrorObject } from '../../modules/utils'; -import { t } from '../../locales'; +import getClientErrorObject from '../../utils/getClientErrorObject'; import withToasts from '../../messageToasts/enhancers/withToasts'; const propTypes = { diff --git a/superset/assets/src/SqlLab/components/SouthPane.jsx b/superset/assets/src/SqlLab/components/SouthPane.jsx index ce81c8dfb1365..eddc8082312ae 100644 --- a/superset/assets/src/SqlLab/components/SouthPane.jsx +++ b/superset/assets/src/SqlLab/components/SouthPane.jsx @@ -4,12 +4,12 @@ import shortid from 'shortid'; import { Alert, Label, Tab, Tabs } from 'react-bootstrap'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; +import { t } from '@superset-ui/translation'; import * as Actions from '../actions'; import QueryHistory from './QueryHistory'; import ResultSet from './ResultSet'; import { STATUS_OPTIONS, STATE_BSSTYLE_MAP } from '../constants'; -import { t } from '../../locales'; /* editorQueries are queries executed by users passed from SqlEditor component diff --git a/superset/assets/src/SqlLab/components/SqlEditor.jsx b/superset/assets/src/SqlLab/components/SqlEditor.jsx index 7f82e02a6fa4d..e739efa518f71 100644 --- a/superset/assets/src/SqlLab/components/SqlEditor.jsx +++ b/superset/assets/src/SqlLab/components/SqlEditor.jsx @@ -14,6 +14,7 @@ import { Collapse, } from 'react-bootstrap'; import SplitPane from 'react-split-pane'; +import { t } from '@superset-ui/translation'; import Button from '../../components/Button'; import TemplateParamsEditor from './TemplateParamsEditor'; @@ -26,8 +27,6 @@ import SqlEditorLeftBar from './SqlEditorLeftBar'; import AceEditorWrapper from './AceEditorWrapper'; import { STATE_BSSTYLE_MAP } from '../constants'; import RunQueryActionButton from './RunQueryActionButton'; -import { t } from '../../locales'; - const propTypes = { actions: PropTypes.object.isRequired, diff --git a/superset/assets/src/SqlLab/components/SqlEditorLeftBar.jsx b/superset/assets/src/SqlLab/components/SqlEditorLeftBar.jsx index 12530eb3750a1..f0b4d1a19f295 100644 --- a/superset/assets/src/SqlLab/components/SqlEditorLeftBar.jsx +++ b/superset/assets/src/SqlLab/components/SqlEditorLeftBar.jsx @@ -4,12 +4,12 @@ import { ControlLabel, Button } from 'react-bootstrap'; import { connect } from 'react-redux'; import Select from 'react-virtualized-select'; import createFilterOptions from 'react-select-fast-filter-options'; +import { t } from '@superset-ui/translation'; import { SupersetClient } from '@superset-ui/core'; import TableElement from './TableElement'; import AsyncSelect from '../../components/AsyncSelect'; import RefreshLabel from '../../components/RefreshLabel'; -import { t } from '../../locales'; const propTypes = { queryEditor: PropTypes.object.isRequired, diff --git a/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx b/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx index 9bf3978592d69..43b73546cd238 100644 --- a/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx +++ b/superset/assets/src/SqlLab/components/TabbedSqlEditors.jsx @@ -4,11 +4,11 @@ import { DropdownButton, MenuItem, Tab, Tabs } from 'react-bootstrap'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import URI from 'urijs'; +import { t } from '@superset-ui/translation'; import * as Actions from '../actions'; import SqlEditor from './SqlEditor'; import { areArraysShallowEqual } from '../../reduxUtils'; -import { t } from '../../locales'; import TabStatusIcon from './TabStatusIcon'; const propTypes = { diff --git a/superset/assets/src/SqlLab/components/TableElement.jsx b/superset/assets/src/SqlLab/components/TableElement.jsx index 96fae9b0b373f..d87d7e5db152f 100644 --- a/superset/assets/src/SqlLab/components/TableElement.jsx +++ b/superset/assets/src/SqlLab/components/TableElement.jsx @@ -1,15 +1,14 @@ import React from 'react'; import PropTypes from 'prop-types'; - import { ButtonGroup, Collapse, Well } from 'react-bootstrap'; import shortid from 'shortid'; +import { t } from '@superset-ui/translation'; import CopyToClipboard from '../../components/CopyToClipboard'; import Link from './Link'; import ColumnElement from './ColumnElement'; import ModalTrigger from '../../components/ModalTrigger'; import Loading from '../../components/Loading'; -import { t } from '../../locales'; const propTypes = { table: PropTypes.object, diff --git a/superset/assets/src/SqlLab/components/TemplateParamsEditor.jsx b/superset/assets/src/SqlLab/components/TemplateParamsEditor.jsx index 8a3387ad54635..baed9409205cc 100644 --- a/superset/assets/src/SqlLab/components/TemplateParamsEditor.jsx +++ b/superset/assets/src/SqlLab/components/TemplateParamsEditor.jsx @@ -1,7 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Badge } from 'react-bootstrap'; - import AceEditor from 'react-ace'; import 'brace/mode/sql'; import 'brace/mode/json'; @@ -9,10 +8,11 @@ import 'brace/mode/html'; import 'brace/mode/markdown'; import 'brace/theme/textmate'; +import { t } from '@superset-ui/translation'; + import ModalTrigger from '../../components/ModalTrigger'; import InfoTooltipWithTrigger from '../../components/InfoTooltipWithTrigger'; import Button from '../../components/Button'; -import { t } from '../../locales'; const propTypes = { onChange: PropTypes.func, diff --git a/superset/assets/src/SqlLab/getInitialState.js b/superset/assets/src/SqlLab/getInitialState.js index aa98bf177456c..ba984c2b9cb51 100644 --- a/superset/assets/src/SqlLab/getInitialState.js +++ b/superset/assets/src/SqlLab/getInitialState.js @@ -1,5 +1,5 @@ import shortid from 'shortid'; -import { t } from '../locales'; +import { t } from '@superset-ui/translation'; import getToastsFromPyFlashMessages from '../messageToasts/utils/getToastsFromPyFlashMessages'; export default function getInitialState({ defaultDbId, ...restBootstrapData }) { diff --git a/superset/assets/src/SqlLab/reducers.js b/superset/assets/src/SqlLab/reducers.js index e1640a542691e..87d033251a071 100644 --- a/superset/assets/src/SqlLab/reducers.js +++ b/superset/assets/src/SqlLab/reducers.js @@ -1,7 +1,8 @@ import { combineReducers } from 'redux'; import shortid from 'shortid'; -import messageToasts from '../messageToasts/reducers'; +import { t } from '@superset-ui/translation'; +import messageToasts from '../messageToasts/reducers'; import getInitialState from './getInitialState'; import * as actions from './actions'; import { now } from '../modules/dates'; @@ -13,7 +14,6 @@ import { getFromArr, addToArr, } from '../reduxUtils'; -import { t } from '../locales'; export const sqlLabReducer = function (state = {}, action) { const actionHandlers = { diff --git a/superset/assets/src/addSlice/AddSliceContainer.jsx b/superset/assets/src/addSlice/AddSliceContainer.jsx index 0d876af537665..f46dbadfeefe9 100644 --- a/superset/assets/src/addSlice/AddSliceContainer.jsx +++ b/superset/assets/src/addSlice/AddSliceContainer.jsx @@ -2,8 +2,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Button, Panel } from 'react-bootstrap'; import Select from 'react-virtualized-select'; +import { t } from '@superset-ui/translation'; import visTypes from '../explore/visTypes'; -import { t } from '../locales'; const propTypes = { datasources: PropTypes.arrayOf(PropTypes.shape({ diff --git a/superset/assets/src/addSlice/App.jsx b/superset/assets/src/addSlice/App.jsx index 56469cc1d95eb..34154a9b2150a 100644 --- a/superset/assets/src/addSlice/App.jsx +++ b/superset/assets/src/addSlice/App.jsx @@ -1,9 +1,9 @@ import React from 'react'; import { hot } from 'react-hot-loader'; -import { appSetup } from '../common'; +import setupApp from '../setup/setupApp'; import AddSliceContainer from './AddSliceContainer'; -appSetup(); +setupApp(); const addSliceContainer = document.getElementById('js-add-slice-container'); const bootstrapData = JSON.parse(addSliceContainer.getAttribute('data-bootstrap')); diff --git a/superset/assets/src/chart/chartAction.js b/superset/assets/src/chart/chartAction.js index 2898740818d00..92bb8028fd7ae 100644 --- a/superset/assets/src/chart/chartAction.js +++ b/superset/assets/src/chart/chartAction.js @@ -1,13 +1,13 @@ /* global window, AbortController */ /* eslint no-undef: 'error' */ +import { t } from '@superset-ui/translation'; import { SupersetClient } from '@superset-ui/core'; import { getExploreUrlAndPayload, getAnnotationJsonUrl } from '../explore/exploreUtils'; import { requiresQuery, ANNOTATION_SOURCE_TYPES } from '../modules/AnnotationTypes'; import { addDangerToast } from '../messageToasts/actions'; import { Logger, LOG_ACTIONS_LOAD_CHART } from '../logger'; -import { getClientErrorObject } from '../modules/utils'; import { TIME_RANGE_SEPARATOR } from '../utils/common'; -import { t } from '../locales'; +import getClientErrorObject from '../utils/getClientErrorObject'; export const CHART_UPDATE_STARTED = 'CHART_UPDATE_STARTED'; export function chartUpdateStarted(queryController, latestQueryFormData, key) { diff --git a/superset/assets/src/chart/chartReducer.js b/superset/assets/src/chart/chartReducer.js index 65df6e50820b7..f6b608cca613f 100644 --- a/superset/assets/src/chart/chartReducer.js +++ b/superset/assets/src/chart/chartReducer.js @@ -1,7 +1,7 @@ /* eslint camelcase: 0 */ +import { t } from '@superset-ui/translation'; import { now } from '../modules/dates'; import * as actions from './chartAction'; -import { t } from '../locales'; export const chart = { id: 0, diff --git a/superset/assets/src/common.js b/superset/assets/src/common.js deleted file mode 100644 index 2dc0488479d5f..0000000000000 --- a/superset/assets/src/common.js +++ /dev/null @@ -1,42 +0,0 @@ -/* eslint global-require: 0 */ -import $ from 'jquery'; -import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'; -import { SupersetClient } from '@superset-ui/core'; -import { toggleCheckbox } from './modules/utils'; -import setupClient from './setup/setupClient'; -import setupColors from './setup/setupColors'; -import setupPlugins from './setup/setupPlugins'; - -setupColors(); -setupPlugins(); - -$(document).ready(function () { - $(':checkbox[data-checkbox-api-prefix]').change(function () { - const $this = $(this); - const prefix = $this.data('checkbox-api-prefix'); - const id = $this.attr('id'); - toggleCheckbox(prefix, '#' + id); - }); - - // for language picker dropdown - $('#language-picker a').click(function (ev) { - ev.preventDefault(); - SupersetClient.get({ - endpoint: ev.currentTarget.getAttribute('href'), - parseMethod: null, - }) - .then(() => { - location.reload(); - }); - }); -}); - -export function appSetup() { - setupClient(); - - // A set of hacks to allow apps to run within a FAB template - // this allows for the server side generated menus to function - window.$ = $; - window.jQuery = $; - require('bootstrap'); -} diff --git a/superset/assets/src/components/AlteredSliceTag.jsx b/superset/assets/src/components/AlteredSliceTag.jsx index a0c1f1ee5246c..bfde6f62bfe99 100644 --- a/superset/assets/src/components/AlteredSliceTag.jsx +++ b/superset/assets/src/components/AlteredSliceTag.jsx @@ -2,11 +2,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Table, Tr, Td, Thead, Th } from 'reactable'; import { isEqual, isEmpty } from 'lodash'; - +import { t } from '@superset-ui/translation'; import TooltipWrapper from './TooltipWrapper'; import { controls } from '../explore/controls'; import ModalTrigger from './ModalTrigger'; -import { t } from '../locales'; const propTypes = { origFormData: PropTypes.object.isRequired, diff --git a/superset/assets/src/components/AsyncSelect.jsx b/superset/assets/src/components/AsyncSelect.jsx index 4c2ae814b66fc..579535f6cf156 100644 --- a/superset/assets/src/components/AsyncSelect.jsx +++ b/superset/assets/src/components/AsyncSelect.jsx @@ -1,8 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import Select from 'react-select'; +import { t } from '@superset-ui/translation'; import { SupersetClient } from '@superset-ui/core'; -import { t } from '../locales'; const propTypes = { dataEndpoint: PropTypes.string.isRequired, diff --git a/superset/assets/src/components/CachedLabel.jsx b/superset/assets/src/components/CachedLabel.jsx index 9bfd03751aab9..845eac5709221 100644 --- a/superset/assets/src/components/CachedLabel.jsx +++ b/superset/assets/src/components/CachedLabel.jsx @@ -2,8 +2,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Label } from 'react-bootstrap'; import moment from 'moment'; +import { t } from '@superset-ui/translation'; import TooltipWrapper from './TooltipWrapper'; -import { t } from '../locales'; const propTypes = { onClick: PropTypes.func, diff --git a/superset/assets/src/components/CopyToClipboard.jsx b/superset/assets/src/components/CopyToClipboard.jsx index c2b9c573e4292..199e8d430f756 100644 --- a/superset/assets/src/components/CopyToClipboard.jsx +++ b/superset/assets/src/components/CopyToClipboard.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Tooltip, OverlayTrigger, MenuItem } from 'react-bootstrap'; -import { t } from '../locales'; +import { t } from '@superset-ui/translation'; const propTypes = { copyNode: PropTypes.node, diff --git a/superset/assets/src/components/EditableTitle.jsx b/superset/assets/src/components/EditableTitle.jsx index a3df71200110d..4d71ac7fd1056 100644 --- a/superset/assets/src/components/EditableTitle.jsx +++ b/superset/assets/src/components/EditableTitle.jsx @@ -1,8 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import cx from 'classnames'; +import { t } from '@superset-ui/translation'; import TooltipWrapper from './TooltipWrapper'; -import { t } from '../locales'; const propTypes = { title: PropTypes.string, diff --git a/superset/assets/src/components/FaveStar.jsx b/superset/assets/src/components/FaveStar.jsx index 60de9d143937e..cba83db6d423d 100644 --- a/superset/assets/src/components/FaveStar.jsx +++ b/superset/assets/src/components/FaveStar.jsx @@ -1,8 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import cx from 'classnames'; +import { t } from '@superset-ui/translation'; import TooltipWrapper from './TooltipWrapper'; -import { t } from '../locales'; const propTypes = { itemId: PropTypes.number.isRequired, diff --git a/superset/assets/src/components/RefreshChartOverlay.jsx b/superset/assets/src/components/RefreshChartOverlay.jsx index 9e3fced23aea7..841559a8b2306 100644 --- a/superset/assets/src/components/RefreshChartOverlay.jsx +++ b/superset/assets/src/components/RefreshChartOverlay.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { t } from '@superset-ui/translation'; import Button from '../components/Button'; -import { t } from '../locales'; const propTypes = { height: PropTypes.number.isRequired, diff --git a/superset/assets/src/components/TableLoader.jsx b/superset/assets/src/components/TableLoader.jsx index 2f57ab80d19d4..0d31934417bfb 100644 --- a/superset/assets/src/components/TableLoader.jsx +++ b/superset/assets/src/components/TableLoader.jsx @@ -1,10 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Table, Tr, Td } from 'reactable'; +import { t } from '@superset-ui/translation'; import { SupersetClient } from '@superset-ui/core'; import withToasts from '../messageToasts/enhancers/withToasts'; -import { t } from '../locales'; import Loading from '../components/Loading'; import '../../stylesheets/reactable-pagination.css'; diff --git a/superset/assets/src/components/URLShortLinkButton.jsx b/superset/assets/src/components/URLShortLinkButton.jsx index 47fd3329dca41..c2072db8ccd68 100644 --- a/superset/assets/src/components/URLShortLinkButton.jsx +++ b/superset/assets/src/components/URLShortLinkButton.jsx @@ -1,9 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Popover, OverlayTrigger } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; import CopyToClipboard from './CopyToClipboard'; import { getShortUrl } from '../utils/common'; -import { t } from '../locales'; import withToasts from '../messageToasts/enhancers/withToasts'; const propTypes = { diff --git a/superset/assets/src/components/URLShortLinkModal.jsx b/superset/assets/src/components/URLShortLinkModal.jsx index 907b239d6adf2..1ad4d21663bdb 100644 --- a/superset/assets/src/components/URLShortLinkModal.jsx +++ b/superset/assets/src/components/URLShortLinkModal.jsx @@ -1,8 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { t } from '@superset-ui/translation'; import CopyToClipboard from './CopyToClipboard'; import { getShortUrl } from '../utils/common'; -import { t } from '../locales'; import withToasts from '../messageToasts/enhancers/withToasts'; import ModalTrigger from './ModalTrigger'; diff --git a/superset/assets/src/dashboard/App.jsx b/superset/assets/src/dashboard/App.jsx index a1d8f2ec0a10d..865803b2bdeea 100644 --- a/superset/assets/src/dashboard/App.jsx +++ b/superset/assets/src/dashboard/App.jsx @@ -6,12 +6,14 @@ import { hot } from 'react-hot-loader'; import { initFeatureFlags } from 'src/featureFlags'; import { initEnhancer } from '../reduxUtils'; -import { appSetup } from '../common'; +import setupApp from '../setup/setupApp'; +import setupPlugins from '../setup/setupPlugins'; import DashboardContainer from './containers/Dashboard'; import getInitialState from './reducers/getInitialState'; import rootReducer from './reducers/index'; -appSetup(); +setupApp(); +setupPlugins(); const appContainer = document.getElementById('app'); const bootstrapData = JSON.parse(appContainer.getAttribute('data-bootstrap')); diff --git a/superset/assets/src/dashboard/actions/dashboardState.js b/superset/assets/src/dashboard/actions/dashboardState.js index 2ff139fcdb714..6fed016c15180 100644 --- a/superset/assets/src/dashboard/actions/dashboardState.js +++ b/superset/assets/src/dashboard/actions/dashboardState.js @@ -1,19 +1,19 @@ /* eslint camelcase: 0 */ import { ActionCreators as UndoActionCreators } from 'redux-undo'; +import { t } from '@superset-ui/translation'; import { SupersetClient } from '@superset-ui/core'; import { addChart, removeChart, refreshChart } from '../../chart/chartAction'; import { chart as initChart } from '../../chart/chartReducer'; import { fetchDatasourceMetadata } from '../../dashboard/actions/datasources'; import { applyDefaultFormData } from '../../explore/store'; -import { getClientErrorObject } from '../../modules/utils'; +import getClientErrorObject from '../../utils/getClientErrorObject'; import { Logger, LOG_ACTIONS_CHANGE_DASHBOARD_FILTER, LOG_ACTIONS_REFRESH_DASHBOARD, } from '../../logger'; import { SAVE_TYPE_OVERWRITE } from '../util/constants'; -import { t } from '../../locales'; import { addSuccessToast, addWarningToast, diff --git a/superset/assets/src/dashboard/actions/datasources.js b/superset/assets/src/dashboard/actions/datasources.js index 85d91bdafde06..f5e8a48da9c5c 100644 --- a/superset/assets/src/dashboard/actions/datasources.js +++ b/superset/assets/src/dashboard/actions/datasources.js @@ -1,5 +1,5 @@ import { SupersetClient } from '@superset-ui/core'; -import { getClientErrorObject } from '../../modules/utils'; +import getClientErrorObject from '../../utils/getClientErrorObject'; export const SET_DATASOURCE = 'SET_DATASOURCE'; export function setDatasource(datasource, key) { diff --git a/superset/assets/src/dashboard/actions/sliceEntities.js b/superset/assets/src/dashboard/actions/sliceEntities.js index 31a03db0d23d2..6194327a8c517 100644 --- a/superset/assets/src/dashboard/actions/sliceEntities.js +++ b/superset/assets/src/dashboard/actions/sliceEntities.js @@ -1,12 +1,10 @@ /* eslint camelcase: 0 */ +import { t } from '@superset-ui/translation'; import { SupersetClient } from '@superset-ui/core'; import { addDangerToast } from '../../messageToasts/actions'; -import { t } from '../../locales'; -import { - getDatasourceParameter, - getClientErrorObject, -} from '../../modules/utils'; +import { getDatasourceParameter } from '../../modules/utils'; +import getClientErrorObject from '../../utils/getClientErrorObject'; export const SET_ALL_SLICES = 'SET_ALL_SLICES'; export function setAllSlices(slices) { diff --git a/superset/assets/src/dashboard/components/AddSliceCard.jsx b/superset/assets/src/dashboard/components/AddSliceCard.jsx index a98546c727af7..12f72a2db75f2 100644 --- a/superset/assets/src/dashboard/components/AddSliceCard.jsx +++ b/superset/assets/src/dashboard/components/AddSliceCard.jsx @@ -1,7 +1,7 @@ import cx from 'classnames'; import React from 'react'; import PropTypes from 'prop-types'; -import { t } from '../../locales'; +import { t } from '@superset-ui/translation'; const propTypes = { datasourceLink: PropTypes.string, diff --git a/superset/assets/src/dashboard/components/BuilderComponentPane.jsx b/superset/assets/src/dashboard/components/BuilderComponentPane.jsx index 4bfb2bb1837cd..145dcc30a0517 100644 --- a/superset/assets/src/dashboard/components/BuilderComponentPane.jsx +++ b/superset/assets/src/dashboard/components/BuilderComponentPane.jsx @@ -4,6 +4,7 @@ import React from 'react'; import cx from 'classnames'; import { StickyContainer, Sticky } from 'react-sticky'; import { ParentSize } from '@vx/responsive'; +import { t } from '@superset-ui/translation'; import NewColumn from './gridComponents/new/NewColumn'; import NewDivider from './gridComponents/new/NewDivider'; @@ -12,7 +13,6 @@ import NewRow from './gridComponents/new/NewRow'; import NewTabs from './gridComponents/new/NewTabs'; import NewMarkdown from './gridComponents/new/NewMarkdown'; import SliceAdder from '../containers/SliceAdder'; -import { t } from '../../locales'; const SUPERSET_HEADER_HEIGHT = 59; diff --git a/superset/assets/src/dashboard/components/CodeModal.jsx b/superset/assets/src/dashboard/components/CodeModal.jsx index cc0c9f2a41fa3..c02f0f5e09645 100644 --- a/superset/assets/src/dashboard/components/CodeModal.jsx +++ b/superset/assets/src/dashboard/components/CodeModal.jsx @@ -1,8 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { t } from '@superset-ui/translation'; import ModalTrigger from '../../components/ModalTrigger'; -import { t } from '../../locales'; const propTypes = { triggerNode: PropTypes.node.isRequired, diff --git a/superset/assets/src/dashboard/components/CssEditor.jsx b/superset/assets/src/dashboard/components/CssEditor.jsx index 45ef86d63acdd..846ee8ab88e71 100644 --- a/superset/assets/src/dashboard/components/CssEditor.jsx +++ b/superset/assets/src/dashboard/components/CssEditor.jsx @@ -1,13 +1,12 @@ import React from 'react'; import PropTypes from 'prop-types'; import Select from 'react-select'; - import AceEditor from 'react-ace'; import 'brace/mode/css'; import 'brace/theme/github'; +import { t } from '@superset-ui/translation'; import ModalTrigger from '../../components/ModalTrigger'; -import { t } from '../../locales'; const propTypes = { initialCss: PropTypes.string, diff --git a/superset/assets/src/dashboard/components/Dashboard.jsx b/superset/assets/src/dashboard/components/Dashboard.jsx index 20c161b6cb805..fffcd69dd421a 100644 --- a/superset/assets/src/dashboard/components/Dashboard.jsx +++ b/superset/assets/src/dashboard/components/Dashboard.jsx @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { t } from '@superset-ui/translation'; import getChartIdsFromLayout from '../util/getChartIdsFromLayout'; import DashboardBuilder from '../containers/DashboardBuilder'; @@ -21,8 +22,6 @@ import { LOG_ACTIONS_FIRST_DASHBOARD_LOAD, } from '../../logger'; -import { t } from '../../locales'; - import '../stylesheets/index.less'; const propTypes = { diff --git a/superset/assets/src/dashboard/components/DeleteComponentModal.jsx b/superset/assets/src/dashboard/components/DeleteComponentModal.jsx index ea7721c037e12..6ebdef4525c33 100644 --- a/superset/assets/src/dashboard/components/DeleteComponentModal.jsx +++ b/superset/assets/src/dashboard/components/DeleteComponentModal.jsx @@ -1,9 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Button } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; import ModalTrigger from '../../components/ModalTrigger'; -import { t } from '../../locales'; const propTypes = { triggerNode: PropTypes.node.isRequired, diff --git a/superset/assets/src/dashboard/components/Header.jsx b/superset/assets/src/dashboard/components/Header.jsx index 1dfe8469a42d2..9cdafb80098fc 100644 --- a/superset/assets/src/dashboard/components/Header.jsx +++ b/superset/assets/src/dashboard/components/Header.jsx @@ -1,6 +1,7 @@ /* eslint-env browser */ import React from 'react'; import PropTypes from 'prop-types'; +import { t } from '@superset-ui/translation'; import HeaderActionsDropdown from './HeaderActionsDropdown'; import EditableTitle from '../../components/EditableTitle'; @@ -9,7 +10,6 @@ import FaveStar from '../../components/FaveStar'; import UndoRedoKeylisteners from './UndoRedoKeylisteners'; import { chartPropShape } from '../util/propShapes'; -import { t } from '../../locales'; import { UNDO_LIMIT, SAVE_TYPE_OVERWRITE, diff --git a/superset/assets/src/dashboard/components/HeaderActionsDropdown.jsx b/superset/assets/src/dashboard/components/HeaderActionsDropdown.jsx index 9967ce0328306..f97d4c1441a3f 100644 --- a/superset/assets/src/dashboard/components/HeaderActionsDropdown.jsx +++ b/superset/assets/src/dashboard/components/HeaderActionsDropdown.jsx @@ -2,13 +2,13 @@ import React from 'react'; import PropTypes from 'prop-types'; import { SupersetClient } from '@superset-ui/core'; import { DropdownButton, MenuItem } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; import CssEditor from './CssEditor'; import RefreshIntervalModal from './RefreshIntervalModal'; import SaveModal from './SaveModal'; import injectCustomCss from '../util/injectCustomCss'; import { SAVE_TYPE_NEWDASHBOARD } from '../util/constants'; -import { t } from '../../locales'; import URLShortLinkModal from '../../components/URLShortLinkModal'; import getDashboardUrl from '../util/getDashboardUrl'; diff --git a/superset/assets/src/dashboard/components/MissingChart.jsx b/superset/assets/src/dashboard/components/MissingChart.jsx index c45c445167fb3..56b28000d3eb8 100644 --- a/superset/assets/src/dashboard/components/MissingChart.jsx +++ b/superset/assets/src/dashboard/components/MissingChart.jsx @@ -1,8 +1,8 @@ import PropTypes from 'prop-types'; import React from 'react'; +import { t } from '@superset-ui/translation'; import Loading from '../../components/Loading'; -import { t } from '../../locales'; const propTypes = { height: PropTypes.number.isRequired, diff --git a/superset/assets/src/dashboard/components/RefreshIntervalModal.jsx b/superset/assets/src/dashboard/components/RefreshIntervalModal.jsx index 1ed4f82bb4ad5..e5d375ae4cf93 100644 --- a/superset/assets/src/dashboard/components/RefreshIntervalModal.jsx +++ b/superset/assets/src/dashboard/components/RefreshIntervalModal.jsx @@ -1,8 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import Select from 'react-select'; +import { t } from '@superset-ui/translation'; + import ModalTrigger from '../../components/ModalTrigger'; -import { t } from '../../locales'; const propTypes = { triggerNode: PropTypes.node.isRequired, diff --git a/superset/assets/src/dashboard/components/SaveModal.jsx b/superset/assets/src/dashboard/components/SaveModal.jsx index 2e3d94973f895..f726028eaac78 100644 --- a/superset/assets/src/dashboard/components/SaveModal.jsx +++ b/superset/assets/src/dashboard/components/SaveModal.jsx @@ -1,10 +1,10 @@ /* eslint-env browser */ import React from 'react'; import PropTypes from 'prop-types'; - import { Button, FormControl, FormGroup, Radio } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; + import ModalTrigger from '../../components/ModalTrigger'; -import { t } from '../../locales'; import Checkbox from '../../components/Checkbox'; import { SAVE_TYPE_OVERWRITE, SAVE_TYPE_NEWDASHBOARD } from '../util/constants'; diff --git a/superset/assets/src/dashboard/components/SliceAdder.jsx b/superset/assets/src/dashboard/components/SliceAdder.jsx index 608cfc15a3613..96b87e96c43b3 100644 --- a/superset/assets/src/dashboard/components/SliceAdder.jsx +++ b/superset/assets/src/dashboard/components/SliceAdder.jsx @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import { DropdownButton, MenuItem } from 'react-bootstrap'; import { CellMeasurer, CellMeasurerCache, List } from 'react-virtualized'; import SearchInput, { createFilter } from 'react-search-input'; +import { t } from '@superset-ui/translation'; import AddSliceCard from './AddSliceCard'; import AddSliceDragPreview from './dnd/AddSliceDragPreview'; @@ -12,7 +13,6 @@ import Loading from '../../components/Loading'; import { CHART_TYPE, NEW_COMPONENT_SOURCE_TYPE } from '../util/componentTypes'; import { NEW_CHART_ID, NEW_COMPONENTS_SOURCE_ID } from '../util/constants'; import { slicePropShape } from '../util/propShapes'; -import { t } from '../../locales'; const propTypes = { fetchAllSlices: PropTypes.func.isRequired, diff --git a/superset/assets/src/dashboard/components/SliceHeader.jsx b/superset/assets/src/dashboard/components/SliceHeader.jsx index 7631ba867e884..325b1fc0e75f8 100644 --- a/superset/assets/src/dashboard/components/SliceHeader.jsx +++ b/superset/assets/src/dashboard/components/SliceHeader.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { t } from '../../locales'; +import { t } from '@superset-ui/translation'; import EditableTitle from '../../components/EditableTitle'; import TooltipWrapper from '../../components/TooltipWrapper'; import SliceHeaderControls from './SliceHeaderControls'; diff --git a/superset/assets/src/dashboard/components/SliceHeaderControls.jsx b/superset/assets/src/dashboard/components/SliceHeaderControls.jsx index b5ee0b81df57c..de412f1680283 100644 --- a/superset/assets/src/dashboard/components/SliceHeaderControls.jsx +++ b/superset/assets/src/dashboard/components/SliceHeaderControls.jsx @@ -2,6 +2,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import moment from 'moment'; import { Dropdown, MenuItem } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; + import { Logger, LOG_ACTIONS_EXPLORE_DASHBOARD_CHART, @@ -9,8 +11,6 @@ import { LOG_ACTIONS_REFRESH_CHART, } from '../../logger'; -import { t } from '../../locales'; - const propTypes = { slice: PropTypes.object.isRequired, isCached: PropTypes.bool, diff --git a/superset/assets/src/dashboard/components/gridComponents/new/NewColumn.jsx b/superset/assets/src/dashboard/components/gridComponents/new/NewColumn.jsx index 4698736fbee33..1c691c74368d5 100644 --- a/superset/assets/src/dashboard/components/gridComponents/new/NewColumn.jsx +++ b/superset/assets/src/dashboard/components/gridComponents/new/NewColumn.jsx @@ -1,9 +1,9 @@ import React from 'react'; +import { t } from '@superset-ui/translation'; import { COLUMN_TYPE } from '../../../util/componentTypes'; import { NEW_COLUMN_ID } from '../../../util/constants'; import DraggableNewComponent from './DraggableNewComponent'; -import { t } from '../../../../locales'; export default function DraggableNewColumn() { return ( diff --git a/superset/assets/src/dashboard/components/gridComponents/new/NewDivider.jsx b/superset/assets/src/dashboard/components/gridComponents/new/NewDivider.jsx index 93518db0a1058..939ce6c8614cd 100644 --- a/superset/assets/src/dashboard/components/gridComponents/new/NewDivider.jsx +++ b/superset/assets/src/dashboard/components/gridComponents/new/NewDivider.jsx @@ -1,9 +1,9 @@ import React from 'react'; +import { t } from '@superset-ui/translation'; import { DIVIDER_TYPE } from '../../../util/componentTypes'; import { NEW_DIVIDER_ID } from '../../../util/constants'; import DraggableNewComponent from './DraggableNewComponent'; -import { t } from '../../../../locales'; export default function DraggableNewDivider() { return ( diff --git a/superset/assets/src/dashboard/components/gridComponents/new/NewHeader.jsx b/superset/assets/src/dashboard/components/gridComponents/new/NewHeader.jsx index 8acf85330a625..78ac9dd6935fa 100644 --- a/superset/assets/src/dashboard/components/gridComponents/new/NewHeader.jsx +++ b/superset/assets/src/dashboard/components/gridComponents/new/NewHeader.jsx @@ -1,9 +1,9 @@ import React from 'react'; +import { t } from '@superset-ui/translation'; import { HEADER_TYPE } from '../../../util/componentTypes'; import { NEW_HEADER_ID } from '../../../util/constants'; import DraggableNewComponent from './DraggableNewComponent'; -import { t } from '../../../../locales'; export default function DraggableNewHeader() { return ( diff --git a/superset/assets/src/dashboard/components/gridComponents/new/NewRow.jsx b/superset/assets/src/dashboard/components/gridComponents/new/NewRow.jsx index 7a2ae01a6b31e..68b0ae0ca80c7 100644 --- a/superset/assets/src/dashboard/components/gridComponents/new/NewRow.jsx +++ b/superset/assets/src/dashboard/components/gridComponents/new/NewRow.jsx @@ -1,9 +1,9 @@ import React from 'react'; +import { t } from '@superset-ui/translation'; import { ROW_TYPE } from '../../../util/componentTypes'; import { NEW_ROW_ID } from '../../../util/constants'; import DraggableNewComponent from './DraggableNewComponent'; -import { t } from '../../../../locales'; export default function DraggableNewRow() { return ( diff --git a/superset/assets/src/dashboard/components/gridComponents/new/NewTabs.jsx b/superset/assets/src/dashboard/components/gridComponents/new/NewTabs.jsx index a77b65e39f043..9127c94d4a0d0 100644 --- a/superset/assets/src/dashboard/components/gridComponents/new/NewTabs.jsx +++ b/superset/assets/src/dashboard/components/gridComponents/new/NewTabs.jsx @@ -1,9 +1,9 @@ import React from 'react'; +import { t } from '@superset-ui/translation'; import { TABS_TYPE } from '../../../util/componentTypes'; import { NEW_TABS_ID } from '../../../util/constants'; import DraggableNewComponent from './DraggableNewComponent'; -import { t } from '../../../../locales'; export default function DraggableNewTabs() { return ( diff --git a/superset/assets/src/dashboard/components/menu/MarkdownModeDropdown.jsx b/superset/assets/src/dashboard/components/menu/MarkdownModeDropdown.jsx index 10aa932233fb7..0be5e6f18deca 100644 --- a/superset/assets/src/dashboard/components/menu/MarkdownModeDropdown.jsx +++ b/superset/assets/src/dashboard/components/menu/MarkdownModeDropdown.jsx @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { t } from '../../../locales'; +import { t } from '@superset-ui/translation'; import PopoverDropdown from './PopoverDropdown'; diff --git a/superset/assets/src/dashboard/reducers/sliceEntities.js b/superset/assets/src/dashboard/reducers/sliceEntities.js index a96368a9ac76a..9f790bec58a66 100644 --- a/superset/assets/src/dashboard/reducers/sliceEntities.js +++ b/superset/assets/src/dashboard/reducers/sliceEntities.js @@ -1,11 +1,11 @@ +import { t } from '@superset-ui/translation'; + import { FETCH_ALL_SLICES_FAILED, FETCH_ALL_SLICES_STARTED, SET_ALL_SLICES, } from '../actions/sliceEntities'; -import { t } from '../../locales'; - export const initSliceEntities = { slices: {}, isLoading: true, diff --git a/superset/assets/src/dashboard/util/backgroundStyleOptions.js b/superset/assets/src/dashboard/util/backgroundStyleOptions.js index 926e7f14073ee..885801fb91409 100644 --- a/superset/assets/src/dashboard/util/backgroundStyleOptions.js +++ b/superset/assets/src/dashboard/util/backgroundStyleOptions.js @@ -1,4 +1,4 @@ -import { t } from '../../locales'; +import { t } from '@superset-ui/translation'; import { BACKGROUND_TRANSPARENT, BACKGROUND_WHITE } from './constants'; export default [ diff --git a/superset/assets/src/dashboard/util/headerStyleOptions.js b/superset/assets/src/dashboard/util/headerStyleOptions.js index a37bd5fdfc4c3..815b032b7e104 100644 --- a/superset/assets/src/dashboard/util/headerStyleOptions.js +++ b/superset/assets/src/dashboard/util/headerStyleOptions.js @@ -1,4 +1,4 @@ -import { t } from '../../locales'; +import { t } from '@superset-ui/translation'; import { SMALL_HEADER, MEDIUM_HEADER, LARGE_HEADER } from './constants'; export default [ diff --git a/superset/assets/src/datasource/DatasourceEditor.jsx b/superset/assets/src/datasource/DatasourceEditor.jsx index 7c7c8d212a560..98d0c9d76a788 100644 --- a/superset/assets/src/datasource/DatasourceEditor.jsx +++ b/superset/assets/src/datasource/DatasourceEditor.jsx @@ -2,10 +2,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Alert, Badge, Col, Label, Tabs, Tab, Well } from 'react-bootstrap'; import shortid from 'shortid'; +import { t } from '@superset-ui/translation'; import { SupersetClient } from '@superset-ui/core'; -import { t } from '../locales'; - import Button from '../components/Button'; import Loading from '../components/Loading'; import CheckboxControl from '../explore/components/controls/CheckboxControl'; diff --git a/superset/assets/src/datasource/DatasourceModal.jsx b/superset/assets/src/datasource/DatasourceModal.jsx index 0d4d8e217d1d9..0b232d7d6c63d 100644 --- a/superset/assets/src/datasource/DatasourceModal.jsx +++ b/superset/assets/src/datasource/DatasourceModal.jsx @@ -2,9 +2,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Alert, Button, Modal } from 'react-bootstrap'; import Dialog from 'react-bootstrap-dialog'; +import { t } from '@superset-ui/translation'; import { SupersetClient } from '@superset-ui/core'; -import { t } from '../locales'; import DatasourceEditor from '../datasource/DatasourceEditor'; import withToasts from '../messageToasts/enhancers/withToasts'; diff --git a/superset/assets/src/explore/App.jsx b/superset/assets/src/explore/App.jsx index 277d34c63783a..e14363ea0dec2 100644 --- a/superset/assets/src/explore/App.jsx +++ b/superset/assets/src/explore/App.jsx @@ -11,11 +11,13 @@ import ExploreViewContainer from './components/ExploreViewContainer'; import getInitialState from './reducers/getInitialState'; import rootReducer from './reducers/index'; -import { appSetup } from '../common'; +import setupApp from '../setup/setupApp'; +import setupPlugins from '../setup/setupPlugins'; import './main.css'; import '../../stylesheets/reactable-pagination.css'; -appSetup(); +setupApp(); +setupPlugins(); const exploreViewContainer = document.getElementById('app'); const bootstrapData = JSON.parse(exploreViewContainer.getAttribute('data-bootstrap')); diff --git a/superset/assets/src/explore/actions/exploreActions.js b/superset/assets/src/explore/actions/exploreActions.js index 2323bf2bb3e3a..df792b22cd453 100644 --- a/superset/assets/src/explore/actions/exploreActions.js +++ b/superset/assets/src/explore/actions/exploreActions.js @@ -1,7 +1,7 @@ /* eslint camelcase: 0 */ +import { t } from '@superset-ui/translation'; import { SupersetClient } from '@superset-ui/core'; import { addDangerToast } from '../../messageToasts/actions'; -import { t } from '../../locales'; const FAVESTAR_BASE_URL = '/superset/favstar/slice'; diff --git a/superset/assets/src/explore/components/AdhocFilterEditPopoverSimpleTabContent.jsx b/superset/assets/src/explore/components/AdhocFilterEditPopoverSimpleTabContent.jsx index 84f8fadc2ea68..5ddbe4a9c63fc 100644 --- a/superset/assets/src/explore/components/AdhocFilterEditPopoverSimpleTabContent.jsx +++ b/superset/assets/src/explore/components/AdhocFilterEditPopoverSimpleTabContent.jsx @@ -2,12 +2,12 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FormGroup } from 'react-bootstrap'; import VirtualizedSelect from 'react-virtualized-select'; +import { t } from '@superset-ui/translation'; import { SupersetClient } from '@superset-ui/core'; import AdhocFilter, { EXPRESSION_TYPES, CLAUSES } from '../AdhocFilter'; import adhocMetricType from '../propTypes/adhocMetricType'; import columnType from '../propTypes/columnType'; -import { t } from '../../locales'; import { OPERATORS, TABLE_ONLY_OPERATORS, diff --git a/superset/assets/src/explore/components/AdhocFilterEditPopoverSqlTabContent.jsx b/superset/assets/src/explore/components/AdhocFilterEditPopoverSqlTabContent.jsx index 6e5fe3c5618ee..e9c31d9195d06 100644 --- a/superset/assets/src/explore/components/AdhocFilterEditPopoverSqlTabContent.jsx +++ b/superset/assets/src/explore/components/AdhocFilterEditPopoverSqlTabContent.jsx @@ -7,6 +7,7 @@ import 'brace/theme/github'; import 'brace/ext/language_tools'; import { FormGroup } from 'react-bootstrap'; import VirtualizedSelect from 'react-virtualized-select'; +import { t } from '@superset-ui/translation'; import { sqlWords } from '../../SqlLab/components/AceEditorWrapper'; import AdhocFilter, { EXPRESSION_TYPES, CLAUSES } from '../AdhocFilter'; @@ -14,7 +15,6 @@ import adhocMetricType from '../propTypes/adhocMetricType'; import columnType from '../propTypes/columnType'; import OnPasteSelect from '../../components/OnPasteSelect'; import VirtualizedRendererWrap from '../../components/VirtualizedRendererWrap'; -import { t } from '../../locales'; const propTypes = { adhocFilter: PropTypes.instanceOf(AdhocFilter).isRequired, diff --git a/superset/assets/src/explore/components/AdhocMetricEditPopover.jsx b/superset/assets/src/explore/components/AdhocMetricEditPopover.jsx index 96b0314b45e82..73609a024c75c 100644 --- a/superset/assets/src/explore/components/AdhocMetricEditPopover.jsx +++ b/superset/assets/src/explore/components/AdhocMetricEditPopover.jsx @@ -7,9 +7,9 @@ import AceEditor from 'react-ace'; import 'brace/mode/sql'; import 'brace/theme/github'; import 'brace/ext/language_tools'; +import { t } from '@superset-ui/translation'; import { AGGREGATES } from '../constants'; -import { t } from '../../locales'; import VirtualizedRendererWrap from '../../components/VirtualizedRendererWrap'; import OnPasteSelect from '../../components/OnPasteSelect'; import AdhocMetricEditPopoverTitle from './AdhocMetricEditPopoverTitle'; diff --git a/superset/assets/src/explore/components/ControlHeader.jsx b/superset/assets/src/explore/components/ControlHeader.jsx index 9dcdc61889059..eca86c9325e03 100644 --- a/superset/assets/src/explore/components/ControlHeader.jsx +++ b/superset/assets/src/explore/components/ControlHeader.jsx @@ -1,8 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { t } from '@superset-ui/translation'; import { ControlLabel, OverlayTrigger, Tooltip } from 'react-bootstrap'; import InfoTooltipWithTrigger from '../../components/InfoTooltipWithTrigger'; -import { t } from '../../locales'; const propTypes = { name: PropTypes.string, diff --git a/superset/assets/src/explore/components/ControlPanelsContainer.jsx b/superset/assets/src/explore/components/ControlPanelsContainer.jsx index fba2e5761a9ce..7730a02eb9e31 100644 --- a/superset/assets/src/explore/components/ControlPanelsContainer.jsx +++ b/superset/assets/src/explore/components/ControlPanelsContainer.jsx @@ -4,13 +4,14 @@ import PropTypes from 'prop-types'; import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import { Alert, Tab, Tabs } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; + import visTypes, { sectionsToRender } from '../visTypes'; import ControlPanelSection from './ControlPanelSection'; import ControlRow from './ControlRow'; import Control from './Control'; import controls from '../controls'; import * as actions from '../actions/exploreActions'; -import { t } from '../../locales'; const propTypes = { actions: PropTypes.object.isRequired, diff --git a/superset/assets/src/explore/components/DisplayQueryButton.jsx b/superset/assets/src/explore/components/DisplayQueryButton.jsx index 0029eff48ede6..de18adc63ac6a 100644 --- a/superset/assets/src/explore/components/DisplayQueryButton.jsx +++ b/superset/assets/src/explore/components/DisplayQueryButton.jsx @@ -8,6 +8,7 @@ import jsonSyntax from 'react-syntax-highlighter/languages/hljs/json'; import github from 'react-syntax-highlighter/styles/hljs/github'; import { DropdownButton, MenuItem, Row, Col, FormControl } from 'react-bootstrap'; import { Table } from 'reactable'; +import { t } from '@superset-ui/translation'; import { SupersetClient } from '@superset-ui/core'; import CopyToClipboard from './../../components/CopyToClipboard'; @@ -16,7 +17,6 @@ import { getExploreUrlAndPayload } from '../exploreUtils'; import Loading from '../../components/Loading'; import ModalTrigger from './../../components/ModalTrigger'; import Button from '../../components/Button'; -import { t } from '../../locales'; import RowCountLabel from './RowCountLabel'; registerLanguage('markdown', markdownSyntax); diff --git a/superset/assets/src/explore/components/EmbedCodeButton.jsx b/superset/assets/src/explore/components/EmbedCodeButton.jsx index e6cccacce572c..ff28fbbfeb990 100644 --- a/superset/assets/src/explore/components/EmbedCodeButton.jsx +++ b/superset/assets/src/explore/components/EmbedCodeButton.jsx @@ -1,9 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Popover, OverlayTrigger } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; + import CopyToClipboard from './../../components/CopyToClipboard'; import { getExploreLongUrl } from '../exploreUtils'; -import { t } from '../../locales'; const propTypes = { latestQueryFormData: PropTypes.object.isRequired, diff --git a/superset/assets/src/explore/components/ExploreActionButtons.jsx b/superset/assets/src/explore/components/ExploreActionButtons.jsx index 1e604240e1dbe..6bb059c66bc17 100644 --- a/superset/assets/src/explore/components/ExploreActionButtons.jsx +++ b/superset/assets/src/explore/components/ExploreActionButtons.jsx @@ -1,10 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; import cx from 'classnames'; +import { t } from '@superset-ui/translation'; + import URLShortLinkButton from '../../components/URLShortLinkButton'; import EmbedCodeButton from './EmbedCodeButton'; import DisplayQueryButton from './DisplayQueryButton'; -import { t } from '../../locales'; import { exportChart, getExploreLongUrl } from '../exploreUtils'; const propTypes = { diff --git a/superset/assets/src/explore/components/ExploreChartHeader.jsx b/superset/assets/src/explore/components/ExploreChartHeader.jsx index 8c9ea91f2a590..3d6eb84f24c6e 100644 --- a/superset/assets/src/explore/components/ExploreChartHeader.jsx +++ b/superset/assets/src/explore/components/ExploreChartHeader.jsx @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { t } from '@superset-ui/translation'; import { chartPropShape } from '../../dashboard/util/propShapes'; import ExploreActionButtons from './ExploreActionButtons'; @@ -10,7 +11,6 @@ import FaveStar from '../../components/FaveStar'; import TooltipWrapper from '../../components/TooltipWrapper'; import Timer from '../../components/Timer'; import CachedLabel from '../../components/CachedLabel'; -import { t } from '../../locales'; const CHART_STATUS_MAP = { failed: 'danger', diff --git a/superset/assets/src/explore/components/RowCountLabel.jsx b/superset/assets/src/explore/components/RowCountLabel.jsx index 3367d1391f6d7..1ba21020fc423 100644 --- a/superset/assets/src/explore/components/RowCountLabel.jsx +++ b/superset/assets/src/explore/components/RowCountLabel.jsx @@ -1,8 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Label } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; -import { t } from '../../locales'; import { defaultNumberFormatter } from '../../modules/utils'; import TooltipWrapper from '../../components/TooltipWrapper'; diff --git a/superset/assets/src/explore/components/SaveModal.jsx b/superset/assets/src/explore/components/SaveModal.jsx index 5a1665913293b..930b6762fbaa4 100644 --- a/superset/assets/src/explore/components/SaveModal.jsx +++ b/superset/assets/src/explore/components/SaveModal.jsx @@ -2,10 +2,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; - import { Modal, Alert, Button, Radio } from 'react-bootstrap'; import Select from 'react-select'; -import { t } from '../../locales'; +import { t } from '@superset-ui/translation'; + import { supersetURL } from '../../utils/common'; import { EXPLORE_ONLY_VIZ_TYPE } from '../constants'; diff --git a/superset/assets/src/explore/components/controls/AdhocFilterControl.jsx b/superset/assets/src/explore/components/controls/AdhocFilterControl.jsx index b51704d4b62af..95983e5076aba 100644 --- a/superset/assets/src/explore/components/controls/AdhocFilterControl.jsx +++ b/superset/assets/src/explore/components/controls/AdhocFilterControl.jsx @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import VirtualizedSelect from 'react-virtualized-select'; -import { t } from '../../../locales'; +import { t } from '@superset-ui/translation'; import ControlHeader from '../ControlHeader'; import adhocFilterType from '../../propTypes/adhocFilterType'; import adhocMetricType from '../../propTypes/adhocMetricType'; diff --git a/superset/assets/src/explore/components/controls/AnnotationLayer.jsx b/superset/assets/src/explore/components/controls/AnnotationLayer.jsx index e1c4dcf3bc539..c2e6c27550cac 100644 --- a/superset/assets/src/explore/components/controls/AnnotationLayer.jsx +++ b/superset/assets/src/explore/components/controls/AnnotationLayer.jsx @@ -3,8 +3,9 @@ import PropTypes from 'prop-types'; import { CompactPicker } from 'react-color'; import { Button } from 'react-bootstrap'; import mathjs from 'mathjs'; - +import { t } from '@superset-ui/translation'; import { SupersetClient } from '@superset-ui/core'; + import SelectControl from './SelectControl'; import TextControl from './TextControl'; import CheckboxControl from './CheckboxControl'; @@ -21,8 +22,6 @@ import PopoverSection from '../../../components/PopoverSection'; import ControlHeader from '../ControlHeader'; import { nonEmpty } from '../../validators'; import getChartMetadataRegistry from '../../../visualizations/core/registries/ChartMetadataRegistrySingleton'; - -import { t } from '../../../locales'; import getCategoricalSchemeRegistry from '../../../modules/colors/CategoricalSchemeRegistrySingleton'; const AUTOMATIC_COLOR = ''; diff --git a/superset/assets/src/explore/components/controls/AnnotationLayerControl.jsx b/superset/assets/src/explore/components/controls/AnnotationLayerControl.jsx index b33dab01957ed..16eb4e6528a2e 100644 --- a/superset/assets/src/explore/components/controls/AnnotationLayerControl.jsx +++ b/superset/assets/src/explore/components/controls/AnnotationLayerControl.jsx @@ -2,14 +2,12 @@ import React from 'react'; import PropTypes from 'prop-types'; import { OverlayTrigger, Popover, ListGroup, ListGroupItem } from 'react-bootstrap'; import { connect } from 'react-redux'; +import { t } from '@superset-ui/translation'; import { getChartKey } from '../../exploreUtils'; import { runAnnotationQuery } from '../../../chart/chartAction'; import InfoTooltipWithTrigger from '../../../components/InfoTooltipWithTrigger'; - import AnnotationLayer from './AnnotationLayer'; -import { t } from '../../../locales'; - const propTypes = { colorScheme: PropTypes.string.isRequired, diff --git a/superset/assets/src/explore/components/controls/BoundsControl.jsx b/superset/assets/src/explore/components/controls/BoundsControl.jsx index 803a539619560..d19b11b34d507 100644 --- a/superset/assets/src/explore/components/controls/BoundsControl.jsx +++ b/superset/assets/src/explore/components/controls/BoundsControl.jsx @@ -1,8 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Col, Row, FormGroup, FormControl } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; import ControlHeader from '../ControlHeader'; -import { t } from '../../../locales'; const propTypes = { onChange: PropTypes.func, diff --git a/superset/assets/src/explore/components/controls/DatasourceControl.jsx b/superset/assets/src/explore/components/controls/DatasourceControl.jsx index cd5ad6b42407a..271eda9922f72 100644 --- a/superset/assets/src/explore/components/controls/DatasourceControl.jsx +++ b/superset/assets/src/explore/components/controls/DatasourceControl.jsx @@ -9,9 +9,9 @@ import { Tooltip, Well, } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; import ControlHeader from '../ControlHeader'; -import { t } from '../../../locales'; import DatasourceModal from '../../../datasource/DatasourceModal'; import ColumnOption from '../../../components/ColumnOption'; import MetricOption from '../../../components/MetricOption'; diff --git a/superset/assets/src/explore/components/controls/DateFilterControl.jsx b/superset/assets/src/explore/components/controls/DateFilterControl.jsx index 2c19b830b7848..ef5f497b77565 100644 --- a/superset/assets/src/explore/components/controls/DateFilterControl.jsx +++ b/superset/assets/src/explore/components/controls/DateFilterControl.jsx @@ -18,10 +18,10 @@ import { import Datetime from 'react-datetime'; import 'react-datetime/css/react-datetime.css'; import moment from 'moment'; +import { t } from '@superset-ui/translation'; import './DateFilterControl.css'; import ControlHeader from '../ControlHeader'; -import { t } from '../../../locales'; import PopoverSection from '../../../components/PopoverSection'; const TYPES = Object.freeze({ diff --git a/superset/assets/src/explore/components/controls/MetricsControl.jsx b/superset/assets/src/explore/components/controls/MetricsControl.jsx index 40f73da820527..7bbb4d111be14 100644 --- a/superset/assets/src/explore/components/controls/MetricsControl.jsx +++ b/superset/assets/src/explore/components/controls/MetricsControl.jsx @@ -1,8 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import VirtualizedSelect from 'react-virtualized-select'; +import { t } from '@superset-ui/translation'; + import ControlHeader from '../ControlHeader'; -import { t } from '../../../locales'; import VirtualizedRendererWrap from '../../../components/VirtualizedRendererWrap'; import OnPasteSelect from '../../../components/OnPasteSelect'; import MetricDefinitionOption from '../MetricDefinitionOption'; diff --git a/superset/assets/src/explore/components/controls/SelectAsyncControl.jsx b/superset/assets/src/explore/components/controls/SelectAsyncControl.jsx index 2fb778bd4a431..b004369be837e 100644 --- a/superset/assets/src/explore/components/controls/SelectAsyncControl.jsx +++ b/superset/assets/src/explore/components/controls/SelectAsyncControl.jsx @@ -1,9 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { t } from '@superset-ui/translation'; + import Select from '../../../components/AsyncSelect'; import ControlHeader from '../ControlHeader'; -import { t } from '../../../locales'; - import withToasts from '../../../messageToasts/enhancers/withToasts'; const propTypes = { diff --git a/superset/assets/src/explore/components/controls/SelectControl.jsx b/superset/assets/src/explore/components/controls/SelectControl.jsx index 4f1e8da469151..9e4dc29c1ec42 100644 --- a/superset/assets/src/explore/components/controls/SelectControl.jsx +++ b/superset/assets/src/explore/components/controls/SelectControl.jsx @@ -2,8 +2,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import VirtualizedSelect from 'react-virtualized-select'; import Select, { Creatable } from 'react-select'; +import { t } from '@superset-ui/translation'; + import ControlHeader from '../ControlHeader'; -import { t } from '../../../locales'; import VirtualizedRendererWrap from '../../../components/VirtualizedRendererWrap'; import OnPasteSelect from '../../../components/OnPasteSelect'; diff --git a/superset/assets/src/explore/components/controls/SpatialControl.jsx b/superset/assets/src/explore/components/controls/SpatialControl.jsx index dac5cb9ca8b96..5b9f8ac3fd745 100644 --- a/superset/assets/src/explore/components/controls/SpatialControl.jsx +++ b/superset/assets/src/explore/components/controls/SpatialControl.jsx @@ -3,12 +3,12 @@ import PropTypes from 'prop-types'; import { Row, Col, Button, Label, OverlayTrigger, Popover, } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; import ControlHeader from '../ControlHeader'; import SelectControl from './SelectControl'; import PopoverSection from '../../../components/PopoverSection'; import Checkbox from '../../../components/Checkbox'; -import { t } from '../../../locales'; const spatialTypes = { latlong: 'latlong', diff --git a/superset/assets/src/explore/components/controls/TextAreaControl.jsx b/superset/assets/src/explore/components/controls/TextAreaControl.jsx index 4a500ea307e78..c533804c0d90a 100644 --- a/superset/assets/src/explore/components/controls/TextAreaControl.jsx +++ b/superset/assets/src/explore/components/controls/TextAreaControl.jsx @@ -8,12 +8,12 @@ import 'brace/mode/json'; import 'brace/mode/html'; import 'brace/mode/markdown'; import 'brace/mode/javascript'; - import 'brace/theme/textmate'; +import { t } from '@superset-ui/translation'; + import ControlHeader from '../ControlHeader'; import ModalTrigger from '../../../components/ModalTrigger'; -import { t } from '../../../locales'; const propTypes = { name: PropTypes.string, diff --git a/superset/assets/src/explore/components/controls/VizTypeControl.jsx b/superset/assets/src/explore/components/controls/VizTypeControl.jsx index 3fb871e513f23..113d3c55c5b5b 100644 --- a/superset/assets/src/explore/components/controls/VizTypeControl.jsx +++ b/superset/assets/src/explore/components/controls/VizTypeControl.jsx @@ -3,9 +3,10 @@ import PropTypes from 'prop-types'; import { Label, Row, Col, FormControl, Modal, OverlayTrigger, Tooltip } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; + import visTypes from '../../visTypes'; import ControlHeader from '../ControlHeader'; -import { t } from '../../../locales'; const propTypes = { description: PropTypes.string, diff --git a/superset/assets/src/explore/controls.jsx b/superset/assets/src/explore/controls.jsx index ad32c52dd3739..92dfb1c24a618 100644 --- a/superset/assets/src/explore/controls.jsx +++ b/superset/assets/src/explore/controls.jsx @@ -39,6 +39,7 @@ * each and every visualization type. */ import React from 'react'; +import { t } from '@superset-ui/translation'; import { formatSelectOptionsForRange, formatSelectOptions, @@ -49,7 +50,6 @@ import { PRIMARY_COLOR } from '../modules/colors'; import { defaultViewport } from '../modules/geo'; import ColumnOption from '../components/ColumnOption'; import OptionDescription from '../components/OptionDescription'; -import { t } from '../locales'; import getCategoricalSchemeRegistry from '../modules/colors/CategoricalSchemeRegistrySingleton'; import getSequentialSchemeRegistry from '../modules/colors/SequentialSchemeRegistrySingleton'; diff --git a/superset/assets/src/explore/validators.js b/superset/assets/src/explore/validators.js index b1625d476f249..ebf4271ae4ff2 100644 --- a/superset/assets/src/explore/validators.js +++ b/superset/assets/src/explore/validators.js @@ -4,7 +4,7 @@ * as arguments and return something that evals to false if v is valid, * and an error message if not valid. * */ -import { t } from '../locales'; +import { t } from '@superset-ui/translation'; export function numeric(v) { if (v && isNaN(v)) { diff --git a/superset/assets/src/explore/visTypes.jsx b/superset/assets/src/explore/visTypes.jsx index 30aba88389f32..9a0943c2fe394 100644 --- a/superset/assets/src/explore/visTypes.jsx +++ b/superset/assets/src/explore/visTypes.jsx @@ -3,10 +3,11 @@ * and associated with each and every visualization type. */ import React from 'react'; +import { t } from '@superset-ui/translation'; + import { isFeatureEnabled, FeatureFlag } from 'src/featureFlags'; import { D3_TIME_FORMAT_OPTIONS } from './controls'; import * as v from './validators'; -import { t } from '../locales'; export const sections = { druidTimeSeries: { diff --git a/superset/assets/src/i18n.jsx b/superset/assets/src/i18n.jsx deleted file mode 100644 index b27f7392f2fff..0000000000000 --- a/superset/assets/src/i18n.jsx +++ /dev/null @@ -1,32 +0,0 @@ -import Jed from 'jed'; - -const DEFAULT_LANGUAGE_PACK = { - domain: 'superset', - locale_data: { - superset: { - '': { - domain: 'superset', - lang: 'en', - plural_forms: 'nplurals=1; plural=0', - }, - }, - }, -}; - -const i18n = (function () { - let languagePack = DEFAULT_LANGUAGE_PACK; - - if (typeof window !== 'undefined') { - const root = document.getElementById('app'); - const bootstrapData = root ? JSON.parse(root.getAttribute('data-bootstrap')) : {}; - if (bootstrapData.common && bootstrapData.common.language_pack) { - languagePack = bootstrapData.common.language_pack; - delete bootstrapData.common.locale; - delete bootstrapData.common.language_pack; - } - } - - return new Jed(languagePack); -}()); - -export default i18n; diff --git a/superset/assets/src/locales.jsx b/superset/assets/src/locales.jsx deleted file mode 100644 index 12b1a876461df..0000000000000 --- a/superset/assets/src/locales.jsx +++ /dev/null @@ -1,148 +0,0 @@ -/* eslint-disable global-require, import/no-dynamic-require */ -import React from 'react'; -import { sprintf } from 'sprintf-js'; -import i18n from './i18n'; - -function formatForReact(formatString, args) { - const rv = []; - let cursor = 0; - sprintf.parse(formatString).forEach((match, idx) => { - const cpoyMatch = match; - let copyIdx = idx; - if (typeof match === 'string') { - rv.push(match); - } else { - let arg = null; - if (match[2]) { - arg = args[0][match[2][0]]; - } else if (match[1]) { - arg = args[parseInt(match[1], 10) - 1]; - } else { - arg = args[cursor++]; - } - if (React.isValidElement(arg)) { - rv.push(React.cloneElement(arg, { key: idx })); - } else { - cpoyMatch[2] = null; - cpoyMatch[1] = 1; - rv.push( - {sprintf.format([cpoyMatch], [null, arg])} - ); - } - } - }); - return rv; -} - -function argsInvolveReact(args) { - if (args.some(React.isValidElement)) { - return true; - } - if (args.length === 1 && typeof args[0] === 'object') { - return Object.keys(args[0]).some(function (key) { - return React.isValidElement(args[0][key]); - }); - } - return false; -} - -export function parseComponentTemplate(string) { - const rv = {}; - function process(startPos, group, inGroup) { - const regex = /\[(.*?)(:|\])|\]/g; - let match; - const buf = []; - let satisfied = false; - let pos = regex.lastIndex = startPos; - match = regex.exec(string); - while (match !== null) { - const substr = string.substr(pos, match.index - pos); - if (substr !== '') { - buf.push(substr); - } - if (match[0] === ']') { - if (inGroup) { - satisfied = true; - break; - } else { - pos = regex.lastIndex; - continue; - } - } - if (match[2] === ']') { - pos = regex.lastIndex; - } else { - pos = regex.lastIndex = process(regex.lastIndex, match[1], true); - } - buf.push({ group: match[1] }); - match = regex.exec(string); - } - let endPos = regex.lastIndex; - if (!satisfied) { - const rest = string.substr(pos); - if (rest) { - buf.push(rest); - } - endPos = string.length; - } - rv[group] = buf; - return endPos; - } - process(0, 'root', false); - return rv; -} - -export function renderComponentTemplate(template, components) { - let idx = 0; - function renderGroup(group) { - const children = []; - (template[group] || []).forEach((item) => { - if (typeof item === 'string') { - children.push({item}); - } else { - children.push(renderGroup(item.group)); - } - }); - let reference = components[group] || ; - if (!React.isValidElement(reference)) { - reference = {reference}; - } - if (children.length > 0) { - return React.cloneElement(reference, { key: idx++ }, children); - } - return React.cloneElement(reference, { key: idx++ }); - } - return renderGroup('root'); -} - -export function format(formatString, args) { - if (argsInvolveReact(args)) { - return formatForReact(formatString, args); - } - return sprintf(formatString, ...args); -} - -export function gettext(string, ...args) { - if (!string || !i18n) { - return string; - } - - let rv = i18n.gettext(string); - if (args.length > 0) { - rv = format(rv, args); - } - return rv; -} - -export function ngettext(singular, plural, ...args) { - return format(i18n.ngettext(singular, plural, args[0] || 0), args); -} - -export function gettextComponentTemplate(template, components) { - const tmpl = parseComponentTemplate(i18n.gettext(template)); - return renderComponentTemplate(tmpl, components); -} - -export const t = gettext; -export const tn = ngettext; -export const tct = gettextComponentTemplate; diff --git a/superset/assets/src/modules/utils.js b/superset/assets/src/modules/utils.js index 1bb656fc90050..bc22c5a06b043 100644 --- a/superset/assets/src/modules/utils.js +++ b/superset/assets/src/modules/utils.js @@ -1,10 +1,7 @@ /* eslint camelcase: 0 */ -import d3 from 'd3'; import $ from 'jquery'; -import { SupersetClient } from '@superset-ui/core'; +import d3 from 'd3'; import { formatDate, UTC } from './dates'; -import { COMMON_ERR_MESSAGES } from '../utils/common'; -import { t } from '../locales'; const siFormatter = d3.format('.3s'); @@ -109,70 +106,6 @@ export function showModal(options) { $(options.modalSelector).modal('show'); } - -function showApiMessage(resp) { - const template = - '
' + - '
'; - const severity = resp.severity || 'info'; - $(template).addClass('alert-' + severity) - .append(resp.message) - .appendTo($('#alert-container')); -} - -export function getClientErrorObject(response) { - // takes a Response object as input, attempts to read response as Json if possible, - // and returns a Promise that resolves to a plain object with error key and text value. - return new Promise((resolve) => { - if (typeof response === 'string') { - resolve({ error: response }); - } else if (response && response.constructor === Response && !response.bodyUsed) { - // attempt to read the body as json, and fallback to text. we must clone the - // response in order to fallback to .text() because Response is single-read - response.clone().json().then((errorJson) => { - let error = { ...response, ...errorJson }; - if (error.stack) { - error = { - ...error, - error: t('Unexpected error: ') + - (error.description || t('(no description, click to see stack trace)')), - stacktrace: error.stack, - }; - } else if (error.responseText && error.responseText.indexOf('CSRF') >= 0) { - error = { - ...error, - error: COMMON_ERR_MESSAGES.SESSION_TIMED_OUT, - }; - } - resolve(error); - }).catch(() => { - // fall back to reading as text - response.text().then((errorText) => { - resolve({ ...response, error: errorText }); - }); - }); - } else { - // fall back to Response.statusText or generic error of we cannot read the response - resolve({ ...response, error: response.statusText || t('An error occurred') }); - } - }); - -} - -export function toggleCheckbox(apiUrlPrefix, selector) { - SupersetClient.get({ endpoint: apiUrlPrefix + $(selector)[0].checked }) - .then(() => {}) - .catch(response => - getClientErrorObject(response) - .then((parsedResp) => { - if (parsedResp && parsedResp.message) { - showApiMessage(parsedResp); - } - }), - ); -} - /** * Fix the height of the table body of a DataTable with scrollY set */ diff --git a/superset/assets/src/preamble.js b/superset/assets/src/preamble.js new file mode 100644 index 0000000000000..9d80dc9e59d4b --- /dev/null +++ b/superset/assets/src/preamble.js @@ -0,0 +1,24 @@ +import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'; +import { configure } from '@superset-ui/translation'; +import setupClient from './setup/setupClient'; +import setupColors from './setup/setupColors'; + +// Configure translation +if (typeof window !== 'undefined') { + const root = document.getElementById('app'); + const bootstrapData = root ? JSON.parse(root.getAttribute('data-bootstrap')) : {}; + if (bootstrapData.common && bootstrapData.common.language_pack) { + const languagePack = bootstrapData.common.language_pack; + configure({ languagePack }); + } else { + configure(); + } +} else { + configure(); +} + +// Setup SupersetClient +setupClient(); + +// Setup color palettes +setupColors(); diff --git a/superset/assets/src/profile/App.jsx b/superset/assets/src/profile/App.jsx index 3ad5bad015897..d4e175b3f36f9 100644 --- a/superset/assets/src/profile/App.jsx +++ b/superset/assets/src/profile/App.jsx @@ -7,11 +7,11 @@ import { Provider } from 'react-redux'; import App from './components/App'; import messageToastReducer from '../messageToasts/reducers'; import { initEnhancer } from '../reduxUtils'; -import { appSetup } from '../common'; +import setupApp from '../setup/setupApp'; import './main.css'; -appSetup(); +setupApp(); const profileViewContainer = document.getElementById('app'); const bootstrap = JSON.parse(profileViewContainer.getAttribute('data-bootstrap')); diff --git a/superset/assets/src/profile/components/App.jsx b/superset/assets/src/profile/components/App.jsx index 0cb9034182327..c71f7b2cdebe4 100644 --- a/superset/assets/src/profile/components/App.jsx +++ b/superset/assets/src/profile/components/App.jsx @@ -1,12 +1,13 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Col, Row, Tabs, Tab, Panel } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; + import Favorites from './Favorites'; import UserInfo from './UserInfo'; import Security from './Security'; import RecentActivity from './RecentActivity'; import CreatedContent from './CreatedContent'; -import { t } from '../../locales'; const propTypes = { user: PropTypes.object.isRequired, diff --git a/superset/assets/src/profile/components/CreatedContent.jsx b/superset/assets/src/profile/components/CreatedContent.jsx index 00d0f9d1eab56..976162fdc78c5 100644 --- a/superset/assets/src/profile/components/CreatedContent.jsx +++ b/superset/assets/src/profile/components/CreatedContent.jsx @@ -1,8 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import moment from 'moment'; +import { t } from '@superset-ui/translation'; + import TableLoader from '../../components/TableLoader'; -import { t } from '../../locales'; const propTypes = { user: PropTypes.object.isRequired, diff --git a/superset/assets/src/profile/components/Favorites.jsx b/superset/assets/src/profile/components/Favorites.jsx index e0ef112d45188..c6eb3e7a764ce 100644 --- a/superset/assets/src/profile/components/Favorites.jsx +++ b/superset/assets/src/profile/components/Favorites.jsx @@ -1,8 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import moment from 'moment'; +import { t } from '@superset-ui/translation'; + import TableLoader from '../../components/TableLoader'; -import { t } from '../../locales'; const propTypes = { user: PropTypes.object.isRequired, diff --git a/superset/assets/src/profile/components/Security.jsx b/superset/assets/src/profile/components/Security.jsx index 748be6b84043c..47831198dd07c 100644 --- a/superset/assets/src/profile/components/Security.jsx +++ b/superset/assets/src/profile/components/Security.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Badge, Label } from 'react-bootstrap'; -import { t } from '../../locales'; +import { t } from '@superset-ui/translation'; const propTypes = { user: PropTypes.object.isRequired, diff --git a/superset/assets/src/profile/components/UserInfo.jsx b/superset/assets/src/profile/components/UserInfo.jsx index 4cc54be6ac956..9bd61bedab8b3 100644 --- a/superset/assets/src/profile/components/UserInfo.jsx +++ b/superset/assets/src/profile/components/UserInfo.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import Gravatar from 'react-gravatar'; import moment from 'moment'; import { Panel } from 'react-bootstrap'; -import { t } from '../../locales'; +import { t } from '@superset-ui/translation'; const propTypes = { user: PropTypes.object.isRequired, diff --git a/superset/assets/src/setup/setupApp.js b/superset/assets/src/setup/setupApp.js new file mode 100644 index 0000000000000..7d2fda2dc8f54 --- /dev/null +++ b/superset/assets/src/setup/setupApp.js @@ -0,0 +1,57 @@ +/* eslint global-require: 0 */ +import $ from 'jquery'; +import { SupersetClient } from '@superset-ui/core'; +import getClientErrorObject from '../utils/getClientErrorObject'; + +function showApiMessage(resp) { + const template = + '
' + + '
'; + const severity = resp.severity || 'info'; + $(template).addClass('alert-' + severity) + .append(resp.message) + .appendTo($('#alert-container')); +} + +function toggleCheckbox(apiUrlPrefix, selector) { + SupersetClient.get({ endpoint: apiUrlPrefix + $(selector)[0].checked }) + .then(() => {}) + .catch(response => + getClientErrorObject(response) + .then((parsedResp) => { + if (parsedResp && parsedResp.message) { + showApiMessage(parsedResp); + } + }), + ); +} + +export default function setupApp() { + $(document).ready(function () { + $(':checkbox[data-checkbox-api-prefix]').change(function () { + const $this = $(this); + const prefix = $this.data('checkbox-api-prefix'); + const id = $this.attr('id'); + toggleCheckbox(prefix, '#' + id); + }); + + // for language picker dropdown + $('#language-picker a').click(function (ev) { + ev.preventDefault(); + SupersetClient.get({ + endpoint: ev.currentTarget.getAttribute('href'), + parseMethod: null, + }) + .then(() => { + location.reload(); + }); + }); + }); + + // A set of hacks to allow apps to run within a FAB template + // this allows for the server side generated menus to function + window.$ = $; + window.jQuery = $; + require('bootstrap'); +} diff --git a/superset/assets/src/utils/common.js b/superset/assets/src/utils/common.js index 9fbe35bcb9e38..a22ca9a1c03be 100644 --- a/superset/assets/src/utils/common.js +++ b/superset/assets/src/utils/common.js @@ -1,8 +1,5 @@ -/* eslint global-require: 0 */ +import d3 from 'd3'; import { SupersetClient } from '@superset-ui/core'; -import { t } from '../locales'; - -const d3 = require('d3'); export const EARTH_CIRCUMFERENCE_KM = 40075.16; export const LUMINANCE_RED_WEIGHT = 0.2126; @@ -113,10 +110,5 @@ export function optionFromValue(opt) { return { value: optionValue(opt), label: optionLabel(opt) }; } -// Error messages used in many places across applications -export const COMMON_ERR_MESSAGES = { - SESSION_TIMED_OUT: t('Your session timed out, please refresh your page and try again.'), -}; - // time_range separator export const TIME_RANGE_SEPARATOR = ' : '; diff --git a/superset/assets/src/utils/errorMessages.js b/superset/assets/src/utils/errorMessages.js new file mode 100644 index 0000000000000..70117b26eb5e3 --- /dev/null +++ b/superset/assets/src/utils/errorMessages.js @@ -0,0 +1,6 @@ +// Error messages used in many places across applications +const COMMON_ERR_MESSAGES = { + SESSION_TIMED_OUT: 'Your session timed out, please refresh your page and try again.', +}; + +export default COMMON_ERR_MESSAGES; diff --git a/superset/assets/src/utils/getClientErrorObject.js b/superset/assets/src/utils/getClientErrorObject.js new file mode 100644 index 0000000000000..ea0ea443c2c6a --- /dev/null +++ b/superset/assets/src/utils/getClientErrorObject.js @@ -0,0 +1,40 @@ +import { t } from '@superset-ui/translation'; +import COMMON_ERR_MESSAGES from './errorMessages'; + +export default function getClientErrorObject(response) { + // takes a Response object as input, attempts to read response as Json if possible, + // and returns a Promise that resolves to a plain object with error key and text value. + return new Promise((resolve) => { + if (typeof response === 'string') { + resolve({ error: response }); + } else if (response && response.constructor === Response && !response.bodyUsed) { + // attempt to read the body as json, and fallback to text. we must clone the + // response in order to fallback to .text() because Response is single-read + response.clone().json().then((errorJson) => { + let error = { ...response, ...errorJson }; + if (error.stack) { + error = { + ...error, + error: t('Unexpected error: ') + + (error.description || t('(no description, click to see stack trace)')), + stacktrace: error.stack, + }; + } else if (error.responseText && error.responseText.indexOf('CSRF') >= 0) { + error = { + ...error, + error: t(COMMON_ERR_MESSAGES.SESSION_TIMED_OUT), + }; + } + resolve(error); + }).catch(() => { + // fall back to reading as text + response.text().then((errorText) => { + resolve({ ...response, error: errorText }); + }); + }); + } else { + // fall back to Response.statusText or generic error of we cannot read the response + resolve({ ...response, error: response.statusText || t('An error occurred') }); + } + }); +} diff --git a/superset/assets/src/visualizations/EventFlow/EventFlow.jsx b/superset/assets/src/visualizations/EventFlow/EventFlow.jsx index 7359bda95e8db..4a688e66be7f3 100644 --- a/superset/assets/src/visualizations/EventFlow/EventFlow.jsx +++ b/superset/assets/src/visualizations/EventFlow/EventFlow.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { App, withParentSize } from '@data-ui/event-flow'; -import { t } from '../../locales'; +import { t } from '@superset-ui/translation'; const propTypes = { className: PropTypes.string, diff --git a/superset/assets/src/visualizations/FilterBox/FilterBox.jsx b/superset/assets/src/visualizations/FilterBox/FilterBox.jsx index 907e8020250c3..05b9c9f07f90a 100644 --- a/superset/assets/src/visualizations/FilterBox/FilterBox.jsx +++ b/superset/assets/src/visualizations/FilterBox/FilterBox.jsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import VirtualizedSelect from 'react-virtualized-select'; import { Creatable } from 'react-select'; import { Button } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; import DateFilterControl from '../../explore/components/controls/DateFilterControl'; import ControlRow from '../../explore/components/ControlRow'; @@ -10,7 +11,6 @@ import Control from '../../explore/components/Control'; import controls from '../../explore/controls'; import OnPasteSelect from '../../components/OnPasteSelect'; import VirtualizedRendererWrap from '../../components/VirtualizedRendererWrap'; -import { t } from '../../locales'; import './FilterBox.css'; // maps control names to their key in extra_filters diff --git a/superset/assets/src/visualizations/PlaySlider.jsx b/superset/assets/src/visualizations/PlaySlider.jsx index 88b033524fa26..891c84840d268 100644 --- a/superset/assets/src/visualizations/PlaySlider.jsx +++ b/superset/assets/src/visualizations/PlaySlider.jsx @@ -1,14 +1,11 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Row, Col } from 'react-bootstrap'; - import Mousetrap from 'mousetrap'; - +import { Row, Col } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; import BootrapSliderWrapper from '../components/BootstrapSliderWrapper'; import './PlaySlider.css'; -import { t } from '../locales'; - const propTypes = { start: PropTypes.number.isRequired, step: PropTypes.number.isRequired, diff --git a/superset/assets/src/visualizations/nvd3/NVD3Vis.js b/superset/assets/src/visualizations/nvd3/NVD3Vis.js index a67c93fb71c75..1267b422b84b6 100644 --- a/superset/assets/src/visualizations/nvd3/NVD3Vis.js +++ b/superset/assets/src/visualizations/nvd3/NVD3Vis.js @@ -4,9 +4,9 @@ import nv from 'nvd3'; import mathjs from 'mathjs'; import moment from 'moment'; import PropTypes from 'prop-types'; +import { t } from '@superset-ui/translation'; import 'nvd3/build/nv.d3.min.css'; -import { t } from '../../locales'; import ANNOTATION_TYPES, { applyNativeColumns } from '../../modules/AnnotationTypes'; import { getScale, getColor } from '../../modules/colors/CategoricalColorNamespace'; import { formatDateVerbose } from '../../modules/dates'; diff --git a/superset/assets/src/welcome/App.jsx b/superset/assets/src/welcome/App.jsx index b22c162c73179..4a894ca2c7264 100644 --- a/superset/assets/src/welcome/App.jsx +++ b/superset/assets/src/welcome/App.jsx @@ -6,11 +6,10 @@ import { Provider } from 'react-redux'; import messageToastReducer from '../messageToasts/reducers'; import { initEnhancer } from '../reduxUtils'; - -import { appSetup } from '../common'; +import setupApp from '../setup/setupApp'; import Welcome from './Welcome'; -appSetup(); +setupApp(); const container = document.getElementById('app'); const bootstrap = JSON.parse(container.getAttribute('data-bootstrap')); diff --git a/superset/assets/src/welcome/DashboardTable.jsx b/superset/assets/src/welcome/DashboardTable.jsx index 29c2988763023..c03e34c534d00 100644 --- a/superset/assets/src/welcome/DashboardTable.jsx +++ b/superset/assets/src/welcome/DashboardTable.jsx @@ -2,9 +2,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Table, Tr, Td, unsafe } from 'reactable'; import { SupersetClient } from '@superset-ui/core'; -import withToasts from '../messageToasts/enhancers/withToasts'; -import { t } from '../locales'; +import { t } from '@superset-ui/translation'; +import withToasts from '../messageToasts/enhancers/withToasts'; import Loading from '../components/Loading'; import '../../stylesheets/reactable-pagination.css'; diff --git a/superset/assets/src/welcome/Welcome.jsx b/superset/assets/src/welcome/Welcome.jsx index 2f4de973ae34a..d059ee11131be 100644 --- a/superset/assets/src/welcome/Welcome.jsx +++ b/superset/assets/src/welcome/Welcome.jsx @@ -1,10 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Panel, Row, Col, Tabs, Tab, FormControl } from 'react-bootstrap'; +import { t } from '@superset-ui/translation'; import RecentActivity from '../profile/components/RecentActivity'; import Favorites from '../profile/components/Favorites'; import DashboardTable from './DashboardTable'; -import { t } from '../locales'; const propTypes = { user: PropTypes.object.isRequired, diff --git a/superset/assets/webpack.config.js b/superset/assets/webpack.config.js index 9da65284ceb59..c37ad55a1eacf 100644 --- a/superset/assets/webpack.config.js +++ b/superset/assets/webpack.config.js @@ -79,19 +79,28 @@ if (isDevMode) { output.chunkFilename = '[name].[chunkhash].chunk.js'; } +const PREAMBLE = [ + 'babel-polyfill', + path.join(APP_DIR, '/src/preamble.js'), +]; + +function addPreamble(entry) { + return PREAMBLE.concat([path.join(APP_DIR, entry)]); +} + const config = { node: { fs: 'empty', }, entry: { - theme: APP_DIR + '/src/theme.js', - common: APP_DIR + '/src/common.js', - addSlice: ['babel-polyfill', APP_DIR + '/src/addSlice/index.jsx'], - explore: ['babel-polyfill', APP_DIR + '/src/explore/index.jsx'], - dashboard: ['babel-polyfill', APP_DIR + '/src/dashboard/index.jsx'], - sqllab: ['babel-polyfill', APP_DIR + '/src/SqlLab/index.jsx'], - welcome: ['babel-polyfill', APP_DIR + '/src/welcome/index.jsx'], - profile: ['babel-polyfill', APP_DIR + '/src/profile/index.jsx'], + theme: path.join(APP_DIR, '/src/theme.js'), + preamble: PREAMBLE, + addSlice: addPreamble('/src/addSlice/index.jsx'), + explore: addPreamble('/src/explore/index.jsx'), + dashboard: addPreamble('/src/dashboard/index.jsx'), + sqllab: addPreamble('/src/SqlLab/index.jsx'), + welcome: addPreamble('/src/welcome/index.jsx'), + profile: addPreamble('/src/profile/index.jsx'), }, output, optimization: { @@ -103,7 +112,7 @@ const config = { default: false, major: { name: 'vendors-major', - test: /[\\/]node_modules\/(brace|react[-]dom|core[-]js)[\\/]/, + test: /[\\/]node_modules\/(brace|react[-]dom|core[-]js|@superset[-]ui\/translation)[\\/]/, }, }, }, diff --git a/superset/assets/yarn.lock b/superset/assets/yarn.lock index a6ffc95c2909a..a59ef5e26ebbc 100644 --- a/superset/assets/yarn.lock +++ b/superset/assets/yarn.lock @@ -406,6 +406,13 @@ "@babel/runtime" "^7.1.2" whatwg-fetch "^2.0.4" +"@superset-ui/translation@^0.2.1": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@superset-ui/translation/-/translation-0.2.1.tgz#252025d566918782bafc25cb9fe2aa31f9917093" + dependencies: + "@babel/runtime" "^7.1.2" + jed "^1.1.1" + "@types/blob-util@1.3.3": version "1.3.3" resolved "https://registry.yarnpkg.com/@types/blob-util/-/blob-util-1.3.3.tgz#adba644ae34f88e1dd9a5864c66ad651caaf628a" @@ -2697,7 +2704,7 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -classnames@^2.1.2, classnames@^2.2.3, classnames@^2.2.4, classnames@^2.2.5: +classnames@^2.2.3, classnames@^2.2.4, classnames@^2.2.5: version "2.2.6" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" @@ -4452,10 +4459,6 @@ executable@4.1.1: dependencies: pify "^2.2.0" -exenv@^1.2.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d" - exif-parser@^0.1.9: version "0.1.12" resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922" @@ -9350,15 +9353,6 @@ react-bootstrap-slider@2.1.5: bootstrap-slider "9.9.0" es6bindall "^0.0.9" -react-bootstrap-table@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/react-bootstrap-table/-/react-bootstrap-table-4.3.1.tgz#f704be55b7f6bf0557d2fc5bec6d25fd307d0cde" - dependencies: - classnames "^2.1.2" - prop-types "^15.5.10" - react-modal "^3.1.7" - react-s-alert "^1.3.2" - react-bootstrap@^0.31.5: version "0.31.5" resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-0.31.5.tgz#57040fa8b1274e1e074803c21a1b895fdabea05a" @@ -9455,7 +9449,7 @@ react-is@^16.3.2, react-is@^16.5.2: version "16.5.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.5.2.tgz#e2a7b7c3f5d48062eb769fcb123505eb928722e3" -react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.4: +react-lifecycles-compat@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" @@ -9488,15 +9482,6 @@ react-markdown@^3.3.0: unist-util-visit "^1.3.0" xtend "^4.0.1" -react-modal@^3.1.7: - version "3.6.1" - resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.6.1.tgz#54d27a1ec2b493bbc451c7efaa3557b6af82332d" - dependencies: - exenv "^1.2.0" - prop-types "^15.5.10" - react-lifecycles-compat "^3.0.0" - warning "^3.0.0" - react-move@^2.1.0: version "2.8.0" resolved "https://registry.yarnpkg.com/react-move/-/react-move-2.8.0.tgz#63deaf6a0e58ca6769357abfcd91dde44d83a596" @@ -9536,12 +9521,6 @@ react-resizable@^1.3.3: prop-types "15.x" react-draggable "^2.2.6 || ^3.0.3" -react-s-alert@^1.3.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/react-s-alert/-/react-s-alert-1.4.1.tgz#ef3665a9d98c4cf2e448fc2d84e48aeca799bb5a" - dependencies: - babel-runtime "^6.23.0" - react-search-input@^0.11.3: version "0.11.3" resolved "https://registry.yarnpkg.com/react-search-input/-/react-search-input-0.11.3.tgz#3dd1f9fc584b6bc40a6ee133ae042b6fbb7ae8dd" @@ -10823,10 +10802,6 @@ split@~0.2.10: dependencies: through "2" -sprintf-js@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.1.tgz#36be78320afe5801f6cea3ee78b6e5aab940ea0c" - sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" diff --git a/superset/templates/superset/base.html b/superset/templates/superset/base.html index b4397f510d880..b2dba505dd554 100644 --- a/superset/templates/superset/base.html +++ b/superset/templates/superset/base.html @@ -10,14 +10,14 @@ {% block head_js %} {{super()}} - {% for entry in get_unloaded_chunks(js_manifest('theme'), loaded_chunks) %} - - {% endfor %} + {% with filename="theme" %} + {% include "superset/partials/_script_tag.html" %} + {% endwith %} {% endblock %} {% block tail_js %} {{super()}} - {% for entry in get_unloaded_chunks(js_manifest('common'), loaded_chunks) %} - - {% endfor %} + {% with filename="preamble" %} + {% include "superset/partials/_script_tag.html" %} + {% endwith %} {% endblock %} diff --git a/superset/templates/superset/basic.html b/superset/templates/superset/basic.html index a5e72f38fae85..f096b55ca6eeb 100644 --- a/superset/templates/superset/basic.html +++ b/superset/templates/superset/basic.html @@ -29,12 +29,9 @@ {% endblock %} - {% for entry in get_unloaded_chunks(js_manifest('theme'), loaded_chunks) %} - - {% endfor %} - {% for entry in get_unloaded_chunks(js_manifest('common'), loaded_chunks) %} - - {% endfor %} + {% with filename="theme" %} + {% include "superset/partials/_script_tag.html" %} + {% endwith %} {% block tail_js %} {% if entry %} - {% set entry_files = js_manifest(entry) %} - {% for entry in get_unloaded_chunks(entry_files, loaded_chunks) %} - - {% endfor %} + {% with filename=entry %} + {% include "superset/partials/_script_tag.html" %} + {% endwith %} {% endif %} {% endblock %} diff --git a/superset/templates/superset/partials/_script_tag.html b/superset/templates/superset/partials/_script_tag.html index f530c7bd4038b..1677925a85973 100644 --- a/superset/templates/superset/partials/_script_tag.html +++ b/superset/templates/superset/partials/_script_tag.html @@ -1,4 +1,4 @@ -{% block tail_js %} +{% block partial_js %} {% for entry in get_unloaded_chunks(js_manifest(filename), loaded_chunks) %} {% endfor %}