This is an automated email from the ASF dual-hosted git repository. beto pushed a commit to branch sl-4-frontend in repository https://gitbox.apache.org/repos/asf/superset.git
commit 274d1c9a395393958abd4dc1ed36aca80c0c1eec Author: Beto Dealmeida <[email protected]> AuthorDate: Mon Feb 2 17:32:34 2026 -0500 feat(semantic-layer): add frontend support for semantic views Update frontend to support semantic layer datasources: - Add SemanticView to DatasourceType enum - Extend DatasourceKey to handle semantic_view type - Update datasource ID type to support string UUIDs - Update DrillBy modal for semantic view compatibility - Update explore utilities for semantic view form data Co-Authored-By: Claude Opus 4.5 <[email protected]> --- .../superset-ui-core/src/query/DatasourceKey.ts | 19 +++++++++++++++---- .../superset-ui-core/src/query/types/Datasource.ts | 3 ++- .../superset-ui-core/src/query/types/Query.ts | 2 +- .../src/components/Chart/DrillBy/DrillByModal.tsx | 9 +++++++-- superset-frontend/src/dashboard/types.ts | 2 +- .../src/explore/actions/saveModalActions.ts | 6 ++++-- .../src/explore/exploreUtils/formData.ts | 8 ++++---- 7 files changed, 34 insertions(+), 15 deletions(-) diff --git a/superset-frontend/packages/superset-ui-core/src/query/DatasourceKey.ts b/superset-frontend/packages/superset-ui-core/src/query/DatasourceKey.ts index 38a38e10b13..5eb22613b40 100644 --- a/superset-frontend/packages/superset-ui-core/src/query/DatasourceKey.ts +++ b/superset-frontend/packages/superset-ui-core/src/query/DatasourceKey.ts @@ -19,16 +19,27 @@ import { DatasourceType } from './types/Datasource'; +const DATASOURCE_TYPE_MAP: Record<string, DatasourceType> = { + table: DatasourceType.Table, + query: DatasourceType.Query, + dataset: DatasourceType.Dataset, + sl_table: DatasourceType.SlTable, + saved_query: DatasourceType.SavedQuery, + semantic_view: DatasourceType.SemanticView, +}; + export default class DatasourceKey { - readonly id: number; + readonly id: number | string; readonly type: DatasourceType; constructor(key: string) { const [idStr, typeStr] = key.split('__'); - this.id = parseInt(idStr, 10); - this.type = DatasourceType.Table; // default to SqlaTable model - this.type = typeStr === 'query' ? DatasourceType.Query : this.type; + // Only parse as integer if the entire string is numeric + // (parseInt would incorrectly parse "85d3139f..." as 85) + const isNumeric = /^\d+$/.test(idStr); + this.id = isNumeric ? parseInt(idStr, 10) : idStr; + this.type = DATASOURCE_TYPE_MAP[typeStr] ?? DatasourceType.Table; } public toString() { diff --git a/superset-frontend/packages/superset-ui-core/src/query/types/Datasource.ts b/superset-frontend/packages/superset-ui-core/src/query/types/Datasource.ts index 47902cf07ae..8fbf63aa4b3 100644 --- a/superset-frontend/packages/superset-ui-core/src/query/types/Datasource.ts +++ b/superset-frontend/packages/superset-ui-core/src/query/types/Datasource.ts @@ -26,6 +26,7 @@ export enum DatasourceType { Dataset = 'dataset', SlTable = 'sl_table', SavedQuery = 'saved_query', + SemanticView = 'semantic_view', } export interface Currency { @@ -37,7 +38,7 @@ export interface Currency { * Datasource metadata. */ export interface Datasource { - id: number; + id: number | string; name: string; type: DatasourceType; columns: Column[]; diff --git a/superset-frontend/packages/superset-ui-core/src/query/types/Query.ts b/superset-frontend/packages/superset-ui-core/src/query/types/Query.ts index 14d4e2273b2..c1ecc99fae5 100644 --- a/superset-frontend/packages/superset-ui-core/src/query/types/Query.ts +++ b/superset-frontend/packages/superset-ui-core/src/query/types/Query.ts @@ -159,7 +159,7 @@ export interface QueryObject export interface QueryContext { datasource: { - id: number; + id: number | string; type: DatasourceType; }; /** Force refresh of all queries */ diff --git a/superset-frontend/src/components/Chart/DrillBy/DrillByModal.tsx b/superset-frontend/src/components/Chart/DrillBy/DrillByModal.tsx index 6245945de45..8a62974ec30 100644 --- a/superset-frontend/src/components/Chart/DrillBy/DrillByModal.tsx +++ b/superset-frontend/src/components/Chart/DrillBy/DrillByModal.tsx @@ -90,11 +90,16 @@ const ModalFooter = ({ formData, closeModal }: ModalFooterProps) => { findPermission('can_explore', 'Superset', state.user?.roles), ); - const [datasource_id, datasource_type] = formData.datasource.split('__'); + const [datasourceIdStr, datasource_type] = formData.datasource.split('__'); + // Try to parse as integer, fall back to string (UUID) if NaN + const parsedDatasourceId = parseInt(datasourceIdStr, 10); + const datasource_id = Number.isNaN(parsedDatasourceId) + ? datasourceIdStr + : parsedDatasourceId; useEffect(() => { // short circuit if the user is embedded as explore is not available if (isEmbedded()) return; - postFormData(Number(datasource_id), datasource_type, formData, 0) + postFormData(datasource_id, datasource_type, formData, 0) .then(key => { setUrl( `/explore/?form_data_key=${key}&dashboard_page_id=${dashboardPageId}`, diff --git a/superset-frontend/src/dashboard/types.ts b/superset-frontend/src/dashboard/types.ts index b2bde968368..162031c695c 100644 --- a/superset-frontend/src/dashboard/types.ts +++ b/superset-frontend/src/dashboard/types.ts @@ -272,7 +272,7 @@ export type Slice = { changed_on: number; changed_on_humanized: string; modified: string; - datasource_id: number; + datasource_id: number | string; datasource_type: DatasourceType; datasource_url: string; datasource_name: string; diff --git a/superset-frontend/src/explore/actions/saveModalActions.ts b/superset-frontend/src/explore/actions/saveModalActions.ts index 978c5cb09ba..24b4d7c878a 100644 --- a/superset-frontend/src/explore/actions/saveModalActions.ts +++ b/superset-frontend/src/explore/actions/saveModalActions.ts @@ -144,12 +144,14 @@ export const getSlicePayload = async ( ...adhocFilters, dashboards, }; - let datasourceId = 0; + let datasourceId: number | string = 0; let datasourceType: DatasourceType = DatasourceType.Table; if (formData.datasource) { const [id, typeString] = formData.datasource.split('__'); - datasourceId = parseInt(id, 10); + // Try to parse as integer, fall back to string (UUID) if NaN + const parsedId = parseInt(id, 10); + datasourceId = Number.isNaN(parsedId) ? id : parsedId; const formattedTypeString = typeString.charAt(0).toUpperCase() + typeString.slice(1); diff --git a/superset-frontend/src/explore/exploreUtils/formData.ts b/superset-frontend/src/explore/exploreUtils/formData.ts index 9a83d8fd8da..994b7f0b4c5 100644 --- a/superset-frontend/src/explore/exploreUtils/formData.ts +++ b/superset-frontend/src/explore/exploreUtils/formData.ts @@ -20,7 +20,7 @@ import { SupersetClient, JsonObject, JsonResponse } from '@superset-ui/core'; import { sanitizeFormData } from 'src/utils/sanitizeFormData'; type Payload = { - datasource_id: number; + datasource_id: number | string; datasource_type: string; form_data: string; chart_id?: number; @@ -36,7 +36,7 @@ const assembleEndpoint = (key?: string, tabId?: string) => { }; const assemblePayload = ( - datasourceId: number, + datasourceId: number | string, datasourceType: string, formData: JsonObject, chartId?: number, @@ -53,7 +53,7 @@ const assemblePayload = ( }; export const postFormData = ( - datasourceId: number, + datasourceId: number | string, datasourceType: string, formData: JsonObject, chartId?: number, @@ -70,7 +70,7 @@ export const postFormData = ( }).then((r: JsonResponse) => r.json.key); export const putFormData = ( - datasourceId: number, + datasourceId: number | string, datasourceType: string, key: string, formData: JsonObject,
