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

beto pushed a commit to branch dbt-metricflow
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/dbt-metricflow by this push:
     new 0917424473 Small fixes
0917424473 is described below

commit 091742447394653b007300eacd1f15f5ca2f6926
Author: Beto Dealmeida <[email protected]>
AuthorDate: Fri Oct 10 15:06:10 2025 -0400

    Small fixes
---
 .../controls/SemanticLayerVerification.tsx         | 166 +++++++++++++++++----
 1 file changed, 138 insertions(+), 28 deletions(-)

diff --git 
a/superset-frontend/src/explore/components/controls/SemanticLayerVerification.tsx
 
b/superset-frontend/src/explore/components/controls/SemanticLayerVerification.tsx
index 444122dd39..8b00c94827 100644
--- 
a/superset-frontend/src/explore/components/controls/SemanticLayerVerification.tsx
+++ 
b/superset-frontend/src/explore/components/controls/SemanticLayerVerification.tsx
@@ -257,7 +257,7 @@ export async function callValidationAPI(
   // Create a key for this specific control to prevent duplicate requests
   const controlKey = `${datasource.id}_${controlName || 'unknown'}`;
   const now = Date.now();
-  
+
   // Check if we already have a pending request for the same parameters
   if (apiCallCache.has(cacheKey)) {
     console.log(`[API] Reusing cached request for control: ${controlName}`);
@@ -266,27 +266,39 @@ export async function callValidationAPI(
 
   // Check if we have a pending request for this specific control
   if (pendingRequests.has(controlKey)) {
-    console.log(`[API] Request already pending for control: ${controlName}, 
waiting...`);
+    console.log(
+      `[API] Request already pending for control: ${controlName}, waiting...`,
+    );
     return pendingRequests.get(controlKey)!;
   }
 
   // Enhanced deduplication: check if we have an identical request in flight
   const requestSignature = 
`${datasource.id}_${selectedDimensions.join(',')}_${selectedMetrics.join(',')}`;
-  
+
   // If we have an identical request already cached, return it
   if (apiCallCache.has(requestSignature)) {
-    console.log(`[API] Identical request found for control: ${controlName}, 
reusing...`);
+    console.log(
+      `[API] Identical request found for control: ${controlName}, reusing...`,
+    );
     return apiCallCache.get(requestSignature)!;
   }
 
   // Time-based deduplication: if we just made a request for this control, 
wait a bit
   const lastTime = lastRequestTime.get(controlKey) || 0;
-  if (now - lastTime < 50) { // 50ms debounce
-    console.log(`[API] Request too soon for control: ${controlName}, 
debouncing...`);
+  if (now - lastTime < 50) {
+    // 50ms debounce
+    console.log(
+      `[API] Request too soon for control: ${controlName}, debouncing...`,
+    );
     return new Promise(resolve => {
       setTimeout(async () => {
         // Try again after debounce
-        const result = await callValidationAPI(datasource, selectedDimensions, 
selectedMetrics, controlName);
+        const result = await callValidationAPI(
+          datasource,
+          selectedDimensions,
+          selectedMetrics,
+          controlName,
+        );
         resolve(result);
       }, 50);
     });
@@ -314,10 +326,10 @@ export async function callValidationAPI(
 
     // Cache the promise for the exact same parameters
     apiCallCache.set(cacheKey, apiPromise);
-    
+
     // Cache by request signature for identical requests
     apiCallCache.set(requestSignature, apiPromise);
-    
+
     // Also track this request for this specific control
     pendingRequests.set(controlKey, apiPromise);
 
@@ -371,7 +383,50 @@ export function createMetricsVerification(controlName?: 
string): AsyncVerify {
 
     console.log(`[MetricsVerification] Query fields:`, queryFields);
     console.log(`[MetricsVerification] Form data:`, form_data);
-    console.log(`[MetricsVerification] Synthetic form data:`, 
syntheticFormData);
+    console.log(
+      `[MetricsVerification] Synthetic form data:`,
+      syntheticFormData,
+    );
+
+    // If no metrics or dimensions are selected, enable all options
+    if (
+      queryFields.dimensions.length === 0 &&
+      queryFields.metrics.length === 0
+    ) {
+      console.log(`[MetricsVerification] No selections, enabling all options`);
+      const dataset = datasource as Dataset;
+
+      // Enable all metrics
+      const updatedDatasourceMetrics = dataset.metrics?.map((metric: any) => ({
+        ...metric,
+        isDisabled: false,
+      }));
+
+      // Enable all columns
+      const updatedDatasourceColumns = dataset.columns?.map((column: any) => ({
+        ...column,
+        isDisabled: false,
+      }));
+
+      const updatedDatasource = {
+        ...dataset,
+        metrics: updatedDatasourceMetrics,
+        columns: updatedDatasourceColumns,
+      };
+
+      // Update Redux store
+      if (
+        props.actions &&
+        typeof props.actions.syncDatasourceMetadata === 'function'
+      ) {
+        props.actions.syncDatasourceMetadata(updatedDatasource);
+      }
+
+      return {
+        savedMetrics,
+        datasource: updatedDatasource,
+      };
+    }
 
     const validationResult = await callValidationAPI(
       datasource as Dataset,
@@ -406,13 +461,18 @@ export function createColumnsVerification(controlName?: 
string): AsyncVerify {
     }
 
     // Handle initial verification for fresh charts
-    const triggerInitialVerification = (props as 
any).triggerInitialVerification;
+    const { triggerInitialVerification } = props as any;
     const datasourceControlKey = `${datasource?.id}_${controlName}`;
-    
-    if (triggerInitialVerification && 
!initialVerificationDone.has(datasourceControlKey)) {
-      console.log(`[ColumnsVerification] Triggering initial verification for 
control: ${controlName}`);
+
+    if (
+      triggerInitialVerification &&
+      !initialVerificationDone.has(datasourceControlKey)
+    ) {
+      console.log(
+        `[ColumnsVerification] Triggering initial verification for control: 
${controlName}`,
+      );
       initialVerificationDone.add(datasourceControlKey);
-      
+
       // Trigger initial verification with empty form data
       const initialResult = await callValidationAPI(
         datasource as Dataset,
@@ -420,7 +480,7 @@ export function createColumnsVerification(controlName?: 
string): AsyncVerify {
         [],
         controlName,
       );
-      
+
       if (initialResult) {
         // Mark all options as enabled/disabled based on initial result
         const validDimensionNames = new Set(initialResult.dimensions);
@@ -463,7 +523,53 @@ export function createColumnsVerification(controlName?: 
string): AsyncVerify {
 
     console.log(`[ColumnsVerification] Query fields:`, queryFields);
     console.log(`[ColumnsVerification] Form data:`, form_data);
-    console.log(`[ColumnsVerification] Synthetic form data:`, 
syntheticFormData);
+    console.log(
+      `[ColumnsVerification] Synthetic form data:`,
+      syntheticFormData,
+    );
+
+    // If no metrics or dimensions are selected, enable all options
+    if (
+      queryFields.dimensions.length === 0 &&
+      queryFields.metrics.length === 0
+    ) {
+      console.log(`[ColumnsVerification] No selections, enabling all options`);
+      const dataset = datasource as Dataset;
+
+      // Enable all options
+      const updatedOptions = options.map((option: any) => ({
+        ...option,
+        isDisabled: false,
+      }));
+
+      // Enable all metrics
+      const updatedDatasourceMetrics = dataset.metrics?.map((metric: any) => ({
+        ...metric,
+        isDisabled: false,
+      }));
+
+      // Enable all columns
+      const updatedDatasourceColumns = dataset.columns?.map((column: any) => ({
+        ...column,
+        isDisabled: false,
+      }));
+
+      const updatedDatasource = {
+        ...dataset,
+        metrics: updatedDatasourceMetrics,
+        columns: updatedDatasourceColumns,
+      };
+
+      // Update Redux store
+      if (actions && typeof actions.syncDatasourceMetadata === 'function') {
+        actions.syncDatasourceMetadata(updatedDatasource);
+      }
+
+      return {
+        options: updatedOptions,
+        datasource: updatedDatasource,
+      };
+    }
 
     const validationResult = await callValidationAPI(
       datasource as Dataset,
@@ -508,17 +614,21 @@ export function createSemanticLayerOnChange(
   return (value: JsonValue, props: ControlPropsWithExtras) => {
     const { actions, form_data } = props;
 
-    // Trigger re-rendering of affected controls by updating their values
-    // This forces the verification to run again
-    affectedControls.forEach(controlField => {
-      if (
-        controlField !== controlName &&
-        form_data &&
-        form_data[controlField]
-      ) {
-        actions.setControlValue(controlField, form_data[controlField], []);
-      }
-    });
+    // Delay re-verification to allow Redux state to propagate first
+    // This prevents race conditions where other controls verify with stale 
form_data
+    setTimeout(() => {
+      // Trigger re-rendering of affected controls by updating their values
+      // This forces the verification to run again
+      affectedControls.forEach(controlField => {
+        if (
+          controlField !== controlName &&
+          form_data &&
+          form_data[controlField]
+        ) {
+          actions.setControlValue(controlField, form_data[controlField], []);
+        }
+      });
+    }, 0);
   };
 }
 

Reply via email to