From af587840403d83a7da7fb0f57bc10ad2335d4eeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Travais?= Date: Tue, 28 Nov 2023 23:32:19 +0100 Subject: [PATCH] feat(deckgl-map): use an arbitraty Mabpox style URL (#26027) (#26031) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: François Travais --- .../superset-ui-core/src/validator/index.ts | 1 + .../src/validator/validateMapboxStylesUrl.ts | 36 ++++++++++++++ .../validator/validateMapboxStylesUrl.test.ts | 47 +++++++++++++++++++ .../src/controlPanel.ts | 14 +++++- .../src/Multi/controlPanel.ts | 3 +- .../src/layers/Arc/controlPanel.ts | 5 +- .../src/layers/Contour/controlPanel.ts | 4 +- .../src/layers/Grid/controlPanel.ts | 3 +- .../src/layers/Heatmap/controlPanel.ts | 3 +- .../src/layers/Hex/controlPanel.ts | 4 +- .../src/layers/Path/controlPanel.ts | 3 +- .../src/layers/Scatter/controlPanel.ts | 5 +- .../src/layers/Screengrid/controlPanel.ts | 5 +- .../src/utilities/Shared_DeckGL.jsx | 8 +++- 14 files changed, 118 insertions(+), 23 deletions(-) create mode 100644 superset-frontend/packages/superset-ui-core/src/validator/validateMapboxStylesUrl.ts create mode 100644 superset-frontend/packages/superset-ui-core/test/validator/validateMapboxStylesUrl.test.ts diff --git a/superset-frontend/packages/superset-ui-core/src/validator/index.ts b/superset-frontend/packages/superset-ui-core/src/validator/index.ts index 532efcc95..169675b68 100644 --- a/superset-frontend/packages/superset-ui-core/src/validator/index.ts +++ b/superset-frontend/packages/superset-ui-core/src/validator/index.ts @@ -22,3 +22,4 @@ export { default as legacyValidateNumber } from './legacyValidateNumber'; export { default as validateInteger } from './validateInteger'; export { default as validateNumber } from './validateNumber'; export { default as validateNonEmpty } from './validateNonEmpty'; +export { default as validateMapboxStylesUrl } from './validateMapboxStylesUrl'; diff --git a/superset-frontend/packages/superset-ui-core/src/validator/validateMapboxStylesUrl.ts b/superset-frontend/packages/superset-ui-core/src/validator/validateMapboxStylesUrl.ts new file mode 100644 index 000000000..bfbbaa716 --- /dev/null +++ b/superset-frontend/packages/superset-ui-core/src/validator/validateMapboxStylesUrl.ts @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { t } from '../translation'; + +/** + * Validate a [Mapbox styles URL](https://docs.mapbox.com/help/glossary/style-url/) + * @param v + */ +export default function validateMapboxStylesUrl(v: unknown) { + if ( + typeof v === 'string' && + v.trim().length > 0 && + v.trim().startsWith('mapbox://styles/') + ) { + return false; + } + + return t('is expected to be a Mapbox URL'); +} diff --git a/superset-frontend/packages/superset-ui-core/test/validator/validateMapboxStylesUrl.test.ts b/superset-frontend/packages/superset-ui-core/test/validator/validateMapboxStylesUrl.test.ts new file mode 100644 index 000000000..dbd582266 --- /dev/null +++ b/superset-frontend/packages/superset-ui-core/test/validator/validateMapboxStylesUrl.test.ts @@ -0,0 +1,47 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +import { validateMapboxStylesUrl } from '@superset-ui/core'; +import './setup'; + +describe('validateMapboxStylesUrl', () => { + it('should validate mapbox style URLs', () => { + expect( + validateMapboxStylesUrl('mapbox://styles/mapbox/streets-v9'), + ).toEqual(false); + expect( + validateMapboxStylesUrl( + 'mapbox://styles/foobar/clp2dr5r4008a01pcg4ad45m8', + ), + ).toEqual(false); + }); + + [ + 123, + ['mapbox://styles/mapbox/streets-v9'], + { url: 'mapbox://styles/mapbox/streets-v9' }, + 'https://superset.apache.org/', + 'mapbox://tileset/mapbox/streets-v9', + ].forEach(value => { + it(`should not validate ${value}`, () => { + expect(validateMapboxStylesUrl(value)).toEqual( + 'is expected to be a Mapbox URL', + ); + }); + }); +}); diff --git a/superset-frontend/plugins/legacy-plugin-chart-map-box/src/controlPanel.ts b/superset-frontend/plugins/legacy-plugin-chart-map-box/src/controlPanel.ts index 1dc75d96e..e0b652460 100644 --- a/superset-frontend/plugins/legacy-plugin-chart-map-box/src/controlPanel.ts +++ b/superset-frontend/plugins/legacy-plugin-chart-map-box/src/controlPanel.ts @@ -16,7 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -import { FeatureFlag, isFeatureEnabled, t } from '@superset-ui/core'; +import { + FeatureFlag, + isFeatureEnabled, + t, + validateMapboxStylesUrl, +} from '@superset-ui/core'; import { columnChoices, ControlPanelConfig, @@ -224,6 +229,8 @@ const config: ControlPanelConfig = { label: t('Map Style'), clearable: false, renderTrigger: true, + freeForm: true, + validators: [validateMapboxStylesUrl], choices: [ ['mapbox://styles/mapbox/streets-v9', t('Streets')], ['mapbox://styles/mapbox/dark-v9', t('Dark')], @@ -236,7 +243,10 @@ const config: ControlPanelConfig = { ['mapbox://styles/mapbox/outdoors-v9', t('Outdoors')], ], default: 'mapbox://styles/mapbox/light-v9', - description: t('Base layer map style'), + description: t( + 'Base layer map style. See Mapbox documentation: %s', + 'https://docs.mapbox.com/help/glossary/style-url/', + ), }, }, ], diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/controlPanel.ts b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/controlPanel.ts index 8571fe23d..8f4df671c 100644 --- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/controlPanel.ts +++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/controlPanel.ts @@ -27,7 +27,8 @@ export default { label: t('Map'), expanded: true, controlSetRows: [ - [mapboxStyle, viewport], + [mapboxStyle], + [viewport], [ { name: 'deck_slices', diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Arc/controlPanel.ts b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Arc/controlPanel.ts index 3794ef38d..664f389a0 100644 --- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Arc/controlPanel.ts +++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Arc/controlPanel.ts @@ -76,10 +76,7 @@ const config: ControlPanelConfig = { }, { label: t('Map'), - controlSetRows: [ - [mapboxStyle, viewport], - [autozoom, null], - ], + controlSetRows: [[mapboxStyle], [autozoom, viewport]], }, { label: t('Arc'), diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Contour/controlPanel.ts b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Contour/controlPanel.ts index 238029aad..407cab316 100644 --- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Contour/controlPanel.ts +++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Contour/controlPanel.ts @@ -52,8 +52,8 @@ const config: ControlPanelConfig = { label: t('Map'), expanded: true, controlSetRows: [ - [mapboxStyle, viewport], - [autozoom], + [mapboxStyle], + [autozoom, viewport], [ { name: 'cellSize', diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Grid/controlPanel.ts b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Grid/controlPanel.ts index 9b8e33d73..fa9a03a8f 100644 --- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Grid/controlPanel.ts +++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Grid/controlPanel.ts @@ -53,7 +53,8 @@ const config: ControlPanelConfig = { { label: t('Map'), controlSetRows: [ - [mapboxStyle, viewport], + [mapboxStyle], + [viewport], ['color_scheme'], [autozoom], [gridSize], diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Heatmap/controlPanel.ts b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Heatmap/controlPanel.ts index 6fa41c2e2..fd343eed1 100644 --- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Heatmap/controlPanel.ts +++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Heatmap/controlPanel.ts @@ -99,7 +99,8 @@ const config: ControlPanelConfig = { { label: t('Map'), controlSetRows: [ - [mapboxStyle, viewport], + [mapboxStyle], + [viewport], ['linear_color_scheme'], [autozoom], [ diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Hex/controlPanel.ts b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Hex/controlPanel.ts index 2f9293c52..8865ed005 100644 --- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Hex/controlPanel.ts +++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Hex/controlPanel.ts @@ -53,8 +53,8 @@ const config: ControlPanelConfig = { { label: t('Map'), controlSetRows: [ - [mapboxStyle, viewport], - ['color_scheme'], + [mapboxStyle], + ['color_scheme', viewport], [autozoom], [gridSize], [extruded], diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Path/controlPanel.ts b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Path/controlPanel.ts index 80691efa6..b0403b359 100644 --- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Path/controlPanel.ts +++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Path/controlPanel.ts @@ -67,7 +67,8 @@ const config: ControlPanelConfig = { label: t('Map'), expanded: true, controlSetRows: [ - [mapboxStyle, viewport], + [mapboxStyle], + [viewport], ['color_picker'], [lineWidth], [ diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Scatter/controlPanel.ts b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Scatter/controlPanel.ts index ef3d45a95..9afeb1b41 100644 --- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Scatter/controlPanel.ts +++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Scatter/controlPanel.ts @@ -62,10 +62,7 @@ const config: ControlPanelConfig = { { label: t('Map'), expanded: true, - controlSetRows: [ - [mapboxStyle, viewport], - [autozoom, null], - ], + controlSetRows: [[mapboxStyle], [autozoom, viewport]], }, { label: t('Point Size'), diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Screengrid/controlPanel.ts b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Screengrid/controlPanel.ts index caf052581..82aeda174 100644 --- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Screengrid/controlPanel.ts +++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Screengrid/controlPanel.ts @@ -52,10 +52,7 @@ const config: ControlPanelConfig = { }, { label: t('Map'), - controlSetRows: [ - [mapboxStyle, viewport], - [autozoom, null], - ], + controlSetRows: [[mapboxStyle], [autozoom, viewport]], }, { label: t('Grid'), diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/Shared_DeckGL.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/Shared_DeckGL.jsx index 9a123e91c..5b307efd9 100644 --- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/Shared_DeckGL.jsx +++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/Shared_DeckGL.jsx @@ -25,6 +25,7 @@ import { isFeatureEnabled, t, validateNonEmpty, + validateMapboxStylesUrl, } from '@superset-ui/core'; import { D3_FORMAT_OPTIONS, sharedControls } from '@superset-ui/chart-controls'; import { columnChoices, PRIMARY_COLOR } from './controls'; @@ -370,6 +371,8 @@ export const mapboxStyle = { label: t('Map Style'), clearable: false, renderTrigger: true, + freeForm: true, + validators: [validateMapboxStylesUrl], choices: [ ['mapbox://styles/mapbox/streets-v9', t('Streets')], ['mapbox://styles/mapbox/dark-v9', t('Dark')], @@ -379,7 +382,10 @@ export const mapboxStyle = { ['mapbox://styles/mapbox/outdoors-v9', t('Outdoors')], ], default: 'mapbox://styles/mapbox/light-v9', - description: t('Base layer map style'), + description: t( + 'Base layer map style. See Mapbox documentation: %s', + 'https://docs.mapbox.com/help/glossary/style-url/', + ), }, };