You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@superset.apache.org by "Stanhoucke (via GitHub)" <gi...@apache.org> on 2024/09/27 15:01:11 UTC

[I] Dashboard Filter 'useFilterScope' Error [superset]

Stanhoucke opened a new issue, #30418:
URL: https://github.com/apache/superset/issues/30418

   ### Bug description
   
   The bug is that when interacting with the filters in an embedded dashboard, the filters will be replaced with an `Unexpected Error` message. The user is forced to refresh the dashboard, losing the state of their filters prior to the error.
   
   ![image](https://github.com/user-attachments/assets/1ae032f0-8c07-456f-a341-1cb5e4bf5da1)
   
   **Steps to reproduce**
   1. Load an embedded dashboard
   2. Interact with the filters without clicking `Apply Filters`
   3. After a certain amount of interactions, the filters will show the above error
   
   I could not reliably find a way or pattern to trigger this error. It may take a minute or two of selecting, deselecting, updating some filter options before seeing the error.
   
   The browser console displays the following TypeError related to the `useFilterScope` function.
   
   ![image](https://github.com/user-attachments/assets/9da0bf33-35fc-4fe3-a1cd-74fe1591f98f)
   
   
   
   ### Screenshots/recordings
   
   _No response_
   
   ### Superset version
   
   4.0.2
   
   ### Python version
   
   3.10
   
   ### Node version
   
   16
   
   ### Browser
   
   Chrome
   
   ### Additional context
   
   _No response_
   
   ### Checklist
   
   - [X] I have searched Superset docs and Slack and didn't find a solution to my problem.
   - [X] I have searched the GitHub issue tracker and didn't find a similar bug report.
   - [X] I have checked Superset's logs for errors and if I found a relevant Python stacktrace, I included it here as text in the "additional context" section.


-- 
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: notifications-unsubscribe@superset.apache.org.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org


Re: [I] Dashboard Filter 'useFilterScope' Error [superset]

Posted by "dosubot[bot] (via GitHub)" <gi...@apache.org>.
dosubot[bot] commented on issue #30418:
URL: https://github.com/apache/superset/issues/30418#issuecomment-2379488933

   <!-- Greeting -->
   Hey there, @Stanhoucke! I'm here to help you with bug fixes, answer your questions, and guide you to become a contributor. Let's tackle this issue together!
   
   <!-- Answer -->
   I found two similar closed issues that might be relevant to your problem:
   
   1. [Superset](https://github.com/apache/superset/issues/27886) - Closed on April 03, 2024.
   2. [Upgrading from 2.0.0 to 2.0.1rc2 causes an error when setting owner and roles on dashboard](https://github.com/apache/superset/issues/21984) - Closed on February 23, 2024. The suggested solution was to upgrade to version 2.0.1, which fixed the issue.
   
   To resolve the `useFilterScope` TypeError in an embedded dashboard when interacting with filters in Superset version 4.0.2, ensure that the `useFilterScope` function is correctly implemented and used. Here is the relevant part of the code:
   
   ```ts
   import { useMemo } from 'react';
   import { useSelector } from 'react-redux';
   import { Filter, t } from '@superset-ui/core';
   import { Layout, LayoutItem, RootState } from 'src/dashboard/types';
   import { DASHBOARD_ROOT_ID } from 'src/dashboard/util/constants';
   import { CHART_TYPE } from 'src/dashboard/util/componentTypes';
   import { useChartIds } from 'src/dashboard/util/charts/useChartIds';
   
   const extractTabLabel = (tab?: LayoutItem) =>
     tab?.meta?.text || tab?.meta?.defaultText || '';
   const extractChartLabel = (chart?: LayoutItem) =>
     chart?.meta?.sliceNameOverride || chart?.meta?.sliceName || chart?.id || '';
   
   export const useFilterScope = (filter: Filter) => {
     const layout = useSelector<RootState, Layout>(
       state => state.dashboardLayout.present,
     );
     const chartIds = useChartIds();
   
     return useMemo(() => {
       let topLevelTabs: string[] | undefined;
       const topElementId = layout[DASHBOARD_ROOT_ID].children[0];
       if (topElementId.startsWith('TABS-')) {
         topLevelTabs = layout[topElementId].children;
       }
   
       if (filter.scope.rootPath.length === 0) {
         return undefined;
       }
   
       if (
         filter.scope.excluded.length === 0 &&
         (filter.scope.rootPath[0] === DASHBOARD_ROOT_ID ||
           topLevelTabs?.every(topLevelTab =>
             filter.scope.rootPath.includes(topLevelTab),
           ))
       ) {
         return { all: [t('All charts')] };
       }
   
       if (filter.scope.excluded.length === 0 && topLevelTabs) {
         return {
           tabs: filter.scope.rootPath
             .map(tabId => extractTabLabel(layout[tabId]))
             .filter(Boolean),
         };
       }
   
       const layoutCharts = Object.values(layout).filter(
         layoutElement => layoutElement.type === CHART_TYPE,
       );
   
       if (filter.scope.rootPath[0] === DASHBOARD_ROOT_ID) {
         return {
           charts: chartIds
             .filter(chartId => !filter.scope.excluded.includes(chartId))
             .map(chartId => {
               const layoutElement = layoutCharts.find(
                 layoutChart => layoutChart.meta.chartId === chartId,
               );
               return extractChartLabel(layoutElement);
             })
             .filter(Boolean),
         };
       }
   
       if (topLevelTabs) {
         const topLevelTabsInFullScope = [...filter.scope.rootPath];
         const layoutChartElementsInTabsInScope = layoutCharts.filter(element =>
           element.parents.some(parent =>
             topLevelTabsInFullScope.includes(parent),
           ),
         );
   
         filter.scope.excluded.forEach(chartId => {
           const excludedIndex = topLevelTabsInFullScope.findIndex(tabId =>
             layoutChartElementsInTabsInScope
               .find(chart => chart.meta.chartId === chartId)
               ?.parents.includes(tabId),
           );
           if (excludedIndex > -1) {
             topLevelTabsInFullScope.splice(excludedIndex, 1);
           }
         });
   
         const chartsInExcludedTabs = chartIds
           .filter(chartId => !filter.scope.excluded.includes(chartId))
           .reduce((acc: LayoutItem[], chartId) => {
             const layoutChartElementInExcludedTab =
               layoutChartElementsInTabsInScope.find(
                 element =>
                   element.meta.chartId === chartId &&
                   element.parents.every(
                     parent => !topLevelTabsInFullScope.includes(parent),
                   ),
               );
             if (layoutChartElementInExcludedTab) {
               acc.push(layoutChartElementInExcludedTab);
             }
             return acc;
           }, []);
   
         return {
           tabs: topLevelTabsInFullScope
             .map(tabId => extractTabLabel(layout[tabId]))
             .filter(Boolean),
           charts: chartsInExcludedTabs.map(extractChartLabel).filter(Boolean),
         };
       }
   
       return undefined;
     }, [chartIds, filter.scope.excluded, filter.scope.rootPath, layout]);
   };
   ```
   
   Ensure that the `useFilterScope` function is correctly used in your component. If you encounter a TypeError, it might be due to incorrect usage or missing dependencies in the context where `useFilterScope` is called.
   
   Here is an example of how to use `useFilterScope` correctly:
   
   ```ts
   import React from 'react';
   import { useFilterScope } from 'path-to-your-state-file';
   
   const MyDashboardComponent = ({ filter }) => {
     const filterScope = useFilterScope(filter);
   
     return (
       <div>
         {/* Render your filters based on the scope */}
         {filterScope?.all && <div>All charts are in scope</div>}
         {filterScope?.tabs && filterScope.tabs.map(tab => <div key={tab}>{tab}</div>)}
         {filterScope?.charts && filterScope.charts.map(chart => <div key={chart}>{chart}</div>)}
       </div>
     );
   };
   ```
   
   Additionally, ensure that the filters passed to `useFilterScope` are correctly structured and that the necessary state selectors (`useSelector`, `useChartIds`, etc.) are functioning as expected. You may also want to check the implementation of the `ScopeRow` component and related utilities like `useTruncation` to ensure they are correctly set up and integrated <sup>[[1]](https://github.com/apache/superset/blob/master/superset-frontend/src/dashboard/components/nativeFilters/state.ts)</sup><sup>[[2]](https://github.com/apache/superset/blob/master/superset-frontend/src/dashboard/components/nativeFilters/FilterCard/useFilterScope.ts)</sup><sup>[[3]](https://github.com/apache/superset/blob/master/superset-frontend/src/dashboard/components/filterscope/FilterScopeSelector.jsx)</sup><sup>[[4]](https://github.com/apache/superset/blob/master/superset-frontend/src/dashboard/util/getFilterScopeFromNodesTree.test.js)</sup><sup>[[5]](https://github.com/apache/superset/blob/master/superset-front
 end/src/dashboard/components/nativeFilters/FilterCard/ScopeRow.tsx)</sup>.
   
   
   <!-- Dosu Comment Footer -->
   *To continue talking to [Dosu](https://dosu.dev), mention @dosu.*
   


-- 
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: notifications-unsubscribe@superset.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org