korbit-ai[bot] commented on code in PR #33106:
URL: https://github.com/apache/superset/pull/33106#discussion_r2040432398


##########
superset-frontend/src/dashboard/reducers/dashboardState.js:
##########
@@ -209,12 +209,17 @@ export default function dashboardStateReducer(state = {}, 
action) {
       };
     },
     [SET_ACTIVE_TAB]() {
-      const newActiveTabs = new Set(state.activeTabs);
-      newActiveTabs.delete(action.prevTabId);
-      newActiveTabs.add(action.tabId);
+      const newActiveTabs = new Set(state.activeTabs).difference(
+        new Set(action.inactiveTabs.concat(action.prevTabId)),
+      );

Review Comment:
   ### Invalid Set operation method <sub>![category 
Functionality](https://img.shields.io/badge/Functionality-0284c7)</sub>
   
   <details>
     <summary>Tell me more</summary>
   
   ###### What is the issue?
   Using the Set.difference() method which does not exist in JavaScript's 
native Set implementation. This will cause a runtime error.
   
   ###### Why this matters
   The code will throw a TypeError when executed as 'difference' is not a 
method of the JavaScript Set object, causing the tab management functionality 
to break.
   
   ###### Suggested change ∙ *Feature Preview*
   Replace with standard Set operations using Array.filter(). Here's the 
corrected version:
   ```javascript
   const newActiveTabs = new Set(
     Array.from(state.activeTabs).filter(
       tab => !action.inactiveTabs.includes(tab) && tab !== action.prevTabId
     )
   );
   ```
   
   
   ###### Provide feedback to improve future suggestions
   [![Nice 
Catch](https://img.shields.io/badge/👍%20Nice%20Catch-71BC78)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/12e58d69-c1ce-4211-b1d6-fc0722d6bc25/upvote)
 
[![Incorrect](https://img.shields.io/badge/👎%20Incorrect-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/12e58d69-c1ce-4211-b1d6-fc0722d6bc25?what_not_true=true)
  [![Not in 
Scope](https://img.shields.io/badge/👎%20Out%20of%20PR%20scope-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/12e58d69-c1ce-4211-b1d6-fc0722d6bc25?what_out_of_scope=true)
 [![Not in coding 
standard](https://img.shields.io/badge/👎%20Not%20in%20our%20standards-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/12e58d69-c1ce-4211-b1d6-fc0722d6bc25?what_not_in_standard=true)
 
[![Other](https://img.shields.io/badge/👎%20Other-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/12e58d69-c1ce-4211-b1d6-fc0722d6bc25)
   </details>
   
   <sub>
   
   💬 Looking for more details? Reply to this comment to chat with Korbit.
   </sub>
   
   <!--- korbi internal id:e0f3d330-7f3e-4977-baf7-61d5dfe2fc84 -->
   
   
   [](e0f3d330-7f3e-4977-baf7-61d5dfe2fc84)



##########
superset-frontend/src/dashboard/actions/dashboardState.js:
##########
@@ -659,7 +659,41 @@ export function setDirectPathToChild(path) {
 
 export const SET_ACTIVE_TAB = 'SET_ACTIVE_TAB';
 export function setActiveTab(tabId, prevTabId) {
-  return { type: SET_ACTIVE_TAB, tabId, prevTabId };
+  return (dispatch, getState) => {
+    const { dashboardLayout, dashboardState } = getState();
+    const { activeTabs, inactiveTabs: prevInactiveTabs } = dashboardState;
+    const { present: currentLayout } = dashboardLayout;
+    const restoredTabs = [];
+    const queue = [tabId];
+    while (queue.length > 0) {
+      const seek = queue.shift();
+      const found =
+        prevInactiveTabs?.filter(inactiveTabId =>
+          currentLayout[inactiveTabId]?.parents
+            .filter(id => id.startsWith('TAB-'))
+            .slice(-1)
+            .includes(seek),
+        ) ?? [];
+
+      restoredTabs.push(...found);
+      queue.push(...found);
+    }

Review Comment:
   ### Potential infinite loop in tab restoration <sub>![category 
Functionality](https://img.shields.io/badge/Functionality-0284c7)</sub>
   
   <details>
     <summary>Tell me more</summary>
   
   ###### What is the issue?
   The tab restoration logic may enter an infinite loop if there is a circular 
parent-child relationship in the tab structure.
   
   ###### Why this matters
   This could cause the browser to hang or crash if there are any cycles in the 
tab hierarchy, severely impacting user experience.
   
   ###### Suggested change ∙ *Feature Preview*
   Add a visited set to prevent processing the same tab multiple times:
   ```javascript
   const restoredTabs = [];
   const queue = [tabId];
   const visited = new Set([tabId]);
   while (queue.length > 0) {
     const seek = queue.shift();
     const found =
       prevInactiveTabs?.filter(inactiveTabId =>
         currentLayout[inactiveTabId]?.parents
           .filter(id => id.startsWith('TAB-'))
           .slice(-1)
           .includes(seek),
       ) ?? [];
   
     for (const tab of found) {
       if (!visited.has(tab)) {
         visited.add(tab);
         restoredTabs.push(tab);
         queue.push(tab);
       }
     }
   }
   ```
   
   
   ###### Provide feedback to improve future suggestions
   [![Nice 
Catch](https://img.shields.io/badge/👍%20Nice%20Catch-71BC78)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/3a441ade-8961-4120-adbe-ffdfe04c0bd2/upvote)
 
[![Incorrect](https://img.shields.io/badge/👎%20Incorrect-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/3a441ade-8961-4120-adbe-ffdfe04c0bd2?what_not_true=true)
  [![Not in 
Scope](https://img.shields.io/badge/👎%20Out%20of%20PR%20scope-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/3a441ade-8961-4120-adbe-ffdfe04c0bd2?what_out_of_scope=true)
 [![Not in coding 
standard](https://img.shields.io/badge/👎%20Not%20in%20our%20standards-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/3a441ade-8961-4120-adbe-ffdfe04c0bd2?what_not_in_standard=true)
 
[![Other](https://img.shields.io/badge/👎%20Other-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/3a441ade-8961-4120-adbe-ffdfe04c0bd2)
   </details>
   
   <sub>
   
   💬 Looking for more details? Reply to this comment to chat with Korbit.
   </sub>
   
   <!--- korbi internal id:7355396a-e336-425b-af30-4d13321aeaf7 -->
   
   
   [](7355396a-e336-425b-af30-4d13321aeaf7)



##########
superset-frontend/src/dashboard/actions/dashboardState.js:
##########
@@ -659,7 +659,41 @@
 
 export const SET_ACTIVE_TAB = 'SET_ACTIVE_TAB';
 export function setActiveTab(tabId, prevTabId) {
-  return { type: SET_ACTIVE_TAB, tabId, prevTabId };
+  return (dispatch, getState) => {
+    const { dashboardLayout, dashboardState } = getState();
+    const { activeTabs, inactiveTabs: prevInactiveTabs } = dashboardState;
+    const { present: currentLayout } = dashboardLayout;
+    const restoredTabs = [];
+    const queue = [tabId];
+    while (queue.length > 0) {
+      const seek = queue.shift();
+      const found =
+        prevInactiveTabs?.filter(inactiveTabId =>
+          currentLayout[inactiveTabId]?.parents
+            .filter(id => id.startsWith('TAB-'))
+            .slice(-1)
+            .includes(seek),
+        ) ?? [];
+
+      restoredTabs.push(...found);
+      queue.push(...found);
+    }
+    const tabIds = restoredTabs ? [tabId].concat(restoredTabs) : [tabId];
+    const inactiveTabs =
+      Boolean(prevTabId) && tabId !== prevTabId
+        ? activeTabs.filter(
+            activeTabId =>
+              activeTabId !== prevTabId &&
+              currentLayout[activeTabId]?.parents.includes(prevTabId),
+          )
+        : [];

Review Comment:
   ### Unclear Tab Inactivation Logic <sub>![category 
Readability](https://img.shields.io/badge/Readability-0284c7)</sub>
   
   <details>
     <summary>Tell me more</summary>
   
   ###### What is the issue?
   The logic for determining inactive tabs uses multiple conditions in a 
ternary operator combined with a filter, making it hard to understand the 
criteria for tab inactivation.
   
   ###### Why this matters
   Complex boolean logic in a single expression makes it difficult to 
understand and modify the tab inactivation rules.
   
   ###### Suggested change ∙ *Feature Preview*
   ```javascript
   const shouldProcessInactiveTabs = Boolean(prevTabId) && tabId !== prevTabId;
   
   const getInactiveTabsForPrevTab = () => 
     activeTabs.filter(activeTabId => 
       activeTabId !== prevTabId && 
       currentLayout[activeTabId]?.parents.includes(prevTabId)
     );
   
   const inactiveTabs = shouldProcessInactiveTabs ? getInactiveTabsForPrevTab() 
: [];
   ```
   
   
   ###### Provide feedback to improve future suggestions
   [![Nice 
Catch](https://img.shields.io/badge/👍%20Nice%20Catch-71BC78)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/04c91584-b153-41d3-be14-f5f8e4ba3bf5/upvote)
 
[![Incorrect](https://img.shields.io/badge/👎%20Incorrect-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/04c91584-b153-41d3-be14-f5f8e4ba3bf5?what_not_true=true)
  [![Not in 
Scope](https://img.shields.io/badge/👎%20Out%20of%20PR%20scope-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/04c91584-b153-41d3-be14-f5f8e4ba3bf5?what_out_of_scope=true)
 [![Not in coding 
standard](https://img.shields.io/badge/👎%20Not%20in%20our%20standards-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/04c91584-b153-41d3-be14-f5f8e4ba3bf5?what_not_in_standard=true)
 
[![Other](https://img.shields.io/badge/👎%20Other-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/04c91584-b153-41d3-be14-f5f8e4ba3bf5)
   </details>
   
   <sub>
   
   💬 Looking for more details? Reply to this comment to chat with Korbit.
   </sub>
   
   <!--- korbi internal id:df971131-8c71-4166-8a64-cda093bacd8b -->
   
   
   [](df971131-8c71-4166-8a64-cda093bacd8b)



##########
superset-frontend/src/dashboard/actions/dashboardState.js:
##########
@@ -659,7 +659,41 @@
 
 export const SET_ACTIVE_TAB = 'SET_ACTIVE_TAB';
 export function setActiveTab(tabId, prevTabId) {
-  return { type: SET_ACTIVE_TAB, tabId, prevTabId };
+  return (dispatch, getState) => {
+    const { dashboardLayout, dashboardState } = getState();
+    const { activeTabs, inactiveTabs: prevInactiveTabs } = dashboardState;
+    const { present: currentLayout } = dashboardLayout;
+    const restoredTabs = [];
+    const queue = [tabId];
+    while (queue.length > 0) {
+      const seek = queue.shift();
+      const found =
+        prevInactiveTabs?.filter(inactiveTabId =>
+          currentLayout[inactiveTabId]?.parents
+            .filter(id => id.startsWith('TAB-'))
+            .slice(-1)
+            .includes(seek),
+        ) ?? [];
+
+      restoredTabs.push(...found);
+      queue.push(...found);
+    }

Review Comment:
   ### Complex Business Logic in Action Creator <sub>![category 
Design](https://img.shields.io/badge/Design-0d9488)</sub>
   
   <details>
     <summary>Tell me more</summary>
   
   ###### What is the issue?
   The tab restoration logic is embedded directly in the action creator, 
violating Single Responsibility Principle and making the code harder to test 
and maintain.
   
   ###### Why this matters
   Having complex business logic in action creators makes the code harder to 
test, maintain, and reuse. The tab restoration logic should be extracted into a 
separate service or utility function.
   
   ###### Suggested change ∙ *Feature Preview*
   Extract the tab restoration logic into a separate utility function:
   ```javascript
   const findTabsToRestore = (tabId, prevInactiveTabs, currentLayout) => {
     const restoredTabs = [];
     const queue = [tabId];
     while (queue.length > 0) {
       const seek = queue.shift();
       const found = prevInactiveTabs?.filter(/* ... */) ?? [];
       restoredTabs.push(...found);
       queue.push(...found);
     }
     return restoredTabs;
   };
   
   export function setActiveTab(tabId, prevTabId) {
     return (dispatch, getState) => {
       const { dashboardLayout, dashboardState } = getState();
       const restoredTabs = findTabsToRestore(tabId, 
dashboardState.inactiveTabs, dashboardLayout.present);
       // ... rest of the logic
     };
   }
   ```
   
   
   ###### Provide feedback to improve future suggestions
   [![Nice 
Catch](https://img.shields.io/badge/👍%20Nice%20Catch-71BC78)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/b481cd3e-8b16-486d-b4e9-3ca8ccd65092/upvote)
 
[![Incorrect](https://img.shields.io/badge/👎%20Incorrect-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/b481cd3e-8b16-486d-b4e9-3ca8ccd65092?what_not_true=true)
  [![Not in 
Scope](https://img.shields.io/badge/👎%20Out%20of%20PR%20scope-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/b481cd3e-8b16-486d-b4e9-3ca8ccd65092?what_out_of_scope=true)
 [![Not in coding 
standard](https://img.shields.io/badge/👎%20Not%20in%20our%20standards-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/b481cd3e-8b16-486d-b4e9-3ca8ccd65092?what_not_in_standard=true)
 
[![Other](https://img.shields.io/badge/👎%20Other-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/b481cd3e-8b16-486d-b4e9-3ca8ccd65092)
   </details>
   
   <sub>
   
   💬 Looking for more details? Reply to this comment to chat with Korbit.
   </sub>
   
   <!--- korbi internal id:adf02420-94db-4faf-a7ad-d04744c07a92 -->
   
   
   [](adf02420-94db-4faf-a7ad-d04744c07a92)



##########
superset-frontend/src/dashboard/reducers/dashboardState.js:
##########
@@ -209,12 +209,17 @@
       };
     },
     [SET_ACTIVE_TAB]() {
-      const newActiveTabs = new Set(state.activeTabs);
-      newActiveTabs.delete(action.prevTabId);
-      newActiveTabs.add(action.tabId);
+      const newActiveTabs = new Set(state.activeTabs).difference(
+        new Set(action.inactiveTabs.concat(action.prevTabId)),
+      );
+      const newInactiveTabs = new Set(state.inactiveTabs)
+        .difference(new Set(action.tabIds))
+        .union(new Set(action.inactiveTabs));

Review Comment:
   ### Complex Set Operations Chain <sub>![category 
Readability](https://img.shields.io/badge/Readability-0284c7)</sub>
   
   <details>
     <summary>Tell me more</summary>
   
   ###### What is the issue?
   The Set operations chain is unnecessarily complex and hard to follow, making 
the tab state management logic difficult to understand at a glance.
   
   ###### Why this matters
   Complex chaining of Set operations reduces code maintainability and makes 
debugging tab state issues more challenging.
   
   ###### Suggested change ∙ *Feature Preview*
   ```javascript
         // First, create the sets
         const inactiveTabsSet = new Set(action.inactiveTabs);
         const prevTabSet = new Set([action.prevTabId]);
         const tabIdsSet = new Set(action.tabIds);
         
         // Then perform operations clearly
         const newActiveTabs = new Set(state.activeTabs);
         // Remove all inactive tabs and previous tab
         inactiveTabsSet.forEach(tab => newActiveTabs.delete(tab));
         newActiveTabs.delete(action.prevTabId);
         // Add new tab IDs
         tabIdsSet.forEach(tab => newActiveTabs.add(tab));
         
         // Similarly for inactive tabs
         const newInactiveTabs = new Set(state.inactiveTabs);
         tabIdsSet.forEach(tab => newInactiveTabs.delete(tab));
         inactiveTabsSet.forEach(tab => newInactiveTabs.add(tab));
   ```
   
   
   ###### Provide feedback to improve future suggestions
   [![Nice 
Catch](https://img.shields.io/badge/👍%20Nice%20Catch-71BC78)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/94ffd1a7-0fed-42e6-9475-f72a6f426114/upvote)
 
[![Incorrect](https://img.shields.io/badge/👎%20Incorrect-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/94ffd1a7-0fed-42e6-9475-f72a6f426114?what_not_true=true)
  [![Not in 
Scope](https://img.shields.io/badge/👎%20Out%20of%20PR%20scope-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/94ffd1a7-0fed-42e6-9475-f72a6f426114?what_out_of_scope=true)
 [![Not in coding 
standard](https://img.shields.io/badge/👎%20Not%20in%20our%20standards-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/94ffd1a7-0fed-42e6-9475-f72a6f426114?what_not_in_standard=true)
 
[![Other](https://img.shields.io/badge/👎%20Other-white)](https://app.korbit.ai/feedback/aa91ff46-6083-4491-9416-b83dd1994b51/94ffd1a7-0fed-42e6-9475-f72a6f426114)
   </details>
   
   <sub>
   
   💬 Looking for more details? Reply to this comment to chat with Korbit.
   </sub>
   
   <!--- korbi internal id:2afb136e-8e7d-4b96-abfc-fd51653084cf -->
   
   
   [](2afb136e-8e7d-4b96-abfc-fd51653084cf)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to