codeant-ai-for-open-source[bot] commented on code in PR #38584:
URL: https://github.com/apache/superset/pull/38584#discussion_r3662412118


##########
superset-frontend/src/explore/components/SaveModal.tsx:
##########
@@ -371,7 +371,10 @@ const SaveModal = ({
       if (dashboardId) {
         try {
           const result = (await loadDashboard(dashboardId)) as Dashboard;
-          if (canUserEditDashboard(result, user)) {
+          if (
+            canUserEditDashboard(result, user) &&
+            !result.is_managed_externally
+          ) {
             setDashboard({ label: result.dashboard_title, value: result.id });
             await loadTabs(dashboardId);
           }

Review Comment:
   **Suggestion:** When `dashboardIdProp` changes to an externally managed or 
non-editable dashboard while the modal remains mounted, this condition simply 
skips the setters, leaving the previously selected dashboard, tabs, and tab 
selection in state. The user can therefore still save using the stale editable 
dashboard. Clear `dashboard`, `tabsData`, and `selectedTab` before loading the 
new dashboard or when the new dashboard fails this condition, and cancel stale 
asynchronous initialization results. [stale reference]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ Charts can be saved to a stale dashboard selection.
   - ❌ Managed-dashboard protection can be bypassed through stale state.
   - ⚠️ Tabs and redirect anchors can reference the old dashboard.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Open Explore with the save modal visible while `ExploreViewContainer` 
renders
   `SaveModal` at
   
`superset-frontend/src/explore/components/ExploreViewContainer/index.tsx:1087-1094`;
 the
   modal remains mounted while `isSaveModalVisible` stays true.
   
   2. Start with an editable dashboard ID supplied through `props.dashboardId`, 
which is
   derived from Explore form data at
   
`superset-frontend/src/explore/components/ExploreViewContainer/index.tsx:1194-1224`.
   `SaveModal` loads that dashboard and stores it in `dashboard` at
   `superset-frontend/src/explore/components/SaveModal.tsx:373-380`, while 
`loadTabs()` also
   stores its tabs and selected tab at
   `superset-frontend/src/explore/components/SaveModal.tsx:292-356`.
   
   3. Change the Explore dashboard context so `dashboardIdProp` changes to a 
dashboard whose
   response has `is_managed_externally: true` or which the user cannot edit. The
   initialization effect reruns because `dashboardIdProp` is a dependency at
   `superset-frontend/src/explore/components/SaveModal.tsx:421-428`, but the 
condition at
   `superset-frontend/src/explore/components/SaveModal.tsx:374-380` skips both 
setters and
   performs no cleanup.
   
   4. Observe that the previous dashboard, tabs, and selected tab remain in 
component state.
   Clicking Save then enters `saveOrOverwrite()` at
   `superset-frontend/src/explore/components/SaveModal.tsx:524-563`, which uses 
the stale
   `dashboard` state and includes that old dashboard ID in 
`formData.dashboards`, allowing
   the chart to be saved to the previously selected dashboard instead of 
clearing the invalid
   selection. Concurrent initialization requests can also apply stale results 
because the
   effect at `superset-frontend/src/explore/components/SaveModal.tsx:360-420` 
has no
   cancellation or request-generation check.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=4e1d8904c4b141cf91692b2f7ee9e6ff&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=4e1d8904c4b141cf91692b2f7ee9e6ff&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset-frontend/src/explore/components/SaveModal.tsx
   **Line:** 374:380
   **Comment:**
        *Stale Reference: When `dashboardIdProp` changes to an externally 
managed or non-editable dashboard while the modal remains mounted, this 
condition simply skips the setters, leaving the previously selected dashboard, 
tabs, and tab selection in state. The user can therefore still save using the 
stale editable dashboard. Clear `dashboard`, `tabsData`, and `selectedTab` 
before loading the new dashboard or when the new dashboard fails this 
condition, and cancel stale asynchronous initialization results.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F38584&comment_hash=12990a333e64d2dc9db3ef399924b06a2da795fc3f46bc89b9681ded8920dae5&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F38584&comment_hash=12990a333e64d2dc9db3ef399924b06a2da795fc3f46bc89b9681ded8920dae5&reaction=dislike'>👎</a>



-- 
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