This is an automated email from the ASF dual-hosted git repository. diegopucci pushed a commit to branch elizabeth/accessibility-tabs in repository https://gitbox.apache.org/repos/asf/superset.git
commit 59bf495a9d5bb58e7c22329c3279704ca4af565e Merge: 1c8462acfe 4428bde024 Author: Diego Pucci <[email protected]> AuthorDate: Mon Apr 8 17:09:20 2024 +0200 Merge .asf.yaml | 13 +- .github/CODEOWNERS | 4 +- .github/ISSUE_TEMPLATE/bug-report.yml | 3 +- .github/actions/setup-backend/action.yml | 34 + .github/actions/setup-supersetbot/action.yml | 36 + .github/workflows/bashlib.sh | 14 - .github/workflows/check_db_migration_confict.yml | 3 +- .github/workflows/codeql-analysis.yml | 12 +- .github/workflows/docker-release.yml | 29 +- .github/workflows/docker.yml | 67 +- .github/workflows/embedded-sdk-release.yml | 5 +- .github/workflows/embedded-sdk-test.yml | 2 +- .github/workflows/generate-FOSSA-report.yml | 5 +- .github/workflows/issue_creation.yml | 34 + .github/workflows/no-op.yml | 67 +- .github/workflows/pre-commit.yml | 24 +- .github/workflows/prefer-typescript.yml | 3 +- .github/workflows/release.yml | 5 +- .github/workflows/superset-applitool-cypress.yml | 25 +- .../workflows/superset-applitools-storybook.yml | 2 +- .github/workflows/superset-cli.yml | 20 +- .github/workflows/superset-docs-deploy.yml | 5 +- .github/workflows/superset-docs-verify.yml | 4 +- .github/workflows/superset-e2e.yml | 19 +- .github/workflows/superset-frontend.yml | 3 +- .github/workflows/superset-helm-lint.yml | 2 +- .github/workflows/superset-helm-release.yml | 1 + .../workflows/superset-python-integrationtest.yml | 39 +- .github/workflows/superset-python-misc.yml | 32 +- .github/workflows/superset-python-presto-hive.yml | 37 +- .github/workflows/superset-python-unittest.yml | 23 +- .github/workflows/superset-translations.yml | 16 +- .github/workflows/superset-websocket.yml | 3 +- .github/workflows/supersetbot.yml | 56 + .github/workflows/tech-debt.yml | 5 +- .github/workflows/update-monorepo-lockfiles.yml | 7 +- .gitignore | 1 + CHANGELOG.md | 1 + CHANGELOG/3.1.2.md | 93 + CONTRIBUTING.md | 12 +- Dockerfile | 24 +- Makefile | 12 +- README.md | 10 + RELEASING/Dockerfile.from_local_tarball | 2 +- RELEASING/Dockerfile.from_svn_tarball | 2 +- RELEASING/Dockerfile.make_docs | 2 +- RELEASING/Dockerfile.make_tarball | 2 +- RELEASING/release-notes-4-0/README.md | 151 + .../release-notes-4-0/media/alert-modal-1.png | Bin 0 -> 156064 bytes .../release-notes-4-0/media/alert-modal-2.png | Bin 0 -> 146949 bytes .../release-notes-4-0/media/alert-modal-3.png | Bin 0 -> 158396 bytes .../release-notes-4-0/media/dashboard-dnd-1.png | Bin 0 -> 626066 bytes .../release-notes-4-0/media/dashboard-dnd-2.png | Bin 0 -> 451634 bytes RELEASING/release-notes-4-0/media/explore-dnd.png | Bin 0 -> 640684 bytes RELEASING/release-notes-4-0/media/sunburst.png | Bin 0 -> 383032 bytes RELEASING/release-notes-4-0/media/tags-1.png | Bin 0 -> 273468 bytes RELEASING/release-notes-4-0/media/tags-2.png | Bin 0 -> 301495 bytes UPDATING.md | 20 +- ...ose-non-dev.yml => docker-compose-image-tag.yml | 10 +- docker-compose-non-dev.yml | 31 +- docker-compose.yml | 34 +- docker/.env | 2 + docker/.env-non-dev | 53 - docker/docker-frontend.sh | 18 +- docs/docs/contributing/hooks-and-linting.mdx | 2 +- docs/docs/contributing/local-backend.mdx | 6 +- .../creating-charts-dashboards/exploring-data.mdx | 27 - docs/docs/frequently-asked-questions.mdx | 2 +- docs/docs/installation/cache.mdx | 2 +- docs/docs/installation/configuring-superset.mdx | 2 +- docs/docs/installation/docker.mdx | 2 +- .../installing-superset-using-docker-compose.mdx | 213 +- docs/docs/installation/running-on-kubernetes.mdx | 12 +- docs/docs/installation/sql-templating.mdx | 14 + docs/docs/intro.mdx | 3 +- docs/docs/miscellaneous/country-map-tools.mdx | 130 +- .../importing-exporting-datasources.mdx | 30 +- docs/docs/quickstart.mdx | 96 +- docs/docs/security/cves.mdx | 10 + docs/docusaurus.config.js | 2 +- docs/package.json | 14 +- docs/src/theme/DocItem/index.js | 5 +- docs/static/.htaccess | 2 + docs/static/resources/openapi.json | 3 + docs/yarn.lock | 441 +- helm/superset/Chart.yaml | 4 +- helm/superset/README.md | 2 +- pyproject.toml | 199 + requirements/base.in | 1 + requirements/base.txt | 97 +- requirements/development.in | 9 +- requirements/development.txt | 247 +- requirements/docker.in | 19 - requirements/docker.txt | 23 - requirements/integration.in | 19 - requirements/integration.txt | 68 - requirements/local.in | 17 - requirements/local.txt | 15 - requirements/testing.in | 31 - requirements/testing.txt | 145 - scripts/build_docker.py | 8 +- scripts/ci_check_no_file_changes.sh | 2 +- scripts/tag_latest_release.sh | 12 +- setup.py | 148 +- superset-embedded-sdk/README.md | 10 +- superset-embedded-sdk/package-lock.json | 16 +- superset-embedded-sdk/package.json | 2 +- superset-embedded-sdk/src/index.ts | 18 +- .../cypress/e2e/chart_list/list.test.ts | 7 + .../cypress/e2e/dashboard/editmode.test.ts | 2 +- .../cypress/e2e/dashboard_list/list.test.ts | 7 + .../cypress/e2e/explore/AdhocMetrics.test.ts | 2 +- .../e2e/explore/visualizations/table.test.ts | 4 +- superset-frontend/package-lock.json | 4220 ++- superset-frontend/package.json | 13 +- .../packages/generator-superset/README.md | 2 +- .../packages/superset-ui-chart-controls/README.md | 2 +- .../src/operators/index.ts | 1 + .../src/operators/{types.ts => rankOperator.ts} | 15 +- .../src/operators/types.ts | 2 +- .../test/operators/rankOperator.test.ts} | 41 +- .../packages/superset-ui-core/README.md | 2 +- .../packages/superset-ui-core/package.json | 4 +- .../src/connection/callApi/parseResponse.ts | 6 +- .../superset-ui-core/src/connection/constants.ts | 5 + .../superset-ui-core/src/connection/index.ts | 1 + .../superset-ui-core/src/query/api/v1/makeApi.ts | 4 +- .../src/query}/getClientErrorObject.ts | 54 +- .../packages/superset-ui-core/src/query/index.ts | 1 + .../src/query/types/PostProcessing.ts | 12 +- .../superset-ui-core/src/query/types/Query.ts | 21 +- .../src/query/types/QueryResponse.ts | 1 + .../src/time-comparison/fetchTimeRange.ts} | 38 +- .../superset-ui-core/src/time-comparison/index.ts | 1 + .../superset-ui-core/src/ui-overrides/types.ts | 41 +- .../chart/components/ChartDataProvider.test.tsx | 13 +- .../test/color/SharedLabelColorSingleton.test.ts | 14 +- .../test/connection/callApi/parseResponse.test.ts | 12 +- .../test/query/getClientErrorObject.test.ts | 233 + .../test/time-comparison/fetchTimeRange.test.ts | 118 + .../packages/superset-ui-demo/README.md | 3 +- .../packages/superset-ui-demo/package.json | 6 +- .../plugins/legacy-plugin-chart-calendar/README.md | 4 +- .../plugins/legacy-plugin-chart-chord/README.md | 4 +- .../plugins/legacy-plugin-chart-chord/src/index.js | 8 +- .../legacy-plugin-chart-country-map/README.md | 4 +- .../scripts/Country Map GeoJSON Generator.ipynb | 1713 +- .../src/countries.ts | 5 + .../src/countries/france_regions.geojson | 36 +- .../src/countries/italy_regions.geojson | 40 +- .../src/countries/turkey_regions.geojson | 18 + .../legacy-plugin-chart-event-flow/README.md | 4 +- .../plugins/legacy-plugin-chart-heatmap/README.md | 4 +- .../legacy-plugin-chart-heatmap/src/Heatmap.js | 15 +- .../legacy-plugin-chart-heatmap/src/index.js | 9 +- .../src/transformProps.js | 8 +- .../legacy-plugin-chart-histogram/README.md | 4 +- .../plugins/legacy-plugin-chart-horizon/README.md | 4 +- .../plugins/legacy-plugin-chart-map-box/README.md | 4 +- .../legacy-plugin-chart-paired-t-test/README.md | 4 +- .../README.md | 4 +- .../src/index.js | 2 +- .../legacy-plugin-chart-partition/README.md | 4 +- .../plugins/legacy-plugin-chart-rose/README.md | 4 +- .../legacy-plugin-chart-sankey-loop/README.md | 4 +- .../plugins/legacy-plugin-chart-sankey/README.md | 4 +- .../legacy-plugin-chart-world-map/README.md | 4 +- .../legacy-plugin-chart-world-map/src/index.js | 1 - .../plugins/legacy-preset-chart-deckgl/README.md | 4 +- .../legacy-preset-chart-deckgl/package.json | 6 +- .../src/layers/Contour/index.ts | 2 +- .../src/layers/Geojson/index.ts | 2 +- .../src/layers/Grid/index.ts | 2 +- .../src/layers/Heatmap/index.ts | 2 +- .../src/layers/Hex/index.ts | 2 +- .../src/layers/Polygon/index.ts | 8 +- .../src/layers/Screengrid/index.ts | 8 +- .../plugins/legacy-preset-chart-nvd3/README.md | 4 +- .../plugins/legacy-preset-chart-nvd3/package.json | 2 +- .../legacy-preset-chart-nvd3/src/Area/index.js | 2 - .../legacy-preset-chart-nvd3/src/Bar/index.js | 2 - .../legacy-preset-chart-nvd3/src/Bubble/index.js | 2 - .../legacy-preset-chart-nvd3/src/DistBar/index.js | 4 - .../legacy-preset-chart-nvd3/src/Line/index.js | 2 +- .../legacy-preset-chart-nvd3/src/Pie/index.js | 2 +- .../plugins/plugin-chart-echarts/README.md | 4 +- .../plugins/plugin-chart-echarts/package.json | 35 +- .../BigNumber/BigNumberPeriodOverPeriod/PopKPI.tsx | 146 +- .../BigNumberPeriodOverPeriod/controlPanel.ts | 78 +- .../BigNumber/BigNumberPeriodOverPeriod/index.ts | 1 - .../BigNumberPeriodOverPeriod/transformProps.ts | 9 +- .../BigNumber/BigNumberPeriodOverPeriod/types.ts | 6 + .../useOverflowDetection.ts | 63 + .../src/BigNumber/BigNumberTotal/index.ts | 1 - .../src/BigNumber/BigNumberWithTrendline/index.ts | 1 - .../plugin-chart-echarts/src/Bubble/index.ts | 1 - .../src/Gauge/transformProps.ts | 13 +- .../plugin-chart-echarts/src/Graph/index.ts | 1 - .../plugin-chart-echarts/src/Heatmap/Heatmap.tsx} | 21 +- .../plugin-chart-echarts/src/Heatmap/buildQuery.ts | 68 + .../src/Heatmap/controlPanel.tsx | 304 + .../src/Heatmap/images/example1.png | Bin 0 -> 69070 bytes .../src/Heatmap/images/example2.png | Bin 0 -> 101622 bytes .../src/Heatmap/images/example3.png | Bin 0 -> 76688 bytes .../src/Heatmap/images/thumbnail.png | Bin 0 -> 66135 bytes .../src/Heatmap/index.ts} | 23 +- .../src/Heatmap/transformProps.ts | 243 + .../plugin-chart-echarts/src/Heatmap/types.ts | 53 + .../src/MixedTimeseries/index.ts | 2 - .../src/MixedTimeseries/transformProps.ts | 5 +- .../plugins/plugin-chart-echarts/src/Pie/index.ts | 1 - .../plugin-chart-echarts/src/Radar/index.ts | 1 - .../plugin-chart-echarts/src/Sunburst/index.ts | 7 +- .../src/Timeseries/Area/index.ts | 1 - .../src/Timeseries/Regular/Bar/index.ts | 2 - .../src/Timeseries/Regular/Line/index.ts | 1 - .../src/Timeseries/Regular/Scatter/index.ts | 1 - .../src/Timeseries/Regular/SmoothLine/index.ts | 1 - .../src/Timeseries/Step/index.ts | 1 - .../plugin-chart-echarts/src/Timeseries/index.ts | 1 - .../src/Timeseries/transformProps.ts | 3 +- .../src/Timeseries/transformers.ts | 28 +- .../plugin-chart-echarts/src/Treemap/index.ts | 1 - .../plugins/plugin-chart-echarts/src/index.ts | 2 + .../plugin-chart-echarts/src/utils/series.ts | 38 +- .../test/Gauge/transformProps.test.ts | 54 +- .../plugin-chart-echarts/test/utils/series.test.ts | 31 + .../plugins/plugin-chart-handlebars/README.md | 3 +- .../plugins/plugin-chart-handlebars/package.json | 2 +- .../plugins/plugin-chart-pivot-table/README.md | 3 +- .../plugins/plugin-chart-pivot-table/package.json | 4 +- .../plugins/plugin-chart-table/README.md | 4 +- .../plugins/plugin-chart-table/package.json | 4 +- .../plugins/plugin-chart-table/src/index.ts | 1 - .../plugins/plugin-chart-table/test/testData.ts | 1 + .../plugins/plugin-chart-word-cloud/README.md | 4 +- .../plugin-chart-word-cloud/src/plugin/index.ts | 9 +- superset-frontend/src/SqlLab/actions/sqlLab.js | 32 +- .../src/SqlLab/actions/sqlLab.test.js | 24 +- .../AceEditorWrapper/useAnnotations.test.ts | 2 +- .../components/AceEditorWrapper/useAnnotations.ts | 4 +- .../components/QueryHistory/QueryHistory.test.tsx | 73 +- .../src/SqlLab/components/QueryHistory/index.tsx | 106 +- .../SqlLab/components/ShareSqlLabQuery/index.tsx | 2 +- .../src/SqlLab/components/SouthPane/Results.tsx | 2 +- .../SqlLab/components/SouthPane/SouthPane.test.tsx | 13 + .../src/SqlLab/components/SouthPane/index.tsx | 14 +- .../SqlLab/components/SqlEditor/SqlEditor.test.tsx | 43 +- .../src/SqlLab/components/SqlEditor/index.tsx | 28 +- .../src/SqlLab/reducers/getInitialState.test.ts | 21 +- .../src/SqlLab/reducers/getInitialState.ts | 9 +- superset-frontend/src/SqlLab/reducers/sqlLab.js | 5 +- .../src/SqlLab/reducers/sqlLab.test.js | 19 + .../src/assets/images/icons/ballot.svg | 4 +- .../src/assets/images/icons/category.svg | 4 +- superset-frontend/src/assets/images/icons/tags.svg | 4 +- .../AlteredSliceTag/AlteredSliceTagMocks.ts | 2 +- .../src/components/AlteredSliceTag/index.tsx | 6 +- superset-frontend/src/components/Chart/Chart.jsx | 66 +- .../src/components/Chart/ChartErrorMessage.tsx | 2 +- .../Chart/DrillBy/useResultsTableView.tsx | 2 + .../DrillDetail/DrillDetailMenuItems.test.tsx | 16 +- .../Chart/DrillDetail/DrillDetailMenuItems.tsx | 187 +- .../src/components/Chart/chartAction.js | 2 +- .../CopyToClipboard/{index.jsx => index.tsx} | 54 +- .../DatabaseSelector/DatabaseSelector.test.tsx | 4 + .../Datasource/ChangeDatasourceModal.tsx | 8 +- .../src/components/Datasource/DatasourceEditor.jsx | 2 +- .../src/components/Datasource/DatasourceModal.tsx | 4 +- .../ErrorMessage/BasicErrorAlert.test.tsx | 3 +- .../components/ErrorMessage/BasicErrorAlert.tsx | 3 +- .../ErrorMessage/DatabaseErrorMessage.test.tsx | 11 +- .../ErrorMessage/DatabaseErrorMessage.tsx | 4 +- .../DatasetNotFoundErrorMessage.test.tsx | 2 +- .../components/ErrorMessage/ErrorAlert.test.tsx | 3 +- .../src/components/ErrorMessage/ErrorAlert.tsx | 9 +- .../ErrorMessageWithStackTrace.test.tsx | 2 +- .../ErrorMessage/ErrorMessageWithStackTrace.tsx | 3 +- .../ErrorMessage/MarshmallowErrorMessage.test.tsx | 8 +- .../ErrorMessage/OAuth2RedirectMessage.test.tsx | 171 + .../ErrorMessage/OAuth2RedirectMessage.tsx | 179 + .../ErrorMessage/ParameterErrorMessage.test.tsx | 2 +- .../ErrorMessage/TimeoutErrorMessage.test.tsx | 2 +- .../src/components/ErrorMessage/types.ts | 87 +- .../src/components/FilterableTable/index.tsx | 7 +- .../src/components/ListView/CardSortSelect.tsx | 18 +- .../src/components/ListView/ListView.test.tsx | 74 + .../src/components/ListView/ListView.tsx | 17 +- superset-frontend/src/components/ListView/types.ts | 4 +- superset-frontend/src/components/ListView/utils.ts | 4 +- .../src/components/Select/AsyncSelect.test.tsx | 12 + .../src/components/Select/AsyncSelect.tsx | 21 +- .../src/components/Select/Select.stories.tsx | 269 +- .../src/components/Select/Select.test.tsx | 12 + superset-frontend/src/components/Select/Select.tsx | 12 +- superset-frontend/src/components/Select/utils.tsx | 18 +- .../src/components/TableSelector/index.tsx | 11 +- superset-frontend/src/components/Tags/utils.tsx | 11 +- .../src/components/TelemetryPixel/index.tsx | 1 + superset-frontend/src/constants.ts | 8 + .../src/dashboard/actions/dashboardInfo.ts | 8 +- .../src/dashboard/actions/dashboardState.js | 2 +- .../src/dashboard/actions/sliceEntities.ts | 8 +- .../components/CssEditor/CssEditor.test.tsx | 54 +- .../components/CssEditor/{index.jsx => index.tsx} | 69 +- .../DashboardBuilder/DashboardBuilder.tsx | 5 + .../Header/HeaderActionsDropdown/index.jsx | 22 +- .../dashboard/components/PropertiesModal/index.tsx | 2 +- .../components/URLShortLinkButton/index.tsx | 3 +- .../src/dashboard/components/dnd/DragDroppable.jsx | 9 + .../dashboard/components/gridComponents/Row.jsx | 16 +- .../dashboard/components/menu/HoverMenu.test.tsx | 16 +- .../src/dashboard/components/menu/HoverMenu.tsx | 19 + .../FilterBar/FilterControls/FilterValue.tsx | 6 +- .../FiltersConfigForm/ColumnSelect.test.tsx | 4 +- .../FiltersConfigForm/ColumnSelect.tsx | 9 +- .../FiltersConfigForm/DatasetSelect.tsx | 7 +- .../FiltersConfigForm/FiltersConfigForm.tsx | 6 +- superset-frontend/src/dashboard/types.ts | 2 + .../src/explore/actions/datasourcesActions.test.ts | 4 +- .../src/explore/actions/datasourcesActions.ts | 3 +- .../src/explore/components/ChartPills.tsx | 2 +- .../explore/components/DataTableControl/index.tsx | 9 - .../components/DataTablesPane/DataTablesPane.tsx | 3 +- .../components/DataTableControls.tsx | 5 +- .../DataTablesPane/components/SamplesPane.tsx | 4 + .../components/SingleQueryResultPane.tsx | 2 + .../DataTablesPane/components/useResultsPane.tsx | 5 +- .../DataTablesPane/test/DataTablesPane.test.tsx | 5 + .../test/ResultsPaneOnDashboard.test.tsx | 4 + .../DataTablesPane/test/SamplesPane.test.tsx | 2 + .../src/explore/components/DataTablesPane/types.ts | 2 + .../DatasourcePanel/DatasourcePanel.test.tsx | 95 +- .../DatasourcePanel/DatasourcePanelItem.test.tsx | 199 + .../DatasourcePanel/DatasourcePanelItem.tsx | 269 + .../explore/components/DatasourcePanel/index.tsx | 403 +- .../ExploreContainer/ExploreContainer.test.tsx | 123 + .../explore/components/ExploreContainer/index.tsx | 88 + .../components/ExploreViewContainer/index.jsx | 44 +- .../explore/components/PropertiesModal/index.tsx | 2 +- .../RowCountLabel/RowCountLabel.test.tsx | 2 +- .../src/explore/components/RowCountLabel/index.tsx | 10 +- .../AnnotationLayerControl/AnnotationLayer.jsx | 350 +- .../AnnotationLayer.test.tsx | 125 +- .../explore/components/controls/BoundsControl.tsx | 14 +- .../controls/DateFilterControl/DateFilterLabel.tsx | 2 +- .../DateFilterControl/components/AdvancedFrame.tsx | 3 +- .../controls/DateFilterControl/tests/utils.test.ts | 33 - .../DateFilterControl/utils/dateFilterUtils.ts | 47 +- .../controls/DateFilterControl/utils/dateParser.ts | 2 +- .../DndFilterSelect.test.tsx | 221 +- .../DndColumnSelectControl/DndFilterSelect.tsx | 41 +- .../DndMetricSelect.test.tsx | 121 + .../DndColumnSelectControl/DndMetricSelect.tsx | 32 +- .../DndColumnSelectControl/DndSelectLabel.test.tsx | 40 + .../DndColumnSelectControl/DndSelectLabel.tsx | 37 +- .../utils/useGetTimeRangeLabel.test.ts | 6 +- .../FilterControl/utils/useGetTimeRangeLabel.tsx | 3 +- .../components/controls/OptionControls/index.tsx | 92 +- .../controls/SelectAsyncControl/index.tsx | 3 +- .../explore/components/controls/ViewQueryModal.tsx | 8 +- .../controls/VizTypeControl/VizTypeGallery.tsx | 62 +- .../components/controls/VizTypeControl/index.tsx | 5 +- superset-frontend/src/explore/types.ts | 1 + .../src/features/alerts/AlertReportModal.test.tsx | 9 +- .../src/features/alerts/AlertReportModal.tsx | 63 +- .../DatabaseConnectionForm/CommonParameters.tsx | 35 +- .../DatabaseConnectionForm/EncryptedField.tsx | 2 +- .../DatabaseConnectionForm/TableCatalog.tsx | 3 +- .../DatabaseConnectionForm/ValidatedInputField.tsx | 2 +- .../DatabaseModal/DatabaseConnectionForm/index.tsx | 130 +- .../databases/DatabaseModal/ExtraOptions.tsx | 16 + .../databases/DatabaseModal/SSHTunnelForm.tsx | 12 +- .../DatabaseModal/SSHTunnelSwitch.test.tsx | 162 + .../databases/DatabaseModal/SSHTunnelSwitch.tsx | 82 +- .../databases/DatabaseModal/index.test.tsx | 11 +- .../src/features/databases/DatabaseModal/index.tsx | 132 +- superset-frontend/src/features/databases/types.ts | 81 +- .../AddDataset/LeftPanel/LeftPanel.test.tsx | 4 + .../src/features/home/ActivityTable.test.tsx | 137 +- .../src/features/home/ChartTable.test.tsx | 126 +- .../src/features/reports/ReportModal/index.tsx | 7 +- .../filters/components/Range/RangeFilterPlugin.tsx | 14 + .../src/hooks/apiResources/queries.test.ts | 154 + .../src/hooks/apiResources/queries.ts | 176 + .../src/hooks/apiResources/queryApi.ts | 12 +- .../src/middleware/asyncEvent.test.ts | 5 +- superset-frontend/src/middleware/asyncEvent.ts | 8 +- .../src/pages/AnnotationList/index.tsx | 9 +- superset-frontend/src/pages/Chart/Chart.test.tsx | 3 + superset-frontend/src/pages/Chart/index.tsx | 2 +- .../src/pages/ChartCreation/index.tsx | 6 +- superset-frontend/src/pages/Home/Home.test.tsx | 16 + superset-frontend/src/pages/Home/index.tsx | 7 +- superset-frontend/src/setup/setupApp.ts | 4 +- superset-frontend/src/setup/setupErrorMessages.ts | 7 +- superset-frontend/src/types/Database.ts | 1 + .../src/utils/getClientErrorObject.test.ts | 83 - superset-frontend/src/views/CRUD/hooks.ts | 16 +- superset-frontend/src/views/CRUD/utils.tsx | 2 +- .../src/visualizations/presets/MainPreset.js | 17 +- superset-frontend/webpack.config.js | 4 +- superset-websocket/package-lock.json | 526 +- superset-websocket/package.json | 14 +- .../utils/client-ws-app/package-lock.json | 368 +- .../utils/client-ws-app/package.json | 2 +- superset/charts/data/api.py | 1 + superset/cli/importexport.py | 39 +- superset/cli/viz_migrations.py | 3 + superset/commands/base.py | 22 +- superset/commands/chart/data/get_data_command.py | 1 - superset/commands/chart/update.py | 5 +- superset/commands/dashboard/update.py | 9 +- superset/commands/database/create.py | 10 +- superset/commands/database/ssh_tunnel/create.py | 11 + .../commands/database/ssh_tunnel/exceptions.py | 4 + superset/commands/database/ssh_tunnel/update.py | 25 +- superset/commands/database/test_connection.py | 45 +- superset/commands/database/update.py | 79 +- superset/commands/dataset/update.py | 5 +- superset/commands/explore/get.py | 11 +- superset/commands/report/alert.py | 2 +- superset/commands/report/exceptions.py | 4 + superset/commands/report/execute.py | 23 +- superset/commands/report/update.py | 7 +- superset/commands/sql_lab/execute.py | 4 +- superset/commands/utils.py | 21 +- superset/common/query_actions.py | 2 + superset/common/query_context.py | 2 +- superset/common/query_context_factory.py | 2 +- superset/common/query_context_processor.py | 1 + superset/common/query_object.py | 2 +- superset/common/utils/query_cache_manager.py | 5 + superset/config.py | 55 +- superset/connectors/sqla/models.py | 70 +- superset/connectors/sqla/utils.py | 2 +- superset/connectors/sqla/views.py | 3 +- superset/daos/base.py | 2 +- superset/daos/database.py | 8 +- superset/dashboards/schemas.py | 1 + superset/databases/api.py | 127 +- superset/databases/decorators.py | 4 +- superset/databases/schemas.py | 42 +- superset/databases/utils.py | 1 - superset/db_engine_specs/README.md | 55 +- superset/db_engine_specs/base.py | 210 +- superset/db_engine_specs/crate.py | 2 +- superset/db_engine_specs/drill.py | 6 +- superset/db_engine_specs/duckdb.py | 26 +- superset/db_engine_specs/gsheets.py | 20 +- superset/db_engine_specs/hive.py | 12 +- superset/db_engine_specs/impala.py | 13 +- .../base.in => superset/db_engine_specs/mariadb.py | 11 +- superset/db_engine_specs/postgres.py | 9 +- superset/db_engine_specs/presto.py | 7 +- superset/db_engine_specs/trino.py | 17 +- superset/errors.py | 8 +- .../Vaccine_Candidates_per_Approach__Stage.yaml | 0 .../Vaccine_Candidates_per_Country.yaml | 0 .../Vaccine_Candidates_per_Country_261.yaml | 0 .../Vaccine_Candidates_per_Country__Stage.yaml | 0 .../Vaccine_Candidates_per_Country__Stage_749.yaml | 0 .../Vaccine_Candidates_per_Phase.yaml | 0 .../Vaccine_Candidates_per_Phase_587.yaml | 0 .../Age_distribution_of_respondents.yaml | 0 .../Are_you_an_ethnic_minority_in_your_city.yaml | 0 .../Breakdown_of_Developer_Type.yaml | 0 .../{ => FCC New Coder Survey}/Commute_Time.yaml | 0 .../Country_of_Citizenship.yaml | 0 ...elopers_Is_this_your_first_development_job.yaml | 0 .../Degrees_vs_Income.yaml | 0 .../Ethnic_Minority__Gender.yaml | 0 .../First_Time_Developer.yaml | 0 .../First_Time_Developer__Commute_Time.yaml | 0 .../charts/{ => FCC New Coder Survey}/Gender.yaml | 0 .../Highest_degree_held.yaml | 0 .../How_do_you_prefer_to_work.yaml | 0 .../How_much_do_you_expect_to_earn_0_-_100k.yaml | 0 .../Last_Year_Income_Distribution.yaml | 0 .../Location_of_Current_Developers.yaml | 0 .../Number_of_Aspiring_Developers.yaml | 0 .../Preferred_Employment_Style.yaml | 0 .../Relocation_ability.yaml | 0 .../Top_15_Languages_Spoken_at_Home.yaml | 0 .../Work_Location_Preference.yaml | 0 .../Cross_Channel_Relationship.yaml | 0 .../Cross_Channel_Relationship_heatmap_2786.yaml | 0 .../{ => Slack Dashboard}/Members_per_Channel.yaml | 0 .../Messages_per_Channel.yaml | 0 .../New_Members_per_Month.yaml | 0 .../{ => Slack Dashboard}/Number_of_Members.yaml | 0 .../{ => Slack Dashboard}/Top_Timezones.yaml | 0 .../{ => Slack Dashboard}/Weekly_Messages.yaml | 0 .../{ => Slack Dashboard}/Weekly_Threads.yaml | 0 .../{ => Unicode Test}/Unicode_Cloud.test.yaml | 0 .../Number_of_Deals_for_each_Combination.yaml | 0 .../Overall_Sales_By_Product_Line.yaml | 0 .../Proportion_of_Revenue_by_Product_Line.yaml | 0 .../{ => Vehicle Sales}/Quarterly_Sales.yaml | 0 .../Quarterly_Sales_By_Product_Line.yaml | 0 .../{ => Vehicle Sales}/Revenue_by_Deal_Size.yaml | 0 .../Seasonality_of_Revenue_per_Product_Line.yaml | 0 .../{ => Vehicle Sales}/Total_Items_Sold.yaml | 0 .../Total_Items_Sold_By_Product_Line.yaml | 0 .../charts/{ => Vehicle Sales}/Total_Revenue.yaml | 0 .../charts/{ => Video Game Sales}/Games.yaml | 0 .../{ => Video Game Sales}/Games_per_Genre.yaml | 0 .../Games_per_Genre_over_time.yaml | 0 .../Most_Dominant_Platforms.yaml | 0 ...mes_That_Hit_100k_in_Sales_By_Release_Year.yaml | 0 .../Popular_Genres_Across_Platforms.yaml | 0 .../Publishers_With_Most_Titles.yaml | 0 .../Rise__Fall_of_Video_Game_Consoles.yaml | 0 ...op_10_Games_Proportion_of_Sales_in_Markets.yaml | 0 .../Total_Sales_per_Market_Grouped_by_Genre.yaml | 0 superset/exceptions.py | 67 + superset/jinja_context.py | 80 +- superset/key_value/types.py | 1 + .../migrations/shared/migrate_viz/processors.py | 15 + ...47_be1b217cd8cd_big_number_kpi_single_metric.py | 93 + ...20_16-02_678eefb4ab44_add_access_token_table.py | 84 + superset/models/core.py | 79 +- superset/models/dashboard.py | 5 +- superset/models/helpers.py | 31 +- superset/models/slice.py | 12 +- superset/models/sql_lab.py | 44 +- superset/queries/api.py | 19 +- superset/reports/models.py | 7 +- superset/reports/notifications/base.py | 1 + superset/reports/notifications/email.py | 12 +- superset/reports/notifications/slack.py | 15 +- superset/reports/schemas.py | 4 +- superset/security/manager.py | 97 +- superset/sql_lab.py | 12 +- superset/sql_parse.py | 598 +- superset/sql_validators/presto_db.py | 2 +- superset/sqllab/api.py | 4 +- superset/sqllab/query_render.py | 3 +- superset/sqllab/schemas.py | 1 + superset/sqllab/utils.py | 16 +- superset/superset_typing.py | 49 + superset/tags/models.py | 4 +- .../templates/superset/oauth2.html | 23 +- superset/translations/tr/LC_MESSAGES/messages.json | 4864 +++ .../{zh => tr}/LC_MESSAGES/messages.po | 30716 +++++++++---------- superset/translations/zh/LC_MESSAGES/messages.json | 2268 +- superset/translations/zh/LC_MESSAGES/messages.po | 1958 +- superset/utils/core.py | 13 +- superset/utils/date_parser.py | 77 +- superset/utils/hashing.py | 4 +- superset/utils/lock.py | 99 + superset/utils/oauth2.py | 182 + superset/utils/pandas_postprocessing/__init__.py | 2 + .../{hashing.py => pandas_postprocessing/rank.py} | 34 +- superset/utils/pandas_postprocessing/resample.py | 5 +- superset/utils/pandas_postprocessing/rolling.py | 2 +- superset/utils/pdf.py | 48 + superset/utils/retries.py | 2 +- superset/views/api.py | 33 +- superset/views/chart/mixin.py | 2 +- superset/views/core.py | 4 + superset/views/database/forms.py | 3 +- superset/views/database/mixins.py | 6 +- superset/views/datasource/views.py | 4 +- superset/views/sql_lab/views.py | 20 +- superset/viz.py | 2 + tests/integration_tests/celery_tests.py | 40 +- tests/integration_tests/charts/api_tests.py | 70 +- tests/integration_tests/charts/commands_tests.py | 7 +- tests/integration_tests/charts/data/api_tests.py | 59 +- tests/integration_tests/core_tests.py | 40 +- tests/integration_tests/dashboards/api_tests.py | 37 + tests/integration_tests/databases/api_tests.py | 206 +- tests/integration_tests/datasets/api_tests.py | 55 + tests/integration_tests/datasource_tests.py | 2 +- .../db_engine_specs/base_engine_spec_tests.py | 5 +- .../db_engine_specs/bigquery_tests.py | 2 +- tests/integration_tests/explore/api_tests.py | 20 +- tests/integration_tests/model_tests.py | 57 +- tests/integration_tests/query_context_tests.py | 67 +- tests/integration_tests/reports/api_tests.py | 87 + tests/integration_tests/reports/commands_tests.py | 6 +- tests/integration_tests/reports/utils.py | 2 +- .../security/row_level_security_tests.py | 4 +- tests/integration_tests/security_tests.py | 2 + tests/integration_tests/sql_lab/api_tests.py | 83 +- tests/integration_tests/sqla_models_tests.py | 76 +- tests/integration_tests/sqllab_tests.py | 94 +- .../unit_tests/commands/dataset/__init__.py | 5 - tests/unit_tests/commands/test_utils.py | 118 + .../unit_tests/connectors/__init__.py | 5 - .../unit_tests/connectors/sqla/__init__.py | 5 - tests/unit_tests/connectors/sqla/models_test.py | 66 + tests/unit_tests/databases/api_test.py | 180 + tests/unit_tests/databases/schema_tests.py | 42 + .../databases/ssh_tunnel/commands/create_test.py | 45 +- .../databases/ssh_tunnel/commands/update_test.py | 35 +- tests/unit_tests/db_engine_specs/test_base.py | 26 +- tests/unit_tests/db_engine_specs/test_bigquery.py | 7 +- .../unit_tests/db_engine_specs/test_clickhouse.py | 6 +- tests/unit_tests/db_engine_specs/test_crate.py | 2 +- tests/unit_tests/db_engine_specs/test_databend.py | 6 +- tests/unit_tests/db_engine_specs/test_drill.py | 8 +- tests/unit_tests/db_engine_specs/test_duckdb.py | 34 + .../db_engine_specs/test_elasticsearch.py | 5 +- tests/unit_tests/db_engine_specs/test_gsheets.py | 205 + tests/unit_tests/extensions/test_sqlalchemy.py | 6 +- tests/unit_tests/jinja_context_test.py | 730 +- .../migrations/viz/heatmap_v1_v2_test.py | 78 + tests/unit_tests/models/helpers_test.py | 72 + tests/unit_tests/models/sql_lab_test.py | 59 + .../pandas_postprocessing/test_resample.py | 54 +- .../pandas_postprocessing/test_rolling.py | 4 +- .../unit_tests/scripts/tag_latest_release_test.py | 4 +- tests/unit_tests/security/manager_test.py | 267 +- tests/unit_tests/sql_lab_test.py | 8 +- tests/unit_tests/sql_parse_tests.py | 265 +- tests/unit_tests/test_jinja_context.py | 305 - tests/unit_tests/utils/date_parser_tests.py | 32 + tests/unit_tests/utils/lock_tests.py | 79 + tests/unit_tests/utils/oauth2_tests.py | 95 + tox.ini | 10 +- 622 files changed, 39352 insertions(+), 25776 deletions(-) diff --cc superset-frontend/src/components/Chart/DrillDetail/DrillDetailMenuItems.tsx index 868fd38a78,6c1669933b..acfb4e01fe --- a/superset-frontend/src/components/Chart/DrillDetail/DrillDetailMenuItems.tsx +++ b/superset-frontend/src/components/Chart/DrillDetail/DrillDetailMenuItems.tsx @@@ -101,11 -109,13 +118,16 @@@ const DrillDetailMenuItems = ( onSelection = () => null, onClick = () => null, submenuIndex = 0, + showModal, + setShowModal, + drillToDetailMenuRef, ...props }: DrillDetailMenuItemsProps) => { + const drillToDetailDisabled = useSelector<RootState, boolean | undefined>( + ({ datasources }) => + datasources[formData.datasource]?.database?.disable_drill_to_detail, + ); + const [modalFilters, setFilters] = useState<BinaryQueryObjectFilterClause[]>( [], ); @@@ -201,55 -165,76 +176,77 @@@ [contextMenuY, filters.length, submenuIndex], ); - if (handlesDimensionContextMenu && !noAggregations && filters?.length) { - drillToDetailByMenuItem = ( - <Menu.SubMenu - {...props} - popupOffset={[0, submenuYOffset]} - popupClassName="chart-context-submenu" - title={DRILL_TO_DETAIL_TEXT} - > - <div data-test="drill-to-detail-by-submenu"> - {filters.map((filter, i) => ( - <MenuItemWithTruncation - {...props} - tooltipText={`${DRILL_TO_DETAIL_TEXT} ${filter.formattedVal}`} - key={`drill-detail-filter-${i}`} - onClick={openModal.bind(null, [filter])} - > - {`${DRILL_TO_DETAIL_TEXT} `} - <StyledFilter stripHTML>{filter.formattedVal}</StyledFilter> - </MenuItemWithTruncation> - ))} - {filters.length > 1 && ( - <Menu.Item - {...props} - key="drill-detail-filter-all" - onClick={openModal.bind(null, filters)} - > - <div> - {`${DRILL_TO_DETAIL_TEXT} `} - <StyledFilter stripHTML={false}>{t('all')}</StyledFilter> - </div> - </Menu.Item> - )} - </div> - </Menu.SubMenu> - ); + let drillDisabled; + let drillByDisabled; + if (drillToDetailDisabled) { + drillDisabled = DISABLED_REASONS.DATABASE; + drillByDisabled = DISABLED_REASONS.DATABASE; + } else if (handlesDimensionContextMenu) { + if (noAggregations) { + drillDisabled = DISABLED_REASONS.NO_AGGREGATIONS; + drillByDisabled = DISABLED_REASONS.NO_AGGREGATIONS; + } else if (!filters?.length) { + drillByDisabled = DISABLED_REASONS.NO_FILTERS; + } + } else { + drillByDisabled = DISABLED_REASONS.NOT_SUPPORTED; } - if (handlesDimensionContextMenu && !noAggregations && !filters?.length) { - drillToDetailByMenuItem = ( - <DisabledMenuItem {...props} key="drill-detail-by-select-aggregation"> - {DRILL_TO_DETAIL_TEXT} - <MenuItemTooltip - title={t( - 'Right-click on a dimension value to drill to detail by that value.', - )} - /> - </DisabledMenuItem> - ); - } + const drillToDetailMenuItem = drillDisabled ? ( + <DisabledMenuItem {...props} key="drill-to-detail-disabled"> + {DRILL_TO_DETAIL} + <MenuItemTooltip title={drillDisabled} /> + </DisabledMenuItem> + ) : ( + <Menu.Item + {...props} + key="drill-to-detail" + onClick={openModal.bind(null, [])} ++ ref={drillToDetailMenuRef} + > + {DRILL_TO_DETAIL} + </Menu.Item> + ); + + const drillToDetailByMenuItem = drillByDisabled ? ( + <DisabledMenuItem {...props} key="drill-to-detail-by-disabled"> + {DRILL_TO_DETAIL_BY} + <MenuItemTooltip title={drillByDisabled} /> + </DisabledMenuItem> + ) : ( + <Menu.SubMenu + {...props} + popupOffset={[0, submenuYOffset]} + popupClassName="chart-context-submenu" + title={DRILL_TO_DETAIL_BY} + > + <div data-test="drill-to-detail-by-submenu"> + {filters.map((filter, i) => ( + <MenuItemWithTruncation + {...props} + tooltipText={`${DRILL_TO_DETAIL_BY} ${filter.formattedVal}`} + key={`drill-detail-filter-${i}`} + onClick={openModal.bind(null, [filter])} + > + {`${DRILL_TO_DETAIL_BY} `} + <StyledFilter stripHTML>{filter.formattedVal}</StyledFilter> + </MenuItemWithTruncation> + ))} + {filters.length > 1 && ( + <Menu.Item + {...props} + key="drill-detail-filter-all" + onClick={openModal.bind(null, filters)} + > + <div> + {`${DRILL_TO_DETAIL_BY} `} + <StyledFilter stripHTML={false}>{t('all')}</StyledFilter> + </div> + </Menu.Item> + )} + </div> + </Menu.SubMenu> + ); return ( <>
