diff --git a/docs/docs/installation/sql-templating.mdx b/docs/docs/installation/sql-templating.mdx index 8a093e643a0..72c2c0a9adb 100644 --- a/docs/docs/installation/sql-templating.mdx +++ b/docs/docs/installation/sql-templating.mdx @@ -298,7 +298,7 @@ Here's a concrete example: It's possible to query physical and virtual datasets using the `dataset` macro. This is useful if you've defined computed columns and metrics on your datasets, and want to reuse the definition in adhoc SQL Lab queries. -To use the macro, first you need to find the ID of the dataset. This can be done by going to the view showing all the datasets, hovering over the dataset you're interested in, and looking at its URL. For example, if the URL for a dataset is https://superset.example.org/superset/explore/table/42/ its ID is 42. +To use the macro, first you need to find the ID of the dataset. This can be done by going to the view showing all the datasets, hovering over the dataset you're interested in, and looking at its URL. For example, if the URL for a dataset is https://superset.example.org/explore/?dataset_type=table&dataset_id=42 its ID is 42. Once you have the ID you can query it as if it were a table: diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/explore.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/explore.js index 5714eb5da10..cf1d691ff91 100644 --- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/explore.js +++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/explore.js @@ -23,7 +23,7 @@ const MAX_URL_LENGTH = 8000; export function getURIDirectory(formData, endpointType = 'base') { // Building the directory part of the URI - let directory = '/superset/explore/'; + let directory = '/explore/'; if (['json', 'csv', 'query', 'results', 'samples'].includes(endpointType)) { directory = '/superset/explore_json/'; } diff --git a/superset-frontend/plugins/legacy-preset-chart-nvd3/src/vendor/superset/exploreUtils.js b/superset-frontend/plugins/legacy-preset-chart-nvd3/src/vendor/superset/exploreUtils.js index cb2561efb86..c4c9c3264ec 100644 --- a/superset-frontend/plugins/legacy-preset-chart-nvd3/src/vendor/superset/exploreUtils.js +++ b/superset-frontend/plugins/legacy-preset-chart-nvd3/src/vendor/superset/exploreUtils.js @@ -24,7 +24,7 @@ const MAX_URL_LENGTH = 8000; export function getURIDirectory(formData, endpointType = 'base') { // Building the directory part of the URI - let directory = '/superset/explore/'; + let directory = '/explore/'; if (['json', 'csv', 'query', 'results', 'samples'].includes(endpointType)) { directory = '/superset/explore_json/'; } diff --git a/superset-frontend/spec/fixtures/mockSliceEntities.js b/superset-frontend/spec/fixtures/mockSliceEntities.js index 69570c5c8f8..cb6d84ea347 100644 --- a/superset-frontend/spec/fixtures/mockSliceEntities.js +++ b/superset-frontend/spec/fixtures/mockSliceEntities.js @@ -26,7 +26,7 @@ export const sliceEntitiesForChart = { slices: { [sliceId]: { slice_id: sliceId, - slice_url: '/superset/explore/?form_data=%7B%22slice_id%22%3A%2018%7D', + slice_url: '/explore/?form_data=%7B%22slice_id%22%3A%2018%7D', slice_name: 'Genders', form_data: { slice_id: sliceId, @@ -62,7 +62,7 @@ export const sliceEntitiesForDashboard = { slices: { [filterId]: { slice_id: filterId, - slice_url: '/superset/explore/?form_data=%7B%22slice_id%22%3A%20127%7D', + slice_url: '/explore/?form_data=%7B%22slice_id%22%3A%20127%7D', slice_name: 'Region Filter', form_data: { instant_filtering: true, @@ -86,7 +86,7 @@ export const sliceEntitiesForDashboard = { }, 128: { slice_id: 128, - slice_url: '/superset/explore/?form_data=%7B%22slice_id%22%3A%20128%7D', + slice_url: '/explore/?form_data=%7B%22slice_id%22%3A%20128%7D', slice_name: "World's Population", form_data: {}, viz_type: 'big_number', @@ -98,7 +98,7 @@ export const sliceEntitiesForDashboard = { }, 129: { slice_id: 129, - slice_url: '/superset/explore/?form_data=%7B%22slice_id%22%3A%20129%7D', + slice_url: '/explore/?form_data=%7B%22slice_id%22%3A%20129%7D', slice_name: 'Most Populated Countries', form_data: {}, viz_type: 'table', @@ -110,7 +110,7 @@ export const sliceEntitiesForDashboard = { }, 130: { slice_id: 130, - slice_url: '/superset/explore/?form_data=%7B%22slice_id%22%3A%20130%7D', + slice_url: '/explore/?form_data=%7B%22slice_id%22%3A%20130%7D', slice_name: 'Growth Rate', form_data: {}, viz_type: 'line', @@ -122,7 +122,7 @@ export const sliceEntitiesForDashboard = { }, 131: { slice_id: 131, - slice_url: '/superset/explore/?form_data=%7B%22slice_id%22%3A%20131%7D', + slice_url: '/explore/?form_data=%7B%22slice_id%22%3A%20131%7D', slice_name: '% Rural', form_data: {}, viz_type: 'world_map', @@ -134,7 +134,7 @@ export const sliceEntitiesForDashboard = { }, 132: { slice_id: 132, - slice_url: '/superset/explore/?form_data=%7B%22slice_id%22%3A%20132%7D', + slice_url: '/explore/?form_data=%7B%22slice_id%22%3A%20132%7D', slice_name: 'Life Expectancy VS Rural %', form_data: {}, viz_type: 'bubble', @@ -146,7 +146,7 @@ export const sliceEntitiesForDashboard = { }, 133: { slice_id: 133, - slice_url: '/superset/explore/?form_data=%7B%22slice_id%22%3A%20133%7D', + slice_url: '/explore/?form_data=%7B%22slice_id%22%3A%20133%7D', slice_name: 'Rural Breakdown', form_data: {}, viz_type: 'sunburst', @@ -158,7 +158,7 @@ export const sliceEntitiesForDashboard = { }, 134: { slice_id: 134, - slice_url: '/superset/explore/?form_data=%7B%22slice_id%22%3A%20134%7D', + slice_url: '/explore/?form_data=%7B%22slice_id%22%3A%20134%7D', slice_name: "World's Pop Growth", form_data: {}, viz_type: 'area', @@ -170,7 +170,7 @@ export const sliceEntitiesForDashboard = { }, 135: { slice_id: 135, - slice_url: '/superset/explore/?form_data=%7B%22slice_id%22%3A%20135%7D', + slice_url: '/explore/?form_data=%7B%22slice_id%22%3A%20135%7D', slice_name: 'Box plot', form_data: {}, viz_type: 'box_plot', @@ -182,7 +182,7 @@ export const sliceEntitiesForDashboard = { }, 136: { slice_id: 136, - slice_url: '/superset/explore/?form_data=%7B%22slice_id%22%3A%20136%7D', + slice_url: '/explore/?form_data=%7B%22slice_id%22%3A%20136%7D', slice_name: 'Treemap', form_data: {}, viz_type: 'treemap', diff --git a/superset-frontend/src/utils/urlUtils.ts b/superset-frontend/src/utils/urlUtils.ts index 0ca104ef024..2aac5f3e281 100644 --- a/superset-frontend/src/utils/urlUtils.ts +++ b/superset-frontend/src/utils/urlUtils.ts @@ -52,10 +52,10 @@ export function getUrlParam({ name, type }: UrlParam): unknown { if (!urlParam) { return null; } - if (urlParam === 'true') { + if (urlParam.toLowerCase() === 'true') { return 1; } - if (urlParam === 'false') { + if (urlParam.toLowerCase() === 'false') { return 0; } if (!Number.isNaN(Number(urlParam))) { @@ -71,7 +71,7 @@ export function getUrlParam({ name, type }: UrlParam): unknown { if (!urlParam) { return null; } - return urlParam !== 'false' && urlParam !== '0'; + return urlParam.toLowerCase() !== 'false' && urlParam !== '0'; case 'rison': if (!urlParam) { return null; diff --git a/superset-frontend/src/views/CRUD/data/dataset/DatasetList.test.jsx b/superset-frontend/src/views/CRUD/data/dataset/DatasetList.test.jsx index 948c22fa407..2f23f455733 100644 --- a/superset-frontend/src/views/CRUD/data/dataset/DatasetList.test.jsx +++ b/superset-frontend/src/views/CRUD/data/dataset/DatasetList.test.jsx @@ -51,7 +51,7 @@ const mockdatasets = [...new Array(3)].map((_, i) => ({ changed_by: 'user', changed_on: new Date().toISOString(), database_name: `db ${i}`, - explore_url: `/explore/table/${i}`, + explore_url: `/explore/?dataset_type=table&dataset_id=${i}`, id: i, schema: `schema ${i}`, table_name: `coolest table ${i}`, diff --git a/superset/connectors/sqla/views.py b/superset/connectors/sqla/views.py index 18533905ee8..cee0a07b54b 100644 --- a/superset/connectors/sqla/views.py +++ b/superset/connectors/sqla/views.py @@ -535,7 +535,7 @@ class TableModelView( # pylint: disable=too-many-ancestors resp = super().edit(pk) if isinstance(resp, str): return resp - return redirect("/superset/explore/table/{}/".format(pk)) + return redirect("/explore/?dataset_type=table&dataset_id={}".format(pk)) @expose("/list/") @has_access diff --git a/superset/models/core.py b/superset/models/core.py index 0cfcea16621..25beb2bee37 100755 --- a/superset/models/core.py +++ b/superset/models/core.py @@ -386,7 +386,7 @@ class Database( if not source and request and request.referrer: if "/superset/dashboard/" in request.referrer: source = utils.QuerySource.DASHBOARD - elif "/superset/explore/" in request.referrer: + elif "/explore/" in request.referrer: source = utils.QuerySource.CHART elif "/superset/sqllab/" in request.referrer: source = utils.QuerySource.SQL_LAB diff --git a/superset/reports/commands/execute.py b/superset/reports/commands/execute.py index ad1b1edcd2a..03b9efce45d 100644 --- a/superset/reports/commands/execute.py +++ b/superset/reports/commands/execute.py @@ -167,7 +167,7 @@ class BaseReportState: force=force, ) return get_url_path( - "Superset.explore", + "ExploreView.root", user_friendly=user_friendly, form_data=json.dumps({"slice_id": self._report_schedule.chart_id}), standalone="true", diff --git a/superset/templates/email/role_extended.txt b/superset/templates/email/role_extended.txt index 89ba1b0f722..463fb32c9c4 100644 --- a/superset/templates/email/role_extended.txt +++ b/superset/templates/email/role_extended.txt @@ -20,7 +20,7 @@ Dear {{ user.username }},
{{ granter.username }} has extended the role {{ role.name }} to include - + {{datasource.full_name}} and granted you access to it.

diff --git a/superset/templates/email/role_granted.txt b/superset/templates/email/role_granted.txt index 8027f41ac48..312a0494738 100644 --- a/superset/templates/email/role_granted.txt +++ b/superset/templates/email/role_granted.txt @@ -21,7 +21,7 @@ Dear {{ user.username }}, {{ granter.username }} has granted you the role {{ role.name }} that gives access to the - + {{datasource.full_name}}

diff --git a/superset/views/core.py b/superset/views/core.py index c27dcfb4a64..cfa9f8eaa7b 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -427,13 +427,13 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods _, slc = get_form_data(slice_id, use_slice_data=True) if not slc: abort(404) - endpoint = "/superset/explore/?form_data={}".format( + endpoint = "/explore/?form_data={}".format( parse.quote(json.dumps({"slice_id": slice_id})) ) is_standalone_mode = ReservedUrlParameters.is_standalone_mode() if is_standalone_mode: - endpoint += f"&{ReservedUrlParameters.STANDALONE}={is_standalone_mode}" + endpoint += f"&{ReservedUrlParameters.STANDALONE}=true" return redirect(endpoint) def get_query_string_response(self, viz_obj: BaseViz) -> FlaskResponse: diff --git a/superset/views/redirects.py b/superset/views/redirects.py index 831fc978b94..93a43394031 100644 --- a/superset/views/redirects.py +++ b/superset/views/redirects.py @@ -34,25 +34,40 @@ class R(BaseSupersetView): # pylint: disable=invalid-name """used for short urls""" @staticmethod - def _validate_url(url: Optional[str] = None) -> bool: - if url and ( - url.startswith("//superset/dashboard/") - or url.startswith("//superset/explore/") - ): - return True - return False + def _validate_explore_url(url: str) -> Optional[str]: + if url.startswith("//superset/explore/p/"): + return url + + if url.startswith("//superset/explore"): + return "/" + url[10:] # Remove /superset from old Explore URLs + + if url.startswith("//explore"): + return url + + return None + + @staticmethod + def _validate_dashboard_url(url: str) -> Optional[str]: + if url.startswith("//superset/dashboard/"): + return url + + return None @event_logger.log_this @expose("/") def index(self, url_id: int) -> FlaskResponse: url = db.session.query(models.Url).get(url_id) if url and url.url: - explore_url = "//superset/explore/?" - if url.url.startswith(explore_url): - explore_url += f"r={url_id}" + explore_url = self._validate_explore_url(url.url) + if explore_url: + if explore_url.startswith("//explore/?"): + explore_url = f"//explore/?r={url_id}" return redirect(explore_url[1:]) - if self._validate_url(url.url): - return redirect(url.url[1:]) + + dashboard_url = self._validate_dashboard_url(url.url) + if dashboard_url: + return redirect(dashboard_url[1:]) + return redirect("/") flash("URL to nowhere...", "danger") diff --git a/tests/integration_tests/core_tests.py b/tests/integration_tests/core_tests.py index abe61ff5953..6bc08cae88a 100644 --- a/tests/integration_tests/core_tests.py +++ b/tests/integration_tests/core_tests.py @@ -123,15 +123,6 @@ class TestCore(SupersetTestCase): @pytest.mark.usefixtures("load_birth_names_dashboard_with_slices") def test_slice_endpoint(self): self.login(username="admin") - slc = self.get_slice("Girls", db.session) - resp = self.get_resp("/superset/slice/{}/".format(slc.id)) - assert "Original value" in resp - assert "List Roles" in resp - - # Testing overrides - resp = self.get_resp("/superset/slice/{}/?standalone=true".format(slc.id)) - assert '