You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by vi...@apache.org on 2021/01/25 13:11:36 UTC

[superset] branch 1.0 updated (5719fef -> b07188e)

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

villebro pushed a change to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git.


    from 5719fef  add rc4 changelog entries
     new bc1a2a2  fix: incorrect cursor position Firefox (#12423)
     new 968ab8d  chore: apply capitalization guidelines - iteration 1 (#12447)
     new e6b916c  Apply capitalization guidelines - iteration 2 (#12343) (#12448)
     new 2cdb92d  fix: faster search for Change Dataset modal (#12669)
     new 3d81853  fix: styling for change dataset confirmation (#12471)
     new 2641a65  fix(explore): Scroll only table in Change Dataset and Edit Dataset Modals (#12598)
     new 200cc1a  Apply capitalization guidelines - iteration 3 (#12343) (#12449)
     new 5e4ce48  feat(native-filters): Show alert for unsaved filters after cancelling Filter Config Modal (#12554)
     new f659d66  Apply capitalization guidelines - iteration 4 (#12343) (#12450)
     new 74f64b1  refactor(explore): move MetricControl and FilterControl to sub-component (#12446)
     new e4453a7  fix(explore): Disable saved metric name edit in Metric popover (#12582)
     new 46507ba  Apply capitalization guidelines - iteration 5 (#12343) (#12451)
     new 6d22b42  Apply capitalization guidelines - iteration 6 (#12343) (#12452)
     new 342f5ea  Apply capitalization guidelines - iteration 7 (#12343) (#12453)
     new 749db0b  Apply capitalization guidelines - iteration 8 (#12343) (#12454)
     new 630bb72  fix: row component handler is visible (#12498)
     new 33dd4e5  chore: bumping superset UI packages (0.16.7 + 0.16.8) (#12564)
     new 10ca58f  Add docs for GLOBAL_ASYNC_QUERIES (SIP-39) (#12573)
     new a4d7e9c  fix: return appropriate response when payload has error (#12575)
     new 0fc2bc5  corrected typo in connections index in the documentation (#12577)
     new 3ccb23c  chore(explore): added tooltips to timepicker (#12580)
     new 8b09414  fix: dropdown indicator in tabs has proper width and position (#12584)
     new 0acd2cc  test: birth names (#12226)
     new bc53be9  test: World bank examples (#12161)
     new c7284fe  fix: error while parsing invalid json form_data (#12586)
     new 41505bb  fix: explore page style fix, remove unnecessary scroll bars (#12649)
     new 522f466  chore(explore): Save Resizable width to localStorage (#12593)
     new 3d770ae  [12601] Hovered menu items on dashboard - brought back padding and added margin on top of chart (#12603)
     new fe0b9f4  Switch button position (#12604)
     new e2ce27f  fix: chart disappears in standalone slice (#12606)
     new d8a7d83  chore(viz): bump superset-ui packages to 0.16.9 (#12632)
     new 0686a1c  fix(multiline): return all chart data on initial request (#12660)
     new 7e9a042  fix(explore): Certified metric icons are various sizes (#12690)
     new 39e3b28  feat(chart): Add expression, description and verbose name to search filter (#12549)
     new 8d80262  feat(explore): better search for dataset pane (#12675)
     new ca0c077  chore: add capitalization guidelines to CONTRIBUTING.md (#12685)
     new c277b84  fix: remove whitespace at the bottom of select dropdown (#12699)
     new b07188e  chore[explore]: Save date if Ok not clicked (#12731)

The 38 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 CONTRIBUTING.md                                    |  71 +++
 docs/installation.rst                              |  26 ++
 .../pages/docs/Connecting to Databases/index.mdx   |   2 +-
 .../integration/chart_list/list_view.test.ts       |   8 +-
 .../cypress/integration/dashboard/save.test.js     |  13 +-
 .../integration/dashboard/url_params.test.js       |   2 +-
 .../integration/explore/AdhocMetrics.test.ts       |   3 +
 .../explore/visualizations/line.test.ts            |   8 +-
 superset-frontend/package-lock.json                | 420 +++++++++---------
 superset-frontend/package.json                     |  56 +--
 .../nativeFilters/NativeFiltersModal_spec.tsx      |  49 +++
 .../spec/javascripts/explore/AdhocFilter_spec.js   |   2 +-
 .../spec/javascripts/explore/AdhocMetric_spec.js   |   4 +-
 .../explore/components/AdhocFilterControl_spec.jsx |   6 +-
 ...AdhocFilterEditPopoverSimpleTabContent_spec.jsx |   6 +-
 .../AdhocFilterEditPopoverSqlTabContent_spec.jsx   |   4 +-
 .../components/AdhocFilterEditPopover_spec.jsx     |  10 +-
 .../explore/components/AdhocFilterOption_spec.jsx  |   4 +-
 .../AdhocMetricEditPopoverTitle_spec.jsx           |  18 +-
 .../components/AdhocMetricEditPopover_spec.jsx     |   6 +-
 .../explore/components/AdhocMetricOption_spec.jsx  |   4 +-
 .../components/AdhocMetricStaticOption_spec.jsx    |   6 +-
 .../components/FilterDefinitionOption_spec.jsx     |   8 +-
 .../components/FixedOrMetricControl_spec.jsx       |   4 +-
 .../components/MetricDefinitionOption_spec.jsx     |   2 +-
 .../components/MetricDefinitionValue_spec.jsx      |   6 +-
 .../explore/components/MetricsControl_spec.jsx     |   6 +-
 .../explore/components/SelectControl_spec.jsx      |   8 +-
 .../components/withAsyncVerification_spec.tsx      |   2 +-
 .../utils/getControlsForVizType_spec.js            |   2 +-
 .../views/CRUD/annotation/AnnotationModal_spec.jsx |   4 +-
 .../annotationlayers/AnnotationLayerModal_spec.jsx |   4 +-
 .../CRUD/csstemplates/CssTemplateModal_spec.jsx    |   4 +-
 superset-frontend/src/CRUD/CollectionTable.tsx     |  65 ++-
 superset-frontend/src/SqlLab/actions/sqlLab.js     |   2 +-
 .../src/SqlLab/components/ColumnElement.tsx        |   4 +-
 .../SqlLab/components/EstimateQueryCostButton.jsx  |   6 +-
 .../src/SqlLab/components/QueryTable.jsx           |   2 +-
 .../src/SqlLab/components/ResultSet.tsx            |   8 +-
 .../src/SqlLab/components/RunQueryActionButton.tsx |   2 +-
 .../src/SqlLab/components/SaveQuery.tsx            |   4 +-
 .../src/SqlLab/components/ScheduleQueryButton.jsx  |   2 +-
 .../src/SqlLab/components/SouthPane.jsx            |   2 +-
 .../src/SqlLab/components/SqlEditor.jsx            |  10 +-
 .../src/SqlLab/components/SqlEditorLeftBar.jsx     |   2 +-
 .../src/SqlLab/components/TemplateParamsEditor.jsx |   2 +-
 superset-frontend/src/SqlLab/main.less             |   4 +-
 .../src/SqlLab/reducers/getInitialState.js         |   2 +-
 superset-frontend/src/chart/chartAction.js         |   2 +-
 .../src/common/components/Modal/Modal.tsx          |   1 +
 .../src/common/components/common.stories.tsx       |  14 +-
 superset-frontend/src/components/AnchorLink.jsx    |   2 +-
 .../src/components/DynamicPlugins/index.tsx        |   2 +-
 superset-frontend/src/components/EditableTitle.tsx |   2 +-
 .../ErrorMessage/DatabaseErrorMessage.tsx          |   2 +-
 .../src/components/ErrorMessage/ErrorAlert.tsx     |   8 +-
 .../ErrorMessage/ErrorMessageWithStackTrace.tsx    |   2 +-
 .../ErrorMessage/ParameterErrorMessage.tsx         |   2 +-
 .../ErrorMessage/TimeoutErrorMessage.tsx           |   2 +-
 .../components/FilterableTable/FilterableTable.tsx |   2 +-
 .../src/components/ListView/ListView.tsx           |   4 +-
 superset-frontend/src/components/Menu/NewMenu.tsx  |   2 +-
 superset-frontend/src/components/OmniContainer.jsx |   2 +-
 .../src/components/RefreshChartOverlay.tsx         |   2 +-
 .../src/components/Select/Select.stories.tsx       |   2 +-
 superset-frontend/src/components/Select/styles.tsx |  27 +-
 .../src/components/TableView/TableView.tsx         |  10 +
 .../src/components/URLShortLinkModal.tsx           |   2 +-
 .../components/ColorSchemeControlWrapper.jsx       |   2 +-
 .../src/dashboard/components/CssEditor.jsx         |   2 +-
 .../src/dashboard/components/DashboardBuilder.jsx  |   4 +-
 .../src/dashboard/components/Header.jsx            |   4 +-
 .../dashboard/components/HeaderActionsDropdown.jsx |   4 +-
 .../src/dashboard/components/PropertiesModal.jsx   |   8 +-
 .../dashboard/components/RefreshIntervalModal.tsx  |   2 +-
 .../src/dashboard/components/SaveModal.tsx         |   2 +-
 .../dashboard/components/SliceHeaderControls.jsx   |   4 +-
 .../dashboard/components/gridComponents/Tabs.jsx   |  16 -
 .../nativeFilters/CancelConfirmationAlert.tsx      | 105 +++++
 .../components/nativeFilters/CascadePopover.tsx    |   2 +-
 .../components/nativeFilters/FilterBar.tsx         |   2 +-
 .../components/nativeFilters/FilterConfigForm.tsx  |   6 +-
 .../components/nativeFilters/FilterConfigModal.tsx |  78 +++-
 .../components/nativeFilters/FiltersList.tsx       |   2 +-
 .../dashboard/components/nativeFilters/state.ts    |   2 +-
 .../src/dashboard/stylesheets/hover-menu.less      |   2 +-
 .../src/dashboard/util/newComponentFactory.js      |   2 +-
 .../src/datasource/ChangeDatasourceModal.tsx       |   9 +-
 .../src/datasource/DatasourceEditor.jsx            |  73 ++--
 .../src/datasource/DatasourceModal.tsx             |  18 +-
 .../explore/components/ControlPanelsContainer.jsx  |  26 +-
 .../src/explore/components/DataTablesPane.tsx      |   1 +
 .../src/explore/components/DatasourcePanel.tsx     |  73 +++-
 .../src/explore/components/ExploreChartPanel.jsx   |  14 +-
 .../explore/components/ExploreViewContainer.jsx    |  52 ++-
 .../src/explore/components/OptionControls.tsx      |   4 +-
 .../src/explore/components/PropertiesModal.tsx     |   4 +-
 .../src/explore/components/SaveModal.tsx           |   2 +-
 .../components/controls/AnnotationLayer.jsx        |  18 +-
 .../components/controls/AnnotationLayerControl.jsx |   6 +-
 .../components/controls/DatasourceControl.jsx      |   4 +-
 .../DateFilterControl/DateFilterControl.tsx        |  12 +-
 .../controls/DateFilterControl/constants.ts        |   2 +-
 .../DateFilterControl/frame/AdvancedFrame.tsx      |   8 +-
 .../DateFilterControl/frame/CustomFrame.tsx        |  10 +-
 .../frame/DateFunctionTooltip.tsx                  | 147 +++++++
 .../components/controls/DateFilterControl/types.ts |   2 +-
 .../components/controls/FilterBoxItemControl.jsx   |  10 +-
 .../controls/FilterControl}/AdhocFilter.js         |   4 +-
 .../{ => FilterControl}/AdhocFilterControl.jsx     |  28 +-
 .../FilterControl}/AdhocFilterEditPopover.jsx      |   6 +-
 .../AdhocFilterEditPopoverSimpleTabContent.jsx     |  12 +-
 .../AdhocFilterEditPopoverSqlTabContent.jsx        |  10 +-
 .../FilterControl}/AdhocFilterOption.jsx           |  10 +-
 .../FilterControl}/AdhocFilterPopoverTrigger.tsx   |   6 +-
 .../controls/FilterControl}/adhocFilterType.js     |   4 +-
 .../components/controls/FixedOrMetricControl.jsx   |   2 +-
 .../controls/MetricControl}/AdhocMetric.js         |   2 +-
 .../MetricControl}/AdhocMetricEditPopover.jsx      |  81 ++--
 .../MetricControl}/AdhocMetricEditPopoverTitle.jsx |  21 +-
 .../MetricControl}/AdhocMetricOption.jsx           |  10 +-
 .../MetricControl}/AdhocMetricPopoverTrigger.tsx   |  23 +-
 .../MetricControl}/AdhocMetricStaticOption.jsx     |   2 +-
 .../MetricControl}/FilterDefinitionOption.jsx      |   4 +-
 .../MetricControl}/MetricDefinitionOption.jsx      |  10 +-
 .../MetricControl}/MetricDefinitionValue.jsx       |  14 +-
 .../{ => MetricControl}/MetricsControl.jsx         |  30 +-
 .../controls/MetricControl}/adhocMetricType.js     |   6 +-
 .../controls/MetricControl}/savedMetricType.js     |   0
 .../controls/MetricControl}/types.ts               |   0
 .../explore/components/controls/SelectControl.jsx  |   6 +-
 .../controls/TimeSeriesColumnControl.jsx           |  12 +-
 .../src/explore/components/controls/index.js       |   4 +-
 superset-frontend/src/explore/constants.js         |   8 +-
 .../src/explore/controlPanels/Separator.js         |   2 +-
 .../src/explore/controlPanels/TimeTable.js         |   2 +-
 .../src/explore/controlPanels/sections.jsx         |  28 +-
 superset-frontend/src/explore/controls.jsx         |  18 +-
 .../src/filters/components/Range/index.ts          |   4 +-
 .../src/filters/components/Select/controlPanel.ts  |   8 +-
 .../src/filters/components/Select/index.ts         |   4 +-
 superset-frontend/src/middleware/asyncEvent.ts     |   8 +-
 superset-frontend/src/modules/AnnotationTypes.js   |   2 +-
 superset-frontend/src/profile/components/App.tsx   |   4 +-
 .../src/views/CRUD/alert/AlertList.tsx             |  12 +-
 .../src/views/CRUD/alert/AlertReportModal.tsx      |  28 +-
 .../src/views/CRUD/alert/ExecutionLog.tsx          |   4 +-
 .../alert/components/AlertReportCronScheduler.tsx  |   2 +-
 .../CRUD/alert/components/AlertStatusIcon.tsx      |  16 +-
 .../src/views/CRUD/annotation/AnnotationList.tsx   |   6 +-
 .../src/views/CRUD/annotation/AnnotationModal.tsx  |  10 +-
 .../CRUD/annotationlayers/AnnotationLayerModal.tsx |   8 +-
 .../CRUD/annotationlayers/AnnotationLayersList.tsx |  18 +-
 .../src/views/CRUD/chart/ChartCard.tsx             |   2 +-
 .../src/views/CRUD/chart/ChartList.tsx             |  20 +-
 .../views/CRUD/csstemplates/CssTemplateModal.tsx   |   8 +-
 .../views/CRUD/csstemplates/CssTemplatesList.tsx   |  16 +-
 superset-frontend/tsconfig.json                    |   2 +-
 superset/charts/api.py                             |  11 +-
 superset/dashboards/commands/export.py             |   4 +-
 superset/examples/birth_names.py                   |  60 ++-
 superset/examples/world_bank.py                    | 233 ++++------
 superset/views/core.py                             |   7 +-
 superset/views/utils.py                            |  13 +-
 superset/viz.py                                    |  71 ++-
 tests/access_tests.py                              |  10 +-
 tests/base_api_tests.py                            |   4 +
 tests/cache_tests.py                               |   5 +
 tests/celery_tests.py                              |  23 +
 tests/charts/api_tests.py                          | 123 +++++-
 tests/conftest.py                                  |   4 -
 tests/core_tests.py                                |  44 +-
 tests/dashboard_tests.py                           |  20 +-
 tests/dashboard_utils.py                           |  10 +-
 tests/dashboards/api_tests.py                      |  22 +-
 tests/dashboards/commands_tests.py                 | 179 ++++++--
 tests/dashboards/dao_tests.py                      |   4 +
 tests/databases/api_tests.py                       |   9 +-
 tests/databases/commands_tests.py                  | 232 +++++-----
 tests/datasets/api_tests.py                        |  12 +-
 tests/datasets/commands_tests.py                   |   8 +-
 tests/datasource_tests.py                          |  46 +-
 tests/fixtures/birth_names_dashboard.py            | 202 +++++++++
 tests/fixtures/unicode_dashboard.py                |   2 +-
 tests/fixtures/world_bank_dashboard.py             | 484 +++++++++++++++++++++
 tests/import_export_tests.py                       |  10 +
 tests/model_tests.py                               |  34 +-
 tests/query_context_tests.py                       |   8 +-
 tests/schedules_test.py                            |  22 +-
 tests/security_tests.py                            |  15 +
 tests/sqla_models_tests.py                         |   2 +
 tests/sqllab_tests.py                              |  21 +-
 tests/strategy_tests.py                            |   6 +-
 tests/tasks/async_queries_tests.py                 |   3 +
 .../utils/get_dashboards.py                        |  23 +-
 tests/utils_tests.py                               |  21 +-
 196 files changed, 3031 insertions(+), 1254 deletions(-)
 create mode 100644 superset-frontend/src/dashboard/components/nativeFilters/CancelConfirmationAlert.tsx
 create mode 100644 superset-frontend/src/explore/components/controls/DateFilterControl/frame/DateFunctionTooltip.tsx
 rename superset-frontend/src/explore/{ => components/controls/FilterControl}/AdhocFilter.js (97%)
 rename superset-frontend/src/explore/components/controls/{ => FilterControl}/AdhocFilterControl.jsx (91%)
 rename superset-frontend/src/explore/components/{ => controls/FilterControl}/AdhocFilterEditPopover.jsx (96%)
 rename superset-frontend/src/explore/components/{ => controls/FilterControl}/AdhocFilterEditPopoverSimpleTabContent.jsx (96%)
 rename superset-frontend/src/explore/components/{ => controls/FilterControl}/AdhocFilterEditPopoverSqlTabContent.jsx (92%)
 rename superset-frontend/src/explore/components/{ => controls/FilterControl}/AdhocFilterOption.jsx (86%)
 rename superset-frontend/src/explore/components/{ => controls/FilterControl}/AdhocFilterPopoverTrigger.tsx (94%)
 rename superset-frontend/src/explore/{propTypes => components/controls/FilterControl}/adhocFilterType.js (93%)
 rename superset-frontend/src/explore/{ => components/controls/MetricControl}/AdhocMetric.js (98%)
 rename superset-frontend/src/explore/components/{ => controls/MetricControl}/AdhocMetricEditPopover.jsx (92%)
 rename superset-frontend/src/explore/components/{ => controls/MetricControl}/AdhocMetricEditPopoverTitle.jsx (84%)
 rename superset-frontend/src/explore/components/{ => controls/MetricControl}/AdhocMetricOption.jsx (90%)
 rename superset-frontend/src/explore/components/{ => controls/MetricControl}/AdhocMetricPopoverTrigger.tsx (84%)
 rename superset-frontend/src/explore/components/{ => controls/MetricControl}/AdhocMetricStaticOption.jsx (95%)
 rename superset-frontend/src/explore/components/{ => controls/MetricControl}/FilterDefinitionOption.jsx (93%)
 rename superset-frontend/src/explore/components/{ => controls/MetricControl}/MetricDefinitionOption.jsx (84%)
 rename superset-frontend/src/explore/components/{ => controls/MetricControl}/MetricDefinitionValue.jsx (87%)
 rename superset-frontend/src/explore/components/controls/{ => MetricControl}/MetricsControl.jsx (93%)
 rename superset-frontend/src/explore/{propTypes => components/controls/MetricControl}/adhocMetricType.js (89%)
 rename superset-frontend/src/explore/{propTypes => components/controls/MetricControl}/savedMetricType.js (100%)
 rename superset-frontend/src/explore/{ => components/controls/MetricControl}/types.ts (100%)
 create mode 100644 tests/fixtures/birth_names_dashboard.py
 create mode 100644 tests/fixtures/world_bank_dashboard.py
 copy superset/migrations/versions/ae19b4ee3692_.py => tests/utils/get_dashboards.py (70%)


[superset] 32/38: fix(multiline): return all chart data on initial request (#12660)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 0686a1c347d65f23515233e692a4bb0c13630f87
Author: Ville Brofeldt <33...@users.noreply.github.com>
AuthorDate: Sat Jan 23 09:01:50 2021 +0200

    fix(multiline): return all chart data on initial request (#12660)
    
    * fix(multiline): return chart data on data request
    
    * bump package
    
    * optimize chart retrieval and fix chart form_data
---
 superset-frontend/package-lock.json |  6 ++--
 superset-frontend/package.json      |  2 +-
 superset/viz.py                     | 71 +++++++++++++++++++++++++++++--------
 3 files changed, 61 insertions(+), 18 deletions(-)

diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json
index 2bd8b2b..779c3ac 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -19011,9 +19011,9 @@
       }
     },
     "@superset-ui/legacy-preset-chart-nvd3": {
-      "version": "0.16.9",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-nvd3/-/legacy-preset-chart-nvd3-0.16.9.tgz",
-      "integrity": "sha512-wfbVZOGqIk/IFUnzW0k44t9N/iHd0VoJzHT6wwM+GgGcCm5mizBDWot9Zuu4U1gf1KLfKUD7/lwEEtyCrs2zXw==",
+      "version": "0.16.10",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-nvd3/-/legacy-preset-chart-nvd3-0.16.10.tgz",
+      "integrity": "sha512-zQPybEGYfthiUpwSOV4E1YUWnSqWY6S4nGXR8rVh2FIUFzyYyr4f5ZzOr6DKmytPlQbL1oXg0m35A8boshOh0g==",
       "requires": {
         "@data-ui/xy-chart": "^0.0.84",
         "@superset-ui/chart-controls": "0.16.9",
diff --git a/superset-frontend/package.json b/superset-frontend/package.json
index c13d59d..16b83d0 100644
--- a/superset-frontend/package.json
+++ b/superset-frontend/package.json
@@ -88,7 +88,7 @@
     "@superset-ui/legacy-plugin-chart-world-map": "^0.16.9",
     "@superset-ui/legacy-preset-chart-big-number": "^0.16.9",
     "@superset-ui/legacy-preset-chart-deckgl": "^0.4.1",
-    "@superset-ui/legacy-preset-chart-nvd3": "^0.16.9",
+    "@superset-ui/legacy-preset-chart-nvd3": "^0.16.10",
     "@superset-ui/plugin-chart-echarts": "^0.16.9",
     "@superset-ui/plugin-chart-table": "^0.16.9",
     "@superset-ui/plugin-chart-word-cloud": "^0.16.9",
diff --git a/superset/viz.py b/superset/viz.py
index 21fbdf8..d8d799d 100644
--- a/superset/viz.py
+++ b/superset/viz.py
@@ -1405,21 +1405,64 @@ class MultiLineViz(NVD3Viz):
         return {}
 
     def get_data(self, df: pd.DataFrame) -> VizData:
-        fd = self.form_data
-        # Late imports to avoid circular import issues
-        from superset import db
-        from superset.models.slice import Slice
-
-        slice_ids1 = fd.get("line_charts")
-        slices1 = db.session.query(Slice).filter(Slice.id.in_(slice_ids1)).all()
-        slice_ids2 = fd.get("line_charts_2")
-        slices2 = db.session.query(Slice).filter(Slice.id.in_(slice_ids2)).all()
-        return {
-            "slices": {
-                "axis1": [slc.data for slc in slices1],
-                "axis2": [slc.data for slc in slices2],
-            }
+        multiline_fd = self.form_data
+        # Late import to avoid circular import issues
+        from superset.charts.dao import ChartDAO
+
+        axis1_chart_ids = multiline_fd.get("line_charts", [])
+        axis2_chart_ids = multiline_fd.get("line_charts_2", [])
+        all_charts = {
+            chart.id: chart
+            for chart in ChartDAO.find_by_ids(axis1_chart_ids + axis2_chart_ids)
         }
+        axis1_charts = [all_charts[chart_id] for chart_id in axis1_chart_ids]
+        axis2_charts = [all_charts[chart_id] for chart_id in axis2_chart_ids]
+
+        filters = multiline_fd.get("filters", [])
+        add_prefix = multiline_fd.get("prefix_metric_with_slice_name", False)
+        data = []
+        min_x, max_x = None, None
+
+        for chart, y_axis in [(chart, 1) for chart in axis1_charts] + [
+            (chart, 2) for chart in axis2_charts
+        ]:
+            prefix = f"{chart.chart}: " if add_prefix else ""
+            chart_fd = chart.form_data
+            chart_fd["filters"] = chart_fd.get("filters", []) + filters
+            if "extra_filters" in multiline_fd:
+                chart_fd["extra_filters"] = multiline_fd["extra_filters"]
+            if "time_range" in multiline_fd:
+                chart_fd["time_range"] = multiline_fd["time_range"]
+            viz_obj = viz_types[chart.viz_type](
+                chart.datasource,
+                form_data=chart_fd,
+                force=self.force,
+                force_cached=self.force_cached,
+            )
+            df = viz_obj.get_df_payload()["df"]
+            chart_series = viz_obj.get_data(df) or []
+            for series in chart_series:
+                x_values = [value["x"] for value in series["values"]]
+                min_x = min(x_values + ([min_x] if min_x is not None else []))
+                max_x = max(x_values + ([max_x] if max_x is not None else []))
+
+                data.append(
+                    {
+                        "key": prefix + ", ".join(series["key"]),
+                        "type": "line",
+                        "values": series["values"],
+                        "yAxis": y_axis,
+                    }
+                )
+        bounds = []
+        if min_x is not None:
+            bounds.append({"x": min_x, "y": None})
+        if max_x is not None:
+            bounds.append({"x": max_x, "y": None})
+
+        for series in data:
+            series["values"].extend(bounds)
+        return data
 
 
 class NVD3DualLineViz(NVD3Viz):


[superset] 09/38: Apply capitalization guidelines - iteration 4 (#12343) (#12450)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit f659d66fee6fed7e18c3b2d40bd7894c8f8a216b
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Fri Jan 22 15:11:38 2021 -0300

    Apply capitalization guidelines - iteration 4 (#12343) (#12450)
---
 .../nativeFilters/NativeFiltersModal_spec.tsx      |  4 +--
 .../dashboard/components/SliceHeaderControls.jsx   |  4 +--
 .../components/nativeFilters/CascadePopover.tsx    |  2 +-
 .../components/nativeFilters/FilterBar.tsx         |  2 +-
 .../components/nativeFilters/FilterConfigForm.tsx  |  6 ++--
 .../components/nativeFilters/FilterConfigModal.tsx |  8 ++---
 .../components/nativeFilters/FiltersList.tsx       |  2 +-
 .../dashboard/components/nativeFilters/state.ts    |  2 +-
 .../src/dashboard/util/newComponentFactory.js      |  2 +-
 .../src/datasource/ChangeDatasourceModal.tsx       |  2 +-
 .../src/datasource/DatasourceEditor.jsx            | 42 +++++++++++-----------
 11 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/superset-frontend/spec/javascripts/dashboard/components/nativeFilters/NativeFiltersModal_spec.tsx b/superset-frontend/spec/javascripts/dashboard/components/nativeFilters/NativeFiltersModal_spec.tsx
index d3f552f..a3329c3 100644
--- a/superset-frontend/spec/javascripts/dashboard/components/nativeFilters/NativeFiltersModal_spec.tsx
+++ b/superset-frontend/spec/javascripts/dashboard/components/nativeFilters/NativeFiltersModal_spec.tsx
@@ -109,7 +109,7 @@ describe('FiltersConfigModal', () => {
       await clickCancel();
       expect(onCancel.mock.calls).toHaveLength(0);
       expect(wrapper.find(Alert).text()).toContain(
-        'Are you sure you want to cancel? "New Filter" will not be saved.',
+        'Are you sure you want to cancel? "New filter" will not be saved.',
       );
     });
 
@@ -119,7 +119,7 @@ describe('FiltersConfigModal', () => {
       await clickCancel();
       expect(onCancel.mock.calls).toHaveLength(0);
       expect(wrapper.find(Alert).text()).toContain(
-        'Are you sure you want to cancel? "New Filter" and "New Filter" will not be saved.',
+        'Are you sure you want to cancel? "New filter" and "New filter" will not be saved.',
       );
     });
   });
diff --git a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx
index f985fe8..dcd142c 100644
--- a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx
+++ b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx
@@ -199,7 +199,7 @@ class SliceHeaderControls extends React.PureComponent {
           : item}
       </div>
     ));
-    const resizeLabel = isFullSize ? t('Minimize Chart') : t('Maximize Chart');
+    const resizeLabel = isFullSize ? t('Minimize chart') : t('Maximize chart');
     const menu = (
       <Menu
         onClick={this.handleMenuClick}
@@ -228,7 +228,7 @@ class SliceHeaderControls extends React.PureComponent {
 
         {this.props.supersetCanExplore && (
           <Menu.Item key={MENU_KEYS.EXPLORE_CHART}>
-            {t('View Chart in Explore')}
+            {t('View chart in Explore')}
           </Menu.Item>
         )}
 
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/CascadePopover.tsx b/superset-frontend/src/dashboard/components/nativeFilters/CascadePopover.tsx
index c7519b4..2b92370 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/CascadePopover.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/CascadePopover.tsx
@@ -118,7 +118,7 @@ const CascadePopover: React.FC<CascadePopoverProps> = ({
     <StyledTitleBox>
       <StyledTitle>
         <StyledIcon name="edit" />
-        {t('Select Parent Filters')} ({totalChildren})
+        {t('Select parent filters')} ({totalChildren})
       </StyledTitle>
       <StyledIcon name="close" onClick={() => onVisibleChange(false)} />
     </StyledTitleBox>
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar.tsx
index bc66d53..abd189a 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar.tsx
@@ -452,7 +452,7 @@ const FilterBar: React.FC<FiltersBarProps> = ({
             buttonSize="sm"
             onClick={handleResetAll}
           >
-            {t('Reset All')}
+            {t('Reset all')}
           </Button>
           <Button
             buttonStyle="primary"
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterConfigForm.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterConfigForm.tsx
index 461250d..bdeb972 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterConfigForm.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterConfigForm.tsx
@@ -132,7 +132,7 @@ export const FilterConfigForm: React.FC<FilterConfigFormProps> = ({
         <p>{t('You have removed this filter.')}</p>
         <div>
           <Button type="primary" onClick={() => restore(filterId)}>
-            {t('Restore Filter')}
+            {t('Restore filter')}
           </Button>
         </div>
       </RemovedContent>
@@ -150,7 +150,7 @@ export const FilterConfigForm: React.FC<FilterConfigFormProps> = ({
       <StyledContainer>
         <StyledFormItem
           name={['filters', filterId, 'name']}
-          label={<StyledLabel>{t('Filter Name')}</StyledLabel>}
+          label={<StyledLabel>{t('Filter name')}</StyledLabel>}
           initialValue={filterToEdit?.name}
           rules={[{ required: !removed, message: t('Name is required') }]}
           data-test="name-input"
@@ -200,7 +200,7 @@ export const FilterConfigForm: React.FC<FilterConfigFormProps> = ({
       </StyledFormItem>
       <StyledFormItem
         name={['filters', filterId, 'parentFilter']}
-        label={<StyledLabel>{t('Parent Filter')}</StyledLabel>}
+        label={<StyledLabel>{t('Parent filter')}</StyledLabel>}
         initialValue={parentFilterOptions.find(
           ({ value }) => value === filterToEdit?.cascadeParentIds[0],
         )}
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterConfigModal.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterConfigModal.tsx
index 2be67db..c2aad91 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterConfigModal.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterConfigModal.tsx
@@ -286,7 +286,7 @@ export function FilterConfigModal({
 
   function getFilterTitle(id: string) {
     return (
-      formValues.filters[id]?.name ?? filterConfigMap[id]?.name ?? 'New Filter'
+      formValues.filters[id]?.name ?? filterConfigMap[id]?.name ?? 'New filter'
     );
   }
 
@@ -353,7 +353,7 @@ export function FilterConfigModal({
 
       return formValues;
     } catch (error) {
-      console.warn('Filter Configuration Failed:', error);
+      console.warn('Filter configuration failed:', error);
 
       if (!error.errorFields || !error.errorFields.length) return null; // not a validation error
 
@@ -484,7 +484,7 @@ export function FilterConfigModal({
   return (
     <StyledModal
       visible={isOpen}
-      title={t('Filter Configuration and Scoping')}
+      title={t('Filter configuration and scoping')}
       width="55%"
       onCancel={handleCancel}
       onOk={onOk}
@@ -517,7 +517,7 @@ export function FilterConfigModal({
               onEdit={onTabEdit}
               addIcon={
                 <StyledAddFilterBox>
-                  <PlusOutlined /> <span>{t('Add Filter')}</span>
+                  <PlusOutlined /> <span>{t('Add filter')}</span>
                 </StyledAddFilterBox>
               }
             >
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FiltersList.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FiltersList.tsx
index 5c91bf6..f85e31b 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FiltersList.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FiltersList.tsx
@@ -53,7 +53,7 @@ const FiltersList = ({ setEditFilter, setDataset }: FiltersListProps) => {
         </Button>
         <span
           role="button"
-          title="Edit Dashboard"
+          title="Edit dashboard"
           tabIndex={0}
           className="action-button"
         >
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/state.ts b/superset-frontend/src/dashboard/components/nativeFilters/state.ts
index 37b7198..6a5388e 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/state.ts
+++ b/superset-frontend/src/dashboard/components/nativeFilters/state.ts
@@ -88,7 +88,7 @@ export function useFilterScopeTree(): {
     children: [],
     key: DASHBOARD_ROOT_ID,
     type: DASHBOARD_ROOT_TYPE,
-    title: t('All Panels'),
+    title: t('All panels'),
   };
   buildTree(layout[DASHBOARD_ROOT_ID], tree, layout, charts);
   return { treeData: [tree], layout };
diff --git a/superset-frontend/src/dashboard/util/newComponentFactory.js b/superset-frontend/src/dashboard/util/newComponentFactory.js
index 1c3d2cf..d3f3a82 100644
--- a/superset-frontend/src/dashboard/util/newComponentFactory.js
+++ b/superset-frontend/src/dashboard/util/newComponentFactory.js
@@ -50,7 +50,7 @@ const typeToDefaultMetaData = {
   [MARKDOWN_TYPE]: { width: GRID_DEFAULT_CHART_WIDTH, height: 50 },
   [ROW_TYPE]: { background: BACKGROUND_TRANSPARENT },
   [TABS_TYPE]: null,
-  [TAB_TYPE]: { text: 'New Tab' },
+  [TAB_TYPE]: { text: 'New tab' },
 };
 
 function uuid(type) {
diff --git a/superset-frontend/src/datasource/ChangeDatasourceModal.tsx b/superset-frontend/src/datasource/ChangeDatasourceModal.tsx
index c2b43eb..5c144e4 100644
--- a/superset-frontend/src/datasource/ChangeDatasourceModal.tsx
+++ b/superset-frontend/src/datasource/ChangeDatasourceModal.tsx
@@ -220,7 +220,7 @@ const ChangeDatasourceModal: FunctionComponent<ChangeDatasourceModalProps> = ({
       show={show}
       onHide={onHide}
       responsive
-      title={t('Change Dataset')}
+      title={t('Change dataset')}
       width={confirmChange ? '432px' : ''}
       height={confirmChange ? 'auto' : '480px'}
       hideFooter={!confirmChange}
diff --git a/superset-frontend/src/datasource/DatasourceEditor.jsx b/superset-frontend/src/datasource/DatasourceEditor.jsx
index 4427b22..ca19a5c 100644
--- a/superset-frontend/src/datasource/DatasourceEditor.jsx
+++ b/superset-frontend/src/datasource/DatasourceEditor.jsx
@@ -132,7 +132,7 @@ function ColumnCollectionTable({
             {showExpression && (
               <Field
                 fieldKey="expression"
-                label={t('SQL Expression')}
+                label={t('SQL expression')}
                 control={
                   <TextAreaControl
                     language="markdown"
@@ -164,7 +164,7 @@ function ColumnCollectionTable({
             {allowEditDataType && (
               <Field
                 fieldKey="type"
-                label={t('Data Type')}
+                label={t('Data type')}
                 control={
                   <SelectControl choices={DATA_TYPES} name="type" freeForm />
                 }
@@ -172,13 +172,13 @@ function ColumnCollectionTable({
             )}
             <Field
               fieldKey="python_date_format"
-              label={t('Datetime Format')}
+              label={t('Datetime format')}
               description={
                 /* Note the fragmented translations may not work. */
                 <div>
                   {t('The pattern of timestamp format. For strings use ')}
                   <a href="https://docs.python.org/2/library/datetime.html#strftime-strptime-behavior">
-                    {t('python datetime string pattern')}
+                    {t('Python datetime string pattern')}
                   </a>
                   {t(' expression which needs to adhere to the ')}
                   <a href="https://en.wikipedia.org/wiki/ISO_8601">
@@ -207,10 +207,10 @@ function ColumnCollectionTable({
       }
       columnLabels={{
         column_name: t('Column'),
-        type: t('Data Type'),
-        groupby: t('Is Dimension'),
-        is_dttm: t('Is Temporal'),
-        filterable: t('Is Filterable'),
+        type: t('Data type'),
+        groupby: t('Is dimension'),
+        is_dttm: t('Is temporal'),
+        filterable: t('Is filterable'),
       }}
       onChange={onChange}
       itemRenderers={{
@@ -537,7 +537,7 @@ class DatasourceEditor extends React.PureComponent {
         {this.state.isSqla && (
           <Field
             fieldKey="fetch_values_predicate"
-            label={t('Autocomplete Query Predicate')}
+            label={t('Autocomplete query predicate')}
             description={t(
               'When using "Autocomplete filters", this can be used to improve performance ' +
                 'of the query fetching the values. Use this option to apply a ' +
@@ -599,7 +599,7 @@ class DatasourceEditor extends React.PureComponent {
       >
         <Field
           fieldKey="cache_timeout"
-          label={t('Cache Timeout')}
+          label={t('Cache timeout')}
           description={t(
             'The duration of time in seconds before the cache is invalidated',
           )}
@@ -702,14 +702,14 @@ class DatasourceEditor extends React.PureComponent {
                   />
                   <Field
                     fieldKey="table_name"
-                    label={t('dataset name')}
+                    label={t('Dataset name')}
                     control={
                       <TextControl
                         controlId="table_name"
                         onChange={table => {
                           this.onDatasourcePropChange('table_name', table);
                         }}
-                        placeholder={t('dataset name')}
+                        placeholder={t('Dataset name')}
                         disabled={!this.state.isEditMode}
                       />
                     }
@@ -835,7 +835,7 @@ class DatasourceEditor extends React.PureComponent {
         columnLabels={{
           metric_name: t('Metric'),
           verbose_name: t('Label'),
-          expression: t('SQL Expression'),
+          expression: t('SQL expression'),
         }}
         expandFieldset={
           <FormContainer>
@@ -857,13 +857,13 @@ class DatasourceEditor extends React.PureComponent {
               />
               <Field
                 fieldKey="d3format"
-                label={t('D3 Format')}
+                label={t('D3 format')}
                 control={
                   <TextControl controlId="d3format" placeholder="%y/%m/%d" />
                 }
               />
               <Field
-                label={t('Warning Message')}
+                label={t('Warning message')}
                 fieldKey="warning_text"
                 description={t(
                   'Warning message to display in the metric selector',
@@ -871,12 +871,12 @@ class DatasourceEditor extends React.PureComponent {
                 control={
                   <TextControl
                     controlId="warning_text"
-                    placeholder={t('Warning Message')}
+                    placeholder={t('Warning message')}
                   />
                 }
               />
               <Field
-                label={t('Certified By')}
+                label={t('Certified by')}
                 fieldKey="certified_by"
                 description={t(
                   'Person or group that has certified this metric',
@@ -884,18 +884,18 @@ class DatasourceEditor extends React.PureComponent {
                 control={
                   <TextControl
                     controlId="certified_by"
-                    placeholder={t('Certified By')}
+                    placeholder={t('Certified by')}
                   />
                 }
               />
               <Field
-                label={t('Certification Details')}
+                label={t('Certification details')}
                 fieldKey="certification_details"
                 description={t('Details of the certification')}
                 control={
                   <TextControl
                     controlId="certification_details"
-                    placeholder={t('Certification Details')}
+                    placeholder={t('Certification details')}
                   />
                 }
               />
@@ -1024,7 +1024,7 @@ class DatasourceEditor extends React.PureComponent {
             tab={
               <CollectionTabTitle
                 collection={this.state.calculatedColumns}
-                title={t('Calculated Columns')}
+                title={t('Calculated columns')}
               />
             }
             key={3}


[superset] 18/38: Add docs for GLOBAL_ASYNC_QUERIES (SIP-39) (#12573)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 10ca58f89a1151a48ba94a54414fbb4b8041f081
Author: Rob DiCiuccio <ro...@gmail.com>
AuthorDate: Tue Jan 19 13:57:25 2021 -0800

    Add docs for GLOBAL_ASYNC_QUERIES (SIP-39) (#12573)
---
 CONTRIBUTING.md       | 24 ++++++++++++++++++++++++
 docs/installation.rst | 26 ++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2980c59..b0670eb 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -81,6 +81,7 @@ little bit helps, and credit will always be given.
     - [Adding a DB migration](#adding-a-db-migration)
     - [Merging DB migrations](#merging-db-migrations)
     - [SQL Lab Async](#sql-lab-async)
+    - [Async Chart Queries](#async-chart-queries)
   - [Chart Parameters](#chart-parameters)
     - [Datasource & Chart Type](#datasource--chart-type)
     - [Time](#time)
@@ -969,6 +970,29 @@ Note that:
   to your production environment, and use the similar broker as well as
   results backend configuration
 
+### Async Chart Queries
+
+It's possible to configure database queries for charts to operate in `async` mode. This is especially useful for dashboards with many charts that may otherwise be affected by browser connection limits. To enable async queries for dashboards and Explore, the following dependencies are required:
+
+- Redis 5.0+ (the feature utilizes [Redis Streams](https://redis.io/topics/streams-intro))
+- Cache backends enabled via the `CACHE_CONFIG` and `DATA_CACHE_CONFIG` config settings
+- Celery workers configured and running to process async tasks
+
+The following configuration settings are available for async queries (see config.py for default values)
+
+- `GLOBAL_ASYNC_QUERIES` (feature flag) - enable or disable async query operation
+- `GLOBAL_ASYNC_QUERIES_REDIS_CONFIG` - Redis connection info
+- `GLOBAL_ASYNC_QUERIES_REDIS_STREAM_PREFIX` - the prefix used with Redis Streams
+- `GLOBAL_ASYNC_QUERIES_REDIS_STREAM_LIMIT` - the maximum number of events for each user-specific event stream (FIFO eviction)
+- `GLOBAL_ASYNC_QUERIES_REDIS_STREAM_LIMIT_FIREHOSE` - the maximum number of events for all users (FIFO eviction)
+- `GLOBAL_ASYNC_QUERIES_JWT_COOKIE_NAME` - the async query feature uses a [JWT](https://tools.ietf.org/html/rfc7519) cookie for authentication, this setting is the cookie's name
+- `GLOBAL_ASYNC_QUERIES_JWT_COOKIE_SECURE` - JWT cookie secure option
+- `GLOBAL_ASYNC_QUERIES_JWT_SECRET` - JWT's use a secret key to sign and validate the contents. This value should be at least 32 bytes and have sufficient randomness for proper security
+- `GLOBAL_ASYNC_QUERIES_TRANSPORT` - currently the only available option is (HTTP) `polling`, but support for a WebSocket will be added in future versions
+- `GLOBAL_ASYNC_QUERIES_POLLING_DELAY` - the time (in ms) between polling requests
+
+More information on the async query feature can be found in [SIP-39](https://github.com/apache/superset/issues/9190).
+
 ## Chart Parameters
 
 Chart parameters are stored as a JSON encoded string the `slices.params` column and are often referenced throughout the code as form-data. Currently the form-data is neither versioned nor typed as thus is somewhat free-formed. Note in the future there may be merit in using something like [JSON Schema](https://json-schema.org/) to both annotate and validate the JSON object in addition to using a Mypy `TypedDict` (introduced in Python 3.8) for typing the form-data in the backend. This sect [...]
diff --git a/docs/installation.rst b/docs/installation.rst
index 095f6be..e283116 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -1113,6 +1113,32 @@ serialization. This can be disabled by setting ``RESULTS_BACKEND_USE_MSGPACK = F
 in your configuration, should any issues arise. Please clear your existing results
 cache store when upgrading an existing environment.
 
+**Async queries for dashboards and Explore**
+
+It's also possible to configure database queries for charts to operate in `async` mode.
+This is especially useful for dashboards with many charts that may otherwise be affected
+by browser connection limits. To enable async queries for dashboards and Explore, the
+following dependencies are required:
+
+- Redis 5.0+ (the feature utilizes `Redis Streams <https://redis.io/topics/streams-intro>`_)
+- Cache backends enabled via the ``CACHE_CONFIG`` and ``DATA_CACHE_CONFIG`` config settings
+- Celery workers configured and running to process async tasks
+
+The following configuration settings are available for async queries (see config.py for default values)
+
+- ``GLOBAL_ASYNC_QUERIES`` (feature flag) - enable or disable async query operation
+- ``GLOBAL_ASYNC_QUERIES_REDIS_CONFIG`` - Redis connection info
+- ``GLOBAL_ASYNC_QUERIES_REDIS_STREAM_PREFIX`` - the prefix used with Redis Streams
+- ``GLOBAL_ASYNC_QUERIES_REDIS_STREAM_LIMIT`` - the maximum number of events for each user-specific event stream (FIFO eviction)
+- ``GLOBAL_ASYNC_QUERIES_REDIS_STREAM_LIMIT_FIREHOSE`` - the maximum number of events for all users (FIFO eviction)
+- ``GLOBAL_ASYNC_QUERIES_JWT_COOKIE_NAME`` - the async query feature uses a `JWT <https://tools.ietf.org/html/rfc7519>`_ cookie for authentication, this setting is the cookie's name
+- ``GLOBAL_ASYNC_QUERIES_JWT_COOKIE_SECURE`` - JWT cookie secure option
+- ``GLOBAL_ASYNC_QUERIES_JWT_SECRET`` - JWT's use a secret key to sign and validate the contents. This value should be at least 32 bytes and have sufficient randomness for proper security
+- ``GLOBAL_ASYNC_QUERIES_TRANSPORT`` - currently the only available option is (HTTP) `polling`, but support for a WebSocket will be added in future versions
+- ``GLOBAL_ASYNC_QUERIES_POLLING_DELAY`` - the time (in ms) between polling requests
+
+More information on the async query feature can be found in `SIP-39 <https://github.com/apache/superset/issues/9190>`_.
+
 **Important notes**
 
 * It is important that all the worker nodes and web servers in


[superset] 14/38: Apply capitalization guidelines - iteration 7 (#12343) (#12453)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 342f5eae718548a4703d82bf4dc14887af19cd7e
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Fri Jan 22 02:46:06 2021 -0300

    Apply capitalization guidelines - iteration 7 (#12343) (#12453)
---
 superset-frontend/src/SqlLab/actions/sqlLab.js                 |  2 +-
 superset-frontend/src/SqlLab/components/ColumnElement.tsx      |  4 ++--
 .../src/SqlLab/components/EstimateQueryCostButton.jsx          |  6 +++---
 superset-frontend/src/SqlLab/components/QueryTable.jsx         |  2 +-
 superset-frontend/src/SqlLab/components/ResultSet.tsx          |  8 ++++----
 .../src/SqlLab/components/RunQueryActionButton.tsx             |  2 +-
 superset-frontend/src/SqlLab/components/SaveQuery.tsx          |  4 ++--
 .../src/SqlLab/components/ScheduleQueryButton.jsx              |  2 +-
 superset-frontend/src/SqlLab/components/SouthPane.jsx          |  2 +-
 superset-frontend/src/SqlLab/components/SqlEditor.jsx          | 10 +++++-----
 superset-frontend/src/SqlLab/components/SqlEditorLeftBar.jsx   |  2 +-
 superset-frontend/src/filters/components/Select/index.ts       |  4 ++--
 superset-frontend/src/middleware/asyncEvent.ts                 |  8 ++++----
 superset-frontend/src/modules/AnnotationTypes.js               |  2 +-
 superset-frontend/src/profile/components/App.tsx               |  4 ++--
 15 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/superset-frontend/src/SqlLab/actions/sqlLab.js b/superset-frontend/src/SqlLab/actions/sqlLab.js
index ebfca91..1806098 100644
--- a/superset-frontend/src/SqlLab/actions/sqlLab.js
+++ b/superset-frontend/src/SqlLab/actions/sqlLab.js
@@ -188,7 +188,7 @@ export function scheduleQuery(query) {
         dispatch(
           addSuccessToast(
             t(
-              'Your query has been scheduled. To see details of your query, navigate to Saved Queries',
+              'Your query has been scheduled. To see details of your query, navigate to Saved queries',
             ),
           ),
         ),
diff --git a/superset-frontend/src/SqlLab/components/ColumnElement.tsx b/superset-frontend/src/SqlLab/components/ColumnElement.tsx
index b9ead1e..8f1953d 100644
--- a/superset-frontend/src/SqlLab/components/ColumnElement.tsx
+++ b/superset-frontend/src/SqlLab/components/ColumnElement.tsx
@@ -65,8 +65,8 @@ const iconMap = {
   index: 'fa-bookmark',
 };
 const tooltipTitleMap = {
-  pk: 'Primary Key',
-  fk: 'Foreign Key',
+  pk: 'Primary key',
+  fk: 'Foreign key',
   index: 'Index',
 };
 
diff --git a/superset-frontend/src/SqlLab/components/EstimateQueryCostButton.jsx b/superset-frontend/src/SqlLab/components/EstimateQueryCostButton.jsx
index b6de813..d5424cd 100644
--- a/superset-frontend/src/SqlLab/components/EstimateQueryCostButton.jsx
+++ b/superset-frontend/src/SqlLab/components/EstimateQueryCostButton.jsx
@@ -82,12 +82,12 @@ const EstimateQueryCostButton = props => {
 
   const { disabled, selectedText, tooltip } = props;
   const btnText = selectedText
-    ? t('Estimate Selected Query Cost')
-    : t('Estimate Cost');
+    ? t('Estimate selected query cost')
+    : t('Estimate cost');
   return (
     <span className="EstimateQueryCostButton">
       <ModalTrigger
-        modalTitle={t('Cost Estimate')}
+        modalTitle={t('Cost estimate')}
         modalBody={renderModalBody()}
         triggerNode={
           <Button
diff --git a/superset-frontend/src/SqlLab/components/QueryTable.jsx b/superset-frontend/src/SqlLab/components/QueryTable.jsx
index a792764..6342f00 100644
--- a/superset-frontend/src/SqlLab/components/QueryTable.jsx
+++ b/superset-frontend/src/SqlLab/components/QueryTable.jsx
@@ -144,7 +144,7 @@ const QueryTable = props => {
               className="ResultsModal"
               triggerNode={
                 <Label bsStyle="info" className="pointer">
-                  {t('view results')}
+                  {t('View results')}
                 </Label>
               }
               modalTitle={t('Data preview')}
diff --git a/superset-frontend/src/SqlLab/components/ResultSet.tsx b/superset-frontend/src/SqlLab/components/ResultSet.tsx
index d54b6bc..0ad2d0e 100644
--- a/superset-frontend/src/SqlLab/components/ResultSet.tsx
+++ b/superset-frontend/src/SqlLab/components/ResultSet.tsx
@@ -466,7 +466,7 @@ export default class ResultSet extends React.PureComponent<
               onChange={this.changeSearch}
               value={this.state.searchText}
               className="form-control input-sm"
-              placeholder={t('Filter Results')}
+              placeholder={t('Filter results')}
             />
           )}
         </div>
@@ -498,7 +498,7 @@ export default class ResultSet extends React.PureComponent<
       return (
         <div className="result-set-error-message">
           <ErrorMessageWithStackTrace
-            title={t('Database Error')}
+            title={t('Database error')}
             error={query?.errors?.[0]}
             subtitle={<MonospaceDiv>{query.errorMessage}</MonospaceDiv>}
             copyText={query.errorMessage || undefined}
@@ -602,7 +602,7 @@ export default class ResultSet extends React.PureComponent<
             buttonStyle="primary"
             onClick={() => this.fetchResults(query)}
           >
-            {t('Refetch Results')}
+            {t('Refetch results')}
           </Button>
         );
       }
@@ -623,7 +623,7 @@ export default class ResultSet extends React.PureComponent<
           buttonSize="small"
           onClick={() => query.trackingUrl && window.open(query.trackingUrl)}
         >
-          {t('Track Job')}
+          {t('Track job')}
         </Button>
       );
     }
diff --git a/superset-frontend/src/SqlLab/components/RunQueryActionButton.tsx b/superset-frontend/src/SqlLab/components/RunQueryActionButton.tsx
index 6a61a0c..1208de3 100644
--- a/superset-frontend/src/SqlLab/components/RunQueryActionButton.tsx
+++ b/superset-frontend/src/SqlLab/components/RunQueryActionButton.tsx
@@ -48,7 +48,7 @@ const buildText = (
     );
   }
   if (selectedText) {
-    return t('Run Selection');
+    return t('Run selection');
   }
   return t('Run');
 };
diff --git a/superset-frontend/src/SqlLab/components/SaveQuery.tsx b/superset-frontend/src/SqlLab/components/SaveQuery.tsx
index 04dc673..4907684 100644
--- a/superset-frontend/src/SqlLab/components/SaveQuery.tsx
+++ b/superset-frontend/src/SqlLab/components/SaveQuery.tsx
@@ -169,7 +169,7 @@ export default function SaveQuery({
         primaryButtonName={isSaved ? t('Save') : t('Save as')}
         width="620px"
         show={showSave}
-        title={<h4>{t('Save Query')}</h4>}
+        title={<h4>{t('Save query')}</h4>}
         footer={[
           <>
             <Button onClick={close} data-test="cancel-query" cta>
@@ -181,7 +181,7 @@ export default function SaveQuery({
               className="m-r-3"
               cta
             >
-              {isSaved ? t('Save As New') : t('Save')}
+              {isSaved ? t('Save as new') : t('Save')}
             </Button>
             {isSaved && (
               <Button
diff --git a/superset-frontend/src/SqlLab/components/ScheduleQueryButton.jsx b/superset-frontend/src/SqlLab/components/ScheduleQueryButton.jsx
index a1d2411..4444d64 100644
--- a/superset-frontend/src/SqlLab/components/ScheduleQueryButton.jsx
+++ b/superset-frontend/src/SqlLab/components/ScheduleQueryButton.jsx
@@ -198,7 +198,7 @@ class ScheduleQueryButton extends React.PureComponent {
           ref={ref => {
             this.saveModal = ref;
           }}
-          modalTitle={t('Schedule Query')}
+          modalTitle={t('Schedule query')}
           modalBody={this.renderModalBody()}
           triggerNode={
             <div
diff --git a/superset-frontend/src/SqlLab/components/SouthPane.jsx b/superset-frontend/src/SqlLab/components/SouthPane.jsx
index bc71157..8abe498 100644
--- a/superset-frontend/src/SqlLab/components/SouthPane.jsx
+++ b/superset-frontend/src/SqlLab/components/SouthPane.jsx
@@ -177,7 +177,7 @@ export class SouthPane extends React.PureComponent {
           <Tabs.TabPane tab={t('Results')} key="Results">
             {results}
           </Tabs.TabPane>
-          <Tabs.TabPane tab={t('Query History')} key="History">
+          <Tabs.TabPane tab={t('Query history')} key="History">
             <QueryHistory
               queries={props.editorQueries}
               actions={props.actions}
diff --git a/superset-frontend/src/SqlLab/components/SqlEditor.jsx b/superset-frontend/src/SqlLab/components/SqlEditor.jsx
index 3b2e936..ce68a2b 100644
--- a/superset-frontend/src/SqlLab/components/SqlEditor.jsx
+++ b/superset-frontend/src/SqlLab/components/SqlEditor.jsx
@@ -306,7 +306,7 @@ class SqlEditor extends React.PureComponent {
         func: () => {
           this.props.addQueryEditor({
             ...this.props.queryEditor,
-            title: t('Untitled Query'),
+            title: t('Untitled query'),
             sql: '',
           });
         },
@@ -698,13 +698,13 @@ class SqlEditor extends React.PureComponent {
   render() {
     const createViewModalTitle =
       this.state.createAs === CtasEnum.VIEW
-        ? 'Create View As'
-        : 'Create Table As';
+        ? 'CREATE VIEW AS'
+        : 'CREATE TABLE AS';
 
     const createModalPlaceHolder =
       this.state.createAs === CtasEnum.VIEW
-        ? 'Specify name to Create View AS schema in: public'
-        : 'Specify name to Create Table AS schema in: public';
+        ? 'Specify name to CREATE VIEW AS schema in: public'
+        : 'Specify name to CREATE TABLE AS schema in: public';
 
     return (
       <div ref={this.sqlEditorRef} className="SqlEditor">
diff --git a/superset-frontend/src/SqlLab/components/SqlEditorLeftBar.jsx b/superset-frontend/src/SqlLab/components/SqlEditorLeftBar.jsx
index 7b2179f..550f623 100644
--- a/superset-frontend/src/SqlLab/components/SqlEditorLeftBar.jsx
+++ b/superset-frontend/src/SqlLab/components/SqlEditorLeftBar.jsx
@@ -156,7 +156,7 @@ export default class SqlEditorLeftBar extends React.PureComponent {
             buttonStyle="danger"
             onClick={this.resetState}
           >
-            <i className="fa fa-bomb" /> {t('Reset State')}
+            <i className="fa fa-bomb" /> {t('Reset state')}
           </Button>
         )}
       </div>
diff --git a/superset-frontend/src/filters/components/Select/index.ts b/superset-frontend/src/filters/components/Select/index.ts
index f0d05c3..7f3cb2a 100644
--- a/superset-frontend/src/filters/components/Select/index.ts
+++ b/superset-frontend/src/filters/components/Select/index.ts
@@ -25,8 +25,8 @@ import thumbnail from './images/thumbnail.png';
 export default class AntdFilterSelectPlugin extends ChartPlugin {
   constructor() {
     const metadata = new ChartMetadata({
-      name: t('Select Filter Plugin'),
-      description: 'Select Filter Plugin using AntD',
+      name: t('Select filter plugin'),
+      description: 'Select filter plugin using AntD',
       isNativeFilter: true,
       thumbnail,
     });
diff --git a/superset-frontend/src/middleware/asyncEvent.ts b/superset-frontend/src/middleware/asyncEvent.ts
index b7a4912..20caad9 100644
--- a/superset-frontend/src/middleware/asyncEvent.ts
+++ b/superset-frontend/src/middleware/asyncEvent.ts
@@ -79,7 +79,7 @@ const initAsyncEvents = (options: AsyncEventOptions) => {
     try {
       lastReceivedEventId = localStorage.getItem(LOCALSTORAGE_KEY);
     } catch (err) {
-      console.warn('failed to fetch last event Id from localStorage');
+      console.warn('Failed to fetch last event Id from localStorage');
     }
 
     const fetchEvents = makeApi<
@@ -114,7 +114,7 @@ const initAsyncEvents = (options: AsyncEventOptions) => {
       try {
         localStorage.setItem(LOCALSTORAGE_KEY, lastReceivedEventId as string);
       } catch (err) {
-        console.warn('Error saving event ID to localStorage', err);
+        console.warn('Error saving event Id to localStorage', err);
       }
     };
 
@@ -138,7 +138,7 @@ const initAsyncEvents = (options: AsyncEventOptions) => {
               const component = componentsByJobId[asyncEvent.job_id];
               if (!component) {
                 console.warn(
-                  'component not found for job_id',
+                  'Component not found for job_id',
                   asyncEvent.job_id,
                 );
                 return setLastId(asyncEvent);
@@ -156,7 +156,7 @@ const initAsyncEvents = (options: AsyncEventOptions) => {
                   );
                   break;
                 default:
-                  console.warn('received event with status', asyncEvent.status);
+                  console.warn('Received event with status', asyncEvent.status);
               }
 
               return setLastId(asyncEvent);
diff --git a/superset-frontend/src/modules/AnnotationTypes.js b/superset-frontend/src/modules/AnnotationTypes.js
index 5741788..1f85561 100644
--- a/superset-frontend/src/modules/AnnotationTypes.js
+++ b/superset-frontend/src/modules/AnnotationTypes.js
@@ -41,7 +41,7 @@ export const ANNOTATION_TYPES_METADATA = {
   },
   TIME_SERIES: {
     value: 'TIME_SERIES',
-    label: 'Time Series',
+    label: 'Time series',
   },
 };
 
diff --git a/superset-frontend/src/profile/components/App.tsx b/superset-frontend/src/profile/components/App.tsx
index 8642dd7..ec6cec8 100644
--- a/superset-frontend/src/profile/components/App.tsx
+++ b/superset-frontend/src/profile/components/App.tsx
@@ -59,7 +59,7 @@ export default function App({ user }: AppProps) {
               key="2"
               tab={
                 <div>
-                  <i className="fa fa-paint-brush" /> {t('Created Content')}
+                  <i className="fa fa-paint-brush" /> {t('Created content')}
                 </div>
               }
             >
@@ -73,7 +73,7 @@ export default function App({ user }: AppProps) {
               key="3"
               tab={
                 <div>
-                  <i className="fa fa-list" /> {t('Recent Activity')}
+                  <i className="fa fa-list" /> {t('Recent activity')}
                 </div>
               }
             >


[superset] 21/38: chore(explore): added tooltips to timepicker (#12580)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 3ccb23c4a3295c36c7d49344ee25649987e8cf9f
Author: Yongjie Zhao <yo...@gmail.com>
AuthorDate: Mon Jan 25 15:58:15 2021 +0800

    chore(explore): added tooltips to timepicker (#12580)
    
    * wip
    
    * wip
    
    * fix lint
    
    * fix: tooltip cosmetic
    
    * wip
    
    * add license
---
 .../DateFilterControl/frame/AdvancedFrame.tsx      |   8 +-
 .../frame/DateFunctionTooltip.tsx                  | 147 +++++++++++++++++++++
 2 files changed, 154 insertions(+), 1 deletion(-)

diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/frame/AdvancedFrame.tsx b/superset-frontend/src/explore/components/controls/DateFilterControl/frame/AdvancedFrame.tsx
index 39a695c..e8fe028 100644
--- a/superset-frontend/src/explore/components/controls/DateFilterControl/frame/AdvancedFrame.tsx
+++ b/superset-frontend/src/explore/components/controls/DateFilterControl/frame/AdvancedFrame.tsx
@@ -21,6 +21,7 @@ import { t } from '@superset-ui/core';
 import { SEPARATOR } from 'src/explore/dateFilterUtils';
 import { Input } from 'src/common/components';
 import { FrameComponentProps } from '../types';
+import DateFunctionTooltip from './DateFunctionTooltip';
 
 export function AdvancedFrame(props: FrameComponentProps) {
   const [since, until] = getAdvancedRange(props.value || '').split(SEPARATOR);
@@ -48,7 +49,12 @@ export function AdvancedFrame(props: FrameComponentProps) {
 
   return (
     <>
-      <div className="section-title">{t('Configure advanced time range')}</div>
+      <div className="section-title">
+        {t('Configure Advanced Time Range ')}
+        <DateFunctionTooltip placement="rightBottom">
+          <i className="fa fa-info-circle text-muted" />
+        </DateFunctionTooltip>
+      </div>
       <div className="control-label">{t('START')}</div>
       <Input
         key="since"
diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/frame/DateFunctionTooltip.tsx b/superset-frontend/src/explore/components/controls/DateFilterControl/frame/DateFunctionTooltip.tsx
new file mode 100644
index 0000000..622d69d
--- /dev/null
+++ b/superset-frontend/src/explore/components/controls/DateFilterControl/frame/DateFunctionTooltip.tsx
@@ -0,0 +1,147 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import React from 'react';
+import { useTheme, t } from '@superset-ui/core';
+
+import { Tooltip } from 'src/common/components/Tooltip';
+import { ClassNames } from '@emotion/core';
+
+const TIME_PICKER_HELPER = (
+  <>
+    <div>
+      <h3>DATETIME</h3>
+      <p>{t('Return to specific datetime.')}</p>
+      <h4>{t('Syntax')}</h4>
+      <pre>
+        <code>datetime([string])</code>
+      </pre>
+      <h4>{t('Example')}</h4>
+      <pre>
+        <code>{`datetime("2020-03-01 12:00:00")
+datetime("now")
+datetime("last year")`}</code>
+      </pre>
+    </div>
+    <div>
+      <h3>DATEADD</h3>
+      <p>{t('Moves the given set of dates by a specified interval.')}</p>
+      <h4>{t('Syntax')}</h4>
+      <pre>
+        <code>{`dateadd([datetime], [integer], [dateunit])
+dateunit = (year | quarter | month | week | day | hour | minute | second)`}</code>
+      </pre>
+      <h4>{t('Example')}</h4>
+      <pre>
+        <code>{`dateadd(datetime("today"), -13, day)
+dateadd(datetime("2020-03-01"), 2, day)`}</code>
+      </pre>
+    </div>
+    <div>
+      <h3>DATETRUNC</h3>
+      <p>
+        {t(
+          'Truncates the specified date to the accuracy specified by the date unit.',
+        )}
+      </p>
+      <h4>{t('Syntax')}</h4>
+      <pre>
+        <code>{`datetrunc([datetime], [dateunit])
+dateunit = (year | month | week)`}</code>
+      </pre>
+      <h4>{t('Example')}</h4>
+      <pre>
+        <code>{`datetrunc(datetime("2020-03-01"), week)
+datetrunc(datetime("2020-03-01"), month)`}</code>
+      </pre>
+    </div>
+    <div>
+      <h3>LASTDAY</h3>
+      <p>{t('Get the last date by the date unit.')}</p>
+      <h4>{t('Syntax')}</h4>
+      <pre>
+        <code>{`lastday([datetime], [dateunit])
+dateunit = (year | month | week)`}</code>
+      </pre>
+      <h4>{t('Example')}</h4>
+      <pre>
+        <code>lastday(datetime("today"), month)</code>
+      </pre>
+    </div>
+    <div>
+      <h3>HOLIDAY</h3>
+      <p>{t('Get the specify date for the holiday')}</p>
+      <h4>{t('Syntax')}</h4>
+      <pre>
+        <code>{`holiday([string])
+holiday([holiday string], [datetime])
+holiday([holiday string], [datetime], [country name])`}</code>
+      </pre>
+      <h4>{t('Example')}</h4>
+      <pre>
+        <code>{`holiday("new year")
+holiday("christmas", datetime("2019"))
+holiday("christmas", dateadd(datetime("2019"), 1, year))
+holiday("christmas", datetime("2 years ago"))
+holiday("Easter Monday", datetime("2019"), "UK")`}</code>
+      </pre>
+    </div>
+  </>
+);
+
+const StyledTooltip = (props: any) => {
+  const theme = useTheme();
+  return (
+    <ClassNames>
+      {({ css }) => (
+        <Tooltip
+          overlayClassName={css`
+            .ant-tooltip-content {
+              min-width: ${theme.gridUnit * 125}px;
+              max-height: 410px;
+              overflow-y: scroll;
+
+              .ant-tooltip-inner {
+                max-width: ${theme.gridUnit * 125}px;
+                h3 {
+                  font-size: ${theme.typography.sizes.m}px;
+                  font-weight: ${theme.typography.weights.bold};
+                }
+                h4 {
+                  font-size: ${theme.typography.sizes.m}px;
+                  font-weight: ${theme.typography.weights.bold};
+                }
+                pre {
+                  border: none;
+                  text-align: left;
+                  word-break: break-word;
+                  font-size: ${theme.typography.sizes.s}px;
+                }
+              }
+            }
+          `}
+          {...props}
+        />
+      )}
+    </ClassNames>
+  );
+};
+
+export default function DateFunctionTooltip(props: any) {
+  return <StyledTooltip title={TIME_PICKER_HELPER} {...props} />;
+}


[superset] 37/38: fix: remove whitespace at the bottom of select dropdown (#12699)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit c277b8466cc420d5dacfb6207c1a7dbae377f6b5
Author: Jesse Yang <je...@airbnb.com>
AuthorDate: Sat Jan 23 17:10:32 2021 -0800

    fix: remove whitespace at the bottom of select dropdown (#12699)
---
 superset-frontend/src/components/Select/styles.tsx | 1 +
 1 file changed, 1 insertion(+)

diff --git a/superset-frontend/src/components/Select/styles.tsx b/superset-frontend/src/components/Select/styles.tsx
index c990416..4776a72 100644
--- a/superset-frontend/src/components/Select/styles.tsx
+++ b/superset-frontend/src/components/Select/styles.tsx
@@ -191,6 +191,7 @@ export const DEFAULT_STYLES: PartialStylesConfig = {
       width: auto;
       min-width: 100%;
       max-width: 80vw;
+      background: none;
       box-shadow: none;
       border: 0;
     `,


[superset] 08/38: feat(native-filters): Show alert for unsaved filters after cancelling Filter Config Modal (#12554)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 5e4ce48ccfcee267ee785981a983c0fbd7187650
Author: Agata Stawarz <47...@users.noreply.github.com>
AuthorDate: Thu Jan 21 05:57:28 2021 +0100

    feat(native-filters): Show alert for unsaved filters after cancelling Filter Config Modal (#12554)
    
    * Add Alert when native filter is canceled and not saved
    
    * Improve styles and setting styles visible
    
    * Improve displaying filter names
    
    * Add tests for canceling native filter modal
    
    * Fix linter errors
    
    * Refactor Cancel Confirmation Alert
---
 .../nativeFilters/NativeFiltersModal_spec.tsx      |  49 ++++++++++
 .../nativeFilters/CancelConfirmationAlert.tsx      | 105 +++++++++++++++++++++
 .../components/nativeFilters/FilterConfigModal.tsx |  70 ++++++++++++--
 3 files changed, 215 insertions(+), 9 deletions(-)

diff --git a/superset-frontend/spec/javascripts/dashboard/components/nativeFilters/NativeFiltersModal_spec.tsx b/superset-frontend/spec/javascripts/dashboard/components/nativeFilters/NativeFiltersModal_spec.tsx
index e075393..d3f552f 100644
--- a/superset-frontend/spec/javascripts/dashboard/components/nativeFilters/NativeFiltersModal_spec.tsx
+++ b/superset-frontend/spec/javascripts/dashboard/components/nativeFilters/NativeFiltersModal_spec.tsx
@@ -19,7 +19,9 @@
 import React from 'react';
 import { styledMount as mount } from 'spec/helpers/theming';
 import { act } from 'react-dom/test-utils';
+import { ReactWrapper } from 'enzyme';
 import { Provider } from 'react-redux';
+import Alert from 'react-bootstrap/lib/Alert';
 import { FilterConfigModal } from 'src/dashboard/components/nativeFilters/FilterConfigModal';
 import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
 import { mockStore } from 'spec/fixtures/mockStore';
@@ -74,4 +76,51 @@ describe('FiltersConfigModal', () => {
     await waitForComponentToPaint(wrapper);
     expect(onSave.mock.calls).toHaveLength(0);
   });
+
+  describe('when click cancel', () => {
+    let onCancel: jest.Mock;
+    let wrapper: ReactWrapper;
+
+    beforeEach(() => {
+      onCancel = jest.fn();
+      wrapper = setup({ onCancel, createNewOnOpen: false });
+    });
+
+    async function clickCancel() {
+      act(() => {
+        wrapper.find('.ant-modal-footer button').at(0).simulate('click');
+      });
+      await waitForComponentToPaint(wrapper);
+    }
+
+    function addFilter() {
+      act(() => {
+        wrapper.find('button[aria-label="Add tab"]').at(0).simulate('click');
+      });
+    }
+
+    it('does not show alert when there is no unsaved filters', async () => {
+      await clickCancel();
+      expect(onCancel.mock.calls).toHaveLength(1);
+    });
+
+    it('shows correct alert message for an unsaved filter', async () => {
+      addFilter();
+      await clickCancel();
+      expect(onCancel.mock.calls).toHaveLength(0);
+      expect(wrapper.find(Alert).text()).toContain(
+        'Are you sure you want to cancel? "New Filter" will not be saved.',
+      );
+    });
+
+    it('shows correct alert message for 2 unsaved filters', async () => {
+      addFilter();
+      addFilter();
+      await clickCancel();
+      expect(onCancel.mock.calls).toHaveLength(0);
+      expect(wrapper.find(Alert).text()).toContain(
+        'Are you sure you want to cancel? "New Filter" and "New Filter" will not be saved.',
+      );
+    });
+  });
 });
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/CancelConfirmationAlert.tsx b/superset-frontend/src/dashboard/components/nativeFilters/CancelConfirmationAlert.tsx
new file mode 100644
index 0000000..96d1307
--- /dev/null
+++ b/superset-frontend/src/dashboard/components/nativeFilters/CancelConfirmationAlert.tsx
@@ -0,0 +1,105 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import React from 'react';
+import { styled, t } from '@superset-ui/core';
+import Alert from 'react-bootstrap/lib/Alert';
+import Button from 'src/components/Button';
+import Icon from 'src/components/Icon';
+
+const StyledAlert = styled(Alert)`
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: ${({ theme }) => theme.gridUnit * 2}px;
+  padding: ${({ theme }) => theme.gridUnit * 2}px;
+`;
+
+const StyledTextContainer = styled.div`
+  display: flex;
+  flex-direction: column;
+  text-align: left;
+  margin-right: ${({ theme }) => theme.gridUnit}px;
+`;
+
+const StyledTitleBox = styled.div`
+  display: flex;
+  align-items: center;
+`;
+
+const StyledAlertTitle = styled.span`
+  font-weight: ${({ theme }) => theme.typography.weights.bold};
+`;
+
+const StyledAlertText = styled.p`
+  margin-left: ${({ theme }) => theme.gridUnit * 9}px;
+`;
+
+const StyledButtonsContainer = styled.div`
+  display: flex;
+  flex-direction: row;
+`;
+
+const StyledAlertIcon = styled(Icon)`
+  color: ${({ theme }) => theme.colors.alert.base};
+  margin-right: ${({ theme }) => theme.gridUnit * 3}px;
+`;
+
+export interface ConfirmationAlertProps {
+  title: string;
+  children: React.ReactNode;
+  onConfirm: () => void;
+  onDismiss: () => void;
+}
+
+export function CancelConfirmationAlert({
+  title,
+  onConfirm,
+  onDismiss,
+  children,
+}: ConfirmationAlertProps) {
+  return (
+    <StyledAlert bsStyle="warning" key="alert">
+      <StyledTextContainer>
+        <StyledTitleBox>
+          <StyledAlertIcon name="alert-solid" />
+          <StyledAlertTitle>{title}</StyledAlertTitle>
+        </StyledTitleBox>
+        <StyledAlertText>{children}</StyledAlertText>
+      </StyledTextContainer>
+      <StyledButtonsContainer>
+        <Button
+          key="submit"
+          buttonSize="small"
+          buttonStyle="primary"
+          onClick={onConfirm}
+        >
+          {t('Yes, cancel')}
+        </Button>
+        <Button
+          key="cancel"
+          buttonSize="small"
+          buttonStyle="secondary"
+          onClick={onDismiss}
+        >
+          {t('Keep editing')}
+        </Button>
+      </StyledButtonsContainer>
+    </StyledAlert>
+  );
+}
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterConfigModal.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterConfigModal.tsx
index 40a644a..2be67db 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterConfigModal.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterConfigModal.tsx
@@ -31,6 +31,7 @@ import ErrorBoundary from 'src/components/ErrorBoundary';
 import { useFilterConfigMap, useFilterConfiguration } from './state';
 import FilterConfigForm from './FilterConfigForm';
 import { FilterConfiguration, NativeFiltersForm } from './types';
+import { CancelConfirmationAlert } from './CancelConfirmationAlert';
 
 // how long to show the "undo" button when removing a filter
 const REMOVAL_DELAY_SECS = 5;
@@ -175,6 +176,8 @@ export function FilterConfigModal({
     Record<string, FilterRemoval>
   >({});
 
+  const [saveAlertVisible, setSaveAlertVisible] = useState<boolean>(false);
+
   // brings back a filter that was previously removed ("Undo")
   const restoreFilter = useCallback(
     (id: string) => {
@@ -232,6 +235,7 @@ export function FilterConfigModal({
     const newFilterId = generateFilterId();
     setNewFilterIds([...newFilterIds, newFilterId]);
     setCurrentFilterId(newFilterId);
+    setSaveAlertVisible(false);
   }, [newFilterIds, setCurrentFilterId]);
 
   // if this is a "create" modal rather than an "edit" modal,
@@ -249,6 +253,7 @@ export function FilterConfigModal({
     setNewFilterIds([]);
     setCurrentFilterId(getInitialCurrentFilterId());
     setRemovedFilters({});
+    setSaveAlertVisible(false);
   }, [form, getInitialCurrentFilterId]);
 
   const completeFilterRemoval = (filterId: string) => {
@@ -273,6 +278,7 @@ export function FilterConfigModal({
         ...removedFilters,
         [filterId]: { isPending: true, timerId },
       }));
+      setSaveAlertVisible(false);
     } else if (action === 'add') {
       addFilter();
     }
@@ -418,11 +424,63 @@ export function FilterConfigModal({
     validateForm,
   ]);
 
-  const handleCancel = () => {
+  const confirmCancel = () => {
     resetForm();
     onCancel();
   };
 
+  const unsavedFiltersIds = newFilterIds.filter(id => !removedFilters[id]);
+
+  const getUnsavedFilterNames = (): string => {
+    const unsavedFiltersNames = unsavedFiltersIds.map(
+      id => `"${getFilterTitle(id)}"`,
+    );
+
+    if (unsavedFiltersNames.length === 0) {
+      return '';
+    }
+
+    if (unsavedFiltersNames.length === 1) {
+      return unsavedFiltersNames[0];
+    }
+
+    const lastFilter = unsavedFiltersNames.pop();
+
+    return `${unsavedFiltersNames.join(', ')} ${t('and')} ${lastFilter}`;
+  };
+
+  const handleCancel = () => {
+    if (unsavedFiltersIds.length > 0) {
+      setSaveAlertVisible(true);
+    } else {
+      confirmCancel();
+    }
+  };
+
+  const renderFooterElements = (): React.ReactNode[] => {
+    if (saveAlertVisible) {
+      return [
+        <CancelConfirmationAlert
+          title={`${unsavedFiltersIds.length} ${t('unsaved filters')}`}
+          onConfirm={confirmCancel}
+          onDismiss={() => setSaveAlertVisible(false)}
+        >
+          {t(`Are you sure you want to cancel?`)} {getUnsavedFilterNames()}{' '}
+          {t(`will not be saved.`)}
+        </CancelConfirmationAlert>,
+      ];
+    }
+
+    return [
+      <Button key="cancel" buttonStyle="secondary" onClick={handleCancel}>
+        {t('Cancel')}
+      </Button>,
+      <Button key="submit" buttonStyle="primary" onClick={onOk}>
+        {t('Save')}
+      </Button>,
+    ];
+  };
+
   return (
     <StyledModal
       visible={isOpen}
@@ -432,14 +490,7 @@ export function FilterConfigModal({
       onOk={onOk}
       centered
       data-test="filter-modal"
-      footer={[
-        <Button key="cancel" buttonStyle="secondary" onClick={handleCancel}>
-          {t('Cancel')}
-        </Button>,
-        <Button key="submit" buttonStyle="primary" onClick={onOk}>
-          {t('Save')}
-        </Button>,
-      ]}
+      footer={renderFooterElements()}
     >
       <ErrorBoundary>
         <StyledModalBody>
@@ -455,6 +506,7 @@ export function FilterConfigModal({
                 // we only need to set this if a name changed
                 setFormValues(values);
               }
+              setSaveAlertVisible(false);
             }}
             layout="vertical"
           >


[superset] 31/38: chore(viz): bump superset-ui packages to 0.16.9 (#12632)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit d8a7d83a06233941e8154d3516a1f3bcbab5dc63
Author: Ville Brofeldt <33...@users.noreply.github.com>
AuthorDate: Thu Jan 21 13:50:47 2021 +0200

    chore(viz): bump superset-ui packages to 0.16.9 (#12632)
---
 superset-frontend/package-lock.json | 236 ++++++++++++++++++------------------
 superset-frontend/package.json      |  52 ++++----
 2 files changed, 144 insertions(+), 144 deletions(-)

diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json
index 68cf991..2bd8b2b 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -18534,9 +18534,9 @@
       }
     },
     "@superset-ui/chart-controls": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/chart-controls/-/chart-controls-0.16.7.tgz",
-      "integrity": "sha512-Fh54+ra6QLsdg6b0xk8dKSNMNPRHGsTmSbSnbCLTQpolMXIMfsYV+ll1Y8TwLvfio9u0sLFyMk2PZqG1/L5Hhg==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/chart-controls/-/chart-controls-0.16.9.tgz",
+      "integrity": "sha512-GTwnJx5AhiYqwed3F3FCz+8Yuc56jlLM/g872zoHYQUejnAXGs/Iomeznga6+281DKfsbCO6ptH6qiOZYDH8PA==",
       "requires": {
         "@superset-ui/core": "0.16.7",
         "lodash": "^4.17.15",
@@ -18626,11 +18626,11 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-calendar": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-calendar/-/legacy-plugin-chart-calendar-0.16.7.tgz",
-      "integrity": "sha512-hu+rqNVWdWNwFhkhzSGHRbxIo/JQgWosK1bQBWkaD02r+HwvCszG6euYz+3pBEd0TpdrrkhSV05oYx0GIOgLdQ==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-calendar/-/legacy-plugin-chart-calendar-0.16.9.tgz",
+      "integrity": "sha512-8SbUVhuyXYB4Jh4ucFEonhWwF9/rEVOmR/E28bfS3dVJ3lChRx2T8ijv0pRxXNuPSl619Qm61/ec4637V7I//g==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "d3-array": "^2.0.3",
         "d3-selection": "^1.4.0",
@@ -18646,11 +18646,11 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-chord": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-chord/-/legacy-plugin-chart-chord-0.16.7.tgz",
-      "integrity": "sha512-5oFgijHXw2hlRskkPUVcKBhx4B0L8v+T4hP6TZ7zMUs6mRQrMPevYI21JFV5DvH7qN6Tlnij03UKWSsOLTVWEQ==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-chord/-/legacy-plugin-chart-chord-0.16.9.tgz",
+      "integrity": "sha512-QK3yJLDzkrIDYAfvAXmZI/nms0fl54WPSQlEN42e17IRe8Z/UNMd7Un4IyAEPjNJqt53uBJq5CEKIBAIB2eTng==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "prop-types": "^15.6.2",
@@ -18658,11 +18658,11 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-country-map": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-country-map/-/legacy-plugin-chart-country-map-0.16.7.tgz",
-      "integrity": "sha512-8kaBjj+HTRlqccrnimhj8PqOpoPvzo39d3tjhNR5hv9amxCVS23e5YxuAIXj0e8RO9mRK0uLGJA5vLKtDmCPfA==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-country-map/-/legacy-plugin-chart-country-map-0.16.9.tgz",
+      "integrity": "sha512-h58JI45Gg/Y7FQEY3v6Wsh07XvYSrH88d+6MJN0Iv72nv9X2iC5h9QVyN0M0jYDpqnfMkoPzsP90Ana8pYqjCw==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "d3-array": "^2.0.3",
@@ -18677,33 +18677,33 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-event-flow": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-event-flow/-/legacy-plugin-chart-event-flow-0.16.7.tgz",
-      "integrity": "sha512-h9FzN/ZUuVLzNhlG8npSHHu9pWLs9cSKnDCiCRqiR8qIklnCB1SBCezaNvjk2QnT17yTvEB48+Tu7TFMLZ5vlw==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-event-flow/-/legacy-plugin-chart-event-flow-0.16.9.tgz",
+      "integrity": "sha512-FWaaXmZXaslb0XlJS3xRcZlFpvGcWtNlGc4x01jrW8vSUzZ16wnQqqPO7b46K6LDJYfgaglXEzNK4gwPWLHKoA==",
       "requires": {
         "@data-ui/event-flow": "^0.0.84",
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "prop-types": "^15.6.2"
       }
     },
     "@superset-ui/legacy-plugin-chart-force-directed": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-force-directed/-/legacy-plugin-chart-force-directed-0.16.7.tgz",
-      "integrity": "sha512-Uns5lvgO+Q9LMV7xpBcFVUhB4WivlWaRpeZnfcc6PMDhNBFG6ahRsYfz+a8xO1VB0Qsqlr5XC/cK40cUlcTjhQ==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-force-directed/-/legacy-plugin-chart-force-directed-0.16.9.tgz",
+      "integrity": "sha512-2kryYHT1HqzpYLXkMW5ocCVEJ57K1zGII6mP+piIhqkEgzfSUL1+mUjfzUypuvc+zpKOuWiDxaGwVJqE8gGSbA==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "prop-types": "^15.7.2"
       }
     },
     "@superset-ui/legacy-plugin-chart-heatmap": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-heatmap/-/legacy-plugin-chart-heatmap-0.16.7.tgz",
-      "integrity": "sha512-XsYlfpPD1kRbt/2VgORu2M0Z2cOzDz1uIxj4yh3LxhA7FPAHzv1RXalOSs3HhxZNhwPbwd4dmyESmIBhhKWJSg==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-heatmap/-/legacy-plugin-chart-heatmap-0.16.9.tgz",
+      "integrity": "sha512-sw1/gOzAyZq6ki7ZocM9KH6BfYuT/yO2zfxW8OMB/8HeMVrM2gPkljSgIX6GYwY5Y83g3ZI+dVPXcp0HNTR0yQ==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "d3-svg-legend": "^1.x",
@@ -18712,13 +18712,13 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-histogram": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-histogram/-/legacy-plugin-chart-histogram-0.16.7.tgz",
-      "integrity": "sha512-QX2e6A0xNbnEhWzJxJNCXEQHyfTNcZCQZ3YaiNdR21DmEAkVxOe7cp45QETOJ+AMVOTOpQgbD8u7Hw129IqxUg==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-histogram/-/legacy-plugin-chart-histogram-0.16.9.tgz",
+      "integrity": "sha512-8g4NXTxRjojIntF/ovDoXKaDws/cg6G4CHtll3fLmr85eXSvJATtYODF+KsjefBmGmfIXNUr0kdIPAjfyprizA==",
       "requires": {
         "@data-ui/histogram": "^0.0.84",
         "@data-ui/theme": "^0.0.84",
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "@vx/legend": "^0.0.198",
         "@vx/responsive": "^0.0.197",
@@ -18787,11 +18787,11 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-horizon": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-horizon/-/legacy-plugin-chart-horizon-0.16.7.tgz",
-      "integrity": "sha512-3VMcLQhzhm5YFcykVDgyJ5RmFur+rMnZ3iYn++vTAapZ+RjW2NwAta0PGusJvUbNdmf4EpEb5fN7s0ev4wa6/Q==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-horizon/-/legacy-plugin-chart-horizon-0.16.9.tgz",
+      "integrity": "sha512-l5uCO0w1cCcMeI5lJtwhOLZO1509Fj+OCZuvsRCe/pjMncwH8tAwxVljGZ54YLLIWi9Dqo1WFQvA2BLsjQcv6w==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "d3-array": "^2.0.3",
         "d3-scale": "^3.0.1",
@@ -18818,11 +18818,11 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-map-box": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-map-box/-/legacy-plugin-chart-map-box-0.16.7.tgz",
-      "integrity": "sha512-MAd4tsUZYPj+KGGohd5Tz3gwbhh/0SRHy5EeovZt9zND1D/M0K/eU3fra6XU0Bw2duOUyIr+Dd3OzTaXUvTRPA==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-map-box/-/legacy-plugin-chart-map-box-0.16.9.tgz",
+      "integrity": "sha512-cf7QdN64rAo4UAmzirhHcJMO7IBYvMX+Slu7/LsCX4CnrVmJtO4d+vGFlNS5FaWU+t2A6lVH5QDpSI1WBgcfAA==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "immutable": "^3.8.2",
         "mapbox-gl": "^0.53.0",
@@ -18840,11 +18840,11 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-paired-t-test": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-paired-t-test/-/legacy-plugin-chart-paired-t-test-0.16.7.tgz",
-      "integrity": "sha512-sDt1DQaFKs4YX7DF9n+kbui18wDZOuYpPWA9QcBgHUbSKDaX26knBeD43JUGVaqMc8NmYVO6bVNBgoB8PrU89w==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-paired-t-test/-/legacy-plugin-chart-paired-t-test-0.16.9.tgz",
+      "integrity": "sha512-YEVJtqn25SWLr0N33BHzm5CjAOuSkwkOrxl05Lmceyf2z2PwHhrCnnLWXRzEEszQ9IXTsbKT8HYJtPkKNFVIWw==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "distributions": "^1.0.0",
         "prop-types": "^15.6.2",
@@ -18852,22 +18852,22 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-parallel-coordinates": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-parallel-coordinates/-/legacy-plugin-chart-parallel-coordinates-0.16.7.tgz",
-      "integrity": "sha512-TcIHSKvaA2Lt2LVIbSqoyTAMOekh720LPPh3KnqmfnwvA98YAHZl2tyAueIZ4jcbFVd8PVaNiaQbfKnQbS2Xpw==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-parallel-coordinates/-/legacy-plugin-chart-parallel-coordinates-0.16.9.tgz",
+      "integrity": "sha512-zX6uToyBEV5fKh+cpELDQ+xD9c+TtAGqKsc7r1mpY/R2Vfzw7oD5aOrwcxBshtMoJxx72jo9EuC5nzgNQf4+ug==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "prop-types": "^15.7.2"
       }
     },
     "@superset-ui/legacy-plugin-chart-partition": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-partition/-/legacy-plugin-chart-partition-0.16.7.tgz",
-      "integrity": "sha512-n4s/lHo7sV/ZRyQJJgannpCJ+IT/YalMRpkN7Ei2uXAvO3MLQVYZVwokZ0pEwpvihQSuOpHlqcwh8aDBm2gpeA==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-partition/-/legacy-plugin-chart-partition-0.16.9.tgz",
+      "integrity": "sha512-OEmirurMTPAInqMEjGkMQqJDUsM0TMJ4OCFaJ2vtwbvlwk3Fgar/fm/m/qhaLzDLXfTIgb6TyUkxiBCWmmF0iA==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "d3-hierarchy": "^1.1.8",
@@ -18875,11 +18875,11 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-pivot-table": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-pivot-table/-/legacy-plugin-chart-pivot-table-0.16.7.tgz",
-      "integrity": "sha512-BIQfZDIF/3WAH69wwW1ew9G8V9/GKSp5obbLGG5eXVGF6Aq0UyJmwyeVLcNcdcEW36UhhUjbHZLEOSs5LQP92Q==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-pivot-table/-/legacy-plugin-chart-pivot-table-0.16.9.tgz",
+      "integrity": "sha512-gpEXyC/WlBVeRD2INPx1IfOi3QwmPkr9bdwLfhXe34xU620uj85jO8VKlSU+tGppiyZz6aNaC2WBU4nTRRXUgg==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "datatables.net-bs": "^1.10.15",
@@ -18887,11 +18887,11 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-rose": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-rose/-/legacy-plugin-chart-rose-0.16.7.tgz",
-      "integrity": "sha512-0k0ydm8GVnMdfLPbWhuHegoIJNnuY690DPG9qeha0o9rGJ5GA2T91hE87tMM58D/EFUwRtjy0Zo5+DHATeFrHQ==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-rose/-/legacy-plugin-chart-rose-0.16.9.tgz",
+      "integrity": "sha512-T6amU5vtlyjohI065OBmLktNW4aNmVsh8UAxSOzKJBRyVDSk0cs1Ntb6FG6jNZLxe7AYh0YVmnYeLI9IVLs2VA==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "nvd3": "1.8.6",
@@ -18899,11 +18899,11 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-sankey": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey/-/legacy-plugin-chart-sankey-0.16.7.tgz",
-      "integrity": "sha512-sAsc7E7ha4q3SkuwnjS7jWhn4YEyzbZUA0Ryb6u5Kc/2PqPKtvT+ViF+bZUDvpoSdwxmgiLrYSWk5GtBhLkLHQ==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey/-/legacy-plugin-chart-sankey-0.16.9.tgz",
+      "integrity": "sha512-Vkauo64wsuRMznDtpqHWPrP6vohnm119wUlWPYk2y9/0e1PgowlRyv6X0RUqWyk2z4/eUXIzGj5YUebqniYjtA==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "d3-sankey": "^0.4.2",
@@ -18911,11 +18911,11 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-sankey-loop": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey-loop/-/legacy-plugin-chart-sankey-loop-0.16.7.tgz",
-      "integrity": "sha512-L3l3OGpfLxHkb+St/6WBtsjg+F0kAJlrmg/fuaHEzeA0EV50Og8y0h5RrbyyWTNueiosTfqtVgX2fMGFoHPN0w==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey-loop/-/legacy-plugin-chart-sankey-loop-0.16.9.tgz",
+      "integrity": "sha512-LtnVsvnoNTrHrOoZcdCuzYX/akCsaiMvWG53KoQis9dsu9+vc4xfKySw0Dct/QpGU+904YbGfFX9qDzh+RCsyw==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "d3-sankey-diagram": "^0.7.3",
         "d3-selection": "^1.4.0",
@@ -18923,22 +18923,22 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-sunburst": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sunburst/-/legacy-plugin-chart-sunburst-0.16.7.tgz",
-      "integrity": "sha512-VQeuisMTPZRaQjiXimoSAuNYu5YFBVyQaovvqCxe1jmyGSWA7hIHFqLMimZxCVZv3AMd4Qwb/9/wQkFJwLRxxA==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sunburst/-/legacy-plugin-chart-sunburst-0.16.9.tgz",
+      "integrity": "sha512-DTOuXy7fPUvwUM8WjiKGmbydcIynAbXlEGdmi/ObLlh4lACaTPCX8IOGc18eJP0G78pxeXpByK9JoEZuCbQyEA==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "prop-types": "^15.6.2"
       }
     },
     "@superset-ui/legacy-plugin-chart-treemap": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-treemap/-/legacy-plugin-chart-treemap-0.16.7.tgz",
-      "integrity": "sha512-LKseexUjopJA5Wm2rCkpjG/kClVsDwlCpOY4SHnN4EeOq2jMi2z9U+aomVj3HAWmjLvgVdO/nY9uOJq4MSV/3g==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-treemap/-/legacy-plugin-chart-treemap-0.16.9.tgz",
+      "integrity": "sha512-P+IQYjaMrmN2RqmIEJ2V3w8UQG6jxLPGgmsK/KkGMCzl8PAJJtPcRZw2Z/9JGh8u/7B70JCAEL+sRcLQCA/aTQ==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "d3-hierarchy": "^1.1.8",
         "d3-selection": "^1.4.0",
@@ -18946,11 +18946,11 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-world-map": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-world-map/-/legacy-plugin-chart-world-map-0.16.7.tgz",
-      "integrity": "sha512-c77CKfUtXCf9I5A87cYhxxuOGdBQS9oLNKYWWmV7bFRIKIGm6U2BsmSbFQ3sjRbgZTolrS4g7vJ51dkH3CzwoA==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-world-map/-/legacy-plugin-chart-world-map-0.16.9.tgz",
+      "integrity": "sha512-PtYzSKgiaInMt5NYyAmG4b6acffYvN1W8hetpq8TpeMkhuLzA69D3rsAj72ky/dgy5/n14t8wgdfKyfrrt9c6A==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "d3-array": "^2.4.0",
@@ -18972,12 +18972,12 @@
       }
     },
     "@superset-ui/legacy-preset-chart-big-number": {
-      "version": "0.16.8",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-big-number/-/legacy-preset-chart-big-number-0.16.8.tgz",
-      "integrity": "sha512-f34LNQBFFakxGleerh6nrHg/0V8Rf7IVxGaDc7IgQcj9Yb3Zoy0vYXoyn6VLBkfKVg1TmsxtuBT9Xf7tV6FNuQ==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-big-number/-/legacy-preset-chart-big-number-0.16.9.tgz",
+      "integrity": "sha512-Iby3rNcdv+cVy1A/I/Lg/n76v71JdPxKJJc+A4YUil3SalmFFo4mxm0glrX9dex6IYxpZMWbDJKgnHEbhalXlw==",
       "requires": {
         "@data-ui/xy-chart": "^0.0.84",
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "@types/d3-color": "^1.2.2",
         "@types/shortid": "^0.0.29",
@@ -19011,12 +19011,12 @@
       }
     },
     "@superset-ui/legacy-preset-chart-nvd3": {
-      "version": "0.16.8",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-nvd3/-/legacy-preset-chart-nvd3-0.16.8.tgz",
-      "integrity": "sha512-n9X/MmIFK6TykgddfQOV1tlWUq7cZfkrIRn/0ZmDKTJi614Kz/8Vq1HUc9ei0iNes9BkK6gaJ07gaaHUGHuGRg==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-nvd3/-/legacy-preset-chart-nvd3-0.16.9.tgz",
+      "integrity": "sha512-wfbVZOGqIk/IFUnzW0k44t9N/iHd0VoJzHT6wwM+GgGcCm5mizBDWot9Zuu4U1gf1KLfKUD7/lwEEtyCrs2zXw==",
       "requires": {
         "@data-ui/xy-chart": "^0.0.84",
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "d3-tip": "^0.9.1",
@@ -19031,11 +19031,11 @@
       }
     },
     "@superset-ui/plugin-chart-echarts": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-echarts/-/plugin-chart-echarts-0.16.7.tgz",
-      "integrity": "sha512-w2T2HuBYTHfFV8oBkz+Gxjl5mYSJ92RjwVqV08dUGuf86LSdDhyXsfpFKq+j+u8dOyyxQp18Nid0Mlxy+F6V2w==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-echarts/-/plugin-chart-echarts-0.16.9.tgz",
+      "integrity": "sha512-MC1eEq3BLedRR+tL88BnisSUkqBxAi4t79JuGY2q9Lgg+7yh1wgD6bqKkR8JaH3SdqSK2XpG0dPkjHZXqFpkMQ==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "@types/echarts": "^4.6.3",
         "@types/mathjs": "^6.0.7",
@@ -19044,12 +19044,12 @@
       }
     },
     "@superset-ui/plugin-chart-table": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-table/-/plugin-chart-table-0.16.7.tgz",
-      "integrity": "sha512-P5oedAqAcM0Z3Pgv4v4eEIjYCz/Sk/aWjKqTWxDFEOdavjGH0FxpTW4TquC13slGKWP7U4ddf1/bx73nH0K+XA==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-table/-/plugin-chart-table-0.16.9.tgz",
+      "integrity": "sha512-SA6ypwoJq1A9nG/xaI+xRhSRG34omNakgNv3vgeBqCYuZLHwSCf+a/c7liwAA9PhlSTNB7CuOZHC542SVSe6ZQ==",
       "requires": {
         "@emotion/core": "^10.0.28",
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "@types/d3-array": "^2.0.0",
         "@types/match-sorter": "^4.0.0",
@@ -19071,11 +19071,11 @@
       }
     },
     "@superset-ui/plugin-chart-word-cloud": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-word-cloud/-/plugin-chart-word-cloud-0.16.7.tgz",
-      "integrity": "sha512-BvVAA2tT0zFQwJimY0tHqic/a96w+3+htILV4mE+D5ZIu8/PjhTepBfWzcXTt6MxXL7jxRmGZ12dPn0ZIU5auw==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-word-cloud/-/plugin-chart-word-cloud-0.16.9.tgz",
+      "integrity": "sha512-NWbPAqxxF8V16xH3jxhhJu9HAoU9BWRZktvhKePQeAtFrGZQ79nQzU+tHYivWvVmjn2bcfhg3D5V5rJwysN9Uw==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "@types/d3-cloud": "^1.2.1",
         "@types/d3-scale": "^2.0.2",
@@ -19105,13 +19105,13 @@
       }
     },
     "@superset-ui/preset-chart-xy": {
-      "version": "0.16.7",
-      "resolved": "https://registry.npmjs.org/@superset-ui/preset-chart-xy/-/preset-chart-xy-0.16.7.tgz",
-      "integrity": "sha512-T6GqBfLizO2CooWRoM0bGbIbVFHCLGYK/NkRyMtmZ1B/UEt7ldOBjzj+qtvHNZfb65K5CF7WLMEeK/X/hOxxNw==",
+      "version": "0.16.9",
+      "resolved": "https://registry.npmjs.org/@superset-ui/preset-chart-xy/-/preset-chart-xy-0.16.9.tgz",
+      "integrity": "sha512-hWIuTVcpVINXAlCSEDKKRWiAatx/d15pFmMaaZC7NzpQJ2XfZC6jpCmwgSxbvhbezbduQhwU7DViNINbg2XoZg==",
       "requires": {
         "@data-ui/theme": "^0.0.84",
         "@data-ui/xy-chart": "^0.0.84",
-        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/chart-controls": "0.16.9",
         "@superset-ui/core": "0.16.7",
         "@vx/axis": "^0.0.198",
         "@vx/legend": "^0.0.198",
@@ -28498,18 +28498,18 @@
       }
     },
     "echarts": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.0.0.tgz",
-      "integrity": "sha512-6SDcJbLVOcfQyjPg+spNU1+JVrkU1B9fzUa5tpbP/mMNUPyigCOJwcEIQAJSbp9jt5UP3EXvQR0vtYXIo9AjyA==",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.0.1.tgz",
+      "integrity": "sha512-JYn22Dolt2esY2jEzUsw1OxbobuW67oGjIoTjZO3rW89SWkfJ4kbrmC2OW9JjsBrD1rdkmaWBuZZ2HgmThyxJw==",
       "requires": {
-        "tslib": "1.10.0",
-        "zrender": "5.0.1"
+        "tslib": "2.0.3",
+        "zrender": "5.0.3"
       },
       "dependencies": {
         "tslib": {
-          "version": "1.10.0",
-          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
-          "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ=="
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
         }
       }
     },
@@ -54336,17 +54336,17 @@
       }
     },
     "zrender": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.0.1.tgz",
-      "integrity": "sha512-i8FNCKAKfF0EfZFJ6w2p30umBrCyy481/PePFQqPdtNgCl5Hp5z7/dovqb7soEoFkhNvhjJ/J4W9zFALeae6yA==",
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.0.3.tgz",
+      "integrity": "sha512-TVcN2IMdo7je3GEq/E4CER4AGBe/n50/izILdupppyHf/hVHuiXCRliqdu8+32Z1OmGg6RfKt5qQlkX+bOtU0g==",
       "requires": {
-        "tslib": "1.10.0"
+        "tslib": "2.0.3"
       },
       "dependencies": {
         "tslib": {
-          "version": "1.10.0",
-          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
-          "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ=="
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+          "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
         }
       }
     },
diff --git a/superset-frontend/package.json b/superset-frontend/package.json
index 65ca3f0..c13d59d 100644
--- a/superset-frontend/package.json
+++ b/superset-frontend/package.json
@@ -65,34 +65,34 @@
     "@babel/runtime-corejs3": "^7.12.5",
     "@data-ui/sparkline": "^0.0.84",
     "@emotion/core": "^10.0.35",
-    "@superset-ui/chart-controls": "^0.16.7",
+    "@superset-ui/chart-controls": "^0.16.9",
     "@superset-ui/core": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-calendar": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-chord": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-country-map": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-event-flow": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-force-directed": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-heatmap": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-histogram": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-horizon": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-map-box": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-paired-t-test": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-parallel-coordinates": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-partition": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-pivot-table": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-rose": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-sankey": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-sankey-loop": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-sunburst": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-treemap": "^0.16.7",
-    "@superset-ui/legacy-plugin-chart-world-map": "^0.16.7",
-    "@superset-ui/legacy-preset-chart-big-number": "^0.16.8",
+    "@superset-ui/legacy-plugin-chart-calendar": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-chord": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-country-map": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-event-flow": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-force-directed": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-heatmap": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-histogram": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-horizon": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-map-box": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-paired-t-test": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-parallel-coordinates": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-partition": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-pivot-table": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-rose": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-sankey": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-sankey-loop": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-sunburst": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-treemap": "^0.16.9",
+    "@superset-ui/legacy-plugin-chart-world-map": "^0.16.9",
+    "@superset-ui/legacy-preset-chart-big-number": "^0.16.9",
     "@superset-ui/legacy-preset-chart-deckgl": "^0.4.1",
-    "@superset-ui/legacy-preset-chart-nvd3": "^0.16.8",
-    "@superset-ui/plugin-chart-echarts": "^0.16.7",
-    "@superset-ui/plugin-chart-table": "^0.16.7",
-    "@superset-ui/plugin-chart-word-cloud": "^0.16.7",
-    "@superset-ui/preset-chart-xy": "^0.16.7",
+    "@superset-ui/legacy-preset-chart-nvd3": "^0.16.9",
+    "@superset-ui/plugin-chart-echarts": "^0.16.9",
+    "@superset-ui/plugin-chart-table": "^0.16.9",
+    "@superset-ui/plugin-chart-word-cloud": "^0.16.9",
+    "@superset-ui/preset-chart-xy": "^0.16.9",
     "@vx/responsive": "^0.0.195",
     "abortcontroller-polyfill": "^1.1.9",
     "antd": "^4.9.4",


[superset] 20/38: corrected typo in connections index in the documentation (#12577)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 0fc2bc5f02454b0aac06ac2e08b24b5d787c3aa3
Author: Radhika <56...@users.noreply.github.com>
AuthorDate: Tue Jan 19 12:03:41 2021 +0530

    corrected typo in connections index in the documentation (#12577)
---
 docs/src/pages/docs/Connecting to Databases/index.mdx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/src/pages/docs/Connecting to Databases/index.mdx b/docs/src/pages/docs/Connecting to Databases/index.mdx
index 493fc30..629d19b 100644
--- a/docs/src/pages/docs/Connecting to Databases/index.mdx	
+++ b/docs/src/pages/docs/Connecting to Databases/index.mdx	
@@ -46,7 +46,7 @@ A list of some of the recommended packages.
 |[PostgreSQL](/docs/databases/postgresql)|```pip install psycopg2```|```postgresql://<UserName>:<DBPassword>@<Database Host>/<Database Name>```|
 |[Presto](/docs/databases/presto)|```pip install pyhive```|```presto://```|
 |[SAP Hana](/docs/databases/hana)|```pip install hdbcli sqlalchemy-hana or pip install apache-superset[hana]```|```hana://{username}:{password}@{host}:{port}```|
-|[Snowflake](/docs/databases/snowflake)|```pip install snowflake-sqlalchemy```|```ssnowflake://{user}:{password}@{account}.{region}/{database}?role={role}&warehouse={warehouse}```|
+|[Snowflake](/docs/databases/snowflake)|```pip install snowflake-sqlalchemy```|```snowflake://{user}:{password}@{account}.{region}/{database}?role={role}&warehouse={warehouse}```|
 |SQLite||```sqlite://```|
 |[SQL Server](/docs/databases/sqlserver)|```pip install pymssql```|```mssql://```|
 |[Teradata](/docs/databases/teradata)|```pip install sqlalchemy-teradata```|```teradata://{user}:{password}@{host}```|


[superset] 11/38: fix(explore): Disable saved metric name edit in Metric popover (#12582)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit e4453a77f7da32254746f81ac10a7e713ca4fdf3
Author: Kamil Gabryjelski <ka...@gmail.com>
AuthorDate: Tue Jan 19 21:28:55 2021 +0100

    fix(explore): Disable saved metric name edit in Metric popover (#12582)
---
 .../integration/explore/AdhocMetrics.test.ts       |  3 +
 .../explore/visualizations/line.test.ts            |  4 ++
 .../AdhocMetricEditPopoverTitle_spec.jsx           | 16 ++++-
 .../MetricControl/AdhocMetricEditPopover.jsx       | 73 +++++++++++++---------
 .../MetricControl/AdhocMetricEditPopoverTitle.jsx  | 21 +++++--
 .../MetricControl/AdhocMetricPopoverTrigger.tsx    | 17 ++++-
 .../MetricControl/MetricDefinitionValue.jsx        |  2 +-
 .../controls/MetricControl/MetricsControl.jsx      |  6 +-
 8 files changed, 99 insertions(+), 43 deletions(-)

diff --git a/superset-frontend/cypress-base/cypress/integration/explore/AdhocMetrics.test.ts b/superset-frontend/cypress-base/cypress/integration/explore/AdhocMetrics.test.ts
index 79b153d..2f145de 100644
--- a/superset-frontend/cypress-base/cypress/integration/explore/AdhocMetrics.test.ts
+++ b/superset-frontend/cypress-base/cypress/integration/explore/AdhocMetrics.test.ts
@@ -37,6 +37,9 @@ describe('AdhocMetrics', () => {
       .find('[data-test="add-metric-button"]')
       .click();
 
+    // Title edit for saved metrics is disabled - switch to Simple
+    cy.get('[id="adhoc-metric-edit-tabs-tab-SIMPLE"]').click();
+
     cy.get('[data-test="AdhocMetricEditTitle#trigger"]').click();
     cy.get('[data-test="AdhocMetricEditTitle#input"]').type(metricName);
 
diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.test.ts b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.test.ts
index 94d295b..889428a 100644
--- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.test.ts
+++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.test.ts
@@ -50,6 +50,10 @@ describe('Visualization > Line', () => {
     cy.get('[data-test=metrics]')
       .find('[data-test="add-metric-button"]')
       .click();
+
+    // Title edit for saved metrics is disabled - switch to Simple
+    cy.get('[id="adhoc-metric-edit-tabs-tab-SIMPLE"]').click();
+
     cy.get('[name="select-column"]').click().type('num{enter}');
     cy.get('[name="select-aggregate"]').click().type('sum{enter}');
     cy.get('[data-test="AdhocMetricEdit#save"]').contains('Save').click();
diff --git a/superset-frontend/spec/javascripts/explore/components/AdhocMetricEditPopoverTitle_spec.jsx b/superset-frontend/spec/javascripts/explore/components/AdhocMetricEditPopoverTitle_spec.jsx
index be02d6b..3609950 100644
--- a/superset-frontend/spec/javascripts/explore/components/AdhocMetricEditPopoverTitle_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/AdhocMetricEditPopoverTitle_spec.jsx
@@ -46,15 +46,25 @@ describe('AdhocMetricEditPopoverTitle', () => {
     expect(wrapper.find(Tooltip)).toExist();
     expect(
       wrapper.find('[data-test="AdhocMetricEditTitle#trigger"]').text(),
-    ).toBe('My Metric\xa0');
+    ).toBe(`${title.label}\xa0`);
   });
 
   it('transfers to edit mode when clicked', () => {
     const { wrapper } = setup();
-    expect(wrapper.state('isEditable')).toBe(false);
+    expect(wrapper.state('isEditMode')).toBe(false);
     wrapper
       .find('[data-test="AdhocMetricEditTitle#trigger"]')
       .simulate('click');
-    expect(wrapper.state('isEditable')).toBe(true);
+    expect(wrapper.state('isEditMode')).toBe(true);
+  });
+
+  it('Render non-interactive span with title when edit is disabled', () => {
+    const { wrapper } = setup({ isEditDisabled: true });
+    expect(
+      wrapper.find('[data-test="AdhocMetricTitle"]').exists(),
+    ).toBeTruthy();
+    expect(
+      wrapper.find('[data-test="AdhocMetricEditTitle#trigger"]').exists(),
+    ).toBeFalsy();
   });
 });
diff --git a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover.jsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover.jsx
index bfe8391..ae39d18 100644
--- a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover.jsx
@@ -29,6 +29,7 @@ import { ColumnOption } from '@superset-ui/chart-controls';
 import FormLabel from 'src/components/FormLabel';
 import { SQLEditor } from 'src/components/AsyncAceEditor';
 import sqlKeywords from 'src/SqlLab/utils/sqlKeywords';
+import { noOp } from 'src/utils/common';
 
 import { AGGREGATES_OPTIONS } from 'src/explore/constants';
 import columnType from 'src/explore/propTypes/columnType';
@@ -40,6 +41,7 @@ const propTypes = {
   onChange: PropTypes.func.isRequired,
   onClose: PropTypes.func.isRequired,
   onResize: PropTypes.func.isRequired,
+  getCurrentTab: PropTypes.func,
   columns: PropTypes.arrayOf(columnType),
   savedMetrics: PropTypes.arrayOf(savedMetricType),
   savedMetric: savedMetricType,
@@ -52,6 +54,7 @@ const propTypes = {
 
 const defaultProps = {
   columns: [],
+  getCurrentTab: noOp,
 };
 
 const ResizeIcon = styled.i`
@@ -64,12 +67,20 @@ const ColumnOptionStyle = styled.span`
   }
 `;
 
-const SAVED_TAB_KEY = 'SAVED';
+export const SAVED_TAB_KEY = 'SAVED';
 
 const startingWidth = 320;
 const startingHeight = 240;
 
 export default class AdhocMetricEditPopover extends React.Component {
+  // "Saved" is a default tab unless there are no saved metrics for dataset
+  defaultActiveTabKey =
+    (this.props.savedMetric.metric_name || this.props.adhocMetric.isNew) &&
+    Array.isArray(this.props.savedMetrics) &&
+    this.props.savedMetrics.length > 0
+      ? SAVED_TAB_KEY
+      : this.props.adhocMetric.expressionType;
+
   constructor(props) {
     super(props);
     this.onSave = this.onSave.bind(this);
@@ -81,6 +92,7 @@ export default class AdhocMetricEditPopover extends React.Component {
     this.onDragDown = this.onDragDown.bind(this);
     this.onMouseMove = this.onMouseMove.bind(this);
     this.onMouseUp = this.onMouseUp.bind(this);
+    this.onTabChange = this.onTabChange.bind(this);
     this.handleAceEditorRef = this.handleAceEditorRef.bind(this);
     this.refreshAceEditor = this.refreshAceEditor.bind(this);
 
@@ -94,6 +106,10 @@ export default class AdhocMetricEditPopover extends React.Component {
     document.addEventListener('mouseup', this.onMouseUp);
   }
 
+  componentDidMount() {
+    this.props.getCurrentTab(this.defaultActiveTabKey);
+  }
+
   componentWillUnmount() {
     document.removeEventListener('mouseup', this.onMouseUp);
     document.removeEventListener('mousemove', this.onMouseMove);
@@ -207,6 +223,11 @@ export default class AdhocMetricEditPopover extends React.Component {
     document.removeEventListener('mousemove', this.onMouseMove);
   }
 
+  onTabChange(tab) {
+    this.refreshAceEditor();
+    this.props.getCurrentTab(tab);
+  }
+
   handleAceEditorRef(ref) {
     if (ref) {
       this.aceEditorRef = ref;
@@ -316,16 +337,33 @@ export default class AdhocMetricEditPopover extends React.Component {
         <Tabs
           id="adhoc-metric-edit-tabs"
           data-test="adhoc-metric-edit-tabs"
-          defaultActiveKey={
-            propsSavedMetric.metric_name
-              ? SAVED_TAB_KEY
-              : adhocMetric.expressionType
-          }
+          defaultActiveKey={this.defaultActiveTabKey}
           className="adhoc-metric-edit-tabs"
           style={{ height: this.state.height, width: this.state.width }}
-          onChange={this.refreshAceEditor}
+          onChange={this.onTabChange}
           allowOverflow
         >
+          <Tabs.TabPane key={SAVED_TAB_KEY} tab={t('Saved')}>
+            <FormGroup>
+              <FormLabel>
+                <strong>{t('Saved metric')}</strong>
+              </FormLabel>
+              <Select name="select-saved" {...savedSelectProps}>
+                {Array.isArray(savedMetrics) &&
+                  savedMetrics.map(savedMetric => (
+                    <Select.Option
+                      value={savedMetric.id}
+                      filterBy={
+                        savedMetric.verbose_name || savedMetric.metric_name
+                      }
+                      key={savedMetric.id}
+                    >
+                      {this.renderColumnOption(savedMetric)}
+                    </Select.Option>
+                  ))}
+              </Select>
+            </FormGroup>
+          </Tabs.TabPane>
           <Tabs.TabPane key={EXPRESSION_TYPES.SIMPLE} tab={t('Simple')}>
             <FormGroup>
               <FormLabel>
@@ -356,27 +394,6 @@ export default class AdhocMetricEditPopover extends React.Component {
               </Select>
             </FormGroup>
           </Tabs.TabPane>
-          <Tabs.TabPane key={SAVED_TAB_KEY} tab={t('Saved')}>
-            <FormGroup>
-              <FormLabel>
-                <strong>{t('Saved metric')}</strong>
-              </FormLabel>
-              <Select name="select-saved" {...savedSelectProps}>
-                {Array.isArray(savedMetrics) &&
-                  savedMetrics.map(savedMetric => (
-                    <Select.Option
-                      value={savedMetric.id}
-                      filterBy={
-                        savedMetric.verbose_name || savedMetric.metric_name
-                      }
-                      key={savedMetric.id}
-                    >
-                      {this.renderColumnOption(savedMetric)}
-                    </Select.Option>
-                  ))}
-              </Select>
-            </FormGroup>
-          </Tabs.TabPane>
           <Tabs.TabPane
             key={EXPRESSION_TYPES.SQL}
             tab={t('Custom SQL')}
diff --git a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopoverTitle.jsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopoverTitle.jsx
index 08eb9e8..4c2f3f4 100644
--- a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopoverTitle.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopoverTitle.jsx
@@ -17,6 +17,7 @@
  * under the License.
  */
 import React from 'react';
+import { t } from '@superset-ui/core';
 import PropTypes from 'prop-types';
 import { FormControl } from 'react-bootstrap';
 import { Tooltip } from 'src/common/components/Tooltip';
@@ -27,6 +28,7 @@ const propTypes = {
     hasCustomLabel: PropTypes.bool,
   }),
   onChange: PropTypes.func.isRequired,
+  isEditDisabled: PropTypes.bool,
 };
 
 export default class AdhocMetricEditPopoverTitle extends React.Component {
@@ -39,7 +41,7 @@ export default class AdhocMetricEditPopoverTitle extends React.Component {
     this.onInputBlur = this.onInputBlur.bind(this);
     this.state = {
       isHovered: false,
-      isEditable: false,
+      isEditMode: false,
     };
   }
 
@@ -52,11 +54,11 @@ export default class AdhocMetricEditPopoverTitle extends React.Component {
   }
 
   onClick() {
-    this.setState({ isEditable: true });
+    this.setState({ isEditMode: true });
   }
 
   onBlur() {
-    this.setState({ isEditable: false });
+    this.setState({ isEditMode: false });
   }
 
   onInputBlur(e) {
@@ -67,9 +69,16 @@ export default class AdhocMetricEditPopoverTitle extends React.Component {
   }
 
   render() {
-    const { title, onChange } = this.props;
+    const { title, onChange, isEditDisabled } = this.props;
+    const defaultLabel = t('My Metric');
 
-    return this.state.isEditable ? (
+    if (isEditDisabled) {
+      return (
+        <span data-test="AdhocMetricTitle">{title.label || defaultLabel}</span>
+      );
+    }
+
+    return this.state.isEditMode ? (
       <FormControl
         className="metric-edit-popover-label-input"
         type="text"
@@ -92,7 +101,7 @@ export default class AdhocMetricEditPopoverTitle extends React.Component {
           role="button"
           tabIndex={0}
         >
-          {title.hasCustomLabel ? title.label : 'My Metric'}
+          {title.label || defaultLabel}
           &nbsp;
           <i
             className="fa fa-pencil"
diff --git a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx
index 649d3fe..c5d0e92 100644
--- a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx
@@ -19,7 +19,9 @@
 import React, { ReactNode } from 'react';
 import Popover from 'src/common/components/Popover';
 import AdhocMetricEditPopoverTitle from 'src/explore/components/controls/MetricControl/AdhocMetricEditPopoverTitle';
-import AdhocMetricEditPopover from './AdhocMetricEditPopover';
+import AdhocMetricEditPopover, {
+  SAVED_TAB_KEY,
+} from './AdhocMetricEditPopover';
 import AdhocMetric from './AdhocMetric';
 import { savedMetricType } from './types';
 
@@ -38,6 +40,7 @@ export type AdhocMetricPopoverTriggerState = {
   popoverVisible: boolean;
   title: { label: string; hasCustomLabel: boolean };
   labelModified: boolean;
+  isTitleEditDisabled: boolean;
 };
 
 class AdhocMetricPopoverTrigger extends React.PureComponent<
@@ -57,6 +60,7 @@ class AdhocMetricPopoverTrigger extends React.PureComponent<
         hasCustomLabel: props.adhocMetric.hasCustomLabel,
       },
       labelModified: false,
+      isTitleEditDisabled: false,
     };
   }
 
@@ -89,11 +93,12 @@ class AdhocMetricPopoverTrigger extends React.PureComponent<
   }
 
   render() {
-    const { adhocMetric } = this.props;
+    const { adhocMetric, savedMetric } = this.props;
+    const { verbose_name, metric_name } = savedMetric;
     const { label, hasCustomLabel } = adhocMetric;
     const title = this.state.labelModified
       ? this.state.title
-      : { label, hasCustomLabel };
+      : { label: verbose_name || metric_name || label, hasCustomLabel };
 
     const overlayContent = (
       <AdhocMetricEditPopover
@@ -106,6 +111,11 @@ class AdhocMetricPopoverTrigger extends React.PureComponent<
         onResize={this.onPopoverResize}
         onClose={this.closePopover}
         onChange={this.props.onMetricEdit}
+        getCurrentTab={(tab: string) =>
+          this.setState({
+            isTitleEditDisabled: tab === SAVED_TAB_KEY,
+          })
+        }
       />
     );
 
@@ -113,6 +123,7 @@ class AdhocMetricPopoverTrigger extends React.PureComponent<
       <AdhocMetricEditPopoverTitle
         title={title}
         onChange={this.onLabelChange}
+        isEditDisabled={this.state.isTitleEditDisabled}
       />
     );
 
diff --git a/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionValue.jsx b/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionValue.jsx
index 5bae01d..30acfda 100644
--- a/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionValue.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionValue.jsx
@@ -62,7 +62,7 @@ export default function MetricDefinitionValue({
 
   if (option instanceof AdhocMetric || savedMetric) {
     const adhocMetric =
-      option instanceof AdhocMetric ? option : new AdhocMetric({});
+      option instanceof AdhocMetric ? option : new AdhocMetric({ isNew: true });
 
     const metricOptionProps = {
       onMetricEdit,
diff --git a/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx
index 83b5c16..7b7233f 100644
--- a/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx
@@ -191,7 +191,9 @@ class MetricsControl extends React.PureComponent {
             // compare saved metrics
             value === oldMetric.metric_name ||
             // compare adhoc metrics
-            value.optionName === oldMetric.optionName
+            typeof value.optionName !== 'undefined'
+              ? value.optionName === oldMetric.optionName
+              : false
           ) {
             return changedMetric;
           }
@@ -263,7 +265,7 @@ class MetricsControl extends React.PureComponent {
     }
     return (
       <AdhocMetricPopoverTrigger
-        adhocMetric={new AdhocMetric({})}
+        adhocMetric={new AdhocMetric({ isNew: true })}
         onMetricEdit={this.onNewMetric}
         columns={this.props.columns}
         savedMetrics={this.props.savedMetrics}


[superset] 01/38: fix: incorrect cursor position Firefox (#12423)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit bc1a2a2258a9cf5e01bdf1bf883e8132c2e55740
Author: Beto Dealmeida <ro...@dealmeida.net>
AuthorDate: Fri Jan 15 14:00:23 2021 -0800

    fix: incorrect cursor position Firefox (#12423)
    
    * fix: incorrect cursor position Firefox
    
    * Use different font
    
    * Fix lint
    
    * Use Lucida Console
---
 superset-frontend/src/SqlLab/main.less | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/superset-frontend/src/SqlLab/main.less b/superset-frontend/src/SqlLab/main.less
index 0b21fe5..d839faa 100644
--- a/superset-frontend/src/SqlLab/main.less
+++ b/superset-frontend/src/SqlLab/main.less
@@ -378,7 +378,9 @@ div.tablePopover {
   //double class is better than !important
   border: 1px solid @gray-light;
   font-feature-settings: @font-feature-settings;
-  font-family: @font-family-monospace;
+  // Fira Code causes problem with Ace under Firefox
+  font-family: 'Menlo', 'Lucida Console', 'Courier New', 'Ubuntu Mono',
+    'Consolas', 'source-code-pro', monospace;
 
   &.ace_autocomplete {
     // Use !important because Ace Editor applies extra CSS at the last second


[superset] 34/38: feat(chart): Add expression, description and verbose name to search filter (#12549)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 39e3b282923c814a8dd304fb05198c4a20dcc0f8
Author: Nikola Gigić <ni...@gmail.com>
AuthorDate: Mon Jan 18 18:38:19 2021 +0100

    feat(chart): Add expression, description and verbose name to search filter (#12549)
---
 superset-frontend/src/explore/components/DatasourcePanel.tsx | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/superset-frontend/src/explore/components/DatasourcePanel.tsx b/superset-frontend/src/explore/components/DatasourcePanel.tsx
index 9d47626..37ab1e9 100644
--- a/superset-frontend/src/explore/components/DatasourcePanel.tsx
+++ b/superset-frontend/src/explore/components/DatasourcePanel.tsx
@@ -180,8 +180,12 @@ const DataSourcePanel = ({
       return;
     }
     setList({
-      columns: matchSorter(columns, value, { keys: ['column_name'] }),
-      metrics: matchSorter(metrics, value, { keys: ['metric_name'] }),
+      columns: matchSorter(columns, value, {
+        keys: ['column_name', 'expression', 'description', 'verbose_name'],
+      }),
+      metrics: matchSorter(metrics, value, {
+        keys: ['metric_name', 'expression', 'description', 'verbose_name'],
+      }),
     });
   };
   useEffect(() => {


[superset] 36/38: chore: add capitalization guidelines to CONTRIBUTING.md (#12685)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit ca0c07722e7b44e6f3b5982f5d3ae48b4ea24ed3
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Fri Jan 22 20:47:55 2021 -0300

    chore: add capitalization guidelines to CONTRIBUTING.md (#12685)
---
 CONTRIBUTING.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b0670eb..280a212 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -41,6 +41,7 @@ little bit helps, and credit will always be given.
       - [Reviewing](#reviewing)
       - [Merging](#merging)
       - [Post-merge Responsibility](#post-merge-responsibility)
+  - [Capitalization Guidelines](#capitalization-guidelines)
   - [Managing Issues and PRs](#managing-issues-and-prs)
   - [Reporting a Security Vulnerability](#reporting-a-security-vulnerability)
   - [Revert Guidelines](#revert-guidelines)
@@ -247,6 +248,52 @@ Finally, never submit a PR that will put master branch in broken state. If the P
 - Project maintainers may contact the PR author if new issues are introduced by the PR.
 - Project maintainers may revert your changes if a critical issue is found, such as breaking master branch CI.
 
+## Capitalization Guidelines
+
+### Sentence case
+
+Use sentence-case capitalization for everything in the UI (except these \*\*).
+
+Sentence case is predominantly lowercase. Capitalize only the initial character of the first word, and other words that require capitalization, like:
+
+- Proper nouns. Objects in the product are not considered proper nouns e.g. dashboards, charts, saved queries etc. Proprietary feature names eg. SQL Lab, Preset Manager are considered proper nouns
+- Acronyms (e.g. CSS, HTML)
+- When referring to **UI labels that are themselves capitalized** from sentence case (e.g. page titles - Dashboards page, Charts page, Saved queries page, etc.)
+- User input that is reflected in the UI. E.g. a user-named a dashboard tab
+
+#### Sentence case vs. Title case:
+
+Title case: "A Dog Takes a Walk in Paris"
+Sentence case: "A dog takes a walk in Paris"
+
+#### Why sentence case?
+
+- It’s generally accepted as the quickest to read
+- It’s the easiest form to distinguish between common and proper nouns
+
+### How to refer to UI elements
+
+When writing about a UI element, use the same capitalization as used in the UI.
+
+For example, if an input field is labeled “Name” then you refer to this as the “Name input field”. Similarly, if a button has the label “Save” in it, then it is correct to refer to the “Save button”.
+
+Where a product page is titled “Settings”, you refer to this in writing as follows:
+“Edit your personal information on the Settings page”.
+
+Often a product page will have the same title as the objects it contains. In this case, refer to the page as it appears in the UI, and the objects as common nouns:
+
+- Upload a dashboard on the Dashboards page
+- Go to Dashboards
+- View dashboard
+- View all dashboards
+- Upload CSS templates on the CSS templates page
+- Queries that you save will appear on the Saved queries page
+- Create custom queries in SQL Lab then create dashboards
+
+### \*\*Exceptions to sentence case:
+
+- Input labels, buttons and tabs are all caps
+
 ## Managing Issues and PRs
 
 To handle issues and PRs that are coming in, committers read issues/PRs and flag them with labels to categorize and help contributors spot where to take actions, as contributors usually have different expertises.


[superset] 35/38: feat(explore): better search for dataset pane (#12675)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 8d80262bed8fdd7b76fb8d819bf20be150b18bb7
Author: Jesse Yang <je...@airbnb.com>
AuthorDate: Fri Jan 22 14:26:55 2021 -0800

    feat(explore): better search for dataset pane (#12675)
    
    1. Upgrade match-sorter from 4.1.0 to 6.1.0
    2. Add a debounce delay of 200 milliseconds to reduce excessive rendering (and searching)
    3. Set keepDiacritics to true to improve performance
    4. Display count of filtered results in "Showing x of xx", instead of the total results
    5. Rank certified metrics to the top
---
 superset-frontend/package-lock.json                | 25 ++++++++--
 superset-frontend/package.json                     |  2 +-
 .../src/explore/components/DatasourcePanel.tsx     | 58 ++++++++++++++++------
 superset-frontend/tsconfig.json                    |  2 +-
 4 files changed, 67 insertions(+), 20 deletions(-)

diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json
index 779c3ac..2428175 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -19063,10 +19063,27 @@
         "xss": "^1.0.6"
       },
       "dependencies": {
+        "@babel/runtime": {
+          "version": "7.12.5",
+          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz",
+          "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==",
+          "requires": {
+            "regenerator-runtime": "^0.13.4"
+          }
+        },
         "d3-array": {
           "version": "2.9.1",
           "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.9.1.tgz",
           "integrity": "sha512-Ob7RdOtkqsjx1NWyQHMFLtCSk6/aKTxDdC4ZIolX+O+mDD2RzrsYgAyc0WGAlfYFVELLSilS7w8BtE3PKM8bHg=="
+        },
+        "match-sorter": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-4.2.1.tgz",
+          "integrity": "sha512-s+3h9TiZU9U1pWhIERHf8/f4LmBN6IXaRgo2CI17+XGByGS1GvG5VvXK9pcGyCjGe3WM3mSYRC3ipGrd5UEVgw==",
+          "requires": {
+            "@babel/runtime": "^7.10.5",
+            "remove-accents": "0.4.2"
+          }
         }
       }
     },
@@ -39439,11 +39456,11 @@
       }
     },
     "match-sorter": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-4.2.1.tgz",
-      "integrity": "sha512-s+3h9TiZU9U1pWhIERHf8/f4LmBN6IXaRgo2CI17+XGByGS1GvG5VvXK9pcGyCjGe3WM3mSYRC3ipGrd5UEVgw==",
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.1.0.tgz",
+      "integrity": "sha512-sKPMf4kbF7Dm5Crx0bbfLpokK68PUJ/0STUIOPa1ZmTZEA3lCaPK3gapQR573oLmvdkTfGojzySkIwuq6Z6xRQ==",
       "requires": {
-        "@babel/runtime": "^7.10.5",
+        "@babel/runtime": "^7.12.5",
         "remove-accents": "0.4.2"
       },
       "dependencies": {
diff --git a/superset-frontend/package.json b/superset-frontend/package.json
index 16b83d0..26cc5e7 100644
--- a/superset-frontend/package.json
+++ b/superset-frontend/package.json
@@ -120,7 +120,7 @@
     "json-stringify-pretty-compact": "^2.0.0",
     "lodash": "^4.17.20",
     "lodash-es": "^4.17.14",
-    "match-sorter": "^4.1.0",
+    "match-sorter": "^6.1.0",
     "mathjs": "^8.0.1",
     "memoize-one": "^5.1.1",
     "moment": "^2.26.0",
diff --git a/superset-frontend/src/explore/components/DatasourcePanel.tsx b/superset-frontend/src/explore/components/DatasourcePanel.tsx
index 37ab1e9..dd81ce0 100644
--- a/superset-frontend/src/explore/components/DatasourcePanel.tsx
+++ b/superset-frontend/src/explore/components/DatasourcePanel.tsx
@@ -24,7 +24,8 @@ import {
   MetricOption,
   ControlType,
 } from '@superset-ui/chart-controls';
-import matchSorter from 'match-sorter';
+import { debounce } from 'lodash';
+import { matchSorter, rankings } from 'match-sorter';
 import { ExploreActions } from '../actions/exploreActions';
 import Control from './Control';
 
@@ -164,36 +165,65 @@ const LabelContainer = styled.div`
   }
 `;
 
-const DataSourcePanel = ({
+export default function DataSourcePanel({
   datasource,
   controls: { datasource: datasourceControl },
   actions,
-}: Props) => {
+}: Props) {
   const { columns, metrics } = datasource;
   const [lists, setList] = useState({
     columns,
     metrics,
   });
-  const search = ({ target: { value } }: { target: { value: string } }) => {
+
+  const search = debounce((value: string) => {
     if (value === '') {
       setList({ columns, metrics });
       return;
     }
     setList({
       columns: matchSorter(columns, value, {
-        keys: ['column_name', 'expression', 'description', 'verbose_name'],
+        keys: [
+          'verbose_name',
+          'column_name',
+          {
+            key: 'description',
+            threshold: rankings.CONTAINS,
+          },
+          {
+            key: 'expression',
+            threshold: rankings.CONTAINS,
+          },
+        ],
+        keepDiacritics: true,
       }),
       metrics: matchSorter(metrics, value, {
-        keys: ['metric_name', 'expression', 'description', 'verbose_name'],
+        keys: [
+          'verbose_name',
+          'metric_name',
+          {
+            key: 'description',
+            threshold: rankings.CONTAINS,
+          },
+          {
+            key: 'expression',
+            threshold: rankings.CONTAINS,
+          },
+        ],
+        keepDiacritics: true,
+        baseSort: (a, b) =>
+          Number(b.item.is_certified) - Number(a.item.is_certified) ||
+          String(a.rankedValue).localeCompare(b.rankedValue),
       }),
     });
-  };
+  }, 200);
+
   useEffect(() => {
     setList({
       columns,
       metrics,
     });
-  }, [datasource]);
+  }, [columns, datasource, metrics]);
 
   const metricSlice = lists.metrics.slice(0, 50);
   const columnSlice = lists.columns.slice(0, 50);
@@ -209,7 +239,9 @@ const DataSourcePanel = ({
       />
       <input
         type="text"
-        onChange={search}
+        onChange={evt => {
+          search(evt.target.value);
+        }}
         className="form-control input-md"
         placeholder={t('Search Metrics & Columns')}
       />
@@ -224,7 +256,7 @@ const DataSourcePanel = ({
             key="metrics"
           >
             <div className="field-length">
-              {t(`Showing %s of %s`, metricSlice.length, metrics.length)}
+              {t(`Showing %s of %s`, metricSlice.length, lists.metrics.length)}
             </div>
             {metricSlice.map(m => (
               <LabelContainer key={m.metric_name} className="column">
@@ -237,7 +269,7 @@ const DataSourcePanel = ({
             key="column"
           >
             <div className="field-length">
-              {t(`Showing %s of %s`, columnSlice.length, columns.length)}
+              {t(`Showing %s of %s`, columnSlice.length, lists.columns.length)}
             </div>
             {columnSlice.map(col => (
               <LabelContainer key={col.column_name} className="column">
@@ -249,6 +281,4 @@ const DataSourcePanel = ({
       </div>
     </DatasourceContainer>
   );
-};
-
-export default DataSourcePanel;
+}
diff --git a/superset-frontend/tsconfig.json b/superset-frontend/tsconfig.json
index af1fc29..ff43496 100644
--- a/superset-frontend/tsconfig.json
+++ b/superset-frontend/tsconfig.json
@@ -27,7 +27,7 @@
       ],
       // for supressing errors caused by incompatible @types/react when `npm link`
       // Ref: https://github.com/Microsoft/typescript/issues/6496#issuecomment-384786222
-      "*": ["./node_modules/@types/*", "*"]
+      "react": ["./node_modules/@types/react"]
     },
     "skipLibCheck": true,
     "sourceMap": true,


[superset] 24/38: test: World bank examples (#12161)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit bc53be95a521e4120244f17b1977474183bb4e09
Author: Karol Kostrzewa <ka...@gmail.com>
AuthorDate: Wed Jan 13 23:20:05 2021 +0100

    test: World bank examples (#12161)
    
    * add world bank data fixture
    
    * fix fixture cleanup, add fixture to dashboard_tests
    
    * apply world bank fixtures, fix tests
    
    * fix fixture typo, dashboard ids
    
    * fix export dashboard metadata
    
    * fix test_export_dashboard_command_key_order
    
    * fix export dash tests, not add row when no orphans
    
    * debug timeout
    
    * fixes after merge
    
    * fix lint
    
    * run pre-commit
    
    * comment test for debug
    
    * fix save.test.js
    
    Co-authored-by: Karol Kostrzewa <ka...@polidea.com>
---
 .../cypress/integration/dashboard/save.test.js     |  11 +-
 .../integration/dashboard/url_params.test.js       |   2 +-
 superset/dashboards/commands/export.py             |   4 +-
 superset/examples/world_bank.py                    | 233 ++++------
 tests/access_tests.py                              |   2 +
 tests/base_api_tests.py                            |   4 +
 tests/charts/api_tests.py                          |  27 +-
 tests/conftest.py                                  |   2 -
 tests/core_tests.py                                |   9 +-
 tests/dashboard_tests.py                           |   3 +
 tests/dashboard_utils.py                           |  10 +-
 tests/dashboards/api_tests.py                      |   9 +-
 tests/dashboards/commands_tests.py                 | 179 ++++++--
 tests/dashboards/dao_tests.py                      |   4 +
 tests/databases/api_tests.py                       |   2 +
 tests/datasets/commands_tests.py                   |   3 +
 tests/fixtures/unicode_dashboard.py                |   2 +-
 tests/fixtures/world_bank_dashboard.py             | 484 +++++++++++++++++++++
 tests/import_export_tests.py                       |   9 +-
 tests/schedules_test.py                            |  20 +-
 tests/security_tests.py                            |  11 +
 tests/utils_tests.py                               |   2 +
 22 files changed, 807 insertions(+), 225 deletions(-)

diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/save.test.js b/superset-frontend/cypress-base/cypress/integration/dashboard/save.test.js
index 757a118..0822081 100644
--- a/superset-frontend/cypress-base/cypress/integration/dashboard/save.test.js
+++ b/superset-frontend/cypress-base/cypress/integration/dashboard/save.test.js
@@ -31,9 +31,6 @@ describe('Dashboard save action', () => {
     cy.server();
     cy.login();
     cy.visit(WORLD_HEALTH_DASHBOARD);
-  });
-
-  it('should save as new dashboard', () => {
     cy.get('#app').then(data => {
       const bootstrapData = JSON.parse(data[0].dataset.bootstrap);
       const dashboard = bootstrapData.dashboard_data;
@@ -50,6 +47,14 @@ describe('Dashboard save action', () => {
     });
   });
 
+  it('should save as new dashboard', () => {
+    cy.wait('@copyRequest').then(xhr => {
+      expect(xhr.response.body.dashboard_title).to.not.equal(
+        `World Bank's Data`,
+      );
+    });
+  });
+
   it('should save/overwrite dashboard', () => {
     cy.get('[data-test="grid-row-background--transparent"]').within(() => {
       cy.get('.box_plot', { timeout: 10000 }).should('be.visible');
diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/url_params.test.js b/superset-frontend/cypress-base/cypress/integration/dashboard/url_params.test.js
index 37dda04..43eb022 100644
--- a/superset-frontend/cypress-base/cypress/integration/dashboard/url_params.test.js
+++ b/superset-frontend/cypress-base/cypress/integration/dashboard/url_params.test.js
@@ -39,7 +39,7 @@ describe('Dashboard form data', () => {
   it('should apply url params to slice requests', () => {
     const aliases = getChartAliases(dashboard.slices);
     // wait and verify one-by-one
-    cy.wait(aliases).then(requests =>
+    cy.wait(aliases, { timeout: 18000 }).then(requests =>
       Promise.all(
         requests.map(async xhr => {
           expect(xhr.status).to.eq(200);
diff --git a/superset/dashboards/commands/export.py b/superset/dashboards/commands/export.py
index 3021197..09ddb75 100644
--- a/superset/dashboards/commands/export.py
+++ b/superset/dashboards/commands/export.py
@@ -137,7 +137,9 @@ class ExportDashboardsCommand(ExportModelsCommand):
         orphan_charts = {
             chart for chart in model.slices if str(chart.uuid) not in referenced_charts
         }
-        payload["position"] = append_charts(payload["position"], orphan_charts)
+
+        if orphan_charts:
+            payload["position"] = append_charts(payload["position"], orphan_charts)
 
         payload["version"] = EXPORT_VERSION
 
diff --git a/superset/examples/world_bank.py b/superset/examples/world_bank.py
index 0596142..f9c3aeb 100644
--- a/superset/examples/world_bank.py
+++ b/superset/examples/world_bank.py
@@ -17,7 +17,7 @@
 """Loads datasets, dashboards and slices in a new superset instance"""
 import json
 import os
-import textwrap
+from typing import List
 
 import pandas as pd
 from sqlalchemy import DateTime, String
@@ -29,6 +29,7 @@ from superset.models.dashboard import Dashboard
 from superset.models.slice import Slice
 from superset.utils import core as utils
 
+from ..connectors.base.models import BaseDatasource
 from .helpers import (
     config,
     EXAMPLES_FOLDER,
@@ -105,6 +106,32 @@ def load_world_bank_health_n_pop(  # pylint: disable=too-many-locals, too-many-s
     db.session.commit()
     tbl.fetch_metadata()
 
+    slices = create_slices(tbl)
+    misc_dash_slices.add(slices[-1].slice_name)
+    for slc in slices:
+        merge_slice(slc)
+
+    print("Creating a World's Health Bank dashboard")
+    dash_name = "World Bank's Data"
+    slug = "world_health"
+    dash = db.session.query(Dashboard).filter_by(slug=slug).first()
+
+    if not dash:
+        dash = Dashboard()
+    dash.published = True
+    pos = dashboard_positions
+    update_slice_ids(pos, slices)
+
+    dash.dashboard_title = dash_name
+    dash.position_json = json.dumps(pos, indent=4)
+    dash.slug = slug
+
+    dash.slices = slices[:-1]
+    db.session.merge(dash)
+    db.session.commit()
+
+
+def create_slices(tbl: BaseDatasource) -> List[Slice]:
     metric = "sum__SP_POP_TOTL"
     metrics = ["sum__SP_POP_TOTL"]
     secondary_metric = {
@@ -118,7 +145,6 @@ def load_world_bank_health_n_pop(  # pylint: disable=too-many-locals, too-many-s
         "hasCustomLabel": True,
         "label": "Rural Population",
     }
-
     defaults = {
         "compare_lag": "10",
         "compare_suffix": "o10Y",
@@ -136,8 +162,7 @@ def load_world_bank_health_n_pop(  # pylint: disable=too-many-locals, too-many-s
         "show_bubbles": True,
     }
 
-    print("Creating slices")
-    slices = [
+    return [
         Slice(
             slice_name="Region Filter",
             viz_type="filter_box",
@@ -340,31 +365,14 @@ def load_world_bank_health_n_pop(  # pylint: disable=too-many-locals, too-many-s
             ),
         ),
     ]
-    misc_dash_slices.add(slices[-1].slice_name)
-    for slc in slices:
-        merge_slice(slc)
 
-    print("Creating a World's Health Bank dashboard")
-    dash_name = "World Bank's Data"
-    slug = "world_health"
-    dash = db.session.query(Dashboard).filter_by(slug=slug).first()
 
-    if not dash:
-        dash = Dashboard()
-    dash.published = True
-    js = textwrap.dedent(
-        """\
-{
+dashboard_positions = {
     "CHART-36bfc934": {
         "children": [],
         "id": "CHART-36bfc934",
-        "meta": {
-            "chartId": 40,
-            "height": 25,
-            "sliceName": "Region Filter",
-            "width": 2
-        },
-        "type": "CHART"
+        "meta": {"chartId": 40, "height": 25, "sliceName": "Region Filter", "width": 2},
+        "type": "CHART",
     },
     "CHART-37982887": {
         "children": [],
@@ -373,9 +381,9 @@ def load_world_bank_health_n_pop(  # pylint: disable=too-many-locals, too-many-s
             "chartId": 41,
             "height": 25,
             "sliceName": "World's Population",
-            "width": 2
+            "width": 2,
         },
-        "type": "CHART"
+        "type": "CHART",
     },
     "CHART-17e0f8d8": {
         "children": [],
@@ -384,31 +392,21 @@ def load_world_bank_health_n_pop(  # pylint: disable=too-many-locals, too-many-s
             "chartId": 42,
             "height": 92,
             "sliceName": "Most Populated Countries",
-            "width": 3
+            "width": 3,
         },
-        "type": "CHART"
+        "type": "CHART",
     },
     "CHART-2ee52f30": {
         "children": [],
         "id": "CHART-2ee52f30",
-        "meta": {
-            "chartId": 43,
-            "height": 38,
-            "sliceName": "Growth Rate",
-            "width": 6
-        },
-        "type": "CHART"
+        "meta": {"chartId": 43, "height": 38, "sliceName": "Growth Rate", "width": 6},
+        "type": "CHART",
     },
     "CHART-2d5b6871": {
         "children": [],
         "id": "CHART-2d5b6871",
-        "meta": {
-            "chartId": 44,
-            "height": 52,
-            "sliceName": "% Rural",
-            "width": 7
-        },
-        "type": "CHART"
+        "meta": {"chartId": 44, "height": 52, "sliceName": "% Rural", "width": 7},
+        "type": "CHART",
     },
     "CHART-0fd0d252": {
         "children": [],
@@ -417,9 +415,9 @@ def load_world_bank_health_n_pop(  # pylint: disable=too-many-locals, too-many-s
             "chartId": 45,
             "height": 50,
             "sliceName": "Life Expectancy VS Rural %",
-            "width": 8
+            "width": 8,
         },
-        "type": "CHART"
+        "type": "CHART",
     },
     "CHART-97f4cb48": {
         "children": [],
@@ -428,9 +426,9 @@ def load_world_bank_health_n_pop(  # pylint: disable=too-many-locals, too-many-s
             "chartId": 46,
             "height": 38,
             "sliceName": "Rural Breakdown",
-            "width": 3
+            "width": 3,
         },
-        "type": "CHART"
+        "type": "CHART",
     },
     "CHART-b5e05d6f": {
         "children": [],
@@ -439,145 +437,80 @@ def load_world_bank_health_n_pop(  # pylint: disable=too-many-locals, too-many-s
             "chartId": 47,
             "height": 50,
             "sliceName": "World's Pop Growth",
-            "width": 4
+            "width": 4,
         },
-        "type": "CHART"
+        "type": "CHART",
     },
     "CHART-e76e9f5f": {
         "children": [],
         "id": "CHART-e76e9f5f",
-        "meta": {
-            "chartId": 48,
-            "height": 50,
-            "sliceName": "Box plot",
-            "width": 4
-        },
-        "type": "CHART"
+        "meta": {"chartId": 48, "height": 50, "sliceName": "Box plot", "width": 4},
+        "type": "CHART",
     },
     "CHART-a4808bba": {
         "children": [],
         "id": "CHART-a4808bba",
-        "meta": {
-            "chartId": 49,
-            "height": 50,
-            "sliceName": "Treemap",
-            "width": 8
-        },
-        "type": "CHART"
+        "meta": {"chartId": 49, "height": 50, "sliceName": "Treemap", "width": 8},
+        "type": "CHART",
+    },
+    "CHART-3nc0d8sk": {
+        "children": [],
+        "id": "CHART-3nc0d8sk",
+        "meta": {"chartId": 50, "height": 50, "sliceName": "Treemap", "width": 8},
+        "type": "CHART",
     },
     "COLUMN-071bbbad": {
-        "children": [
-            "ROW-1e064e3c",
-            "ROW-afdefba9"
-        ],
+        "children": ["ROW-1e064e3c", "ROW-afdefba9"],
         "id": "COLUMN-071bbbad",
-        "meta": {
-            "background": "BACKGROUND_TRANSPARENT",
-            "width": 9
-        },
-        "type": "COLUMN"
+        "meta": {"background": "BACKGROUND_TRANSPARENT", "width": 9},
+        "type": "COLUMN",
     },
     "COLUMN-fe3914b8": {
-        "children": [
-            "CHART-36bfc934",
-            "CHART-37982887"
-        ],
+        "children": ["CHART-36bfc934", "CHART-37982887"],
         "id": "COLUMN-fe3914b8",
-        "meta": {
-            "background": "BACKGROUND_TRANSPARENT",
-            "width": 2
-        },
-        "type": "COLUMN"
+        "meta": {"background": "BACKGROUND_TRANSPARENT", "width": 2},
+        "type": "COLUMN",
     },
     "GRID_ID": {
-        "children": [
-            "ROW-46632bc2",
-            "ROW-3fa26c5d",
-            "ROW-812b3f13"
-        ],
+        "children": ["ROW-46632bc2", "ROW-3fa26c5d", "ROW-812b3f13"],
         "id": "GRID_ID",
-        "type": "GRID"
+        "type": "GRID",
     },
     "HEADER_ID": {
         "id": "HEADER_ID",
-        "meta": {
-            "text": "World's Bank Data"
-        },
-        "type": "HEADER"
-    },
-    "ROOT_ID": {
-        "children": [
-            "GRID_ID"
-        ],
-        "id": "ROOT_ID",
-        "type": "ROOT"
+        "meta": {"text": "World's Bank Data"},
+        "type": "HEADER",
     },
+    "ROOT_ID": {"children": ["GRID_ID"], "id": "ROOT_ID", "type": "ROOT"},
     "ROW-1e064e3c": {
-        "children": [
-            "COLUMN-fe3914b8",
-            "CHART-2d5b6871"
-        ],
+        "children": ["COLUMN-fe3914b8", "CHART-2d5b6871"],
         "id": "ROW-1e064e3c",
-        "meta": {
-            "background": "BACKGROUND_TRANSPARENT"
-        },
-        "type": "ROW"
+        "meta": {"background": "BACKGROUND_TRANSPARENT"},
+        "type": "ROW",
     },
     "ROW-3fa26c5d": {
-        "children": [
-            "CHART-b5e05d6f",
-            "CHART-0fd0d252"
-        ],
+        "children": ["CHART-b5e05d6f", "CHART-0fd0d252"],
         "id": "ROW-3fa26c5d",
-        "meta": {
-            "background": "BACKGROUND_TRANSPARENT"
-        },
-        "type": "ROW"
+        "meta": {"background": "BACKGROUND_TRANSPARENT"},
+        "type": "ROW",
     },
     "ROW-46632bc2": {
-        "children": [
-            "COLUMN-071bbbad",
-            "CHART-17e0f8d8"
-        ],
+        "children": ["COLUMN-071bbbad", "CHART-17e0f8d8"],
         "id": "ROW-46632bc2",
-        "meta": {
-            "background": "BACKGROUND_TRANSPARENT"
-        },
-        "type": "ROW"
+        "meta": {"background": "BACKGROUND_TRANSPARENT"},
+        "type": "ROW",
     },
     "ROW-812b3f13": {
-        "children": [
-            "CHART-a4808bba",
-            "CHART-e76e9f5f"
-        ],
+        "children": ["CHART-a4808bba", "CHART-e76e9f5f"],
         "id": "ROW-812b3f13",
-        "meta": {
-            "background": "BACKGROUND_TRANSPARENT"
-        },
-        "type": "ROW"
+        "meta": {"background": "BACKGROUND_TRANSPARENT"},
+        "type": "ROW",
     },
     "ROW-afdefba9": {
-        "children": [
-            "CHART-2ee52f30",
-            "CHART-97f4cb48"
-        ],
+        "children": ["CHART-2ee52f30", "CHART-97f4cb48"],
         "id": "ROW-afdefba9",
-        "meta": {
-            "background": "BACKGROUND_TRANSPARENT"
-        },
-        "type": "ROW"
+        "meta": {"background": "BACKGROUND_TRANSPARENT"},
+        "type": "ROW",
     },
-    "DASHBOARD_VERSION_KEY": "v2"
+    "DASHBOARD_VERSION_KEY": "v2",
 }
-    """
-    )
-    pos = json.loads(js)
-    update_slice_ids(pos, slices)
-
-    dash.dashboard_title = dash_name
-    dash.position_json = json.dumps(pos, indent=4)
-    dash.slug = slug
-
-    dash.slices = slices[:-1]
-    db.session.merge(dash)
-    db.session.commit()
diff --git a/tests/access_tests.py b/tests/access_tests.py
index 4e568a5..d3cc55a 100644
--- a/tests/access_tests.py
+++ b/tests/access_tests.py
@@ -22,6 +22,7 @@ from unittest import mock
 from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 
 import pytest
+from tests.fixtures.world_bank_dashboard import load_world_bank_dashboard_with_slices
 
 from tests.fixtures.energy_dashboard import load_energy_table_with_slice
 from tests.test_app import app  # isort:skip
@@ -321,6 +322,7 @@ class TestRequestAccess(SupersetTestCase):
         gamma_user.roles.remove(security_manager.find_role(DB_ACCESS_ROLE))
         session.commit()
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_clean_requests_after_schema_grant(self):
         session = db.session
 
diff --git a/tests/base_api_tests.py b/tests/base_api_tests.py
index 1708cff..3dd21dc 100644
--- a/tests/base_api_tests.py
+++ b/tests/base_api_tests.py
@@ -16,7 +16,9 @@
 # under the License.
 # isort:skip_file
 import json
+from tests.fixtures.world_bank_dashboard import load_world_bank_dashboard_with_slices
 
+import pytest
 from flask_appbuilder.models.sqla.interface import SQLAInterface
 import prison
 
@@ -66,6 +68,7 @@ class TestOpenApiSpec(SupersetTestCase):
 
 
 class TestBaseModelRestApi(SupersetTestCase):
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_default_missing_declaration_get(self):
         """
         API: Test default missing declaration on get
@@ -148,6 +151,7 @@ class TestBaseModelRestApi(SupersetTestCase):
         }
         self.assertEqual(response, expected_response)
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_default_missing_declaration_put(self):
         """
         API: Test default missing declaration on put
diff --git a/tests/charts/api_tests.py b/tests/charts/api_tests.py
index 99ab93c..f7ba39a 100644
--- a/tests/charts/api_tests.py
+++ b/tests/charts/api_tests.py
@@ -33,6 +33,7 @@ import yaml
 from sqlalchemy import and_, or_
 from sqlalchemy.sql import func
 
+from tests.fixtures.world_bank_dashboard import load_world_bank_dashboard_with_slices
 from tests.test_app import app
 from superset.charts.commands.data import ChartDataCommand
 from superset.connectors.connector_registry import ConnectorRegistry
@@ -435,7 +436,10 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         db.session.delete(user_alpha2)
         db.session.commit()
 
-    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
+    @pytest.mark.usefixtures(
+        "load_world_bank_dashboard_with_slices",
+        "load_birth_names_dashboard_with_slices",
+    )
     def test_create_chart(self):
         """
         Chart API: Test create chart
@@ -544,15 +548,18 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
             response, {"message": {"datasource_id": ["Datasource does not exist"]}}
         )
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_update_chart(self):
         """
         Chart API: Test update
         """
         admin = self.get_user("admin")
         gamma = self.get_user("gamma")
-
-        chart_id = self.insert_chart("title", [admin.id], 1, admin).id
         birth_names_table_id = SupersetTestCase.get_table_by_name("birth_names").id
+        chart_id = self.insert_chart(
+            "title", [admin.id], birth_names_table_id, admin
+        ).id
+        dash_id = db.session.query(Dashboard.id).filter_by(slug="births").first()[0]
         chart_data = {
             "slice_name": "title1_changed",
             "description": "description1",
@@ -562,14 +569,14 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
             "cache_timeout": 1000,
             "datasource_id": birth_names_table_id,
             "datasource_type": "table",
-            "dashboards": [1],
+            "dashboards": [dash_id],
         }
         self.login(username="admin")
         uri = f"api/v1/chart/{chart_id}"
         rv = self.put_assert_metric(uri, chart_data, "put")
         self.assertEqual(rv.status_code, 200)
         model = db.session.query(Slice).get(chart_id)
-        related_dashboard = db.session.query(Dashboard).get(1)
+        related_dashboard = db.session.query(Dashboard).filter_by(slug="births").first()
         self.assertEqual(model.created_by, admin)
         self.assertEqual(model.slice_name, "title1_changed")
         self.assertEqual(model.description, "description1")
@@ -581,7 +588,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         self.assertEqual(model.datasource_id, birth_names_table_id)
         self.assertEqual(model.datasource_type, "table")
         self.assertEqual(model.datasource_name, "birth_names")
-        self.assertIn(related_dashboard, model.dashboards)
+        self.assertIn(model.id, [slice.id for slice in related_dashboard.slices])
         db.session.delete(model)
         db.session.commit()
 
@@ -698,6 +705,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         expected_response = {"message": {"owners": ["Owners are invalid"]}}
         self.assertEqual(response, expected_response)
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_get_chart(self):
         """
         Chart API: Test get chart
@@ -758,6 +766,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         "load_energy_table_with_slice",
         "load_birth_names_dashboard_with_slices",
         "load_unicode_dashboard_with_slice",
+        "load_world_bank_dashboard_with_slices",
     )
     def test_get_charts(self):
         """
@@ -798,7 +807,10 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         db.session.delete(chart)
         db.session.commit()
 
-    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
+    @pytest.mark.usefixtures(
+        "load_world_bank_dashboard_with_slices",
+        "load_birth_names_dashboard_with_slices",
+    )
     def test_get_charts_filter(self):
         """
         Chart API: Test get charts filter
@@ -1008,6 +1020,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
     @pytest.mark.usefixtures(
         "load_unicode_dashboard_with_slice",
         "load_energy_table_with_slice",
+        "load_world_bank_dashboard_with_slices",
         "load_birth_names_dashboard_with_slices",
     )
     def test_get_charts_page(self):
diff --git a/tests/conftest.py b/tests/conftest.py
index efa549f..b854385 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -42,13 +42,11 @@ def setup_sample_data() -> Any:
         from superset import examples
 
         examples.load_css_templates()
-        examples.load_world_bank_health_n_pop(sample=True)
 
     yield
 
     with app.app_context():
         engine = get_example_database().get_sqla_engine()
-        engine.execute("DROP TABLE wb_health_population")
 
         # drop sqlachemy tables
 
diff --git a/tests/core_tests.py b/tests/core_tests.py
index 16620b4..2363ab0 100644
--- a/tests/core_tests.py
+++ b/tests/core_tests.py
@@ -66,6 +66,7 @@ from superset.views import core as views
 from superset.views.database.views import DatabaseView
 
 from .base_tests import SupersetTestCase
+from tests.fixtures.world_bank_dashboard import load_world_bank_dashboard_with_slices
 
 logger = logging.getLogger(__name__)
 
@@ -1223,6 +1224,7 @@ class TestCore(SupersetTestCase):
         {"FOO": lambda x: 1},
         clear=True,
     )
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_feature_flag_serialization(self):
         """
         Functions in feature flags don't break bootstrap data serialization.
@@ -1238,13 +1240,14 @@ class TestCore(SupersetTestCase):
             .replace("'", "&#39;")
             .replace('"', "&#34;")
         )
-
+        dash_id = db.session.query(Dashboard.id).first()[0]
+        tbl_id = self.table_ids.get("wb_health_population")
         urls = [
             "/superset/sqllab",
             "/superset/welcome",
-            "/superset/dashboard/1/",
+            f"/superset/dashboard/{dash_id}/",
             "/superset/profile/admin/",
-            "/superset/explore/table/1",
+            f"/superset/explore/table/{tbl_id}",
         ]
         for url in urls:
             data = self.get_resp(url)
diff --git a/tests/dashboard_tests.py b/tests/dashboard_tests.py
index 8d4df16..be3e0a9 100644
--- a/tests/dashboard_tests.py
+++ b/tests/dashboard_tests.py
@@ -34,6 +34,7 @@ from superset.models import core as models
 from superset.models.dashboard import Dashboard
 from superset.models.slice import Slice
 from tests.fixtures.energy_dashboard import load_energy_table_with_slice
+from tests.fixtures.world_bank_dashboard import load_world_bank_dashboard_with_slices
 
 from .base_tests import SupersetTestCase
 
@@ -161,6 +162,7 @@ class TestDashboard(SupersetTestCase):
         resp = self.get_resp(url, data=dict(data=json.dumps(data)))
         self.assertIn("SUCCESS", resp)
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_save_dash_with_filter(self, username="admin"):
         self.login(username=username)
         dash = db.session.query(Dashboard).filter_by(slug="world_health").first()
@@ -190,6 +192,7 @@ class TestDashboard(SupersetTestCase):
         resp = self.get_resp(new_url)
         self.assertIn("North America", resp)
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_save_dash_with_invalid_filters(self, username="admin"):
         self.login(username=username)
         dash = db.session.query(Dashboard).filter_by(slug="world_health").first()
diff --git a/tests/dashboard_utils.py b/tests/dashboard_utils.py
index 36e329e..6944b63 100644
--- a/tests/dashboard_utils.py
+++ b/tests/dashboard_utils.py
@@ -17,7 +17,7 @@
 """Utils to provide dashboards for tests"""
 
 import json
-from typing import Any, Dict
+from typing import Any, Dict, List
 
 from pandas import DataFrame
 
@@ -71,7 +71,9 @@ def create_slice(
     )
 
 
-def create_dashboard(slug: str, title: str, position: str, slice: Slice) -> Dashboard:
+def create_dashboard(
+    slug: str, title: str, position: str, slices: List[Slice]
+) -> Dashboard:
     dash = db.session.query(Dashboard).filter_by(slug=slug).one_or_none()
 
     if not dash:
@@ -82,8 +84,8 @@ def create_dashboard(slug: str, title: str, position: str, slice: Slice) -> Dash
         pos = json.loads(js)
         dash.position_json = json.dumps(pos, indent=4)
     dash.slug = slug
-    if slice is not None:
-        dash.slices = [slice]
+    if slices is not None:
+        dash.slices = slices
     db.session.merge(dash)
     db.session.commit()
 
diff --git a/tests/dashboards/api_tests.py b/tests/dashboards/api_tests.py
index 299dd2d..38ce1ae 100644
--- a/tests/dashboards/api_tests.py
+++ b/tests/dashboards/api_tests.py
@@ -49,6 +49,7 @@ from tests.fixtures.importexport import (
     dataset_metadata_config,
 )
 from tests.utils.get_dashboards import get_dashboards_ids
+from tests.fixtures.world_bank_dashboard import load_world_bank_dashboard_with_slices
 
 DASHBOARDS_FIXTURE_COUNT = 10
 
@@ -1102,13 +1103,17 @@ class TestDashboardApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         db.session.delete(user_alpha2)
         db.session.commit()
 
+    @pytest.mark.usefixtures(
+        "load_world_bank_dashboard_with_slices",
+        "load_birth_names_dashboard_with_slices",
+    )
     def test_export(self):
         """
         Dashboard API: Test dashboard export
         """
         self.login(username="admin")
-        argument = [1, 2]
-        uri = f"api/v1/dashboard/export/?q={prison.dumps(argument)}"
+        dashboards_ids = get_dashboards_ids(db, ["world_health", "births"])
+        uri = f"api/v1/dashboard/export/?q={prison.dumps(dashboards_ids)}"
 
         # freeze time to ensure filename is deterministic
         with freeze_time("2020-01-01T00:00:00Z"):
diff --git a/tests/dashboards/commands_tests.py b/tests/dashboards/commands_tests.py
index f3d96f3..3449c00 100644
--- a/tests/dashboards/commands_tests.py
+++ b/tests/dashboards/commands_tests.py
@@ -48,16 +48,20 @@ from tests.fixtures.importexport import (
     dataset_config,
     dataset_metadata_config,
 )
+from tests.fixtures.world_bank_dashboard import load_world_bank_dashboard_with_slices
 
 
 class TestExportDashboardsCommand(SupersetTestCase):
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     @patch("superset.security.manager.g")
     @patch("superset.views.base.g")
     def test_export_dashboard_command(self, mock_g1, mock_g2):
         mock_g1.user = security_manager.find_user("admin")
         mock_g2.user = security_manager.find_user("admin")
 
-        example_dashboard = db.session.query(Dashboard).filter_by(id=1).one()
+        example_dashboard = (
+            db.session.query(Dashboard).filter_by(slug="world_health").one()
+        )
         command = ExportDashboardsCommand([example_dashboard.id])
         contents = dict(command.run())
 
@@ -83,82 +87,152 @@ class TestExportDashboardsCommand(SupersetTestCase):
         assert metadata == {
             "dashboard_title": "World Bank's Data",
             "description": None,
-            "css": "",
+            "css": None,
             "slug": "world_health",
             "uuid": str(example_dashboard.uuid),
             "position": {
-                "DASHBOARD_CHART_TYPE-0": {
+                "CHART-36bfc934": {
                     "children": [],
-                    "id": "DASHBOARD_CHART_TYPE-0",
-                    "meta": {"height": 50, "width": 4},
+                    "id": "CHART-36bfc934",
+                    "meta": {"height": 25, "sliceName": "Region Filter", "width": 2},
                     "type": "CHART",
                 },
-                "DASHBOARD_CHART_TYPE-1": {
+                "CHART-37982887": {
                     "children": [],
-                    "id": "DASHBOARD_CHART_TYPE-1",
-                    "meta": {"height": 50, "width": 4},
+                    "id": "CHART-37982887",
+                    "meta": {
+                        "height": 25,
+                        "sliceName": "World's Population",
+                        "width": 2,
+                    },
                     "type": "CHART",
                 },
-                "DASHBOARD_CHART_TYPE-2": {
+                "CHART-17e0f8d8": {
                     "children": [],
-                    "id": "DASHBOARD_CHART_TYPE-2",
-                    "meta": {"height": 50, "width": 4},
+                    "id": "CHART-17e0f8d8",
+                    "meta": {
+                        "height": 92,
+                        "sliceName": "Most Populated Countries",
+                        "width": 3,
+                    },
                     "type": "CHART",
                 },
-                "DASHBOARD_CHART_TYPE-3": {
+                "CHART-2ee52f30": {
                     "children": [],
-                    "id": "DASHBOARD_CHART_TYPE-3",
-                    "meta": {"height": 50, "width": 4},
+                    "id": "CHART-2ee52f30",
+                    "meta": {"height": 38, "sliceName": "Growth Rate", "width": 6},
                     "type": "CHART",
                 },
-                "DASHBOARD_CHART_TYPE-4": {
+                "CHART-2d5b6871": {
                     "children": [],
-                    "id": "DASHBOARD_CHART_TYPE-4",
-                    "meta": {"height": 50, "width": 4},
+                    "id": "CHART-2d5b6871",
+                    "meta": {"height": 52, "sliceName": "% Rural", "width": 7},
                     "type": "CHART",
                 },
-                "DASHBOARD_CHART_TYPE-5": {
+                "CHART-0fd0d252": {
                     "children": [],
-                    "id": "DASHBOARD_CHART_TYPE-5",
-                    "meta": {"height": 50, "width": 4},
+                    "id": "CHART-0fd0d252",
+                    "meta": {
+                        "height": 50,
+                        "sliceName": "Life Expectancy VS Rural %",
+                        "width": 8,
+                    },
                     "type": "CHART",
                 },
-                "DASHBOARD_CHART_TYPE-6": {
+                "CHART-97f4cb48": {
                     "children": [],
-                    "id": "DASHBOARD_CHART_TYPE-6",
-                    "meta": {"height": 50, "width": 4},
+                    "id": "CHART-97f4cb48",
+                    "meta": {"height": 38, "sliceName": "Rural Breakdown", "width": 3},
                     "type": "CHART",
                 },
-                "DASHBOARD_CHART_TYPE-7": {
+                "CHART-b5e05d6f": {
                     "children": [],
-                    "id": "DASHBOARD_CHART_TYPE-7",
-                    "meta": {"height": 50, "width": 4},
+                    "id": "CHART-b5e05d6f",
+                    "meta": {
+                        "height": 50,
+                        "sliceName": "World's Pop Growth",
+                        "width": 4,
+                    },
                     "type": "CHART",
                 },
-                "DASHBOARD_CHART_TYPE-8": {
+                "CHART-e76e9f5f": {
                     "children": [],
-                    "id": "DASHBOARD_CHART_TYPE-8",
-                    "meta": {"height": 50, "width": 4},
+                    "id": "CHART-e76e9f5f",
+                    "meta": {"height": 50, "sliceName": "Box plot", "width": 4},
                     "type": "CHART",
                 },
-                "DASHBOARD_CHART_TYPE-9": {
+                "CHART-a4808bba": {
                     "children": [],
-                    "id": "DASHBOARD_CHART_TYPE-9",
-                    "meta": {"height": 50, "width": 4},
+                    "id": "CHART-a4808bba",
+                    "meta": {"height": 50, "sliceName": "Treemap", "width": 8},
                     "type": "CHART",
                 },
+                "CHART-3nc0d8sk": {
+                    "children": [],
+                    "id": "CHART-3nc0d8sk",
+                    "meta": {"height": 50, "sliceName": "Treemap", "width": 8},
+                    "type": "CHART",
+                },
+                "COLUMN-071bbbad": {
+                    "children": ["ROW-1e064e3c", "ROW-afdefba9"],
+                    "id": "COLUMN-071bbbad",
+                    "meta": {"background": "BACKGROUND_TRANSPARENT", "width": 9},
+                    "type": "COLUMN",
+                },
+                "COLUMN-fe3914b8": {
+                    "children": ["CHART-36bfc934", "CHART-37982887"],
+                    "id": "COLUMN-fe3914b8",
+                    "meta": {"background": "BACKGROUND_TRANSPARENT", "width": 2},
+                    "type": "COLUMN",
+                },
+                "GRID_ID": {
+                    "children": ["ROW-46632bc2", "ROW-3fa26c5d", "ROW-812b3f13"],
+                    "id": "GRID_ID",
+                    "type": "GRID",
+                },
+                "HEADER_ID": {
+                    "id": "HEADER_ID",
+                    "meta": {"text": "World's Bank Data"},
+                    "type": "HEADER",
+                },
+                "ROOT_ID": {"children": ["GRID_ID"], "id": "ROOT_ID", "type": "ROOT"},
+                "ROW-1e064e3c": {
+                    "children": ["COLUMN-fe3914b8", "CHART-2d5b6871"],
+                    "id": "ROW-1e064e3c",
+                    "meta": {"background": "BACKGROUND_TRANSPARENT"},
+                    "type": "ROW",
+                },
+                "ROW-3fa26c5d": {
+                    "children": ["CHART-b5e05d6f", "CHART-0fd0d252"],
+                    "id": "ROW-3fa26c5d",
+                    "meta": {"background": "BACKGROUND_TRANSPARENT"},
+                    "type": "ROW",
+                },
+                "ROW-46632bc2": {
+                    "children": ["COLUMN-071bbbad", "CHART-17e0f8d8"],
+                    "id": "ROW-46632bc2",
+                    "meta": {"background": "BACKGROUND_TRANSPARENT"},
+                    "type": "ROW",
+                },
+                "ROW-812b3f13": {
+                    "children": ["CHART-a4808bba", "CHART-e76e9f5f"],
+                    "id": "ROW-812b3f13",
+                    "meta": {"background": "BACKGROUND_TRANSPARENT"},
+                    "type": "ROW",
+                },
+                "ROW-afdefba9": {
+                    "children": ["CHART-2ee52f30", "CHART-97f4cb48"],
+                    "id": "ROW-afdefba9",
+                    "meta": {"background": "BACKGROUND_TRANSPARENT"},
+                    "type": "ROW",
+                },
                 "DASHBOARD_VERSION_KEY": "v2",
             },
-            "metadata": {
-                "timed_refresh_immune_slices": [],
-                "expanded_slices": {},
-                "refresh_frequency": 0,
-                "default_filters": "{}",
-                "color_scheme": None,
-            },
+            "metadata": {"mock_key": "mock_value"},
             "version": "1.0.0",
         }
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     @patch("superset.security.manager.g")
     @patch("superset.views.base.g")
     def test_export_dashboard_command_no_access(self, mock_g1, mock_g2):
@@ -166,12 +240,15 @@ class TestExportDashboardsCommand(SupersetTestCase):
         mock_g1.user = security_manager.find_user("gamma")
         mock_g2.user = security_manager.find_user("gamma")
 
-        example_dashboard = db.session.query(Dashboard).filter_by(id=1).one()
+        example_dashboard = (
+            db.session.query(Dashboard).filter_by(slug="world_health").one()
+        )
         command = ExportDashboardsCommand([example_dashboard.id])
         contents = command.run()
         with self.assertRaises(DashboardNotFoundError):
             next(contents)
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     @patch("superset.security.manager.g")
     @patch("superset.views.base.g")
     def test_export_dashboard_command_invalid_dataset(self, mock_g1, mock_g2):
@@ -183,6 +260,7 @@ class TestExportDashboardsCommand(SupersetTestCase):
         with self.assertRaises(DashboardNotFoundError):
             next(contents)
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     @patch("superset.security.manager.g")
     @patch("superset.views.base.g")
     def test_export_dashboard_command_key_order(self, mock_g1, mock_g2):
@@ -190,7 +268,9 @@ class TestExportDashboardsCommand(SupersetTestCase):
         mock_g1.user = security_manager.find_user("admin")
         mock_g2.user = security_manager.find_user("admin")
 
-        example_dashboard = db.session.query(Dashboard).filter_by(id=1).one()
+        example_dashboard = (
+            db.session.query(Dashboard).filter_by(slug="world_health").one()
+        )
         command = ExportDashboardsCommand([example_dashboard.id])
         contents = dict(command.run())
 
@@ -206,6 +286,7 @@ class TestExportDashboardsCommand(SupersetTestCase):
             "version",
         ]
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     @patch("superset.dashboards.commands.export.suffix")
     def test_append_charts(self, mock_suffix):
         """Test that oprhaned charts are added to the dashbaord position"""
@@ -213,7 +294,7 @@ class TestExportDashboardsCommand(SupersetTestCase):
         mock_suffix.side_effect = (str(i) for i in itertools.count(1))
 
         position = get_default_position("example")
-        chart_1 = db.session.query(Slice).filter_by(id=1).one()
+        chart_1 = db.session.query(Slice).filter_by(slice_name="Region Filter").one()
         new_position = append_charts(position, {chart_1})
         assert new_position == {
             "DASHBOARD_VERSION_KEY": "v2",
@@ -240,7 +321,7 @@ class TestExportDashboardsCommand(SupersetTestCase):
                 "children": [],
                 "id": "CHART-1",
                 "meta": {
-                    "chartId": 1,
+                    "chartId": chart_1.id,
                     "height": 50,
                     "sliceName": "Region Filter",
                     "uuid": str(chart_1.uuid),
@@ -251,7 +332,9 @@ class TestExportDashboardsCommand(SupersetTestCase):
             },
         }
 
-        chart_2 = db.session.query(Slice).filter_by(id=2).one()
+        chart_2 = (
+            db.session.query(Slice).filter_by(slice_name="World's Population").one()
+        )
         new_position = append_charts(new_position, {chart_2})
         assert new_position == {
             "DASHBOARD_VERSION_KEY": "v2",
@@ -285,7 +368,7 @@ class TestExportDashboardsCommand(SupersetTestCase):
                 "children": [],
                 "id": "CHART-1",
                 "meta": {
-                    "chartId": 1,
+                    "chartId": chart_1.id,
                     "height": 50,
                     "sliceName": "Region Filter",
                     "uuid": str(chart_1.uuid),
@@ -298,7 +381,7 @@ class TestExportDashboardsCommand(SupersetTestCase):
                 "children": [],
                 "id": "CHART-3",
                 "meta": {
-                    "chartId": 2,
+                    "chartId": chart_2.id,
                     "height": 50,
                     "sliceName": "World's Population",
                     "uuid": str(chart_2.uuid),
@@ -316,7 +399,7 @@ class TestExportDashboardsCommand(SupersetTestCase):
                 "children": [],
                 "id": "CHART-5",
                 "meta": {
-                    "chartId": 1,
+                    "chartId": chart_1.id,
                     "height": 50,
                     "sliceName": "Region Filter",
                     "uuid": str(chart_1.uuid),
@@ -328,7 +411,7 @@ class TestExportDashboardsCommand(SupersetTestCase):
                 "children": [],
                 "id": "CHART-6",
                 "meta": {
-                    "chartId": 2,
+                    "chartId": chart_2.id,
                     "height": 50,
                     "sliceName": "World's Population",
                     "uuid": str(chart_2.uuid),
diff --git a/tests/dashboards/dao_tests.py b/tests/dashboards/dao_tests.py
index 6bb22b8..48d058c 100644
--- a/tests/dashboards/dao_tests.py
+++ b/tests/dashboards/dao_tests.py
@@ -18,14 +18,18 @@
 import copy
 import json
 
+import pytest
+
 import tests.test_app  # pylint: disable=unused-import
 from superset import db
 from superset.dashboards.dao import DashboardDAO
 from superset.models.dashboard import Dashboard
 from tests.base_tests import SupersetTestCase
+from tests.fixtures.world_bank_dashboard import load_world_bank_dashboard_with_slices
 
 
 class TestDashboardDAO(SupersetTestCase):
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_set_dash_metadata(self):
         dash = db.session.query(Dashboard).filter_by(slug="world_health").first()
         data = dash.data
diff --git a/tests/databases/api_tests.py b/tests/databases/api_tests.py
index 46af4f0..82a5cb5 100644
--- a/tests/databases/api_tests.py
+++ b/tests/databases/api_tests.py
@@ -21,6 +21,7 @@ import json
 from io import BytesIO
 from unittest import mock
 from zipfile import is_zipfile, ZipFile
+from tests.fixtures.world_bank_dashboard import load_world_bank_dashboard_with_slices
 from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 
 import prison
@@ -848,6 +849,7 @@ class TestDatabaseApi(SupersetTestCase):
     @pytest.mark.usefixtures(
         "load_unicode_dashboard_with_position",
         "load_energy_table_with_slice",
+        "load_world_bank_dashboard_with_slices",
         "load_birth_names_dashboard_with_slices",
     )
     def test_get_database_related_objects(self):
diff --git a/tests/datasets/commands_tests.py b/tests/datasets/commands_tests.py
index 01bc91c..f72e7f3 100644
--- a/tests/datasets/commands_tests.py
+++ b/tests/datasets/commands_tests.py
@@ -43,6 +43,7 @@ from tests.fixtures.importexport import (
     dataset_metadata_config,
     dataset_ui_export,
 )
+from tests.fixtures.world_bank_dashboard import load_world_bank_dashboard_with_slices
 
 
 class TestExportDatasetsCommand(SupersetTestCase):
@@ -212,6 +213,7 @@ class TestExportDatasetsCommand(SupersetTestCase):
 
 
 class TestImportDatasetsCommand(SupersetTestCase):
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_import_v0_dataset_cli_export(self):
         num_datasets = db.session.query(SqlaTable).count()
 
@@ -251,6 +253,7 @@ class TestImportDatasetsCommand(SupersetTestCase):
         db.session.delete(dataset)
         db.session.commit()
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_import_v0_dataset_ui_export(self):
         num_datasets = db.session.query(SqlaTable).count()
 
diff --git a/tests/fixtures/unicode_dashboard.py b/tests/fixtures/unicode_dashboard.py
index 1393757..02dbd4c 100644
--- a/tests/fixtures/unicode_dashboard.py
+++ b/tests/fixtures/unicode_dashboard.py
@@ -87,7 +87,7 @@ def _create_unicode_dashboard(
     if slice_title:
         slice = _create_and_commit_unicode_slice(table, slice_title)
 
-    return create_dashboard("unicode-test", "Unicode Test", position, slice)
+    return create_dashboard("unicode-test", "Unicode Test", position, [slice])
 
 
 def _create_and_commit_unicode_slice(table: SqlaTable, title: str):
diff --git a/tests/fixtures/world_bank_dashboard.py b/tests/fixtures/world_bank_dashboard.py
new file mode 100644
index 0000000..4f27b56
--- /dev/null
+++ b/tests/fixtures/world_bank_dashboard.py
@@ -0,0 +1,484 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+import json
+import string
+from random import choice, randint, random, uniform
+from typing import Any, Dict, List
+
+import pandas as pd
+import pytest
+from pandas import DataFrame
+from sqlalchemy import DateTime, String, TIMESTAMP
+
+from superset import db
+from superset.connectors.sqla.models import SqlaTable
+from superset.models.core import Database
+from superset.models.dashboard import Dashboard
+from superset.models.slice import Slice
+from superset.utils.core import get_example_database
+from tests.dashboard_utils import create_dashboard, create_table_for_dashboard
+from tests.test_app import app
+
+
+@pytest.fixture()
+def load_world_bank_dashboard_with_slices():
+    dash_id_to_delete, slices_ids_to_delete = _load_data()
+    yield
+    with app.app_context():
+        _cleanup(dash_id_to_delete, slices_ids_to_delete)
+
+
+@pytest.fixture(scope="module")
+def load_world_bank_dashboard_with_slices_module_scope():
+    dash_id_to_delete, slices_ids_to_delete = _load_data()
+    yield
+    with app.app_context():
+        _cleanup(dash_id_to_delete, slices_ids_to_delete)
+
+
+def _load_data():
+    table_name = "wb_health_population"
+
+    with app.app_context():
+        database = get_example_database()
+        df = _get_dataframe(database)
+        dtype = {
+            "year": DateTime if database.backend != "presto" else String(255),
+            "country_code": String(3),
+            "country_name": String(255),
+            "region": String(255),
+        }
+        table = create_table_for_dashboard(df, table_name, database, dtype)
+        slices = _create_world_bank_slices(table)
+        dash = _create_world_bank_dashboard(table, slices)
+        slices_ids_to_delete = [slice.id for slice in slices]
+        dash_id_to_delete = dash.id
+        return dash_id_to_delete, slices_ids_to_delete
+
+
+def _create_world_bank_slices(table: SqlaTable) -> List[Slice]:
+    from superset.examples.world_bank import create_slices
+
+    slices = create_slices(table)
+    _commit_slices(slices)
+    return slices
+
+
+def _commit_slices(slices: List[Slice]):
+    for slice in slices:
+        o = db.session.query(Slice).filter_by(slice_name=slice.slice_name).one_or_none()
+        if o:
+            db.session.delete(o)
+        db.session.add(slice)
+        db.session.commit()
+
+
+def _create_world_bank_dashboard(table: SqlaTable, slices: List[Slice]) -> Dashboard:
+    from superset.examples.world_bank import dashboard_positions
+
+    pos = dashboard_positions
+    from superset.examples.helpers import update_slice_ids
+
+    update_slice_ids(pos, slices)
+
+    table.fetch_metadata()
+
+    dash = create_dashboard(
+        "world_health", "World Bank's Data", json.dumps(pos), slices
+    )
+    dash.json_metadata = '{"mock_key": "mock_value"}'
+    db.session.commit()
+    return dash
+
+
+def _cleanup(dash_id: int, slices_ids: List[int]) -> None:
+    engine = get_example_database().get_sqla_engine()
+    engine.execute("DROP TABLE IF EXISTS wb_health_population")
+    dash = db.session.query(Dashboard).filter_by(id=dash_id).first()
+    db.session.delete(dash)
+    for slice_id in slices_ids:
+        db.session.query(Slice).filter_by(id=slice_id).delete()
+    db.session.commit()
+
+
+def _get_dataframe(database: Database) -> DataFrame:
+    data = _get_world_bank_data()
+    df = pd.DataFrame.from_dict(data)
+    if database.backend == "presto":
+        df.year = pd.to_datetime(df.year)
+        df.year = df.year.dt.strftime("%Y-%m-%d %H:%M%:%S")
+    else:
+        df.year = pd.to_datetime(df.year)
+
+    return df
+
+
+def _get_world_bank_data() -> List[Dict[Any, Any]]:
+    data = []
+    for _ in range(100):
+        data.append(
+            {
+                "country_name": "".join(
+                    choice(string.ascii_uppercase + string.ascii_lowercase + " ")
+                    for _ in range(randint(3, 10))
+                ),
+                "country_code": "".join(
+                    choice(string.ascii_uppercase + string.ascii_lowercase)
+                    for _ in range(3)
+                ),
+                "region": "".join(
+                    choice(string.ascii_uppercase + string.ascii_lowercase)
+                    for _ in range(randint(3, 10))
+                ),
+                "year": "-".join(
+                    [str(randint(1900, 2020)), str(randint(1, 12)), str(randint(1, 28))]
+                ),
+                "NY_GNP_PCAP_CD": get_random_float_or_none(0, 100, 0.3),
+                "SE_ADT_1524_LT_FM_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SE_ADT_1524_LT_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SE_ADT_1524_LT_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SE_ADT_LITR_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SE_ADT_LITR_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SE_ADT_LITR_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SE_ENR_ORPH": get_random_float_or_none(0, 100, 0.3),
+                "SE_PRM_CMPT_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SE_PRM_CMPT_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SE_PRM_CMPT_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SE_PRM_ENRR": get_random_float_or_none(0, 100, 0.3),
+                "SE_PRM_ENRR_FE": get_random_float_or_none(0, 100, 0.3),
+                "SE_PRM_ENRR_MA": get_random_float_or_none(0, 100, 0.3),
+                "SE_PRM_NENR": get_random_float_or_none(0, 100, 0.3),
+                "SE_PRM_NENR_FE": get_random_float_or_none(0, 100, 0.3),
+                "SE_PRM_NENR_MA": get_random_float_or_none(0, 100, 0.3),
+                "SE_SEC_ENRR": get_random_float_or_none(0, 100, 0.3),
+                "SE_SEC_ENRR_FE": get_random_float_or_none(0, 100, 0.3),
+                "SE_SEC_ENRR_MA": get_random_float_or_none(0, 100, 0.3),
+                "SE_SEC_NENR": get_random_float_or_none(0, 100, 0.3),
+                "SE_SEC_NENR_FE": get_random_float_or_none(0, 100, 0.3),
+                "SE_SEC_NENR_MA": get_random_float_or_none(0, 100, 0.3),
+                "SE_TER_ENRR": get_random_float_or_none(0, 100, 0.3),
+                "SE_TER_ENRR_FE": get_random_float_or_none(0, 100, 0.3),
+                "SE_XPD_TOTL_GD_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_ANM_CHLD_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_ANM_NPRG_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_CON_1524_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_CON_1524_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_CON_AIDS_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_CON_AIDS_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_DTH_COMM_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_DTH_IMRT": get_random_float_or_none(0, 100, 0.3),
+                "SH_DTH_INJR_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_DTH_MORT": get_random_float_or_none(0, 100, 0.3),
+                "SH_DTH_NCOM_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_DTH_NMRT": get_random_float_or_none(0, 100, 0.3),
+                "SH_DYN_AIDS": get_random_float_or_none(0, 100, 0.3),
+                "SH_DYN_AIDS_DH": get_random_float_or_none(0, 100, 0.3),
+                "SH_DYN_AIDS_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_DYN_AIDS_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_DYN_MORT": get_random_float_or_none(0, 100, 0.3),
+                "SH_DYN_MORT_FE": get_random_float_or_none(0, 100, 0.3),
+                "SH_DYN_MORT_MA": get_random_float_or_none(0, 100, 0.3),
+                "SH_DYN_NMRT": get_random_float_or_none(0, 100, 0.3),
+                "SH_FPL_SATI_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_H2O_SAFE_RU_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_H2O_SAFE_UR_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_H2O_SAFE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_HIV_0014": get_random_float_or_none(0, 100, 0.3),
+                "SH_HIV_1524_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_HIV_1524_KW_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_HIV_1524_KW_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_HIV_1524_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_HIV_ARTC_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_HIV_KNOW_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_HIV_KNOW_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_HIV_ORPH": get_random_float_or_none(0, 100, 0.3),
+                "SH_HIV_TOTL": get_random_float_or_none(0, 100, 0.3),
+                "SH_IMM_HEPB": get_random_float_or_none(0, 100, 0.3),
+                "SH_IMM_HIB3": get_random_float_or_none(0, 100, 0.3),
+                "SH_IMM_IBCG": get_random_float_or_none(0, 100, 0.3),
+                "SH_IMM_IDPT": get_random_float_or_none(0, 100, 0.3),
+                "SH_IMM_MEAS": get_random_float_or_none(0, 100, 0.3),
+                "SH_IMM_POL3": get_random_float_or_none(0, 100, 0.3),
+                "SH_MED_BEDS_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_MED_CMHW_P3": get_random_float_or_none(0, 100, 0.3),
+                "SH_MED_NUMW_P3": get_random_float_or_none(0, 100, 0.3),
+                "SH_MED_PHYS_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_MLR_NETS_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_MLR_PREG_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_MLR_SPF2_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_MLR_TRET_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_MMR_DTHS": get_random_float_or_none(0, 100, 0.3),
+                "SH_MMR_LEVE": get_random_float_or_none(0, 100, 0.3),
+                "SH_MMR_RISK": get_random_float_or_none(0, 100, 0.3),
+                "SH_MMR_RISK_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_MMR_WAGE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_PRG_ANEM": get_random_float_or_none(0, 100, 0.3),
+                "SH_PRG_ARTC_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_PRG_SYPH_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_PRV_SMOK_FE": get_random_float_or_none(0, 100, 0.3),
+                "SH_PRV_SMOK_MA": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_ACSN": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_ACSN_RU": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_ACSN_UR": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_ANV4_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_ANVC_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_ARIC_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_BFED_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_BRTC_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_BRTW_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_DIAB_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_IYCF_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_MALN_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_MALN_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_MALN_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_MALR": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_MMRT": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_MMRT_NE": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_ORCF_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_ORTH": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_OW15_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_OW15_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_OW15_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_OWGH_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_OWGH_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_OWGH_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_PNVC_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_STNT_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_STNT_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_STNT_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_WAST_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_WAST_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_STA_WAST_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_SVR_WAST_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_SVR_WAST_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_SVR_WAST_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_TBS_CURE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_TBS_DTEC_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_TBS_INCD": get_random_float_or_none(0, 100, 0.3),
+                "SH_TBS_MORT": get_random_float_or_none(0, 100, 0.3),
+                "SH_TBS_PREV": get_random_float_or_none(0, 100, 0.3),
+                "SH_VAC_TTNS_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_XPD_EXTR_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_XPD_OOPC_TO_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_XPD_OOPC_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_XPD_PCAP": get_random_float_or_none(0, 100, 0.3),
+                "SH_XPD_PCAP_PP_KD": get_random_float_or_none(0, 100, 0.3),
+                "SH_XPD_PRIV": get_random_float_or_none(0, 100, 0.3),
+                "SH_XPD_PRIV_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_XPD_PUBL": get_random_float_or_none(0, 100, 0.3),
+                "SH_XPD_PUBL_GX_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_XPD_PUBL_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SH_XPD_TOTL_CD": get_random_float_or_none(0, 100, 0.3),
+                "SH_XPD_TOTL_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SI_POV_NAHC": get_random_float_or_none(0, 100, 0.3),
+                "SI_POV_RUHC": get_random_float_or_none(0, 100, 0.3),
+                "SI_POV_URHC": get_random_float_or_none(0, 100, 0.3),
+                "SL_EMP_INSV_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SL_TLF_TOTL_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SL_TLF_TOTL_IN": get_random_float_or_none(0, 100, 0.3),
+                "SL_UEM_TOTL_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SL_UEM_TOTL_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SL_UEM_TOTL_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SM_POP_NETM": get_random_float_or_none(0, 100, 0.3),
+                "SN_ITK_DEFC": get_random_float_or_none(0, 100, 0.3),
+                "SN_ITK_DEFC_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SN_ITK_SALT_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SN_ITK_VITA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_ADO_TFRT": get_random_float_or_none(0, 100, 0.3),
+                "SP_DYN_AMRT_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_DYN_AMRT_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_DYN_CBRT_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_DYN_CDRT_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_DYN_CONU_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_DYN_IMRT_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_DYN_IMRT_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_DYN_IMRT_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_DYN_LE00_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_DYN_LE00_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_DYN_LE00_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_DYN_SMAM_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_DYN_SMAM_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_DYN_TFRT_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_DYN_TO65_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_DYN_TO65_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_DYN_WFRT": get_random_float_or_none(0, 100, 0.3),
+                "SP_HOU_FEMA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_MTR_1519_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_0004_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_0004_FE_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_0004_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_0004_MA_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_0014_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_0014_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_0014_TO": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_0014_TO_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_0509_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_0509_FE_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_0509_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_0509_MA_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_1014_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_1014_FE_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_1014_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_1014_MA_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_1519_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_1519_FE_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_1519_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_1519_MA_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_1564_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_1564_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_1564_TO": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_1564_TO_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_2024_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_2024_FE_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_2024_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_2024_MA_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_2529_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_2529_FE_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_2529_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_2529_MA_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_3034_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_3034_FE_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_3034_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_3034_MA_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_3539_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_3539_FE_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_3539_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_3539_MA_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_4044_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_4044_FE_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_4044_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_4044_MA_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_4549_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_4549_FE_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_4549_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_4549_MA_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_5054_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_5054_FE_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_5054_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_5054_MA_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_5559_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_5559_FE_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_5559_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_5559_MA_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_6064_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_6064_FE_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_6064_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_6064_MA_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_6569_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_6569_FE_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_6569_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_6569_MA_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_65UP_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_65UP_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_65UP_TO": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_65UP_TO_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_7074_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_7074_FE_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_7074_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_7074_MA_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_7579_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_7579_FE_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_7579_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_7579_MA_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_80UP_FE": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_80UP_FE_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_80UP_MA": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_80UP_MA_5Y": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG00_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG00_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG01_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG01_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG02_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG02_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG03_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG03_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG04_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG04_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG05_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG05_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG06_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG06_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG07_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG07_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG08_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG08_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG09_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG09_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG10_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG10_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG11_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG11_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG12_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG12_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG13_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG13_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG14_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG14_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG15_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG15_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG16_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG16_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG17_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG17_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG18_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG18_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG19_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG19_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG20_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG20_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG21_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG21_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG22_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG22_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG23_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG23_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG24_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG24_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG25_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_AG25_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_BRTH_MF": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_DPND": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_DPND_OL": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_DPND_YG": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_GROW": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_TOTL": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_TOTL_FE_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_TOTL_FE_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_TOTL_MA_IN": get_random_float_or_none(0, 100, 0.3),
+                "SP_POP_TOTL_MA_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_REG_BRTH_RU_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_REG_BRTH_UR_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_REG_BRTH_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_REG_DTHS_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_RUR_TOTL": get_random_float_or_none(0, 100, 0.3),
+                "SP_RUR_TOTL_ZG": get_random_float_or_none(0, 100, 0.3),
+                "SP_RUR_TOTL_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_URB_GROW": get_random_float_or_none(0, 100, 0.3),
+                "SP_URB_TOTL": get_random_float_or_none(0, 100, 0.3),
+                "SP_URB_TOTL_IN_ZS": get_random_float_or_none(0, 100, 0.3),
+                "SP_UWT_TFRT": get_random_float_or_none(0, 100, 0.3),
+            }
+        )
+
+    return data
+
+
+def get_random_float_or_none(min_value, max_value, none_probability):
+    if random() < none_probability:
+        return None
+    else:
+        return uniform(min_value, max_value)
diff --git a/tests/import_export_tests.py b/tests/import_export_tests.py
index 2dc29f0..4aaf8fb 100644
--- a/tests/import_export_tests.py
+++ b/tests/import_export_tests.py
@@ -41,6 +41,7 @@ from superset.models.dashboard import Dashboard
 from superset.models.slice import Slice
 from superset.utils.core import get_example_database
 
+from tests.fixtures.world_bank_dashboard import load_world_bank_dashboard_with_slices
 from .base_tests import SupersetTestCase
 
 
@@ -270,7 +271,10 @@ class TestImportExport(SupersetTestCase):
             self.get_table_by_name("birth_names"), exported_tables[0]
         )
 
-    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
+    @pytest.mark.usefixtures(
+        "load_world_bank_dashboard_with_slices",
+        "load_birth_names_dashboard_with_slices",
+    )
     def test_export_2_dashboards(self):
         self.login("admin")
         birth_dash = self.get_dash_by_slug("births")
@@ -311,6 +315,7 @@ class TestImportExport(SupersetTestCase):
             self.get_table_by_name("wb_health_population"), exported_tables[1]
         )
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_import_1_slice(self):
         expected_slice = self.create_slice("Import Me", id=10001)
         slc_id = import_chart(expected_slice, None, import_time=1989)
@@ -321,6 +326,7 @@ class TestImportExport(SupersetTestCase):
         table_id = self.get_table_by_name("wb_health_population").id
         self.assertEqual(table_id, self.get_slice(slc_id).datasource_id)
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_import_2_slices_for_same_table(self):
         table_id = self.get_table_by_name("wb_health_population").id
         # table_id != 666, import func will have to find the table
@@ -363,6 +369,7 @@ class TestImportExport(SupersetTestCase):
         imported_dash = self.get_dash(imported_dash_id)
         self.assert_dash_equals(empty_dash, imported_dash, check_position=False)
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_import_dashboard_1_slice(self):
         slc = self.create_slice("health_slc", id=10006)
         dash_with_1_slice = self.create_dashboard(
diff --git a/tests/schedules_test.py b/tests/schedules_test.py
index 8ff7a52..45693f4 100644
--- a/tests/schedules_test.py
+++ b/tests/schedules_test.py
@@ -23,6 +23,9 @@ import pytest
 from selenium.common.exceptions import WebDriverException
 from slack import errors, WebClient
 
+from tests.fixtures.world_bank_dashboard import (
+    load_world_bank_dashboard_with_slices_module_scope,
+)
 from tests.test_app import app
 from superset import db
 from superset.models.dashboard import Dashboard
@@ -62,7 +65,6 @@ class TestSchedules(SupersetTestCase):
                 deliver_as_group=True,
                 delivery_type=EmailDeliveryType.inline,
             )
-
             # Pick up a sample slice and dashboard
             slce = db.session.query(Slice).filter_by(slice_name="Participants").one()
             dashboard = (
@@ -99,6 +101,7 @@ class TestSchedules(SupersetTestCase):
             ).delete()
             db.session.commit()
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices_module_scope")
     def test_crontab_scheduler(self):
         crontab = "* * * * *"
 
@@ -126,6 +129,7 @@ class TestSchedules(SupersetTestCase):
         self.assertEqual(schedules[-1], stop_at - timedelta(seconds=12 * 60))
         self.assertEqual(len(schedules), 5)
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices_module_scope")
     def test_wider_schedules(self):
         crontab = "*/15 2,10 * * *"
 
@@ -141,7 +145,10 @@ class TestSchedules(SupersetTestCase):
             else:
                 self.assertEqual(len(schedules), 0)
 
-    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices_module_scope")
+    @pytest.mark.usefixtures(
+        "load_world_bank_dashboard_with_slices_module_scope",
+        "load_birth_names_dashboard_with_slices_module_scope",
+    )
     def test_complex_schedule(self):
         # Run the job on every Friday of March and May
         # On these days, run the job at
@@ -169,6 +176,7 @@ class TestSchedules(SupersetTestCase):
         self.assertEqual(schedules[59], datetime.strptime("2018-03-30 17:40:00", fmt))
         self.assertEqual(schedules[60], datetime.strptime("2018-05-04 17:10:00", fmt))
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices_module_scope")
     @patch("superset.tasks.schedules.firefox.webdriver.WebDriver")
     def test_create_driver(self, mock_driver_class):
         mock_driver = Mock()
@@ -178,6 +186,7 @@ class TestSchedules(SupersetTestCase):
         create_webdriver(db.session)
         mock_driver.add_cookie.assert_called_once()
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices_module_scope")
     @patch("superset.tasks.schedules.firefox.webdriver.WebDriver")
     @patch("superset.tasks.schedules.send_email_smtp")
     @patch("superset.tasks.schedules.time")
@@ -211,6 +220,7 @@ class TestSchedules(SupersetTestCase):
         driver.screenshot.assert_not_called()
         send_email_smtp.assert_called_once()
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices_module_scope")
     @patch("superset.tasks.schedules.firefox.webdriver.WebDriver")
     @patch("superset.tasks.schedules.send_email_smtp")
     @patch("superset.tasks.schedules.time")
@@ -254,6 +264,7 @@ class TestSchedules(SupersetTestCase):
             element.screenshot_as_png,
         )
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices_module_scope")
     @patch("superset.tasks.schedules.firefox.webdriver.WebDriver")
     @patch("superset.tasks.schedules.send_email_smtp")
     @patch("superset.tasks.schedules.time")
@@ -297,6 +308,7 @@ class TestSchedules(SupersetTestCase):
             driver.screenshot.return_value,
         )
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices_module_scope")
     @patch("superset.tasks.schedules.firefox.webdriver.WebDriver")
     @patch("superset.tasks.schedules.send_email_smtp")
     @patch("superset.tasks.schedules.time")
@@ -338,6 +350,7 @@ class TestSchedules(SupersetTestCase):
         self.assertEqual(send_email_smtp.call_count, 2)
         self.assertEqual(send_email_smtp.call_args[1]["bcc"], self.BCC)
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices_module_scope")
     @patch("superset.tasks.slack_util.WebClient.files_upload")
     @patch("superset.tasks.schedules.firefox.webdriver.WebDriver")
     @patch("superset.tasks.schedules.send_email_smtp")
@@ -391,6 +404,7 @@ class TestSchedules(SupersetTestCase):
             },
         )
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices_module_scope")
     @patch("superset.tasks.slack_util.WebClient.files_upload")
     @patch("superset.tasks.schedules.firefox.webdriver.WebDriver")
     @patch("superset.tasks.schedules.send_email_smtp")
@@ -445,6 +459,7 @@ class TestSchedules(SupersetTestCase):
             },
         )
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices_module_scope")
     @patch("superset.tasks.slack_util.WebClient.files_upload")
     @patch("superset.tasks.schedules.urllib.request.OpenerDirector.open")
     @patch("superset.tasks.schedules.urllib.request.urlopen")
@@ -491,6 +506,7 @@ class TestSchedules(SupersetTestCase):
             },
         )
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices_module_scope")
     @patch("superset.tasks.slack_util.WebClient.files_upload")
     @patch("superset.tasks.schedules.urllib.request.urlopen")
     @patch("superset.tasks.schedules.urllib.request.OpenerDirector.open")
diff --git a/tests/security_tests.py b/tests/security_tests.py
index 7ddc326..1b7e0b3 100644
--- a/tests/security_tests.py
+++ b/tests/security_tests.py
@@ -29,6 +29,9 @@ import random
 from flask import current_app, g
 from sqlalchemy import Float, Date, String
 
+from superset.models.dashboard import Dashboard
+from tests.fixtures.world_bank_dashboard import load_world_bank_dashboard_with_slices
+
 from superset import app, appbuilder, db, security_manager, viz, ConnectorRegistry
 from superset.connectors.druid.models import DruidCluster, DruidDatasource
 from superset.connectors.sqla.models import RowLevelSecurityFilter, SqlaTable
@@ -260,6 +263,7 @@ class TestRolePermission(SupersetTestCase):
         session.delete(stored_table)
         session.commit()
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_set_perm_druid_datasource(self):
         self.create_druid_test_objects()
         session = db.session
@@ -534,7 +538,12 @@ class TestRolePermission(SupersetTestCase):
         self.assertIsNotNone(vm)
         delete_schema_perm("[examples].[2]")
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_gamma_user_schema_access_to_dashboards(self):
+        dash = db.session.query(Dashboard).filter_by(slug="world_health").first()
+        dash.published = True
+        db.session.commit()
+
         self.login(username="gamma")
         data = str(self.client.get("api/v1/dashboard/").data)
         self.assertIn("/superset/dashboard/world_health/", data)
@@ -546,6 +555,7 @@ class TestRolePermission(SupersetTestCase):
         self.assertIn("wb_health_population", data)
         self.assertNotIn("birth_names", data)
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_gamma_user_schema_access_to_charts(self):
         self.login(username="gamma")
         data = str(self.client.get("api/v1/chart/").data)
@@ -820,6 +830,7 @@ class TestRolePermission(SupersetTestCase):
     @unittest.skipUnless(
         SupersetTestCase.is_module_installed("pydruid"), "pydruid not installed"
     )
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_admin_permissions(self):
         self.assert_can_gamma(get_perm_tuples("Admin"))
         self.assert_can_alpha(get_perm_tuples("Admin"))
diff --git a/tests/utils_tests.py b/tests/utils_tests.py
index a16db4b..1c6e6b2 100644
--- a/tests/utils_tests.py
+++ b/tests/utils_tests.py
@@ -70,6 +70,7 @@ from superset.views.utils import (
     get_time_range_endpoints,
 )
 from tests.base_tests import SupersetTestCase
+from tests.fixtures.world_bank_dashboard import load_world_bank_dashboard_with_slices
 
 from .fixtures.certificates import ssl_certificate
 
@@ -853,6 +854,7 @@ class TestUtils(SupersetTestCase):
         self.assertListEqual(get_iterable([123]), [123])
         self.assertListEqual(get_iterable("foo"), ["foo"])
 
+    @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices")
     def test_build_extra_filters(self):
         world_health = db.session.query(Dashboard).filter_by(slug="world_health").one()
         layout = json.loads(world_health.position_json)


[superset] 25/38: fix: error while parsing invalid json form_data (#12586)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit c7284fe2421caf8b088c0e71d3d40b1bd38528d7
Author: Duy Nguyen Hoang <du...@global-fashion-group.com>
AuthorDate: Tue Jan 19 23:15:16 2021 +0700

    fix: error while parsing invalid json form_data (#12586)
    
    * Fix error while parsing invalid json form_data
    
    * Refine error returned
---
 superset/charts/api.py    | 11 ++++++++---
 superset/views/utils.py   | 13 ++++++++++---
 tests/charts/api_tests.py | 17 ++++++++++++++++-
 tests/utils_tests.py      | 16 +++++++++++++++-
 4 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/superset/charts/api.py b/superset/charts/api.py
index 2d46cce..cce76da 100644
--- a/superset/charts/api.py
+++ b/superset/charts/api.py
@@ -534,13 +534,18 @@ class ChartRestApi(BaseSupersetModelRestApi):
             500:
               $ref: '#/components/responses/500'
         """
+        json_body = None
         if request.is_json:
             json_body = request.json
         elif request.form.get("form_data"):
             # CSV export submits regular form data
-            json_body = json.loads(request.form["form_data"])
-        else:
-            return self.response_400(message="Request is not JSON")
+            try:
+                json_body = json.loads(request.form["form_data"])
+            except (TypeError, json.JSONDecodeError):
+                json_body = None
+
+        if json_body is None:
+            return self.response_400(message=_("Request is not JSON"))
 
         try:
             command = ChartDataCommand()
diff --git a/superset/views/utils.py b/superset/views/utils.py
index 28104aa..3ea253c 100644
--- a/superset/views/utils.py
+++ b/superset/views/utils.py
@@ -126,6 +126,13 @@ def get_viz(
     return viz_obj
 
 
+def loads_request_json(request_json_data: str) -> Dict[Any, Any]:
+    try:
+        return json.loads(request_json_data)
+    except (TypeError, json.JSONDecodeError):
+        return {}
+
+
 def get_form_data(
     slice_id: Optional[int] = None, use_slice_data: bool = False
 ) -> Tuple[Dict[str, Any], Optional[Slice]]:
@@ -141,10 +148,10 @@ def get_form_data(
     if request_json_data:
         form_data.update(request_json_data)
     if request_form_data:
-        form_data.update(json.loads(request_form_data))
+        form_data.update(loads_request_json(request_form_data))
     # request params can overwrite the body
     if request_args_data:
-        form_data.update(json.loads(request_args_data))
+        form_data.update(loads_request_json(request_args_data))
 
     # Fallback to using the Flask globals (used for cache warmup) if defined.
     if not form_data and hasattr(g, "form_data"):
@@ -157,7 +164,7 @@ def get_form_data(
             url_str = parse.unquote_plus(
                 saved_url.url.split("?")[1][10:], encoding="utf-8"
             )
-            url_form_data = json.loads(url_str)
+            url_form_data = loads_request_json(url_str)
             # allow form_date in request override saved url
             url_form_data.update(form_data)
             form_data = url_form_data
diff --git a/tests/charts/api_tests.py b/tests/charts/api_tests.py
index f7ba39a..8e22074 100644
--- a/tests/charts/api_tests.py
+++ b/tests/charts/api_tests.py
@@ -1176,6 +1176,21 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         self.assertEqual(rv.status_code, 400)
 
     @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
+    def test_chart_data_invalid_form_data(self):
+        """
+        Chart data API: Test chart data with invalid form_data json
+        """
+        self.login(username="admin")
+        data = {"form_data": "NOT VALID JSON"}
+
+        rv = self.client.post(
+            CHART_DATA_URI, data=data, content_type="multipart/form-data"
+        )
+        response = json.loads(rv.data.decode("utf-8"))
+        self.assertEqual(rv.status_code, 400)
+        self.assertEqual(response["message"], "Request is not JSON")
+
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_chart_data_query_result_type(self):
         """
         Chart data API: Test chart data with query result format
@@ -1592,7 +1607,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         assert rv.status_code == 422
         assert response == {
             "message": {
-                "charts/imported_chart.yaml": "Chart already exists and `overwrite=true` was not passed",
+                "charts/imported_chart.yaml": "Chart already exists and `overwrite=true` was not passed"
             }
         }
 
diff --git a/tests/utils_tests.py b/tests/utils_tests.py
index 1c6e6b2..fbdf131 100644
--- a/tests/utils_tests.py
+++ b/tests/utils_tests.py
@@ -925,7 +925,7 @@ class TestUtils(SupersetTestCase):
 
             self.assertEqual(
                 form_data,
-                {"time_range_endpoints": get_time_range_endpoints(form_data={}),},
+                {"time_range_endpoints": get_time_range_endpoints(form_data={})},
             )
 
             self.assertEqual(slc, None)
@@ -994,6 +994,20 @@ class TestUtils(SupersetTestCase):
 
             self.assertEqual(slc, None)
 
+    def test_get_form_data_corrupted_json(self) -> None:
+        with app.test_request_context(
+            data={"form_data": "{x: '2324'}"},
+            query_string={"form_data": '{"baz": "bar"'},
+        ):
+            form_data, slc = get_form_data()
+
+            self.assertEqual(
+                form_data,
+                {"time_range_endpoints": get_time_range_endpoints(form_data={})},
+            )
+
+            self.assertEqual(slc, None)
+
     @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_log_this(self) -> None:
         # TODO: Add additional scenarios.


[superset] 02/38: chore: apply capitalization guidelines - iteration 1 (#12447)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 968ab8d22f2e9c57226eeee953d18e2a647cdd14
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Tue Jan 12 15:47:55 2021 -0300

    chore: apply capitalization guidelines - iteration 1 (#12447)
    
    Apply capitalization guidelines defined in #12343
    
    Use sentence casing for most places.
---
 .../javascripts/utils/getControlsForVizType_spec.js    |  2 +-
 superset-frontend/src/chart/chartAction.js             |  2 +-
 .../src/common/components/common.stories.tsx           | 14 +++++++-------
 superset-frontend/src/components/AnchorLink.jsx        |  2 +-
 superset-frontend/src/components/EditableTitle.tsx     |  2 +-
 superset-frontend/src/components/OmniContainer.jsx     |  2 +-
 .../controls/DateFilterControl/DateFilterControl.tsx   | 12 ++++++------
 .../components/controls/DateFilterControl/constants.ts |  2 +-
 .../components/controls/DateFilterControl/types.ts     |  2 +-
 superset-frontend/src/explore/constants.js             |  8 ++++----
 superset-frontend/src/explore/controls.jsx             | 18 +++++++++---------
 11 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/superset-frontend/spec/javascripts/utils/getControlsForVizType_spec.js b/superset-frontend/spec/javascripts/utils/getControlsForVizType_spec.js
index 3819782..6e06b18 100644
--- a/superset-frontend/spec/javascripts/utils/getControlsForVizType_spec.js
+++ b/superset-frontend/spec/javascripts/utils/getControlsForVizType_spec.js
@@ -83,7 +83,7 @@ describe('getControlsForVizType', () => {
       JSON.stringify({
         label_colors: {
           type: 'ColorMapControl',
-          label: t('Color Map'),
+          label: t('Color map'),
           default: {},
           renderTrigger: true,
           mapStateToProps: state => ({
diff --git a/superset-frontend/src/chart/chartAction.js b/superset-frontend/src/chart/chartAction.js
index 802208e..74ed410 100644
--- a/superset-frontend/src/chart/chartAction.js
+++ b/superset-frontend/src/chart/chartAction.js
@@ -301,7 +301,7 @@ export function runAnnotationQuery(
             dispatch(
               annotationQueryFailed(
                 annotation,
-                { error: 'Query Timeout' },
+                { error: 'Query timeout' },
                 sliceKey,
               ),
             );
diff --git a/superset-frontend/src/common/components/common.stories.tsx b/superset-frontend/src/common/components/common.stories.tsx
index dab4951..6c9abb0 100644
--- a/superset-frontend/src/common/components/common.stories.tsx
+++ b/superset-frontend/src/common/components/common.stories.tsx
@@ -38,14 +38,14 @@ import Collapse from './Collapse';
 import { CronPicker, CronError } from './CronPicker';
 
 export default {
-  title: 'Common Components',
+  title: 'Common components',
   decorators: [withKnobs],
 };
 
 export const StyledModal = () => (
   <Modal
     disablePrimaryButton={false}
-    onHandledPrimaryAction={action('Primary Action')}
+    onHandledPrimaryAction={action('Primary action')}
     primaryButtonName="Danger"
     primaryButtonType="danger"
     show
@@ -65,14 +65,14 @@ export const StyledTabs = () => (
     <Tabs.TabPane
       tab="Tab 1"
       key="1"
-      disabled={boolean('Tab 1 Disabled', false)}
+      disabled={boolean('Tab 1 disabled', false)}
     >
       Tab 1 Content!
     </Tabs.TabPane>
     <Tabs.TabPane
       tab="Tab 2"
       key="2"
-      disabled={boolean('Tab 2 Disabled', false)}
+      disabled={boolean('Tab 2 disabled', false)}
     >
       Tab 2 Content!
     </Tabs.TabPane>
@@ -88,14 +88,14 @@ export const StyledEditableTabs = () => (
     <Tabs.TabPane
       tab="Tab 1"
       key="1"
-      disabled={boolean('Tab 1 Disabled', false)}
+      disabled={boolean('Tab 1 disabled', false)}
     >
       Tab 1 Content!
     </Tabs.TabPane>
     <Tabs.TabPane
       tab="Tab 2"
       key="2"
-      disabled={boolean('Tab 2 Disabled', false)}
+      disabled={boolean('Tab 2 disabled', false)}
     >
       Tab 2 Content!
     </Tabs.TabPane>
@@ -123,7 +123,7 @@ export const TabsWithDropdownMenu = () => (
         </>
       }
       key="1"
-      disabled={boolean('Tab 1 Disabled', false)}
+      disabled={boolean('Tab 1 disabled', false)}
     >
       Tab 1 Content!
     </Tabs.TabPane>
diff --git a/superset-frontend/src/components/AnchorLink.jsx b/superset-frontend/src/components/AnchorLink.jsx
index 26d9ed7..f98bd66 100644
--- a/superset-frontend/src/components/AnchorLink.jsx
+++ b/superset-frontend/src/components/AnchorLink.jsx
@@ -85,7 +85,7 @@ class AnchorLink extends React.PureComponent {
               filters,
               anchorLinkId,
             )}
-            emailSubject={t('Superset Chart')}
+            emailSubject={t('Superset chart')}
             emailContent={t('Check out this chart in dashboard:')}
             placement={placement}
           />
diff --git a/superset-frontend/src/components/EditableTitle.tsx b/superset-frontend/src/components/EditableTitle.tsx
index 4085bad..5f4f7a4 100644
--- a/superset-frontend/src/components/EditableTitle.tsx
+++ b/superset-frontend/src/components/EditableTitle.tsx
@@ -178,7 +178,7 @@ export default function EditableTitle({
         label="title"
         tooltip={
           canEdit
-            ? t('click to edit')
+            ? t('Click to edit')
             : noPermitTooltip ||
               t("You don't have the rights to alter this title.")
         }
diff --git a/superset-frontend/src/components/OmniContainer.jsx b/superset-frontend/src/components/OmniContainer.jsx
index 22a4c50..e641a7c 100644
--- a/superset-frontend/src/components/OmniContainer.jsx
+++ b/superset-frontend/src/components/OmniContainer.jsx
@@ -41,7 +41,7 @@ const getDashboards = query =>
       })),
     )
     .catch(() => ({
-      title: t('An error occurred while fethching Dashboards'),
+      title: t('An error occurred while fetching dashboards'),
     }));
 
 const OmniModal = styled(Modal)`
diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/DateFilterControl.tsx b/superset-frontend/src/explore/components/controls/DateFilterControl/DateFilterControl.tsx
index fc440a2..6903c2c 100644
--- a/superset-frontend/src/explore/components/controls/DateFilterControl/DateFilterControl.tsx
+++ b/superset-frontend/src/explore/components/controls/DateFilterControl/DateFilterControl.tsx
@@ -60,7 +60,7 @@ const guessFrame = (timeRange: string): FrameType => {
     return 'Calendar';
   }
   if (timeRange === 'No filter') {
-    return 'No Filter';
+    return 'No filter';
   }
   if (customTimeRangeDecode(timeRange).matchedFlag) {
     return 'Custom';
@@ -251,7 +251,7 @@ export default function DateFilterControl(props: DateFilterLabelProps) {
   };
 
   function onFrame(option: SelectOptionType) {
-    if (option.value === 'No Filter') {
+    if (option.value === 'No filter') {
       setTimeRangeValue('No filter');
     }
     setFrame(option.value as FrameType);
@@ -266,7 +266,7 @@ export default function DateFilterControl(props: DateFilterLabelProps) {
         onChange={onFrame}
         className="frame-dropdown"
       />
-      {frame !== 'No Filter' && <Divider />}
+      {frame !== 'No filter' && <Divider />}
       {frame === 'Common' && (
         <CommonFrame value={timeRangeValue} onChange={setTimeRangeValue} />
       )}
@@ -279,10 +279,10 @@ export default function DateFilterControl(props: DateFilterLabelProps) {
       {frame === 'Custom' && (
         <CustomFrame value={timeRangeValue} onChange={setTimeRangeValue} />
       )}
-      {frame === 'No Filter' && <div data-test="no-filter" />}
+      {frame === 'No filter' && <div data-test="no-filter" />}
       <Divider />
       <div>
-        <div className="section-title">{t('Actual Time Range')}</div>
+        <div className="section-title">{t('Actual time range')}</div>
         {validTimeRange && <div>{evalResponse}</div>}
         {!validTimeRange && (
           <IconWrapper className="warning">
@@ -321,7 +321,7 @@ export default function DateFilterControl(props: DateFilterLabelProps) {
   const title = (
     <IconWrapper>
       <Icon name="edit-alt" />
-      <span className="text">{t('Edit Time Range')}</span>
+      <span className="text">{t('Edit time range')}</span>
     </IconWrapper>
   );
 
diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/constants.ts b/superset-frontend/src/explore/components/controls/DateFilterControl/constants.ts
index d1ec0a8..175b36c 100644
--- a/superset-frontend/src/explore/components/controls/DateFilterControl/constants.ts
+++ b/superset-frontend/src/explore/components/controls/DateFilterControl/constants.ts
@@ -32,7 +32,7 @@ export const FRAME_OPTIONS: SelectOptionType[] = [
   { value: 'Calendar', label: t('Previous') },
   { value: 'Custom', label: t('Custom') },
   { value: 'Advanced', label: t('Advanced') },
-  { value: 'No Filter', label: t('No Filter') },
+  { value: 'No filter', label: t('No filter') },
 ];
 
 export const COMMON_RANGE_OPTIONS: SelectOptionType[] = [
diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/types.ts b/superset-frontend/src/explore/components/controls/DateFilterControl/types.ts
index 5b264b9..1d400de 100644
--- a/superset-frontend/src/explore/components/controls/DateFilterControl/types.ts
+++ b/superset-frontend/src/explore/components/controls/DateFilterControl/types.ts
@@ -26,7 +26,7 @@ export type FrameType =
   | 'Calendar'
   | 'Custom'
   | 'Advanced'
-  | 'No Filter';
+  | 'No filter';
 
 export type DateTimeGrainType =
   | 'second'
diff --git a/superset-frontend/src/explore/constants.js b/superset-frontend/src/explore/constants.js
index 2232fe5..4a771d0 100644
--- a/superset-frontend/src/explore/constants.js
+++ b/superset-frontend/src/explore/constants.js
@@ -77,11 +77,11 @@ export const sqlaAutoGeneratedMetricRegex = /^(LONG|DOUBLE|FLOAT)?(SUM|AVG|MAX|M
 export const druidAutoGeneratedMetricRegex = /^(LONG|DOUBLE|FLOAT)?(SUM|MAX|MIN|COUNT)\([A-Z0-9_."]*\)$/i;
 
 export const TIME_FILTER_LABELS = {
-  time_range: t('Time Range'),
-  granularity_sqla: t('Time Column'),
-  time_grain_sqla: t('Time Grain'),
+  time_range: t('Time range'),
+  granularity_sqla: t('Time column'),
+  time_grain_sqla: t('Time grain'),
   druid_time_origin: t('Origin'),
-  granularity: t('Time Granularity'),
+  granularity: t('Time granularity'),
 };
 
 export const FILTER_CONFIG_ATTRIBUTES = {
diff --git a/superset-frontend/src/explore/controls.jsx b/superset-frontend/src/explore/controls.jsx
index c94f9d0..dfbfd21 100644
--- a/superset-frontend/src/explore/controls.jsx
+++ b/superset-frontend/src/explore/controls.jsx
@@ -203,13 +203,13 @@ export const controls = {
 
   viz_type: {
     type: 'VizTypeControl',
-    label: t('Visualization Type'),
+    label: t('Visualization type'),
     default: 'table',
     description: t('The type of visualization to display'),
   },
 
   color_picker: {
-    label: t('Fixed Color'),
+    label: t('Fixed color'),
     description: t('Use this to define a static color for all circles'),
     type: 'ColorPickerControl',
     default: PRIMARY_COLOR,
@@ -218,14 +218,14 @@ export const controls = {
 
   metric_2: {
     ...metric,
-    label: t('Right Axis Metric'),
+    label: t('Right axis metric'),
     clearable: true,
     description: t('Choose a metric for right axis'),
   },
 
   linear_color_scheme: {
     type: 'ColorSchemeControl',
-    label: t('Linear Color Scheme'),
+    label: t('Linear color scheme'),
     choices: () =>
       sequentialSchemeRegistry.values().map(value => [value.id, value.label]),
     default: sequentialSchemeRegistry.getDefaultKey(),
@@ -238,7 +238,7 @@ export const controls = {
 
   secondary_metric: {
     ...metric,
-    label: t('Color Metric'),
+    label: t('Color metric'),
     default: null,
     validators: [],
     description: t('A metric to use for color'),
@@ -385,7 +385,7 @@ export const controls = {
 
   timeseries_limit_metric: {
     type: 'MetricsControl',
-    label: t('Sort By'),
+    label: t('Sort by'),
     default: null,
     clearable: true,
     description: t('Metric used to define the top series'),
@@ -433,7 +433,7 @@ export const controls = {
 
   size: {
     ...metric,
-    label: t('Bubble Size'),
+    label: t('Bubble size'),
     default: null,
   },
 
@@ -479,7 +479,7 @@ export const controls = {
 
   color_scheme: {
     type: 'ColorSchemeControl',
-    label: t('Color Scheme'),
+    label: t('Color scheme'),
     default: categoricalSchemeRegistry.getDefaultKey(),
     renderTrigger: true,
     choices: () => categoricalSchemeRegistry.keys().map(s => [s, s]),
@@ -489,7 +489,7 @@ export const controls = {
 
   label_colors: {
     type: 'ColorMapControl',
-    label: t('Color Map'),
+    label: t('Color map'),
     default: {},
     renderTrigger: true,
     mapStateToProps: state => ({


[superset] 15/38: Apply capitalization guidelines - iteration 8 (#12343) (#12454)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 749db0b94422b31fef8821e35c477987ab97fbf4
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Fri Jan 22 02:46:18 2021 -0300

    Apply capitalization guidelines - iteration 8 (#12343) (#12454)
---
 .../integration/chart_list/list_view.test.ts       |  8 +++----
 .../explore/visualizations/line.test.ts            |  4 ++--
 .../views/CRUD/annotation/AnnotationModal_spec.jsx |  4 ++--
 .../annotationlayers/AnnotationLayerModal_spec.jsx |  4 ++--
 .../CRUD/csstemplates/CssTemplateModal_spec.jsx    |  4 ++--
 .../src/SqlLab/components/TemplateParamsEditor.jsx |  2 +-
 .../src/SqlLab/reducers/getInitialState.js         |  2 +-
 .../components/controls/AnnotationLayer.jsx        |  2 +-
 .../components/controls/AnnotationLayerControl.jsx |  4 ++--
 .../src/views/CRUD/alert/AlertList.tsx             | 12 +++++-----
 .../src/views/CRUD/alert/AlertReportModal.tsx      | 28 +++++++++++-----------
 .../src/views/CRUD/alert/ExecutionLog.tsx          |  4 ++--
 .../alert/components/AlertReportCronScheduler.tsx  |  2 +-
 .../CRUD/alert/components/AlertStatusIcon.tsx      | 16 ++++++-------
 .../src/views/CRUD/annotation/AnnotationList.tsx   |  6 ++---
 .../src/views/CRUD/annotation/AnnotationModal.tsx  | 10 ++++----
 .../CRUD/annotationlayers/AnnotationLayerModal.tsx |  8 +++----
 .../CRUD/annotationlayers/AnnotationLayersList.tsx | 18 +++++++-------
 .../src/views/CRUD/chart/ChartCard.tsx             |  2 +-
 .../src/views/CRUD/chart/ChartList.tsx             | 20 ++++++++--------
 .../views/CRUD/csstemplates/CssTemplateModal.tsx   |  8 +++----
 .../views/CRUD/csstemplates/CssTemplatesList.tsx   | 16 ++++++-------
 22 files changed, 92 insertions(+), 92 deletions(-)

diff --git a/superset-frontend/cypress-base/cypress/integration/chart_list/list_view.test.ts b/superset-frontend/cypress-base/cypress/integration/chart_list/list_view.test.ts
index 5b55036..0a5f29c 100644
--- a/superset-frontend/cypress-base/cypress/integration/chart_list/list_view.test.ts
+++ b/superset-frontend/cypress-base/cypress/integration/chart_list/list_view.test.ts
@@ -30,11 +30,11 @@ describe('chart list view', () => {
     cy.get('[data-test="listview-table"]').should('be.visible');
     // check chart list view header
     cy.get('[data-test="sort-header"]').eq(1).contains('Chart');
-    cy.get('[data-test="sort-header"]').eq(2).contains('Visualization Type');
+    cy.get('[data-test="sort-header"]').eq(2).contains('Visualization type');
     cy.get('[data-test="sort-header"]').eq(3).contains('Dataset');
-    cy.get('[data-test="sort-header"]').eq(4).contains('Modified By');
-    cy.get('[data-test="sort-header"]').eq(5).contains('Last Modified');
-    cy.get('[data-test="sort-header"]').eq(6).contains('Created By');
+    cy.get('[data-test="sort-header"]').eq(4).contains('Modified by');
+    cy.get('[data-test="sort-header"]').eq(5).contains('Last modified');
+    cy.get('[data-test="sort-header"]').eq(6).contains('Created by');
     cy.get('[data-test="sort-header"]').eq(7).contains('Actions');
     cy.get('[data-test="table-row"]').should('have.length', 25);
   });
diff --git a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.test.ts b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.test.ts
index 889428a..dd92585 100644
--- a/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.test.ts
+++ b/superset-frontend/cypress-base/cypress/integration/explore/visualizations/line.test.ts
@@ -35,10 +35,10 @@ describe('Visualization > Line', () => {
 
   it('should preload mathjs', () => {
     cy.get('script[src*="mathjs"]').should('have.length', 1);
-    cy.contains('Add Annotation Layer').scrollIntoView().click();
+    cy.contains('Add annotation layer').scrollIntoView().click();
     // should not load additional mathjs
     cy.get('script[src*="mathjs"]').should('have.length', 1);
-    cy.contains('Layer Configuration');
+    cy.contains('Layer configuration');
   });
 
   it('should not show validator error when metric added', () => {
diff --git a/superset-frontend/spec/javascripts/views/CRUD/annotation/AnnotationModal_spec.jsx b/superset-frontend/spec/javascripts/views/CRUD/annotation/AnnotationModal_spec.jsx
index 54d1422..990928c 100644
--- a/superset-frontend/spec/javascripts/views/CRUD/annotation/AnnotationModal_spec.jsx
+++ b/superset-frontend/spec/javascripts/views/CRUD/annotation/AnnotationModal_spec.jsx
@@ -80,12 +80,12 @@ describe('AnnotationModal', () => {
     const addWrapper = await mountAndWait({});
     expect(
       addWrapper.find('[data-test="annotaion-modal-title"]').text(),
-    ).toEqual('Add Annotation');
+    ).toEqual('Add annotation');
   });
 
   it('renders edit header when annotation prop is included', () => {
     expect(wrapper.find('[data-test="annotaion-modal-title"]').text()).toEqual(
-      'Edit Annotation',
+      'Edit annotation',
     );
   });
 
diff --git a/superset-frontend/spec/javascripts/views/CRUD/annotationlayers/AnnotationLayerModal_spec.jsx b/superset-frontend/spec/javascripts/views/CRUD/annotationlayers/AnnotationLayerModal_spec.jsx
index 64fd55b..a9add98 100644
--- a/superset-frontend/spec/javascripts/views/CRUD/annotationlayers/AnnotationLayerModal_spec.jsx
+++ b/superset-frontend/spec/javascripts/views/CRUD/annotationlayers/AnnotationLayerModal_spec.jsx
@@ -73,13 +73,13 @@ describe('AnnotationLayerModal', () => {
     const addWrapper = await mountAndWait({});
     expect(
       addWrapper.find('[data-test="annotation-layer-modal-title"]').text(),
-    ).toEqual('Add Annotation Layer');
+    ).toEqual('Add annotation layer');
   });
 
   it('renders edit header when layer prop is included', () => {
     expect(
       wrapper.find('[data-test="annotation-layer-modal-title"]').text(),
-    ).toEqual('Edit Annotation Layer Properties');
+    ).toEqual('Edit annotation layer properties');
   });
 
   it('renders input element for name', () => {
diff --git a/superset-frontend/spec/javascripts/views/CRUD/csstemplates/CssTemplateModal_spec.jsx b/superset-frontend/spec/javascripts/views/CRUD/csstemplates/CssTemplateModal_spec.jsx
index 1e3d3bf..c3b8289 100644
--- a/superset-frontend/spec/javascripts/views/CRUD/csstemplates/CssTemplateModal_spec.jsx
+++ b/superset-frontend/spec/javascripts/views/CRUD/csstemplates/CssTemplateModal_spec.jsx
@@ -74,13 +74,13 @@ describe('CssTemplateModal', () => {
     const addWrapper = await mountAndWait({});
     expect(
       addWrapper.find('[data-test="css-template-modal-title"]').text(),
-    ).toEqual('Add CSS Template');
+    ).toEqual('Add CSS template');
   });
 
   it('renders edit header when css template prop is included', () => {
     expect(
       wrapper.find('[data-test="css-template-modal-title"]').text(),
-    ).toEqual('Edit CSS Template Properties');
+    ).toEqual('Edit CSS template properties');
   });
 
   it('renders input elements for template name', () => {
diff --git a/superset-frontend/src/SqlLab/components/TemplateParamsEditor.jsx b/superset-frontend/src/SqlLab/components/TemplateParamsEditor.jsx
index 21fb624..863e994 100644
--- a/superset-frontend/src/SqlLab/components/TemplateParamsEditor.jsx
+++ b/superset-frontend/src/SqlLab/components/TemplateParamsEditor.jsx
@@ -122,7 +122,7 @@ export default class TemplateParamsEditor extends React.Component {
       : 0;
     return (
       <ModalTrigger
-        modalTitle={t('Template Parameters')}
+        modalTitle={t('Template parameters')}
         triggerNode={
           <div tooltip={t('Edit template parameters')} buttonSize="small">
             {`${t('Parameters')} `}
diff --git a/superset-frontend/src/SqlLab/reducers/getInitialState.js b/superset-frontend/src/SqlLab/reducers/getInitialState.js
index 9f7a0a1..60cd420 100644
--- a/superset-frontend/src/SqlLab/reducers/getInitialState.js
+++ b/superset-frontend/src/SqlLab/reducers/getInitialState.js
@@ -41,7 +41,7 @@ export default function getInitialState({
   const defaultQueryEditor = {
     id: null,
     loaded: true,
-    title: t('Untitled Query'),
+    title: t('Untitled query'),
     sql: 'SELECT *\nFROM\nWHERE',
     selectedText: null,
     latestQueryId: null,
diff --git a/superset-frontend/src/explore/components/controls/AnnotationLayer.jsx b/superset-frontend/src/explore/components/controls/AnnotationLayer.jsx
index 10e9502..db20976 100644
--- a/superset-frontend/src/explore/components/controls/AnnotationLayer.jsx
+++ b/superset-frontend/src/explore/components/controls/AnnotationLayer.jsx
@@ -698,7 +698,7 @@ export default class AnnotationLayer extends React.PureComponent {
             <PopoverSection
               isSelected
               onSelect={() => {}}
-              title={t('Layer Configuration')}
+              title={t('Layer configuration')}
               info={t('Configure the basics of your Annotation Layer.')}
             >
               <TextControl
diff --git a/superset-frontend/src/explore/components/controls/AnnotationLayerControl.jsx b/superset-frontend/src/explore/components/controls/AnnotationLayerControl.jsx
index a701892..e29a57a 100644
--- a/superset-frontend/src/explore/components/controls/AnnotationLayerControl.jsx
+++ b/superset-frontend/src/explore/components/controls/AnnotationLayerControl.jsx
@@ -188,7 +188,7 @@ class AnnotationLayerControl extends React.PureComponent {
             trigger="click"
             placement="right"
             content={this.renderPopover(addLayerPopoverKey, addedAnnotation)}
-            title={t('Add Annotation Layer')}
+            title={t('Add annotation layer')}
             visible={this.state.popoverVisible[addLayerPopoverKey]}
             destroyTooltipOnHide
             onVisibleChange={visible =>
@@ -200,7 +200,7 @@ class AnnotationLayerControl extends React.PureComponent {
                 data-test="add-annotation-layer-button"
                 className="fa fa-plus"
               />{' '}
-              &nbsp; {t('Add Annotation Layer')}
+              &nbsp; {t('Add annotation layer')}
             </ListGroupItem>
           </Popover>
         </ListGroup>
diff --git a/superset-frontend/src/views/CRUD/alert/AlertList.tsx b/superset-frontend/src/views/CRUD/alert/AlertList.tsx
index 736ec4e..192b0f5 100644
--- a/superset-frontend/src/views/CRUD/alert/AlertList.tsx
+++ b/superset-frontend/src/views/CRUD/alert/AlertList.tsx
@@ -210,7 +210,7 @@ function AlertList({
             ? moment.utc(lastEvalDttm).local().format(DATETIME_WITH_TIME_ZONE)
             : '',
         accessor: 'last_eval_dttm',
-        Header: t('Last Run'),
+        Header: t('Last run'),
         size: 'lg',
       },
       {
@@ -242,7 +242,7 @@ function AlertList({
             <RecipientIcon key={r.id} type={r.type} />
           )),
         accessor: 'recipients',
-        Header: t('Notification Method'),
+        Header: t('Notification method'),
         disableSortBy: true,
         size: 'xl',
       },
@@ -289,7 +289,7 @@ function AlertList({
             canEdit
               ? {
                   label: 'execution-log-action',
-                  tooltip: t('Execution Log'),
+                  tooltip: t('Execution log'),
                   placement: 'bottom',
                   icon: 'note' as IconName,
                   onClick: handleGotoExecutionLog,
@@ -344,7 +344,7 @@ function AlertList({
   }
   if (canDelete) {
     subMenuButtons.push({
-      name: t('Bulk Select'),
+      name: t('Bulk select'),
       onClick: toggleBulkSelect,
       buttonStyle: 'secondary',
       'data-test': 'bulk-select-toggle',
@@ -365,7 +365,7 @@ function AlertList({
   const filters: Filters = useMemo(
     () => [
       {
-        Header: t('Created By'),
+        Header: t('Created by'),
         id: 'created_by',
         input: 'select',
         operator: FilterOperators.relationOneMany,
@@ -408,7 +408,7 @@ function AlertList({
     <>
       <SubMenu
         activeChild={pathName}
-        name={t('Alerts & Reports')}
+        name={t('Alerts & reports')}
         tabs={[
           {
             name: 'Alerts',
diff --git a/superset-frontend/src/views/CRUD/alert/AlertReportModal.tsx b/superset-frontend/src/views/CRUD/alert/AlertReportModal.tsx
index d0b871a..fba09c6 100644
--- a/superset-frontend/src/views/CRUD/alert/AlertReportModal.tsx
+++ b/superset-frontend/src/views/CRUD/alert/AlertReportModal.tsx
@@ -69,15 +69,15 @@ const CONDITIONS = [
     value: '>=',
   },
   {
-    label: t('== (Is Equal)'),
+    label: t('== (Is equal)'),
     value: '==',
   },
   {
-    label: t('!= (Is Not Equal)'),
+    label: t('!= (Is not equal)'),
     value: '!=',
   },
   {
-    label: t('Not Null'),
+    label: t('Not null'),
     value: 'not null',
   },
 ];
@@ -1060,7 +1060,7 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
         <div className="header-section">
           <StyledInputContainer>
             <div className="control-label">
-              {isReport ? t('Report Name') : t('Alert Name')}
+              {isReport ? t('Report name') : t('Alert name')}
               <span className="required">*</span>
             </div>
             <div className="input-container">
@@ -1068,7 +1068,7 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
                 type="text"
                 name="name"
                 value={currentAlert ? currentAlert.name : ''}
-                placeholder={isReport ? t('Report Name') : t('Alert Name')}
+                placeholder={isReport ? t('Report name') : t('Alert name')}
                 onChange={onTextChange}
               />
             </div>
@@ -1114,7 +1114,7 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
           {!isReport && (
             <div className="column condition">
               <StyledSectionTitle>
-                <h4>{t('Alert Condition')}</h4>
+                <h4>{t('Alert condition')}</h4>
               </StyledSectionTitle>
               <StyledInputContainer>
                 <div className="control-label">
@@ -1210,8 +1210,8 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
             <StyledSectionTitle>
               <h4>
                 {isReport
-                  ? t('Report Schedule')
-                  : t('Alert Condition Schedule')}
+                  ? t('Report schedule')
+                  : t('Alert condition schedule')}
               </h4>
             </StyledSectionTitle>
             <AlertReportCronScheduler
@@ -1221,11 +1221,11 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
               onChange={newVal => updateAlertState('crontab', newVal)}
             />
             <StyledSectionTitle>
-              <h4>{t('Schedule Settings')}</h4>
+              <h4>{t('Schedule settings')}</h4>
             </StyledSectionTitle>
             <StyledInputContainer>
               <div className="control-label">
-                {t('Log Retention')}
+                {t('Log retention')}
                 <span className="required">*</span>
               </div>
               <div className="input-container">
@@ -1249,7 +1249,7 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
             </StyledInputContainer>
             <StyledInputContainer>
               <div className="control-label">
-                {t('Working Timeout')}
+                {t('Working timeout')}
                 <span className="required">*</span>
               </div>
               <div className="input-container">
@@ -1264,7 +1264,7 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
               </div>
             </StyledInputContainer>
             <StyledInputContainer>
-              <div className="control-label">{t('Grace Period')}</div>
+              <div className="control-label">{t('Grace period')}</div>
               <div className="input-container">
                 <input
                   type="number"
@@ -1279,7 +1279,7 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
           </div>
           <div className="column message">
             <StyledSectionTitle>
-              <h4>{t('Message Content')}</h4>
+              <h4>{t('Message content')}</h4>
             </StyledSectionTitle>
             <div className="inline-container add-margin">
               <Radio.Group onChange={onContentTypeChange} value={contentType}>
@@ -1328,7 +1328,7 @@ const AlertReportModal: FunctionComponent<AlertReportModalProps> = ({
               onChange={onDashboardChange}
             />
             <StyledSectionTitle>
-              <h4>{t('Notification Method')}</h4>
+              <h4>{t('Notification method')}</h4>
             </StyledSectionTitle>
             <NotificationMethod
               setting={notificationSettings[0]}
diff --git a/superset-frontend/src/views/CRUD/alert/ExecutionLog.tsx b/superset-frontend/src/views/CRUD/alert/ExecutionLog.tsx
index 8baaaba..99f9b95 100644
--- a/superset-frontend/src/views/CRUD/alert/ExecutionLog.tsx
+++ b/superset-frontend/src/views/CRUD/alert/ExecutionLog.tsx
@@ -105,7 +105,7 @@ function ExecutionLog({ addDangerToast, isReportEnabled }: ExecutionLogProps) {
             original: { start_dttm: startDttm },
           },
         }: any) => moment(new Date(startDttm)).format('MM/DD/YYYY hh:mm:ss a'),
-        Header: t('Start At'),
+        Header: t('Start at'),
         accessor: 'start_dttm',
       },
       {
@@ -124,7 +124,7 @@ function ExecutionLog({ addDangerToast, isReportEnabled }: ExecutionLogProps) {
       },
       {
         accessor: 'error_message',
-        Header: t('Error Message'),
+        Header: t('Error message'),
       },
     ],
     [isReportEnabled],
diff --git a/superset-frontend/src/views/CRUD/alert/components/AlertReportCronScheduler.tsx b/superset-frontend/src/views/CRUD/alert/components/AlertReportCronScheduler.tsx
index 8ca3604..4a4caf0 100644
--- a/superset-frontend/src/views/CRUD/alert/components/AlertReportCronScheduler.tsx
+++ b/superset-frontend/src/views/CRUD/alert/components/AlertReportCronScheduler.tsx
@@ -80,7 +80,7 @@ export const AlertReportCronScheduler: FunctionComponent<AlertReportCronSchedule
                 name="crontab"
                 ref={inputRef}
                 style={error ? { borderColor: theme.colors.error.base } : {}}
-                placeholder={t('CRON Expression')}
+                placeholder={t('CRON expression')}
                 disabled={scheduleFormat !== 'input'}
                 onBlur={event => {
                   onChange(event.target.value);
diff --git a/superset-frontend/src/views/CRUD/alert/components/AlertStatusIcon.tsx b/superset-frontend/src/views/CRUD/alert/components/AlertStatusIcon.tsx
index 6bbfa06..6b83d47 100644
--- a/superset-frontend/src/views/CRUD/alert/components/AlertStatusIcon.tsx
+++ b/superset-frontend/src/views/CRUD/alert/components/AlertStatusIcon.tsx
@@ -59,27 +59,27 @@ export default function AlertStatusIcon({
     case AlertState.success:
       lastStateConfig.name = isReportEnabled ? 'check' : 'alert-solid-small';
       lastStateConfig.label = isReportEnabled
-        ? t('Report Sent')
-        : t('Alert Triggered, Notification Sent');
+        ? t('Report sent')
+        : t('Alert triggered, notification sent');
       lastStateConfig.status = AlertState.success;
       break;
     case AlertState.working:
       lastStateConfig.name = 'running';
       lastStateConfig.label = isReportEnabled
-        ? t('Report Sending')
-        : t('Alert Running');
+        ? t('Report sending')
+        : t('Alert running');
       lastStateConfig.status = AlertState.working;
       break;
     case AlertState.error:
       lastStateConfig.name = 'x-small';
       lastStateConfig.label = isReportEnabled
-        ? t('Report Failed')
-        : t('Alert Failed');
+        ? t('Report failed')
+        : t('Alert failed');
       lastStateConfig.status = AlertState.error;
       break;
     case AlertState.noop:
       lastStateConfig.name = 'check';
-      lastStateConfig.label = t('Nothing Triggered');
+      lastStateConfig.label = t('Nothing triggered');
       lastStateConfig.status = AlertState.noop;
       break;
     case AlertState.grace:
@@ -89,7 +89,7 @@ export default function AlertStatusIcon({
       break;
     default:
       lastStateConfig.name = 'check';
-      lastStateConfig.label = t('Nothing Triggered');
+      lastStateConfig.label = t('Nothing triggered');
       lastStateConfig.status = AlertState.noop;
   }
   return (
diff --git a/superset-frontend/src/views/CRUD/annotation/AnnotationList.tsx b/superset-frontend/src/views/CRUD/annotation/AnnotationList.tsx
index d1b7ef5..bdcbf41 100644
--- a/superset-frontend/src/views/CRUD/annotation/AnnotationList.tsx
+++ b/superset-frontend/src/views/CRUD/annotation/AnnotationList.tsx
@@ -177,14 +177,14 @@ function AnnotationList({
           const actions = [
             {
               label: 'edit-action',
-              tooltip: t('Edit Annotation'),
+              tooltip: t('Edit annotation'),
               placement: 'bottom',
               icon: 'edit' as IconName,
               onClick: handleEdit,
             },
             {
               label: 'delete-action',
-              tooltip: t('Delete Annotation'),
+              tooltip: t('Delete annotation'),
               placement: 'bottom',
               icon: 'trash' as IconName,
               onClick: handleDelete,
@@ -215,7 +215,7 @@ function AnnotationList({
   });
 
   subMenuButtons.push({
-    name: t('Bulk Select'),
+    name: t('Bulk select'),
     onClick: toggleBulkSelect,
     buttonStyle: 'secondary',
     'data-test': 'annotation-bulk-select',
diff --git a/superset-frontend/src/views/CRUD/annotation/AnnotationModal.tsx b/superset-frontend/src/views/CRUD/annotation/AnnotationModal.tsx
index 246e0df..b59d8df 100644
--- a/superset-frontend/src/views/CRUD/annotation/AnnotationModal.tsx
+++ b/superset-frontend/src/views/CRUD/annotation/AnnotationModal.tsx
@@ -262,16 +262,16 @@ const AnnotationModal: FunctionComponent<AnnotationModalProps> = ({
           ) : (
             <StyledIcon name="plus-large" />
           )}
-          {isEditMode ? t('Edit Annotation') : t('Add Annotation')}
+          {isEditMode ? t('Edit annotation') : t('Add annotation')}
         </h4>
       }
     >
       <StyledAnnotationTitle>
-        <h4>{t('Basic Information')}</h4>
+        <h4>{t('Basic information')}</h4>
       </StyledAnnotationTitle>
       <AnnotationContainer>
         <div className="control-label">
-          {t('annotation name')}
+          {t('Annotation name')}
           <span className="required">*</span>
         </div>
         <input
@@ -304,7 +304,7 @@ const AnnotationModal: FunctionComponent<AnnotationModalProps> = ({
         />
       </AnnotationContainer>
       <StyledAnnotationTitle>
-        <h4>{t('Additional Information')}</h4>
+        <h4>{t('Additional information')}</h4>
       </StyledAnnotationTitle>
       <AnnotationContainer>
         <div className="control-label">{t('description')}</div>
@@ -316,7 +316,7 @@ const AnnotationModal: FunctionComponent<AnnotationModalProps> = ({
         />
       </AnnotationContainer>
       <AnnotationContainer>
-        <div className="control-label">{t('json metadata')}</div>
+        <div className="control-label">{t('JSON metadata')}</div>
         <StyledJsonEditor
           onChange={onJsonChange}
           value={
diff --git a/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayerModal.tsx b/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayerModal.tsx
index f5d1999..d410b86 100644
--- a/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayerModal.tsx
+++ b/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayerModal.tsx
@@ -215,17 +215,17 @@ const AnnotationLayerModal: FunctionComponent<AnnotationLayerModalProps> = ({
             <StyledIcon name="plus-large" />
           )}
           {isEditMode
-            ? t('Edit Annotation Layer Properties')
-            : t('Add Annotation Layer')}
+            ? t('Edit annotation layer properties')
+            : t('Add annotation layer')}
         </h4>
       }
     >
       <StyledAnnotationLayerTitle>
-        <h4>{t('Basic Information')}</h4>
+        <h4>{t('Basic information')}</h4>
       </StyledAnnotationLayerTitle>
       <LayerContainer>
         <div className="control-label">
-          {t('annotation layer name')}
+          {t('Annotation layer name')}
           <span className="required">*</span>
         </div>
         <input
diff --git a/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayersList.tsx b/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayersList.tsx
index 4057715..44892c8 100644
--- a/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayersList.tsx
+++ b/superset-frontend/src/views/CRUD/annotationlayers/AnnotationLayersList.tsx
@@ -64,7 +64,7 @@ function AnnotationLayersList({
     toggleBulkSelect,
   } = useListViewResource<AnnotationLayerObject>(
     'annotation_layer',
-    t('annotation layers'),
+    t('Annotation layers'),
     addDangerToast,
   );
 
@@ -178,7 +178,7 @@ function AnnotationLayersList({
 
           return moment(utc).format(MOMENT_FORMAT);
         },
-        Header: t('Last Modified'),
+        Header: t('Last modified'),
         accessor: 'changed_on',
         size: 'xl',
       },
@@ -203,14 +203,14 @@ function AnnotationLayersList({
 
           return moment(utc).format(MOMENT_FORMAT);
         },
-        Header: t('Created On'),
+        Header: t('Created on'),
         accessor: 'created_on',
         size: 'xl',
       },
       {
         accessor: 'created_by',
         disableSortBy: true,
-        Header: t('Created By'),
+        Header: t('Created by'),
         Cell: ({
           row: {
             original: { created_by: createdBy },
@@ -263,7 +263,7 @@ function AnnotationLayersList({
     subMenuButtons.push({
       name: (
         <>
-          <i className="fa fa-plus" /> {t('Annotation Layer')}
+          <i className="fa fa-plus" /> {t('Annotation layer')}
         </>
       ),
       buttonStyle: 'primary',
@@ -275,7 +275,7 @@ function AnnotationLayersList({
 
   if (canDelete) {
     subMenuButtons.push({
-      name: t('Bulk Select'),
+      name: t('Bulk select'),
       onClick: toggleBulkSelect,
       buttonStyle: 'secondary',
     });
@@ -284,7 +284,7 @@ function AnnotationLayersList({
   const filters: Filters = useMemo(
     () => [
       {
-        Header: t('Created By'),
+        Header: t('Created by'),
         id: 'created_by',
         input: 'select',
         operator: 'rel_o_m',
@@ -320,7 +320,7 @@ function AnnotationLayersList({
       }}
     >
       <>
-        <i className="fa fa-plus" /> {t('Annotation Layer')}
+        <i className="fa fa-plus" /> {t('Annotation layer')}
       </>
     </Button>
   );
@@ -336,7 +336,7 @@ function AnnotationLayersList({
 
   return (
     <>
-      <SubMenu name={t('Annotation Layers')} buttons={subMenuButtons} />
+      <SubMenu name={t('Annotation layers')} buttons={subMenuButtons} />
       <AnnotationLayerModal
         addDangerToast={addDangerToast}
         layer={currentAnnotationLayer}
diff --git a/superset-frontend/src/views/CRUD/chart/ChartCard.tsx b/superset-frontend/src/views/CRUD/chart/ChartCard.tsx
index 6f7bc81..c6be62a 100644
--- a/superset-frontend/src/views/CRUD/chart/ChartCard.tsx
+++ b/superset-frontend/src/views/CRUD/chart/ChartCard.tsx
@@ -69,7 +69,7 @@ export default function ChartCard({
       {canDelete && (
         <Menu.Item>
           <ConfirmStatusChange
-            title={t('Please Confirm')}
+            title={t('Please confirm')}
             description={
               <>
                 {t('Are you sure you want to delete')} <b>{chart.slice_name}</b>
diff --git a/superset-frontend/src/views/CRUD/chart/ChartList.tsx b/superset-frontend/src/views/CRUD/chart/ChartList.tsx
index f262578..2148fc0 100644
--- a/superset-frontend/src/views/CRUD/chart/ChartList.tsx
+++ b/superset-frontend/src/views/CRUD/chart/ChartList.tsx
@@ -217,7 +217,7 @@ function ChartList(props: ChartListProps) {
             original: { viz_type: vizType },
           },
         }: any) => registry.get(vizType)?.name || vizType,
-        Header: t('Visualization Type'),
+        Header: t('Visualization type'),
         accessor: 'viz_type',
         size: 'xxl',
       },
@@ -244,7 +244,7 @@ function ChartList(props: ChartListProps) {
             },
           },
         }: any) => <a href={changedByUrl}>{changedByName}</a>,
-        Header: t('Modified By'),
+        Header: t('Modified by'),
         accessor: 'changed_by.first_name',
         size: 'xl',
       },
@@ -254,7 +254,7 @@ function ChartList(props: ChartListProps) {
             original: { changed_on_delta_humanized: changedOn },
           },
         }: any) => <span className="no-wrap">{changedOn}</span>,
-        Header: t('Last Modified'),
+        Header: t('Last modified'),
         accessor: 'changed_on_delta_humanized',
         size: 'xl',
       },
@@ -270,7 +270,7 @@ function ChartList(props: ChartListProps) {
           },
         }: any) =>
           createdBy ? `${createdBy.first_name} ${createdBy.last_name}` : '',
-        Header: t('Created By'),
+        Header: t('Created by'),
         accessor: 'created_by',
         disableSortBy: true,
         size: 'xl',
@@ -294,7 +294,7 @@ function ChartList(props: ChartListProps) {
             <span className="actions">
               {canDelete && (
                 <ConfirmStatusChange
-                  title={t('Please Confirm')}
+                  title={t('Please confirm')}
                   description={
                     <>
                       {t('Are you sure you want to delete')}{' '}
@@ -388,7 +388,7 @@ function ChartList(props: ChartListProps) {
       paginate: true,
     },
     {
-      Header: t('Created By'),
+      Header: t('Created by'),
       id: 'created_by',
       input: 'select',
       operator: FilterOperators.relationOneMany,
@@ -409,7 +409,7 @@ function ChartList(props: ChartListProps) {
       paginate: true,
     },
     {
-      Header: t('Viz Type'),
+      Header: t('Viz type'),
       id: 'viz_type',
       input: 'select',
       operator: FilterOperators.equals,
@@ -480,13 +480,13 @@ function ChartList(props: ChartListProps) {
     {
       desc: true,
       id: 'changed_on_delta_humanized',
-      label: 'Recently Modified',
+      label: 'Recently modified',
       value: 'recently_modified',
     },
     {
       desc: false,
       id: 'changed_on_delta_humanized',
-      label: 'Least Recently Modified',
+      label: 'Least recently modified',
       value: 'least_recently_modified',
     },
   ];
@@ -510,7 +510,7 @@ function ChartList(props: ChartListProps) {
   const subMenuButtons: SubMenuProps['buttons'] = [];
   if (canDelete || canExport) {
     subMenuButtons.push({
-      name: t('Bulk Select'),
+      name: t('Bulk select'),
       buttonStyle: 'secondary',
       onClick: toggleBulkSelect,
     });
diff --git a/superset-frontend/src/views/CRUD/csstemplates/CssTemplateModal.tsx b/superset-frontend/src/views/CRUD/csstemplates/CssTemplateModal.tsx
index 7614e15..5589121 100644
--- a/superset-frontend/src/views/CRUD/csstemplates/CssTemplateModal.tsx
+++ b/superset-frontend/src/views/CRUD/csstemplates/CssTemplateModal.tsx
@@ -219,17 +219,17 @@ const CssTemplateModal: FunctionComponent<CssTemplateModalProps> = ({
             <StyledIcon name="plus-large" />
           )}
           {isEditMode
-            ? t('Edit CSS Template Properties')
-            : t('Add CSS Template')}
+            ? t('Edit CSS template properties')
+            : t('Add CSS template')}
         </h4>
       }
     >
       <StyledCssTemplateTitle>
-        <h4>{t('Basic Information')}</h4>
+        <h4>{t('Basic information')}</h4>
       </StyledCssTemplateTitle>
       <TemplateContainer>
         <div className="control-label">
-          {t('css template name')}
+          {t('CSS template name')}
           <span className="required">*</span>
         </div>
         <input
diff --git a/superset-frontend/src/views/CRUD/csstemplates/CssTemplatesList.tsx b/superset-frontend/src/views/CRUD/csstemplates/CssTemplatesList.tsx
index bcd6ebd..cc87c6b 100644
--- a/superset-frontend/src/views/CRUD/csstemplates/CssTemplatesList.tsx
+++ b/superset-frontend/src/views/CRUD/csstemplates/CssTemplatesList.tsx
@@ -63,7 +63,7 @@ function CssTemplatesList({
     toggleBulkSelect,
   } = useListViewResource<TemplateObject>(
     'css_template',
-    t('css templates'),
+    t('CSS templates'),
     addDangerToast,
   );
   const [cssTemplateModalOpen, setCssTemplateModalOpen] = useState<boolean>(
@@ -155,7 +155,7 @@ function CssTemplatesList({
             </TooltipWrapper>
           );
         },
-        Header: t('Last Modified'),
+        Header: t('Last modified'),
         accessor: 'changed_on_delta_humanized',
         size: 'xl',
         disableSortBy: true,
@@ -181,7 +181,7 @@ function CssTemplatesList({
 
           return moment(utc).fromNow();
         },
-        Header: t('Created On'),
+        Header: t('Created on'),
         accessor: 'created_on',
         size: 'xl',
         disableSortBy: true,
@@ -189,7 +189,7 @@ function CssTemplatesList({
       {
         accessor: 'created_by',
         disableSortBy: true,
-        Header: t('Created By'),
+        Header: t('Created by'),
         Cell: ({
           row: {
             original: { created_by: createdBy },
@@ -237,7 +237,7 @@ function CssTemplatesList({
   );
 
   const menuData: SubMenuProps = {
-    name: t('CSS Templates'),
+    name: t('CSS templates'),
   };
 
   const subMenuButtons: SubMenuProps['buttons'] = [];
@@ -246,7 +246,7 @@ function CssTemplatesList({
     subMenuButtons.push({
       name: (
         <>
-          <i className="fa fa-plus" /> {t('Css Template')}
+          <i className="fa fa-plus" /> {t('CSS template')}
         </>
       ),
       buttonStyle: 'primary',
@@ -259,7 +259,7 @@ function CssTemplatesList({
 
   if (canDelete) {
     subMenuButtons.push({
-      name: t('Bulk Select'),
+      name: t('Bulk select'),
       onClick: toggleBulkSelect,
       buttonStyle: 'secondary',
     });
@@ -270,7 +270,7 @@ function CssTemplatesList({
   const filters: Filters = useMemo(
     () => [
       {
-        Header: t('Created By'),
+        Header: t('Created by'),
         id: 'created_by',
         input: 'select',
         operator: 'rel_o_m',


[superset] 07/38: Apply capitalization guidelines - iteration 3 (#12343) (#12449)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 200cc1a5c4905f8bb724f5fa3d64ee488874faf4
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Fri Jan 22 15:11:28 2021 -0300

    Apply capitalization guidelines - iteration 3 (#12343) (#12449)
---
 .../cypress-base/cypress/integration/dashboard/save.test.js       | 2 +-
 superset-frontend/src/CRUD/CollectionTable.tsx                    | 2 +-
 superset-frontend/src/components/Menu/NewMenu.tsx                 | 2 +-
 superset-frontend/src/components/Select/Select.stories.tsx        | 2 +-
 .../src/dashboard/components/ColorSchemeControlWrapper.jsx        | 2 +-
 superset-frontend/src/dashboard/components/CssEditor.jsx          | 2 +-
 superset-frontend/src/dashboard/components/Header.jsx             | 4 ++--
 .../src/dashboard/components/HeaderActionsDropdown.jsx            | 4 ++--
 superset-frontend/src/dashboard/components/PropertiesModal.jsx    | 8 ++++----
 .../src/dashboard/components/RefreshIntervalModal.tsx             | 2 +-
 superset-frontend/src/dashboard/components/SaveModal.tsx          | 2 +-
 11 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/superset-frontend/cypress-base/cypress/integration/dashboard/save.test.js b/superset-frontend/cypress-base/cypress/integration/dashboard/save.test.js
index ff8dd49..757a118 100644
--- a/superset-frontend/cypress-base/cypress/integration/dashboard/save.test.js
+++ b/superset-frontend/cypress-base/cypress/integration/dashboard/save.test.js
@@ -92,7 +92,7 @@ describe('Dashboard save action', () => {
 
         // open color scheme dropdown
         cy.get('.ant-modal-body')
-          .contains('Color Scheme')
+          .contains('Color scheme')
           .parents('.ControlHeader')
           .next('.Select')
           .click()
diff --git a/superset-frontend/src/CRUD/CollectionTable.tsx b/superset-frontend/src/CRUD/CollectionTable.tsx
index 480e593..8166034 100644
--- a/superset-frontend/src/CRUD/CollectionTable.tsx
+++ b/superset-frontend/src/CRUD/CollectionTable.tsx
@@ -314,7 +314,7 @@ export default class CRUDCollection extends React.PureComponent<
                 data-test="add-item-button"
               >
                 <i data-test="crud-add-table-item" className="fa fa-plus" />{' '}
-                {t('Add Item')}
+                {t('Add item')}
               </Button>
             </span>
           )}
diff --git a/superset-frontend/src/components/Menu/NewMenu.tsx b/superset-frontend/src/components/Menu/NewMenu.tsx
index a9e2a90..d13ed1a 100644
--- a/superset-frontend/src/components/Menu/NewMenu.tsx
+++ b/superset-frontend/src/components/Menu/NewMenu.tsx
@@ -23,7 +23,7 @@ import NavDropdown from 'src/components/NavDropdown';
 
 const dropdownItems = [
   {
-    label: t('SQL Query'),
+    label: t('SQL query'),
     url: '/superset/sqllab',
     icon: 'fa-fw fa-search',
   },
diff --git a/superset-frontend/src/components/Select/Select.stories.tsx b/superset-frontend/src/components/Select/Select.stories.tsx
index dc10420..72cffdd 100644
--- a/superset-frontend/src/components/Select/Select.stories.tsx
+++ b/superset-frontend/src/components/Select/Select.stories.tsx
@@ -28,7 +28,7 @@ const OPTIONS = [
 ];
 
 export default {
-  title: 'Select Component',
+  title: 'Select component',
   argTypes: {
     options: {
       type: 'select',
diff --git a/superset-frontend/src/dashboard/components/ColorSchemeControlWrapper.jsx b/superset-frontend/src/dashboard/components/ColorSchemeControlWrapper.jsx
index 21db6ba..871dad6 100644
--- a/superset-frontend/src/dashboard/components/ColorSchemeControlWrapper.jsx
+++ b/superset-frontend/src/dashboard/components/ColorSchemeControlWrapper.jsx
@@ -53,7 +53,7 @@ class ColorSchemeControlWrapper extends React.PureComponent {
         description={t(
           "Any color palette selected here will override the colors applied to this dashboard's individual charts",
         )}
-        label={t('Color Scheme')}
+        label={t('Color scheme')}
         name="color_scheme"
         onChange={this.props.onChange}
         value={colorScheme}
diff --git a/superset-frontend/src/dashboard/components/CssEditor.jsx b/superset-frontend/src/dashboard/components/CssEditor.jsx
index 396276f..19cfd1c 100644
--- a/superset-frontend/src/dashboard/components/CssEditor.jsx
+++ b/superset-frontend/src/dashboard/components/CssEditor.jsx
@@ -85,7 +85,7 @@ class CssEditor extends React.PureComponent {
           <div>
             {this.renderTemplateSelector()}
             <div style={{ zIndex: 1 }}>
-              <h5>{t('Live CSS Editor')}</h5>
+              <h5>{t('Live CSS editor')}</h5>
               <div style={{ border: 'solid 1px grey' }}>
                 <AceCssEditor
                   minLines={12}
diff --git a/superset-frontend/src/dashboard/components/Header.jsx b/superset-frontend/src/dashboard/components/Header.jsx
index 9ef5471..e155413 100644
--- a/superset-frontend/src/dashboard/components/Header.jsx
+++ b/superset-frontend/src/dashboard/components/Header.jsx
@@ -456,7 +456,7 @@ class Header extends React.PureComponent {
                     buttonStyle="default"
                     data-test="discard-changes-button"
                   >
-                    {t('Discard Changes')}
+                    {t('Discard changes')}
                   </Button>
                   <Button
                     buttonSize="small"
@@ -482,7 +482,7 @@ class Header extends React.PureComponent {
             <>
               <span
                 role="button"
-                title="Edit Dashboard"
+                title="Edit dashboard"
                 tabIndex={0}
                 className="action-button"
                 onClick={this.toggleEditMode}
diff --git a/superset-frontend/src/dashboard/components/HeaderActionsDropdown.jsx b/superset-frontend/src/dashboard/components/HeaderActionsDropdown.jsx
index b18056d..e5eafa4 100644
--- a/superset-frontend/src/dashboard/components/HeaderActionsDropdown.jsx
+++ b/superset-frontend/src/dashboard/components/HeaderActionsDropdown.jsx
@@ -201,7 +201,7 @@ class HeaderActionsDropdown extends React.PureComponent {
       lastModifiedTime,
     } = this.props;
 
-    const emailTitle = t('Superset Dashboard');
+    const emailTitle = t('Superset dashboard');
     const emailSubject = `${emailTitle} ${dashboardTitle}`;
     const emailBody = t('Check out this dashboard: ');
 
@@ -302,7 +302,7 @@ class HeaderActionsDropdown extends React.PureComponent {
 
         {!editMode && (
           <Menu.Item key={MENU_KEYS.TOGGLE_FULLSCREEN}>
-            {t('Toggle FullScreen')}
+            {t('Toggle fullscreen')}
           </Menu.Item>
         )}
       </Menu>
diff --git a/superset-frontend/src/dashboard/components/PropertiesModal.jsx b/superset-frontend/src/dashboard/components/PropertiesModal.jsx
index 1cc75b1..f45f483 100644
--- a/superset-frontend/src/dashboard/components/PropertiesModal.jsx
+++ b/superset-frontend/src/dashboard/components/PropertiesModal.jsx
@@ -292,7 +292,7 @@ class PropertiesModal extends React.PureComponent {
       <Modal
         show={this.props.show}
         onHide={this.props.onHide}
-        title={t('Dashboard Properties')}
+        title={t('Dashboard properties')}
         footer={
           <>
             <Button
@@ -321,7 +321,7 @@ class PropertiesModal extends React.PureComponent {
         <form data-test="dashboard-edit-properties-form" onSubmit={this.submit}>
           <Row>
             <Col md={12}>
-              <h3>{t('Basic Information')}</h3>
+              <h3>{t('Basic information')}</h3>
             </Col>
           </Row>
           <Row>
@@ -338,7 +338,7 @@ class PropertiesModal extends React.PureComponent {
               />
             </Col>
             <Col md={6}>
-              <FormLabel htmlFor="embed-height">{t('URL Slug')}</FormLabel>
+              <FormLabel htmlFor="embed-height">{t('URL slug')}</FormLabel>
               <FormControl
                 name="slug"
                 type="text"
@@ -397,7 +397,7 @@ class PropertiesModal extends React.PureComponent {
               {isAdvancedOpen && (
                 <>
                   <FormLabel htmlFor="json_metadata">
-                    {t('JSON Metadata')}
+                    {t('JSON metadata')}
                   </FormLabel>
                   <StyledJsonEditor
                     showLoadingForImport
diff --git a/superset-frontend/src/dashboard/components/RefreshIntervalModal.tsx b/superset-frontend/src/dashboard/components/RefreshIntervalModal.tsx
index 9be1dd7..a16b457 100644
--- a/superset-frontend/src/dashboard/components/RefreshIntervalModal.tsx
+++ b/superset-frontend/src/dashboard/components/RefreshIntervalModal.tsx
@@ -112,7 +112,7 @@ class RefreshIntervalModal extends React.PureComponent<
       <StyledModalTrigger
         ref={this.modalRef}
         triggerNode={this.props.triggerNode}
-        modalTitle={t('Refresh Interval')}
+        modalTitle={t('Refresh interval')}
         modalBody={
           <div>
             <FormLabel>{t('Refresh frequency')}</FormLabel>
diff --git a/superset-frontend/src/dashboard/components/SaveModal.tsx b/superset-frontend/src/dashboard/components/SaveModal.tsx
index c8f327b..a377edb 100644
--- a/superset-frontend/src/dashboard/components/SaveModal.tsx
+++ b/superset-frontend/src/dashboard/components/SaveModal.tsx
@@ -178,7 +178,7 @@ class SaveModal extends React.PureComponent<SaveModalProps, SaveModalState> {
       <ModalTrigger
         ref={this.setModalRef}
         triggerNode={this.props.triggerNode}
-        modalTitle={t('Save Dashboard')}
+        modalTitle={t('Save dashboard')}
         modalBody={
           <FormGroup>
             <Radio


[superset] 10/38: refactor(explore): move MetricControl and FilterControl to sub-component (#12446)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 74f64b1794cd9a4423b1a5ccbf443debb2b59611
Author: Yongjie Zhao <yo...@gmail.com>
AuthorDate: Tue Jan 19 22:46:28 2021 +0800

    refactor(explore): move MetricControl and FilterControl to sub-component (#12446)
    
    * wip
    
    * wip
    
    * wip
    
    * wip
    
    * move spec
    
    * wip
    
    * wip
    
    * remove unused file
    
    * wip
    
    * wip
    
    * Update superset-frontend/spec/javascripts/explore/components/AdhocFilterEditPopoverSqlTabContent_spec.jsx
    
    Co-authored-by: Ville Brofeldt <33...@users.noreply.github.com>
    
    * Update superset-frontend/spec/javascripts/explore/components/AdhocFilterOption_spec.jsx
    
    Co-authored-by: Ville Brofeldt <33...@users.noreply.github.com>
    
    * Update superset-frontend/spec/javascripts/explore/components/AdhocMetricEditPopoverTitle_spec.jsx
    
    Co-authored-by: Ville Brofeldt <33...@users.noreply.github.com>
    
    Co-authored-by: Ville Brofeldt <33...@users.noreply.github.com>
---
 .../spec/javascripts/explore/AdhocFilter_spec.js   |  2 +-
 .../spec/javascripts/explore/AdhocMetric_spec.js   |  4 +++-
 .../explore/components/AdhocFilterControl_spec.jsx |  6 ++---
 ...AdhocFilterEditPopoverSimpleTabContent_spec.jsx |  6 ++---
 .../AdhocFilterEditPopoverSqlTabContent_spec.jsx   |  4 ++--
 .../components/AdhocFilterEditPopover_spec.jsx     | 10 ++++----
 .../explore/components/AdhocFilterOption_spec.jsx  |  4 ++--
 .../AdhocMetricEditPopoverTitle_spec.jsx           |  2 +-
 .../components/AdhocMetricEditPopover_spec.jsx     |  6 +++--
 .../explore/components/AdhocMetricOption_spec.jsx  |  4 ++--
 .../components/AdhocMetricStaticOption_spec.jsx    |  6 +++--
 .../components/FilterDefinitionOption_spec.jsx     |  8 ++++---
 .../components/FixedOrMetricControl_spec.jsx       |  4 ++--
 .../components/MetricDefinitionOption_spec.jsx     |  2 +-
 .../components/MetricDefinitionValue_spec.jsx      |  6 ++---
 .../explore/components/MetricsControl_spec.jsx     |  6 +++--
 .../components/withAsyncVerification_spec.tsx      |  2 +-
 .../src/explore/components/OptionControls.tsx      |  4 ++--
 .../controls/FilterControl}/AdhocFilter.js         |  4 ++--
 .../{ => FilterControl}/AdhocFilterControl.jsx     | 28 +++++++++++-----------
 .../FilterControl}/AdhocFilterEditPopover.jsx      |  6 ++---
 .../AdhocFilterEditPopoverSimpleTabContent.jsx     | 10 ++++----
 .../AdhocFilterEditPopoverSqlTabContent.jsx        |  6 ++---
 .../FilterControl}/AdhocFilterOption.jsx           | 10 ++++----
 .../FilterControl}/AdhocFilterPopoverTrigger.tsx   |  6 ++---
 .../controls/FilterControl}/adhocFilterType.js     |  4 ++--
 .../components/controls/FixedOrMetricControl.jsx   |  2 +-
 .../controls/MetricControl}/AdhocMetric.js         |  2 +-
 .../MetricControl}/AdhocMetricEditPopover.jsx      |  8 +++----
 .../MetricControl}/AdhocMetricEditPopoverTitle.jsx |  0
 .../MetricControl}/AdhocMetricOption.jsx           | 10 ++++----
 .../MetricControl}/AdhocMetricPopoverTrigger.tsx   |  6 ++---
 .../MetricControl}/AdhocMetricStaticOption.jsx     |  2 +-
 .../MetricControl}/FilterDefinitionOption.jsx      |  4 ++--
 .../MetricControl}/MetricDefinitionOption.jsx      | 10 ++++----
 .../MetricControl}/MetricDefinitionValue.jsx       | 12 +++++-----
 .../{ => MetricControl}/MetricsControl.jsx         | 24 +++++++++----------
 .../controls/MetricControl}/adhocMetricType.js     |  6 ++---
 .../controls/MetricControl}/savedMetricType.js     |  0
 .../controls/MetricControl}/types.ts               |  0
 .../src/explore/components/controls/index.js       |  4 ++--
 41 files changed, 130 insertions(+), 120 deletions(-)

diff --git a/superset-frontend/spec/javascripts/explore/AdhocFilter_spec.js b/superset-frontend/spec/javascripts/explore/AdhocFilter_spec.js
index 9b119e8..90dcdf0 100644
--- a/superset-frontend/spec/javascripts/explore/AdhocFilter_spec.js
+++ b/superset-frontend/spec/javascripts/explore/AdhocFilter_spec.js
@@ -19,7 +19,7 @@
 import AdhocFilter, {
   EXPRESSION_TYPES,
   CLAUSES,
-} from 'src/explore/AdhocFilter';
+} from 'src/explore/components/controls/FilterControl/AdhocFilter';
 
 describe('AdhocFilter', () => {
   it('sets filterOptionName in constructor', () => {
diff --git a/superset-frontend/spec/javascripts/explore/AdhocMetric_spec.js b/superset-frontend/spec/javascripts/explore/AdhocMetric_spec.js
index 0dbb2d9..f3b7d08 100644
--- a/superset-frontend/spec/javascripts/explore/AdhocMetric_spec.js
+++ b/superset-frontend/spec/javascripts/explore/AdhocMetric_spec.js
@@ -16,8 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import AdhocMetric, { EXPRESSION_TYPES } from 'src/explore/AdhocMetric';
 import { AGGREGATES } from 'src/explore/constants';
+import AdhocMetric, {
+  EXPRESSION_TYPES,
+} from 'src/explore/components/controls/MetricControl/AdhocMetric';
 
 const valueColumn = { type: 'DOUBLE', column_name: 'value' };
 
diff --git a/superset-frontend/spec/javascripts/explore/components/AdhocFilterControl_spec.jsx b/superset-frontend/spec/javascripts/explore/components/AdhocFilterControl_spec.jsx
index 94af81c..a22d615 100644
--- a/superset-frontend/spec/javascripts/explore/components/AdhocFilterControl_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/AdhocFilterControl_spec.jsx
@@ -25,11 +25,11 @@ import { supersetTheme } from '@superset-ui/core';
 import AdhocFilter, {
   EXPRESSION_TYPES,
   CLAUSES,
-} from 'src/explore/AdhocFilter';
-import AdhocFilterControl from 'src/explore/components/controls/AdhocFilterControl';
+} from 'src/explore/components/controls/FilterControl/AdhocFilter';
 import { LabelsContainer } from 'src/explore/components/OptionControls';
-import AdhocMetric from 'src/explore/AdhocMetric';
 import { AGGREGATES, OPERATORS } from 'src/explore/constants';
+import AdhocFilterControl from 'src/explore/components/controls/FilterControl/AdhocFilterControl';
+import AdhocMetric from 'src/explore/components/controls/MetricControl/AdhocMetric';
 
 const simpleAdhocFilter = new AdhocFilter({
   expressionType: EXPRESSION_TYPES.SIMPLE,
diff --git a/superset-frontend/spec/javascripts/explore/components/AdhocFilterEditPopoverSimpleTabContent_spec.jsx b/superset-frontend/spec/javascripts/explore/components/AdhocFilterEditPopoverSimpleTabContent_spec.jsx
index 91e5d37..01a83ca 100644
--- a/superset-frontend/spec/javascripts/explore/components/AdhocFilterEditPopoverSimpleTabContent_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/AdhocFilterEditPopoverSimpleTabContent_spec.jsx
@@ -25,10 +25,10 @@ import { FormGroup } from 'react-bootstrap';
 import AdhocFilter, {
   EXPRESSION_TYPES,
   CLAUSES,
-} from 'src/explore/AdhocFilter';
-import AdhocMetric from 'src/explore/AdhocMetric';
-import AdhocFilterEditPopoverSimpleTabContent from 'src/explore/components/AdhocFilterEditPopoverSimpleTabContent';
+} from 'src/explore/components/controls/FilterControl/AdhocFilter';
 import { AGGREGATES } from 'src/explore/constants';
+import AdhocFilterEditPopoverSimpleTabContent from 'src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent';
+import AdhocMetric from 'src/explore/components/controls/MetricControl/AdhocMetric';
 
 const simpleAdhocFilter = new AdhocFilter({
   expressionType: EXPRESSION_TYPES.SIMPLE,
diff --git a/superset-frontend/spec/javascripts/explore/components/AdhocFilterEditPopoverSqlTabContent_spec.jsx b/superset-frontend/spec/javascripts/explore/components/AdhocFilterEditPopoverSqlTabContent_spec.jsx
index 57f0a8b..e0da5e0 100644
--- a/superset-frontend/spec/javascripts/explore/components/AdhocFilterEditPopoverSqlTabContent_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/AdhocFilterEditPopoverSqlTabContent_spec.jsx
@@ -25,8 +25,8 @@ import { FormGroup } from 'react-bootstrap';
 import AdhocFilter, {
   EXPRESSION_TYPES,
   CLAUSES,
-} from 'src/explore/AdhocFilter';
-import AdhocFilterEditPopoverSqlTabContent from 'src/explore/components/AdhocFilterEditPopoverSqlTabContent';
+} from 'src/explore/components/controls/FilterControl/AdhocFilter';
+import AdhocFilterEditPopoverSqlTabContent from 'src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent';
 
 const sqlAdhocFilter = new AdhocFilter({
   expressionType: EXPRESSION_TYPES.SQL,
diff --git a/superset-frontend/spec/javascripts/explore/components/AdhocFilterEditPopover_spec.jsx b/superset-frontend/spec/javascripts/explore/components/AdhocFilterEditPopover_spec.jsx
index 51ad246..492b112 100644
--- a/superset-frontend/spec/javascripts/explore/components/AdhocFilterEditPopover_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/AdhocFilterEditPopover_spec.jsx
@@ -27,12 +27,12 @@ import Tabs from 'src/common/components/Tabs';
 import AdhocFilter, {
   EXPRESSION_TYPES,
   CLAUSES,
-} from 'src/explore/AdhocFilter';
-import AdhocMetric from 'src/explore/AdhocMetric';
-import AdhocFilterEditPopover from 'src/explore/components/AdhocFilterEditPopover';
-import AdhocFilterEditPopoverSimpleTabContent from 'src/explore/components/AdhocFilterEditPopoverSimpleTabContent';
-import AdhocFilterEditPopoverSqlTabContent from 'src/explore/components/AdhocFilterEditPopoverSqlTabContent';
+} from 'src/explore/components/controls/FilterControl/AdhocFilter';
 import { AGGREGATES } from 'src/explore/constants';
+import AdhocFilterEditPopover from 'src/explore/components/controls/FilterControl/AdhocFilterEditPopover';
+import AdhocFilterEditPopoverSimpleTabContent from 'src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent';
+import AdhocFilterEditPopoverSqlTabContent from 'src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent';
+import AdhocMetric from 'src/explore/components/controls/MetricControl/AdhocMetric';
 
 const simpleAdhocFilter = new AdhocFilter({
   expressionType: EXPRESSION_TYPES.SIMPLE,
diff --git a/superset-frontend/spec/javascripts/explore/components/AdhocFilterOption_spec.jsx b/superset-frontend/spec/javascripts/explore/components/AdhocFilterOption_spec.jsx
index 781f221..c76937e 100644
--- a/superset-frontend/spec/javascripts/explore/components/AdhocFilterOption_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/AdhocFilterOption_spec.jsx
@@ -25,8 +25,8 @@ import Popover from 'src/common/components/Popover';
 import AdhocFilter, {
   EXPRESSION_TYPES,
   CLAUSES,
-} from 'src/explore/AdhocFilter';
-import AdhocFilterOption from 'src/explore/components/AdhocFilterOption';
+} from 'src/explore/components/controls/FilterControl/AdhocFilter';
+import AdhocFilterOption from 'src/explore/components/controls/FilterControl/AdhocFilterOption';
 
 const simpleAdhocFilter = new AdhocFilter({
   expressionType: EXPRESSION_TYPES.SIMPLE,
diff --git a/superset-frontend/spec/javascripts/explore/components/AdhocMetricEditPopoverTitle_spec.jsx b/superset-frontend/spec/javascripts/explore/components/AdhocMetricEditPopoverTitle_spec.jsx
index 9d9bbe2..be02d6b 100644
--- a/superset-frontend/spec/javascripts/explore/components/AdhocMetricEditPopoverTitle_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/AdhocMetricEditPopoverTitle_spec.jsx
@@ -22,7 +22,7 @@ import sinon from 'sinon';
 import { shallow } from 'enzyme';
 import { Tooltip } from 'src/common/components/Tooltip';
 
-import AdhocMetricEditPopoverTitle from 'src/explore/components/AdhocMetricEditPopoverTitle';
+import AdhocMetricEditPopoverTitle from 'src/explore/components/controls/MetricControl/AdhocMetricEditPopoverTitle';
 
 const title = {
   label: 'Title',
diff --git a/superset-frontend/spec/javascripts/explore/components/AdhocMetricEditPopover_spec.jsx b/superset-frontend/spec/javascripts/explore/components/AdhocMetricEditPopover_spec.jsx
index d026c2b..59bc07c 100644
--- a/superset-frontend/spec/javascripts/explore/components/AdhocMetricEditPopover_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/AdhocMetricEditPopover_spec.jsx
@@ -23,9 +23,11 @@ import { shallow } from 'enzyme';
 import { FormGroup } from 'react-bootstrap';
 import Button from 'src/components/Button';
 
-import AdhocMetric, { EXPRESSION_TYPES } from 'src/explore/AdhocMetric';
-import AdhocMetricEditPopover from 'src/explore/components/AdhocMetricEditPopover';
 import { AGGREGATES } from 'src/explore/constants';
+import AdhocMetricEditPopover from 'src/explore/components/controls/MetricControl/AdhocMetricEditPopover';
+import AdhocMetric, {
+  EXPRESSION_TYPES,
+} from 'src/explore/components/controls/MetricControl/AdhocMetric';
 
 const columns = [
   { type: 'VARCHAR(255)', column_name: 'source', id: 1 },
diff --git a/superset-frontend/spec/javascripts/explore/components/AdhocMetricOption_spec.jsx b/superset-frontend/spec/javascripts/explore/components/AdhocMetricOption_spec.jsx
index ceef77d..559520f 100644
--- a/superset-frontend/spec/javascripts/explore/components/AdhocMetricOption_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/AdhocMetricOption_spec.jsx
@@ -22,9 +22,9 @@ import sinon from 'sinon';
 import { shallow } from 'enzyme';
 
 import Popover from 'src/common/components/Popover';
-import AdhocMetric from 'src/explore/AdhocMetric';
-import AdhocMetricOption from 'src/explore/components/AdhocMetricOption';
 import { AGGREGATES } from 'src/explore/constants';
+import AdhocMetricOption from 'src/explore/components/controls/MetricControl/AdhocMetricOption';
+import AdhocMetric from 'src/explore/components/controls/MetricControl/AdhocMetric';
 
 const columns = [
   { type: 'VARCHAR(255)', column_name: 'source' },
diff --git a/superset-frontend/spec/javascripts/explore/components/AdhocMetricStaticOption_spec.jsx b/superset-frontend/spec/javascripts/explore/components/AdhocMetricStaticOption_spec.jsx
index 7d3b926..cba7178 100644
--- a/superset-frontend/spec/javascripts/explore/components/AdhocMetricStaticOption_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/AdhocMetricStaticOption_spec.jsx
@@ -20,9 +20,11 @@
 import React from 'react';
 import { shallow } from 'enzyme';
 
-import AdhocMetricStaticOption from 'src/explore/components/AdhocMetricStaticOption';
-import AdhocMetric, { EXPRESSION_TYPES } from 'src/explore/AdhocMetric';
 import { AGGREGATES } from 'src/explore/constants';
+import AdhocMetricStaticOption from 'src/explore/components/controls/MetricControl/AdhocMetricStaticOption';
+import AdhocMetric, {
+  EXPRESSION_TYPES,
+} from 'src/explore/components/controls/MetricControl/AdhocMetric';
 
 const sumValueAdhocMetric = new AdhocMetric({
   expressionType: EXPRESSION_TYPES.SIMPLE,
diff --git a/superset-frontend/spec/javascripts/explore/components/FilterDefinitionOption_spec.jsx b/superset-frontend/spec/javascripts/explore/components/FilterDefinitionOption_spec.jsx
index fbdb712..f12212f 100644
--- a/superset-frontend/spec/javascripts/explore/components/FilterDefinitionOption_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/FilterDefinitionOption_spec.jsx
@@ -21,10 +21,12 @@ import React from 'react';
 import { shallow } from 'enzyme';
 
 import { ColumnOption } from '@superset-ui/chart-controls';
-import FilterDefinitionOption from 'src/explore/components/FilterDefinitionOption';
-import AdhocMetricStaticOption from 'src/explore/components/AdhocMetricStaticOption';
-import AdhocMetric, { EXPRESSION_TYPES } from 'src/explore/AdhocMetric';
+import FilterDefinitionOption from 'src/explore/components/controls/MetricControl/FilterDefinitionOption';
+import AdhocMetricStaticOption from 'src/explore/components/controls/MetricControl/AdhocMetricStaticOption';
 import { AGGREGATES } from 'src/explore/constants';
+import AdhocMetric, {
+  EXPRESSION_TYPES,
+} from 'src/explore/components/controls/MetricControl/AdhocMetric';
 
 const sumValueAdhocMetric = new AdhocMetric({
   expressionType: EXPRESSION_TYPES.SIMPLE,
diff --git a/superset-frontend/spec/javascripts/explore/components/FixedOrMetricControl_spec.jsx b/superset-frontend/spec/javascripts/explore/components/FixedOrMetricControl_spec.jsx
index 3ad9a3c..dae156c 100644
--- a/superset-frontend/spec/javascripts/explore/components/FixedOrMetricControl_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/FixedOrMetricControl_spec.jsx
@@ -20,9 +20,9 @@
 import React from 'react';
 import { shallow } from 'enzyme';
 
-import FixedOrMetricControl from 'src/explore/components/controls/FixedOrMetricControl';
 import TextControl from 'src/explore/components/controls/TextControl';
-import MetricsControl from 'src/explore/components/controls/MetricsControl';
+import FixedOrMetricControl from 'src/explore/components/controls/FixedOrMetricControl';
+import MetricsControl from 'src/explore/components/controls/MetricControl/MetricsControl';
 
 const defaultProps = {
   value: {},
diff --git a/superset-frontend/spec/javascripts/explore/components/MetricDefinitionOption_spec.jsx b/superset-frontend/spec/javascripts/explore/components/MetricDefinitionOption_spec.jsx
index b626674..d1a93df 100644
--- a/superset-frontend/spec/javascripts/explore/components/MetricDefinitionOption_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/MetricDefinitionOption_spec.jsx
@@ -21,7 +21,7 @@ import configureStore from 'redux-mock-store';
 import { shallow } from 'enzyme';
 import { ColumnOption, MetricOption } from '@superset-ui/chart-controls';
 
-import MetricDefinitionOption from 'src/explore/components/MetricDefinitionOption';
+import MetricDefinitionOption from 'src/explore/components/controls/MetricControl/MetricDefinitionOption';
 import AggregateOption from 'src/explore/components/AggregateOption';
 
 describe('MetricDefinitionOption', () => {
diff --git a/superset-frontend/spec/javascripts/explore/components/MetricDefinitionValue_spec.jsx b/superset-frontend/spec/javascripts/explore/components/MetricDefinitionValue_spec.jsx
index 9e22795..f2e038e 100644
--- a/superset-frontend/spec/javascripts/explore/components/MetricDefinitionValue_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/MetricDefinitionValue_spec.jsx
@@ -20,10 +20,10 @@
 import React from 'react';
 import { shallow } from 'enzyme';
 
-import MetricDefinitionValue from 'src/explore/components/MetricDefinitionValue';
-import AdhocMetricOption from 'src/explore/components/AdhocMetricOption';
-import AdhocMetric from 'src/explore/AdhocMetric';
 import { AGGREGATES } from 'src/explore/constants';
+import MetricDefinitionValue from 'src/explore/components/controls/MetricControl/MetricDefinitionValue';
+import AdhocMetricOption from 'src/explore/components/controls/MetricControl/AdhocMetricOption';
+import AdhocMetric from 'src/explore/components/controls/MetricControl/AdhocMetric';
 
 const sumValueAdhocMetric = new AdhocMetric({
   column: { type: 'DOUBLE', column_name: 'value' },
diff --git a/superset-frontend/spec/javascripts/explore/components/MetricsControl_spec.jsx b/superset-frontend/spec/javascripts/explore/components/MetricsControl_spec.jsx
index 638a20e..825b57e 100644
--- a/superset-frontend/spec/javascripts/explore/components/MetricsControl_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/MetricsControl_spec.jsx
@@ -21,11 +21,13 @@ import React from 'react';
 import sinon from 'sinon';
 import { shallow } from 'enzyme';
 
-import MetricsControl from 'src/explore/components/controls/MetricsControl';
 import { AGGREGATES } from 'src/explore/constants';
-import AdhocMetric, { EXPRESSION_TYPES } from 'src/explore/AdhocMetric';
 import { LabelsContainer } from 'src/explore/components/OptionControls';
 import { supersetTheme } from '@superset-ui/core';
+import MetricsControl from 'src/explore/components/controls/MetricControl/MetricsControl';
+import AdhocMetric, {
+  EXPRESSION_TYPES,
+} from 'src/explore/components/controls/MetricControl/AdhocMetric';
 
 const defaultProps = {
   name: 'metrics',
diff --git a/superset-frontend/spec/javascripts/explore/components/withAsyncVerification_spec.tsx b/superset-frontend/spec/javascripts/explore/components/withAsyncVerification_spec.tsx
index 35292ba..355f81c 100644
--- a/superset-frontend/spec/javascripts/explore/components/withAsyncVerification_spec.tsx
+++ b/superset-frontend/spec/javascripts/explore/components/withAsyncVerification_spec.tsx
@@ -21,12 +21,12 @@ import { ReactWrapper } from 'enzyme';
 import { styledMount as mount } from 'spec/helpers/theming';
 import { act } from 'react-dom/test-utils';
 
-import MetricsControl from 'src/explore/components/controls/MetricsControl';
 import withAsyncVerification, {
   ControlPropsWithExtras,
   WithAsyncVerificationOptions,
 } from 'src/explore/components/controls/withAsyncVerification';
 import { ExtraControlProps } from '@superset-ui/chart-controls';
+import MetricsControl from 'src/explore/components/controls/MetricControl/MetricsControl';
 
 const VALID_METRIC = {
   metric_name: 'sum__value',
diff --git a/superset-frontend/src/explore/components/OptionControls.tsx b/superset-frontend/src/explore/components/OptionControls.tsx
index 8d157c8..c822b32 100644
--- a/superset-frontend/src/explore/components/OptionControls.tsx
+++ b/superset-frontend/src/explore/components/OptionControls.tsx
@@ -24,8 +24,8 @@ import { findDOMNode } from 'react-dom';
 import { DragSource, DropTarget } from 'react-dnd';
 import { styled, useTheme } from '@superset-ui/core';
 import { ColumnOption } from '@superset-ui/chart-controls';
-import Icon from '../../components/Icon';
-import { savedMetricType } from '../types';
+import Icon from 'src/components/Icon';
+import { savedMetricType } from 'src/explore/components/controls/MetricControl/types';
 
 const TYPE = 'label-dnd';
 
diff --git a/superset-frontend/src/explore/AdhocFilter.js b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilter.js
similarity index 97%
rename from superset-frontend/src/explore/AdhocFilter.js
rename to superset-frontend/src/explore/components/controls/FilterControl/AdhocFilter.js
index 22e70c8..09fde0a 100644
--- a/superset-frontend/src/explore/AdhocFilter.js
+++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilter.js
@@ -16,8 +16,8 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { CUSTOM_OPERATORS } from './constants';
-import { getSimpleSQLExpression } from './exploreUtils';
+import { CUSTOM_OPERATORS } from 'src/explore/constants';
+import { getSimpleSQLExpression } from 'src/explore/exploreUtils';
 
 export const EXPRESSION_TYPES = {
   SIMPLE: 'SIMPLE',
diff --git a/superset-frontend/src/explore/components/controls/AdhocFilterControl.jsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterControl.jsx
similarity index 91%
rename from superset-frontend/src/explore/components/controls/AdhocFilterControl.jsx
rename to superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterControl.jsx
index f5c9f5d..bad9bba 100644
--- a/superset-frontend/src/explore/components/controls/AdhocFilterControl.jsx
+++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterControl.jsx
@@ -20,25 +20,25 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import { t, logging, SupersetClient, withTheme } from '@superset-ui/core';
 
-import ControlHeader from '../ControlHeader';
-import adhocFilterType from '../../propTypes/adhocFilterType';
-import adhocMetricType from '../../propTypes/adhocMetricType';
-import savedMetricType from '../../propTypes/savedMetricType';
-import columnType from '../../propTypes/columnType';
-import AdhocFilter, { CLAUSES, EXPRESSION_TYPES } from '../../AdhocFilter';
-import AdhocMetric from '../../AdhocMetric';
-import { OPERATORS } from '../../constants';
-import AdhocFilterOption from '../AdhocFilterOption';
-import FilterDefinitionOption from '../FilterDefinitionOption';
+import ControlHeader from 'src/explore/components/ControlHeader';
+import adhocMetricType from 'src/explore/components/controls/MetricControl/adhocMetricType';
+import savedMetricType from 'src/explore/components/controls/MetricControl/savedMetricType';
+import columnType from 'src/explore/propTypes/columnType';
+import AdhocMetric from 'src/explore/components/controls/MetricControl/AdhocMetric';
+import { OPERATORS } from 'src/explore/constants';
+import FilterDefinitionOption from 'src/explore/components/controls/MetricControl/FilterDefinitionOption';
 import {
   AddControlLabel,
   AddIconButton,
   HeaderContainer,
   LabelsContainer,
-} from '../OptionControls';
-import Icon from '../../../components/Icon';
-import AdhocFilterPopoverTrigger from '../AdhocFilterPopoverTrigger';
-import DndWithHTML5Backend from '../../DndContextProvider';
+} from 'src/explore/components/OptionControls';
+import Icon from 'src/components/Icon';
+import DndWithHTML5Backend from 'src/explore/DndContextProvider';
+import AdhocFilterPopoverTrigger from './AdhocFilterPopoverTrigger';
+import AdhocFilterOption from './AdhocFilterOption';
+import AdhocFilter, { CLAUSES, EXPRESSION_TYPES } from './AdhocFilter';
+import adhocFilterType from './adhocFilterType';
 
 const propTypes = {
   name: PropTypes.string,
diff --git a/superset-frontend/src/explore/components/AdhocFilterEditPopover.jsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopover.jsx
similarity index 96%
rename from superset-frontend/src/explore/components/AdhocFilterEditPopover.jsx
rename to superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopover.jsx
index 005d437..b1d47ef 100644
--- a/superset-frontend/src/explore/components/AdhocFilterEditPopover.jsx
+++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopover.jsx
@@ -23,9 +23,9 @@ import { styled, t } from '@superset-ui/core';
 
 import ErrorBoundary from 'src/components/ErrorBoundary';
 import Tabs from 'src/common/components/Tabs';
-import columnType from '../propTypes/columnType';
-import adhocMetricType from '../propTypes/adhocMetricType';
-import AdhocFilter, { EXPRESSION_TYPES } from '../AdhocFilter';
+import columnType from 'src/explore/propTypes/columnType';
+import adhocMetricType from 'src/explore/components/controls/MetricControl/adhocMetricType';
+import AdhocFilter, { EXPRESSION_TYPES } from './AdhocFilter';
 import AdhocFilterEditPopoverSimpleTabContent from './AdhocFilterEditPopoverSimpleTabContent';
 import AdhocFilterEditPopoverSqlTabContent from './AdhocFilterEditPopoverSqlTabContent';
 
diff --git a/superset-frontend/src/explore/components/AdhocFilterEditPopoverSimpleTabContent.jsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent.jsx
similarity index 97%
rename from superset-frontend/src/explore/components/AdhocFilterEditPopoverSimpleTabContent.jsx
rename to superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent.jsx
index 5856bfa..dbec5e6 100644
--- a/superset-frontend/src/explore/components/AdhocFilterEditPopoverSimpleTabContent.jsx
+++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent.jsx
@@ -23,9 +23,8 @@ import { Select } from 'src/common/components/Select';
 import { Input } from 'src/common/components';
 import { t, SupersetClient, styled } from '@superset-ui/core';
 
-import AdhocFilter, { EXPRESSION_TYPES, CLAUSES } from '../AdhocFilter';
-import adhocMetricType from '../propTypes/adhocMetricType';
-import columnType from '../propTypes/columnType';
+import adhocMetricType from 'src/explore/components/controls/MetricControl/adhocMetricType';
+import columnType from 'src/explore/propTypes/columnType';
 import {
   OPERATORS,
   OPERATORS_OPTIONS,
@@ -35,8 +34,9 @@ import {
   MULTI_OPERATORS,
   CUSTOM_OPERATORS,
   DISABLE_INPUT_OPERATORS,
-} from '../constants';
-import FilterDefinitionOption from './FilterDefinitionOption';
+} from 'src/explore/constants';
+import FilterDefinitionOption from 'src/explore/components/controls/MetricControl/FilterDefinitionOption';
+import AdhocFilter, { EXPRESSION_TYPES, CLAUSES } from './AdhocFilter';
 
 const SelectWithLabel = styled(Select)`
   .ant-select-selector::after {
diff --git a/superset-frontend/src/explore/components/AdhocFilterEditPopoverSqlTabContent.jsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent.jsx
similarity index 95%
rename from superset-frontend/src/explore/components/AdhocFilterEditPopoverSqlTabContent.jsx
rename to superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent.jsx
index ffd0175..7841d88 100644
--- a/superset-frontend/src/explore/components/AdhocFilterEditPopoverSqlTabContent.jsx
+++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent.jsx
@@ -24,9 +24,9 @@ import { t } from '@superset-ui/core';
 import { SQLEditor } from 'src/components/AsyncAceEditor';
 import sqlKeywords from 'src/SqlLab/utils/sqlKeywords';
 
-import AdhocFilter, { EXPRESSION_TYPES, CLAUSES } from '../AdhocFilter';
-import adhocMetricType from '../propTypes/adhocMetricType';
-import columnType from '../propTypes/columnType';
+import adhocMetricType from 'src/explore/components/controls/MetricControl/adhocMetricType';
+import columnType from 'src/explore/propTypes/columnType';
+import AdhocFilter, { EXPRESSION_TYPES, CLAUSES } from './AdhocFilter';
 
 const propTypes = {
   adhocFilter: PropTypes.instanceOf(AdhocFilter).isRequired,
diff --git a/superset-frontend/src/explore/components/AdhocFilterOption.jsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterOption.jsx
similarity index 86%
rename from superset-frontend/src/explore/components/AdhocFilterOption.jsx
rename to superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterOption.jsx
index a6b26c5..954bb8a 100644
--- a/superset-frontend/src/explore/components/AdhocFilterOption.jsx
+++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterOption.jsx
@@ -18,12 +18,12 @@
  */
 import React from 'react';
 import PropTypes from 'prop-types';
-import AdhocFilter from '../AdhocFilter';
-import columnType from '../propTypes/columnType';
-import adhocMetricType from '../propTypes/adhocMetricType';
+import columnType from 'src/explore/propTypes/columnType';
+import adhocMetricType from 'src/explore/components/controls/MetricControl/adhocMetricType';
+import { DraggableOptionControlLabel } from 'src/explore/components/OptionControls';
+import { OPTION_TYPES } from 'src/explore/components/optionTypes';
 import AdhocFilterPopoverTrigger from './AdhocFilterPopoverTrigger';
-import { DraggableOptionControlLabel } from './OptionControls';
-import { OPTION_TYPES } from './optionTypes';
+import AdhocFilter from './AdhocFilter';
 
 const propTypes = {
   adhocFilter: PropTypes.instanceOf(AdhocFilter).isRequired,
diff --git a/superset-frontend/src/explore/components/AdhocFilterPopoverTrigger.tsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterPopoverTrigger.tsx
similarity index 94%
rename from superset-frontend/src/explore/components/AdhocFilterPopoverTrigger.tsx
rename to superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterPopoverTrigger.tsx
index ce2fddf..ceab93b 100644
--- a/superset-frontend/src/explore/components/AdhocFilterPopoverTrigger.tsx
+++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterPopoverTrigger.tsx
@@ -21,10 +21,10 @@ import { t } from '@superset-ui/core';
 import { InfoTooltipWithTrigger } from '@superset-ui/chart-controls';
 
 import Popover from 'src/common/components/Popover';
+import columnType from 'src/explore/propTypes/columnType';
+import adhocMetricType from 'src/explore/components/controls/MetricControl/adhocMetricType';
 import AdhocFilterEditPopover from './AdhocFilterEditPopover';
-import AdhocFilter from '../AdhocFilter';
-import columnType from '../propTypes/columnType';
-import adhocMetricType from '../propTypes/adhocMetricType';
+import AdhocFilter from './AdhocFilter';
 
 interface AdhocFilterPopoverTriggerProps {
   adhocFilter: AdhocFilter;
diff --git a/superset-frontend/src/explore/propTypes/adhocFilterType.js b/superset-frontend/src/explore/components/controls/FilterControl/adhocFilterType.js
similarity index 93%
rename from superset-frontend/src/explore/propTypes/adhocFilterType.js
rename to superset-frontend/src/explore/components/controls/FilterControl/adhocFilterType.js
index 9bc1b94..f036fc0 100644
--- a/superset-frontend/src/explore/propTypes/adhocFilterType.js
+++ b/superset-frontend/src/explore/components/controls/FilterControl/adhocFilterType.js
@@ -18,8 +18,8 @@
  */
 import PropTypes from 'prop-types';
 
-import { OPERATORS } from '../constants';
-import { EXPRESSION_TYPES, CLAUSES } from '../AdhocFilter';
+import { OPERATORS } from 'src/explore/constants';
+import { EXPRESSION_TYPES, CLAUSES } from './AdhocFilter';
 
 export default PropTypes.oneOfType([
   PropTypes.shape({
diff --git a/superset-frontend/src/explore/components/controls/FixedOrMetricControl.jsx b/superset-frontend/src/explore/components/controls/FixedOrMetricControl.jsx
index d7cf050..d95df79 100644
--- a/superset-frontend/src/explore/components/controls/FixedOrMetricControl.jsx
+++ b/superset-frontend/src/explore/components/controls/FixedOrMetricControl.jsx
@@ -22,7 +22,7 @@ import { Panel } from 'react-bootstrap';
 
 import Label from 'src/components/Label';
 import TextControl from './TextControl';
-import MetricsControl from './MetricsControl';
+import MetricsControl from './MetricControl/MetricsControl';
 import ControlHeader from '../ControlHeader';
 import PopoverSection from '../../../components/PopoverSection';
 
diff --git a/superset-frontend/src/explore/AdhocMetric.js b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetric.js
similarity index 98%
rename from superset-frontend/src/explore/AdhocMetric.js
rename to superset-frontend/src/explore/components/controls/MetricControl/AdhocMetric.js
index 24b18da..f5a4885 100644
--- a/superset-frontend/src/explore/AdhocMetric.js
+++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetric.js
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { sqlaAutoGeneratedMetricRegex } from './constants';
+import { sqlaAutoGeneratedMetricRegex } from 'src/explore/constants';
 
 export const EXPRESSION_TYPES = {
   SIMPLE: 'SIMPLE',
diff --git a/superset-frontend/src/explore/components/AdhocMetricEditPopover.jsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover.jsx
similarity index 98%
rename from superset-frontend/src/explore/components/AdhocMetricEditPopover.jsx
rename to superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover.jsx
index a6218b3..bfe8391 100644
--- a/superset-frontend/src/explore/components/AdhocMetricEditPopover.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopover.jsx
@@ -30,10 +30,10 @@ import FormLabel from 'src/components/FormLabel';
 import { SQLEditor } from 'src/components/AsyncAceEditor';
 import sqlKeywords from 'src/SqlLab/utils/sqlKeywords';
 
-import { AGGREGATES_OPTIONS } from '../constants';
-import columnType from '../propTypes/columnType';
-import savedMetricType from '../propTypes/savedMetricType';
-import AdhocMetric, { EXPRESSION_TYPES } from '../AdhocMetric';
+import { AGGREGATES_OPTIONS } from 'src/explore/constants';
+import columnType from 'src/explore/propTypes/columnType';
+import savedMetricType from './savedMetricType';
+import AdhocMetric, { EXPRESSION_TYPES } from './AdhocMetric';
 
 const propTypes = {
   adhocMetric: PropTypes.instanceOf(AdhocMetric).isRequired,
diff --git a/superset-frontend/src/explore/components/AdhocMetricEditPopoverTitle.jsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopoverTitle.jsx
similarity index 100%
rename from superset-frontend/src/explore/components/AdhocMetricEditPopoverTitle.jsx
rename to superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopoverTitle.jsx
diff --git a/superset-frontend/src/explore/components/AdhocMetricOption.jsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricOption.jsx
similarity index 90%
rename from superset-frontend/src/explore/components/AdhocMetricOption.jsx
rename to superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricOption.jsx
index 77eab7c..a43d93f 100644
--- a/superset-frontend/src/explore/components/AdhocMetricOption.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricOption.jsx
@@ -19,12 +19,12 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import { Tooltip } from 'src/common/components/Tooltip';
-import AdhocMetric from '../AdhocMetric';
-import columnType from '../propTypes/columnType';
-import savedMetricType from '../propTypes/savedMetricType';
-import { DraggableOptionControlLabel } from './OptionControls';
+import columnType from 'src/explore/propTypes/columnType';
+import { DraggableOptionControlLabel } from 'src/explore/components/OptionControls';
+import { OPTION_TYPES } from 'src/explore/components/optionTypes';
+import AdhocMetric from './AdhocMetric';
+import savedMetricType from './savedMetricType';
 import AdhocMetricPopoverTrigger from './AdhocMetricPopoverTrigger';
-import { OPTION_TYPES } from './optionTypes';
 
 const propTypes = {
   adhocMetric: PropTypes.instanceOf(AdhocMetric),
diff --git a/superset-frontend/src/explore/components/AdhocMetricPopoverTrigger.tsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx
similarity index 96%
rename from superset-frontend/src/explore/components/AdhocMetricPopoverTrigger.tsx
rename to superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx
index 6179816..649d3fe 100644
--- a/superset-frontend/src/explore/components/AdhocMetricPopoverTrigger.tsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricPopoverTrigger.tsx
@@ -18,10 +18,10 @@
  */
 import React, { ReactNode } from 'react';
 import Popover from 'src/common/components/Popover';
-import AdhocMetricEditPopoverTitle from 'src/explore/components/AdhocMetricEditPopoverTitle';
+import AdhocMetricEditPopoverTitle from 'src/explore/components/controls/MetricControl/AdhocMetricEditPopoverTitle';
 import AdhocMetricEditPopover from './AdhocMetricEditPopover';
-import AdhocMetric from '../AdhocMetric';
-import { savedMetricType } from '../types';
+import AdhocMetric from './AdhocMetric';
+import { savedMetricType } from './types';
 
 export type AdhocMetricPopoverTriggerProps = {
   adhocMetric: AdhocMetric;
diff --git a/superset-frontend/src/explore/components/AdhocMetricStaticOption.jsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricStaticOption.jsx
similarity index 95%
rename from superset-frontend/src/explore/components/AdhocMetricStaticOption.jsx
rename to superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricStaticOption.jsx
index 7c6265c..ee5eed7 100644
--- a/superset-frontend/src/explore/components/AdhocMetricStaticOption.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricStaticOption.jsx
@@ -20,7 +20,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import { ColumnTypeLabel } from '@superset-ui/chart-controls';
 
-import adhocMetricType from '../propTypes/adhocMetricType';
+import adhocMetricType from './adhocMetricType';
 
 const propTypes = {
   adhocMetric: adhocMetricType,
diff --git a/superset-frontend/src/explore/components/FilterDefinitionOption.jsx b/superset-frontend/src/explore/components/controls/MetricControl/FilterDefinitionOption.jsx
similarity index 93%
rename from superset-frontend/src/explore/components/FilterDefinitionOption.jsx
rename to superset-frontend/src/explore/components/controls/MetricControl/FilterDefinitionOption.jsx
index 6fa227d..fd256b4 100644
--- a/superset-frontend/src/explore/components/FilterDefinitionOption.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/FilterDefinitionOption.jsx
@@ -20,9 +20,9 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import { ColumnOption, ColumnTypeLabel } from '@superset-ui/chart-controls';
 
+import columnType from 'src/explore/propTypes/columnType';
 import AdhocMetricStaticOption from './AdhocMetricStaticOption';
-import columnType from '../propTypes/columnType';
-import adhocMetricType from '../propTypes/adhocMetricType';
+import adhocMetricType from './adhocMetricType';
 
 const propTypes = {
   option: PropTypes.oneOfType([
diff --git a/superset-frontend/src/explore/components/MetricDefinitionOption.jsx b/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionOption.jsx
similarity index 84%
rename from superset-frontend/src/explore/components/MetricDefinitionOption.jsx
rename to superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionOption.jsx
index a484e24..91e239d 100644
--- a/superset-frontend/src/explore/components/MetricDefinitionOption.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionOption.jsx
@@ -20,11 +20,11 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import { ColumnOption, MetricOption } from '@superset-ui/chart-controls';
 
-import AggregateOption from './AggregateOption';
-import columnType from '../propTypes/columnType';
-import savedMetricType from '../propTypes/savedMetricType';
-import aggregateOptionType from '../propTypes/aggregateOptionType';
-import withToasts from '../../messageToasts/enhancers/withToasts';
+import AggregateOption from 'src/explore/components/AggregateOption';
+import columnType from 'src/explore/propTypes/columnType';
+import aggregateOptionType from 'src/explore/propTypes/aggregateOptionType';
+import withToasts from 'src/messageToasts/enhancers/withToasts';
+import savedMetricType from './savedMetricType';
 
 const propTypes = {
   option: PropTypes.oneOfType([
diff --git a/superset-frontend/src/explore/components/MetricDefinitionValue.jsx b/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionValue.jsx
similarity index 88%
rename from superset-frontend/src/explore/components/MetricDefinitionValue.jsx
rename to superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionValue.jsx
index 1a65da1..5bae01d 100644
--- a/superset-frontend/src/explore/components/MetricDefinitionValue.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionValue.jsx
@@ -18,13 +18,13 @@
  */
 import React from 'react';
 import PropTypes from 'prop-types';
+import columnType from 'src/explore/propTypes/columnType';
+import { DraggableOptionControlLabel } from 'src/explore/components/OptionControls';
+import { OPTION_TYPES } from 'src/explore/components/optionTypes';
 import AdhocMetricOption from './AdhocMetricOption';
-import AdhocMetric from '../AdhocMetric';
-import columnType from '../propTypes/columnType';
-import savedMetricType from '../propTypes/savedMetricType';
-import adhocMetricType from '../propTypes/adhocMetricType';
-import { DraggableOptionControlLabel } from './OptionControls';
-import { OPTION_TYPES } from './optionTypes';
+import AdhocMetric from './AdhocMetric';
+import savedMetricType from './savedMetricType';
+import adhocMetricType from './adhocMetricType';
 
 const propTypes = {
   option: PropTypes.oneOfType([savedMetricType, adhocMetricType]).isRequired,
diff --git a/superset-frontend/src/explore/components/controls/MetricsControl.jsx b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx
similarity index 94%
rename from superset-frontend/src/explore/components/controls/MetricsControl.jsx
rename to superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx
index f643e2b..83b5c16 100644
--- a/superset-frontend/src/explore/components/controls/MetricsControl.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx
@@ -20,27 +20,27 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import { t, withTheme } from '@superset-ui/core';
 import { isEqual } from 'lodash';
-import ControlHeader from '../ControlHeader';
-import MetricDefinitionOption from '../MetricDefinitionOption';
-import MetricDefinitionValue from '../MetricDefinitionValue';
-import AdhocMetric from '../../AdhocMetric';
-import columnType from '../../propTypes/columnType';
-import savedMetricType from '../../propTypes/savedMetricType';
-import adhocMetricType from '../../propTypes/adhocMetricType';
+import ControlHeader from 'src/explore/components/ControlHeader';
+import columnType from 'src/explore/propTypes/columnType';
 import {
   AGGREGATES_OPTIONS,
   sqlaAutoGeneratedMetricNameRegex,
   druidAutoGeneratedMetricRegex,
-} from '../../constants';
-import AdhocMetricPopoverTrigger from '../AdhocMetricPopoverTrigger';
-import Icon from '../../../components/Icon';
+} from 'src/explore/constants';
+import Icon from 'src/components/Icon';
 import {
   AddIconButton,
   AddControlLabel,
   HeaderContainer,
   LabelsContainer,
-} from '../OptionControls';
-import DndWithHTML5Backend from '../../DndContextProvider';
+} from 'src/explore/components/OptionControls';
+import DndWithHTML5Backend from 'src/explore/DndContextProvider';
+import MetricDefinitionOption from './MetricDefinitionOption';
+import MetricDefinitionValue from './MetricDefinitionValue';
+import AdhocMetric from './AdhocMetric';
+import savedMetricType from './savedMetricType';
+import adhocMetricType from './adhocMetricType';
+import AdhocMetricPopoverTrigger from './AdhocMetricPopoverTrigger';
 
 const propTypes = {
   name: PropTypes.string.isRequired,
diff --git a/superset-frontend/src/explore/propTypes/adhocMetricType.js b/superset-frontend/src/explore/components/controls/MetricControl/adhocMetricType.js
similarity index 89%
rename from superset-frontend/src/explore/propTypes/adhocMetricType.js
rename to superset-frontend/src/explore/components/controls/MetricControl/adhocMetricType.js
index 5ebf6e4..a03766e 100644
--- a/superset-frontend/src/explore/propTypes/adhocMetricType.js
+++ b/superset-frontend/src/explore/components/controls/MetricControl/adhocMetricType.js
@@ -18,9 +18,9 @@
  */
 import PropTypes from 'prop-types';
 
-import { AGGREGATES } from '../constants';
-import columnType from './columnType';
-import { EXPRESSION_TYPES } from '../AdhocMetric';
+import { AGGREGATES } from 'src/explore/constants';
+import columnType from 'src/explore/propTypes/columnType';
+import { EXPRESSION_TYPES } from './AdhocMetric';
 
 export default PropTypes.oneOfType([
   PropTypes.shape({
diff --git a/superset-frontend/src/explore/propTypes/savedMetricType.js b/superset-frontend/src/explore/components/controls/MetricControl/savedMetricType.js
similarity index 100%
rename from superset-frontend/src/explore/propTypes/savedMetricType.js
rename to superset-frontend/src/explore/components/controls/MetricControl/savedMetricType.js
diff --git a/superset-frontend/src/explore/types.ts b/superset-frontend/src/explore/components/controls/MetricControl/types.ts
similarity index 100%
rename from superset-frontend/src/explore/types.ts
rename to superset-frontend/src/explore/components/controls/MetricControl/types.ts
diff --git a/superset-frontend/src/explore/components/controls/index.js b/superset-frontend/src/explore/components/controls/index.js
index e3714db..ba82c3c 100644
--- a/superset-frontend/src/explore/components/controls/index.js
+++ b/superset-frontend/src/explore/components/controls/index.js
@@ -36,8 +36,8 @@ import TextControl from './TextControl';
 import TimeSeriesColumnControl from './TimeSeriesColumnControl';
 import ViewportControl from './ViewportControl';
 import VizTypeControl from './VizTypeControl';
-import MetricsControl from './MetricsControl';
-import AdhocFilterControl from './AdhocFilterControl';
+import MetricsControl from './MetricControl/MetricsControl';
+import AdhocFilterControl from './FilterControl/AdhocFilterControl';
 import FilterBoxItemControl from './FilterBoxItemControl';
 
 const controlMap = {


[superset] 13/38: Apply capitalization guidelines - iteration 6 (#12343) (#12452)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 6d22b42e41e1304c201b779a023efa640aa6a78c
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Fri Jan 22 02:45:44 2021 -0300

    Apply capitalization guidelines - iteration 6 (#12343) (#12452)
---
 .../explore/components/SelectControl_spec.jsx      |  8 +++----
 .../DateFilterControl/frame/AdvancedFrame.tsx      |  2 +-
 .../DateFilterControl/frame/CustomFrame.tsx        |  4 ++--
 .../components/controls/FilterBoxItemControl.jsx   | 10 ++++----
 .../explore/components/controls/SelectControl.jsx  |  6 ++---
 .../controls/TimeSeriesColumnControl.jsx           | 12 +++++-----
 .../src/explore/controlPanels/Separator.js         |  2 +-
 .../src/explore/controlPanels/TimeTable.js         |  2 +-
 .../src/explore/controlPanels/sections.jsx         | 28 +++++++++++-----------
 .../src/filters/components/Range/index.ts          |  4 ++--
 .../src/filters/components/Select/controlPanel.ts  |  8 +++----
 11 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/superset-frontend/spec/javascripts/explore/components/SelectControl_spec.jsx b/superset-frontend/spec/javascripts/explore/components/SelectControl_spec.jsx
index 35a0fcc..2c76ce4 100644
--- a/superset-frontend/spec/javascripts/explore/components/SelectControl_spec.jsx
+++ b/superset-frontend/spec/javascripts/explore/components/SelectControl_spec.jsx
@@ -78,7 +78,7 @@ describe('SelectControl', () => {
       onChange: sinon.spy(),
     };
     wrapper.setProps(selectAllProps);
-    wrapper.instance().onChange([{ meta: true, value: 'Select All' }]);
+    wrapper.instance().onChange([{ meta: true, value: 'Select all' }]);
     expect(selectAllProps.onChange.calledWith(expectedValues)).toBe(true);
   });
 
@@ -207,7 +207,7 @@ describe('SelectControl', () => {
         expect(wrapper.instance().optionsRemaining()).toEqual(2);
       });
     });
-    describe('with Select All', () => {
+    describe('with Select all', () => {
       it('does not count it', () => {
         const props = { ...defaultProps, multi: true, allowAll: true };
         const wrapper = mount(<SelectControl {...props} />);
@@ -234,9 +234,9 @@ describe('SelectControl', () => {
       };
       wrapper.setProps(selectAllProps);
       expect(wrapper.instance().getOptions(selectAllProps)).toContainEqual({
-        label: 'Select All',
+        label: 'Select all',
         meta: true,
-        value: 'Select All',
+        value: 'Select all',
       });
     });
 
diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/frame/AdvancedFrame.tsx b/superset-frontend/src/explore/components/controls/DateFilterControl/frame/AdvancedFrame.tsx
index 93ce72f..39a695c 100644
--- a/superset-frontend/src/explore/components/controls/DateFilterControl/frame/AdvancedFrame.tsx
+++ b/superset-frontend/src/explore/components/controls/DateFilterControl/frame/AdvancedFrame.tsx
@@ -48,7 +48,7 @@ export function AdvancedFrame(props: FrameComponentProps) {
 
   return (
     <>
-      <div className="section-title">{t('Configure Advanced Time Range')}</div>
+      <div className="section-title">{t('Configure advanced time range')}</div>
       <div className="control-label">{t('START')}</div>
       <Input
         key="since"
diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/frame/CustomFrame.tsx b/superset-frontend/src/explore/components/controls/DateFilterControl/frame/CustomFrame.tsx
index 2ad8e63..553aea9 100644
--- a/superset-frontend/src/explore/components/controls/DateFilterControl/frame/CustomFrame.tsx
+++ b/superset-frontend/src/explore/components/controls/DateFilterControl/frame/CustomFrame.tsx
@@ -118,7 +118,7 @@ export function CustomFrame(props: FrameComponentProps) {
 
   return (
     <div data-test="custom-frame">
-      <div className="section-title">{t('Configure Custom Time Range')}</div>
+      <div className="section-title">{t('Configure custom time range')}</div>
       <Row gutter={24}>
         <Col span={12}>
           <div className="control-label">{t('START')}</div>
@@ -226,7 +226,7 @@ export function CustomFrame(props: FrameComponentProps) {
       </Row>
       {sinceMode === 'relative' && untilMode === 'relative' && (
         <div className="control-anchor-to">
-          <div className="control-label">{t('ANCHOR TO')}</div>
+          <div className="control-label">{t('Anchor to')}</div>
           <Row align="middle">
             <Col>
               <Radio.Group
diff --git a/superset-frontend/src/explore/components/controls/FilterBoxItemControl.jsx b/superset-frontend/src/explore/components/controls/FilterBoxItemControl.jsx
index da7a003..418de45 100644
--- a/superset-frontend/src/explore/components/controls/FilterBoxItemControl.jsx
+++ b/superset-frontend/src/explore/components/controls/FilterBoxItemControl.jsx
@@ -181,7 +181,7 @@ export default class FilterBoxItemControl extends React.Component {
           }
         />
         <FormRow
-          label={t('Sort Metric')}
+          label={t('Sort metric')}
           tooltip={t('Metric to sort the results by')}
           control={
             <SelectControl
@@ -201,7 +201,7 @@ export default class FilterBoxItemControl extends React.Component {
           }
         />
         <FormRow
-          label={t('Sort Ascending')}
+          label={t('Sort ascending')}
           tooltip={t('Check for sorting ascending')}
           isCheckbox
           control={
@@ -212,7 +212,7 @@ export default class FilterBoxItemControl extends React.Component {
           }
         />
         <FormRow
-          label={t('Allow Multiple Selections')}
+          label={t('Allow multiple selections')}
           isCheckbox
           tooltip={t(
             'Multiple selections allowed, otherwise filter ' +
@@ -228,7 +228,7 @@ export default class FilterBoxItemControl extends React.Component {
           }
         />
         <FormRow
-          label={t('Search All Filter Options')}
+          label={t('Search all filter options')}
           tooltip={t(
             'By default, each filter loads at most 1000 choices at the initial page load. ' +
               'Check this box if you have more than 1000 filter values and want to enable dynamically ' +
@@ -278,7 +278,7 @@ export default class FilterBoxItemControl extends React.Component {
           trigger="click"
           placement="right"
           content={this.renderPopover()}
-          title={t('Filter Configuration')}
+          title={t('Filter configuration')}
         >
           <InfoTooltipWithTrigger
             icon="edit"
diff --git a/superset-frontend/src/explore/components/controls/SelectControl.jsx b/superset-frontend/src/explore/components/controls/SelectControl.jsx
index 799ded9..e192c17 100644
--- a/superset-frontend/src/explore/components/controls/SelectControl.jsx
+++ b/superset-frontend/src/explore/components/controls/SelectControl.jsx
@@ -184,7 +184,7 @@ export default class SelectControl extends React.PureComponent {
   }
 
   isMetaSelectAllOption(o) {
-    return o.meta && o.meta === true && o.label === 'Select All';
+    return o.meta && o.meta === true && o.label === 'Select all';
   }
 
   optionsIncludesSelectAll(o) {
@@ -205,8 +205,8 @@ export default class SelectControl extends React.PureComponent {
   }
 
   createMetaSelectAllOption() {
-    const option = { label: 'Select All', meta: true };
-    option[this.props.valueKey] = 'Select All';
+    const option = { label: 'Select all', meta: true };
+    option[this.props.valueKey] = 'Select all';
     return option;
   }
 
diff --git a/superset-frontend/src/explore/components/controls/TimeSeriesColumnControl.jsx b/superset-frontend/src/explore/components/controls/TimeSeriesColumnControl.jsx
index e981720..5e9e8ee 100644
--- a/superset-frontend/src/explore/components/controls/TimeSeriesColumnControl.jsx
+++ b/superset-frontend/src/explore/components/controls/TimeSeriesColumnControl.jsx
@@ -45,7 +45,7 @@ const propTypes = {
 };
 
 const defaultProps = {
-  label: t('Time Series Columns'),
+  label: t('Time series columns'),
   tooltip: '',
   colType: '',
   width: '',
@@ -65,14 +65,14 @@ const comparisonTypeOptions = [
   { value: 'value', label: 'Actual value' },
   { value: 'diff', label: 'Difference' },
   { value: 'perc', label: 'Percentage' },
-  { value: 'perc_change', label: 'Percentage Change' },
+  { value: 'perc_change', label: 'Percentage change' },
 ];
 
 const colTypeOptions = [
-  { value: 'time', label: 'Time Comparison' },
+  { value: 'time', label: 'Time comparison' },
   { value: 'contrib', label: 'Contribution' },
   { value: 'spark', label: 'Sparkline' },
-  { value: 'avg', label: 'Period Average' },
+  { value: 'avg', label: 'Period average' },
 ];
 
 export default class TimeSeriesColumnControl extends React.Component {
@@ -209,7 +209,7 @@ export default class TimeSeriesColumnControl extends React.Component {
           )}
         {['time', 'avg'].indexOf(this.state.colType) >= 0 &&
           this.formRow(
-            'Time Lag',
+            'Time lag',
             'Number of periods to compare against',
             'time-lag',
             <FormControl
@@ -221,7 +221,7 @@ export default class TimeSeriesColumnControl extends React.Component {
           )}
         {['spark'].indexOf(this.state.colType) >= 0 &&
           this.formRow(
-            'Time Ratio',
+            'Time ratio',
             'Number of periods to ratio against',
             'time-ratio',
             <FormControl
diff --git a/superset-frontend/src/explore/controlPanels/Separator.js b/superset-frontend/src/explore/controlPanels/Separator.js
index aaca4a6..588adea 100644
--- a/superset-frontend/src/explore/controlPanels/Separator.js
+++ b/superset-frontend/src/explore/controlPanels/Separator.js
@@ -29,7 +29,7 @@ export default {
             name: 'markup_type',
             config: {
               type: 'SelectControl',
-              label: t('Markup Type'),
+              label: t('Markup type'),
               clearable: false,
               choices: formatSelectOptions(['markdown', 'html']),
               default: 'markdown',
diff --git a/superset-frontend/src/explore/controlPanels/TimeTable.js b/superset-frontend/src/explore/controlPanels/TimeTable.js
index c370f30..3d72176 100644
--- a/superset-frontend/src/explore/controlPanels/TimeTable.js
+++ b/superset-frontend/src/explore/controlPanels/TimeTable.js
@@ -35,7 +35,7 @@ export default {
             name: 'column_collection',
             config: {
               type: 'CollectionControl',
-              label: t('Time Series Columns'),
+              label: t('Time series columns'),
               validators: [validateNonEmpty],
               controlName: 'TimeSeriesColumnControl',
             },
diff --git a/superset-frontend/src/explore/controlPanels/sections.jsx b/superset-frontend/src/explore/controlPanels/sections.jsx
index 29e7cda..d69a69e 100644
--- a/superset-frontend/src/explore/controlPanels/sections.jsx
+++ b/superset-frontend/src/explore/controlPanels/sections.jsx
@@ -28,7 +28,7 @@ export const druidTimeSeries = {
 };
 
 export const datasourceAndVizType = {
-  label: t('Chart Type'),
+  label: t('Chart type'),
   expanded: true,
   controlSetRows: [
     ['datasource'],
@@ -56,7 +56,7 @@ export const datasourceAndVizType = {
         name: 'url_params',
         config: {
           type: 'HiddenControl',
-          label: t('URL Parameters'),
+          label: t('URL parameters'),
           hidden: true,
           description: t('Extra parameters for use in jinja templated queries'),
         },
@@ -75,7 +75,7 @@ export const datasourceAndVizType = {
 };
 
 export const colorScheme = {
-  label: t('Color Scheme'),
+  label: t('Color scheme'),
   controlSetRows: [['color_scheme', 'label_colors']],
 };
 
@@ -87,7 +87,7 @@ export const sqlaTimeSeries = {
 };
 
 export const annotations = {
-  label: t('Annotations and Layers'),
+  label: t('Annotations and layers'),
   tabOverride: 'data',
   expanded: true,
   controlSetRows: [
@@ -98,7 +98,7 @@ export const annotations = {
           type: 'AnnotationLayerControl',
           label: '',
           default: [],
-          description: 'Annotation Layers',
+          description: 'Annotation layers',
           renderTrigger: true,
           tabOverride: 'data',
         },
@@ -121,7 +121,7 @@ export const NVD3TimeSeries = [
           name: 'order_desc',
           config: {
             type: 'CheckboxControl',
-            label: t('Sort Descending'),
+            label: t('Sort descending'),
             default: true,
             description: t('Whether to sort descending or ascending'),
           },
@@ -140,7 +140,7 @@ export const NVD3TimeSeries = [
     ],
   },
   {
-    label: t('Advanced Analytics'),
+    label: t('Advanced analytics'),
     tabOverride: 'data',
     description: t(
       'This section contains options ' +
@@ -148,13 +148,13 @@ export const NVD3TimeSeries = [
         'of query results',
     ),
     controlSetRows: [
-      [<h1 className="section-header">{t('Rolling Window')}</h1>],
+      [<h1 className="section-header">{t('Rolling window')}</h1>],
       [
         {
           name: 'rolling_type',
           config: {
             type: 'SelectControl',
-            label: t('Rolling Function'),
+            label: t('Rolling function'),
             default: 'None',
             choices: formatSelectOptions([
               'None',
@@ -185,7 +185,7 @@ export const NVD3TimeSeries = [
           name: 'min_periods',
           config: {
             type: 'TextControl',
-            label: t('Min Periods'),
+            label: t('Min periods'),
             isInt: true,
             description: t(
               'The minimum number of rolling periods required to show ' +
@@ -197,7 +197,7 @@ export const NVD3TimeSeries = [
           },
         },
       ],
-      [<h1 className="section-header">{t('Time Comparison')}</h1>],
+      [<h1 className="section-header">{t('Time comparison')}</h1>],
       [
         {
           name: 'time_compare',
@@ -205,7 +205,7 @@ export const NVD3TimeSeries = [
             type: 'SelectControl',
             multi: true,
             freeForm: true,
-            label: t('Time Shift'),
+            label: t('Time shift'),
             choices: formatSelectOptions([
               '1 day',
               '1 week',
@@ -231,7 +231,7 @@ export const NVD3TimeSeries = [
             label: t('Calculation type'),
             default: 'values',
             choices: [
-              ['values', 'Actual Values'],
+              ['values', 'Actual values'],
               ['absolute', 'Absolute difference'],
               ['percentage', 'Percentage change'],
               ['ratio', 'Ratio'],
@@ -244,7 +244,7 @@ export const NVD3TimeSeries = [
           },
         },
       ],
-      [<h1 className="section-header">{t('Python Functions')}</h1>],
+      [<h1 className="section-header">{t('Python functions')}</h1>],
       // eslint-disable-next-line jsx-a11y/heading-has-content
       [<h2 className="section-header">pandas.resample</h2>],
       [
diff --git a/superset-frontend/src/filters/components/Range/index.ts b/superset-frontend/src/filters/components/Range/index.ts
index 4a77fbb..73fbfa7 100644
--- a/superset-frontend/src/filters/components/Range/index.ts
+++ b/superset-frontend/src/filters/components/Range/index.ts
@@ -25,8 +25,8 @@ import thumbnail from './images/thumbnail.png';
 export default class AntdRangeFilterPlugin extends ChartPlugin {
   constructor() {
     const metadata = new ChartMetadata({
-      name: t('Range Filter Plugin'),
-      description: 'Range Filter Plugin using AntD',
+      name: t('Range filter plugin'),
+      description: 'Range filter plugin using AntD',
       isNativeFilter: true,
       thumbnail,
     });
diff --git a/superset-frontend/src/filters/components/Select/controlPanel.ts b/superset-frontend/src/filters/components/Select/controlPanel.ts
index 2432396..22ef1b2 100644
--- a/superset-frontend/src/filters/components/Select/controlPanel.ts
+++ b/superset-frontend/src/filters/components/Select/controlPanel.ts
@@ -44,7 +44,7 @@ const config: ControlPanelConfig = {
             name: 'multiSelect',
             config: {
               type: 'CheckboxControl',
-              label: t('Multiple Select'),
+              label: t('Multiple select'),
               default: multiSelect,
               description: t('Allow selecting multiple values'),
             },
@@ -55,7 +55,7 @@ const config: ControlPanelConfig = {
             name: 'enableEmptyFilter',
             config: {
               type: 'CheckboxControl',
-              label: t('Enable Empty Filter'),
+              label: t('Enable empty filter'),
               default: enableEmptyFilter,
               description: t(
                 'When selection is empty, should an always false filter event be emitted',
@@ -68,7 +68,7 @@ const config: ControlPanelConfig = {
             name: 'inverseSelection',
             config: {
               type: 'CheckboxControl',
-              label: t('Inverse Selection'),
+              label: t('Inverse selection'),
               default: inverseSelection,
               description: t('Exclude selected values'),
             },
@@ -79,7 +79,7 @@ const config: ControlPanelConfig = {
             name: 'showSearch',
             config: {
               type: 'CheckboxControl',
-              label: t('Search Field'),
+              label: t('Search field'),
               default: showSearch,
               description: t('Allow typing search terms'),
             },


[superset] 17/38: chore: bumping superset UI packages (0.16.7 + 0.16.8) (#12564)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 33dd4e55f2985ac1da800019cb15210e33d76aad
Author: Evan Rusackas <ev...@preset.io>
AuthorDate: Tue Jan 19 09:38:04 2021 -0800

    chore: bumping superset UI packages (0.16.7 + 0.16.8) (#12564)
    
    * chore: package bump manifest (package.json)
    
    * fresh package lock
---
 superset-frontend/package-lock.json | 399 +++++++++++++++++-------------------
 superset-frontend/package.json      |  54 ++---
 2 files changed, 218 insertions(+), 235 deletions(-)

diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json
index 7fc12b3..68cf991 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -18534,19 +18534,19 @@
       }
     },
     "@superset-ui/chart-controls": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/chart-controls/-/chart-controls-0.16.4.tgz",
-      "integrity": "sha512-85oMM54hhDPEdN8mcFC0ZHTSaQcykcZ1/thq10yGfDXBukwX+Sy8DKBfQe40gYScmyoEWRR6AtyYCUbNsyOmMg==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/chart-controls/-/chart-controls-0.16.7.tgz",
+      "integrity": "sha512-Fh54+ra6QLsdg6b0xk8dKSNMNPRHGsTmSbSnbCLTQpolMXIMfsYV+ll1Y8TwLvfio9u0sLFyMk2PZqG1/L5Hhg==",
       "requires": {
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/core": "0.16.7",
         "lodash": "^4.17.15",
         "prop-types": "^15.7.2"
       }
     },
     "@superset-ui/core": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/core/-/core-0.16.4.tgz",
-      "integrity": "sha512-WJlUFZkQWahtUGwvQguDCD8EGDM7PUQzHoA4iHBvul2kNeFYc3gDUmZ1+s3cr8XWbdFC5MHkww65Nw0Be8TOgg==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/core/-/core-0.16.7.tgz",
+      "integrity": "sha512-9i/o9ZC+dJibhoWZnoKGvxMMFcz65LjHuYk+hRspuRWA4qwobcdu64piQpfwuFVhw1yh3cbdxq+OSsNmNX9A9g==",
       "requires": {
         "@babel/runtime": "^7.1.2",
         "@emotion/core": "^10.0.28",
@@ -18626,12 +18626,12 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-calendar": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-calendar/-/legacy-plugin-chart-calendar-0.16.4.tgz",
-      "integrity": "sha512-+P3X+uCNr10RJ65/59z1l7e1R9IHlpll6YghK7E+EK6zj5tJjxw0l3KCVK6SOdXNbWnr3ffKTp3CdGSCEK34SA==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-calendar/-/legacy-plugin-chart-calendar-0.16.7.tgz",
+      "integrity": "sha512-hu+rqNVWdWNwFhkhzSGHRbxIo/JQgWosK1bQBWkaD02r+HwvCszG6euYz+3pBEd0TpdrrkhSV05oYx0GIOgLdQ==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "d3-array": "^2.0.3",
         "d3-selection": "^1.4.0",
         "d3-tip": "^0.9.1",
@@ -18646,24 +18646,24 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-chord": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-chord/-/legacy-plugin-chart-chord-0.16.4.tgz",
-      "integrity": "sha512-dbRz6zItl8ArxlBHS+JI8AoC59zTFRsvmVDn1qvLBR2n36oxVt6ZXRBojII+pgOCtmJpqjG08YCjFJ/OhLITqg==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-chord/-/legacy-plugin-chart-chord-0.16.7.tgz",
+      "integrity": "sha512-5oFgijHXw2hlRskkPUVcKBhx4B0L8v+T4hP6TZ7zMUs6mRQrMPevYI21JFV5DvH7qN6Tlnij03UKWSsOLTVWEQ==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "prop-types": "^15.6.2",
         "react": "^16.13.1"
       }
     },
     "@superset-ui/legacy-plugin-chart-country-map": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-country-map/-/legacy-plugin-chart-country-map-0.16.4.tgz",
-      "integrity": "sha512-5c6xtqEK5UGE3CUbs1+PBwEU/RaMv0GfW7d95GDYrM0+UgmAWn4ouzVBXQVFAxI0eH6J0iHAg2IZiQ8sWEte3Q==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-country-map/-/legacy-plugin-chart-country-map-0.16.7.tgz",
+      "integrity": "sha512-8kaBjj+HTRlqccrnimhj8PqOpoPvzo39d3tjhNR5hv9amxCVS23e5YxuAIXj0e8RO9mRK0uLGJA5vLKtDmCPfA==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "d3-array": "^2.0.3",
         "prop-types": "^15.6.2"
@@ -18677,34 +18677,34 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-event-flow": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-event-flow/-/legacy-plugin-chart-event-flow-0.16.4.tgz",
-      "integrity": "sha512-0j5A6DOwuqJKzqQoA5z+wFAAQOXnwHGAD48ylHSsLzEP/qFXhDGkicduCqm72VwpBDV2nxJVdxfv8ot7hgTXcw==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-event-flow/-/legacy-plugin-chart-event-flow-0.16.7.tgz",
+      "integrity": "sha512-h9FzN/ZUuVLzNhlG8npSHHu9pWLs9cSKnDCiCRqiR8qIklnCB1SBCezaNvjk2QnT17yTvEB48+Tu7TFMLZ5vlw==",
       "requires": {
         "@data-ui/event-flow": "^0.0.84",
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "prop-types": "^15.6.2"
       }
     },
     "@superset-ui/legacy-plugin-chart-force-directed": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-force-directed/-/legacy-plugin-chart-force-directed-0.16.4.tgz",
-      "integrity": "sha512-CSlt46tomfiB8Way64Saxp8gFZYjkrepc/BVLAhcXcAXnmCbssULLPBFDDNdQnTzXbIizb73Y1pMKOEfx5MCNg==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-force-directed/-/legacy-plugin-chart-force-directed-0.16.7.tgz",
+      "integrity": "sha512-Uns5lvgO+Q9LMV7xpBcFVUhB4WivlWaRpeZnfcc6PMDhNBFG6ahRsYfz+a8xO1VB0Qsqlr5XC/cK40cUlcTjhQ==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "prop-types": "^15.7.2"
       }
     },
     "@superset-ui/legacy-plugin-chart-heatmap": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-heatmap/-/legacy-plugin-chart-heatmap-0.16.4.tgz",
-      "integrity": "sha512-LVCIEixeJPLk0Cn98aCT05H8OVmNerMq/h8Yi/HdOtD35HRkmpgEM1rMUHrDHCrpfUlKq1oNMaQ+qVeMXWuk0Q==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-heatmap/-/legacy-plugin-chart-heatmap-0.16.7.tgz",
+      "integrity": "sha512-XsYlfpPD1kRbt/2VgORu2M0Z2cOzDz1uIxj4yh3LxhA7FPAHzv1RXalOSs3HhxZNhwPbwd4dmyESmIBhhKWJSg==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "d3-svg-legend": "^1.x",
         "d3-tip": "^0.9.1",
@@ -18712,14 +18712,14 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-histogram": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-histogram/-/legacy-plugin-chart-histogram-0.16.4.tgz",
-      "integrity": "sha512-WAXSi8Zusb8BYR8hfpZ3Z7uZ0q1H4dncuzHILreY9InW8J5YV58prwkQoiTN7odH6YaoT0bPVjrlRG1jR79Amw==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-histogram/-/legacy-plugin-chart-histogram-0.16.7.tgz",
+      "integrity": "sha512-QX2e6A0xNbnEhWzJxJNCXEQHyfTNcZCQZ3YaiNdR21DmEAkVxOe7cp45QETOJ+AMVOTOpQgbD8u7Hw129IqxUg==",
       "requires": {
         "@data-ui/histogram": "^0.0.84",
         "@data-ui/theme": "^0.0.84",
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "@vx/legend": "^0.0.198",
         "@vx/responsive": "^0.0.197",
         "@vx/scale": "^0.0.197",
@@ -18787,12 +18787,12 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-horizon": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-horizon/-/legacy-plugin-chart-horizon-0.16.4.tgz",
-      "integrity": "sha512-2Guz2uuawdK5YdJ/KIw0ewjSDYNxCHzHzaxMts7Mu3CdiVYB5ob8NdreRJqBEk4CSo/fNdk30zO6chSmDKYpAg==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-horizon/-/legacy-plugin-chart-horizon-0.16.7.tgz",
+      "integrity": "sha512-3VMcLQhzhm5YFcykVDgyJ5RmFur+rMnZ3iYn++vTAapZ+RjW2NwAta0PGusJvUbNdmf4EpEb5fN7s0ev4wa6/Q==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "d3-array": "^2.0.3",
         "d3-scale": "^3.0.1",
         "prop-types": "^15.6.2"
@@ -18818,12 +18818,12 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-map-box": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-map-box/-/legacy-plugin-chart-map-box-0.16.4.tgz",
-      "integrity": "sha512-gsG+4EQYnvAxqCLFuEzsvFnsbNc1e2fVdveLiiWmSKErcTXQMIpN0KTjVRnc7Y7Z+t76wGI6jX1qowMjFwR6Tw==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-map-box/-/legacy-plugin-chart-map-box-0.16.7.tgz",
+      "integrity": "sha512-MAd4tsUZYPj+KGGohd5Tz3gwbhh/0SRHy5EeovZt9zND1D/M0K/eU3fra6XU0Bw2duOUyIr+Dd3OzTaXUvTRPA==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "immutable": "^3.8.2",
         "mapbox-gl": "^0.53.0",
         "prop-types": "^15.6.2",
@@ -18840,118 +18840,118 @@
       }
     },
     "@superset-ui/legacy-plugin-chart-paired-t-test": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-paired-t-test/-/legacy-plugin-chart-paired-t-test-0.16.4.tgz",
-      "integrity": "sha512-AqJWceanxwmD7HGL0V/nD8TT2h+Tq9wJ/PMmJK/OcegYk8A0n7L46ibbiiLhNUHgWOCSN2BckLT9gRZvWSkijg==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-paired-t-test/-/legacy-plugin-chart-paired-t-test-0.16.7.tgz",
+      "integrity": "sha512-sDt1DQaFKs4YX7DF9n+kbui18wDZOuYpPWA9QcBgHUbSKDaX26knBeD43JUGVaqMc8NmYVO6bVNBgoB8PrU89w==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "distributions": "^1.0.0",
         "prop-types": "^15.6.2",
         "reactable-arc": "0.15.0"
       }
     },
     "@superset-ui/legacy-plugin-chart-parallel-coordinates": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-parallel-coordinates/-/legacy-plugin-chart-parallel-coordinates-0.16.4.tgz",
-      "integrity": "sha512-U0WMD/Jcxmn27pUeQxk3UqCK+aZUmp/Fa1V0pSnke2lBLAf4hBnkxsnU+Xap6cPXzKmTKThZApo6+YgPy/oTYw==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-parallel-coordinates/-/legacy-plugin-chart-parallel-coordinates-0.16.7.tgz",
+      "integrity": "sha512-TcIHSKvaA2Lt2LVIbSqoyTAMOekh720LPPh3KnqmfnwvA98YAHZl2tyAueIZ4jcbFVd8PVaNiaQbfKnQbS2Xpw==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "prop-types": "^15.7.2"
       }
     },
     "@superset-ui/legacy-plugin-chart-partition": {
-      "version": "0.16.6",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-partition/-/legacy-plugin-chart-partition-0.16.6.tgz",
-      "integrity": "sha512-N/JrdGFSWA0tKeUEc8znDkqFBeKWdP6F9dXpCWF1uwsGwxYeSOV+lgrJlCTYYOOFnIGe8s9FijoqScrnWJ0EyA==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-partition/-/legacy-plugin-chart-partition-0.16.7.tgz",
+      "integrity": "sha512-n4s/lHo7sV/ZRyQJJgannpCJ+IT/YalMRpkN7Ei2uXAvO3MLQVYZVwokZ0pEwpvihQSuOpHlqcwh8aDBm2gpeA==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "d3-hierarchy": "^1.1.8",
         "prop-types": "^15.6.2"
       }
     },
     "@superset-ui/legacy-plugin-chart-pivot-table": {
-      "version": "0.16.6",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-pivot-table/-/legacy-plugin-chart-pivot-table-0.16.6.tgz",
-      "integrity": "sha512-5golzZMM4E1MuAMdPYJeg+6vrDTo1WFbMEBWIvsC4mI0ckzdSF8WW5XFvJ819fQHERICcdpgujYHgiSRm3mXjQ==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-pivot-table/-/legacy-plugin-chart-pivot-table-0.16.7.tgz",
+      "integrity": "sha512-BIQfZDIF/3WAH69wwW1ew9G8V9/GKSp5obbLGG5eXVGF6Aq0UyJmwyeVLcNcdcEW36UhhUjbHZLEOSs5LQP92Q==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "datatables.net-bs": "^1.10.15",
         "prop-types": "^15.6.2"
       }
     },
     "@superset-ui/legacy-plugin-chart-rose": {
-      "version": "0.16.6",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-rose/-/legacy-plugin-chart-rose-0.16.6.tgz",
-      "integrity": "sha512-ngXsW3pM5pcydbMin1P7lHoaZC7k12aMXirUqfv99fkpGIDd8OTdewgE7rPN262MIoPIolny6oGKtWGX+qu28Q==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-rose/-/legacy-plugin-chart-rose-0.16.7.tgz",
+      "integrity": "sha512-0k0ydm8GVnMdfLPbWhuHegoIJNnuY690DPG9qeha0o9rGJ5GA2T91hE87tMM58D/EFUwRtjy0Zo5+DHATeFrHQ==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "nvd3": "1.8.6",
         "prop-types": "^15.6.2"
       }
     },
     "@superset-ui/legacy-plugin-chart-sankey": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey/-/legacy-plugin-chart-sankey-0.16.4.tgz",
-      "integrity": "sha512-Pi1y4ngGwc7GwGQ7GpuhsJoVxb1LFSvVh8nI52/DLLOYpfkOc7i/xQ6TVQM/Ep/2Vj2T9vVWUpsgt18Roqku4Q==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey/-/legacy-plugin-chart-sankey-0.16.7.tgz",
+      "integrity": "sha512-sAsc7E7ha4q3SkuwnjS7jWhn4YEyzbZUA0Ryb6u5Kc/2PqPKtvT+ViF+bZUDvpoSdwxmgiLrYSWk5GtBhLkLHQ==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "d3-sankey": "^0.4.2",
         "prop-types": "^15.6.2"
       }
     },
     "@superset-ui/legacy-plugin-chart-sankey-loop": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey-loop/-/legacy-plugin-chart-sankey-loop-0.16.4.tgz",
-      "integrity": "sha512-5khuNutTwZdOisoUo9hJ4NtKhh8rqCouVaFdB8nrySCMMxOCvISQBmzHakXp8ILUSONAinwx15dqbMFtNILhhQ==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey-loop/-/legacy-plugin-chart-sankey-loop-0.16.7.tgz",
+      "integrity": "sha512-L3l3OGpfLxHkb+St/6WBtsjg+F0kAJlrmg/fuaHEzeA0EV50Og8y0h5RrbyyWTNueiosTfqtVgX2fMGFoHPN0w==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "d3-sankey-diagram": "^0.7.3",
         "d3-selection": "^1.4.0",
         "prop-types": "^15.6.2"
       }
     },
     "@superset-ui/legacy-plugin-chart-sunburst": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sunburst/-/legacy-plugin-chart-sunburst-0.16.4.tgz",
-      "integrity": "sha512-ruHNP7jhHwScsk1w2+5GaO3xlVC53GjPaueDqTwnBOucNtqBmVCUBIfC6AtDf+ickEpDO/0EafauKrisVPXpXg==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sunburst/-/legacy-plugin-chart-sunburst-0.16.7.tgz",
+      "integrity": "sha512-VQeuisMTPZRaQjiXimoSAuNYu5YFBVyQaovvqCxe1jmyGSWA7hIHFqLMimZxCVZv3AMd4Qwb/9/wQkFJwLRxxA==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "prop-types": "^15.6.2"
       }
     },
     "@superset-ui/legacy-plugin-chart-treemap": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-treemap/-/legacy-plugin-chart-treemap-0.16.4.tgz",
-      "integrity": "sha512-etGlfzd6af9xbj+dw79f1szNkYtRd6f02+PRK/i16m6DzRty1XAwSG2BjXV7hutnj3MMn/gvyGGzNn77L0fR4Q==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-treemap/-/legacy-plugin-chart-treemap-0.16.7.tgz",
+      "integrity": "sha512-LKseexUjopJA5Wm2rCkpjG/kClVsDwlCpOY4SHnN4EeOq2jMi2z9U+aomVj3HAWmjLvgVdO/nY9uOJq4MSV/3g==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "d3-hierarchy": "^1.1.8",
         "d3-selection": "^1.4.0",
         "prop-types": "^15.6.2"
       }
     },
     "@superset-ui/legacy-plugin-chart-world-map": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-world-map/-/legacy-plugin-chart-world-map-0.16.4.tgz",
-      "integrity": "sha512-nl9zycAW4fhO2p5/Idk+v/SF8E+9iAt+9hbmstIs7q9REO70/UavBQlBAkU7WDIB7YFuXmLNffZdADGB3fIkQw==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-world-map/-/legacy-plugin-chart-world-map-0.16.7.tgz",
+      "integrity": "sha512-c77CKfUtXCf9I5A87cYhxxuOGdBQS9oLNKYWWmV7bFRIKIGm6U2BsmSbFQ3sjRbgZTolrS4g7vJ51dkH3CzwoA==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "d3-array": "^2.4.0",
         "d3-color": "^1.4.1",
@@ -18972,13 +18972,13 @@
       }
     },
     "@superset-ui/legacy-preset-chart-big-number": {
-      "version": "0.16.6",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-big-number/-/legacy-preset-chart-big-number-0.16.6.tgz",
-      "integrity": "sha512-D8gK2vYSEguCT5gK83r/rNN5zCAjDqjfNV54927bORvyOAot8u5UrRRsNb4UD8hmXoC0rGlQ+fFqYnUOJ9tayw==",
+      "version": "0.16.8",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-big-number/-/legacy-preset-chart-big-number-0.16.8.tgz",
+      "integrity": "sha512-f34LNQBFFakxGleerh6nrHg/0V8Rf7IVxGaDc7IgQcj9Yb3Zoy0vYXoyn6VLBkfKVg1TmsxtuBT9Xf7tV6FNuQ==",
       "requires": {
         "@data-ui/xy-chart": "^0.0.84",
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "@types/d3-color": "^1.2.2",
         "@types/shortid": "^0.0.29",
         "d3-color": "^1.2.3",
@@ -19011,13 +19011,13 @@
       }
     },
     "@superset-ui/legacy-preset-chart-nvd3": {
-      "version": "0.16.6",
-      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-nvd3/-/legacy-preset-chart-nvd3-0.16.6.tgz",
-      "integrity": "sha512-lDHa0YKDt0kIcbXi6N1qgmW9ZarMpwYsPj/TeEChFd+yuCjhZ4syuRoQF73tmuimR9deeVK7KCGbnjROhvFCbA==",
+      "version": "0.16.8",
+      "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-nvd3/-/legacy-preset-chart-nvd3-0.16.8.tgz",
+      "integrity": "sha512-n9X/MmIFK6TykgddfQOV1tlWUq7cZfkrIRn/0ZmDKTJi614Kz/8Vq1HUc9ei0iNes9BkK6gaJ07gaaHUGHuGRg==",
       "requires": {
         "@data-ui/xy-chart": "^0.0.84",
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "d3": "^3.5.17",
         "d3-tip": "^0.9.1",
         "dompurify": "^2.0.6",
@@ -19031,12 +19031,12 @@
       }
     },
     "@superset-ui/plugin-chart-echarts": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-echarts/-/plugin-chart-echarts-0.16.4.tgz",
-      "integrity": "sha512-1ef4Mo5Q2aG8FulaqcDISQAdvFsfqz4XtRSElhOqT0YM9rOGzFof2jL5Y4dhIGE9rg3/6eGy5g8eiT+JRgG+4w==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-echarts/-/plugin-chart-echarts-0.16.7.tgz",
+      "integrity": "sha512-w2T2HuBYTHfFV8oBkz+Gxjl5mYSJ92RjwVqV08dUGuf86LSdDhyXsfpFKq+j+u8dOyyxQp18Nid0Mlxy+F6V2w==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "@types/echarts": "^4.6.3",
         "@types/mathjs": "^6.0.7",
         "echarts": "^5.0.0",
@@ -19044,13 +19044,13 @@
       }
     },
     "@superset-ui/plugin-chart-table": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-table/-/plugin-chart-table-0.16.4.tgz",
-      "integrity": "sha512-jmN9TMkB0j02zX/1d4Tv3lApkF5jzH+TykFlDhRLruJ5lYZMdeqKovN+KV4UPf+v8lePjm02SWUngCQLW6xi/g==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-table/-/plugin-chart-table-0.16.7.tgz",
+      "integrity": "sha512-P5oedAqAcM0Z3Pgv4v4eEIjYCz/Sk/aWjKqTWxDFEOdavjGH0FxpTW4TquC13slGKWP7U4ddf1/bx73nH0K+XA==",
       "requires": {
         "@emotion/core": "^10.0.28",
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "@types/d3-array": "^2.0.0",
         "@types/match-sorter": "^4.0.0",
         "@types/react-table": "^7.0.19",
@@ -19063,37 +19063,20 @@
         "xss": "^1.0.6"
       },
       "dependencies": {
-        "@babel/runtime": {
-          "version": "7.12.5",
-          "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz",
-          "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==",
-          "requires": {
-            "regenerator-runtime": "^0.13.4"
-          }
-        },
         "d3-array": {
           "version": "2.9.1",
           "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.9.1.tgz",
           "integrity": "sha512-Ob7RdOtkqsjx1NWyQHMFLtCSk6/aKTxDdC4ZIolX+O+mDD2RzrsYgAyc0WGAlfYFVELLSilS7w8BtE3PKM8bHg=="
-        },
-        "match-sorter": {
-          "version": "4.2.1",
-          "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-4.2.1.tgz",
-          "integrity": "sha512-s+3h9TiZU9U1pWhIERHf8/f4LmBN6IXaRgo2CI17+XGByGS1GvG5VvXK9pcGyCjGe3WM3mSYRC3ipGrd5UEVgw==",
-          "requires": {
-            "@babel/runtime": "^7.10.5",
-            "remove-accents": "0.4.2"
-          }
         }
       }
     },
     "@superset-ui/plugin-chart-word-cloud": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-word-cloud/-/plugin-chart-word-cloud-0.16.4.tgz",
-      "integrity": "sha512-i/vhrfu48g5V0SAity+0NCIx+WdN+2qmyeX8ZNBURaGvLylFv++3/ewYHuSZ/DZFSZiKBukumH4ezEIPxCgO/A==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-word-cloud/-/plugin-chart-word-cloud-0.16.7.tgz",
+      "integrity": "sha512-BvVAA2tT0zFQwJimY0tHqic/a96w+3+htILV4mE+D5ZIu8/PjhTepBfWzcXTt6MxXL7jxRmGZ12dPn0ZIU5auw==",
       "requires": {
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "@types/d3-cloud": "^1.2.1",
         "@types/d3-scale": "^2.0.2",
         "d3-cloud": "^1.2.5",
@@ -19122,14 +19105,14 @@
       }
     },
     "@superset-ui/preset-chart-xy": {
-      "version": "0.16.4",
-      "resolved": "https://registry.npmjs.org/@superset-ui/preset-chart-xy/-/preset-chart-xy-0.16.4.tgz",
-      "integrity": "sha512-FAx0r6CnTKgliPgdG6kyMTdaZ7n9gsUrOghvSOkKZqfhXKoAhvnsxdGMmPjiY/enn12+/m3HcfpWMVbUuf0QDA==",
+      "version": "0.16.7",
+      "resolved": "https://registry.npmjs.org/@superset-ui/preset-chart-xy/-/preset-chart-xy-0.16.7.tgz",
+      "integrity": "sha512-T6GqBfLizO2CooWRoM0bGbIbVFHCLGYK/NkRyMtmZ1B/UEt7ldOBjzj+qtvHNZfb65K5CF7WLMEeK/X/hOxxNw==",
       "requires": {
         "@data-ui/theme": "^0.0.84",
         "@data-ui/xy-chart": "^0.0.84",
-        "@superset-ui/chart-controls": "0.16.4",
-        "@superset-ui/core": "0.16.4",
+        "@superset-ui/chart-controls": "0.16.7",
+        "@superset-ui/core": "0.16.7",
         "@vx/axis": "^0.0.198",
         "@vx/legend": "^0.0.198",
         "@vx/scale": "^0.0.197",
@@ -20993,9 +20976,9 @@
       "integrity": "sha512-JK7HNHXZA7i/nEp6fbNAxoX/1j1ysZXmv2/nlkt2UpX1LiUWKLtyt/dMmDTlMPR6t6PkwMmIr2W2AAyu6oELNw=="
     },
     "@types/mathjs": {
-      "version": "6.0.9",
-      "resolved": "https://registry.npmjs.org/@types/mathjs/-/mathjs-6.0.9.tgz",
-      "integrity": "sha512-u93l9ZU0DhbT+gGtrP12/jPhx/X2eshLiv1if97qC7Nuld4/kxS+1WoyIM7NC5b5XiwvATWDTHsI8LvcPBWxcA==",
+      "version": "6.0.11",
+      "resolved": "https://registry.npmjs.org/@types/mathjs/-/mathjs-6.0.11.tgz",
+      "integrity": "sha512-q9B8ZreO41L38iTY76bCZEtAqzeRs4mNIOZpZ1sLSlcYgvgfFrnf8y8qfmas0tVWrsODjmQbQJFD6RJJJCqJbQ==",
       "requires": {
         "decimal.js": "^10.0.0"
       }
@@ -25318,28 +25301,28 @@
           "dependencies": {
             "abbrev": {
               "version": "1.1.1",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
               "dev": true,
               "optional": true
             },
             "ansi-regex": {
               "version": "2.1.1",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
               "dev": true,
               "optional": true
             },
             "aproba": {
               "version": "1.2.0",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
               "dev": true,
               "optional": true
             },
             "are-we-there-yet": {
               "version": "1.1.5",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
               "dev": true,
               "optional": true,
@@ -25350,14 +25333,14 @@
             },
             "balanced-match": {
               "version": "1.0.0",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
               "dev": true,
               "optional": true
             },
             "brace-expansion": {
               "version": "1.1.11",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
               "dev": true,
               "optional": true,
@@ -25368,35 +25351,35 @@
             },
             "code-point-at": {
               "version": "1.1.0",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
               "dev": true,
               "optional": true
             },
             "concat-map": {
               "version": "0.0.1",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
               "dev": true,
               "optional": true
             },
             "console-control-strings": {
               "version": "1.1.0",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
               "dev": true,
               "optional": true
             },
             "core-util-is": {
               "version": "1.0.2",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
               "dev": true,
               "optional": true
             },
             "debug": {
               "version": "4.1.1",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
               "dev": true,
               "optional": true,
@@ -25406,35 +25389,35 @@
             },
             "deep-extend": {
               "version": "0.6.0",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
               "dev": true,
               "optional": true
             },
             "delegates": {
               "version": "1.0.0",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
               "dev": true,
               "optional": true
             },
             "detect-libc": {
               "version": "1.0.3",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
               "dev": true,
               "optional": true
             },
             "fs.realpath": {
               "version": "1.0.0",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
               "dev": true,
               "optional": true
             },
             "gauge": {
               "version": "2.7.4",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
               "dev": true,
               "optional": true,
@@ -25451,7 +25434,7 @@
             },
             "glob": {
               "version": "7.1.3",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
               "dev": true,
               "optional": true,
@@ -25466,14 +25449,14 @@
             },
             "has-unicode": {
               "version": "2.0.1",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
               "dev": true,
               "optional": true
             },
             "iconv-lite": {
               "version": "0.4.24",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
               "dev": true,
               "optional": true,
@@ -25483,7 +25466,7 @@
             },
             "ignore-walk": {
               "version": "3.0.1",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==",
               "dev": true,
               "optional": true,
@@ -25493,7 +25476,7 @@
             },
             "inflight": {
               "version": "1.0.6",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
               "dev": true,
               "optional": true,
@@ -25504,14 +25487,14 @@
             },
             "inherits": {
               "version": "2.0.3",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
               "dev": true,
               "optional": true
             },
             "is-fullwidth-code-point": {
               "version": "1.0.0",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
               "dev": true,
               "optional": true,
@@ -25521,14 +25504,14 @@
             },
             "isarray": {
               "version": "1.0.0",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
               "dev": true,
               "optional": true
             },
             "minimatch": {
               "version": "3.0.4",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
               "dev": true,
               "optional": true,
@@ -25545,14 +25528,14 @@
             },
             "ms": {
               "version": "2.1.1",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
               "dev": true,
               "optional": true
             },
             "needle": {
               "version": "2.3.0",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==",
               "dev": true,
               "optional": true,
@@ -25564,7 +25547,7 @@
             },
             "node-pre-gyp": {
               "version": "0.12.0",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==",
               "dev": true,
               "optional": true,
@@ -25583,7 +25566,7 @@
             },
             "nopt": {
               "version": "4.0.1",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
               "dev": true,
               "optional": true,
@@ -25594,14 +25577,14 @@
             },
             "npm-bundled": {
               "version": "1.0.6",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==",
               "dev": true,
               "optional": true
             },
             "npm-packlist": {
               "version": "1.4.1",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==",
               "dev": true,
               "optional": true,
@@ -25612,7 +25595,7 @@
             },
             "npmlog": {
               "version": "4.1.2",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
               "dev": true,
               "optional": true,
@@ -25625,21 +25608,21 @@
             },
             "number-is-nan": {
               "version": "1.0.1",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
               "dev": true,
               "optional": true
             },
             "object-assign": {
               "version": "4.1.1",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
               "dev": true,
               "optional": true
             },
             "once": {
               "version": "1.4.0",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
               "dev": true,
               "optional": true,
@@ -25649,21 +25632,21 @@
             },
             "os-homedir": {
               "version": "1.0.2",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
               "dev": true,
               "optional": true
             },
             "os-tmpdir": {
               "version": "1.0.2",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
               "dev": true,
               "optional": true
             },
             "osenv": {
               "version": "0.1.5",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
               "dev": true,
               "optional": true,
@@ -25674,21 +25657,21 @@
             },
             "path-is-absolute": {
               "version": "1.0.1",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
               "dev": true,
               "optional": true
             },
             "process-nextick-args": {
               "version": "2.0.0",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
               "dev": true,
               "optional": true
             },
             "rc": {
               "version": "1.2.8",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
               "dev": true,
               "optional": true,
@@ -25701,7 +25684,7 @@
             },
             "readable-stream": {
               "version": "2.3.6",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
               "dev": true,
               "optional": true,
@@ -25717,7 +25700,7 @@
             },
             "rimraf": {
               "version": "2.6.3",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
               "dev": true,
               "optional": true,
@@ -25727,49 +25710,49 @@
             },
             "safe-buffer": {
               "version": "5.1.2",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
               "dev": true,
               "optional": true
             },
             "safer-buffer": {
               "version": "2.1.2",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
               "dev": true,
               "optional": true
             },
             "sax": {
               "version": "1.2.4",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
               "dev": true,
               "optional": true
             },
             "semver": {
               "version": "5.7.0",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
               "dev": true,
               "optional": true
             },
             "set-blocking": {
               "version": "2.0.0",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
               "dev": true,
               "optional": true
             },
             "signal-exit": {
               "version": "3.0.2",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
               "dev": true,
               "optional": true
             },
             "string-width": {
               "version": "1.0.2",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
               "dev": true,
               "optional": true,
@@ -25781,7 +25764,7 @@
             },
             "string_decoder": {
               "version": "1.1.1",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
               "dev": true,
               "optional": true,
@@ -25791,7 +25774,7 @@
             },
             "strip-ansi": {
               "version": "3.0.1",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
               "dev": true,
               "optional": true,
@@ -25801,21 +25784,21 @@
             },
             "strip-json-comments": {
               "version": "2.0.1",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
               "dev": true,
               "optional": true
             },
             "util-deprecate": {
               "version": "1.0.2",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
               "dev": true,
               "optional": true
             },
             "wide-align": {
               "version": "1.1.3",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
               "dev": true,
               "optional": true,
@@ -25825,7 +25808,7 @@
             },
             "wrappy": {
               "version": "1.0.2",
-              "resolved": false,
+              "resolved": "",
               "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
               "dev": true,
               "optional": true
diff --git a/superset-frontend/package.json b/superset-frontend/package.json
index f409c6f..65ca3f0 100644
--- a/superset-frontend/package.json
+++ b/superset-frontend/package.json
@@ -65,34 +65,34 @@
     "@babel/runtime-corejs3": "^7.12.5",
     "@data-ui/sparkline": "^0.0.84",
     "@emotion/core": "^10.0.35",
-    "@superset-ui/chart-controls": "^0.16.4",
-    "@superset-ui/core": "^0.16.4",
-    "@superset-ui/legacy-plugin-chart-calendar": "^0.16.4",
-    "@superset-ui/legacy-plugin-chart-chord": "^0.16.4",
-    "@superset-ui/legacy-plugin-chart-country-map": "^0.16.4",
-    "@superset-ui/legacy-plugin-chart-event-flow": "^0.16.4",
-    "@superset-ui/legacy-plugin-chart-force-directed": "^0.16.4",
-    "@superset-ui/legacy-plugin-chart-heatmap": "^0.16.4",
-    "@superset-ui/legacy-plugin-chart-histogram": "^0.16.4",
-    "@superset-ui/legacy-plugin-chart-horizon": "^0.16.4",
-    "@superset-ui/legacy-plugin-chart-map-box": "^0.16.4",
-    "@superset-ui/legacy-plugin-chart-paired-t-test": "^0.16.4",
-    "@superset-ui/legacy-plugin-chart-parallel-coordinates": "^0.16.4",
-    "@superset-ui/legacy-plugin-chart-partition": "^0.16.6",
-    "@superset-ui/legacy-plugin-chart-pivot-table": "^0.16.6",
-    "@superset-ui/legacy-plugin-chart-rose": "^0.16.6",
-    "@superset-ui/legacy-plugin-chart-sankey": "^0.16.4",
-    "@superset-ui/legacy-plugin-chart-sankey-loop": "^0.16.4",
-    "@superset-ui/legacy-plugin-chart-sunburst": "^0.16.4",
-    "@superset-ui/legacy-plugin-chart-treemap": "^0.16.4",
-    "@superset-ui/legacy-plugin-chart-world-map": "^0.16.4",
-    "@superset-ui/legacy-preset-chart-big-number": "^0.16.6",
+    "@superset-ui/chart-controls": "^0.16.7",
+    "@superset-ui/core": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-calendar": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-chord": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-country-map": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-event-flow": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-force-directed": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-heatmap": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-histogram": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-horizon": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-map-box": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-paired-t-test": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-parallel-coordinates": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-partition": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-pivot-table": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-rose": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-sankey": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-sankey-loop": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-sunburst": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-treemap": "^0.16.7",
+    "@superset-ui/legacy-plugin-chart-world-map": "^0.16.7",
+    "@superset-ui/legacy-preset-chart-big-number": "^0.16.8",
     "@superset-ui/legacy-preset-chart-deckgl": "^0.4.1",
-    "@superset-ui/legacy-preset-chart-nvd3": "^0.16.6",
-    "@superset-ui/plugin-chart-echarts": "^0.16.4",
-    "@superset-ui/plugin-chart-table": "^0.16.4",
-    "@superset-ui/plugin-chart-word-cloud": "^0.16.4",
-    "@superset-ui/preset-chart-xy": "^0.16.4",
+    "@superset-ui/legacy-preset-chart-nvd3": "^0.16.8",
+    "@superset-ui/plugin-chart-echarts": "^0.16.7",
+    "@superset-ui/plugin-chart-table": "^0.16.7",
+    "@superset-ui/plugin-chart-word-cloud": "^0.16.7",
+    "@superset-ui/preset-chart-xy": "^0.16.7",
     "@vx/responsive": "^0.0.195",
     "abortcontroller-polyfill": "^1.1.9",
     "antd": "^4.9.4",


[superset] 03/38: Apply capitalization guidelines - iteration 2 (#12343) (#12448)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit e6b916c06f48f4bd9d0a4c7617121ed43dc73b1f
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Fri Jan 22 02:45:12 2021 -0300

    Apply capitalization guidelines - iteration 2 (#12343) (#12448)
---
 superset-frontend/src/components/DynamicPlugins/index.tsx         | 2 +-
 .../src/components/ErrorMessage/DatabaseErrorMessage.tsx          | 2 +-
 superset-frontend/src/components/ErrorMessage/ErrorAlert.tsx      | 8 ++++----
 .../src/components/ErrorMessage/ErrorMessageWithStackTrace.tsx    | 2 +-
 .../src/components/ErrorMessage/ParameterErrorMessage.tsx         | 2 +-
 .../src/components/ErrorMessage/TimeoutErrorMessage.tsx           | 2 +-
 .../src/components/FilterableTable/FilterableTable.tsx            | 2 +-
 superset-frontend/src/components/ListView/ListView.tsx            | 4 ++--
 superset-frontend/src/components/RefreshChartOverlay.tsx          | 2 +-
 superset-frontend/src/components/URLShortLinkModal.tsx            | 2 +-
 10 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/superset-frontend/src/components/DynamicPlugins/index.tsx b/superset-frontend/src/components/DynamicPlugins/index.tsx
index 9f51bd1..52570fe 100644
--- a/superset-frontend/src/components/DynamicPlugins/index.tsx
+++ b/superset-frontend/src/components/DynamicPlugins/index.tsx
@@ -163,7 +163,7 @@ export const DynamicPluginProvider: React.FC = ({ children }) => {
         }),
       );
     } catch (error) {
-      logging.error('failed to load dynamic plugins', error.stack || error);
+      logging.error('Failed to load dynamic plugins', error.stack || error);
     }
   }
 
diff --git a/superset-frontend/src/components/ErrorMessage/DatabaseErrorMessage.tsx b/superset-frontend/src/components/ErrorMessage/DatabaseErrorMessage.tsx
index 6fdff31..c552d3a 100644
--- a/superset-frontend/src/components/ErrorMessage/DatabaseErrorMessage.tsx
+++ b/superset-frontend/src/components/ErrorMessage/DatabaseErrorMessage.tsx
@@ -78,7 +78,7 @@ ${extra.issue_codes.map(issueCode => issueCode.message).join('\n')}`;
 
   return (
     <ErrorAlert
-      title={t('%s Error', extra.engine_name || t('DB Engine'))}
+      title={t('%s Error', extra.engine_name || t('DB engine'))}
       subtitle={message}
       level={level}
       source={source}
diff --git a/superset-frontend/src/components/ErrorMessage/ErrorAlert.tsx b/superset-frontend/src/components/ErrorMessage/ErrorAlert.tsx
index 71455db..ce5ebe6 100644
--- a/superset-frontend/src/components/ErrorMessage/ErrorAlert.tsx
+++ b/superset-frontend/src/components/ErrorMessage/ErrorAlert.tsx
@@ -120,7 +120,7 @@ export default function ErrorAlert({
             className="link"
             onClick={() => setIsModalOpen(true)}
           >
-            {t('See More')}
+            {t('See more')}
           </span>
         )}
       </div>
@@ -136,7 +136,7 @@ export default function ErrorAlert({
                   className="link"
                   onClick={() => setIsBodyExpanded(true)}
                 >
-                  {t('See More')}
+                  {t('See more')}
                 </span>
               )}
               {isBodyExpanded && (
@@ -149,7 +149,7 @@ export default function ErrorAlert({
                     className="link"
                     onClick={() => setIsBodyExpanded(false)}
                   >
-                    {t('See Less')}
+                    {t('See less')}
                   </span>
                 </>
               )}
@@ -178,7 +178,7 @@ export default function ErrorAlert({
                   text={copyText}
                   shouldShowText={false}
                   wrapped={false}
-                  copyNode={<Button onClick={noOp}>{t('Copy Message')}</Button>}
+                  copyNode={<Button onClick={noOp}>{t('Copy message')}</Button>}
                 />
               )}
               <Button
diff --git a/superset-frontend/src/components/ErrorMessage/ErrorMessageWithStackTrace.tsx b/superset-frontend/src/components/ErrorMessage/ErrorMessageWithStackTrace.tsx
index 554e2f9..29bd73c 100644
--- a/superset-frontend/src/components/ErrorMessage/ErrorMessageWithStackTrace.tsx
+++ b/superset-frontend/src/components/ErrorMessage/ErrorMessageWithStackTrace.tsx
@@ -23,7 +23,7 @@ import getErrorMessageComponentRegistry from './getErrorMessageComponentRegistry
 import { SupersetError, ErrorSource } from './types';
 import ErrorAlert from './ErrorAlert';
 
-const DEFAULT_TITLE = t('Unexpected Error');
+const DEFAULT_TITLE = t('Unexpected error');
 
 type Props = {
   title?: string;
diff --git a/superset-frontend/src/components/ErrorMessage/ParameterErrorMessage.tsx b/superset-frontend/src/components/ErrorMessage/ParameterErrorMessage.tsx
index 145200d..1eb4437 100644
--- a/superset-frontend/src/components/ErrorMessage/ParameterErrorMessage.tsx
+++ b/superset-frontend/src/components/ErrorMessage/ParameterErrorMessage.tsx
@@ -111,7 +111,7 @@ ${extra.issue_codes.map(issueCode => issueCode.message).join('\n')}`;
 
   return (
     <ErrorAlert
-      title={t('Parameter Error')}
+      title={t('Parameter error')}
       subtitle={message}
       level={level}
       source={source}
diff --git a/superset-frontend/src/components/ErrorMessage/TimeoutErrorMessage.tsx b/superset-frontend/src/components/ErrorMessage/TimeoutErrorMessage.tsx
index 8980595..0e9d663 100644
--- a/superset-frontend/src/components/ErrorMessage/TimeoutErrorMessage.tsx
+++ b/superset-frontend/src/components/ErrorMessage/TimeoutErrorMessage.tsx
@@ -95,7 +95,7 @@ ${extra.issue_codes.map(issueCode => issueCode.message).join('\n')}`;
 
   return (
     <ErrorAlert
-      title={t('Timeout Error')}
+      title={t('Timeout error')}
       subtitle={subtitle}
       level={level}
       source={source}
diff --git a/superset-frontend/src/components/FilterableTable/FilterableTable.tsx b/superset-frontend/src/components/FilterableTable/FilterableTable.tsx
index 67bea7f..c762996 100644
--- a/superset-frontend/src/components/FilterableTable/FilterableTable.tsx
+++ b/superset-frontend/src/components/FilterableTable/FilterableTable.tsx
@@ -314,7 +314,7 @@ export default class FilterableTable extends PureComponent<
             <CopyToClipboard shouldShowText={false} text={jsonString} />
           </Button>
         }
-        modalTitle={t('Cell Content')}
+        modalTitle={t('Cell content')}
         triggerNode={node}
       />
     );
diff --git a/superset-frontend/src/components/ListView/ListView.tsx b/superset-frontend/src/components/ListView/ListView.tsx
index 6ee998c..621b8d8 100644
--- a/superset-frontend/src/components/ListView/ListView.tsx
+++ b/superset-frontend/src/components/ListView/ListView.tsx
@@ -345,7 +345,7 @@ function ListView<T extends object = any>({
                     className="deselect-all"
                     onClick={() => toggleAllRowsSelected(false)}
                   >
-                    {t('Deselect All')}
+                    {t('Deselect all')}
                   </span>
                   <div className="divider" />
                   {bulkActions.map(action => (
@@ -390,7 +390,7 @@ function ListView<T extends object = any>({
             <EmptyWrapper className={viewMode}>
               <Empty
                 image={<EmptyImage />}
-                description={emptyState.message || 'No Data'}
+                description={emptyState.message || 'No data'}
               >
                 {emptyState.slot || null}
               </Empty>
diff --git a/superset-frontend/src/components/RefreshChartOverlay.tsx b/superset-frontend/src/components/RefreshChartOverlay.tsx
index bd965b4..7e727bd 100644
--- a/superset-frontend/src/components/RefreshChartOverlay.tsx
+++ b/superset-frontend/src/components/RefreshChartOverlay.tsx
@@ -45,7 +45,7 @@ class RefreshChartOverlay extends React.PureComponent<Props> {
       <RefreshOverlayWrapper>
         <div>
           <Button onClick={this.props.onQuery} buttonStyle="primary">
-            {t('Run Query')}
+            {t('Run query')}
           </Button>
         </div>
       </RefreshOverlayWrapper>
diff --git a/superset-frontend/src/components/URLShortLinkModal.tsx b/superset-frontend/src/components/URLShortLinkModal.tsx
index 40e9b45..148d86c 100644
--- a/superset-frontend/src/components/URLShortLinkModal.tsx
+++ b/superset-frontend/src/components/URLShortLinkModal.tsx
@@ -80,7 +80,7 @@ class URLShortLinkModal extends React.Component<
         ref={this.setModalRef}
         triggerNode={this.props.triggerNode}
         beforeOpen={this.getCopyUrl}
-        modalTitle={this.props.title || t('Share Dashboard')}
+        modalTitle={this.props.title || t('Share dashboard')}
         modalBody={
           <div>
             <CopyToClipboard


[superset] 22/38: fix: dropdown indicator in tabs has proper width and position (#12584)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 8b094148066d16b840941c3f02c0cb3ef3a72777
Author: Kasia Kucharczyk <25...@users.noreply.github.com>
AuthorDate: Wed Jan 20 23:18:42 2021 +0100

    fix: dropdown indicator in tabs has proper width and position (#12584)
    
    Closes #12481 , partially fix #12486
---
 .../src/dashboard/components/gridComponents/Tabs.jsx     | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/superset-frontend/src/dashboard/components/gridComponents/Tabs.jsx b/superset-frontend/src/dashboard/components/gridComponents/Tabs.jsx
index 455a41a..e1bedbe 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/Tabs.jsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/Tabs.jsx
@@ -86,22 +86,6 @@ const StyledTabsContainer = styled.div`
     position: relative;
   }
 
-  .drop-indicator--left {
-    left: ${({ theme }) => -theme.gridUnit * 3}px !important;
-  }
-  .drop-indicator--right {
-    left: ${({ theme }) => `calc(100% + ${theme.gridUnit * 6}px)`} !important;
-  }
-
-  .drop-indicator--bottom,
-  .drop-indicator--top {
-    width: ${({ theme }) => `calc(100% + ${theme.gridUnit * 6}px)`} !important;
-  }
-
-  .drop-indicator--top {
-    top: ${({ theme }) => theme.gridUnit * 2}px;
-  }
-
   .ant-tabs {
     overflow: visible;
 


[superset] 26/38: fix: explore page style fix, remove unnecessary scroll bars (#12649)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 41505bb2d410ab81cff5d00449b9a965f76069c4
Author: Jesse Yang <je...@airbnb.com>
AuthorDate: Fri Jan 22 09:18:13 2021 -0800

    fix: explore page style fix, remove unnecessary scroll bars (#12649)
    
    * fix: various style touch on Explore page
    
    * More style fixes
    
    * Force 100% height for sidebars
    
    * Fix linting
---
 superset-frontend/src/components/Select/styles.tsx | 26 +++++++++++++---------
 .../explore/components/ControlPanelsContainer.jsx  | 26 ++++++++++++----------
 .../src/explore/components/DataTablesPane.tsx      |  1 +
 .../src/explore/components/ExploreChartPanel.jsx   |  7 +++---
 .../explore/components/ExploreViewContainer.jsx    |  7 ++++--
 5 files changed, 38 insertions(+), 29 deletions(-)

diff --git a/superset-frontend/src/components/Select/styles.tsx b/superset-frontend/src/components/Select/styles.tsx
index 9358021..c990416 100644
--- a/superset-frontend/src/components/Select/styles.tsx
+++ b/superset-frontend/src/components/Select/styles.tsx
@@ -161,10 +161,8 @@ export const DEFAULT_STYLES: PartialStylesConfig = {
   ) => {
     const isPseudoFocused = isFocused && !menuIsOpen;
     let borderColor = colors.grayBorder;
-    if (isPseudoFocused) {
+    if (isPseudoFocused || menuIsOpen) {
       borderColor = colors.grayBorderDark;
-    } else if (menuIsOpen) {
-      borderColor = `${colors.grayBorderDark} ${colors.grayBorder} ${colors.grayBorderLight}`;
     }
     return [
       provider,
@@ -185,22 +183,28 @@ export const DEFAULT_STYLES: PartialStylesConfig = {
       `,
     ];
   },
-  menu: (provider, { theme: { borderRadius, zIndex, colors } }) => [
+  menu: (provider, { theme: { zIndex } }) => [
+    provider,
+    css`
+      padding-bottom: 2em;
+      z-index: ${zIndex}; /* override at least multi-page pagination */
+      width: auto;
+      min-width: 100%;
+      max-width: 80vw;
+      box-shadow: none;
+      border: 0;
+    `,
+  ],
+  menuList: (provider, { theme: { borderRadius, colors } }) => [
     provider,
     css`
       border-radius: 0 0 ${borderRadius}px ${borderRadius}px;
-      border: 1px solid #ccc;
+      border: 1px solid ${colors.grayBorderDark};
       box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06);
       margin-top: -1px;
       border-top-color: ${colors.grayBorderLight};
       min-width: 100%;
       width: auto;
-      z-index: ${zIndex}; /* override at least multi-page pagination */
-    `,
-  ],
-  menuList: (provider, { theme: { borderRadius } }) => [
-    provider,
-    css`
       border-radius: 0 0 ${borderRadius}px ${borderRadius}px;
       padding-top: 0;
       padding-bottom: 0;
diff --git a/superset-frontend/src/explore/components/ControlPanelsContainer.jsx b/superset-frontend/src/explore/components/ControlPanelsContainer.jsx
index 70c347c..a534438 100644
--- a/superset-frontend/src/explore/components/ControlPanelsContainer.jsx
+++ b/superset-frontend/src/explore/components/ControlPanelsContainer.jsx
@@ -22,7 +22,6 @@ import PropTypes from 'prop-types';
 import { bindActionCreators } from 'redux';
 import { connect } from 'react-redux';
 import { Alert } from 'react-bootstrap';
-import { css } from '@emotion/core';
 import { t, styled, getChartControlPanelRegistry } from '@superset-ui/core';
 
 import Tabs from 'src/common/components/Tabs';
@@ -46,16 +45,16 @@ const propTypes = {
 
 const Styles = styled.div`
   height: 100%;
-  max-height: 100%;
+  width: 100%;
   overflow: auto;
+  overflow-x: visible;
+  overflow-y: auto;
   .remove-alert {
     cursor: pointer;
   }
   #controlSections {
-    display: flex;
-    flex-direction: column;
-    height: 100%;
-    max-height: 100%;
+    min-height: 100%;
+    overflow: visible;
   }
   .nav-tabs {
     flex: 0 0 1;
@@ -64,15 +63,18 @@ const Styles = styled.div`
     overflow: auto;
     flex: 1 1 100%;
   }
+  .Select__menu {
+    max-width: 100%;
+  }
 `;
 
 const ControlPanelsTabs = styled(Tabs)`
-  ${({ fullWidth }) =>
-    css`
-      .ant-tabs-nav-list {
-        width: ${fullWidth ? '100%' : '50%'};
-      }
-    `}
+  .ant-tabs-nav-list {
+    width: ${({ fullWidth }) => (fullWidth ? '100%' : '50%')};
+  }
+  .ant-tabs-content-holder {
+    overflow: visible;
+  }
 `;
 
 class ControlPanelsContainer extends React.Component {
diff --git a/superset-frontend/src/explore/components/DataTablesPane.tsx b/superset-frontend/src/explore/components/DataTablesPane.tsx
index e0a7445..a3c74d6 100644
--- a/superset-frontend/src/explore/components/DataTablesPane.tsx
+++ b/superset-frontend/src/explore/components/DataTablesPane.tsx
@@ -57,6 +57,7 @@ const SouthPane = styled.div`
   position: relative;
   background-color: ${({ theme }) => theme.colors.grayscale.light5};
   z-index: 5;
+  overflow: hidden;
 `;
 
 const TabsWrapper = styled.div<{ contentHeight: number }>`
diff --git a/superset-frontend/src/explore/components/ExploreChartPanel.jsx b/superset-frontend/src/explore/components/ExploreChartPanel.jsx
index bb9bd60..bc7e5c7 100644
--- a/superset-frontend/src/explore/components/ExploreChartPanel.jsx
+++ b/superset-frontend/src/explore/components/ExploreChartPanel.jsx
@@ -66,6 +66,8 @@ const Styles = styled.div`
   align-items: stretch;
   align-content: stretch;
   overflow: auto;
+  box-shadow: none;
+  height: 100%;
 
   & > div:last-of-type {
     flex-basis: 100%;
@@ -235,10 +237,7 @@ const ExploreChartPanel = props => {
   });
 
   return (
-    <Styles
-      className="panel panel-default chart-container"
-      style={{ height: props.height }}
-    >
+    <Styles className="panel panel-default chart-container">
       <div className="panel-heading" ref={headerRef}>
         {header}
       </div>
diff --git a/superset-frontend/src/explore/components/ExploreViewContainer.jsx b/superset-frontend/src/explore/components/ExploreViewContainer.jsx
index 349bded..5ea90a2 100644
--- a/superset-frontend/src/explore/components/ExploreViewContainer.jsx
+++ b/superset-frontend/src/explore/components/ExploreViewContainer.jsx
@@ -95,6 +95,9 @@ const Styles = styled.div`
     flex: 1;
     min-width: ${({ theme }) => theme.gridUnit * 128}px;
     border-left: 1px solid ${({ theme }) => theme.colors.grayscale.light2};
+    .panel {
+      margin-bottom: 0;
+    }
   }
   .controls-column {
     align-self: flex-start;
@@ -404,7 +407,7 @@ function ExploreViewContainer(props) {
         />
       )}
       <Resizable
-        defaultSize={{ width: 300 }}
+        defaultSize={{ width: 300, height: '100%' }}
         minWidth={300}
         maxWidth="33%"
         enable={{ right: true }}
@@ -456,7 +459,7 @@ function ExploreViewContainer(props) {
         </div>
       ) : null}
       <Resizable
-        defaultSize={{ width: 320 }}
+        defaultSize={{ width: 320, height: '100%' }}
         minWidth={320}
         maxWidth="33%"
         enable={{ right: true }}


[superset] 16/38: fix: row component handler is visible (#12498)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 630bb7264ecba36da80c08dd7dfba6bd5c6301e3
Author: Kasia Kucharczyk <25...@users.noreply.github.com>
AuthorDate: Mon Jan 18 02:38:17 2021 +0100

    fix: row component handler is visible (#12498)
---
 superset-frontend/src/dashboard/components/DashboardBuilder.jsx | 2 +-
 superset-frontend/src/dashboard/stylesheets/hover-menu.less     | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/superset-frontend/src/dashboard/components/DashboardBuilder.jsx b/superset-frontend/src/dashboard/components/DashboardBuilder.jsx
index 861f3ad..aad5c41 100644
--- a/superset-frontend/src/dashboard/components/DashboardBuilder.jsx
+++ b/superset-frontend/src/dashboard/components/DashboardBuilder.jsx
@@ -97,7 +97,7 @@ const StyledDashboardContent = styled.div`
       ${({ theme }) => theme.gridUnit * 8}px
       ${({ theme }) => theme.gridUnit * 6}px
       ${({ theme, dashboardFiltersOpen }) => {
-        if (dashboardFiltersOpen) return theme.gridUnit * 4;
+        if (dashboardFiltersOpen) return theme.gridUnit * 8;
         return 0;
       }}px;
   }
diff --git a/superset-frontend/src/dashboard/stylesheets/hover-menu.less b/superset-frontend/src/dashboard/stylesheets/hover-menu.less
index e3bcb40..8953ce0 100644
--- a/superset-frontend/src/dashboard/stylesheets/hover-menu.less
+++ b/superset-frontend/src/dashboard/stylesheets/hover-menu.less
@@ -27,8 +27,7 @@
   width: 24px;
   top: 50%;
   transform: translate(0, -50%);
-  left: -24px;
-  padding: 8px 0;
+  left: -28px;
   display: flex;
   flex-direction: column;
   justify-content: center;


[superset] 29/38: Switch button position (#12604)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit fe0b9f419bcd3de4ddc98b63e35cd83e82102fed
Author: Geido <60...@users.noreply.github.com>
AuthorDate: Tue Jan 19 19:26:46 2021 +0100

    Switch button position (#12604)
---
 superset-frontend/src/datasource/DatasourceModal.tsx | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/superset-frontend/src/datasource/DatasourceModal.tsx b/superset-frontend/src/datasource/DatasourceModal.tsx
index 2dc1cee..839f1e3 100644
--- a/superset-frontend/src/datasource/DatasourceModal.tsx
+++ b/superset-frontend/src/datasource/DatasourceModal.tsx
@@ -194,21 +194,21 @@ const DatasourceModal: FunctionComponent<DatasourceModalProps> = ({
             </Button>
           )}
           <Button
+            data-test="datasource-modal-cancel"
             buttonSize="sm"
-            buttonStyle="primary"
             className="m-r-5"
-            data-test="datasource-modal-save"
-            onClick={onClickSave}
-            disabled={isSaving || errors.length > 0}
+            onClick={onHide}
           >
-            {t('Save')}
+            {t('Cancel')}
           </Button>
           <Button
-            data-test="datasource-modal-cancel"
             buttonSize="sm"
-            onClick={onHide}
+            buttonStyle="primary"
+            data-test="datasource-modal-save"
+            onClick={onClickSave}
+            disabled={isSaving || errors.length > 0}
           >
-            {t('Cancel')}
+            {t('Save')}
           </Button>
         </>
       }


[superset] 19/38: fix: return appropriate response when payload has error (#12575)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit a4d7e9c35da69f7ff57e27dbf7f92aab3f51527c
Author: Yongjie Zhao <yo...@gmail.com>
AuthorDate: Tue Jan 19 14:57:25 2021 +0800

    fix: return appropriate response when payload has error (#12575)
---
 superset/views/core.py | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/superset/views/core.py b/superset/views/core.py
index 2895340..2ef0e1a 100755
--- a/superset/views/core.py
+++ b/superset/views/core.py
@@ -421,9 +421,10 @@ class Superset(BaseSupersetView):  # pylint: disable=too-many-public-methods
         )
 
     def get_raw_results(self, viz_obj: BaseViz) -> FlaskResponse:
-        return self.json_response(
-            {"data": viz_obj.get_df_payload()["df"].to_dict("records")}
-        )
+        payload = viz_obj.get_df_payload()
+        if viz_obj.has_error(payload):
+            return json_error_response(payload=payload, status=400)
+        return self.json_response({"data": payload["df"].to_dict("records")})
 
     def get_samples(self, viz_obj: BaseViz) -> FlaskResponse:
         return self.json_response({"data": viz_obj.get_samples()})


[superset] 06/38: fix(explore): Scroll only table in Change Dataset and Edit Dataset Modals (#12598)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 2641a65feb6b748887bc4dd3897ff1f96eda63d9
Author: Geido <60...@users.noreply.github.com>
AuthorDate: Thu Jan 21 19:34:41 2021 +0100

    fix(explore): Scroll only table in Change Dataset and Edit Dataset Modals (#12598)
---
 superset-frontend/src/CRUD/CollectionTable.tsx     | 65 ++++++++++++++++------
 .../src/common/components/Modal/Modal.tsx          |  1 +
 .../src/components/TableView/TableView.tsx         | 10 ++++
 .../src/datasource/ChangeDatasourceModal.tsx       |  3 +
 .../src/datasource/DatasourceEditor.jsx            | 31 ++++++++---
 5 files changed, 83 insertions(+), 27 deletions(-)

diff --git a/superset-frontend/src/CRUD/CollectionTable.tsx b/superset-frontend/src/CRUD/CollectionTable.tsx
index 72370c8..480e593 100644
--- a/superset-frontend/src/CRUD/CollectionTable.tsx
+++ b/superset-frontend/src/CRUD/CollectionTable.tsx
@@ -18,7 +18,7 @@
  */
 import React, { ReactNode } from 'react';
 import shortid from 'shortid';
-import { t } from '@superset-ui/core';
+import { t, styled } from '@superset-ui/core';
 import Button from 'src/components/Button';
 import Fieldset from './Fieldset';
 import { recurseReactClone } from './utils';
@@ -41,6 +41,7 @@ interface CRUDCollectionProps {
   ) => ReactNode)[];
   onChange?: (arg0: any) => void;
   tableColumns: Array<any>;
+  stickyHeader?: boolean;
 }
 
 interface CRUDCollectionState {
@@ -60,6 +61,27 @@ function createKeyedCollection(arr: Array<object>) {
   return map;
 }
 
+const CrudTableWrapper = styled.div<{ stickyHeader?: boolean }>`
+  ${({ stickyHeader }) =>
+    stickyHeader &&
+    `
+      height: 350px;
+      overflow: auto;
+
+      thead th {
+        background: #fff;
+        position: sticky;
+        top: 0;
+        z-index: 9;
+      }
+    `}
+`;
+
+const CrudButtonWrapper = styled.div`
+  text-align: right;
+  ${({ theme }) => `margin-bottom: ${theme.gridUnit * 2}px`}
+`;
+
 export default class CRUDCollection extends React.PureComponent<
   CRUDCollectionProps,
   CRUDCollectionState
@@ -281,25 +303,32 @@ export default class CRUDCollection extends React.PureComponent<
 
   render() {
     return (
-      <div className="CRUD">
-        <span className="float-right m-t-10 m-r-10">
+      <>
+        <CrudButtonWrapper>
           {this.props.allowAddItem && (
-            <Button
-              buttonSize="sm"
-              buttonStyle="primary"
-              onClick={this.onAddItem}
-              data-test="add-item-button"
-            >
-              <i data-test="crud-add-table-item" className="fa fa-plus" />{' '}
-              {t('Add Item')}
-            </Button>
+            <span className="m-t-10 m-r-10">
+              <Button
+                buttonSize="sm"
+                buttonStyle="primary"
+                onClick={this.onAddItem}
+                data-test="add-item-button"
+              >
+                <i data-test="crud-add-table-item" className="fa fa-plus" />{' '}
+                {t('Add Item')}
+              </Button>
+            </span>
           )}
-        </span>
-        <table data-test="crud-table" className="table">
-          {this.renderHeaderRow()}
-          {this.renderTableBody()}
-        </table>
-      </div>
+        </CrudButtonWrapper>
+        <CrudTableWrapper
+          className="CRUD"
+          stickyHeader={this.props.stickyHeader}
+        >
+          <table data-test="crud-table" className="table">
+            {this.renderHeaderRow()}
+            {this.renderTableBody()}
+          </table>
+        </CrudTableWrapper>
+      </>
     );
   }
 }
diff --git a/superset-frontend/src/common/components/Modal/Modal.tsx b/superset-frontend/src/common/components/Modal/Modal.tsx
index 64fad2b..d81dc85 100644
--- a/superset-frontend/src/common/components/Modal/Modal.tsx
+++ b/superset-frontend/src/common/components/Modal/Modal.tsx
@@ -48,6 +48,7 @@ interface StyledModalProps extends SupersetThemeProps {
   maxWidth?: string;
   responsive?: boolean;
   height?: string;
+  hideFooter?: boolean;
 }
 
 export const StyledModal = styled(BaseModal)<StyledModalProps>`
diff --git a/superset-frontend/src/components/TableView/TableView.tsx b/superset-frontend/src/components/TableView/TableView.tsx
index 10dc4b2..a6c441d 100644
--- a/superset-frontend/src/components/TableView/TableView.tsx
+++ b/superset-frontend/src/components/TableView/TableView.tsx
@@ -43,6 +43,7 @@ export interface TableViewProps {
   className?: string;
   isPaginationSticky?: boolean;
   showRowCount?: boolean;
+  scrollTable?: boolean;
 }
 
 const EmptyWrapper = styled.div`
@@ -51,7 +52,16 @@ const EmptyWrapper = styled.div`
 
 const TableViewStyles = styled.div<{
   isPaginationSticky?: boolean;
+  scrollTable?: boolean;
 }>`
+  ${({ scrollTable, theme }) =>
+    scrollTable &&
+    `
+    height: 300px;
+    margin-bottom: ${theme.gridUnit * 4}px;
+    overflow: auto;
+  `}
+
   .table-cell.table-cell {
     vertical-align: top;
   }
diff --git a/superset-frontend/src/datasource/ChangeDatasourceModal.tsx b/superset-frontend/src/datasource/ChangeDatasourceModal.tsx
index 2e5937f..c2b43eb 100644
--- a/superset-frontend/src/datasource/ChangeDatasourceModal.tsx
+++ b/superset-frontend/src/datasource/ChangeDatasourceModal.tsx
@@ -222,6 +222,8 @@ const ChangeDatasourceModal: FunctionComponent<ChangeDatasourceModalProps> = ({
       responsive
       title={t('Change Dataset')}
       width={confirmChange ? '432px' : ''}
+      height={confirmChange ? 'auto' : '480px'}
+      hideFooter={!confirmChange}
       footer={
         <>
           {confirmChange && (
@@ -267,6 +269,7 @@ const ChangeDatasourceModal: FunctionComponent<ChangeDatasourceModalProps> = ({
                 pageSize={20}
                 className="table-condensed"
                 emptyWrapperType={EmptyWrapperType.Small}
+                scrollTable
               />
             )}
           </>
diff --git a/superset-frontend/src/datasource/DatasourceEditor.jsx b/superset-frontend/src/datasource/DatasourceEditor.jsx
index 347947a..4427b22 100644
--- a/superset-frontend/src/datasource/DatasourceEditor.jsx
+++ b/superset-frontend/src/datasource/DatasourceEditor.jsx
@@ -22,9 +22,8 @@ import { Alert, Col, Radio, Well } from 'react-bootstrap';
 import Badge from 'src/common/components/Badge';
 import shortid from 'shortid';
 import { styled, SupersetClient, t, supersetTheme } from '@superset-ui/core';
-
-import Tabs from 'src/common/components/Tabs';
 import Button from 'src/components/Button';
+import Tabs from 'src/common/components/Tabs';
 import CertifiedIconWithTooltip from 'src/components/CertifiedIconWithTooltip';
 import DatabaseSelector from 'src/components/DatabaseSelector';
 import Icon from 'src/components/Icon';
@@ -78,6 +77,11 @@ const EditLockContainer = styled.div`
   }
 `;
 
+const ColumnButtonWrapper = styled.div`
+  text-align: right;
+  ${({ theme }) => `margin-bottom: ${theme.gridUnit * 2}px`}
+`;
+
 const checkboxGenerator = (d, onChange) => (
   <CheckboxControl value={d} onChange={onChange} />
 );
@@ -121,6 +125,7 @@ function ColumnCollectionTable({
       allowDeletes
       allowAddItem={allowAddItem}
       itemGenerator={itemGenerator}
+      stickyHeader
       expandFieldset={
         <FormContainer>
           <Fieldset compact>
@@ -943,6 +948,7 @@ class DatasourceEditor extends React.PureComponent {
           ),
         }}
         allowDeletes
+        stickyHeader
       />
     );
   }
@@ -991,19 +997,26 @@ class DatasourceEditor extends React.PureComponent {
             key={2}
           >
             <div>
+              <ColumnButtonWrapper>
+                <span className="m-t-10 m-r-10">
+                  <Button
+                    buttonSize="sm"
+                    buttonStyle="primary"
+                    onClick={this.syncMetadata}
+                    className="sync-from-source"
+                  >
+                    <i className="fa fa-database" />{' '}
+                    {t('Sync columns from source')}
+                  </Button>
+                </span>
+              </ColumnButtonWrapper>
               <ColumnCollectionTable
+                className="columns-table"
                 columns={this.state.databaseColumns}
                 onChange={databaseColumns =>
                   this.setColumns({ databaseColumns })
                 }
               />
-              <Button
-                buttonStyle="primary"
-                onClick={this.syncMetadata}
-                className="sync-from-source"
-              >
-                {t('Sync columns from source')}
-              </Button>
               {this.state.metadataLoading && <Loading />}
             </div>
           </Tabs.TabPane>


[superset] 12/38: Apply capitalization guidelines - iteration 5 (#12343) (#12451)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 46507ba58ac272d543b0bb1133cbb12c574d08e9
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Fri Jan 22 15:11:48 2021 -0300

    Apply capitalization guidelines - iteration 5 (#12343) (#12451)
---
 superset-frontend/src/datasource/DatasourceModal.tsx     |  2 +-
 .../src/explore/components/ExploreViewContainer.jsx      |  2 +-
 .../src/explore/components/PropertiesModal.tsx           |  4 ++--
 superset-frontend/src/explore/components/SaveModal.tsx   |  2 +-
 .../src/explore/components/controls/AnnotationLayer.jsx  | 16 ++++++++--------
 .../components/controls/AnnotationLayerControl.jsx       |  2 +-
 .../explore/components/controls/DatasourceControl.jsx    |  4 ++--
 .../AdhocFilterEditPopoverSimpleTabContent.jsx           |  2 +-
 .../AdhocFilterEditPopoverSqlTabContent.jsx              |  4 ++--
 .../MetricControl/AdhocMetricEditPopoverTitle.jsx        |  2 +-
 10 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/superset-frontend/src/datasource/DatasourceModal.tsx b/superset-frontend/src/datasource/DatasourceModal.tsx
index 2ccb8fe..2dc1cee 100644
--- a/superset-frontend/src/datasource/DatasourceModal.tsx
+++ b/superset-frontend/src/datasource/DatasourceModal.tsx
@@ -190,7 +190,7 @@ const DatasourceModal: FunctionComponent<DatasourceModalProps> = ({
                   currentDatasource.edit_url || currentDatasource.url;
               }}
             >
-              {t('Use Legacy Datasource Editor')}
+              {t('Use legacy datasource editor')}
             </Button>
           )}
           <Button
diff --git a/superset-frontend/src/explore/components/ExploreViewContainer.jsx b/superset-frontend/src/explore/components/ExploreViewContainer.jsx
index 1a701df..349bded 100644
--- a/superset-frontend/src/explore/components/ExploreViewContainer.jsx
+++ b/superset-frontend/src/explore/components/ExploreViewContainer.jsx
@@ -443,7 +443,7 @@ function ExploreViewContainer(props) {
           tabIndex={0}
         >
           <span role="button" tabIndex={0} className="action-button">
-            <Tooltip title={t('Open Datasource Tab')}>
+            <Tooltip title={t('Open Datasource tab')}>
               <Icon
                 name="collapse"
                 color={supersetTheme.colors.primary.base}
diff --git a/superset-frontend/src/explore/components/PropertiesModal.tsx b/superset-frontend/src/explore/components/PropertiesModal.tsx
index cdbea9f..1f0de03 100644
--- a/superset-frontend/src/explore/components/PropertiesModal.tsx
+++ b/superset-frontend/src/explore/components/PropertiesModal.tsx
@@ -194,7 +194,7 @@ export default function PropertiesModal({
       <form onSubmit={onSubmit}>
         <Row>
           <Col md={6}>
-            <h3>{t('Basic Information')}</h3>
+            <h3>{t('Basic information')}</h3>
             <FormGroup>
               <FormLabel htmlFor="name" required>
                 {t('Name')}
@@ -235,7 +235,7 @@ export default function PropertiesModal({
           <Col md={6}>
             <h3>{t('Configuration')}</h3>
             <FormGroup>
-              <FormLabel htmlFor="cacheTimeout">{t('Cache Timeout')}</FormLabel>
+              <FormLabel htmlFor="cacheTimeout">{t('Cache timeout')}</FormLabel>
               <FormControl
                 name="cacheTimeout"
                 type="text"
diff --git a/superset-frontend/src/explore/components/SaveModal.tsx b/superset-frontend/src/explore/components/SaveModal.tsx
index e079b1a..c4e42e4 100644
--- a/superset-frontend/src/explore/components/SaveModal.tsx
+++ b/superset-frontend/src/explore/components/SaveModal.tsx
@@ -162,7 +162,7 @@ class SaveModal extends React.Component<SaveModalProps, SaveModalState> {
       <StyledModal
         show
         onHide={this.props.onHide}
-        title={t('Save Chart')}
+        title={t('Save chart')}
         footer={
           <div data-test="save-modal-footer">
             <Button id="btn_cancel" buttonSize="sm" onClick={this.props.onHide}>
diff --git a/superset-frontend/src/explore/components/controls/AnnotationLayer.jsx b/superset-frontend/src/explore/components/controls/AnnotationLayer.jsx
index 1c65c56..10e9502 100644
--- a/superset-frontend/src/explore/components/controls/AnnotationLayer.jsx
+++ b/superset-frontend/src/explore/components/controls/AnnotationLayer.jsx
@@ -377,7 +377,7 @@ export default class AnnotationLayer extends React.PureComponent {
     let description = '';
     if (requiresQuery(sourceType)) {
       if (sourceType === ANNOTATION_SOURCE_TYPES.NATIVE) {
-        label = 'Annotation Layer';
+        label = 'Annotation layer';
         description = 'Select the Annotation Layer you would like to use.';
       } else {
         label = t('Chart');
@@ -467,8 +467,8 @@ export default class AnnotationLayer extends React.PureComponent {
                 name="annotation-layer-time-column"
                 label={
                   annotationType === ANNOTATION_TYPES.INTERVAL
-                    ? 'Interval Start column'
-                    : 'Event Time Column'
+                    ? 'Interval start column'
+                    : 'Event time column'
                 }
                 description="This column must contain date/time information."
                 validationErrors={!timeColumn ? ['Mandatory'] : []}
@@ -608,7 +608,7 @@ export default class AnnotationLayer extends React.PureComponent {
           options={[
             { value: 'solid', label: 'Solid' },
             { value: 'dashed', label: 'Dashed' },
-            { value: 'longDashed', label: 'Long Dashed' },
+            { value: 'longDashed', label: 'Long dashed' },
             { value: 'dotted', label: 'Dotted' },
           ]}
           value={style}
@@ -648,7 +648,7 @@ export default class AnnotationLayer extends React.PureComponent {
         </div>
         <TextControl
           name="annotation-layer-stroke-width"
-          label={t('Line Width')}
+          label={t('Line width')}
           isInt
           value={width}
           onChange={v => this.setState({ width: v })}
@@ -711,14 +711,14 @@ export default class AnnotationLayer extends React.PureComponent {
               />
               <CheckboxControl
                 name="annotation-layer-hide"
-                label={t('Hide Layer')}
+                label={t('Hide layer')}
                 value={!show}
                 onChange={v => this.setState({ show: !v })}
               />
               <SelectControl
                 hovered
-                description={t('Choose the Annotation Layer Type')}
-                label={t('Annotation Layer Type')}
+                description={t('Choose the annotation layer type')}
+                label={t('Annotation layer type')}
                 name="annotation-layer-type"
                 clearable={false}
                 options={supportedAnnotationTypes}
diff --git a/superset-frontend/src/explore/components/controls/AnnotationLayerControl.jsx b/superset-frontend/src/explore/components/controls/AnnotationLayerControl.jsx
index e47388c..a701892 100644
--- a/superset-frontend/src/explore/components/controls/AnnotationLayerControl.jsx
+++ b/superset-frontend/src/explore/components/controls/AnnotationLayerControl.jsx
@@ -163,7 +163,7 @@ class AnnotationLayerControl extends React.PureComponent {
         key={i}
         trigger="click"
         placement="right"
-        title={t('Edit Annotation Layer')}
+        title={t('Edit annotation layer')}
         content={this.renderPopover(
           i,
           anno,
diff --git a/superset-frontend/src/explore/components/controls/DatasourceControl.jsx b/superset-frontend/src/explore/components/controls/DatasourceControl.jsx
index e30aebe..d531d55 100644
--- a/superset-frontend/src/explore/components/controls/DatasourceControl.jsx
+++ b/superset-frontend/src/explore/components/controls/DatasourceControl.jsx
@@ -156,10 +156,10 @@ class DatasourceControl extends React.PureComponent {
       <Menu onClick={this.handleMenuItemClick}>
         {this.props.isEditable && (
           <Menu.Item key={EDIT_DATASET} data-test="edit-dataset">
-            {t('Edit Dataset')}
+            {t('Edit dataset')}
           </Menu.Item>
         )}
-        <Menu.Item key={CHANGE_DATASET}>{t('Change Dataset')}</Menu.Item>
+        <Menu.Item key={CHANGE_DATASET}>{t('Change dataset')}</Menu.Item>
         <Menu.Item key={VIEW_IN_SQL_LAB}>{t('View in SQL Lab')}</Menu.Item>
       </Menu>
     );
diff --git a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent.jsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent.jsx
index dbec5e6..9940d06 100644
--- a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent.jsx
+++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSimpleTabContent.jsx
@@ -323,7 +323,7 @@ export default class AdhocFilterEditPopoverSimpleTabContent extends React.Compon
       loading: this.state.loading,
       value: comparator,
       onChange: this.onComparatorChange,
-      notFoundContent: t('type a value here'),
+      notFoundContent: t('Type a value here'),
       disabled: DISABLE_INPUT_OPERATORS.includes(operator),
       placeholder: this.createSuggestionsPlaceholder(),
       labelText: comparator?.length > 0 && this.createSuggestionsPlaceholder(),
diff --git a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent.jsx b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent.jsx
index 7841d88..429414b 100644
--- a/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent.jsx
+++ b/superset-frontend/src/explore/components/controls/FilterControl/AdhocFilterEditPopoverSqlTabContent.jsx
@@ -124,9 +124,9 @@ export default class AdhocFilterEditPopoverSqlTabContent extends React.Component
             ))}
           </Select>
           <span className="filter-edit-clause-info">
-            <strong>WHERE</strong> {t('filters by columns')}
+            <strong>WHERE</strong> {t('Filters by columns')}
             <br />
-            <strong>HAVING</strong> {t('filters by metrics')}
+            <strong>HAVING</strong> {t('Filters by metrics')}
           </span>
         </FormGroup>
         <FormGroup>
diff --git a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopoverTitle.jsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopoverTitle.jsx
index 4c2f3f4..d5ac317 100644
--- a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopoverTitle.jsx
+++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricEditPopoverTitle.jsx
@@ -70,7 +70,7 @@ export default class AdhocMetricEditPopoverTitle extends React.Component {
 
   render() {
     const { title, onChange, isEditDisabled } = this.props;
-    const defaultLabel = t('My Metric');
+    const defaultLabel = t('My metric');
 
     if (isEditDisabled) {
       return (


[superset] 27/38: chore(explore): Save Resizable width to localStorage (#12593)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 522f466b237d616e98ceb7f6b15fe255ff8d324a
Author: Nikola Gigić <ni...@gmail.com>
AuthorDate: Mon Jan 25 05:30:09 2021 +0100

    chore(explore): Save Resizable width to localStorage (#12593)
---
 .../explore/components/ExploreViewContainer.jsx    | 47 ++++++++++++++++++++--
 1 file changed, 43 insertions(+), 4 deletions(-)

diff --git a/superset-frontend/src/explore/components/ExploreViewContainer.jsx b/superset-frontend/src/explore/components/ExploreViewContainer.jsx
index 5ea90a2..990373a 100644
--- a/superset-frontend/src/explore/components/ExploreViewContainer.jsx
+++ b/superset-frontend/src/explore/components/ExploreViewContainer.jsx
@@ -169,6 +169,16 @@ function ExploreViewContainer(props) {
     ? `${props.forcedHeight}px`
     : `${windowSize.height - navHeight}px`;
 
+  const storageKeys = {
+    controlsWidth: 'controls_width',
+    dataSourceWidth: 'datasource_width',
+  };
+
+  const defaultSidebarsWidth = {
+    controls_width: 320,
+    datasource_width: 300,
+  };
+
   function addHistory({ isReplace = false, title } = {}) {
     const payload = { ...props.form_data };
     const longUrl = getExploreLongUrl(
@@ -368,6 +378,23 @@ function ExploreViewContainer(props) {
     );
   }
 
+  function getSidebarWidths(key) {
+    try {
+      return localStorage.getItem(key) || defaultSidebarsWidth[key];
+    } catch {
+      return defaultSidebarsWidth[key];
+    }
+  }
+
+  function setSidebarWidths(key, dimension) {
+    try {
+      const newDimension = Number(getSidebarWidths(key)) + dimension.width;
+      localStorage.setItem(key, newDimension);
+    } catch {
+      // Catch in case localStorage is unavailable
+    }
+  }
+
   if (props.standalone) {
     return renderChartContainer();
   }
@@ -407,8 +434,14 @@ function ExploreViewContainer(props) {
         />
       )}
       <Resizable
-        defaultSize={{ width: 300, height: '100%' }}
-        minWidth={300}
+        onResizeStop={(evt, direction, ref, d) =>
+          setSidebarWidths(storageKeys.dataSourceWidth, d)
+        }
+        defaultSize={{
+          width: getSidebarWidths(storageKeys.dataSourceWidth),
+          height: '100%',
+        }}
+        minWidth={defaultSidebarsWidth[storageKeys.dataSourceWidth]}
         maxWidth="33%"
         enable={{ right: true }}
         className={
@@ -459,8 +492,14 @@ function ExploreViewContainer(props) {
         </div>
       ) : null}
       <Resizable
-        defaultSize={{ width: 320, height: '100%' }}
-        minWidth={320}
+        onResizeStop={(evt, direction, ref, d) =>
+          setSidebarWidths(storageKeys.controlsWidth, d)
+        }
+        defaultSize={{
+          width: getSidebarWidths(storageKeys.controlsWidth),
+          height: '100%',
+        }}
+        minWidth={defaultSidebarsWidth[storageKeys.controlsWidth]}
         maxWidth="33%"
         enable={{ right: true }}
         className="col-sm-3 explore-column controls-column"


[superset] 05/38: fix: styling for change dataset confirmation (#12471)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 3d8185383d9f46c62589db31805fabdbb3b0c4e9
Author: Hugh A. Miles II <hu...@gmail.com>
AuthorDate: Wed Jan 13 12:48:15 2021 -0500

    fix: styling for change dataset confirmation (#12471)
---
 superset-frontend/src/datasource/ChangeDatasourceModal.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/superset-frontend/src/datasource/ChangeDatasourceModal.tsx b/superset-frontend/src/datasource/ChangeDatasourceModal.tsx
index 7831dba..2e5937f 100644
--- a/superset-frontend/src/datasource/ChangeDatasourceModal.tsx
+++ b/superset-frontend/src/datasource/ChangeDatasourceModal.tsx
@@ -221,7 +221,7 @@ const ChangeDatasourceModal: FunctionComponent<ChangeDatasourceModalProps> = ({
       onHide={onHide}
       responsive
       title={t('Change Dataset')}
-      height="350px"
+      width={confirmChange ? '432px' : ''}
       footer={
         <>
           {confirmChange && (


[superset] 23/38: test: birth names (#12226)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 0acd2ccaaacacb96a18bd0e96fb2324ed941dc87
Author: Karol Kostrzewa <ka...@gmail.com>
AuthorDate: Mon Jan 11 14:57:55 2021 +0100

    test: birth names (#12226)
    
    * add birth names fixture
    
    * fix birth names related tests
    
    * fix test_import_v0_dataset_cli_export columns order
    
    * fix celery tests drop table
    
    * fix mysql datetime type
    
    * fix mysql typo in charts/api_tests
    
    * refactor
    
    * add licence
    
    * fix use fixture for presto
    
    * fix presto, hive query
    
    * fix flaky metadata
    
    * fix mysql bigint type
    
    * fix run query
    
    * fix hive datatype in metadata
    
    * fix slice owner for cypress
    
    * refactor num_boys num_girls
    
    * fix is_dttm column
    
    * debug logging
    
    * fix query offset
    
    * fix presto ds type in metadata
    
    * fix presto ds type
    
    * clean up debug logging
---
 superset/examples/birth_names.py        |  60 ++++++---
 tests/access_tests.py                   |   8 +-
 tests/cache_tests.py                    |   5 +
 tests/celery_tests.py                   |  23 ++++
 tests/charts/api_tests.py               |  83 ++++++++++--
 tests/conftest.py                       |   2 -
 tests/core_tests.py                     |  35 ++++-
 tests/dashboard_tests.py                |  17 ++-
 tests/dashboards/api_tests.py           |  13 +-
 tests/databases/api_tests.py            |   7 +-
 tests/databases/commands_tests.py       | 232 +++++++++++++++++---------------
 tests/datasets/api_tests.py             |  12 +-
 tests/datasets/commands_tests.py        |   5 +-
 tests/datasource_tests.py               |  46 ++++++-
 tests/fixtures/birth_names_dashboard.py | 202 +++++++++++++++++++++++++++
 tests/import_export_tests.py            |   3 +
 tests/model_tests.py                    |  34 ++---
 tests/query_context_tests.py            |   8 +-
 tests/schedules_test.py                 |   4 +
 tests/security_tests.py                 |   4 +
 tests/sqla_models_tests.py              |   2 +
 tests/sqllab_tests.py                   |  21 ++-
 tests/strategy_tests.py                 |   6 +-
 tests/tasks/async_queries_tests.py      |   3 +
 tests/utils/get_dashboards.py           |  28 ++++
 tests/utils_tests.py                    |   3 +
 26 files changed, 677 insertions(+), 189 deletions(-)

diff --git a/superset/examples/birth_names.py b/superset/examples/birth_names.py
index ae7367a..a872994 100644
--- a/superset/examples/birth_names.py
+++ b/superset/examples/birth_names.py
@@ -108,32 +108,49 @@ def load_birth_names(
         print(f"Creating table [{tbl_name}] reference")
         obj = TBL(table_name=tbl_name)
         db.session.add(obj)
-    obj.main_dttm_col = "ds"
-    obj.database = database
-    obj.filter_select_enabled = True
-    obj.fetch_metadata()
 
-    if not any(col.column_name == "num_california" for col in obj.columns):
+    _set_table_metadata(obj, database)
+    _add_table_metrics(obj)
+
+    db.session.commit()
+
+    slices, _ = create_slices(obj, admin_owner=True)
+    create_dashboard(slices)
+
+
+def _set_table_metadata(datasource: "BaseDatasource", database: "Database") -> None:
+    datasource.main_dttm_col = "ds"  # type: ignore
+    datasource.database = database
+    datasource.filter_select_enabled = True
+    datasource.fetch_metadata()
+
+
+def _add_table_metrics(datasource: "BaseDatasource") -> None:
+    if not any(col.column_name == "num_california" for col in datasource.columns):
         col_state = str(column("state").compile(db.engine))
         col_num = str(column("num").compile(db.engine))
-        obj.columns.append(
+        datasource.columns.append(
             TableColumn(
                 column_name="num_california",
                 expression=f"CASE WHEN {col_state} = 'CA' THEN {col_num} ELSE 0 END",
             )
         )
 
-    if not any(col.metric_name == "sum__num" for col in obj.metrics):
+    if not any(col.metric_name == "sum__num" for col in datasource.metrics):
         col = str(column("num").compile(db.engine))
-        obj.metrics.append(SqlMetric(metric_name="sum__num", expression=f"SUM({col})"))
-
-    db.session.commit()
+        datasource.metrics.append(
+            SqlMetric(metric_name="sum__num", expression=f"SUM({col})")
+        )
 
-    slices, _ = create_slices(obj)
-    create_dashboard(slices)
+    for col in datasource.columns:
+        if col.column_name == "ds":
+            col.is_dttm = True  # type: ignore
+            break
 
 
-def create_slices(tbl: BaseDatasource) -> Tuple[List[Slice], List[Slice]]:
+def create_slices(
+    tbl: BaseDatasource, admin_owner: bool
+) -> Tuple[List[Slice], List[Slice]]:
     metrics = [
         {
             "expressionType": "SIMPLE",
@@ -160,9 +177,17 @@ def create_slices(tbl: BaseDatasource) -> Tuple[List[Slice], List[Slice]]:
         "markup_type": "markdown",
     }
 
-    slice_props = dict(
-        datasource_id=tbl.id, datasource_type="table", owners=[admin], created_by=admin
-    )
+    if admin_owner:
+        slice_props = dict(
+            datasource_id=tbl.id,
+            datasource_type="table",
+            owners=[admin],
+            created_by=admin,
+        )
+    else:
+        slice_props = dict(
+            datasource_id=tbl.id, datasource_type="table", owners=[], created_by=admin
+        )
 
     print("Creating some slices")
     slices = [
@@ -475,7 +500,7 @@ def create_slices(tbl: BaseDatasource) -> Tuple[List[Slice], List[Slice]]:
     return slices, misc_slices
 
 
-def create_dashboard(slices: List[Slice]) -> None:
+def create_dashboard(slices: List[Slice]) -> Dashboard:
     print("Creating a dashboard")
 
     dash = db.session.query(Dashboard).filter_by(slug="births").first()
@@ -779,3 +804,4 @@ def create_dashboard(slices: List[Slice]) -> None:
     dash.position_json = json.dumps(pos, indent=4)
     dash.slug = "births"
     db.session.commit()
+    return dash
diff --git a/tests/access_tests.py b/tests/access_tests.py
index 2dec294..4e568a5 100644
--- a/tests/access_tests.py
+++ b/tests/access_tests.py
@@ -19,6 +19,7 @@
 import json
 import unittest
 from unittest import mock
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 
 import pytest
 
@@ -142,6 +143,7 @@ class TestRequestAccess(SupersetTestCase):
         )
         self.assertNotEqual(405, response.status_code)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_override_role_permissions_1_table(self):
         response = self.client.post(
             "/superset/override_role_permissions/",
@@ -160,6 +162,7 @@ class TestRequestAccess(SupersetTestCase):
             "datasource_access", updated_override_me.permissions[0].permission.name
         )
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_override_role_permissions_druid_and_table(self):
         response = self.client.post(
             "/superset/override_role_permissions/",
@@ -187,7 +190,9 @@ class TestRequestAccess(SupersetTestCase):
         )
         self.assertEqual(3, len(perms))
 
-    @pytest.mark.usefixtures("load_energy_table_with_slice")
+    @pytest.mark.usefixtures(
+        "load_energy_table_with_slice", "load_birth_names_dashboard_with_slices"
+    )
     def test_override_role_permissions_drops_absent_perms(self):
         override_me = security_manager.find_role("override_me")
         override_me.permissions.append(
@@ -247,6 +252,7 @@ class TestRequestAccess(SupersetTestCase):
             gamma_user = security_manager.find_user(username="gamma")
             gamma_user.roles.remove(security_manager.find_role("test_role1"))
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_clean_requests_after_alpha_grant(self):
         session = db.session
 
diff --git a/tests/cache_tests.py b/tests/cache_tests.py
index 3ffd52a..43a4cf6 100644
--- a/tests/cache_tests.py
+++ b/tests/cache_tests.py
@@ -17,9 +17,12 @@
 """Unit tests for Superset with caching"""
 import json
 
+import pytest
+
 from superset import app, db
 from superset.extensions import cache_manager
 from superset.utils.core import QueryStatus
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 
 from .base_tests import SupersetTestCase
 
@@ -34,6 +37,7 @@ class TestCache(SupersetTestCase):
         cache_manager.cache.clear()
         cache_manager.data_cache.clear()
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_no_data_cache(self):
         data_cache_config = app.config["DATA_CACHE_CONFIG"]
         app.config["DATA_CACHE_CONFIG"] = {"CACHE_TYPE": "null"}
@@ -54,6 +58,7 @@ class TestCache(SupersetTestCase):
         self.assertFalse(resp["is_cached"])
         self.assertFalse(resp_from_cache["is_cached"])
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_slice_data_cache(self):
         # Override cache config
         data_cache_config = app.config["DATA_CACHE_CONFIG"]
diff --git a/tests/celery_tests.py b/tests/celery_tests.py
index f492cf0..689eea8 100644
--- a/tests/celery_tests.py
+++ b/tests/celery_tests.py
@@ -23,6 +23,7 @@ import string
 import time
 import unittest.mock as mock
 from typing import Optional
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 
 import pytest
 
@@ -160,6 +161,7 @@ def test_run_sync_query_dont_exist(setup_sqllab, ctas_method):
         }
 
 
+@pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
 @pytest.mark.parametrize("ctas_method", [CtasMethod.TABLE, CtasMethod.VIEW])
 def test_run_sync_query_cta(setup_sqllab, ctas_method):
     tmp_table_name = f"{TEST_SYNC}_{ctas_method.lower()}"
@@ -173,7 +175,10 @@ def test_run_sync_query_cta(setup_sqllab, ctas_method):
     assert QueryStatus.SUCCESS == results["status"], results
     assert len(results["data"]) > 0
 
+    delete_tmp_view_or_table(tmp_table_name, ctas_method)
 
+
+@pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
 def test_run_sync_query_cta_no_data(setup_sqllab):
     sql_empty_result = "SELECT * FROM birth_names WHERE name='random'"
     result = run_sql(sql_empty_result)
@@ -184,6 +189,7 @@ def test_run_sync_query_cta_no_data(setup_sqllab):
     assert QueryStatus.SUCCESS == query.status
 
 
+@pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
 @pytest.mark.parametrize("ctas_method", [CtasMethod.TABLE, CtasMethod.VIEW])
 @mock.patch(
     "superset.views.core.get_cta_schema_name", lambda d, u, s, sql: CTAS_SCHEMA_NAME
@@ -208,7 +214,10 @@ def test_run_sync_query_cta_config(setup_sqllab, ctas_method):
     results = run_sql(query.select_sql)
     assert QueryStatus.SUCCESS == results["status"], result
 
+    delete_tmp_view_or_table(f"{CTAS_SCHEMA_NAME}.{tmp_table_name}", ctas_method)
+
 
+@pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
 @pytest.mark.parametrize("ctas_method", [CtasMethod.TABLE, CtasMethod.VIEW])
 @mock.patch(
     "superset.views.core.get_cta_schema_name", lambda d, u, s, sql: CTAS_SCHEMA_NAME
@@ -232,7 +241,10 @@ def test_run_async_query_cta_config(setup_sqllab, ctas_method):
         == query.executed_sql
     )
 
+    delete_tmp_view_or_table(f"{CTAS_SCHEMA_NAME}.{tmp_table_name}", ctas_method)
 
+
+@pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
 @pytest.mark.parametrize("ctas_method", [CtasMethod.TABLE, CtasMethod.VIEW])
 def test_run_async_cta_query(setup_sqllab, ctas_method):
     table_name = f"{TEST_ASYNC_CTA}_{ctas_method.lower()}"
@@ -252,7 +264,10 @@ def test_run_async_cta_query(setup_sqllab, ctas_method):
     assert query.select_as_cta
     assert query.select_as_cta_used
 
+    delete_tmp_view_or_table(table_name, ctas_method)
+
 
+@pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
 @pytest.mark.parametrize("ctas_method", [CtasMethod.TABLE, CtasMethod.VIEW])
 def test_run_async_cta_query_with_lower_limit(setup_sqllab, ctas_method):
     tmp_table = f"{TEST_ASYNC_LOWER_LIMIT}_{ctas_method.lower()}"
@@ -272,6 +287,8 @@ def test_run_async_cta_query_with_lower_limit(setup_sqllab, ctas_method):
     assert query.select_as_cta
     assert query.select_as_cta_used
 
+    delete_tmp_view_or_table(tmp_table, ctas_method)
+
 
 SERIALIZATION_DATA = [("a", 4, 4.0, datetime.datetime(2019, 8, 18, 16, 39, 16, 660000))]
 CURSOR_DESCR = (
@@ -306,6 +323,7 @@ def test_new_data_serialization():
     assert isinstance(data[0], bytes)
 
 
+@pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
 def test_default_payload_serialization():
     use_new_deserialization = False
     db_engine_spec = BaseEngineSpec()
@@ -338,6 +356,7 @@ def test_default_payload_serialization():
     assert isinstance(serialized, str)
 
 
+@pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
 def test_msgpack_payload_serialization():
     use_new_deserialization = True
     db_engine_spec = BaseEngineSpec()
@@ -406,3 +425,7 @@ def test_in_app_context():
         my_task()
     finally:
         flask._app_ctx_stack.push(popped_app)
+
+
+def delete_tmp_view_or_table(name: str, db_object_type: str):
+    db.get_engine().execute(f"DROP {db_object_type} IF EXISTS {name}")
diff --git a/tests/charts/api_tests.py b/tests/charts/api_tests.py
index b8a46cf..99ab93c 100644
--- a/tests/charts/api_tests.py
+++ b/tests/charts/api_tests.py
@@ -18,16 +18,19 @@
 """Unit tests for Superset"""
 import json
 from typing import List, Optional
-from datetime import datetime
+from datetime import datetime, timedelta
 from io import BytesIO
 from unittest import mock
 from zipfile import is_zipfile, ZipFile
 
+from superset.models.sql_lab import Query
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
+
 import humanize
 import prison
 import pytest
 import yaml
-from sqlalchemy import and_
+from sqlalchemy import and_, or_
 from sqlalchemy.sql import func
 
 from tests.test_app import app
@@ -41,7 +44,7 @@ from superset.models.dashboard import Dashboard
 from superset.models.reports import ReportSchedule, ReportScheduleType
 from superset.models.slice import Slice
 from superset.utils import core as utils
-from superset.utils.core import AnnotationType, get_example_database
+from superset.utils.core import AnnotationType, get_example_database, get_main_database
 
 from tests.base_api_tests import ApiOwnersTestCaseMixin
 from tests.base_tests import SupersetTestCase, post_assert_metric, test_client
@@ -57,6 +60,7 @@ from tests.fixtures.energy_dashboard import load_energy_table_with_slice
 from tests.fixtures.query_context import get_query_context, ANNOTATION_LAYERS
 from tests.fixtures.unicode_dashboard import load_unicode_dashboard_with_slice
 from tests.annotation_layers.fixtures import create_annotation_layers
+from tests.utils.get_dashboards import get_dashboards_ids
 
 CHART_DATA_URI = "api/v1/chart/data"
 CHARTS_FIXTURE_COUNT = 10
@@ -431,10 +435,12 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         db.session.delete(user_alpha2)
         db.session.commit()
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_create_chart(self):
         """
         Chart API: Test create chart
         """
+        dashboards_ids = get_dashboards_ids(db, ["world_health", "births"])
         admin_id = self.get_user("admin").id
         chart_data = {
             "slice_name": "name1",
@@ -445,7 +451,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
             "cache_timeout": 1000,
             "datasource_id": 1,
             "datasource_type": "table",
-            "dashboards": [1, 2],
+            "dashboards": dashboards_ids,
         }
         self.login(username="admin")
         uri = f"api/v1/chart/"
@@ -733,6 +739,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         rv = self.get_assert_metric(uri, "get")
         self.assertEqual(rv.status_code, 404)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_get_chart_no_data_access(self):
         """
         Chart API: Test get chart without data access
@@ -747,8 +754,11 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         rv = self.client.get(uri)
         self.assertEqual(rv.status_code, 404)
 
-    @pytest.mark.usefixtures("load_unicode_dashboard_with_slice")
-    @pytest.mark.usefixtures("load_energy_table_with_slice")
+    @pytest.mark.usefixtures(
+        "load_energy_table_with_slice",
+        "load_birth_names_dashboard_with_slices",
+        "load_unicode_dashboard_with_slice",
+    )
     def test_get_charts(self):
         """
         Chart API: Test get charts
@@ -788,6 +798,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         db.session.delete(chart)
         db.session.commit()
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_get_charts_filter(self):
         """
         Chart API: Test get charts filter
@@ -995,7 +1006,9 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         self.assertEqual(len(data["result"]), 3)
 
     @pytest.mark.usefixtures(
-        "load_unicode_dashboard_with_slice", "load_energy_table_with_slice"
+        "load_unicode_dashboard_with_slice",
+        "load_energy_table_with_slice",
+        "load_birth_names_dashboard_with_slices",
     )
     def test_get_charts_page(self):
         """
@@ -1028,6 +1041,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         data = json.loads(rv.data.decode("utf-8"))
         self.assertEqual(data["count"], 0)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_chart_data_simple(self):
         """
         Chart data API: Test chart data query
@@ -1037,8 +1051,10 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data")
         self.assertEqual(rv.status_code, 200)
         data = json.loads(rv.data.decode("utf-8"))
-        self.assertEqual(data["result"][0]["rowcount"], 45)
+        expected_row_count = self.get_expected_row_count("client_id_1")
+        self.assertEqual(data["result"][0]["rowcount"], expected_row_count)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_chart_data_applied_time_extras(self):
         """
         Chart data API: Test chart data query with applied time extras
@@ -1060,8 +1076,10 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
             data["result"][0]["rejected_filters"],
             [{"column": "__time_origin", "reason": "not_druid_datasource"},],
         )
-        self.assertEqual(data["result"][0]["rowcount"], 45)
+        expected_row_count = self.get_expected_row_count("client_id_2")
+        self.assertEqual(data["result"][0]["rowcount"], expected_row_count)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_chart_data_limit_offset(self):
         """
         Chart data API: Test chart data query with limit and offset
@@ -1090,6 +1108,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         self.assertEqual(result["rowcount"], 5)
         self.assertEqual(result["data"][0]["name"], expected_name)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     @mock.patch(
         "superset.common.query_object.config", {**app.config, "ROW_LIMIT": 7},
     )
@@ -1105,6 +1124,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         result = response_payload["result"][0]
         self.assertEqual(result["rowcount"], 7)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     @mock.patch(
         "superset.common.query_context.config", {**app.config, "SAMPLES_ROW_LIMIT": 5},
     )
@@ -1131,6 +1151,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data")
         self.assertEqual(rv.status_code, 400)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_chart_data_incorrect_result_format(self):
         """
         Chart data API: Test chart data with unsupported result format
@@ -1141,6 +1162,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data")
         self.assertEqual(rv.status_code, 400)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_chart_data_query_result_type(self):
         """
         Chart data API: Test chart data with query result format
@@ -1151,6 +1173,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data")
         self.assertEqual(rv.status_code, 200)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_chart_data_csv_result_format(self):
         """
         Chart data API: Test chart data with CSV result format
@@ -1161,6 +1184,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data")
         self.assertEqual(rv.status_code, 200)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_chart_data_mixed_case_filter_op(self):
         """
         Chart data API: Ensure mixed case filter operator generates valid result
@@ -1208,6 +1232,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         self.assertIn("sum__num__yhat_lower", row)
         self.assertEqual(result["rowcount"], 47)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_chart_data_query_missing_filter(self):
         """
         Chart data API: Ensure filter referencing missing column is ignored
@@ -1223,6 +1248,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         response_payload = json.loads(rv.data.decode("utf-8"))
         assert "non_existent_filter" not in response_payload["result"][0]["query"]
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_chart_data_no_data(self):
         """
         Chart data API: Test chart data with empty result
@@ -1283,6 +1309,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         rv = self.post_assert_metric(CHART_DATA_URI, payload, "data")
         self.assertEqual(rv.status_code, 401)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_chart_data_jinja_filter_request(self):
         """
         Chart data API: Ensure request referencing filters via jinja renders a correct query
@@ -1325,6 +1352,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         "superset.extensions.feature_flag_manager._feature_flags",
         GLOBAL_ASYNC_QUERIES=True,
     )
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_chart_data_async_results_type(self):
         """
         Chart data API: Test chart data query non-JSON format (async)
@@ -1353,6 +1381,7 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         rv = post_assert_metric(test_client, CHART_DATA_URI, request_payload, "data")
         self.assertEqual(rv.status_code, 401)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     @mock.patch.dict(
         "superset.extensions.feature_flag_manager._feature_flags",
         GLOBAL_ASYNC_QUERIES=True,
@@ -1379,8 +1408,9 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
             )
             data = json.loads(rv.data.decode("utf-8"))
 
+        expected_row_count = self.get_expected_row_count("client_id_3")
         self.assertEqual(rv.status_code, 200)
-        self.assertEqual(data["result"][0]["rowcount"], 45)
+        self.assertEqual(data["result"][0]["rowcount"], expected_row_count)
 
     @mock.patch.dict(
         "superset.extensions.feature_flag_manager._feature_flags",
@@ -1609,7 +1639,9 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
             "message": {"metadata.yaml": {"type": ["Must be equal to Slice."]}}
         }
 
-    @pytest.mark.usefixtures("create_annotation_layers")
+    @pytest.mark.usefixtures(
+        "create_annotation_layers", "load_birth_names_dashboard_with_slices"
+    )
     def test_chart_data_annotations(self):
         """
         Chart data API: Test chart data query
@@ -1648,3 +1680,32 @@ class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         data = json.loads(rv.data.decode("utf-8"))
         # response should only contain interval and event data, not formula
         self.assertEqual(len(data["result"][0]["annotation_data"]), 2)
+
+    def get_expected_row_count(self, client_id: str) -> int:
+        start_date = datetime.now()
+        start_date = start_date.replace(
+            year=start_date.year - 100, hour=0, minute=0, second=0
+        )
+
+        quoted_table_name = self.quote_name("birth_names")
+        sql = f"""
+                            SELECT COUNT(*) AS rows_count FROM (
+                                SELECT name AS name, SUM(num) AS sum__num
+                                FROM {quoted_table_name}
+                                WHERE ds >= '{start_date.strftime("%Y-%m-%d %H:%M:%S")}'
+                                AND gender = 'boy'
+                                GROUP BY name
+                                ORDER BY sum__num DESC
+                                LIMIT 100) AS inner__query
+                        """
+        resp = self.run_sql(sql, client_id, raise_on_error=True)
+        db.session.query(Query).delete()
+        db.session.commit()
+        return resp["data"][0]["rows_count"]
+
+    def quote_name(self, name: str):
+        if get_main_database().backend in {"presto", "hive"}:
+            return get_example_database().inspector.engine.dialect.identifier_preparer.quote_identifier(
+                name
+            )
+        return name
diff --git a/tests/conftest.py b/tests/conftest.py
index 0e197b8..efa549f 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -43,14 +43,12 @@ def setup_sample_data() -> Any:
 
         examples.load_css_templates()
         examples.load_world_bank_health_n_pop(sample=True)
-        examples.load_birth_names(sample=True)
 
     yield
 
     with app.app_context():
         engine = get_example_database().get_sqla_engine()
         engine.execute("DROP TABLE wb_health_population")
-        engine.execute("DROP TABLE birth_names")
 
         # drop sqlachemy tables
 
diff --git a/tests/core_tests.py b/tests/core_tests.py
index 97ae5eb..16620b4 100644
--- a/tests/core_tests.py
+++ b/tests/core_tests.py
@@ -25,6 +25,7 @@ import json
 import logging
 from typing import Dict, List
 from urllib.parse import quote
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 
 import pytest
 import pytz
@@ -100,6 +101,7 @@ class TestCore(SupersetTestCase):
         resp = self.client.get("/superset/dashboard/-1/")
         assert resp.status_code == 404
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_slice_endpoint(self):
         self.login(username="admin")
         slc = self.get_slice("Girls", db.session)
@@ -114,6 +116,7 @@ class TestCore(SupersetTestCase):
         resp = self.client.get("/superset/slice/-1/")
         assert resp.status_code == 404
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_viz_cache_key(self):
         self.login(username="admin")
         slc = self.get_slice("Girls", db.session)
@@ -327,6 +330,7 @@ class TestCore(SupersetTestCase):
         assert len(resp) > 0
         assert "energy_target0" in resp
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_slice_data(self):
         # slice data should have some required attributes
         self.login(username="admin")
@@ -372,6 +376,7 @@ class TestCore(SupersetTestCase):
         resp = self.client.get(url)
         self.assertEqual(resp.status_code, 200)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_get_user_slices_for_owners(self):
         self.login(username="alpha")
         user = security_manager.find_user("alpha")
@@ -577,7 +582,9 @@ class TestCore(SupersetTestCase):
         database.allow_run_async = False
         db.session.commit()
 
-    @pytest.mark.usefixtures("load_energy_table_with_slice")
+    @pytest.mark.usefixtures(
+        "load_energy_table_with_slice", "load_birth_names_dashboard_with_slices"
+    )
     def test_warm_up_cache(self):
         self.login()
         slc = self.get_slice("Girls", db.session)
@@ -602,6 +609,7 @@ class TestCore(SupersetTestCase):
             + quote(json.dumps([{"col": "name", "op": "in", "val": ["Jennifer"]}]))
         ) == [{"slice_id": slc.id, "viz_error": None, "viz_status": "success"}]
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_cache_logging(self):
         store_cache_keys = app.config["STORE_CACHE_KEYS_IN_METADATA_DB"]
         app.config["STORE_CACHE_KEYS_IN_METADATA_DB"] = True
@@ -649,12 +657,21 @@ class TestCore(SupersetTestCase):
         assert "Charts" in self.get_resp("/chart/list/")
         assert "Dashboards" in self.get_resp("/dashboard/list/")
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_csv_endpoint(self):
         self.login()
-        sql = """
+        client_id = "{}".format(random.getrandbits(64))[:10]
+        get_name_sql = """
+                    SELECT name
+                    FROM birth_names
+                    LIMIT 1
+                """
+        resp = self.run_sql(get_name_sql, client_id, raise_on_error=True)
+        name = resp["data"][0]["name"]
+        sql = f"""
             SELECT name
             FROM birth_names
-            WHERE name = 'James'
+            WHERE name = '{name}'
             LIMIT 1
         """
         client_id = "{}".format(random.getrandbits(64))[:10]
@@ -662,18 +679,19 @@ class TestCore(SupersetTestCase):
 
         resp = self.get_resp("/superset/csv/{}".format(client_id))
         data = csv.reader(io.StringIO(resp))
-        expected_data = csv.reader(io.StringIO("name\nJames\n"))
+        expected_data = csv.reader(io.StringIO(f"name\n{name}\n"))
 
         client_id = "{}".format(random.getrandbits(64))[:10]
         self.run_sql(sql, client_id, raise_on_error=True)
 
         resp = self.get_resp("/superset/csv/{}".format(client_id))
         data = csv.reader(io.StringIO(resp))
-        expected_data = csv.reader(io.StringIO("name\nJames\n"))
+        expected_data = csv.reader(io.StringIO(f"name\n{name}\n"))
 
         self.assertEqual(list(expected_data), list(data))
         self.logout()
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_extra_table_metadata(self):
         self.login()
         example_db = utils.get_example_database()
@@ -730,6 +748,7 @@ class TestCore(SupersetTestCase):
         for k in keys:
             self.assertIn(k, resp.keys())
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_user_profile(self, username="admin"):
         self.login(username=username)
         slc = self.get_slice("Girls", db.session)
@@ -762,6 +781,7 @@ class TestCore(SupersetTestCase):
         data = self.get_json_resp(f"/superset/fave_dashboards_by_username/{username}/")
         self.assertNotIn("message", data)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_slice_id_is_always_logged_correctly_on_web_request(self):
         # superset/explore case
         slc = db.session.query(Slice).filter_by(slice_name="Girls").one()
@@ -845,6 +865,7 @@ class TestCore(SupersetTestCase):
             "The datasource associated with this chart no longer exists",
         )
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_explore_json(self):
         tbl_id = self.table_ids.get("birth_names")
         form_data = {
@@ -867,6 +888,7 @@ class TestCore(SupersetTestCase):
         self.assertEqual(rv.status_code, 200)
         self.assertEqual(data["rowcount"], 2)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     @mock.patch.dict(
         "superset.extensions.feature_flag_manager._feature_flags",
         GLOBAL_ASYNC_QUERIES=True,
@@ -897,6 +919,7 @@ class TestCore(SupersetTestCase):
             keys, ["channel_id", "job_id", "user_id", "status", "errors", "result_url"]
         )
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     @mock.patch.dict(
         "superset.extensions.feature_flag_manager._feature_flags",
         GLOBAL_ASYNC_QUERIES=True,
@@ -922,6 +945,7 @@ class TestCore(SupersetTestCase):
         )
         self.assertEqual(rv.status_code, 200)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     @mock.patch(
         "superset.utils.cache_manager.CacheManager.cache",
         new_callable=mock.PropertyMock,
@@ -1029,6 +1053,7 @@ class TestCore(SupersetTestCase):
         assert data == ["this_schema_is_allowed_too"]
         self.delete_fake_db()
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_select_star(self):
         self.login(username="admin")
         examples_db = utils.get_example_database()
diff --git a/tests/dashboard_tests.py b/tests/dashboard_tests.py
index 5874de8..8d4df16 100644
--- a/tests/dashboard_tests.py
+++ b/tests/dashboard_tests.py
@@ -20,6 +20,7 @@ from datetime import datetime
 import json
 import unittest
 from random import random
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 
 import pytest
 from flask import escape, url_for
@@ -129,6 +130,7 @@ class TestDashboard(SupersetTestCase):
         dash_count_after = db.session.query(func.count(Dashboard.id)).first()[0]
         self.assertEqual(dash_count_before + 1, dash_count_after)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_dashboard_modes(self):
         self.login(username="admin")
         dash = db.session.query(Dashboard).filter_by(slug="births").first()
@@ -142,6 +144,7 @@ class TestDashboard(SupersetTestCase):
         self.assertIn("standalone_mode&#34;: true", resp)
         self.assertIn('<body class="standalone">', resp)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_save_dash(self, username="admin"):
         self.login(username=username)
         dash = db.session.query(Dashboard).filter_by(slug="births").first()
@@ -213,6 +216,7 @@ class TestDashboard(SupersetTestCase):
         new_url = updatedDash.url
         self.assertNotIn("region", new_url)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_save_dash_with_dashboard_title(self, username="admin"):
         self.login(username=username)
         dash = db.session.query(Dashboard).filter_by(slug="births").first()
@@ -234,6 +238,7 @@ class TestDashboard(SupersetTestCase):
         data["dashboard_title"] = origin_title
         self.get_resp(url, data=dict(data=json.dumps(data)))
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_save_dash_with_colors(self, username="admin"):
         self.login(username=username)
         dash = db.session.query(Dashboard).filter_by(slug="births").first()
@@ -263,7 +268,9 @@ class TestDashboard(SupersetTestCase):
         self.get_resp(url, data=dict(data=json.dumps(data)))
 
     @pytest.mark.usefixtures(
-        "cleanup_copied_dash", "load_unicode_dashboard_with_position"
+        "load_birth_names_dashboard_with_slices",
+        "cleanup_copied_dash",
+        "load_unicode_dashboard_with_position",
     )
     def test_copy_dash(self, username="admin"):
         self.login(username=username)
@@ -303,7 +310,9 @@ class TestDashboard(SupersetTestCase):
                 if key not in ["modified", "changed_on", "changed_on_humanized"]:
                     self.assertEqual(slc[key], resp["slices"][index][key])
 
-    @pytest.mark.usefixtures("load_energy_table_with_slice")
+    @pytest.mark.usefixtures(
+        "load_energy_table_with_slice", "load_birth_names_dashboard_with_slices"
+    )
     def test_add_slices(self, username="admin"):
         self.login(username=username)
         dash = db.session.query(Dashboard).filter_by(slug="births").first()
@@ -332,6 +341,7 @@ class TestDashboard(SupersetTestCase):
         dash.slices = [o for o in dash.slices if o.slice_name != "Energy Force Layout"]
         db.session.commit()
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_remove_slices(self, username="admin"):
         self.login(username=username)
         dash = db.session.query(Dashboard).filter_by(slug="births").first()
@@ -364,6 +374,7 @@ class TestDashboard(SupersetTestCase):
         data = dash.data
         self.assertEqual(len(data["slices"]), origin_slices_length - 1)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_public_user_dashboard_access(self):
         table = db.session.query(SqlaTable).filter_by(table_name="birth_names").one()
 
@@ -404,6 +415,7 @@ class TestDashboard(SupersetTestCase):
         # Cleanup
         self.revoke_public_access_to_table(table)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_dashboard_with_created_by_can_be_accessed_by_public_users(self):
         self.logout()
         table = db.session.query(SqlaTable).filter_by(table_name="birth_names").one()
@@ -419,6 +431,7 @@ class TestDashboard(SupersetTestCase):
         # Cleanup
         self.revoke_public_access_to_table(table)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_only_owners_can_save(self):
         dash = db.session.query(Dashboard).filter_by(slug="births").first()
         dash.owners = []
diff --git a/tests/dashboards/api_tests.py b/tests/dashboards/api_tests.py
index cd91bad..299dd2d 100644
--- a/tests/dashboards/api_tests.py
+++ b/tests/dashboards/api_tests.py
@@ -22,6 +22,7 @@ from io import BytesIO
 from typing import List, Optional
 from unittest.mock import patch
 from zipfile import is_zipfile, ZipFile
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 
 import pytest
 import prison
@@ -29,7 +30,7 @@ import yaml
 from sqlalchemy.sql import func
 
 from freezegun import freeze_time
-from sqlalchemy import and_
+from sqlalchemy import and_, or_
 from superset import db, security_manager
 from superset.models.dashboard import Dashboard
 from superset.models.core import FavStar, FavStarClassName
@@ -47,7 +48,7 @@ from tests.fixtures.importexport import (
     dataset_config,
     dataset_metadata_config,
 )
-
+from tests.utils.get_dashboards import get_dashboards_ids
 
 DASHBOARDS_FIXTURE_COUNT = 10
 
@@ -654,6 +655,7 @@ class TestDashboardApi(SupersetTestCase, ApiOwnersTestCaseMixin):
             model = db.session.query(Dashboard).get(dashboard_id)
             self.assertEqual(model, None)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_delete_dashboard_not_owned(self):
         """
         Dashboard API: Test delete try not owned
@@ -679,6 +681,7 @@ class TestDashboardApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         db.session.delete(user_alpha2)
         db.session.commit()
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_delete_bulk_dashboard_not_owned(self):
         """
         Dashboard API: Test delete bulk try not owned
@@ -906,6 +909,7 @@ class TestDashboardApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         db.session.delete(model)
         db.session.commit()
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_update_dashboard_chart_owners(self):
         """
         Dashboard API: Test update chart owners
@@ -1071,6 +1075,7 @@ class TestDashboardApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         db.session.delete(model)
         db.session.commit()
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_update_dashboard_not_owned(self):
         """
         Dashboard API: Test update dashboard not owned
@@ -1147,8 +1152,8 @@ class TestDashboardApi(SupersetTestCase, ApiOwnersTestCaseMixin):
         """
         Dashboard API: Test dashboard export
         """
-        argument = [1, 2]
-        uri = f"api/v1/dashboard/export/?q={prison.dumps(argument)}"
+        dashboards_ids = get_dashboards_ids(db, ["world_health", "births"])
+        uri = f"api/v1/dashboard/export/?q={prison.dumps(dashboards_ids)}"
 
         self.login(username="admin")
         rv = self.client.get(uri)
diff --git a/tests/databases/api_tests.py b/tests/databases/api_tests.py
index a49ce3e..46af4f0 100644
--- a/tests/databases/api_tests.py
+++ b/tests/databases/api_tests.py
@@ -21,6 +21,7 @@ import json
 from io import BytesIO
 from unittest import mock
 from zipfile import is_zipfile, ZipFile
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 
 import prison
 import pytest
@@ -559,6 +560,7 @@ class TestDatabaseApi(SupersetTestCase):
         }
         self.assertEqual(response, expected_response)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_get_table_metadata(self):
         """
         Database API: Test get table metadata info
@@ -622,6 +624,7 @@ class TestDatabaseApi(SupersetTestCase):
         rv = self.client.get(uri)
         self.assertEqual(rv.status_code, 404)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_get_select_star(self):
         """
         Database API: Test get select star
@@ -843,7 +846,9 @@ class TestDatabaseApi(SupersetTestCase):
         app.config["PREVENT_UNSAFE_DB_CONNECTIONS"] = False
 
     @pytest.mark.usefixtures(
-        "load_unicode_dashboard_with_position", "load_energy_table_with_slice"
+        "load_unicode_dashboard_with_position",
+        "load_energy_table_with_slice",
+        "load_birth_names_dashboard_with_slices",
     )
     def test_get_database_related_objects(self):
         """
diff --git a/tests/databases/commands_tests.py b/tests/databases/commands_tests.py
index 70fcd7c..3b1767f 100644
--- a/tests/databases/commands_tests.py
+++ b/tests/databases/commands_tests.py
@@ -15,7 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 # pylint: disable=no-self-use, invalid-name
-
 from unittest.mock import patch
 
 import pytest
@@ -31,6 +30,8 @@ from superset.databases.commands.importers.v1 import ImportDatabasesCommand
 from superset.models.core import Database
 from superset.utils.core import backend, get_example_database
 from tests.base_tests import SupersetTestCase
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
+from tests.fixtures.energy_dashboard import load_energy_table_with_slice
 from tests.fixtures.importexport import (
     database_config,
     database_metadata_config,
@@ -41,10 +42,15 @@ from tests.fixtures.importexport import (
 
 class TestExportDatabasesCommand(SupersetTestCase):
     @patch("superset.security.manager.g")
+    @pytest.mark.usefixtures(
+        "load_birth_names_dashboard_with_slices", "load_energy_table_with_slice"
+    )
     def test_export_database_command(self, mock_g):
         mock_g.user = security_manager.find_user("admin")
 
         example_db = get_example_database()
+        db_uuid = example_db.uuid
+
         command = ExportDatabasesCommand([example_db.id])
         contents = dict(command.run())
 
@@ -68,6 +74,18 @@ class TestExportDatabasesCommand(SupersetTestCase):
 
         assert core_files.issubset(set(contents.keys()))
 
+        if example_db.backend == "postgresql":
+            ds_type = "TIMESTAMP WITHOUT TIME ZONE"
+        elif example_db.backend == "hive":
+            ds_type = "TIMESTAMP"
+        elif example_db.backend == "presto":
+            ds_type = "VARCHAR(255)"
+        else:
+            ds_type = "DATETIME"
+        if example_db.backend == "mysql":
+            big_int_type = "BIGINT(20)"
+        else:
+            big_int_type = "BIGINT"
         metadata = yaml.safe_load(contents["databases/examples.yaml"])
         assert metadata == (
             {
@@ -87,153 +105,149 @@ class TestExportDatabasesCommand(SupersetTestCase):
 
         metadata = yaml.safe_load(contents["datasets/examples/birth_names.yaml"])
         metadata.pop("uuid")
-        assert metadata == {
-            "table_name": "birth_names",
-            "main_dttm_col": None,
-            "description": "Adding a DESCRip",
-            "default_endpoint": "",
-            "offset": 66,
-            "cache_timeout": 55,
-            "schema": "",
-            "sql": "",
-            "params": None,
-            "template_params": None,
-            "filter_select_enabled": True,
-            "fetch_values_predicate": None,
-            "extra": None,
-            "metrics": [
-                {
-                    "metric_name": "ratio",
-                    "verbose_name": "Ratio Boys/Girls",
-                    "metric_type": None,
-                    "expression": "sum(num_boys) / sum(num_girls)",
-                    "description": "This represents the ratio of boys/girls",
-                    "d3format": ".2%",
-                    "extra": None,
-                    "warning_text": "no warning",
-                },
-                {
-                    "metric_name": "sum__num",
-                    "verbose_name": "Babies",
-                    "metric_type": None,
-                    "expression": "SUM(num)",
-                    "description": "",
-                    "d3format": "",
-                    "extra": None,
-                    "warning_text": "",
-                },
+
+        metadata["columns"].sort(key=lambda x: x["column_name"])
+        expected_metadata = {
+            "cache_timeout": None,
+            "columns": [
                 {
-                    "metric_name": "count",
-                    "verbose_name": "",
-                    "metric_type": None,
-                    "expression": "count(1)",
+                    "column_name": "ds",
                     "description": None,
-                    "d3format": None,
-                    "extra": None,
-                    "warning_text": None,
+                    "expression": None,
+                    "filterable": True,
+                    "groupby": True,
+                    "is_active": True,
+                    "is_dttm": True,
+                    "python_date_format": None,
+                    "type": ds_type,
+                    "verbose_name": None,
                 },
-            ],
-            "columns": [
                 {
-                    "column_name": "num_california",
-                    "verbose_name": None,
-                    "is_dttm": False,
-                    "is_active": None,
-                    "type": "NUMBER",
-                    "groupby": False,
-                    "filterable": False,
-                    "expression": "CASE WHEN state = 'CA' THEN num ELSE 0 END",
+                    "column_name": "gender",
                     "description": None,
+                    "expression": None,
+                    "filterable": True,
+                    "groupby": True,
+                    "is_active": True,
+                    "is_dttm": False,
                     "python_date_format": None,
+                    "type": "STRING" if example_db.backend == "hive" else "VARCHAR(16)",
+                    "verbose_name": None,
                 },
                 {
-                    "column_name": "ds",
-                    "verbose_name": "",
-                    "is_dttm": True,
-                    "is_active": None,
-                    "type": "DATETIME",
-                    "groupby": True,
-                    "filterable": True,
-                    "expression": "",
+                    "column_name": "name",
                     "description": None,
+                    "expression": None,
+                    "filterable": True,
+                    "groupby": True,
+                    "is_active": True,
+                    "is_dttm": False,
                     "python_date_format": None,
+                    "type": "STRING"
+                    if example_db.backend == "hive"
+                    else "VARCHAR(255)",
+                    "verbose_name": None,
                 },
                 {
-                    "column_name": "num_girls",
-                    "verbose_name": None,
-                    "is_dttm": False,
-                    "is_active": None,
-                    "type": "BIGINT(20)",
-                    "groupby": False,
-                    "filterable": False,
-                    "expression": "",
+                    "column_name": "num",
                     "description": None,
+                    "expression": None,
+                    "filterable": True,
+                    "groupby": True,
+                    "is_active": True,
+                    "is_dttm": False,
                     "python_date_format": None,
+                    "type": big_int_type,
+                    "verbose_name": None,
                 },
                 {
-                    "column_name": "gender",
-                    "verbose_name": None,
-                    "is_dttm": False,
-                    "is_active": None,
-                    "type": "VARCHAR(16)",
-                    "groupby": True,
-                    "filterable": True,
-                    "expression": "",
+                    "column_name": "num_california",
                     "description": None,
+                    "expression": "CASE WHEN state = 'CA' THEN num ELSE 0 END",
+                    "filterable": True,
+                    "groupby": True,
+                    "is_active": True,
+                    "is_dttm": False,
                     "python_date_format": None,
+                    "type": None,
+                    "verbose_name": None,
                 },
                 {
                     "column_name": "state",
-                    "verbose_name": None,
-                    "is_dttm": None,
-                    "is_active": None,
-                    "type": "VARCHAR(10)",
-                    "groupby": True,
-                    "filterable": True,
-                    "expression": None,
                     "description": None,
+                    "expression": None,
+                    "filterable": True,
+                    "groupby": True,
+                    "is_active": True,
+                    "is_dttm": False,
                     "python_date_format": None,
+                    "type": "STRING" if example_db.backend == "hive" else "VARCHAR(10)",
+                    "verbose_name": None,
                 },
                 {
                     "column_name": "num_boys",
-                    "verbose_name": None,
-                    "is_dttm": None,
-                    "is_active": None,
-                    "type": "BIGINT(20)",
-                    "groupby": True,
-                    "filterable": True,
-                    "expression": None,
                     "description": None,
+                    "expression": None,
+                    "filterable": True,
+                    "groupby": True,
+                    "is_active": True,
+                    "is_dttm": False,
                     "python_date_format": None,
+                    "type": big_int_type,
+                    "verbose_name": None,
                 },
                 {
-                    "column_name": "num",
-                    "verbose_name": None,
-                    "is_dttm": None,
-                    "is_active": None,
-                    "type": "BIGINT(20)",
-                    "groupby": True,
-                    "filterable": True,
-                    "expression": None,
+                    "column_name": "num_girls",
                     "description": None,
+                    "expression": None,
+                    "filterable": True,
+                    "groupby": True,
+                    "is_active": True,
+                    "is_dttm": False,
                     "python_date_format": None,
+                    "type": big_int_type,
+                    "verbose_name": None,
                 },
+            ],
+            "database_uuid": str(db_uuid),
+            "default_endpoint": None,
+            "description": "",
+            "extra": None,
+            "fetch_values_predicate": None,
+            "filter_select_enabled": True,
+            "main_dttm_col": "ds",
+            "metrics": [
                 {
-                    "column_name": "name",
-                    "verbose_name": None,
-                    "is_dttm": None,
-                    "is_active": None,
-                    "type": "VARCHAR(255)",
-                    "groupby": True,
-                    "filterable": True,
-                    "expression": None,
+                    "d3format": None,
                     "description": None,
-                    "python_date_format": None,
+                    "expression": "COUNT(*)",
+                    "extra": None,
+                    "metric_name": "count",
+                    "metric_type": "count",
+                    "verbose_name": "COUNT(*)",
+                    "warning_text": None,
+                },
+                {
+                    "d3format": None,
+                    "description": None,
+                    "expression": "SUM(num)",
+                    "extra": None,
+                    "metric_name": "sum__num",
+                    "metric_type": None,
+                    "verbose_name": None,
+                    "warning_text": None,
                 },
             ],
+            "offset": 0,
+            "params": None,
+            "schema": None,
+            "sql": None,
+            "table_name": "birth_names",
+            "template_params": None,
             "version": "1.0.0",
-            "database_uuid": str(example_db.uuid),
         }
+        expected_metadata["columns"].sort(key=lambda x: x["column_name"])
+        assert metadata == expected_metadata
 
     @patch("superset.security.manager.g")
     def test_export_database_command_no_access(self, mock_g):
diff --git a/tests/datasets/api_tests.py b/tests/datasets/api_tests.py
index ee0c224..ba1e999 100644
--- a/tests/datasets/api_tests.py
+++ b/tests/datasets/api_tests.py
@@ -40,6 +40,7 @@ from superset.utils.core import backend, get_example_database, get_main_database
 from superset.utils.dict_import_export import export_to_dict
 from tests.base_tests import SupersetTestCase
 from tests.conftest import CTAS_SCHEMA_NAME
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 from tests.fixtures.energy_dashboard import load_energy_table_with_slice
 from tests.fixtures.importexport import (
     database_config,
@@ -272,13 +273,12 @@ class TestDatasetApi(SupersetTestCase):
                 )
             )
             schema_values = [
-                "",
                 "admin_database",
                 "information_schema",
                 "public",
             ]
             expected_response = {
-                "count": 4,
+                "count": 3,
                 "result": [{"text": val, "value": val} for val in schema_values],
             }
             self.login(username="admin")
@@ -302,14 +302,9 @@ class TestDatasetApi(SupersetTestCase):
 
             query_parameter = {"page": 0, "page_size": 1}
             pg_test_query_parameter(
-                query_parameter, {"count": 4, "result": [{"text": "", "value": ""}]},
-            )
-
-            query_parameter = {"page": 1, "page_size": 1}
-            pg_test_query_parameter(
                 query_parameter,
                 {
-                    "count": 4,
+                    "count": 3,
                     "result": [{"text": "admin_database", "value": "admin_database"}],
                 },
             )
@@ -1182,6 +1177,7 @@ class TestDatasetApi(SupersetTestCase):
         # gamma users by default do not have access to this dataset
         assert rv.status_code == 404
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_get_dataset_related_objects(self):
         """
         Dataset API: Test get chart and dashboard count related to a dataset
diff --git a/tests/datasets/commands_tests.py b/tests/datasets/commands_tests.py
index 78ed44a..01bc91c 100644
--- a/tests/datasets/commands_tests.py
+++ b/tests/datasets/commands_tests.py
@@ -234,7 +234,8 @@ class TestImportDatasetsCommand(SupersetTestCase):
         assert len(dataset.metrics) == 2
         assert dataset.main_dttm_col == "ds"
         assert dataset.filter_select_enabled
-        assert [col.column_name for col in dataset.columns] == [
+        dataset.columns.sort(key=lambda obj: obj.column_name)
+        expected_columns = [
             "num_california",
             "ds",
             "state",
@@ -244,6 +245,8 @@ class TestImportDatasetsCommand(SupersetTestCase):
             "num_girls",
             "num",
         ]
+        expected_columns.sort()
+        assert [col.column_name for col in dataset.columns] == expected_columns
 
         db.session.delete(dataset)
         db.session.commit()
diff --git a/tests/datasource_tests.py b/tests/datasource_tests.py
index 14ad01d..290e135 100644
--- a/tests/datasource_tests.py
+++ b/tests/datasource_tests.py
@@ -18,15 +18,30 @@
 import json
 from copy import deepcopy
 
-from superset import app, db
+import pytest
+
+from superset import app, ConnectorRegistry, db
 from superset.connectors.sqla.models import SqlaTable
 from superset.utils.core import get_example_database
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 
 from .base_tests import SupersetTestCase
 from .fixtures.datasource import datasource_post
 
 
 class TestDatasource(SupersetTestCase):
+    def setUp(self):
+        self.original_attrs = {}
+        self.datasource = None
+
+    def tearDown(self):
+        if self.datasource:
+            for key, value in self.original_attrs.items():
+                setattr(self.datasource, key, value)
+
+            db.session.commit()
+
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_external_metadata_for_physical_table(self):
         self.login(username="admin")
         tbl = self.get_table_by_name("birth_names")
@@ -105,6 +120,12 @@ class TestDatasource(SupersetTestCase):
     def test_save(self):
         self.login(username="admin")
         tbl_id = self.get_table_by_name("birth_names").id
+
+        self.datasource = ConnectorRegistry.get_datasource("table", tbl_id, db.session)
+
+        for key in self.datasource.export_fields:
+            self.original_attrs[key] = getattr(self.datasource, key)
+
         datasource_post["id"] = tbl_id
         data = dict(data=json.dumps(datasource_post))
         resp = self.get_json_resp("/datasource/save/", data)
@@ -130,6 +151,11 @@ class TestDatasource(SupersetTestCase):
         db_id = tbl.database_id
         datasource_post["id"] = tbl_id
 
+        self.datasource = ConnectorRegistry.get_datasource("table", tbl_id, db.session)
+
+        for key in self.datasource.export_fields:
+            self.original_attrs[key] = getattr(self.datasource, key)
+
         new_db = self.create_fake_db()
 
         datasource_post["database"]["id"] = new_db.id
@@ -145,6 +171,11 @@ class TestDatasource(SupersetTestCase):
     def test_save_duplicate_key(self):
         self.login(username="admin")
         tbl_id = self.get_table_by_name("birth_names").id
+        self.datasource = ConnectorRegistry.get_datasource("table", tbl_id, db.session)
+
+        for key in self.datasource.export_fields:
+            self.original_attrs[key] = getattr(self.datasource, key)
+
         datasource_post_copy = deepcopy(datasource_post)
         datasource_post_copy["id"] = tbl_id
         datasource_post_copy["columns"].extend(
@@ -172,6 +203,14 @@ class TestDatasource(SupersetTestCase):
     def test_get_datasource(self):
         self.login(username="admin")
         tbl = self.get_table_by_name("birth_names")
+        self.datasource = ConnectorRegistry.get_datasource("table", tbl.id, db.session)
+
+        for key in self.datasource.export_fields:
+            self.original_attrs[key] = getattr(self.datasource, key)
+
+        datasource_post["id"] = tbl.id
+        data = dict(data=json.dumps(datasource_post))
+        self.get_json_resp("/datasource/save/", data)
         url = f"/datasource/get/{tbl.type}/{tbl.id}/"
         resp = self.get_json_resp(url)
         self.assertEqual(resp.get("type"), "table")
@@ -199,6 +238,11 @@ class TestDatasource(SupersetTestCase):
 
         self.login(username="admin")
         tbl = self.get_table_by_name("birth_names")
+        self.datasource = ConnectorRegistry.get_datasource("table", tbl.id, db.session)
+
+        for key in self.datasource.export_fields:
+            self.original_attrs[key] = getattr(self.datasource, key)
+
         url = f"/datasource/get/{tbl.type}/{tbl.id}/"
         tbl.health_check(commit=True, force=True)
         resp = self.get_json_resp(url)
diff --git a/tests/fixtures/birth_names_dashboard.py b/tests/fixtures/birth_names_dashboard.py
new file mode 100644
index 0000000..d07bbf4
--- /dev/null
+++ b/tests/fixtures/birth_names_dashboard.py
@@ -0,0 +1,202 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+import json
+import string
+from datetime import date, datetime
+from random import choice, getrandbits, randint, random, uniform
+from typing import Any, Dict, List
+
+import pandas as pd
+import pytest
+from pandas import DataFrame
+from sqlalchemy import DateTime, String, TIMESTAMP
+
+from superset import ConnectorRegistry, db
+from superset.connectors.sqla.models import SqlaTable
+from superset.models.core import Database
+from superset.models.dashboard import Dashboard
+from superset.models.slice import Slice
+from superset.utils.core import get_example_database
+from tests.dashboard_utils import create_dashboard, create_table_for_dashboard
+from tests.test_app import app
+
+
+@pytest.fixture()
+def load_birth_names_dashboard_with_slices():
+    dash_id_to_delete, slices_ids_to_delete = _load_data()
+    yield
+    with app.app_context():
+        _cleanup(dash_id_to_delete, slices_ids_to_delete)
+
+
+@pytest.fixture(scope="module")
+def load_birth_names_dashboard_with_slices_module_scope():
+    dash_id_to_delete, slices_ids_to_delete = _load_data()
+    yield
+    with app.app_context():
+        _cleanup(dash_id_to_delete, slices_ids_to_delete)
+
+
+def _load_data():
+    table_name = "birth_names"
+
+    with app.app_context():
+        database = get_example_database()
+        df = _get_dataframe(database)
+        dtype = {
+            "ds": DateTime if database.backend != "presto" else String(255),
+            "gender": String(16),
+            "state": String(10),
+            "name": String(255),
+        }
+        table = _create_table(df, table_name, database, dtype)
+
+        from superset.examples.birth_names import create_slices, create_dashboard
+
+        slices, _ = create_slices(table, admin_owner=False)
+        dash = create_dashboard(slices)
+        slices_ids_to_delete = [slice.id for slice in slices]
+        dash_id_to_delete = dash.id
+        return dash_id_to_delete, slices_ids_to_delete
+
+
+def _create_table(
+    df: DataFrame, table_name: str, database: "Database", dtype: Dict[str, Any]
+):
+    table = create_table_for_dashboard(df, table_name, database, dtype)
+    from superset.examples.birth_names import _add_table_metrics, _set_table_metadata
+
+    _set_table_metadata(table, database)
+    _add_table_metrics(table)
+    db.session.commit()
+    return table
+
+
+def _cleanup(dash_id: int, slices_ids: List[int]) -> None:
+    table_id = db.session.query(SqlaTable).filter_by(table_name="birth_names").one().id
+    datasource = ConnectorRegistry.get_datasource("table", table_id, db.session)
+    columns = [column for column in datasource.columns]
+    metrics = [metric for metric in datasource.metrics]
+
+    engine = get_example_database().get_sqla_engine()
+    engine.execute("DROP TABLE IF EXISTS birth_names")
+    for column in columns:
+        db.session.delete(column)
+    for metric in metrics:
+        db.session.delete(metric)
+
+    dash = db.session.query(Dashboard).filter_by(id=dash_id).first()
+
+    db.session.delete(dash)
+    for slice_id in slices_ids:
+        db.session.query(Slice).filter_by(id=slice_id).delete()
+    db.session.commit()
+
+
+def _get_dataframe(database: Database) -> DataFrame:
+    data = _get_birth_names_data()
+    df = pd.DataFrame.from_dict(data)
+    if database.backend == "presto":
+        df.ds = df.ds.dt.strftime("%Y-%m-%d %H:%M%:%S")
+    return df
+
+
+def _get_birth_names_data() -> List[Dict[Any, Any]]:
+    data = []
+    names = generate_names()
+    for year in range(1960, 2020):
+        ds = datetime(year, 1, 1, 0, 0, 0)
+        for _ in range(20):
+            gender = "boy" if choice([True, False]) else "girl"
+            num = randint(1, 100000)
+            data.append(
+                {
+                    "ds": ds,
+                    "gender": gender,
+                    "name": choice(names),
+                    "num": num,
+                    "state": choice(us_states),
+                    "num_boys": num if gender == "boy" else 0,
+                    "num_girls": num if gender == "girl" else 0,
+                }
+            )
+
+    return data
+
+
+def generate_names() -> List[str]:
+    names = []
+    for _ in range(250):
+        names.append(
+            "".join(choice(string.ascii_lowercase) for _ in range(randint(3, 12)))
+        )
+    return names
+
+
+us_states = [
+    "AL",
+    "AK",
+    "AZ",
+    "AR",
+    "CA",
+    "CO",
+    "CT",
+    "DE",
+    "FL",
+    "GA",
+    "HI",
+    "ID",
+    "IL",
+    "IN",
+    "IA",
+    "KS",
+    "KY",
+    "LA",
+    "ME",
+    "MD",
+    "MA",
+    "MI",
+    "MN",
+    "MS",
+    "MO",
+    "MT",
+    "NE",
+    "NV",
+    "NH",
+    "NJ",
+    "NM",
+    "NY",
+    "NC",
+    "ND",
+    "OH",
+    "OK",
+    "OR",
+    "PA",
+    "RI",
+    "SC",
+    "SD",
+    "TN",
+    "TX",
+    "UT",
+    "VT",
+    "VA",
+    "WA",
+    "WV",
+    "WI",
+    "WY",
+    "other",
+]
diff --git a/tests/import_export_tests.py b/tests/import_export_tests.py
index b0ef243..2dc29f0 100644
--- a/tests/import_export_tests.py
+++ b/tests/import_export_tests.py
@@ -18,6 +18,7 @@
 """Unit tests for Superset"""
 import json
 import unittest
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 
 import pytest
 from flask import g
@@ -240,6 +241,7 @@ class TestImportExport(SupersetTestCase):
             self.assertEqual(e_slc.datasource.schema, params["schema"])
             self.assertEqual(e_slc.datasource.database.name, params["database_name"])
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_export_1_dashboard(self):
         self.login("admin")
         birth_dash = self.get_dash_by_slug("births")
@@ -268,6 +270,7 @@ class TestImportExport(SupersetTestCase):
             self.get_table_by_name("birth_names"), exported_tables[0]
         )
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_export_2_dashboards(self):
         self.login("admin")
         birth_dash = self.get_dash_by_slug("births")
diff --git a/tests/model_tests.py b/tests/model_tests.py
index 45dfee9..e0eaf4a 100644
--- a/tests/model_tests.py
+++ b/tests/model_tests.py
@@ -17,6 +17,7 @@
 # isort:skip_file
 import textwrap
 import unittest
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 
 import pandas
 import pytest
@@ -214,6 +215,7 @@ class TestDatabaseModel(SupersetTestCase):
 
 
 class TestSqlaTableModel(SupersetTestCase):
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_get_timestamp_expression(self):
         tbl = self.get_table_by_name("birth_names")
         ds_col = tbl.get_column("ds")
@@ -233,6 +235,7 @@ class TestSqlaTableModel(SupersetTestCase):
             self.assertEqual(compiled, "DATE(DATE_ADD(ds, 1))")
         ds_col.expression = prev_ds_expr
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_get_timestamp_expression_epoch(self):
         tbl = self.get_table_by_name("birth_names")
         ds_col = tbl.get_column("ds")
@@ -297,6 +300,7 @@ class TestSqlaTableModel(SupersetTestCase):
         self.assertFalse(qr.df.empty)
         return qr.df
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_query_with_expr_groupby_timeseries(self):
         if get_example_database().backend == "presto":
             # TODO(bkyryliuk): make it work for presto.
@@ -313,29 +317,13 @@ class TestSqlaTableModel(SupersetTestCase):
         name_list2 = cannonicalize_df(df1).name.values.tolist()
         self.assertFalse(df2.empty)
 
-        expected_namelist = [
-            "Anthony",
-            "Brian",
-            "Christopher",
-            "Daniel",
-            "David",
-            "Eric",
-            "James",
-            "Jeffrey",
-            "John",
-            "Joseph",
-            "Kenneth",
-            "Kevin",
-            "Mark",
-            "Michael",
-            "Paul",
-        ]
-        assert name_list2 == expected_namelist
-        assert name_list1 == expected_namelist
+        assert name_list2 == name_list1
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_query_with_expr_groupby(self):
         self.query_with_expr_helper(is_timeseries=False)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_sql_mutator(self):
         tbl = self.get_table_by_name("birth_names")
         query_obj = dict(
@@ -381,14 +369,18 @@ class TestSqlaTableModel(SupersetTestCase):
 
         self.assertTrue("Metric 'invalid' does not exist", context.exception)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_data_for_slices(self):
         tbl = self.get_table_by_name("birth_names")
         slc = (
             metadata_db.session.query(Slice)
-            .filter_by(datasource_id=tbl.id, datasource_type=tbl.type)
+            .filter_by(
+                datasource_id=tbl.id,
+                datasource_type=tbl.type,
+                slice_name="Participants",
+            )
             .first()
         )
-
         data_for_slices = tbl.data_for_slices([slc])
         self.assertEqual(len(data_for_slices["columns"]), 0)
         self.assertEqual(len(data_for_slices["metrics"]), 1)
diff --git a/tests/query_context_tests.py b/tests/query_context_tests.py
index 43bdccd..2201900 100644
--- a/tests/query_context_tests.py
+++ b/tests/query_context_tests.py
@@ -14,6 +14,8 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
+import pytest
+
 from superset import db
 from superset.charts.schemas import ChartDataQueryContextSchema
 from superset.connectors.connector_registry import ConnectorRegistry
@@ -25,6 +27,7 @@ from superset.utils.core import (
     TimeRangeEndpoint,
 )
 from tests.base_tests import SupersetTestCase
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 from tests.fixtures.query_context import get_query_context
 
 
@@ -141,7 +144,7 @@ class TestQueryContext(SupersetTestCase):
         self.login(username="admin")
         adhoc_metric = {
             "expressionType": "SIMPLE",
-            "column": {"column_name": "sum_boys", "type": "BIGINT(20)"},
+            "column": {"column_name": "num_boys", "type": "BIGINT(20)"},
             "aggregate": "SUM",
             "label": "Boys",
             "optionName": "metric_11",
@@ -166,6 +169,7 @@ class TestQueryContext(SupersetTestCase):
         self.assertEqual(query_object.granularity, "timecol")
         self.assertIn("having_druid", query_object.extras)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_csv_response_format(self):
         """
         Ensure that CSV result format works
@@ -224,6 +228,7 @@ class TestQueryContext(SupersetTestCase):
         query_payload = query_context.get_payload()
         assert query_payload["queries"][0].get("error") is not None
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_samples_response_type(self):
         """
         Ensure that samples result type works
@@ -240,6 +245,7 @@ class TestQueryContext(SupersetTestCase):
         self.assertEqual(len(data), 5)
         self.assertNotIn("sum__num", data[0])
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_query_response_type(self):
         """
         Ensure that query result type works
diff --git a/tests/schedules_test.py b/tests/schedules_test.py
index b18007e..8ff7a52 100644
--- a/tests/schedules_test.py
+++ b/tests/schedules_test.py
@@ -41,6 +41,9 @@ from superset.tasks.schedules import (
 from superset.models.slice import Slice
 from tests.base_tests import SupersetTestCase
 from tests.utils import read_fixture
+from tests.fixtures.birth_names_dashboard import (
+    load_birth_names_dashboard_with_slices_module_scope,
+)
 
 
 class TestSchedules(SupersetTestCase):
@@ -138,6 +141,7 @@ class TestSchedules(SupersetTestCase):
             else:
                 self.assertEqual(len(schedules), 0)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices_module_scope")
     def test_complex_schedule(self):
         # Run the job on every Friday of March and May
         # On these days, run the job at
diff --git a/tests/security_tests.py b/tests/security_tests.py
index d866527..7ddc326 100644
--- a/tests/security_tests.py
+++ b/tests/security_tests.py
@@ -47,6 +47,7 @@ from .dashboard_utils import (
 )
 from .fixtures.energy_dashboard import load_energy_table_with_slice
 from .fixtures.unicode_dashboard import load_unicode_dashboard_with_slice
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 
 NEW_SECURITY_CONVERGE_VIEWS = (
     "Annotation",
@@ -1149,6 +1150,7 @@ class TestRowLevelSecurity(SupersetTestCase):
         assert tbl.get_extra_cache_keys(self.query_obj) == [1]
         assert "value > 1" in sql
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_rls_filter_alters_gamma_birth_names_query(self):
         g.user = self.get_user(username="gamma")
         tbl = self.get_table_by_name("birth_names")
@@ -1161,6 +1163,7 @@ class TestRowLevelSecurity(SupersetTestCase):
             in sql
         )
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_rls_filter_alters_no_role_user_birth_names_query(self):
         g.user = self.get_user(username="NoRlsRoleUser")
         tbl = self.get_table_by_name("birth_names")
@@ -1173,6 +1176,7 @@ class TestRowLevelSecurity(SupersetTestCase):
         # base query should be present
         assert self.BASE_FILTER_REGEX.search(sql)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_rls_filter_doesnt_alter_admin_birth_names_query(self):
         g.user = self.get_user(username="admin")
         tbl = self.get_table_by_name("birth_names")
diff --git a/tests/sqla_models_tests.py b/tests/sqla_models_tests.py
index f6bb4fc..95c9c16 100644
--- a/tests/sqla_models_tests.py
+++ b/tests/sqla_models_tests.py
@@ -27,6 +27,7 @@ from superset.db_engine_specs.druid import DruidEngineSpec
 from superset.exceptions import QueryObjectValidationError
 from superset.models.core import Database
 from superset.utils.core import DbColumnType, get_example_database, FilterOperator
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 
 from .base_tests import SupersetTestCase
 
@@ -165,6 +166,7 @@ class TestDatabaseModel(SupersetTestCase):
             db.session.delete(table)
         db.session.commit()
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_where_operators(self):
         class FilterTestCase(NamedTuple):
             operator: str
diff --git a/tests/sqllab_tests.py b/tests/sqllab_tests.py
index 8c2b10a..3959485 100644
--- a/tests/sqllab_tests.py
+++ b/tests/sqllab_tests.py
@@ -18,17 +18,19 @@
 """Unit tests for Sql Lab"""
 import json
 from datetime import datetime, timedelta
-from random import random
-from unittest import mock
 
+import pytest
 from parameterized import parameterized
+from random import random
+from unittest import mock
+from superset.extensions import db
 import prison
-import pytest
 
 from superset import db, security_manager
 from superset.connectors.sqla.models import SqlaTable
 from superset.db_engine_specs import BaseEngineSpec
 from superset.errors import ErrorLevel, SupersetErrorType
+from superset.models.core import Database
 from superset.models.sql_lab import Query, SavedQuery
 from superset.result_set import SupersetResultSet
 from superset.sql_lab import execute_sql_statements, SqlLabException
@@ -41,6 +43,7 @@ from superset.utils.core import (
 
 from .base_tests import SupersetTestCase
 from .conftest import CTAS_SCHEMA_NAME
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 
 QUERY_1 = "SELECT * FROM birth_names LIMIT 1"
 QUERY_2 = "SELECT * FROM NO_TABLE"
@@ -64,6 +67,7 @@ class TestSqlLab(SupersetTestCase):
         db.session.commit()
         db.session.close()
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_sql_json(self):
         self.login("admin")
 
@@ -84,6 +88,7 @@ class TestSqlLab(SupersetTestCase):
             ]
         }
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_sql_json_to_saved_query_info(self):
         """
         SQLLab: Test SQLLab query execution info propagation to saved queries
@@ -115,6 +120,7 @@ class TestSqlLab(SupersetTestCase):
             db.session.commit()
 
     @parameterized.expand([CtasMethod.TABLE, CtasMethod.VIEW])
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_sql_json_cta_dynamic_db(self, ctas_method):
         examples_db = get_example_database()
         if examples_db.backend == "sqlite":
@@ -146,8 +152,9 @@ class TestSqlLab(SupersetTestCase):
             data = engine.execute(
                 f"SELECT * FROM admin_database.{tmp_table_name}"
             ).fetchall()
+            names_count = engine.execute(f"SELECT COUNT(*) FROM birth_names").first()
             self.assertEqual(
-                100, len(data)
+                names_count[0], len(data)
             )  # SQL_MAX_ROW not applied due to the SQLLAB_CTAS_NO_LIMIT set to True
 
             # cleanup
@@ -155,6 +162,7 @@ class TestSqlLab(SupersetTestCase):
             examples_db.allow_ctas = old_allow_ctas
             db.session.commit()
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_multi_sql(self):
         self.login("admin")
 
@@ -165,12 +173,14 @@ class TestSqlLab(SupersetTestCase):
         data = self.run_sql(multi_sql, "2234")
         self.assertLess(0, len(data["data"]))
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_explain(self):
         self.login("admin")
 
         data = self.run_sql("EXPLAIN SELECT * FROM birth_names", "1")
         self.assertLess(0, len(data["data"]))
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_sql_json_has_access(self):
         examples_db = get_example_database()
         examples_db_permission_view = security_manager.add_permission_view_menu(
@@ -312,6 +322,7 @@ class TestSqlLab(SupersetTestCase):
         self.assertEqual(1, len(data))
         self.assertEqual(data[0]["userId"], user_id)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_search_query_on_status(self):
         self.run_some_queries()
         self.login("admin")
@@ -481,6 +492,7 @@ class TestSqlLab(SupersetTestCase):
         )
         db.session.commit()
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_sql_limit(self):
         self.login("admin")
         test_limit = 1
@@ -589,6 +601,7 @@ class TestSqlLab(SupersetTestCase):
         )
         self.delete_fake_db()
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     @mock.patch.dict(
         "superset.extensions.feature_flag_manager._feature_flags",
         {"ENABLE_TEMPLATE_PROCESSING": True},
diff --git a/tests/strategy_tests.py b/tests/strategy_tests.py
index 29f736c..bba560f 100644
--- a/tests/strategy_tests.py
+++ b/tests/strategy_tests.py
@@ -19,6 +19,7 @@
 import datetime
 import json
 from unittest.mock import MagicMock
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 
 from sqlalchemy import String, Date, Float
 
@@ -184,6 +185,7 @@ class TestCacheWarmUp(SupersetTestCase):
         }
         self.assertEqual(result, expected)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_top_n_dashboards_strategy(self):
         # create a top visited dashboard
         db.session.query(Log).delete()
@@ -204,7 +206,9 @@ class TestCacheWarmUp(SupersetTestCase):
                 db.session.delete(o)
             db.session.commit()
 
-    @pytest.mark.usefixtures("load_unicode_dashboard_with_slice")
+    @pytest.mark.usefixtures(
+        "load_unicode_dashboard_with_slice", "load_birth_names_dashboard_with_slices"
+    )
     def test_dashboard_tags(self):
         tag1 = get_tag("tag1", db.session, TagTypes.custom)
         # delete first to make test idempotent
diff --git a/tests/tasks/async_queries_tests.py b/tests/tasks/async_queries_tests.py
index f816e0b..e44a515 100644
--- a/tests/tasks/async_queries_tests.py
+++ b/tests/tasks/async_queries_tests.py
@@ -32,6 +32,7 @@ from superset.tasks.async_queries import (
     load_explore_json_into_cache,
 )
 from tests.base_tests import SupersetTestCase
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 from tests.fixtures.query_context import get_query_context
 from tests.test_app import app
 
@@ -42,6 +43,7 @@ def get_table_by_name(name: str) -> SqlaTable:
 
 
 class TestAsyncQueries(SupersetTestCase):
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     @mock.patch.object(async_query_manager, "update_job")
     def test_load_chart_data_into_cache(self, mock_update_job):
         async_query_manager.init_app(app)
@@ -79,6 +81,7 @@ class TestAsyncQueries(SupersetTestCase):
         errors = [{"message": "Error: foo"}]
         mock_update_job.assert_called_with(job_metadata, "error", errors=errors)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     @mock.patch.object(async_query_manager, "update_job")
     def test_load_explore_json_into_cache(self, mock_update_job):
         async_query_manager.init_app(app)
diff --git a/tests/utils/get_dashboards.py b/tests/utils/get_dashboards.py
new file mode 100644
index 0000000..03260fb
--- /dev/null
+++ b/tests/utils/get_dashboards.py
@@ -0,0 +1,28 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from typing import List
+
+from flask_appbuilder import SQLA
+
+from superset.models.dashboard import Dashboard
+
+
+def get_dashboards_ids(db: SQLA, dashboard_slugs: List[str]) -> List[int]:
+    result = (
+        db.session.query(Dashboard.id).filter(Dashboard.slug.in_(dashboard_slugs)).all()
+    )
+    return [row[0] for row in result]
diff --git a/tests/utils_tests.py b/tests/utils_tests.py
index b47f7d1..a16db4b 100644
--- a/tests/utils_tests.py
+++ b/tests/utils_tests.py
@@ -24,8 +24,10 @@ import json
 import os
 import re
 from unittest.mock import Mock, patch
+from tests.fixtures.birth_names_dashboard import load_birth_names_dashboard_with_slices
 
 import numpy
+import pytest
 from flask import Flask, g
 import marshmallow
 from sqlalchemy.exc import ArgumentError
@@ -990,6 +992,7 @@ class TestUtils(SupersetTestCase):
 
             self.assertEqual(slc, None)
 
+    @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices")
     def test_log_this(self) -> None:
         # TODO: Add additional scenarios.
         self.login(username="admin")


[superset] 04/38: fix: faster search for Change Dataset modal (#12669)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 2cdb92d05c9b8bbeb24bf48859cf05afdcd41aad
Author: Jesse Yang <je...@airbnb.com>
AuthorDate: Fri Jan 22 14:26:02 2021 -0800

    fix: faster search for Change Dataset modal (#12669)
---
 superset-frontend/src/datasource/ChangeDatasourceModal.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/superset-frontend/src/datasource/ChangeDatasourceModal.tsx b/superset-frontend/src/datasource/ChangeDatasourceModal.tsx
index 1ab8249..7831dba 100644
--- a/superset-frontend/src/datasource/ChangeDatasourceModal.tsx
+++ b/superset-frontend/src/datasource/ChangeDatasourceModal.tsx
@@ -133,7 +133,7 @@ const ChangeDatasourceModal: FunctionComponent<ChangeDatasourceModalProps> = ({
         }),
       });
     },
-    1000,
+    300,
     [filter],
   );
 


[superset] 30/38: fix: chart disappears in standalone slice (#12606)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit e2ce27fe46768ed9b92b553710fe13c6fcb955e8
Author: Duy Nguyen Hoang <nh...@gmail.com>
AuthorDate: Wed Jan 20 02:56:24 2021 +0700

    fix: chart disappears in standalone slice (#12606)
---
 superset-frontend/src/explore/components/ExploreChartPanel.jsx | 7 ++++++-
 superset/charts/api.py                                         | 2 +-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/superset-frontend/src/explore/components/ExploreChartPanel.jsx b/superset-frontend/src/explore/components/ExploreChartPanel.jsx
index bc7e5c7..8fed5b6 100644
--- a/superset-frontend/src/explore/components/ExploreChartPanel.jsx
+++ b/superset-frontend/src/explore/components/ExploreChartPanel.jsx
@@ -205,6 +205,11 @@ const ExploreChartPanel = props => {
     [chartRef, renderChart],
   );
 
+  const standaloneChartBody = useMemo(
+    () => <div ref={chartRef}>{renderChart()}</div>,
+    [chartRef, renderChart],
+  );
+
   if (props.standalone) {
     // dom manipulation hack to get rid of the boostrap theme's body background
     const standaloneClass = 'background-transparent';
@@ -212,7 +217,7 @@ const ExploreChartPanel = props => {
     if (!bodyClasses.includes(standaloneClass)) {
       document.body.className += ` ${standaloneClass}`;
     }
-    return renderChart();
+    return standaloneChartBody;
   }
 
   const header = (
diff --git a/superset/charts/api.py b/superset/charts/api.py
index cce76da..35cf44c 100644
--- a/superset/charts/api.py
+++ b/superset/charts/api.py
@@ -542,7 +542,7 @@ class ChartRestApi(BaseSupersetModelRestApi):
             try:
                 json_body = json.loads(request.form["form_data"])
             except (TypeError, json.JSONDecodeError):
-                json_body = None
+                pass
 
         if json_body is None:
             return self.response_400(message=_("Request is not JSON"))


[superset] 33/38: fix(explore): Certified metric icons are various sizes (#12690)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 7e9a042ed1689aa142190141b8ac0ca3dee295a6
Author: Geido <60...@users.noreply.github.com>
AuthorDate: Fri Jan 22 22:14:40 2021 +0100

    fix(explore): Certified metric icons are various sizes (#12690)
---
 superset-frontend/src/explore/components/DatasourcePanel.tsx | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/superset-frontend/src/explore/components/DatasourcePanel.tsx b/superset-frontend/src/explore/components/DatasourcePanel.tsx
index 95b9d3f..9d47626 100644
--- a/superset-frontend/src/explore/components/DatasourcePanel.tsx
+++ b/superset-frontend/src/explore/components/DatasourcePanel.tsx
@@ -153,9 +153,14 @@ const LabelContainer = styled.div`
     display: inline;
   }
 
-  .metric-option > .option-label {
-    overflow: hidden;
-    text-overflow: ellipsis;
+  .metric-option {
+    & > svg {
+      min-width: ${({ theme }) => `${theme.gridUnit * 4}px`};
+    }
+    & > .option-label {
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
   }
 `;
 


[superset] 38/38: chore[explore]: Save date if Ok not clicked (#12731)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit b07188e11db16649f73a5081fcda57eb2961b707
Author: Nikola Gigić <ni...@gmail.com>
AuthorDate: Mon Jan 25 12:48:45 2021 +0100

    chore[explore]: Save date if Ok not clicked (#12731)
    
    * Save date if Ok not clicked
    
    * answering. comments
---
 .../components/controls/DateFilterControl/frame/CustomFrame.tsx     | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/frame/CustomFrame.tsx b/superset-frontend/src/explore/components/controls/DateFilterControl/frame/CustomFrame.tsx
index 553aea9..3f15873 100644
--- a/superset-frontend/src/explore/components/controls/DateFilterControl/frame/CustomFrame.tsx
+++ b/superset-frontend/src/explore/components/controls/DateFilterControl/frame/CustomFrame.tsx
@@ -136,7 +136,7 @@ export function CustomFrame(props: FrameComponentProps) {
               <DatePicker
                 showTime
                 value={dttmToMoment(sinceDatetime)}
-                onChange={(datetime: Moment) =>
+                onSelect={(datetime: Moment) =>
                   onChange('sinceDatetime', datetime.format(MOMENT_FORMAT))
                 }
                 allowClear={false}
@@ -188,7 +188,7 @@ export function CustomFrame(props: FrameComponentProps) {
               <DatePicker
                 showTime
                 value={dttmToMoment(untilDatetime)}
-                onChange={(datetime: Moment) =>
+                onSelect={(datetime: Moment) =>
                   onChange('untilDatetime', datetime.format(MOMENT_FORMAT))
                 }
                 allowClear={false}
@@ -247,7 +247,7 @@ export function CustomFrame(props: FrameComponentProps) {
                 <DatePicker
                   showTime
                   value={dttmToMoment(anchorValue)}
-                  onChange={(datetime: Moment) =>
+                  onSelect={(datetime: Moment) =>
                     onChange('anchorValue', datetime.format(MOMENT_FORMAT))
                   }
                   allowClear={false}


[superset] 28/38: [12601] Hovered menu items on dashboard - brought back padding and added margin on top of chart (#12603)

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch 1.0
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 3d770aeeb945d1ce1aeed3e0109ff106c80d02f8
Author: Kasia Kucharczyk <25...@users.noreply.github.com>
AuthorDate: Thu Jan 21 10:32:34 2021 +0100

    [12601] Hovered menu items on dashboard - brought back padding and added margin on top of chart (#12603)
---
 superset-frontend/src/dashboard/components/DashboardBuilder.jsx | 2 +-
 superset-frontend/src/dashboard/stylesheets/hover-menu.less     | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/superset-frontend/src/dashboard/components/DashboardBuilder.jsx b/superset-frontend/src/dashboard/components/DashboardBuilder.jsx
index aad5c41..2c9ba0c 100644
--- a/superset-frontend/src/dashboard/components/DashboardBuilder.jsx
+++ b/superset-frontend/src/dashboard/components/DashboardBuilder.jsx
@@ -93,7 +93,7 @@ const StyledDashboardContent = styled.div`
     width: 100%;
     flex-grow: 1;
     position: relative;
-    margin: ${({ theme }) => theme.gridUnit * 2}px
+    margin: ${({ theme }) => theme.gridUnit * 6}px
       ${({ theme }) => theme.gridUnit * 8}px
       ${({ theme }) => theme.gridUnit * 6}px
       ${({ theme, dashboardFiltersOpen }) => {
diff --git a/superset-frontend/src/dashboard/stylesheets/hover-menu.less b/superset-frontend/src/dashboard/stylesheets/hover-menu.less
index 8953ce0..41ce575 100644
--- a/superset-frontend/src/dashboard/stylesheets/hover-menu.less
+++ b/superset-frontend/src/dashboard/stylesheets/hover-menu.less
@@ -28,6 +28,7 @@
   top: 50%;
   transform: translate(0, -50%);
   left: -28px;
+  padding: 8px 0;
   display: flex;
   flex-direction: column;
   justify-content: center;