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


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

Review Comment:
   Agreed. The hydration effect should be keyed by the dashboard identity, and 
the hydration guard must be reset when that identity changes. Otherwise SPA 
navigation can leave the component “hydrated” for dashboard A while rendering 
dashboard B.
   
   For example:
   
   ```tsx
   const previousDashboardId = useRef<number>();
   
   useEffect(() => {
     if (!readyToRender || !id) return;
   
     if (previousDashboardId.current !== id) {
       isDashboardHydrated.current = false;
       previousDashboardId.current = id;
     }
   
     // Existing hydration logic, including:
     // const savedFilters = getSavedDashboardFilters(id)
   }, [readyToRender, id]);
   ```
   
   The saved-filter lookup should therefore run from an effect whose 
dependencies include both `readyToRender` and `id`. Any in-flight hydration for 
the previous dashboard should also be guarded or cancelled so it cannot 
overwrite the new dashboard’s state. This ensures dashboard B reads only 
`superset_dashboard_filters_${B}` and does not retain dashboard A’s mask.



##########
superset-frontend/src/dashboard/containers/DashboardPage.tsx:
##########
@@ -157,20 +181,26 @@ export const DashboardPage: FC<PageProps> = ({ idOrSlug 
}: PageProps) => {
   const isNotFoundError = (error as SupersetApiError | null)?.status === 404;
   const readyToRender = Boolean(dashboard && charts);
   const { dashboard_title, id = 0 } = dashboard || {};
+  const hydratedDashboardId = useSelector<RootState, number | undefined>(
+    state => state.dashboardInfo?.id,
+  );
+  const fullDataMask = useSelector(selectDataMask);
 
+  useEffect(() => {
+    if (!id || hydratedDashboardId !== id) return;
+    saveDashboardFilters(id, fullDataMask);
+  }, [id, hydratedDashboardId, fullDataMask]);

Review Comment:
   Yes. The write should be gated by an explicit “initial filter load 
completed” state, not only by `dashboardInfo.id`. During SPA navigation, the 
Redux `dataMask` can temporarily be cleared while `dashboardInfo.id` still 
refers to the old dashboard.
   
   For example:
   
   ```tsx
   const [initialFiltersLoaded, setInitialFiltersLoaded] = useState(false);
   
   useEffect(() => {
     setInitialFiltersLoaded(false);
   }, [id]);
   
   useEffect(() => {
     let cancelled = false;
   
     async function loadInitialFilters() {
       // Resolve permalink, URL filter, or localStorage state here.
       // Apply the resulting dataMask to Redux.
   
       if (!cancelled) {
         setInitialFiltersLoaded(true);
       }
     }
   
     if (id) {
       loadInitialFilters();
     }
   
     return () => {
       cancelled = true;
     };
   }, [id]);
   
   useEffect(() => {
     if (
       !id ||
       hydratedDashboardId !== id ||
       !initialFiltersLoaded
     ) {
       return;
     }
   
     saveDashboardFilters(id, fullDataMask);
   }, [id, hydratedDashboardId, fullDataMask, initialFiltersLoaded]);
   ```
   
   The load effect should set `initialFiltersLoaded` only after the initial 
mask has been selected and dispatched, including the cases where there is no 
URL/localStorage value. This prevents the transient `{}` from overwriting the 
saved state, while still allowing subsequent user changes to be persisted. The 
existing dashboard-ID guard remains necessary to prevent cross-dashboard 
leakage.



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