sadpandajoe commented on code in PR #43108:
URL: https://github.com/apache/superset/pull/43108#discussion_r3819465236


##########
superset-frontend/src/dashboard/containers/DashboardPage.tsx:
##########
@@ -381,8 +434,24 @@ export const DashboardPage: FC<PageProps> = ({ idOrSlug }: 
PageProps) => {
   }, [addDangerToast, datasets, datasetsApiError, dispatch, isNotFoundError]);
 
   const relevantDataMask = useSelector(selectRelevantDatamask);
+  const fullDataMask = useSelector(selectDataMask);
+  const nativeFilters = useSelector(selectNativeFilters);
   const activeFilters = useSelector(selectActiveFilters);
 
+  useEffect(() => {
+    if (!id || hydratedDashboardId !== id) return;
+    // Persist only entries that correspond to configured native filters.
+    // This avoids saving chart customization or other transient dataMask
+    // entries that are not part of the user's filter selections.
+    const nativeFilterIds = Object.keys(nativeFilters);
+    const nativeFilterMask = Object.fromEntries(
+      nativeFilterIds
+        .filter(filterId => filterId in fullDataMask)
+        .map(filterId => [filterId, fullDataMask[filterId]]),
+    );
+    saveDashboardFilters(id, userId, nativeFilterMask);

Review Comment:
   This can overwrite the saved selection with `{}` before the next dashboard 
has hydrated. `Dashboard` clears `dataMask` on unmount while the old 
`dashboardInfo.id` remains, so if the dashboard response arrives before charts, 
this matching-ID effect persists the empty mask and line 272 later restores 
that empty value. Should persistence wait until this dashboard's restore has 
completed?



##########
superset-frontend/src/dashboard/containers/DashboardPage.tsx:
##########
@@ -226,6 +268,17 @@ export const DashboardPage: FC<PageProps> = ({ idOrSlug }: 
PageProps) => {
         }
       } else if (nativeFilterKeyValue) {
         dataMask = await getFilterValue(id, nativeFilterKeyValue);
+      } else {
+        const savedFilters = getSavedDashboardFilters(id, userId);

Review Comment:
   This restore only runs when `readyToRender` changes, but the effect depends 
on `[readyToRender]` alone. During an SPA transition from dashboard A to B 
where both API results remain ready, it does not rerun for B, so B's saved 
filters are never loaded. Can the hydration trigger include the dashboard 
identity (and relevant URL/user inputs)?



##########
superset-frontend/src/dashboard/containers/DashboardPage.tsx:
##########
@@ -226,6 +268,17 @@ export const DashboardPage: FC<PageProps> = ({ idOrSlug }: 
PageProps) => {
         }
       } else if (nativeFilterKeyValue) {
         dataMask = await getFilterValue(id, nativeFilterKeyValue);
+      } else {
+        const savedFilters = getSavedDashboardFilters(id, userId);
+        // Guard against corrupted or unexpected localStorage data shapes
+        // (e.g. a JSON array or primitive) before assigning to dataMask.
+        if (
+          savedFilters &&
+          typeof savedFilters === 'object' &&
+          !Array.isArray(savedFilters)
+        ) {
+          dataMask = savedFilters;

Review Comment:
   A plain-object check does not establish that this saved mask still matches 
the dashboard's current filter definition. If an editor keeps a filter ID but 
retargets it to another column or dataset, the old `extraFormData` is hydrated 
and can apply the previous selection to the new filter. Should restore validate 
the stored entries against the current native-filter configuration or 
invalidate them when it changes?



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