From 9af34ba51cdb23a2970e968d0cbdee82778c6799 Mon Sep 17 00:00:00 2001 From: Grace Guo Date: Wed, 20 Sep 2017 12:37:33 -0700 Subject: [PATCH] js translation -- performance improvment (#3390) * Chinese page * Using react-intl-universal to improve multi language in react page * Using react-intl-universal to improve multi language in react page * react_intl_universal * change * change * change * change * change * change * change * merge * multiple page in js * merge * merge * merge * merge * Js Translations * JS Translation * JS Translations * Js translation * JS translations * JS translations * Js translaion * JS en Translation * JS Translation * upgrade document Fixing the damn build (#3179) * Fixing the build * Going deeper [bugfix] only filterable columns should show up in FilterBox list (#3105) * [bugfix] only filterable columns should show up in FilterBox list * Touchups Datasource cannot be empty (#3035) add title description to model view (#3045) * add title description to model view * add missing import Add 'show/hide totals' option to pivot table vis (#3101) [bugfix] numeric value for date fields in table viz (#3036) Bug was present only when using the NOT GROUPED BY option fixes https://github.com/ApacheInfra/superset/issues/3027 fix hive.fetch_logs (#2968) add Zalando to the list of organizations (#3171) docs: fixup installation examples code indentation (#3169) [bugfix] fix bar order (#3180) [bugfix] visualize flow error: 'Metric x is not valid' (#3181) The metric name in the frontend doesn't match the one generated on the backend. It turns out the explore view will default to the first metric so specifying one isn't needed. Fix the segment interval for pulling metadata (#3174) The end of the interval would be on the truncated today date, which means that you will exclude today. If your realtime ingestion job runs shorter than a day, the metadata cannot be pulled from the druid cluster. Bump cryptography to 1.9 (#3065) As 1.7.2 doesn't compile here with openssl 1.1.0f Escaping the user's SQL in the explore view (#3186) * Escaping the user's SQL in the explore view When executing SQL from SQL Lab, we use a lower level API to the database which doesn't require escaping the SQL. When going through the explore view, the stack chain leading to the same method may need escaping depending on how the DBAPI driver is written, and that is the case for Presto (and perhaps other drivers). * Using regex to avoid doubling doubles [sqllab] improve Hive support (#3187) * [sqllab] improve Hive support * Fix "Transport not open" bug * Getting progress bar to show * Bump pyhive to 0.4.0 * Getting [Track Job] button to show * Fix testzz Add BigQuery engine specifications (#3193) As contributed by @mxmzdlv on issue #945 [bugfix] fix merge conflict that broke Hive support (#3196) Adding 'apache' to docs (#3194) [druid] Allow custom druid postaggregators (#3146) * [druid] Allow custom druid postaggregators Also, fix the postaggregation for approxHistogram quantiles so it adds the dependent field and that can show up in the graphs/tables. In general, postAggregators add significant power, we should probably support including custom postAggregators. Plywood has standard postAggregators here, and a customAggregator escape hatch that allows you to define custom postAggregators. This commit adds a similar capability for Superset and a additional field/fields/fieldName breakdown of the typical naming for dependent aggregations, which should make it significantly easier to develop approxHistogram and custom postAggregation-required dashboards. * [druid] Minor style cleanup in tests file. * [druid] Apply code review suggestions * break out CustomPostAggregator into separate class. This just cleans up the creation of the postaggregator a little bit. * minor style issues. * move the function around so the git diff is more readable add combine config for metrics in pivot table (#3086) * add combine config for metrics in pivot table * change method to stack/unstack * update backendSync Autofocus search input in VizTypeControl modal onEnter (#2929) Speed up JS build time (#3203) Also bumping a few related libs JS Translation JS translations js translation fix issue 3204 (#3205) [bugfix] capture Hive job_id pre-url transformation (#3213) js translation fix issue 3204 (#3205) [bugfix] capture Hive job_id pre-url transformation (#3213) [docs] update url in CONTRIBUTING.md (#3212) [sqllab/cosmetics] add margin-top for labels in query history (#3222) [explore] nvd3 sort values in rich tooltip (#3197) [sqllab] fix UI shows 'The query returned no results' momentarily (#3214) this is visible when running async queries between the fetching and success state as the rows are getting cached in the component [explore] DatasourceControl to pick datasource in modal (#3210) * [explore] DatasourceControl to pick datasource in modal Makes it easier to change datasource, also makes it such that the list of all datasources doesn't need to be loaded upfront. * Adding more metadata * Js translation * js tran * js trans * js trans * js tran * js trans * js trans * js tran * js translation * js trans * js translation * try load language pack async * Backend translations things * create language pack inside common data * performance improvement for js i18n. - js bundle should not contain localized content - we populate translation content from server-side, in boostrap.common.language_pack - in client-side, use promise to wrap around translation content. text will be translated after translation content arrived/parsed. - fix linting * fix Timer unit test * 1. add global hook for all tests, to make translation pack avaialble before each test starts. 2. fix unit test for Timer component 3. remove noused method get_locale, and modules 4. fix page reload after user change page language * parse and build i18n dictionary as a module * fix sync-backend task, which should run without DOM --- CONTRIBUTING.md | 14 + babel/babel.cfg | 4 + babel/messages.pot | 2814 ++++++++++++-- superset/assets/javascripts/SqlLab/actions.js | 27 +- .../SqlLab/components/CopyQueryTabUrl.jsx | 5 +- .../SqlLab/components/HighlightedSql.jsx | 7 +- .../SqlLab/components/QueryHistory.jsx | 3 +- .../SqlLab/components/QuerySearch.jsx | 17 +- .../SqlLab/components/QueryTable.jsx | 17 +- .../SqlLab/components/ResultSet.jsx | 19 +- .../components/RunQueryActionButton.jsx | 11 +- .../SqlLab/components/SaveQuery.jsx | 17 +- .../SqlLab/components/SouthPane.jsx | 9 +- .../SqlLab/components/SqlEditor.jsx | 5 +- .../SqlLab/components/SqlEditorLeftBar.jsx | 23 +- .../SqlLab/components/TabbedSqlEditors.jsx | 13 +- .../SqlLab/components/TableElement.jsx | 17 +- .../SqlLab/components/VisualizeModal.jsx | 23 +- .../assets/javascripts/SqlLab/constants.js | 10 +- .../assets/javascripts/SqlLab/reducers.js | 25 +- .../addSlice/AddSliceContainer.jsx | 12 +- superset/assets/javascripts/common.js | 11 + .../javascripts/components/AsyncSelect.jsx | 3 +- .../javascripts/components/CachedLabel.jsx | 7 +- .../components/CopyToClipboard.jsx | 9 +- .../javascripts/components/EditableTitle.jsx | 5 +- .../javascripts/components/FaveStar.jsx | 3 +- .../javascripts/dashboard/Dashboard.jsx | 17 +- .../dashboard/components/CodeModal.jsx | 3 +- .../dashboard/components/Controls.jsx | 7 +- .../dashboard/components/CssEditor.jsx | 9 +- .../components/RefreshIntervalModal.jsx | 15 +- .../dashboard/components/SaveModal.jsx | 19 +- .../dashboard/components/SliceAdder.jsx | 13 +- .../dashboard/components/SliceCell.jsx | 15 +- .../explore/components/ChartContainer.jsx | 5 +- .../explore/components/ControlHeader.jsx | 5 +- .../components/ControlPanelsContainer.jsx | 2 +- .../explore/components/DisplayQueryButton.jsx | 5 +- .../explore/components/EmbedCodeButton.jsx | 7 +- .../components/ExploreActionButtons.jsx | 5 +- .../explore/components/SaveModal.jsx | 28 +- .../explore/components/URLShortLinkButton.jsx | 5 +- .../components/controls/BoundsControl.jsx | 9 +- .../components/controls/DatasourceControl.jsx | 11 +- .../explore/components/controls/Filter.jsx | 7 +- .../components/controls/FilterControl.jsx | 3 +- .../components/controls/SelectControl.jsx | 3 +- .../components/controls/TextAreaControl.jsx | 5 +- .../components/controls/VizTypeControl.jsx | 5 +- superset/assets/javascripts/explore/index.jsx | 4 +- .../explore/reducers/chartReducer.js | 11 +- .../javascripts/explore/stores/controls.jsx | 553 ++- .../javascripts/explore/stores/visTypes.js | 348 +- superset/assets/javascripts/i18n.jsx | 32 + superset/assets/javascripts/locales.jsx | 148 + .../assets/javascripts/modules/superset.js | 11 +- .../javascripts/profile/components/App.jsx | 9 +- .../profile/components/CreatedContent.jsx | 9 +- .../profile/components/Favorites.jsx | 9 +- .../profile/components/Security.jsx | 7 +- .../profile/components/UserInfo.jsx | 7 +- superset/assets/javascripts/profile/index.jsx | 2 +- superset/assets/package.json | 3 + .../components/AsyncSelect_spec.jsx | 16 +- .../profile/EditableTitle_spec.jsx | 2 +- .../javascripts/sqllab/SaveQuery_spec.jsx | 9 +- .../spec/javascripts/sqllab/Timer_spec.jsx | 13 +- .../spec/javascripts/sqllab/reducers_spec.js | 6 +- superset/assets/visualizations/EventFlow.jsx | 3 +- superset/assets/visualizations/filter_box.jsx | 3 +- superset/config.py | 4 +- .../templates/appbuilder/navbar_right.html | 2 +- superset/templates/superset/dashboard.html | 1 + superset/translations/__init__.py | 0 .../translations/en/LC_MESSAGES/messages.json | 1 + .../translations/en/LC_MESSAGES/messages.mo | Bin 0 -> 58211 bytes .../translations/en/LC_MESSAGES/messages.po | 3327 +++++++++++++++++ .../translations/es/LC_MESSAGES/messages.json | 1 + .../translations/es/LC_MESSAGES/messages.mo | Bin 16501 -> 58211 bytes .../translations/es/LC_MESSAGES/messages.po | 3026 +++++++++++++-- .../translations/fr/LC_MESSAGES/messages.json | 1 + .../translations/fr/LC_MESSAGES/messages.mo | Bin 24674 -> 0 bytes .../translations/fr/LC_MESSAGES/messages.po | 1383 ------- .../translations/it/LC_MESSAGES/messages.json | 1 + .../translations/it/LC_MESSAGES/messages.mo | Bin 17303 -> 59013 bytes .../translations/it/LC_MESSAGES/messages.po | 3064 +++++++++++++-- superset/translations/utils.py | 33 + .../translations/zh/LC_MESSAGES/messages.json | 1 + .../translations/zh/LC_MESSAGES/messages.mo | Bin 15904 -> 53786 bytes .../translations/zh/LC_MESSAGES/messages.po | 3206 ++++++++++++++-- superset/views/base.py | 5 + 92 files changed, 15170 insertions(+), 3424 deletions(-) create mode 100644 superset/assets/javascripts/i18n.jsx create mode 100644 superset/assets/javascripts/locales.jsx create mode 100644 superset/translations/__init__.py create mode 100644 superset/translations/en/LC_MESSAGES/messages.json create mode 100644 superset/translations/en/LC_MESSAGES/messages.mo create mode 100644 superset/translations/en/LC_MESSAGES/messages.po create mode 100644 superset/translations/es/LC_MESSAGES/messages.json create mode 100644 superset/translations/fr/LC_MESSAGES/messages.json delete mode 100644 superset/translations/fr/LC_MESSAGES/messages.mo delete mode 100644 superset/translations/fr/LC_MESSAGES/messages.po create mode 100644 superset/translations/it/LC_MESSAGES/messages.json create mode 100644 superset/translations/utils.py create mode 100644 superset/translations/zh/LC_MESSAGES/messages.json diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0539ac3c823ab..da403d16f46eb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -331,6 +331,8 @@ key is to instrument the strings that need translation using a module, all you have to do is to `_("Wrap your strings")` using the underscore `_` "function". +We use `import {t, tn, TCT} from locales;` in js, JSX file, locales is in `./superset/assets/javascripts/` directory. + To enable changing language in your environment, you can simply add the `LANGUAGES` parameter to your `superset_config.py`. Having more than one options here will add a language selection dropdown on the right side of the @@ -342,6 +344,10 @@ navigation bar. 'zh': {'flag': 'cn', 'name': 'Chinese'}, } +We need to extract the string to be translated, run the following command: + + pybabel extract -F ./babel/babel.cfg -k _ -k __ -k t -k tn -k tct -o ./babel/messages.pot . + As per the [Flask AppBuilder documentation] about translation, to create a new language dictionary, run the following command: @@ -358,6 +364,14 @@ to take effect, they need to be compiled using this command: fabmanager babel-compile --target superset/translations/ +In the case of JS translation, we need to convert the PO file into a JSON file, and we need the global download of the npm package po2json. +We need to be compiled using this command: + + npm install po2json -g + +Execute this command to convert the en PO file into a json file: + + po2json -d superset -f jed1.x superset/translations/en/LC_MESSAGES/messages.po superset/translations/en/LC_MESSAGES/messages.json ## Adding new datasources diff --git a/babel/babel.cfg b/babel/babel.cfg index 790b262731b74..762ac64e77c96 100644 --- a/babel/babel.cfg +++ b/babel/babel.cfg @@ -1,4 +1,8 @@ [ignore: superset/assets/node_modules/**] [python: superset/**.py] [jinja2: superset/**/templates/**.html] +[javascript: superset/assets/javascripts/**.js] +[javascript: superset/assets/javascripts/**.jsx] +[javascript: superset/assets/visualizations/**.js] +[javascript: superset/assets/visualizations/**.jsx] encoding = utf-8 diff --git a/babel/messages.pot b/babel/messages.pot index 5ebccd2646a4e..810ccb0dbbcfa 100755 --- a/babel/messages.pot +++ b/babel/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2017-08-17 03:23+0200\n" +"POT-Creation-Date: 2017-09-12 20:55-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,76 +17,77 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.4.0\n" +#: superset/assets/javascripts/explore/stores/controls.jsx:505 #: superset/db_engine_specs.py:192 superset/db_engine_specs.py:223 #: superset/db_engine_specs.py:267 superset/db_engine_specs.py:315 -#: superset/db_engine_specs.py:360 superset/db_engine_specs.py:810 -#: superset/db_engine_specs.py:846 superset/db_engine_specs.py:878 -#: superset/db_engine_specs.py:924 superset/db_engine_specs.py:961 -#: superset/db_engine_specs.py:987 +#: superset/db_engine_specs.py:371 superset/db_engine_specs.py:839 +#: superset/db_engine_specs.py:875 superset/db_engine_specs.py:907 +#: superset/db_engine_specs.py:953 superset/db_engine_specs.py:990 +#: superset/db_engine_specs.py:1016 msgid "Time Column" msgstr "" #: superset/db_engine_specs.py:193 superset/db_engine_specs.py:224 -#: superset/db_engine_specs.py:316 superset/db_engine_specs.py:361 -#: superset/db_engine_specs.py:811 superset/db_engine_specs.py:879 -#: superset/db_engine_specs.py:962 +#: superset/db_engine_specs.py:316 superset/db_engine_specs.py:372 +#: superset/db_engine_specs.py:840 superset/db_engine_specs.py:908 +#: superset/db_engine_specs.py:991 msgid "second" msgstr "" #: superset/db_engine_specs.py:194 superset/db_engine_specs.py:227 -#: superset/db_engine_specs.py:319 superset/db_engine_specs.py:363 -#: superset/db_engine_specs.py:813 superset/db_engine_specs.py:847 -#: superset/db_engine_specs.py:881 superset/db_engine_specs.py:925 -#: superset/db_engine_specs.py:963 superset/db_engine_specs.py:988 +#: superset/db_engine_specs.py:319 superset/db_engine_specs.py:374 +#: superset/db_engine_specs.py:842 superset/db_engine_specs.py:876 +#: superset/db_engine_specs.py:910 superset/db_engine_specs.py:954 +#: superset/db_engine_specs.py:992 superset/db_engine_specs.py:1017 msgid "minute" msgstr "" #: superset/db_engine_specs.py:195 superset/db_engine_specs.py:231 -#: superset/db_engine_specs.py:321 superset/db_engine_specs.py:365 -#: superset/db_engine_specs.py:819 superset/db_engine_specs.py:849 -#: superset/db_engine_specs.py:883 superset/db_engine_specs.py:931 -#: superset/db_engine_specs.py:964 superset/db_engine_specs.py:989 +#: superset/db_engine_specs.py:321 superset/db_engine_specs.py:376 +#: superset/db_engine_specs.py:848 superset/db_engine_specs.py:878 +#: superset/db_engine_specs.py:912 superset/db_engine_specs.py:960 +#: superset/db_engine_specs.py:993 superset/db_engine_specs.py:1018 msgid "hour" msgstr "" #: superset/db_engine_specs.py:196 superset/db_engine_specs.py:236 #: superset/db_engine_specs.py:268 superset/db_engine_specs.py:323 -#: superset/db_engine_specs.py:367 superset/db_engine_specs.py:821 -#: superset/db_engine_specs.py:851 superset/db_engine_specs.py:885 -#: superset/db_engine_specs.py:933 superset/db_engine_specs.py:965 -#: superset/db_engine_specs.py:990 +#: superset/db_engine_specs.py:378 superset/db_engine_specs.py:850 +#: superset/db_engine_specs.py:880 superset/db_engine_specs.py:914 +#: superset/db_engine_specs.py:962 superset/db_engine_specs.py:994 +#: superset/db_engine_specs.py:1019 msgid "day" msgstr "" #: superset/db_engine_specs.py:197 superset/db_engine_specs.py:242 #: superset/db_engine_specs.py:269 superset/db_engine_specs.py:324 -#: superset/db_engine_specs.py:369 superset/db_engine_specs.py:823 -#: superset/db_engine_specs.py:853 superset/db_engine_specs.py:887 -#: superset/db_engine_specs.py:966 superset/db_engine_specs.py:991 +#: superset/db_engine_specs.py:380 superset/db_engine_specs.py:852 +#: superset/db_engine_specs.py:882 superset/db_engine_specs.py:916 +#: superset/db_engine_specs.py:995 superset/db_engine_specs.py:1020 msgid "week" msgstr "" #: superset/db_engine_specs.py:198 superset/db_engine_specs.py:244 #: superset/db_engine_specs.py:271 superset/db_engine_specs.py:326 -#: superset/db_engine_specs.py:371 superset/db_engine_specs.py:825 -#: superset/db_engine_specs.py:855 superset/db_engine_specs.py:889 -#: superset/db_engine_specs.py:935 superset/db_engine_specs.py:967 -#: superset/db_engine_specs.py:992 +#: superset/db_engine_specs.py:382 superset/db_engine_specs.py:854 +#: superset/db_engine_specs.py:884 superset/db_engine_specs.py:918 +#: superset/db_engine_specs.py:964 superset/db_engine_specs.py:996 +#: superset/db_engine_specs.py:1021 msgid "month" msgstr "" #: superset/db_engine_specs.py:199 superset/db_engine_specs.py:246 -#: superset/db_engine_specs.py:328 superset/db_engine_specs.py:373 -#: superset/db_engine_specs.py:827 superset/db_engine_specs.py:857 -#: superset/db_engine_specs.py:891 superset/db_engine_specs.py:937 -#: superset/db_engine_specs.py:968 superset/db_engine_specs.py:993 +#: superset/db_engine_specs.py:328 superset/db_engine_specs.py:384 +#: superset/db_engine_specs.py:856 superset/db_engine_specs.py:886 +#: superset/db_engine_specs.py:920 superset/db_engine_specs.py:966 +#: superset/db_engine_specs.py:997 superset/db_engine_specs.py:1022 msgid "quarter" msgstr "" #: superset/db_engine_specs.py:200 superset/db_engine_specs.py:250 -#: superset/db_engine_specs.py:330 superset/db_engine_specs.py:829 -#: superset/db_engine_specs.py:859 superset/db_engine_specs.py:939 -#: superset/db_engine_specs.py:969 superset/db_engine_specs.py:994 +#: superset/db_engine_specs.py:330 superset/db_engine_specs.py:858 +#: superset/db_engine_specs.py:888 superset/db_engine_specs.py:968 +#: superset/db_engine_specs.py:998 superset/db_engine_specs.py:1023 msgid "year" msgstr "" @@ -94,27 +95,27 @@ msgstr "" msgid "week_start_monday" msgstr "" -#: superset/db_engine_specs.py:375 superset/db_engine_specs.py:893 +#: superset/db_engine_specs.py:386 superset/db_engine_specs.py:922 msgid "week_ending_saturday" msgstr "" -#: superset/db_engine_specs.py:378 superset/db_engine_specs.py:896 +#: superset/db_engine_specs.py:389 superset/db_engine_specs.py:925 msgid "week_start_sunday" msgstr "" -#: superset/db_engine_specs.py:815 superset/db_engine_specs.py:927 +#: superset/db_engine_specs.py:844 superset/db_engine_specs.py:956 msgid "5 minute" msgstr "" -#: superset/db_engine_specs.py:817 +#: superset/db_engine_specs.py:846 msgid "half hour" msgstr "" -#: superset/db_engine_specs.py:929 +#: superset/db_engine_specs.py:958 msgid "10 minute" msgstr "" -#: superset/utils.py:499 +#: superset/utils.py:503 #, python-format msgid "[Superset] Access to the datasource %(name)s was granted" msgstr "" @@ -123,237 +124,2569 @@ msgstr "" msgid "Viz is missing a datasource" msgstr "" -#: superset/viz.py:158 +#: superset/viz.py:163 msgid "From date cannot be larger than to date" msgstr "" -#: superset/viz.py:322 +#: superset/assets/javascripts/explore/stores/visTypes.js:321 +#: superset/viz.py:328 msgid "Table View" msgstr "" -#: superset/viz.py:334 +#: superset/viz.py:340 msgid "Pick a granularity in the Time section or uncheck 'Include Time'" msgstr "" -#: superset/viz.py:344 +#: superset/viz.py:350 msgid "Choose either fields to [Group By] and [Metrics] or [Columns], not both" msgstr "" -#: superset/viz.py:378 +#: superset/assets/javascripts/explore/stores/visTypes.js:372 +#: superset/viz.py:384 msgid "Pivot Table" msgstr "" -#: superset/viz.py:392 +#: superset/viz.py:398 msgid "Please choose at least one \"Group by\" field " msgstr "" -#: superset/viz.py:394 -msgid "Please choose at least one metric" +#: superset/viz.py:400 +msgid "Please choose at least one metric" +msgstr "" + +#: superset/viz.py:404 +msgid "'Group By' and 'Columns' can't overlap" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:359 +#: superset/viz.py:437 +msgid "Markup" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:397 +#: superset/viz.py:456 +msgid "Separator" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:419 +#: superset/viz.py:468 +msgid "Word Cloud" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:440 +#: superset/viz.py:491 +msgid "Treemap" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:467 +#: superset/viz.py:517 +msgid "Calendar Heatmap" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:488 +#: superset/viz.py:575 +msgid "Box Plot" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:509 +#: superset/viz.py:664 +msgid "Bubble Chart" +msgstr "" + +#: superset/viz.py:688 +msgid "Pick a metric for x, y and size" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:560 +#: superset/viz.py:714 +msgid "Bullet Chart" +msgstr "" + +#: superset/viz.py:740 +msgid "Pick a metric to display" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:583 +#: superset/viz.py:763 +msgid "Big Number with Trendline" +msgstr "" + +#: superset/viz.py:771 superset/viz.py:800 +msgid "Pick a metric!" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:608 +#: superset/viz.py:792 +msgid "Big Number" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:149 +#: superset/viz.py:819 +msgid "Time Series - Line Chart" +msgstr "" + +#: superset/viz.py:866 superset/viz.py:1011 +msgid "Pick a time granularity for your time series" +msgstr "" + +#: superset/viz.py:954 +msgid "Time Series - Dual Axis Line Chart" +msgstr "" + +#: superset/viz.py:964 +msgid "Pick a metric for left axis!" +msgstr "" + +#: superset/viz.py:966 +msgid "Pick a metric for right axis!" +msgstr "" + +#: superset/viz.py:968 +msgid "Please choose different metrics on left and right axis" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:228 +#: superset/viz.py:1029 +msgid "Time Series - Bar Chart" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:263 +#: superset/viz.py:1037 +msgid "Time Series - Percent Change" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:285 +#: superset/viz.py:1045 +msgid "Time Series - Stacked" +msgstr "" + +#: superset/viz.py:1054 +msgid "Distribution - NVD3 - Pie Chart" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:633 +#: superset/viz.py:1072 +msgid "Histogram" +msgstr "" + +#: superset/viz.py:1082 +msgid "Must have one numeric column specified" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:88 +#: superset/viz.py:1097 +msgid "Distribution - Bar Chart" +msgstr "" + +#: superset/viz.py:1108 +msgid "Can't have overlap between Series and Breakdowns" +msgstr "" + +#: superset/viz.py:1110 +msgid "Pick at least one metric" +msgstr "" + +#: superset/viz.py:1112 +msgid "Pick at least one field for [Series]" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:665 +#: superset/viz.py:1165 +msgid "Sunburst" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:702 +#: superset/viz.py:1198 +msgid "Sankey" +msgstr "" + +#: superset/viz.py:1205 +msgid "Pick exactly 2 columns as [Source / Target]" +msgstr "" + +#: superset/viz.py:1236 +msgid "" +"There's a loop in your Sankey, please provide a tree. Here's a faulty " +"link: {}" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:729 +#: superset/viz.py:1247 superset/viz.py:1268 +msgid "Directed Force Layout" +msgstr "" + +#: superset/viz.py:1254 +msgid "Pick exactly 2 columns to 'Group By'" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:794 +#: superset/viz.py:1301 +msgid "Country Map" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:827 +#: superset/viz.py:1330 +msgid "World Map" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:72 +#: superset/viz.py:1380 +msgid "Filters" +msgstr "" + +#: superset/viz.py:1388 +msgid "Pick at least one filter field" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:895 +#: superset/viz.py:1415 +msgid "iFrame" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:907 +#: superset/viz.py:1432 +msgid "Parallel Coordinates" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:929 +#: superset/viz.py:1457 +msgid "Heatmap" +msgstr "" + +#: superset/viz.py:1508 +msgid "Horizon Charts" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:974 +#: superset/viz.py:1519 +msgid "Mapbox" +msgstr "" + +#: superset/viz.py:1534 +msgid "Must have a [Group By] column to have 'count' as the [Label]" +msgstr "" + +#: superset/viz.py:1547 +msgid "Choice of [Label] must be present in [Group By]" +msgstr "" + +#: superset/viz.py:1552 +msgid "Choice of [Point Radius] must be present in [Group By]" +msgstr "" + +#: superset/viz.py:1557 +msgid "[Longitude] and [Latitude] columns must be present in [Group By]" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1045 +#: superset/viz.py:1622 +msgid "Event flow" +msgstr "" + +#: superset/assets/javascripts/SqlLab/actions.js:57 +msgid "Your query was saved" +msgstr "" + +#: superset/assets/javascripts/SqlLab/actions.js:58 +msgid "Your query could not be saved" +msgstr "" + +#: superset/assets/javascripts/SqlLab/actions.js:111 +msgid "Failed at retrieving results from the results backend" +msgstr "" + +#: superset/assets/javascripts/SqlLab/actions.js:157 +msgid "Could not connect to server" +msgstr "" + +#: superset/assets/javascripts/SqlLab/actions.js:162 +msgid "Your session timed out, please refresh your page and try again." +msgstr "" + +#: superset/assets/javascripts/SqlLab/actions.js:181 +msgid "Query was stopped." +msgstr "" + +#: superset/assets/javascripts/SqlLab/actions.js:184 +msgid "Failed at stopping query." +msgstr "" + +#: superset/assets/javascripts/SqlLab/actions.js:297 +#: superset/assets/javascripts/SqlLab/actions.js:310 +msgid "Error occurred while fetching table metadata" +msgstr "" + +#: superset/assets/javascripts/SqlLab/actions.js:364 +msgid "shared query" +msgstr "" + +#: superset/assets/javascripts/SqlLab/actions.js:372 +#: superset/assets/javascripts/SqlLab/actions.js:392 +msgid "The query couldn't be loaded" +msgstr "" + +#: superset/assets/javascripts/SqlLab/actions.js:425 +msgid "An error occurred while creating the data source" +msgstr "" + +#: superset/assets/javascripts/SqlLab/constants.js:30 +msgid "Pick a chart type!" +msgstr "" + +#: superset/assets/javascripts/SqlLab/constants.js:31 +msgid "To use this chart type you need at least one column flagged as a date" +msgstr "" + +#: superset/assets/javascripts/SqlLab/constants.js:32 +msgid "To use this chart type you need at least one dimension" +msgstr "" + +#: superset/assets/javascripts/SqlLab/constants.js:33 +msgid "To use this chart type you need at least one aggregation function" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/QueryTable.jsx:49 +#: superset/assets/javascripts/SqlLab/reducers.js:11 +msgid "Untitled Query" +msgstr "" + +#: superset/assets/javascripts/SqlLab/reducers.js:44 +#, python-format +msgid "Copy of %s" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/CopyQueryTabUrl.jsx:30 +msgid "share query" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/CopyQueryTabUrl.jsx:33 +msgid "copy URL to clipboard" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/HighlightedSql.jsx:61 +msgid "Raw SQL" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/HighlightedSql.jsx:71 +msgid "Source SQL" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/HighlightedSql.jsx:83 +#: superset/assets/javascripts/explore/stores/visTypes.js:40 +msgid "SQL" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/QueryHistory.jsx:28 +msgid "No query history yet..." +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/QuerySearch.jsx:106 +#: superset/assets/javascripts/SqlLab/components/SqlEditorLeftBar.jsx:66 +msgid "It seems you don't have access to any database" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/QuerySearch.jsx:154 +#: superset/assets/javascripts/SqlLab/components/ResultSet.jsx:89 +msgid "Search Results" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/QuerySearch.jsx:160 +msgid "[From]-" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/QuerySearch.jsx:170 +msgid "[To]-" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/QuerySearch.jsx:179 +msgid "[Query Status]" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/QuerySearch.jsx:188 +msgid "Search" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/QueryTable.jsx:114 +msgid "Open in SQL Editor" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/QueryTable.jsx:133 +msgid "view results" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/QueryTable.jsx:136 +msgid "Data preview" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/QueryTable.jsx:176 +msgid "Visualize the data out of this query" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/QueryTable.jsx:182 +msgid "Overwrite text in editor with a query on this table" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/QueryTable.jsx:188 +msgid "Run query in a new tab" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/QueryTable.jsx:193 +msgid "Remove query from log" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/ResultSet.jsx:67 +msgid ".CSV" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/ResultSet.jsx:78 +#: superset/assets/javascripts/SqlLab/components/VisualizeModal.jsx:241 +#: superset/assets/javascripts/SqlLab/components/VisualizeModal.jsx:280 +msgid "Visualize" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/ResultSet.jsx:162 +#: superset/connectors/sqla/views.py:86 superset/connectors/sqla/views.py:136 +#: superset/connectors/sqla/views.py:214 superset/views/core.py:376 +msgid "Table" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/ResultSet.jsx:162 +msgid "was created" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/ResultSet.jsx:169 +msgid "Query in a new tab" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/ResultSet.jsx:210 +msgid "Fetch data preview" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/ResultSet.jsx:230 +msgid "Track Job" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/ResultSet.jsx:236 +msgid "Loading..." +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/RunQueryActionButton.jsx:19 +msgid "Run Selected Query" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/RunQueryActionButton.jsx:19 +msgid "Run Query" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/RunQueryActionButton.jsx:22 +msgid "Run query asynchronously" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/RunQueryActionButton.jsx:57 +msgid "Stop" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SaveQuery.jsx:16 +msgid "Undefined" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SaveQuery.jsx:66 +#: superset/views/sql_lab.py:53 +msgid "Label" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SaveQuery.jsx:71 +msgid "Label for your query" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SaveQuery.jsx:81 +#: superset/connectors/druid/views.py:107 +#: superset/connectors/druid/views.py:227 superset/connectors/sqla/views.py:83 +#: superset/connectors/sqla/views.py:132 superset/connectors/sqla/views.py:227 +#: superset/views/core.py:370 superset/views/sql_lab.py:56 +msgid "Description" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SaveQuery.jsx:85 +msgid "Write a description for your query" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SaveQuery.jsx:99 +#: superset/assets/javascripts/dashboard/components/SaveModal.jsx:155 +#: superset/assets/javascripts/explore/components/SaveModal.jsx:217 +msgid "Save" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SaveQuery.jsx:102 +#: superset/templates/superset/request_access.html:16 +msgid "Cancel" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SaveQuery.jsx:123 +msgid "Save Query" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SouthPane.jsx:52 +msgid "Run a query to display results here" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SouthPane.jsx:57 +#, python-format +msgid "Preview for %s" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SouthPane.jsx:81 +msgid "Results" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SouthPane.jsx:87 +msgid "Query History" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SqlEditor.jsx:120 +msgid "Create table as with query results" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SqlEditor.jsx:128 +msgid "new table name" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SqlEditorLeftBar.jsx:90 +msgid "Error while fetching table list" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SqlEditorLeftBar.jsx:131 +msgid "Error while fetching schema list" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SqlEditorLeftBar.jsx:153 +msgid "Error while fetching database list" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SqlEditorLeftBar.jsx:159 +msgid "Database:" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SqlEditorLeftBar.jsx:163 +msgid "Select a database" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SqlEditorLeftBar.jsx:170 +#, python-format +msgid "Select a schema (%s)" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SqlEditorLeftBar.jsx:175 +msgid "Schema:" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SqlEditorLeftBar.jsx:190 +#, python-format +msgid "Add a table (%s)" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SqlEditorLeftBar.jsx:203 +msgid "Type to search ..." +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/SqlEditorLeftBar.jsx:226 +msgid "Reset State" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/TabbedSqlEditors.jsx:105 +msgid "Enter a new title for the tab" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/TabbedSqlEditors.jsx:124 +#, python-format +msgid "Untitled Query %s" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/TabbedSqlEditors.jsx:170 +msgid "close tab" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/TabbedSqlEditors.jsx:173 +msgid "rename tab" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/TabbedSqlEditors.jsx:181 +msgid "expand tool bar" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/TabbedSqlEditors.jsx:181 +msgid "hide tool bar" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/TableElement.jsx:75 +msgid "Copy partition query to clipboard" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/TableElement.jsx:94 +msgid "latest partition:" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/TableElement.jsx:110 +msgid "Keys for table" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/TableElement.jsx:119 +#, python-format +msgid "View keys & indexes (%s)" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/TableElement.jsx:135 +msgid "Sort columns alphabetically" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/TableElement.jsx:136 +msgid "Original table column order" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/TableElement.jsx:146 +msgid "Copy SELECT statement to clipboard" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/TableElement.jsx:152 +msgid "Remove table preview" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/VisualizeModal.jsx:90 +#, python-format +msgid "%s is not right as a column name, please alias it (as in SELECT count(*) " +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/VisualizeModal.jsx:91 +msgid "AS my_alias" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/VisualizeModal.jsx:91 +msgid "using only alphanumeric characters and underscores" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/VisualizeModal.jsx:166 +msgid "Creating a data source and popping a new tab" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/VisualizeModal.jsx:196 +msgid "No results available for this query" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/VisualizeModal.jsx:248 +msgid "Chart Type" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/VisualizeModal.jsx:251 +msgid "[Chart Type]" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/VisualizeModal.jsx:259 +msgid "Datasource Name" +msgstr "" + +#: superset/assets/javascripts/SqlLab/components/VisualizeModal.jsx:263 +msgid "datasource name" +msgstr "" + +#: superset/assets/javascripts/components/AsyncSelect.jsx:20 +msgid "Select ..." +msgstr "" + +#: superset/assets/javascripts/components/CachedLabel.jsx:26 +msgid "Loaded data cached" +msgstr "" + +#: superset/assets/javascripts/components/CachedLabel.jsx:28 +msgid "Loaded from cache" +msgstr "" + +#: superset/assets/javascripts/components/CachedLabel.jsx:33 +msgid "Click to force-refresh" +msgstr "" + +#: superset/assets/javascripts/components/CopyToClipboard.jsx:21 +#: superset/assets/javascripts/explore/components/EmbedCodeButton.jsx:67 +#: superset/assets/javascripts/explore/components/URLShortLinkButton.jsx:37 +msgid "Copy to clipboard" +msgstr "" + +#: superset/assets/javascripts/components/CopyToClipboard.jsx:65 +msgid "Not successful" +msgstr "" + +#: superset/assets/javascripts/components/CopyToClipboard.jsx:68 +msgid "Sorry, your browser does not support copying. Use Ctrl / Cmd + C!" +msgstr "" + +#: superset/assets/javascripts/components/CopyToClipboard.jsx:79 +msgid "Copied!" +msgstr "" + +#: superset/assets/javascripts/components/EditableTitle.jsx:12 +#: superset/views/core.py:471 superset/views/core.py:538 +msgid "Title" +msgstr "" + +#: superset/assets/javascripts/components/EditableTitle.jsx:75 +msgid "click to edit title" +msgstr "" + +#: superset/assets/javascripts/components/EditableTitle.jsx:75 +msgid "You don't have the rights to alter this title." +msgstr "" + +#: superset/assets/javascripts/components/FaveStar.jsx:32 +#: superset/assets/javascripts/modules/superset.js:33 +msgid "Click to favorite/unfavorite" +msgstr "" + +#: superset/assets/javascripts/dashboard/Dashboard.jsx:42 +#: superset/assets/javascripts/dashboard/Dashboard.jsx:59 +msgid "You have unsaved changes." +msgstr "" + +#: superset/assets/javascripts/dashboard/Dashboard.jsx:59 +msgid "Click the" +msgstr "" + +#: superset/assets/javascripts/dashboard/Dashboard.jsx:61 +msgid "button on the top right to save your changes." +msgstr "" + +#: superset/assets/javascripts/dashboard/Dashboard.jsx:164 +#, python-format +msgid "Served from data cached %s . Click to force refresh." +msgstr "" + +#: superset/assets/javascripts/dashboard/Dashboard.jsx:169 +msgid "Click to force refresh" +msgstr "" + +#: superset/assets/javascripts/dashboard/Dashboard.jsx:353 +#: superset/assets/javascripts/dashboard/components/SaveModal.jsx:100 +msgid "Error" +msgstr "" + +#: superset/assets/javascripts/dashboard/Dashboard.jsx:354 +#, python-format +msgid "Sorry, there was an error adding slices to this dashboard: %s" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/CodeModal.jsx:35 +msgid "Active Dashboard Filters" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/Controls.jsx:48 +#, python-format +msgid "Checkout this dashboard: %s" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/Controls.jsx:54 +msgid "Force refresh the whole dashboard" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/Controls.jsx:94 +msgid "Edit this dashboard's properties" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/CssEditor.jsx:65 +msgid "Load a template" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/CssEditor.jsx:68 +msgid "Load a CSS template" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/CssEditor.jsx:80 +#: superset/views/core.py:478 +msgid "CSS" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/CssEditor.jsx:86 +msgid "Live CSS Editor" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/RefreshIntervalModal.jsx:19 +msgid "Don't refresh" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/RefreshIntervalModal.jsx:20 +msgid "10 seconds" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/RefreshIntervalModal.jsx:21 +msgid "30 seconds" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/RefreshIntervalModal.jsx:22 +msgid "1 minute" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/RefreshIntervalModal.jsx:23 +msgid "5 minutes" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/RefreshIntervalModal.jsx:38 +msgid "Refresh Interval" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/RefreshIntervalModal.jsx:41 +msgid "Choose the refresh frequency for this dashboard" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SaveModal.jsx:63 +msgid "This dashboard was saved successfully." +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SaveModal.jsx:69 +msgid "Sorry, there was an error saving this dashboard: " +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SaveModal.jsx:101 +msgid "You must pick a name for the new dashboard" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SaveModal.jsx:115 +msgid "Save Dashboard" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SaveModal.jsx:123 +#, python-format +msgid "Overwrite Dashboard [%s]" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SaveModal.jsx:131 +msgid "Save as:" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SaveModal.jsx:135 +#: superset/assets/javascripts/explore/components/SaveModal.jsx:205 +msgid "[dashboard name]" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SliceAdder.jsx:142 +#: superset/views/core.py:375 +msgid "Name" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SliceAdder.jsx:148 +msgid "Viz" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SliceAdder.jsx:157 +#: superset/views/core.py:476 superset/views/core.py:540 +#: superset/views/sql_lab.py:57 +msgid "Modified" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SliceAdder.jsx:167 +msgid "Add Slices" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SliceAdder.jsx:176 +msgid "Add a new slice to the dashboard" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SliceAdder.jsx:181 +msgid "Add Slices to Dashboard" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SliceCell.jsx:24 +msgid "Move chart" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SliceCell.jsx:27 +msgid "Force refresh data" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SliceCell.jsx:31 +msgid "Toggle chart description" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SliceCell.jsx:41 +msgid "Edit chart" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SliceCell.jsx:46 +msgid "Export CSV" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SliceCell.jsx:49 +msgid "Explore chart" +msgstr "" + +#: superset/assets/javascripts/dashboard/components/SliceCell.jsx:54 +msgid "Remove chart from dashboard" +msgstr "" + +#: superset/assets/javascripts/explore/components/ChartContainer.jsx:173 +#, python-format +msgid "%s - untitled" +msgstr "" + +#: superset/assets/javascripts/explore/components/ChartContainer.jsx:280 +msgid "Edit slice properties" +msgstr "" + +#: superset/assets/javascripts/explore/components/ControlHeader.jsx:32 +msgid "description" +msgstr "" + +#: superset/assets/javascripts/explore/components/ControlHeader.jsx:42 +msgid "bolt" +msgstr "" + +#: superset/assets/javascripts/explore/components/DisplayQueryButton.jsx:61 +msgid "Error..." +msgstr "" + +#: superset/assets/javascripts/explore/components/DisplayQueryButton.jsx:97 +#: superset/assets/javascripts/explore/stores/visTypes.js:49 +#: superset/assets/javascripts/explore/stores/visTypes.js:129 +#: superset/assets/javascripts/explore/stores/visTypes.js:375 +#: superset/assets/javascripts/explore/stores/visTypes.js:422 +#: superset/assets/javascripts/explore/stores/visTypes.js:443 +#: superset/assets/javascripts/explore/stores/visTypes.js:471 +#: superset/assets/javascripts/explore/stores/visTypes.js:491 +#: superset/assets/javascripts/explore/stores/visTypes.js:512 +#: superset/assets/javascripts/explore/stores/visTypes.js:564 +#: superset/assets/javascripts/explore/stores/visTypes.js:586 +#: superset/assets/javascripts/explore/stores/visTypes.js:611 +#: superset/assets/javascripts/explore/stores/visTypes.js:636 +#: superset/assets/javascripts/explore/stores/visTypes.js:668 +#: superset/assets/javascripts/explore/stores/visTypes.js:705 +#: superset/assets/javascripts/explore/stores/visTypes.js:732 +#: superset/assets/javascripts/explore/stores/visTypes.js:759 +#: superset/assets/javascripts/explore/stores/visTypes.js:797 +#: superset/assets/javascripts/explore/stores/visTypes.js:830 +#: superset/assets/javascripts/explore/stores/visTypes.js:867 +#: superset/assets/javascripts/explore/stores/visTypes.js:910 +#: superset/assets/javascripts/explore/stores/visTypes.js:977 +msgid "Query" +msgstr "" + +#: superset/assets/javascripts/explore/components/EmbedCodeButton.jsx:76 +msgid "Height" +msgstr "" + +#: superset/assets/javascripts/explore/components/EmbedCodeButton.jsx:90 +msgid "Width" +msgstr "" + +#: superset/assets/javascripts/explore/components/ExploreActionButtons.jsx:32 +msgid "Export to .json" +msgstr "" + +#: superset/assets/javascripts/explore/components/ExploreActionButtons.jsx:42 +msgid "Export to .csv format" +msgstr "" + +#: superset/assets/javascripts/explore/components/SaveModal.jsx:74 +msgid "Please enter a slice name" +msgstr "" + +#: superset/assets/javascripts/explore/components/SaveModal.jsx:89 +msgid "Please select a dashboard" +msgstr "" + +#: superset/assets/javascripts/explore/components/SaveModal.jsx:97 +msgid "Please enter a dashboard name" +msgstr "" + +#: superset/assets/javascripts/explore/components/SaveModal.jsx:130 +msgid "Save A Slice" +msgstr "" + +#: superset/assets/javascripts/explore/components/SaveModal.jsx:151 +#, python-format +msgid "Overwrite slice %s" +msgstr "" + +#: superset/assets/javascripts/explore/components/SaveModal.jsx:160 +msgid "Save as" +msgstr "" + +#: superset/assets/javascripts/explore/components/SaveModal.jsx:164 +msgid "[slice name]" +msgstr "" + +#: superset/assets/javascripts/explore/components/SaveModal.jsx:177 +msgid "Do not add to a dashboard" +msgstr "" + +#: superset/assets/javascripts/explore/components/SaveModal.jsx:185 +msgid "Add slice to existing dashboard" +msgstr "" + +#: superset/assets/javascripts/explore/components/SaveModal.jsx:200 +msgid "Add to new dashboard" +msgstr "" + +#: superset/assets/javascripts/explore/components/SaveModal.jsx:226 +msgid "Save & go to dashboard" +msgstr "" + +#: superset/assets/javascripts/explore/components/URLShortLinkButton.jsx:32 +#, python-format +msgid "Check out this slice: %s" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/BoundsControl.jsx:55 +msgid "`Min` value should be numeric or empty" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/BoundsControl.jsx:58 +msgid "`Max` value should be numeric or empty" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/BoundsControl.jsx:75 +#: superset/connectors/druid/views.py:50 superset/connectors/sqla/views.py:89 +msgid "Min" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/BoundsControl.jsx:83 +#: superset/connectors/druid/views.py:51 superset/connectors/sqla/views.py:90 +msgid "Max" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/DatasourceControl.jsx:70 +msgid "Something went wrong while fetching the datasource list" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/DatasourceControl.jsx:95 +msgid "Click to point to another datasource" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/DatasourceControl.jsx:106 +msgid "Edit the datasource's configuration" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/DatasourceControl.jsx:122 +msgid "Select a datasource" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/DatasourceControl.jsx:132 +#: superset/assets/javascripts/explore/components/controls/VizTypeControl.jsx:120 +msgid "Search / Filter" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/Filter.jsx:118 +msgid "Filter value" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/Filter.jsx:147 +msgid "Select metric" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/Filter.jsx:147 +msgid "Select column" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/Filter.jsx:159 +msgid "Select operator" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/FilterControl.jsx:70 +#: superset/templates/appbuilder/general/widgets/search.html:6 +msgid "Add Filter" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/SelectControl.jsx:106 +#, python-format +msgid "Select %s" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/TextAreaControl.jsx:63 +msgid "textarea" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/TextAreaControl.jsx:81 +msgid "Edit" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/TextAreaControl.jsx:81 +msgid "in modal" +msgstr "" + +#: superset/assets/javascripts/explore/components/controls/VizTypeControl.jsx:110 +msgid "Select a visualization type" +msgstr "" + +#: superset/assets/javascripts/explore/reducers/chartReducer.js:32 +msgid "Updating chart was stopped" +msgstr "" + +#: superset/assets/javascripts/explore/reducers/chartReducer.js:38 +#: superset/assets/javascripts/modules/superset.js:222 +#, python-format +msgid "An error occurred while rendering the visualization: %s" +msgstr "" + +#: superset/assets/javascripts/explore/reducers/chartReducer.js:47 +msgid "" +"Perhaps your data has grown, your database is under unusual load, or you " +"are simply querying a data source that is to large to be processed within" +" the timeout range. If that is the case, we recommend that you summarize " +"your data further." +msgstr "" + +#: superset/assets/javascripts/explore/reducers/chartReducer.js:56 +msgid "Network error." +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:36 +msgid "A reference to the [Time] configuration, taking granularity into account" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:44 +msgid "Group by" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:47 +msgid "One or many controls to group by" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:66 +#: superset/connectors/druid/views.py:45 superset/views/core.py:314 +#: superset/views/core.py:338 superset/views/core.py:369 +msgid "Datasource" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:76 +#: superset/views/core.py:377 +msgid "Visualization Type" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:78 +msgid "The type of visualization to display" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:84 +msgid "Metrics" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:93 +#: superset/assets/javascripts/explore/stores/controls.jsx:110 +msgid "One or many metrics to display" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:97 +msgid "Y Axis Bounds" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:100 +msgid "" +"Bounds for the Y axis. When left empty, the bounds are dynamically " +"defined based on the min/max of the data. Note that this feature will " +"only expand the axis range. It won't narrow the data's extent." +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:108 +msgid "Ordering" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:118 +#: superset/assets/javascripts/explore/stores/visTypes.js:818 +#: superset/connectors/druid/views.py:106 superset/connectors/sqla/views.py:131 +msgid "Metric" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:120 +msgid "Choose the metric" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:133 +msgid "Right Axis Metric" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:137 +msgid "Choose a metric for right axis" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:148 +msgid "Stacked Style" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:160 +msgid "Linear Color Scheme" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:177 +msgid "Normalize Across" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:184 +msgid "" +"Color will be rendered based on a ratio of the cell against the sum of " +"across this criteria" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:191 +msgid "Horizon Color Scale" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:198 +msgid "Defines how the color are attributed." +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:203 +msgid "Rendering" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:209 +msgid "" +"image-rendering CSS attribute of the canvas object that defines how the " +"browser scales up the image" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:215 +msgid "XScale Interval" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:218 +msgid "Number of steps to take between ticks when displaying the X scale" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:224 +msgid "YScale Interval" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:227 +msgid "Number of steps to take between ticks when displaying the Y scale" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:233 +msgid "Include Time" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:234 +msgid "Whether to include the time granularity as defined in the time section" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:240 +msgid "Stacked Bars" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:248 +msgid "Show totals" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:251 +msgid "Display total row/column" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:256 +msgid "Show Markers" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:259 +msgid "Show data points as circle markers on the lines" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:264 +msgid "Bar Values" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:267 +msgid "Show the value on top of the bar" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:272 +msgid "Sort Bars" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:274 +msgid "Sort bars by x labels." +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:279 +msgid "Combine Metrics" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:281 +msgid "" +"Display metrics side by side within each column, as opposed to each " +"column being displayed side by side for each metric." +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:287 +msgid "Extra Controls" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:290 +msgid "" +"Whether to show extra controls or not. Extra controls include things like" +" making mulitBar charts stacked or side by side." +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:297 +msgid "Reduce X ticks" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:300 +msgid "" +"Reduces the number of X axis ticks to be rendered. If true, the x axis " +"wont overflow and labels may be missing. If false, a minimum width will " +"be applied to columns and the width may overflow into an horizontal " +"scroll." +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:309 +msgid "Include Series" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:312 +msgid "Include series name as an axis" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:317 +msgid "Color Metric" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:319 +msgid "A metric to use for color" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:326 +msgid "Country Name" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:345 +msgid "The name of country that Superset should display" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:349 +msgid "Country Field Type" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:357 +msgid "" +"The country code standard that Superset should expect to find in the " +"[country] column" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:364 +#: superset/assets/javascripts/explore/stores/controls.jsx:371 +msgid "Columns" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:365 +msgid "One or many controls to pivot as columns" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:373 +#: superset/assets/javascripts/explore/stores/controls.jsx:383 +#: superset/assets/javascripts/explore/stores/controls.jsx:393 +msgid "Columns to display" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:402 +msgid "Origin" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:408 +msgid "" +"Defines the origin where time buckets start, accepts natural dates as in " +"`now`, `sunday` or `1970-01-01`" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:415 +msgid "Bottom Margin" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:419 +msgid "Bottom margin, in pixels, allowing for more room for axis labels" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:425 +msgid "Left Margin" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:429 +msgid "Left margin, in pixels, allowing for more room for axis labels" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:435 +msgid "Time Granularity" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:452 +msgid "" +"The time granularity for the visualization. Note that you can type and " +"use simple natural language as in `10 seconds`, `1 day` or `56 weeks`" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:459 +msgid "Domain" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:462 +msgid "The time unit used for the grouping of blocks" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:467 +msgid "Subdomain" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:470 +msgid "" +"The time unit for each block. Should be a smaller unit than " +"domain_granularity. Should be larger or equal to Time Grain" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:477 +msgid "Link Length" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:480 +msgid "Link length in the force layout" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:486 +msgid "Charge" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:500 +msgid "Charge in the force layout" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:508 +msgid "" +"The time column for the visualization. Note that you can define arbitrary" +" expression that return a DATETIME column in the table or. Also note that" +" the filter below is applied against this column or expression" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:520 +msgid "Time Grain" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:522 +msgid "" +"The time granularity for the visualization. This applies a date " +"transformation to alter your time column and defines a new time " +"granularity. The options here are defined on a per database engine basis " +"in the Superset source code." +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:535 +msgid "Resample Rule" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:538 +msgid "Pandas resample rule" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:544 +msgid "Resample How" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:547 +msgid "Pandas resample how" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:553 +msgid "Resample Fill Method" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:556 +msgid "Pandas resample fill method" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:562 +msgid "Since" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:563 +msgid "7 days ago" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:569 +msgid "Until" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:576 +msgid "Max Bubble Size" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:584 +msgid "Whisker/outlier options" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:586 +msgid "Determines how whiskers and outliers are calculated." +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:597 +msgid "Ratio" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:600 +msgid "Target aspect ratio for treemap tiles." +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:606 +#: superset/assets/javascripts/explore/stores/visTypes.js:602 +#: superset/assets/javascripts/explore/stores/visTypes.js:627 +#: superset/assets/javascripts/explore/stores/visTypes.js:776 +msgid "Number format" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:616 +msgid "Row limit" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:624 +msgid "Series limit" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:627 +msgid "Limits the number of time series that get displayed" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:632 +msgid "Sort By" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:634 +msgid "Metric used to define the top series" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:642 +msgid "Rolling" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:645 +msgid "" +"Defines a rolling window function to apply, works along with the " +"[Periods] text box" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:651 +msgid "Periods" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:653 +msgid "" +"Defines the size of the rolling window function, relative to the time " +"granularity selected" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:659 +msgid "Min Periods" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:661 +msgid "" +"The minimum number of rolling periods required to show a value. For " +"instance if you do a cumulative sum on 7 days you may want your \"Min " +"Period\" to be 7, so that all data points shown are the total of 7 " +"periods. This will hide the \"ramp up\" taking place over the first 7 " +"periods" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:670 +#: superset/assets/javascripts/explore/stores/visTypes.js:115 +msgid "Series" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:672 +msgid "" +"Defines the grouping of entities. Each series is shown as a specific " +"color on the chart and has a legend toggle" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:682 +msgid "Entity" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:685 +msgid "This defines the element to be plotted on the chart" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:693 +#: superset/assets/javascripts/explore/stores/visTypes.js:164 +#: superset/assets/javascripts/explore/stores/visTypes.js:533 +msgid "X Axis" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:694 +msgid "Metric assigned to the [X] axis" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:707 +#: superset/assets/javascripts/explore/stores/visTypes.js:171 +#: superset/assets/javascripts/explore/stores/visTypes.js:541 +msgid "Y Axis" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:710 +msgid "Metric assigned to the [Y] axis" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:721 +msgid "Bubble Size" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:734 +msgid "URL" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:735 +msgid "" +"The URL, this control is templated, so you can integrate {{ width }} " +"and/or {{ height }} in your URL string." +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:742 +msgid "X Axis Label" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:749 +msgid "Y Axis Label" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:756 +msgid "Custom WHERE clause" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:758 +msgid "" +"The text in this box gets included in your query's WHERE clause, as an " +"AND to other criteria. You can include complex expression, parenthesis " +"and anything else supported by the backend it is directed towards." +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:766 +msgid "Custom HAVING clause" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:768 +msgid "" +"The text in this box gets included in your query's HAVING clause, as an " +"AND to other criteria. You can include complex expression, parenthesis " +"and anything else supported by the backend it is directed towards." +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:776 +msgid "Comparison Period Lag" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:778 +msgid "Based on granularity, number of time periods to compare against" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:783 +msgid "Comparison suffix" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:784 +msgid "Suffix to apply after the percentage display" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:790 +msgid "Table Timestamp Format" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:795 +msgid "Timestamp Format" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:801 +msgid "Series Height" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:804 +msgid "Pixel height of each series" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:810 +msgid "Page Length" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:813 +msgid "Rows per page, 0 means no pagination" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:819 +#: superset/assets/javascripts/explore/stores/controls.jsx:829 +msgid "X Axis Format" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:839 +msgid "Y Axis Format" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:849 +msgid "Right Axis Format" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:857 +msgid "Markup Type" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:862 +msgid "Pick your favorite markup language" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:867 +msgid "Rotation" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:870 +msgid "Rotation to apply to words in the cloud" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:875 +msgid "Line Style" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:880 +msgid "Line interpolation as defined by d3.js" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:885 +msgid "Label Type" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:892 +msgid "What should be shown on the label?" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:897 +#: superset/assets/javascripts/explore/stores/visTypes.js:362 +#: superset/assets/javascripts/explore/stores/visTypes.js:400 +msgid "Code" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:898 +msgid "Put your code here" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:907 +msgid "Aggregation function" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:919 +msgid "" +"Aggregate function to apply when pivoting and computing the total rows " +"and columns" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:926 +msgid "Font Size From" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:928 +msgid "Font size for the smallest value in the list" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:934 +msgid "Font Size To" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:936 +msgid "Font size for the biggest value in the list" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:941 +msgid "Instant Filtering" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:952 +msgid "Range Filter" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:955 +msgid "Whether to display the time range interactive selector" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:960 +msgid "Date Filter" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:962 +msgid "Whether to include a time filter" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:967 +msgid "Data Table" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:969 +msgid "Whether to display the interactive data table" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:974 +msgid "Search Box" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:977 +msgid "Whether to include a client side search box" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:982 +msgid "Table Filter" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:984 +msgid "Whether to apply filter when table cell is clicked" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:989 +msgid "Show Bubbles" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:992 +msgid "Whether to display bubbles on top of countries" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:997 +msgid "Legend" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1000 +msgid "Whether to display the legend (toggles)" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1005 +msgid "X bounds" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1008 +msgid "Whether to display the min and max values of the X axis" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1013 +msgid "Y bounds" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1016 +msgid "Whether to display the min and max values of the Y axis" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1021 +msgid "Rich Tooltip" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1024 +msgid "The rich tooltip shows a list of all series for that point in time" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1030 +msgid "Y Log Scale" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1033 +msgid "Use a log scale for the Y axis" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1038 +msgid "X Log Scale" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1041 +msgid "Use a log scale for the X axis" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1046 +msgid "Donut" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1049 +msgid "Do you want a donut or a pie?" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1054 +msgid "Put labels outside" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1057 +msgid "Put the labels outside the pie?" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1062 +msgid "Contribution" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1064 +msgid "Compute the contribution to the total" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1069 +msgid "Period Ratio" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1072 +msgid "" +"[integer] Number of period to compare against, this is relative to the " +"granularity selected" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1078 +msgid "Period Ratio Type" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1081 +msgid "" +"`factor` means (new/previous), `growth` is ((new/previous) - 1), `value` " +"is (new-previous)" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1087 +msgid "Time Shift" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1089 +msgid "" +"Overlay a timeseries from a relative time period. Expects relative time " +"delta in natural language (example: 24 hours, 7 days, 56 weeks, 365 " +"days)" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1097 +msgid "Subheader" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1098 +msgid "Description text that shows up below your Big Number" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1104 +msgid "label" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1106 +msgid "" +"`count` is COUNT(*) if a group by is used. Numerical columns will be " +"aggregated with the aggregator. Non-numerical columns will be used to " +"label points. Leave empty to get a count of points in each cluster." +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1117 +msgid "Map Style" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1127 +msgid "Base layer map style" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1133 +msgid "Clustering Radius" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1146 +msgid "" +"The radius (in pixels) the algorithm uses to define a cluster. Choose 0 " +"to turn off clustering, but beware that a large number of points (>1000) " +"will cause lag." +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1153 +msgid "Point Radius" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1155 +msgid "" +"The radius of individual points (ones that are not in a cluster). Either " +"a numerical column or `Auto`, which scales the point based on the largest" +" cluster" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1165 +msgid "Point Radius Unit" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1168 +msgid "The unit of measure for the specified point radius" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1173 +msgid "Opacity" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1176 +msgid "Opacity of all clusters, points, and labels. Between 0 and 1." +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1182 +msgid "Zoom" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1185 +msgid "Zoom level of the map" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1191 +msgid "Default latitude" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1194 +msgid "Latitude of default viewport" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1200 +msgid "Default longitude" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1203 +msgid "Longitude of default viewport" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1209 +msgid "Live render" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1211 +msgid "Points and clusters will update as viewport is being changed" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1217 +msgid "RGB Color" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1227 +msgid "The color for points and clusters in RGB" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1232 +msgid "Ranges" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1234 +msgid "Ranges to highlight with shading" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1239 +msgid "Range labels" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1241 +msgid "Labels for the ranges" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1246 +msgid "Markers" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1248 +msgid "List of values to mark with triangles" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1253 +msgid "Marker labels" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1255 +msgid "Labels for the markers" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1260 +msgid "Marker lines" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1262 +msgid "List of values to mark with lines" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1267 +msgid "Marker line labels" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1269 +msgid "Labels for the marker lines" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1296 +msgid "Slice ID" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1298 +msgid "The id of the active slice" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1303 +msgid "Cache Timeout (seconds)" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1305 +msgid "The number of seconds before expiring the cache" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1310 +msgid "Order by entity id" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1311 +msgid "" +"Important! Select this if the table is not already sorted by entity id, " +"else there is no guarantee that all events for each entity are returned." +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1319 +msgid "Minimum leaf node event count" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1322 +msgid "" +"Leaf nodes that represent fewer than this number of events will be " +"initially hidden in the visualization" +msgstr "" + +#: superset/assets/javascripts/explore/stores/controls.jsx:1328 +#: superset/assets/javascripts/explore/stores/visTypes.js:25 +msgid "Color Scheme" msgstr "" -#: superset/viz.py:398 -msgid "'Group By' and 'Columns' can't overlap" +#: superset/assets/javascripts/explore/stores/controls.jsx:1332 +msgid "The color scheme for rendering chart" msgstr "" -#: superset/viz.py:431 -msgid "Markup" +#: superset/assets/javascripts/explore/stores/visTypes.js:7 +#: superset/assets/javascripts/explore/stores/visTypes.js:31 +msgid "Time" msgstr "" -#: superset/viz.py:450 -msgid "Separator" +#: superset/assets/javascripts/explore/stores/visTypes.js:9 +#: superset/assets/javascripts/explore/stores/visTypes.js:32 +msgid "Time related form attributes" msgstr "" -#: superset/viz.py:466 -msgid "Word Cloud" +#: superset/assets/javascripts/explore/stores/visTypes.js:16 +msgid "Datasource & Chart Type" msgstr "" -#: superset/viz.py:489 -msgid "Treemap" +#: superset/assets/javascripts/explore/stores/visTypes.js:45 +msgid "This section exposes ways to include snippets of SQL in your query" msgstr "" -#: superset/viz.py:515 -msgid "Calendar Heatmap" +#: superset/assets/javascripts/explore/stores/visTypes.js:58 +msgid "Advanced Analytics" msgstr "" -#: superset/viz.py:573 -msgid "Box Plot" +#: superset/assets/javascripts/explore/stores/visTypes.js:59 +msgid "" +"This section contains options that allow for advanced analytical post " +"processing of query results" msgstr "" -#: superset/viz.py:662 -msgid "Bubble Chart" +#: superset/assets/javascripts/explore/stores/visTypes.js:77 +msgid "Result Filters" msgstr "" -#: superset/viz.py:686 -msgid "Pick a metric for x, y and size" +#: superset/assets/javascripts/explore/stores/visTypes.js:79 +msgid "" +"The filters to apply after post-aggregation.Leave the value control empty" +" to filter empty strings or nulls" msgstr "" -#: superset/viz.py:712 -msgid "Bullet Chart" +#: superset/assets/javascripts/explore/stores/visTypes.js:92 +#: superset/assets/javascripts/explore/stores/visTypes.js:101 +#: superset/assets/javascripts/explore/stores/visTypes.js:137 +#: superset/assets/javascripts/explore/stores/visTypes.js:155 +#: superset/assets/javascripts/explore/stores/visTypes.js:193 +#: superset/assets/javascripts/explore/stores/visTypes.js:234 +#: superset/assets/javascripts/explore/stores/visTypes.js:268 +#: superset/assets/javascripts/explore/stores/visTypes.js:290 +#: superset/assets/javascripts/explore/stores/visTypes.js:451 +#: superset/assets/javascripts/explore/stores/visTypes.js:499 +#: superset/assets/javascripts/explore/stores/visTypes.js:520 +#: superset/assets/javascripts/explore/stores/visTypes.js:644 +#: superset/assets/javascripts/explore/stores/visTypes.js:677 +#: superset/assets/javascripts/explore/stores/visTypes.js:714 +#: superset/assets/javascripts/explore/stores/visTypes.js:767 +#: superset/assets/javascripts/explore/stores/visTypes.js:965 +msgid "Chart Options" msgstr "" -#: superset/viz.py:738 -msgid "Pick a metric to display" +#: superset/assets/javascripts/explore/stores/visTypes.js:118 +msgid "Breakdowns" msgstr "" -#: superset/viz.py:761 -msgid "Big Number with Trendline" +#: superset/assets/javascripts/explore/stores/visTypes.js:119 +msgid "Defines how each series is broken down" msgstr "" -#: superset/viz.py:769 superset/viz.py:798 -msgid "Pick a metric!" +#: superset/assets/javascripts/explore/stores/visTypes.js:125 +msgid "Pie Chart" msgstr "" -#: superset/viz.py:790 -msgid "Big Number" +#: superset/assets/javascripts/explore/stores/visTypes.js:189 +msgid "Dual Axis Line Chart" msgstr "" -#: superset/viz.py:817 -msgid "Time Series - Line Chart" +#: superset/assets/javascripts/explore/stores/visTypes.js:200 +msgid "Y Axis 1" msgstr "" -#: superset/viz.py:864 superset/viz.py:1001 -msgid "Pick a time granularity for your time series" +#: superset/assets/javascripts/explore/stores/visTypes.js:206 +msgid "Y Axis 2" msgstr "" -#: superset/viz.py:944 -msgid "Time Series - Dual Axis Line Chart" +#: superset/assets/javascripts/explore/stores/visTypes.js:214 +msgid "Left Axis Metric" msgstr "" -#: superset/viz.py:954 -msgid "Pick a metric for left axis!" +#: superset/assets/javascripts/explore/stores/visTypes.js:215 +msgid "Choose a metric for left axis" msgstr "" -#: superset/viz.py:956 -msgid "Pick a metric for right axis!" +#: superset/assets/javascripts/explore/stores/visTypes.js:218 +msgid "Left Axis Format" msgstr "" -#: superset/viz.py:958 -msgid "Please choose different metrics on left and right axis" +#: superset/assets/javascripts/explore/stores/visTypes.js:244 +#: superset/assets/javascripts/explore/stores/visTypes.js:300 +msgid "Axes" msgstr "" -#: superset/viz.py:1019 -msgid "Time Series - Bar Chart" +#: superset/assets/javascripts/explore/stores/visTypes.js:324 +msgid "GROUP BY" msgstr "" -#: superset/viz.py:1027 -msgid "Time Series - Percent Change" +#: superset/assets/javascripts/explore/stores/visTypes.js:325 +msgid "Use this section if you want a query that aggregates" msgstr "" -#: superset/viz.py:1035 -msgid "Time Series - Stacked" +#: superset/assets/javascripts/explore/stores/visTypes.js:332 +msgid "NOT GROUPED BY" msgstr "" -#: superset/viz.py:1044 -msgid "Distribution - NVD3 - Pie Chart" +#: superset/assets/javascripts/explore/stores/visTypes.js:333 +msgid "Use this section if you want to query atomic rows" msgstr "" -#: superset/viz.py:1062 -msgid "Histogram" +#: superset/assets/javascripts/explore/stores/visTypes.js:340 +#: superset/assets/javascripts/explore/stores/visTypes.js:741 +#: superset/assets/javascripts/explore/stores/visTypes.js:805 +#: superset/assets/javascripts/explore/stores/visTypes.js:898 +msgid "Options" msgstr "" -#: superset/viz.py:1072 -msgid "Must have one numeric column specified" +#: superset/assets/javascripts/explore/stores/visTypes.js:527 +#: superset/assets/javascripts/explore/stores/visTypes.js:839 +msgid "Bubbles" msgstr "" -#: superset/viz.py:1087 -msgid "Distribution - Bar Chart" +#: superset/assets/javascripts/explore/stores/visTypes.js:653 +msgid "Numeric Column" msgstr "" -#: superset/viz.py:1098 -msgid "Can't have overlap between Series and Breakdowns" +#: superset/assets/javascripts/explore/stores/visTypes.js:654 +msgid "Select the numeric column to draw the histogram" msgstr "" -#: superset/viz.py:1100 -msgid "Pick at least one metric" +#: superset/assets/javascripts/explore/stores/visTypes.js:657 +msgid "No of Bins" msgstr "" -#: superset/viz.py:1102 -msgid "Pick at least one field for [Series]" +#: superset/assets/javascripts/explore/stores/visTypes.js:658 +msgid "Select number of bins for the histogram" msgstr "" -#: superset/viz.py:1155 -msgid "Sunburst" +#: superset/assets/javascripts/explore/stores/visTypes.js:685 +msgid "Primary Metric" msgstr "" -#: superset/viz.py:1188 -msgid "Sankey" +#: superset/assets/javascripts/explore/stores/visTypes.js:686 +msgid "The primary metric is used to define the arc segment sizes" msgstr "" -#: superset/viz.py:1195 -msgid "Pick exactly 2 columns as [Source / Target]" +#: superset/assets/javascripts/explore/stores/visTypes.js:689 +msgid "Secondary Metric" msgstr "" -#: superset/viz.py:1226 +#: superset/assets/javascripts/explore/stores/visTypes.js:690 msgid "" -"There's a loop in your Sankey, please provide a tree. Here's a faulty " -"link: {}" +"This secondary metric is used to define the color as a ratio against the " +"primary metric. If the two metrics match, color is mapped level groups" msgstr "" -#: superset/viz.py:1237 superset/viz.py:1258 -msgid "Directed Force Layout" +#: superset/assets/javascripts/explore/stores/visTypes.js:695 +msgid "Hierarchy" msgstr "" -#: superset/viz.py:1244 -msgid "Pick exactly 2 columns to 'Group By'" +#: superset/assets/javascripts/explore/stores/visTypes.js:696 +msgid "This defines the level of the hierarchy" msgstr "" -#: superset/viz.py:1291 -msgid "Country Map" +#: superset/assets/javascripts/explore/stores/visTypes.js:722 +#: superset/assets/javascripts/explore/stores/visTypes.js:750 +msgid "Source / Target" msgstr "" -#: superset/viz.py:1320 -msgid "World Map" +#: superset/assets/javascripts/explore/stores/visTypes.js:723 +#: superset/assets/javascripts/explore/stores/visTypes.js:751 +msgid "Choose a source and a target" msgstr "" -#: superset/viz.py:1370 -msgid "Filters" +#: superset/assets/javascripts/explore/stores/visTypes.js:756 +msgid "Chord Diagram" msgstr "" -#: superset/viz.py:1378 -msgid "Pick at least one filter field" +#: superset/assets/javascripts/explore/stores/visTypes.js:777 +msgid "Choose a number format" msgstr "" -#: superset/viz.py:1405 -msgid "iFrame" +#: superset/assets/javascripts/explore/stores/visTypes.js:780 +msgid "Source" msgstr "" -#: superset/viz.py:1422 -msgid "Parallel Coordinates" +#: superset/assets/javascripts/explore/stores/visTypes.js:783 +msgid "Choose a source" msgstr "" -#: superset/viz.py:1447 -msgid "Heatmap" +#: superset/assets/javascripts/explore/stores/visTypes.js:786 +msgid "Target" msgstr "" -#: superset/viz.py:1498 -msgid "Horizon Charts" +#: superset/assets/javascripts/explore/stores/visTypes.js:789 +msgid "Choose a target" msgstr "" -#: superset/viz.py:1509 -msgid "Mapbox" +#: superset/assets/javascripts/explore/stores/visTypes.js:814 +msgid "ISO 3166-1 codes of region/province/department" msgstr "" -#: superset/viz.py:1524 -msgid "Must have a [Group By] column to have 'count' as the [Label]" +#: superset/assets/javascripts/explore/stores/visTypes.js:815 +msgid "" +"It's ISO 3166-1 of your region/province/department in your table. (see " +"documentation for list of ISO 3166-1)" msgstr "" -#: superset/viz.py:1537 -msgid "Choice of [Label] must be present in [Group By]" +#: superset/assets/javascripts/explore/stores/visTypes.js:849 +msgid "Country Control" msgstr "" -#: superset/viz.py:1542 -msgid "Choice of [Point Radius] must be present in [Group By]" +#: superset/assets/javascripts/explore/stores/visTypes.js:850 +msgid "3 letter code of the country" msgstr "" -#: superset/viz.py:1547 -msgid "[Longitude] and [Latitude] columns must be present in [Group By]" +#: superset/assets/javascripts/explore/stores/visTypes.js:853 +msgid "Metric for color" msgstr "" -#: superset/viz.py:1612 -msgid "Event flow" +#: superset/assets/javascripts/explore/stores/visTypes.js:854 +msgid "Metric that defines the color of the country" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:857 +msgid "Bubble size" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:858 +msgid "Metric that defines the size of the bubble" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:864 +msgid "Filter Box" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:883 +msgid "Filter controls" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:884 +msgid "" +"The controls you want to filter on. Note that only columns checked as " +"\"filterable\" will show up on this list." +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:932 +msgid "Axis & Metrics" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:940 +msgid "Heatmap Options" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:961 +msgid "Horizon" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:987 +msgid "Points" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:994 +msgid "Labelling" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1001 +msgid "Visual Tweaks" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1010 +msgid "Viewport" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1020 +msgid "Longitude" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1021 +msgid "Column containing longitude data" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1024 +msgid "Latitude" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1025 +msgid "Column containing latitude data" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1028 +msgid "Cluster label aggregator" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1029 +msgid "" +"Aggregate function applied to the list of points in each cluster to " +"produce the cluster label." +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1033 +msgid "Tooltip" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1034 +msgid "Show a tooltip when hovering over points and clusters describing the label" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1038 +msgid "" +"One or many controls to group by. If grouping, latitude and longitude " +"columns must be present." +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1049 +msgid "Event definition" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1059 +msgid "Additional meta data" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1067 +msgid "Column containing entity ids" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1068 +msgid "e.g., a \"user id\" column" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1071 +msgid "Column containing event names" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1079 +msgid "Event count limit" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1080 +msgid "The maximum number of events to return, equivalent to number of rows" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1083 +msgid "Meta data" +msgstr "" + +#: superset/assets/javascripts/explore/stores/visTypes.js:1084 +msgid "Select any columns for meta data inspection" +msgstr "" + +#: superset/assets/javascripts/modules/superset.js:134 +msgid "" +"The server could not be reached. You may want to verify your connection " +"and try again." +msgstr "" + +#: superset/assets/javascripts/modules/superset.js:137 +#, python-format +msgid "An unknown error occurred. (Status: %s )" msgstr "" -#: superset/connectors/druid/models.py:975 +#: superset/assets/javascripts/profile/components/App.jsx:24 +msgid "Favorites" +msgstr "" + +#: superset/assets/javascripts/profile/components/App.jsx:30 +msgid "Created Content" +msgstr "" + +#: superset/assets/javascripts/profile/components/App.jsx:37 +msgid "Recent Activity" +msgstr "" + +#: superset/assets/javascripts/profile/components/App.jsx:42 +msgid "Security & Access" +msgstr "" + +#: superset/assets/javascripts/profile/components/CreatedContent.jsx:33 +msgid "No slices" +msgstr "" + +#: superset/assets/javascripts/profile/components/CreatedContent.jsx:49 +msgid "No dashboards" +msgstr "" + +#: superset/assets/javascripts/profile/components/CreatedContent.jsx:58 +#: superset/assets/javascripts/profile/components/Favorites.jsx:59 +#: superset/templates/superset/welcome.html:13 superset/views/core.py:368 +#: superset/views/core.py:528 +msgid "Dashboards" +msgstr "" + +#: superset/assets/javascripts/profile/components/CreatedContent.jsx:61 +#: superset/assets/javascripts/profile/components/Favorites.jsx:62 +#: superset/views/core.py:404 superset/views/core.py:473 +msgid "Slices" +msgstr "" + +#: superset/assets/javascripts/profile/components/Favorites.jsx:34 +msgid "No favorite slices yet, go click on stars!" +msgstr "" + +#: superset/assets/javascripts/profile/components/Favorites.jsx:50 +msgid "No favorite dashboards yet, go click on stars!" +msgstr "" + +#: superset/assets/javascripts/profile/components/Security.jsx:14 +msgid "Roles" +msgstr "" + +#: superset/assets/javascripts/profile/components/Security.jsx:23 +#: superset/views/core.py:280 +msgid "Databases" +msgstr "" + +#: superset/assets/javascripts/profile/components/Security.jsx:34 +msgid "Datasources" +msgstr "" + +#: superset/assets/javascripts/profile/components/UserInfo.jsx:18 +msgid "Profile picture provided by Gravatar" +msgstr "" + +#: superset/assets/javascripts/profile/components/UserInfo.jsx:33 +msgid "joined" +msgstr "" + +#: superset/assets/javascripts/profile/components/UserInfo.jsx:43 +msgid "id:" +msgstr "" + +#: superset/assets/visualizations/EventFlow.jsx:56 +msgid "Sorry, there appears to be no data" +msgstr "" + +#: superset/assets/visualizations/filter_box.jsx:106 +#, python-format +msgid "Select [%s]" +msgstr "" + +#: superset/connectors/druid/models.py:976 msgid "No data was returned." msgstr "" @@ -382,11 +2715,6 @@ msgstr "" msgid "Type" msgstr "" -#: superset/connectors/druid/views.py:45 superset/views/core.py:314 -#: superset/views/core.py:338 superset/views/core.py:369 -msgid "Datasource" -msgstr "" - #: superset/connectors/druid/views.py:46 superset/connectors/sqla/views.py:84 msgid "Groupable" msgstr "" @@ -403,14 +2731,6 @@ msgstr "" msgid "Sum" msgstr "" -#: superset/connectors/druid/views.py:50 superset/connectors/sqla/views.py:89 -msgid "Min" -msgstr "" - -#: superset/connectors/druid/views.py:51 superset/connectors/sqla/views.py:90 -msgid "Max" -msgstr "" - #: superset/connectors/druid/views.py:54 superset/connectors/sqla/views.py:50 msgid "" "Whether this column is exposed in the `Filters` section of the explore " @@ -440,17 +2760,6 @@ msgid "" "metric)' are allowed to access this metric" msgstr "" -#: superset/connectors/druid/views.py:106 superset/connectors/sqla/views.py:131 -msgid "Metric" -msgstr "" - -#: superset/connectors/druid/views.py:107 -#: superset/connectors/druid/views.py:229 superset/connectors/sqla/views.py:83 -#: superset/connectors/sqla/views.py:132 superset/connectors/sqla/views.py:229 -#: superset/views/core.py:370 superset/views/sql_lab.py:56 -msgid "Description" -msgstr "" - #: superset/connectors/druid/views.py:108 superset/connectors/sqla/views.py:82 #: superset/connectors/sqla/views.py:133 msgid "Verbose Name" @@ -481,7 +2790,7 @@ msgid "Edit Druid Cluster" msgstr "" #: superset/connectors/druid/views.py:142 -#: superset/connectors/druid/views.py:228 +#: superset/connectors/druid/views.py:226 msgid "Cluster" msgstr "" @@ -514,8 +2823,8 @@ msgid "Druid Clusters" msgstr "" #: superset/connectors/druid/views.py:166 -#: superset/connectors/druid/views.py:268 -#: superset/connectors/druid/views.py:307 superset/connectors/sqla/views.py:287 +#: superset/connectors/druid/views.py:266 +#: superset/connectors/druid/views.py:305 superset/connectors/sqla/views.py:285 #: superset/views/core.py:283 msgid "Sources" msgstr "" @@ -536,7 +2845,7 @@ msgstr "" msgid "Edit Druid Datasource" msgstr "" -#: superset/connectors/druid/views.py:197 superset/connectors/sqla/views.py:178 +#: superset/connectors/druid/views.py:195 superset/connectors/sqla/views.py:176 msgid "" "The list of slices associated with this table. By altering this " "datasource, you may change how these associated slices behave. Also note " @@ -545,11 +2854,11 @@ msgid "" "datasource for a slice, overwrite the slice from the 'explore view'" msgstr "" -#: superset/connectors/druid/views.py:205 superset/connectors/sqla/views.py:186 +#: superset/connectors/druid/views.py:203 superset/connectors/sqla/views.py:184 msgid "Timezone offset (in hours) for this datasource" msgstr "" -#: superset/connectors/druid/views.py:209 +#: superset/connectors/druid/views.py:207 msgid "" "Time expression to use as a predicate when retrieving distinct values to " "populate the filter component. Only applies when `Enable Filter Select` " @@ -557,71 +2866,71 @@ msgid "" "filter will be populated based on the distinct value over the past week" msgstr "" -#: superset/connectors/druid/views.py:216 superset/connectors/sqla/views.py:208 +#: superset/connectors/druid/views.py:214 superset/connectors/sqla/views.py:206 msgid "" "Whether to populate the filter's dropdown in the explore view's filter " "section with a list of distinct values fetched from the backend on the " "fly" msgstr "" -#: superset/connectors/druid/views.py:220 +#: superset/connectors/druid/views.py:218 msgid "" "Redirects to this endpoint when clicking on the datasource from the " "datasource list" msgstr "" -#: superset/connectors/druid/views.py:226 superset/connectors/sqla/views.py:215 +#: superset/connectors/druid/views.py:224 superset/connectors/sqla/views.py:213 msgid "Associated Slices" msgstr "" -#: superset/connectors/druid/views.py:227 +#: superset/connectors/druid/views.py:225 msgid "Data Source" msgstr "" -#: superset/connectors/druid/views.py:230 superset/connectors/sqla/views.py:227 +#: superset/connectors/druid/views.py:228 superset/connectors/sqla/views.py:225 msgid "Owner" msgstr "" -#: superset/connectors/druid/views.py:231 +#: superset/connectors/druid/views.py:229 msgid "Is Hidden" msgstr "" -#: superset/connectors/druid/views.py:232 superset/connectors/sqla/views.py:220 +#: superset/connectors/druid/views.py:230 superset/connectors/sqla/views.py:218 msgid "Enable Filter Select" msgstr "" -#: superset/connectors/druid/views.py:233 superset/connectors/sqla/views.py:222 +#: superset/connectors/druid/views.py:231 superset/connectors/sqla/views.py:220 msgid "Default Endpoint" msgstr "" -#: superset/connectors/druid/views.py:234 +#: superset/connectors/druid/views.py:232 msgid "Time Offset" msgstr "" -#: superset/connectors/druid/views.py:235 superset/connectors/sqla/views.py:224 +#: superset/connectors/druid/views.py:233 superset/connectors/sqla/views.py:222 #: superset/views/core.py:248 superset/views/core.py:366 msgid "Cache Timeout" msgstr "" -#: superset/connectors/druid/views.py:266 +#: superset/connectors/druid/views.py:264 msgid "Druid Datasources" msgstr "" -#: superset/connectors/druid/views.py:304 +#: superset/connectors/druid/views.py:302 msgid "Refresh Druid Metadata" msgstr "" -#: superset/connectors/sqla/models.py:390 +#: superset/connectors/sqla/models.py:392 msgid "" "Datetime column not provided as part table configuration and is required " "by this type of chart" msgstr "" -#: superset/connectors/sqla/models.py:395 +#: superset/connectors/sqla/models.py:397 msgid "Metric '{}' is not valid" msgstr "" -#: superset/connectors/sqla/models.py:581 +#: superset/connectors/sqla/models.py:585 msgid "" "Table doesn't seem to exist in the specified database, couldn't fetch " "column information" @@ -656,11 +2965,6 @@ msgid "" "most case users should not need to alter this." msgstr "" -#: superset/connectors/sqla/views.py:86 superset/connectors/sqla/views.py:136 -#: superset/connectors/sqla/views.py:216 superset/views/core.py:376 -msgid "Table" -msgstr "" - #: superset/connectors/sqla/views.py:91 msgid "Expression" msgstr "" @@ -721,77 +3025,77 @@ msgstr "" msgid "Edit Table" msgstr "" -#: superset/connectors/sqla/views.py:187 +#: superset/connectors/sqla/views.py:185 msgid "Name of the table that exists in the source database" msgstr "" -#: superset/connectors/sqla/views.py:189 +#: superset/connectors/sqla/views.py:187 msgid "Schema, as used only in some databases like Postgres, Redshift and DB2" msgstr "" -#: superset/connectors/sqla/views.py:195 +#: superset/connectors/sqla/views.py:193 msgid "" "This fields acts a Superset view, meaning that Superset will run a query " "against this string as a subquery." msgstr "" -#: superset/connectors/sqla/views.py:199 +#: superset/connectors/sqla/views.py:197 msgid "" "Predicate applied when fetching distinct value to populate the filter " "control component. Supports jinja template syntax. Applies only when " "`Enable Filter Select` is on." msgstr "" -#: superset/connectors/sqla/views.py:205 +#: superset/connectors/sqla/views.py:203 msgid "Redirects to this endpoint when clicking on the table from the table list" msgstr "" -#: superset/connectors/sqla/views.py:217 +#: superset/connectors/sqla/views.py:215 msgid "Changed By" msgstr "" -#: superset/connectors/sqla/views.py:218 superset/views/core.py:244 +#: superset/connectors/sqla/views.py:216 superset/views/core.py:244 #: superset/views/sql_lab.py:19 superset/views/sql_lab.py:55 msgid "Database" msgstr "" -#: superset/connectors/sqla/views.py:219 superset/views/core.py:246 +#: superset/connectors/sqla/views.py:217 superset/views/core.py:246 msgid "Last Changed" msgstr "" -#: superset/connectors/sqla/views.py:221 +#: superset/connectors/sqla/views.py:219 msgid "Schema" msgstr "" -#: superset/connectors/sqla/views.py:223 +#: superset/connectors/sqla/views.py:221 msgid "Offset" msgstr "" -#: superset/connectors/sqla/views.py:225 +#: superset/connectors/sqla/views.py:223 msgid "Table Name" msgstr "" -#: superset/connectors/sqla/views.py:226 +#: superset/connectors/sqla/views.py:224 msgid "Fetch Values Predicate" msgstr "" -#: superset/connectors/sqla/views.py:228 +#: superset/connectors/sqla/views.py:226 msgid "Main Datetime Column" msgstr "" -#: superset/connectors/sqla/views.py:248 +#: superset/connectors/sqla/views.py:246 msgid "" "Table [{}] could not be found, please double check your database " "connection, schema, and table name" msgstr "" -#: superset/connectors/sqla/views.py:261 +#: superset/connectors/sqla/views.py:259 msgid "" "The table was created. As part of this two phase configuration process, " "you should now click the edit button by the new table to configure it." msgstr "" -#: superset/connectors/sqla/views.py:285 +#: superset/connectors/sqla/views.py:283 msgid "Tables" msgstr "" @@ -815,10 +3119,6 @@ msgstr "" msgid "No records found" msgstr "" -#: superset/templates/appbuilder/general/widgets/search.html:6 -msgid "Add Filter" -msgstr "" - #: superset/templates/superset/import_dashboards.html:11 msgid "Import" msgstr "" @@ -836,37 +3136,28 @@ msgstr "" msgid "Request Permissions" msgstr "" -#: superset/templates/superset/request_access.html:16 -msgid "Cancel" -msgstr "" - #: superset/templates/superset/welcome.html:3 msgid "Welcome!" msgstr "" -#: superset/templates/superset/welcome.html:13 superset/views/core.py:368 -#: superset/views/core.py:528 -msgid "Dashboards" -msgstr "" - #: superset/templates/superset/models/database/macros.html:4 msgid "Test Connection" msgstr "" -#: superset/views/base.py:58 +#: superset/views/base.py:62 #, python-format msgid "Datasource %(name)s already exists" msgstr "" -#: superset/views/base.py:206 +#: superset/views/base.py:221 msgid "json isn't valid" msgstr "" -#: superset/views/base.py:257 +#: superset/views/base.py:272 msgid "Delete" msgstr "" -#: superset/views/base.py:258 +#: superset/views/base.py:273 msgid "Delete all Really?" msgstr "" @@ -994,15 +3285,11 @@ msgstr "" msgid "Import Dashboards" msgstr "" -#: superset/views/core.py:273 superset/views/core.py:2330 +#: superset/views/core.py:273 superset/views/core.py:2334 #: superset/views/sql_lab.py:30 msgid "Manage" msgstr "" -#: superset/views/core.py:280 -msgid "Databases" -msgstr "" - #: superset/views/core.py:311 superset/views/core.py:552 #: superset/views/sql_lab.py:18 superset/views/sql_lab.py:54 msgid "User" @@ -1076,18 +3363,6 @@ msgstr "" msgid "Slice" msgstr "" -#: superset/views/core.py:375 -msgid "Name" -msgstr "" - -#: superset/views/core.py:377 -msgid "Visualization Type" -msgstr "" - -#: superset/views/core.py:404 superset/views/core.py:473 -msgid "Slices" -msgstr "" - #: superset/views/core.py:433 msgid "List Dashboards" msgstr "" @@ -1136,27 +3411,14 @@ msgstr "" msgid "Dashboard" msgstr "" -#: superset/views/core.py:471 superset/views/core.py:538 -msgid "Title" -msgstr "" - #: superset/views/core.py:472 msgid "Slug" msgstr "" -#: superset/views/core.py:476 superset/views/core.py:540 -#: superset/views/sql_lab.py:57 -msgid "Modified" -msgstr "" - #: superset/views/core.py:477 msgid "Position JSON" msgstr "" -#: superset/views/core.py:478 -msgid "CSS" -msgstr "" - #: superset/views/core.py:479 msgid "JSON Metadata" msgstr "" @@ -1205,53 +3467,53 @@ msgstr "" msgid "You have no permission to approve this request" msgstr "" -#: superset/views/core.py:1618 +#: superset/views/core.py:1625 msgid "" "Malformed request. slice_id or table_name and db_name arguments are " "expected" msgstr "" -#: superset/views/core.py:1624 +#: superset/views/core.py:1631 #, python-format msgid "Slice %(id)s not found" msgstr "" -#: superset/views/core.py:1636 +#: superset/views/core.py:1643 #, python-format msgid "Table %(t)s wasn't found in the database %(d)s" msgstr "" -#: superset/views/core.py:1774 +#: superset/views/core.py:1782 #, python-format msgid "Can't find User '%(name)s', please ask your admin to create one." msgstr "" -#: superset/views/core.py:1781 +#: superset/views/core.py:1789 #, python-format msgid "Can't find DruidCluster with cluster_name = '%(name)s'" msgstr "" -#: superset/views/core.py:2042 +#: superset/views/core.py:2050 msgid "Query record was not created as expected." msgstr "" -#: superset/views/core.py:2316 +#: superset/views/core.py:2320 msgid "Template Name" msgstr "" -#: superset/views/core.py:2327 +#: superset/views/core.py:2331 msgid "CSS Templates" msgstr "" -#: superset/views/core.py:2337 +#: superset/views/core.py:2341 msgid "SQL Editor" msgstr "" -#: superset/views/core.py:2342 superset/views/core.py:2351 +#: superset/views/core.py:2346 superset/views/core.py:2355 msgid "SQL Lab" msgstr "" -#: superset/views/core.py:2346 +#: superset/views/core.py:2350 msgid "Query Search" msgstr "" @@ -1287,10 +3549,6 @@ msgstr "" msgid "Edit Saved Query" msgstr "" -#: superset/views/sql_lab.py:53 -msgid "Label" -msgstr "" - #: superset/views/sql_lab.py:59 msgid "Pop Tab Link" msgstr "" diff --git a/superset/assets/javascripts/SqlLab/actions.js b/superset/assets/javascripts/SqlLab/actions.js index 517c5d28d933d..6438226e74a76 100644 --- a/superset/assets/javascripts/SqlLab/actions.js +++ b/superset/assets/javascripts/SqlLab/actions.js @@ -1,6 +1,7 @@ /* global notify */ import shortid from 'shortid'; import { now } from '../modules/dates'; +import { t } from '../locales'; const $ = require('jquery'); @@ -53,8 +54,8 @@ export function saveQuery(query) { type: 'POST', url, data: query, - success: () => notify.success('Your query was saved'), - error: () => notify.error('Your query could not be saved'), + success: () => notify.success(t('Your query was saved')), + error: () => notify.error(t('Your query could not be saved')), dataType: 'json', }); return { type: SAVE_QUERY }; @@ -107,7 +108,7 @@ export function fetchQueryResults(query) { dispatch(querySuccess(query, results)); }, error(err) { - let msg = 'Failed at retrieving results from the results backend'; + let msg = t('Failed at retrieving results from the results backend'); if (err.responseJSON && err.responseJSON.error) { msg = err.responseJSON.error; } @@ -153,12 +154,12 @@ export function runQuery(query) { } } if (textStatus === 'error' && errorThrown === '') { - msg = 'Could not connect to server'; + msg = t('Could not connect to server'); } else if (msg === null) { msg = `[${textStatus}] ${errorThrown}`; } if (msg.indexOf('CSRF token') > 0) { - msg = 'Your session timed out, please refresh your page and try again.'; + msg = t('Your session timed out, please refresh your page and try again.'); } dispatch(queryFailed(query, msg)); }, @@ -177,10 +178,10 @@ export function postStopQuery(query) { url: stopQueryUrl, data: stopQueryRequestData, success() { - notify.success('Query was stopped.'); + notify.success(t('Query was stopped.')); }, error() { - notify.error('Failed at stopping query.'); + notify.error(t('Failed at stopping query.')); }, }); }; @@ -293,7 +294,7 @@ export function addTable(query, tableName, schemaName) { isMetadataLoading: false, }); dispatch(mergeTable(newTable)); - notify.error('Error occurred while fetching table metadata'); + notify.error(t('Error occurred while fetching table metadata')); }); url = `/superset/extra_table_metadata/${query.dbId}/${tableName}/${schemaName}/`; @@ -306,7 +307,7 @@ export function addTable(query, tableName, schemaName) { isExtraMetadataLoading: false, }); dispatch(mergeTable(newTable)); - notify.error('Error occurred while fetching table metadata'); + notify.error(t('Error occurred while fetching table metadata')); }); }; } @@ -360,7 +361,7 @@ export function popStoredQuery(urlId) { success: (data) => { const newQuery = JSON.parse(data); const queryEditorProps = { - title: newQuery.title ? newQuery.title : 'shared query', + title: newQuery.title ? newQuery.title : t('shared query'), dbId: newQuery.dbId ? parseInt(newQuery.dbId, 10) : null, schema: newQuery.schema ? newQuery.schema : null, autorun: newQuery.autorun ? newQuery.autorun : false, @@ -368,7 +369,7 @@ export function popStoredQuery(urlId) { }; dispatch(addQueryEditor(queryEditorProps)); }, - error: () => notify.error("The query couldn't be loaded"), + error: () => notify.error(t('The query couldn\'t be loaded')), }); }; } @@ -388,7 +389,7 @@ export function popSavedQuery(saveQueryId) { }; dispatch(addQueryEditor(queryEditorProps)); }, - error: () => notify.error("The query couldn't be loaded"), + error: () => notify.error(t('The query couldn\'t be loaded')), }); }; } @@ -421,7 +422,7 @@ export function createDatasource(vizOptions, context) { dispatch(createDatasourceSuccess(resp)); }, error: () => { - dispatch(createDatasourceFailed('An error occurred while creating the data source')); + dispatch(createDatasourceFailed(t('An error occurred while creating the data source'))); }, }); }; diff --git a/superset/assets/javascripts/SqlLab/components/CopyQueryTabUrl.jsx b/superset/assets/javascripts/SqlLab/components/CopyQueryTabUrl.jsx index 5491eed545b3e..66e60c9b2b4f7 100644 --- a/superset/assets/javascripts/SqlLab/components/CopyQueryTabUrl.jsx +++ b/superset/assets/javascripts/SqlLab/components/CopyQueryTabUrl.jsx @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import CopyToClipboard from '../../components/CopyToClipboard'; import { storeQuery } from '../../../utils/common'; +import { t } from '../../locales'; const propTypes = { queryEditor: PropTypes.object.isRequired, @@ -26,10 +27,10 @@ export default class CopyQueryTabUrl extends React.PureComponent { inMenu copyNode={(
- share query + {t('share query')}
)} - tooltipText="copy URL to clipboard" + tooltipText={t('copy URL to clipboard')} shouldShowText={false} getText={this.getUrl.bind(this)} /> diff --git a/superset/assets/javascripts/SqlLab/components/HighlightedSql.jsx b/superset/assets/javascripts/SqlLab/components/HighlightedSql.jsx index f7d69416de4d4..3efab4c9c341a 100644 --- a/superset/assets/javascripts/SqlLab/components/HighlightedSql.jsx +++ b/superset/assets/javascripts/SqlLab/components/HighlightedSql.jsx @@ -6,6 +6,7 @@ import sql from 'react-syntax-highlighter/dist/languages/sql'; import github from 'react-syntax-highlighter/dist/styles/github'; import ModalTrigger from '../../components/ModalTrigger'; +import { t } from '../../locales'; registerLanguage('sql', sql); @@ -57,7 +58,7 @@ class HighlightedSql extends React.Component { if (this.props.rawSql && this.props.rawSql !== this.props.sql) { rawSql = (
-

Raw SQL

+

{t('Raw SQL')}

{this.props.rawSql} @@ -67,7 +68,7 @@ class HighlightedSql extends React.Component { this.setState({ modalBody: (
-

Source SQL

+

{t('Source SQL')}

{this.props.sql} @@ -79,7 +80,7 @@ class HighlightedSql extends React.Component { render() { return ( { } return ( - No query history yet... + {t('No query history yet...')} ); }; diff --git a/superset/assets/javascripts/SqlLab/components/QuerySearch.jsx b/superset/assets/javascripts/SqlLab/components/QuerySearch.jsx index 5101f09f8b723..10c1c88e79c72 100644 --- a/superset/assets/javascripts/SqlLab/components/QuerySearch.jsx +++ b/superset/assets/javascripts/SqlLab/components/QuerySearch.jsx @@ -7,6 +7,7 @@ import { now, epochTimeXHoursAgo, epochTimeXDaysAgo, epochTimeXYearsAgo } from '../../modules/dates'; import { STATUS_OPTIONS, TIME_OPTIONS } from '../constants'; import AsyncSelect from '../../components/AsyncSelect'; +import { t } from '../../locales'; const $ = window.$ = require('jquery'); @@ -102,7 +103,7 @@ class QuerySearch extends React.PureComponent { if (data.result.length === 0) { this.props.actions.addAlert({ bsStyle: 'danger', - msg: "It seems you don't have access to any database", + msg: t('It seems you don\'t have access to any database'), }); } return options; @@ -150,15 +151,15 @@ class QuerySearch extends React.PureComponent { type="text" onChange={this.changeSearch.bind(this)} className="form-control input-sm" - placeholder="Search Results" + placeholder={t('Search Results')} />
({ value: t, label: t }))} + placeholder={t('[To]-')} + options={TIME_OPTIONS.map(xt => ({ value: xt, label: xt }))} value={this.state.to} autosize={false} onChange={this.changeTo.bind(this)} @@ -175,7 +176,7 @@ class QuerySearch extends React.PureComponent { (
- Schema: {o.label} + {t('Schema:')} {o.label}
)} isLoading={this.state.schemaLoading} @@ -186,7 +187,7 @@ class SqlEditorLeftBar extends React.PureComponent { ref="selectTable" isLoading={this.state.tableLoading} value={this.state.tableName} - placeholder={`Add a table (${this.state.tableOptions.length})`} + placeholder={t('Add a table (%s)', this.state.tableOptions.length)} autosize={false} onChange={this.changeTable.bind(this)} filterOptions={this.state.filterOptions} @@ -199,7 +200,7 @@ class SqlEditorLeftBar extends React.PureComponent { name="async-select-table" ref="selectTable" value={this.state.tableName} - placeholder={'Type to search ...'} + placeholder={t('Type to search ...')} autosize={false} onChange={this.changeTable.bind(this)} loadOptions={this.getTableNamesBySubStr.bind(this)} @@ -222,7 +223,7 @@ class SqlEditorLeftBar extends React.PureComponent {
{shouldShowReset && }
diff --git a/superset/assets/javascripts/SqlLab/components/TabbedSqlEditors.jsx b/superset/assets/javascripts/SqlLab/components/TabbedSqlEditors.jsx index 73ba6bcd29c6f..4f716d9a71ab3 100644 --- a/superset/assets/javascripts/SqlLab/components/TabbedSqlEditors.jsx +++ b/superset/assets/javascripts/SqlLab/components/TabbedSqlEditors.jsx @@ -9,6 +9,7 @@ import * as Actions from '../actions'; import SqlEditor from './SqlEditor'; import CopyQueryTabUrl from './CopyQueryTabUrl'; import { areArraysShallowEqual } from '../../reduxUtils'; +import { t } from '../../locales'; const propTypes = { actions: PropTypes.object.isRequired, @@ -101,7 +102,7 @@ class TabbedSqlEditors extends React.PureComponent { } renameTab(qe) { /* eslint no-alert: 0 */ - const newTitle = prompt('Enter a new title for the tab'); + const newTitle = prompt(t('Enter a new title for the tab')); if (newTitle) { this.props.actions.queryEditorSetTitle(qe, newTitle); } @@ -120,7 +121,7 @@ class TabbedSqlEditors extends React.PureComponent { queryCount++; const activeQueryEditor = this.activeQueryEditor(); const qe = { - title: `Untitled Query ${queryCount}`, + title: t('Untitled Query %s', queryCount), dbId: (activeQueryEditor && activeQueryEditor.dbId) ? activeQueryEditor.dbId : this.props.defaultDbId, @@ -166,10 +167,10 @@ class TabbedSqlEditors extends React.PureComponent { title="" > - close tab + {t('close tab')} - rename tab + {t('rename tab')} {qe && @@ -177,7 +178,7 @@ class TabbedSqlEditors extends React.PureComponent {   - {this.state.hideLeftBar ? 'expand tool bar' : 'hide tool bar'} + {this.state.hideLeftBar ? t('expand tool bar') : t('hide tool bar')} @@ -193,7 +194,7 @@ class TabbedSqlEditors extends React.PureComponent { {isSelected && (t.queryEditorId === qe.id))} + tables={this.props.tables.filter(xt => (xt.queryEditorId === qe.id))} queryEditor={qe} editorQueries={this.state.queriesArray} dataPreviewQueries={this.state.dataPreviewQueries} diff --git a/superset/assets/javascripts/SqlLab/components/TableElement.jsx b/superset/assets/javascripts/SqlLab/components/TableElement.jsx index fc8ae0c669991..624a0ed1c7650 100644 --- a/superset/assets/javascripts/SqlLab/components/TableElement.jsx +++ b/superset/assets/javascripts/SqlLab/components/TableElement.jsx @@ -9,6 +9,7 @@ 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, @@ -71,7 +72,7 @@ class TableElement extends React.PureComponent { let partitionClipBoard; if (table.partitions.partitionQuery) { partitionQuery = table.partitions.partitionQuery; - const tt = 'Copy partition query to clipboard'; + const tt = t('Copy partition query to clipboard'); partitionClipBoard = (
- latest partition: {latest} + {t('latest partition:')} {latest} {partitionClipBoard}
@@ -106,7 +107,7 @@ class TableElement extends React.PureComponent { - Keys for table {table.name} + {t('Keys for table')} {table.name} } modalBody={table.indexes.map((ix, i) => ( @@ -115,7 +116,7 @@ class TableElement extends React.PureComponent { triggerNode={ } /> @@ -131,8 +132,8 @@ class TableElement extends React.PureComponent { onClick={this.toggleSortColumns.bind(this)} tooltip={ !this.state.sortColumns ? - 'Sort columns alphabetically' : - 'Original table column order'} + t('Sort columns alphabetically') : + t('Original table column order')} href="#" /> {table.selectStar && @@ -142,13 +143,13 @@ class TableElement extends React.PureComponent { } text={table.selectStar} shouldShowText={false} - tooltipText="Copy SELECT statement to clipboard" + tooltipText={t('Copy SELECT statement to clipboard')} /> } diff --git a/superset/assets/javascripts/SqlLab/components/VisualizeModal.jsx b/superset/assets/javascripts/SqlLab/components/VisualizeModal.jsx index ff9119a84ecf4..965718df78884 100644 --- a/superset/assets/javascripts/SqlLab/components/VisualizeModal.jsx +++ b/superset/assets/javascripts/SqlLab/components/VisualizeModal.jsx @@ -13,6 +13,7 @@ import { getExploreUrl } from '../../explore/exploreUtils'; import * as actions from '../actions'; import { VISUALIZE_VALIDATION_ERRORS } from '../constants'; import visTypes from '../../explore/stores/visTypes'; +import { t } from '../../locales'; const CHART_TYPES = Object.keys(visTypes) .filter(typeName => !!visTypes[typeName].showOnExplore) @@ -86,9 +87,9 @@ class VisualizeModal extends React.PureComponent { if (!re.test(colName)) { hints.push(
- "{colName}" is not right as a column name, please alias it - (as in SELECT count(*) AS my_alias) using only - alphanumeric characters and underscores + {t('%s is not right as a column name, please alias it ' + + '(as in SELECT count(*) ', colName)} {t('AS my_alias')}) {t('using only ' + + 'alphanumeric characters and underscores')}
); } }); @@ -162,7 +163,7 @@ class VisualizeModal extends React.PureComponent { if (mainGroupBy) { formData.groupby = [mainGroupBy.name]; } - notify.info('Creating a data source and popping a new tab'); + notify.info(t('Creating a data source and popping a new tab')); window.open(getExploreUrl(formData)); }) @@ -192,7 +193,7 @@ class VisualizeModal extends React.PureComponent {
- No results available for this query + {t('No results available for this query')}
@@ -237,17 +238,17 @@ class VisualizeModal extends React.PureComponent {
- Visualize + {t('Visualize')} {alerts} {this.buildVisualizeAdvise()}
- Chart Type + {t('Chart Type')} @@ -276,7 +277,7 @@ class VisualizeModal extends React.PureComponent { bsStyle="primary" disabled={(this.state.hints.length > 0)} > - Visualize + {t('Visualize')} diff --git a/superset/assets/javascripts/SqlLab/constants.js b/superset/assets/javascripts/SqlLab/constants.js index 6d678067cc7a1..6af44e4651b2e 100644 --- a/superset/assets/javascripts/SqlLab/constants.js +++ b/superset/assets/javascripts/SqlLab/constants.js @@ -1,3 +1,5 @@ +import { t } from '../locales'; + export const STATE_BSSTYLE_MAP = { failed: 'danger', pending: 'info', @@ -25,8 +27,8 @@ export const TIME_OPTIONS = [ ]; export const VISUALIZE_VALIDATION_ERRORS = { - REQUIRE_CHART_TYPE: 'Pick a chart type!', - REQUIRE_TIME: 'To use this chart type you need at least one column flagged as a date', - REQUIRE_DIMENSION: 'To use this chart type you need at least one dimension', - REQUIRE_AGGREGATION_FUNCTION: 'To use this chart type you need at least one aggregation function', + REQUIRE_CHART_TYPE: t('Pick a chart type!'), + REQUIRE_TIME: t('To use this chart type you need at least one column flagged as a date'), + REQUIRE_DIMENSION: t('To use this chart type you need at least one dimension'), + REQUIRE_AGGREGATION_FUNCTION: t('To use this chart type you need at least one aggregation function'), }; diff --git a/superset/assets/javascripts/SqlLab/reducers.js b/superset/assets/javascripts/SqlLab/reducers.js index c85d27d240b50..3a49bd1b881cc 100644 --- a/superset/assets/javascripts/SqlLab/reducers.js +++ b/superset/assets/javascripts/SqlLab/reducers.js @@ -3,11 +3,12 @@ import * as actions from './actions'; import { now } from '../modules/dates'; import { addToObject, alterInObject, alterInArr, removeFromArr, getFromArr, addToArr } from '../reduxUtils'; +import { t } from '../locales'; export function getInitialState(defaultDbId) { const defaultQueryEditor = { id: shortid.generate(), - title: 'Untitled Query', + title: t('Untitled Query'), sql: 'SELECT *\nFROM\nWHERE', selectedText: null, latestQueryId: null, @@ -40,7 +41,7 @@ export const sqlLabReducer = function (state, action) { qe.id === state.tabHistory[state.tabHistory.length - 1]); const qe = { id: shortid.generate(), - title: `Copy of ${progenitor.title}`, + title: t('Copy of %s', progenitor.title), dbId: (action.query.dbId) ? action.query.dbId : null, schema: (action.query.schema) ? action.query.schema : null, autorun: true, @@ -76,13 +77,13 @@ export const sqlLabReducer = function (state, action) { [actions.MERGE_TABLE]() { const at = Object.assign({}, action.table); let existingTable; - state.tables.forEach((t) => { + state.tables.forEach((xt) => { if ( - t.dbId === at.dbId && - t.queryEditorId === at.queryEditorId && - t.schema === at.schema && - t.name === at.name) { - existingTable = t; + xt.dbId === at.dbId && + xt.queryEditorId === at.queryEditorId && + xt.schema === at.schema && + xt.name === at.name) { + existingTable = xt; } }); if (existingTable) { @@ -115,11 +116,11 @@ export const sqlLabReducer = function (state, action) { delete queries[action.oldQueryId]; const newTables = []; - state.tables.forEach((t) => { - if (t.dataPreviewQueryId === action.oldQueryId) { - newTables.push(Object.assign({}, t, { dataPreviewQueryId: action.newQuery.id })); + state.tables.forEach((xt) => { + if (xt.dataPreviewQueryId === action.oldQueryId) { + newTables.push(Object.assign({}, xt, { dataPreviewQueryId: action.newQuery.id })); } else { - newTables.push(t); + newTables.push(xt); } }); return Object.assign( diff --git a/superset/assets/javascripts/addSlice/AddSliceContainer.jsx b/superset/assets/javascripts/addSlice/AddSliceContainer.jsx index c316e2c76ed09..f0fc1218622b2 100644 --- a/superset/assets/javascripts/addSlice/AddSliceContainer.jsx +++ b/superset/assets/javascripts/addSlice/AddSliceContainer.jsx @@ -50,30 +50,30 @@ export default class AddSliceContainer extends React.PureComponent { render() { return (
- Create a new slice}> + {('Create a new slice')}}>
-

Choose a datasource

+

{('Choose a datasource')}

@@ -83,7 +83,7 @@ export default class AddSliceContainer extends React.PureComponent { disabled={this.isBtnDisabled()} onClick={this.gotoSlice.bind(this)} > - Create new slice + {('Create new slice')}

diff --git a/superset/assets/javascripts/common.js b/superset/assets/javascripts/common.js index 8ecfbe5822137..d84f064065e82 100644 --- a/superset/assets/javascripts/common.js +++ b/superset/assets/javascripts/common.js @@ -10,6 +10,17 @@ $(document).ready(function () { const id = $this.attr('id'); utils.toggleCheckbox(prefix, '#' + id); }); + + // for language picker dropdown + $('#language-picker a').click(function (ev) { + ev.preventDefault(); + + const targetUrl = ev.currentTarget.href; + $.ajax(targetUrl) + .then(() => { + location.reload(); + }); + }); }); export function appSetup() { diff --git a/superset/assets/javascripts/components/AsyncSelect.jsx b/superset/assets/javascripts/components/AsyncSelect.jsx index e045dc973c987..007281a116a04 100644 --- a/superset/assets/javascripts/components/AsyncSelect.jsx +++ b/superset/assets/javascripts/components/AsyncSelect.jsx @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import Select from 'react-select'; +import { t } from '../locales'; const $ = window.$ = require('jquery'); @@ -16,7 +17,7 @@ const propTypes = { }; const defaultProps = { - placeholder: 'Select ...', + placeholder: t('Select ...'), valueRenderer: o => (
{o.label}
), onAsyncError: () => {}, }; diff --git a/superset/assets/javascripts/components/CachedLabel.jsx b/superset/assets/javascripts/components/CachedLabel.jsx index e78e4f7996a81..8d0c0f2f2a740 100644 --- a/superset/assets/javascripts/components/CachedLabel.jsx +++ b/superset/assets/javascripts/components/CachedLabel.jsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import { Label } from 'react-bootstrap'; import moment from 'moment'; import TooltipWrapper from './TooltipWrapper'; +import { t } from '../locales'; const propTypes = { onClick: PropTypes.func, @@ -22,14 +23,14 @@ class CacheLabel extends React.PureComponent { updateTooltipContent() { const cachedText = this.props.cachedTimestamp ? ( - Loaded data cached {moment.utc(this.props.cachedTimestamp).fromNow()} + t('Loaded data cached') {moment.utc(this.props.cachedTimestamp).fromNow()} ) : - 'Loaded from cache'; + t('Loaded from cache'); const tooltipContent = ( {cachedText}. - Click to force-refresh + {t('Click to force-refresh')} ); this.setState({ tooltipContent }); diff --git a/superset/assets/javascripts/components/CopyToClipboard.jsx b/superset/assets/javascripts/components/CopyToClipboard.jsx index c9120b2b3ef28..d00347d998987 100644 --- a/superset/assets/javascripts/components/CopyToClipboard.jsx +++ b/superset/assets/javascripts/components/CopyToClipboard.jsx @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Tooltip, OverlayTrigger, MenuItem } from 'react-bootstrap'; +import { t } from '../locales'; const propTypes = { copyNode: PropTypes.node, @@ -17,7 +18,7 @@ const defaultProps = { onCopyEnd: () => {}, shouldShowText: true, inMenu: false, - tooltipText: 'Copy to clipboard', + tooltipText: t('Copy to clipboard'), }; export default class CopyToClipboard extends React.Component { @@ -61,10 +62,10 @@ export default class CopyToClipboard extends React.Component { textArea.select(); try { if (!document.execCommand('copy')) { - throw new Error('Not successful'); + throw new Error(t('Not successful')); } } catch (err) { - window.alert('Sorry, your browser does not support copying. Use Ctrl / Cmd + C!'); // eslint-disable-line + window.alert(t('Sorry, your browser does not support copying. Use Ctrl / Cmd + C!')); // eslint-disable-line } document.body.removeChild(textArea); @@ -75,7 +76,7 @@ export default class CopyToClipboard extends React.Component { tooltipText() { if (this.state.hasCopied) { - return 'Copied!'; + return t('Copied!'); } return this.props.tooltipText; } diff --git a/superset/assets/javascripts/components/EditableTitle.jsx b/superset/assets/javascripts/components/EditableTitle.jsx index 9d71388828ad2..26f474420d0ae 100644 --- a/superset/assets/javascripts/components/EditableTitle.jsx +++ b/superset/assets/javascripts/components/EditableTitle.jsx @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import TooltipWrapper from './TooltipWrapper'; +import { t } from '../locales'; const propTypes = { title: PropTypes.string, @@ -8,7 +9,7 @@ const propTypes = { onSaveTitle: PropTypes.func.isRequired, }; const defaultProps = { - title: 'Title', + title: t('Title'), canEdit: false, }; @@ -71,7 +72,7 @@ class EditableTitle extends React.PureComponent { - You have unsaved changes. Click the  + {t('You have unsaved changes.')} {t('Click the')}     - button on the top right to save your changes. + {t('button on the top right to save your changes.')}
, document.getElementById('alert-container'), @@ -161,13 +161,12 @@ export function dashboardContainer(dashboard, datasources, userid) { .addClass('danger') .attr( 'title', - `Served from data cached ${cachedWhen}. ` + - 'Click to force refresh') + t('Served from data cached %s . Click to force refresh.', cachedWhen)) .tooltip('fixTitle'); } else { refresh .removeClass('danger') - .attr('title', 'Click to force refresh') + .attr('title', t('Click to force refresh')) .tooltip('fixTitle'); } }, @@ -351,8 +350,8 @@ export function dashboardContainer(dashboard, datasources, userid) { error(error) { const errorMsg = getAjaxErrorMsg(error); utils.showModal({ - title: 'Error', - body: 'Sorry, there was an error adding slices to this dashboard: ' + errorMsg, + title: t('Error'), + body: t('Sorry, there was an error adding slices to this dashboard: %s', errorMsg), }); }, }); diff --git a/superset/assets/javascripts/dashboard/components/CodeModal.jsx b/superset/assets/javascripts/dashboard/components/CodeModal.jsx index 77f2dafea08a0..f9c1535a7708a 100644 --- a/superset/assets/javascripts/dashboard/components/CodeModal.jsx +++ b/superset/assets/javascripts/dashboard/components/CodeModal.jsx @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import ModalTrigger from '../../components/ModalTrigger'; +import { t } from '../../locales'; const propTypes = { triggerNode: PropTypes.node.isRequired, @@ -31,7 +32,7 @@ export default class CodeModal extends React.PureComponent { triggerNode={this.props.triggerNode} isButton beforeOpen={this.beforeOpen.bind(this)} - modalTitle="Active Dashboard Filters" + modalTitle={t('Active Dashboard Filters')} modalBody={
diff --git a/superset/assets/javascripts/dashboard/components/Controls.jsx b/superset/assets/javascripts/dashboard/components/Controls.jsx
index 1169642ff60e5..e18c2701fee9b 100644
--- a/superset/assets/javascripts/dashboard/components/Controls.jsx
+++ b/superset/assets/javascripts/dashboard/components/Controls.jsx
@@ -8,6 +8,7 @@ import RefreshIntervalModal from './RefreshIntervalModal';
 import SaveModal from './SaveModal';
 import CodeModal from './CodeModal';
 import SliceAdder from './SliceAdder';
+import { t } from '../../locales';
 
 const $ = window.$ = require('jquery');
 
@@ -44,13 +45,13 @@ class Controls extends React.PureComponent {
   }
   render() {
     const dashboard = this.props.dashboard;
-    const emailBody = `Checkout this dashboard: ${window.location.href}`;
+    const emailBody = t('Checkout this dashboard: %s', window.location.href);
     const emailLink = 'mailto:?Subject=Superset%20Dashboard%20'
       + `${dashboard.dashboard_title}&Body=${emailBody}`;
     return (
       
         
diff --git a/superset/assets/javascripts/dashboard/components/CssEditor.jsx b/superset/assets/javascripts/dashboard/components/CssEditor.jsx
index b77ab9d0ff5e6..bbcc19f078604 100644
--- a/superset/assets/javascripts/dashboard/components/CssEditor.jsx
+++ b/superset/assets/javascripts/dashboard/components/CssEditor.jsx
@@ -7,6 +7,7 @@ import 'brace/mode/css';
 import 'brace/theme/github';
 
 import ModalTrigger from '../../components/ModalTrigger';
+import { t } from '../../locales';
 
 const propTypes = {
   initialCss: PropTypes.string,
@@ -61,10 +62,10 @@ class CssEditor extends React.PureComponent {
     if (this.props.templates) {
       return (
         
-
Load a template
+
{t('Load a template')}
' + errorMsg); + notify.error(t('Sorry, there was an error saving this dashboard: ') + '' + errorMsg); }, }); } @@ -96,8 +97,8 @@ class SaveModal extends React.PureComponent { if (!newDashboardTitle) { this.modal.close(); showModal({ - title: 'Error', - body: 'You must pick a name for the new dashboard', + title: t('Error'), + body: t('You must pick a name for the new dashboard'), }); } else { data.dashboard_title = newDashboardTitle; @@ -111,7 +112,7 @@ class SaveModal extends React.PureComponent { { this.modal = modal; }} triggerNode={this.props.triggerNode} - modalTitle="Save Dashboard" + modalTitle={t('Save Dashboard')} modalBody={ - Overwrite Dashboard [{this.props.dashboard.dashboard_title}] + {t('Overwrite Dashboard [%s]', this.props.dashboard.dashboard_title)}
- Save as: + {t('Save as:')} { this.saveDashboard(this.state.saveType, this.state.newDashName); }} > - Save + {t('Save')}
} diff --git a/superset/assets/javascripts/dashboard/components/SliceAdder.jsx b/superset/assets/javascripts/dashboard/components/SliceAdder.jsx index 9d8965cce42c6..4c5f462a02ba9 100644 --- a/superset/assets/javascripts/dashboard/components/SliceAdder.jsx +++ b/superset/assets/javascripts/dashboard/components/SliceAdder.jsx @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table'; import ModalTrigger from '../../components/ModalTrigger'; +import { t } from '../../locales'; require('react-bootstrap-table/css/react-bootstrap-table.css'); @@ -138,13 +139,13 @@ class SliceAdder extends React.Component { dataField="sliceName" dataSort > - Name + {t('Name')} - Viz + {t('Viz')} modified} > - Modified + {t('Modified')}
@@ -172,12 +173,12 @@ class SliceAdder extends React.Component { return ( ); } diff --git a/superset/assets/javascripts/dashboard/components/SliceCell.jsx b/superset/assets/javascripts/dashboard/components/SliceCell.jsx index 0a179034825bf..3cd1334dc0db6 100644 --- a/superset/assets/javascripts/dashboard/components/SliceCell.jsx +++ b/superset/assets/javascripts/dashboard/components/SliceCell.jsx @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { t } from '../../locales'; import { getExploreUrl } from '../../explore/exploreUtils'; const propTypes = { @@ -20,14 +21,14 @@ function SliceCell({ expandedSlices, removeSlice, slice }) {
@@ -72,7 +73,7 @@ export default class EmbedCodeButton extends React.Component {
- +
- + @@ -38,7 +39,7 @@ export default function ExploreActionButtons({ diff --git a/superset/assets/javascripts/explore/components/SaveModal.jsx b/superset/assets/javascripts/explore/components/SaveModal.jsx index 45f5ac138ff2e..ac76e3a5ad68e 100644 --- a/superset/assets/javascripts/explore/components/SaveModal.jsx +++ b/superset/assets/javascripts/explore/components/SaveModal.jsx @@ -6,6 +6,7 @@ import { connect } from 'react-redux'; import { Modal, Alert, Button, Radio } from 'react-bootstrap'; import Select from 'react-select'; import { getExploreUrl } from '../exploreUtils'; +import { t } from '../../locales'; const propTypes = { can_overwrite: PropTypes.bool, @@ -70,7 +71,7 @@ class SaveModal extends React.Component { if (sliceParams.action === 'saveas') { sliceName = this.state.newSliceName; if (sliceName === '') { - this.setState({ alert: 'Please enter a slice name' }); + this.setState({ alert: t('Please enter a slice name') }); return; } sliceParams.slice_name = sliceName; @@ -85,7 +86,7 @@ class SaveModal extends React.Component { case ('existing'): dashboard = this.state.saveToDashboardId; if (!dashboard) { - this.setState({ alert: 'Please select a dashboard' }); + this.setState({ alert: t('Please select a dashboard') }); return; } sliceParams.save_to_dashboard_id = dashboard; @@ -93,7 +94,7 @@ class SaveModal extends React.Component { case ('new'): dashboard = this.state.newDashboardName; if (dashboard === '') { - this.setState({ alert: 'Please enter a dashboard name' }); + this.setState({ alert: t('Please enter a dashboard name') }); return; } sliceParams.new_dashboard_name = dashboard; @@ -126,7 +127,7 @@ class SaveModal extends React.Component { > - Save A Slice + {t('Save A Slice')} @@ -147,7 +148,7 @@ class SaveModal extends React.Component { checked={this.state.action === 'overwrite'} onChange={this.changeAction.bind(this, 'overwrite')} > - {`Overwrite slice ${this.props.slice.slice_name}`} + {t('Overwrite slice %s', this.props.slice.slice_name)} } @@ -156,11 +157,11 @@ class SaveModal extends React.Component { inline checked={this.state.action === 'saveas'} onChange={this.changeAction.bind(this, 'saveas')} - > Save as   + > {t('Save as')}   @@ -173,7 +174,7 @@ class SaveModal extends React.Component { checked={this.state.addToDash === 'noSave'} onChange={this.changeDash.bind(this, 'noSave')} > - Do not add to a dashboard + {t('Do not add to a dashboard')} - Add slice to existing dashboard + {t('Add slice to existing dashboard')} + @@ -212,7 +214,7 @@ class SaveModal extends React.Component { className="btn pull-left" onClick={this.saveOrOverwrite.bind(this, false)} > - Save + {t('Save')} diff --git a/superset/assets/javascripts/explore/components/URLShortLinkButton.jsx b/superset/assets/javascripts/explore/components/URLShortLinkButton.jsx index 4dbf0f1103a4e..ddae9a2206429 100644 --- a/superset/assets/javascripts/explore/components/URLShortLinkButton.jsx +++ b/superset/assets/javascripts/explore/components/URLShortLinkButton.jsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import { Popover, OverlayTrigger } from 'react-bootstrap'; import CopyToClipboard from './../../components/CopyToClipboard'; import { getShortUrl } from '../../../utils/common'; +import { t } from '../../locales'; const propTypes = { slice: PropTypes.object.isRequired, @@ -28,12 +29,12 @@ export default class URLShortLinkButton extends React.Component { } renderPopover() { - const emailBody = `Check out this slice: ${this.state.shortUrl}`; + const emailBody = t('Check out this slice: %s', this.state.shortUrl); return ( } + copyNode={} />    diff --git a/superset/assets/javascripts/explore/components/controls/BoundsControl.jsx b/superset/assets/javascripts/explore/components/controls/BoundsControl.jsx index 313ab93ae3f8e..776f7a499bde0 100644 --- a/superset/assets/javascripts/explore/components/controls/BoundsControl.jsx +++ b/superset/assets/javascripts/explore/components/controls/BoundsControl.jsx @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Col, Row, FormGroup, FormControl } from 'react-bootstrap'; import ControlHeader from '../ControlHeader'; +import { t } from '../../../locales'; const propTypes = { name: PropTypes.string.isRequired, @@ -51,10 +52,10 @@ export default class BoundsControl extends React.Component { const mm = this.state.minMax; const errors = []; if (mm[0] && isNaN(mm[0])) { - errors.push('`Min` value should be numeric or empty'); + errors.push(t('`Min` value should be numeric or empty')); } if (mm[1] && isNaN(mm[1])) { - errors.push('`Max` value should be numeric or empty'); + errors.push(t('`Max` value should be numeric or empty')); } if (errors.length === 0) { this.props.onChange([parseFloat(mm[0]), parseFloat(mm[1])], errors); @@ -71,7 +72,7 @@ export default class BoundsControl extends React.Component { @@ -79,7 +80,7 @@ export default class BoundsControl extends React.Component { diff --git a/superset/assets/javascripts/explore/components/controls/DatasourceControl.jsx b/superset/assets/javascripts/explore/components/controls/DatasourceControl.jsx index b00fe3fc79368..eb7a63367cf0f 100644 --- a/superset/assets/javascripts/explore/components/controls/DatasourceControl.jsx +++ b/superset/assets/javascripts/explore/components/controls/DatasourceControl.jsx @@ -5,6 +5,7 @@ import { Table } from 'reactable'; import { Label, FormControl, Modal, OverlayTrigger, Tooltip } from 'react-bootstrap'; import ControlHeader from '../ControlHeader'; +import { t } from '../../../locales'; const propTypes = { description: PropTypes.string, @@ -66,7 +67,7 @@ export default class DatasourceControl extends React.PureComponent { }, error() { that.setState({ loading: false }); - notify.error('Something went wrong while fetching the datasource list'); + notify.error(t('Something went wrong while fetching the datasource list')); }, }); } @@ -91,7 +92,7 @@ export default class DatasourceControl extends React.PureComponent { Click to point to another datasource + {t('Click to point to another datasource')} } >
}> Created Content
+
{t('Created Content')}
} > - Recent Activity
}> + {t('Recent Activity')}}> - Security & Access}> + {t('Security & Access')}}> diff --git a/superset/assets/javascripts/profile/components/CreatedContent.jsx b/superset/assets/javascripts/profile/components/CreatedContent.jsx index 87921c6872e6c..895be78434ce9 100644 --- a/superset/assets/javascripts/profile/components/CreatedContent.jsx +++ b/superset/assets/javascripts/profile/components/CreatedContent.jsx @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import moment from 'moment'; import TableLoader from './TableLoader'; +import { t } from '../../locales'; const propTypes = { user: PropTypes.object.isRequired, @@ -29,7 +30,7 @@ class CreatedContent extends React.PureComponent { className="table table-condensed" columns={['slice', 'favorited']} mutator={mutator} - noDataText="No slices" + noDataText={t('No slices')} sortable /> ); @@ -45,7 +46,7 @@ class CreatedContent extends React.PureComponent { className="table table-condensed" mutator={mutator} dataEndpoint={`/superset/created_dashboards/${this.props.user.userId}/`} - noDataText="No dashboards" + noDataText={t('No dashboards')} columns={['dashboard', 'favorited']} sortable /> @@ -54,10 +55,10 @@ class CreatedContent extends React.PureComponent { render() { return (
-

Dashboards

+

{t('Dashboards')}

{this.renderDashboardTable()}
-

Slices

+

{t('Slices')}

{this.renderSliceTable()}
); diff --git a/superset/assets/javascripts/profile/components/Favorites.jsx b/superset/assets/javascripts/profile/components/Favorites.jsx index 9039d916518b4..3141bb0c32850 100644 --- a/superset/assets/javascripts/profile/components/Favorites.jsx +++ b/superset/assets/javascripts/profile/components/Favorites.jsx @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import moment from 'moment'; import TableLoader from './TableLoader'; +import { t } from '../../locales'; const propTypes = { user: PropTypes.object.isRequired, @@ -30,7 +31,7 @@ export default class Favorites extends React.PureComponent { className="table table-condensed" columns={['slice', 'creator', 'favorited']} mutator={mutator} - noDataText="No favorite slices yet, go click on stars!" + noDataText={t('No favorite slices yet, go click on stars!')} sortable /> ); @@ -46,7 +47,7 @@ export default class Favorites extends React.PureComponent { className="table table-condensed" mutator={mutator} dataEndpoint={`/superset/fave_dashboards/${this.props.user.userId}/`} - noDataText="No favorite dashboards yet, go click on stars!" + noDataText={t('No favorite dashboards yet, go click on stars!')} columns={['dashboard', 'creator', 'favorited']} sortable /> @@ -55,10 +56,10 @@ export default class Favorites extends React.PureComponent { render() { return (
-

Dashboards

+

{t('Dashboards')}

{this.renderDashboardTable()}
-

Slices

+

{t('Slices')}

{this.renderSliceTable()}
); diff --git a/superset/assets/javascripts/profile/components/Security.jsx b/superset/assets/javascripts/profile/components/Security.jsx index 0d942dd83fdee..748be6b84043c 100644 --- a/superset/assets/javascripts/profile/components/Security.jsx +++ b/superset/assets/javascripts/profile/components/Security.jsx @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Badge, Label } from 'react-bootstrap'; +import { t } from '../../locales'; const propTypes = { user: PropTypes.object.isRequired, @@ -10,7 +11,7 @@ export default function Security({ user }) {

- Roles {Object.keys(user.roles).length} + {t('Roles')} {Object.keys(user.roles).length}

{Object.keys(user.roles).map(role => )}
@@ -19,7 +20,7 @@ export default function Security({ user }) { {user.permissions.database_access &&

- Databases {user.permissions.database_access.length} + {t('Databases')} {user.permissions.database_access.length}

{user.permissions.database_access.map(role => )}
@@ -30,7 +31,7 @@ export default function Security({ user }) { {user.permissions.datasource_access &&

- Datasources {user.permissions.datasource_access.length} + {t('Datasources')} {user.permissions.datasource_access.length}

{user.permissions.datasource_access.map(role => )}
diff --git a/superset/assets/javascripts/profile/components/UserInfo.jsx b/superset/assets/javascripts/profile/components/UserInfo.jsx index 4f751ed0d2391..cf9bde717bb6e 100644 --- a/superset/assets/javascripts/profile/components/UserInfo.jsx +++ b/superset/assets/javascripts/profile/components/UserInfo.jsx @@ -3,6 +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'; const propTypes = { user: PropTypes.object.isRequired, @@ -14,7 +15,7 @@ const UserInfo = ({ user }) => ( email={user.email} width="100%" height="" - alt="Profile picture provided by Gravatar" + alt={t('Profile picture provided by Gravatar')} className="img-rounded" style={{ borderRadius: 15 }} /> @@ -29,7 +30,7 @@ const UserInfo = ({ user }) => (

- joined {moment(user.createdOn, 'YYYYMMDD').fromNow()} + {t('joined')} {moment(user.createdOn, 'YYYYMMDD').fromNow()}

{user.email} @@ -39,7 +40,7 @@ const UserInfo = ({ user }) => (

  - id:  + {t('id:')}  {user.userId}

diff --git a/superset/assets/javascripts/profile/index.jsx b/superset/assets/javascripts/profile/index.jsx index adf371e699768..e9ed59bd719b2 100644 --- a/superset/assets/javascripts/profile/index.jsx +++ b/superset/assets/javascripts/profile/index.jsx @@ -1,7 +1,7 @@ /* eslint no-unused-vars: 0 */ import React from 'react'; import ReactDOM from 'react-dom'; -import { Badge, Col, Label, Row, Tabs, Tab, Panel } from 'react-bootstrap'; + import App from './components/App'; import { appSetup } from '../common'; diff --git a/superset/assets/package.json b/superset/assets/package.json index 002d0e8e39ca3..729bb022a66f4 100644 --- a/superset/assets/package.json +++ b/superset/assets/package.json @@ -54,6 +54,8 @@ "datamaps": "^0.5.8", "datatables.net-bs": "^1.10.15", "immutable": "^3.8.1", + "jed": "^1.1.1", + "po2json": "^0.4.5", "jquery": "3.1.1", "lodash.throttle": "^4.1.1", "moment": "^2.14.1", @@ -85,6 +87,7 @@ "redux-localstorage": "^0.4.1", "redux-thunk": "^2.1.0", "shortid": "^2.2.6", + "sprintf-js": "^1.1.1", "supercluster": "https://github.com/georgeke/supercluster/tarball/ac3492737e7ce98e07af679623aad452373bbc40", "urijs": "^1.18.10", "viewport-mercator-project": "^2.1.0" diff --git a/superset/assets/spec/javascripts/components/AsyncSelect_spec.jsx b/superset/assets/spec/javascripts/components/AsyncSelect_spec.jsx index c08cc664197c9..35b6f8141108c 100644 --- a/superset/assets/spec/javascripts/components/AsyncSelect_spec.jsx +++ b/superset/assets/spec/javascripts/components/AsyncSelect_spec.jsx @@ -1,6 +1,6 @@ import React from 'react'; import Select from 'react-select'; -import { mount, shallow } from 'enzyme'; +import { shallow } from 'enzyme'; import { describe, it } from 'mocha'; import { expect } from 'chai'; import sinon from 'sinon'; @@ -11,10 +11,12 @@ describe('AsyncSelect', () => { const mockedProps = { dataEndpoint: '/slicemodelview/api/read', onChange: sinon.spy(), + placeholder: 'Select...', mutator: () => [ { value: 1, label: 'main' }, { value: 2, label: 'another' }, ], + valueRenderer: opt => opt.label, }; it('is valid element', () => { expect( @@ -49,34 +51,34 @@ describe('AsyncSelect', () => { server.restore(); }); it('should be off by default', () => { - const wrapper = mount( + const wrapper = shallow( , ); + wrapper.instance().fetchOptions(); const spy = sinon.spy(wrapper.instance(), 'onChange'); expect(spy.callCount).to.equal(0); }); it('should auto select first option', () => { - const wrapper = mount( + const wrapper = shallow( , ); const spy = sinon.spy(wrapper.instance(), 'onChange'); - + wrapper.instance().fetchOptions(); server.respond(); expect(spy.callCount).to.equal(1); expect(spy.calledWith(wrapper.instance().state.options[0])).to.equal(true); }); it('should not auto select when value prop is set', () => { - const wrapper = mount( + const wrapper = shallow( , ); const spy = sinon.spy(wrapper.instance(), 'onChange'); - + wrapper.instance().fetchOptions(); server.respond(); expect(spy.callCount).to.equal(0); expect(wrapper.find(Select)).to.have.length(1); - expect(wrapper.find('.Select-value-label').children().first().text()).to.equal('another'); }); }); }); diff --git a/superset/assets/spec/javascripts/profile/EditableTitle_spec.jsx b/superset/assets/spec/javascripts/profile/EditableTitle_spec.jsx index edce86a0245a9..4e63b267ee785 100644 --- a/superset/assets/spec/javascripts/profile/EditableTitle_spec.jsx +++ b/superset/assets/spec/javascripts/profile/EditableTitle_spec.jsx @@ -19,7 +19,7 @@ describe('EditableTitle', () => { }, }; const editableWrapper = shallow(); - const notEditableWrapper = shallow(); + const notEditableWrapper = shallow(); it('is valid', () => { expect( React.isValidElement(), diff --git a/superset/assets/spec/javascripts/sqllab/SaveQuery_spec.jsx b/superset/assets/spec/javascripts/sqllab/SaveQuery_spec.jsx index 3c8953fbc4abd..98c8758a8db26 100644 --- a/superset/assets/spec/javascripts/sqllab/SaveQuery_spec.jsx +++ b/superset/assets/spec/javascripts/sqllab/SaveQuery_spec.jsx @@ -1,9 +1,8 @@ import React from 'react'; import { Overlay, Popover, FormControl } from 'react-bootstrap'; -import { shallow, mount } from 'enzyme'; +import { shallow } from 'enzyme'; import { describe, it } from 'mocha'; import { expect } from 'chai'; - import SaveQuery from '../../../javascripts/SqlLab/components/SaveQuery'; describe('SavedQuery', () => { @@ -30,11 +29,11 @@ describe('SavedQuery', () => { expect(wrapper.find(Popover)).to.have.length(1); }); it('pops and hides', () => { - const wrapper = mount(); + const wrapper = shallow(); expect(wrapper.state().showSave).to.equal(false); - wrapper.find('.toggleSave').simulate('click'); + wrapper.find('.toggleSave').simulate('click', { target: { value: 'test' } }); expect(wrapper.state().showSave).to.equal(true); - wrapper.find('.toggleSave').simulate('click'); + wrapper.find('.toggleSave').simulate('click', { target: { value: 'test' } }); expect(wrapper.state().showSave).to.equal(false); }); it('has a cancel button', () => { diff --git a/superset/assets/spec/javascripts/sqllab/Timer_spec.jsx b/superset/assets/spec/javascripts/sqllab/Timer_spec.jsx index 21a8a4fb3d442..e9172a928c1c2 100644 --- a/superset/assets/spec/javascripts/sqllab/Timer_spec.jsx +++ b/superset/assets/spec/javascripts/sqllab/Timer_spec.jsx @@ -2,6 +2,7 @@ import React from 'react'; import { mount } from 'enzyme'; import { describe, it, beforeEach } from 'mocha'; import { expect } from 'chai'; +import sinon from 'sinon'; import Timer from '../../../javascripts/components/Timer'; import { now } from '../../../javascripts/modules/dates'; @@ -9,16 +10,21 @@ import { now } from '../../../javascripts/modules/dates'; describe('Timer', () => { let wrapper; + let clock; const mockedProps = { - startTime: now(), endTime: null, isRunning: true, status: 'warning', }; beforeEach(() => { + clock = sinon.useFakeTimers(); + mockedProps.startTime = now() + 1; wrapper = mount(); }); + afterEach(() => { + clock.restore(); + }); it('is a valid element', () => { expect(React.isValidElement()).to.equal(true); @@ -26,9 +32,8 @@ describe('Timer', () => { it('componentWillMount starts timer after 30ms and sets state.clockStr', () => { expect(wrapper.state().clockStr).to.equal(''); - setTimeout(() => { - expect(wrapper.state().clockStr).not.equal(''); - }, 31); + clock.tick(31); + expect(wrapper.state().clockStr).not.equal(''); }); it('calls startTimer on mount', () => { diff --git a/superset/assets/spec/javascripts/sqllab/reducers_spec.js b/superset/assets/spec/javascripts/sqllab/reducers_spec.js index f777503e01308..a3a5dbf7b5771 100644 --- a/superset/assets/spec/javascripts/sqllab/reducers_spec.js +++ b/superset/assets/spec/javascripts/sqllab/reducers_spec.js @@ -1,4 +1,4 @@ -import { beforeEach, describe, it } from 'mocha'; +import { describe, it } from 'mocha'; import { expect } from 'chai'; import * as r from '../../../javascripts/SqlLab/reducers'; @@ -9,7 +9,9 @@ describe('sqlLabReducer', () => { describe('CLONE_QUERY_TO_NEW_TAB', () => { const testQuery = { sql: 'SELECT * FROM...', dbId: 1, id: 'flasj233' }; let newState = Object.assign({}, initialState, { queries: { [testQuery.id]: testQuery } }); - newState = r.sqlLabReducer(newState, actions.cloneQueryToNewTab(testQuery)); + beforeEach(() => { + newState = r.sqlLabReducer(newState, actions.cloneQueryToNewTab(testQuery)); + }); it('should have at most one more tab', () => { expect(newState.queryEditors).have.length(2); diff --git a/superset/assets/visualizations/EventFlow.jsx b/superset/assets/visualizations/EventFlow.jsx index 110f4a76482c6..83811a5f465f4 100644 --- a/superset/assets/visualizations/EventFlow.jsx +++ b/superset/assets/visualizations/EventFlow.jsx @@ -9,6 +9,7 @@ import { EVENT_NAME, ENTITY_ID, } from '@data-ui/event-flow'; +import { t } from '../javascripts/locales'; /* * This function takes the slice object and json payload as input and renders a @@ -52,7 +53,7 @@ function renderEventFlow(slice, json) { Component = ; } else { - Component =
Sorry, there appears to be no data
; + Component =
{t('Sorry, there appears to be no data')}
; } ReactDOM.render(Component, container); diff --git a/superset/assets/visualizations/filter_box.jsx b/superset/assets/visualizations/filter_box.jsx index a5de26a810811..1bcaa52fa579a 100644 --- a/superset/assets/visualizations/filter_box.jsx +++ b/superset/assets/visualizations/filter_box.jsx @@ -8,6 +8,7 @@ import { Button } from 'react-bootstrap'; import { TIME_CHOICES } from './constants'; import './filter_box.css'; +import { t } from '../javascripts/locales'; const propTypes = { origSelectedValues: PropTypes.object, @@ -102,7 +103,7 @@ class FilterBox extends React.Component {
{this.props.datasource.verbose_map[filter] || filter}
-