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


##########
superset-frontend/src/dashboard/reducers/dashboardInfo.ts:
##########
@@ -124,22 +122,11 @@ export default function dashboardInfoReducer(
     case DASHBOARD_INFO_UPDATED: {
       const dashAction = action as DashboardInfoAction;
       const newInfo = dashAction.newInfo || {};
-      const { theme_id: themeId, ...otherInfo } = newInfo;
-      const updatedState: DashboardInfoState = {
+      return {
         ...state,
-        ...otherInfo,
+        ...newInfo,
         last_modified_time: Math.round(new Date().getTime() / 1000),
       };

Review Comment:
   **Suggestion:** When handling the generic dashboard info update action, the 
reducer now shallow-merges `newInfo.metadata` into the existing state without 
preserving `chartsInScope`/`tabsInScope` for `native_filter_configuration`, 
even though the `preserveScopes` helper exists and is used for HYDRATE. This 
means that whenever `dashboardInfoChanged` is dispatched with a 
`metadata.native_filter_configuration` coming from the server (which may omit 
those scope fields), the reducer will overwrite the in-memory 
`native_filter_configuration` array and drop the existing scope data, causing 
native filters to lose their chart/tab scoping after such updates. To avoid 
this regression, the DASHBOARD_INFO_UPDATED branch should merge 
`metadata.native_filter_configuration` via `preserveScopes` instead of blindly 
overwriting it. [logic error]
   
   <details>
   <summary><b>Severity Level:</b> Critical 🚨</summary>
   
   ```mdx
   - ❌ Saving dashboard overwrites native filter chart/tab scoping.
   - ⚠️ Native filter bar shows filters as globally scoped again.
   - ⚠️ Cross-filter and scoping UX becomes inconsistent after saves.
   - ⚠️ HYDRATE preserves scopes but later updates silently discard them.
   ```
   </details>
   
   ```suggestion
       case DASHBOARD_INFO_UPDATED: {
         const dashAction = action as DashboardInfoAction;
         const newInfo = dashAction.newInfo || {};
   
         let mergedMetadata = newInfo.metadata;
         if (
           newInfo.metadata?.native_filter_configuration &&
           state.metadata?.native_filter_configuration
         ) {
           mergedMetadata = {
             ...newInfo.metadata,
             native_filter_configuration: preserveScopes(
               state.metadata.native_filter_configuration,
               newInfo.metadata.native_filter_configuration,
             ),
           } as DashboardInfo['metadata'];
         }
   
         return {
           ...state,
           ...newInfo,
           ...(mergedMetadata && { metadata: mergedMetadata }),
           last_modified_time: Math.round(new Date().getTime() / 1000),
         };
       }
   ```
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Open a dashboard with native filters and adjust their chart/tab scoping 
via the Native
   Filters UI. The scoping update is handled by `setInScopeStatusOfFilters` in
   `superset-frontend/src/dashboard/actions/nativeFilters.ts:106-147`, which 
merges the new
   `chartsInScope`/`tabsInScope` into `metadata.native_filter_configuration` 
and dispatches
   `dashboardInfoChanged({ metadata })` (lines 141-145), populating
   `state.dashboardInfo.metadata.native_filter_configuration` with those scope 
fields.
   
   2. In the same session, click the "Save" button in the dashboard header. 
This triggers
   `overwriteDashboard` in
   `superset-frontend/src/dashboard/components/Header/index.tsx:431-501`, which 
calls
   `boundActionCreators.onSave(data, dashboardInfo.id, SAVE_TYPE_OVERWRITE)` 
(line 479).
   `onSave` is bound to `saveDashboardRequest` from
   `superset-frontend/src/dashboard/actions/dashboardState.ts` (import and 
binding at lines
   70-73 and 318-319).
   
   3. Inside `saveDashboardRequest`
   (`superset-frontend/src/dashboard/actions/dashboardState.ts:424-732`), after 
a successful
   `PUT /api/v1/dashboard/:id`, `onUpdateSuccess` (lines 548-603) parses the 
backend
   `json_metadata` into `parsedMetadata` (lines 554-557) and dispatches
   `setDashboardMetadata(parsedMetadata)` (line 558). `setDashboardMetadata` 
(lines 391-402)
   in the same file then dispatches `dashboardInfoChanged({ metadata: {
   ...dashboardInfo?.metadata, ...updatedMetadata } })`, where 
`updatedMetadata` comes from
   the server and includes a `native_filter_configuration` that does not 
contain the
   client-only `chartsInScope`/`tabsInScope` fields.
   
   4. The `dashboardInfoChanged` action creator in
   `superset-frontend/src/dashboard/actions/dashboardInfo.ts:44-47` emits `{ 
type:
   DASHBOARD_INFO_UPDATED, newInfo }`, which is handled by 
`dashboardInfoReducer` in
   `superset-frontend/src/dashboard/reducers/dashboardInfo.ts:117-129`. In the
   `DASHBOARD_INFO_UPDATED` case (lines 122-129), the reducer shallow-merges 
`...newInfo`
   into `state`, so `state.metadata` is entirely replaced by 
`newInfo.metadata`. Because
   `newInfo.metadata.native_filter_configuration` came from the server without
   `chartsInScope`/`tabsInScope`, the existing scopes stored in
   `state.metadata.native_filter_configuration` are dropped. On subsequent 
renders, any
   component relying on 
`state.dashboardInfo.metadata.native_filter_configuration` for
   scoping (e.g., via `nativeFilters` state and Filter Bar components 
referenced in
   `superset-frontend/src/dashboard/components/nativeFilters/*`) will see 
filters as if they
   have lost their chart/tab scoping.
   ```
   </details>
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset-frontend/src/dashboard/reducers/dashboardInfo.ts
   **Line:** 122:129
   **Comment:**
        *Logic Error: When handling the generic dashboard info update action, 
the reducer now shallow-merges `newInfo.metadata` into the existing state 
without preserving `chartsInScope`/`tabsInScope` for 
`native_filter_configuration`, even though the `preserveScopes` helper exists 
and is used for HYDRATE. This means that whenever `dashboardInfoChanged` is 
dispatched with a `metadata.native_filter_configuration` coming from the server 
(which may omit those scope fields), the reducer will overwrite the in-memory 
`native_filter_configuration` array and drop the existing scope data, causing 
native filters to lose their chart/tab scoping after such updates. To avoid 
this regression, the DASHBOARD_INFO_UPDATED branch should merge 
`metadata.native_filter_configuration` via `preserveScopes` instead of blindly 
overwriting it.
   
   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.
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F38384&comment_hash=8b86cd6edb7f3f7a349372b7072b8beef3aeda4f8e122c7ae03025e3fa38ccce&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F38384&comment_hash=8b86cd6edb7f3f7a349372b7072b8beef3aeda4f8e122c7ae03025e3fa38ccce&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