You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by be...@apache.org on 2026/02/03 21:08:13 UTC

(superset) branch sl-4-frontend created (now 274d1c9a395)

This is an automated email from the ASF dual-hosted git repository.

beto pushed a change to branch sl-4-frontend
in repository https://gitbox.apache.org/repos/asf/superset.git


      at 274d1c9a395 feat(semantic-layer): add frontend support for semantic views

This branch includes the following new commits:

     new 274d1c9a395 feat(semantic-layer): add frontend support for semantic views

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(superset) 01/01: feat(semantic-layer): add frontend support for semantic views

Posted by be...@apache.org.
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 <ro...@dealmeida.net>
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 <no...@anthropic.com>
---
 .../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,