You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by mi...@apache.org on 2023/07/11 13:41:54 UTC

[superset] branch master updated: fix: Validation of out of scope filters and interaction with Clear All (#24610)

This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 0efb88479e fix: Validation of out of scope filters and interaction with Clear All (#24610)
0efb88479e is described below

commit 0efb88479edd7761b415ae32fd9b3e97699e533f
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Tue Jul 11 10:41:45 2023 -0300

    fix: Validation of out of scope filters and interaction with Clear All (#24610)
---
 .../FilterBar/FilterControls/FilterControl.tsx     | 13 +++++++----
 .../FilterBar/FilterControls/FilterValue.tsx       | 11 +++------
 .../FilterBar/FilterControls/types.ts              |  1 +
 .../components/nativeFilters/FilterBar/index.tsx   | 27 +++++++++++++++-------
 .../dashboard/components/nativeFilters/state.ts    |  2 +-
 5 files changed, 32 insertions(+), 22 deletions(-)

diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControl.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControl.tsx
index 2d8af510dc..c826d5dbff 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControl.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControl.tsx
@@ -32,6 +32,7 @@ import { FilterCard } from '../../FilterCard';
 import { FilterBarScrollContext } from '../Vertical';
 import { FilterControlProps } from './types';
 import { FilterCardPlacement } from '../../FilterCard/types';
+import { useIsFilterInScope } from '../../state';
 
 const StyledIcon = styled.div`
   position: absolute;
@@ -233,10 +234,11 @@ const FilterControl = ({
 
   const { name = '<undefined>' } = filter;
 
-  const isMissingRequiredValue = checkIsMissingRequiredValue(
-    filter,
-    filter.dataMask?.filterState,
-  );
+  const isFilterInScope = useIsFilterInScope();
+  const isMissingRequiredValue =
+    isFilterInScope(filter) &&
+    checkIsMissingRequiredValue(filter, filter.dataMask?.filterState);
+  const validateStatus = isMissingRequiredValue ? 'error' : undefined;
   const isRequired = !!filter.controlValues?.enableEmptyFilter;
 
   const {
@@ -293,6 +295,7 @@ const FilterControl = ({
           setFilterActive={setIsFilterActive}
           orientation={orientation}
           overflow={overflow}
+          validateStatus={validateStatus}
         />
       </InPortal>
       <FilterControlContainer
@@ -311,7 +314,7 @@ const FilterControl = ({
             <FormItem
               label={label}
               required={filter?.controlValues?.enableEmptyFilter}
-              validateStatus={isMissingRequiredValue ? 'error' : undefined}
+              validateStatus={validateStatus}
             >
               <OutPortal node={portalNode} />
             </FormItem>
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterValue.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterValue.tsx
index 9ea15f87f1..b600553669 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterValue.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterValue.tsx
@@ -57,7 +57,6 @@ import { dispatchHoverAction, dispatchFocusAction } from './utils';
 import { FilterControlProps } from './types';
 import { getFormData } from '../../utils';
 import { useFilterDependencies } from './state';
-import { checkIsMissingRequiredValue } from '../utils';
 import { useFilterOutlined } from '../useFilterOutlined';
 
 const HEIGHT = 32;
@@ -95,6 +94,7 @@ const FilterValue: React.FC<FilterControlProps> = ({
   setFilterActive,
   orientation = FilterBarOrientation.VERTICAL,
   overflow = false,
+  validateStatus,
 }) => {
   const { id, targets, filterType, adhoc_filters, time_range } = filter;
   const metadata = getChartMetadataRegistry().get(filterType);
@@ -281,17 +281,12 @@ const FilterValue: React.FC<FilterControlProps> = ({
     ],
   );
 
-  const isMissingRequiredValue = checkIsMissingRequiredValue(
-    filter,
-    filter.dataMask?.filterState,
-  );
-
   const filterState = useMemo(
     () => ({
       ...filter.dataMask?.filterState,
-      validateStatus: isMissingRequiredValue && 'error',
+      validateStatus,
     }),
-    [filter.dataMask?.filterState, isMissingRequiredValue],
+    [filter.dataMask?.filterState, validateStatus],
   );
 
   const displaySettings = useMemo(
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/types.ts b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/types.ts
index ac9cca8c01..a1f432977d 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/types.ts
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/types.ts
@@ -42,4 +42,5 @@ export interface FilterControlProps extends BaseFilterProps {
   showOverflow?: boolean;
   parentRef?: RefObject<any>;
   setFilterActive?: (isActive: boolean) => void;
+  validateStatus?: string;
 }
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx
index 5dfcaba488..fe3a8e21d2 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx
+++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx
@@ -51,6 +51,7 @@ import { createFilterKey, updateFilterKey } from './keyValue';
 import ActionButtons from './ActionButtons';
 import Horizontal from './Horizontal';
 import Vertical from './Vertical';
+import { useSelectFiltersInScope } from '../state';
 
 // FilterBar is just being hidden as it must still
 // render fully due to encapsulated logics
@@ -141,6 +142,8 @@ const FilterBar: React.FC<FiltersBarProps> = ({
     ({ dashboardInfo }) => dashboardInfo.dash_edit_perm,
   );
 
+  const [filtersInScope] = useSelectFiltersInScope(nativeFilterValues);
+
   const handleFilterSelectionChange = useCallback(
     (
       filter: Pick<Filter, 'id'> & Partial<Filter>,
@@ -222,24 +225,32 @@ const FilterBar: React.FC<FiltersBarProps> = ({
   }, [dataMaskSelected, dispatch]);
 
   const handleClearAll = useCallback(() => {
-    const filterIds = Object.keys(dataMaskSelected);
-    filterIds.forEach(filterId => {
-      if (dataMaskSelected[filterId]) {
-        dispatch(clearDataMask(filterId));
+    const clearDataMaskIds: string[] = [];
+    let dispatchAllowed = false;
+    filtersInScope.filter(isNativeFilter).forEach(filter => {
+      const { id } = filter;
+      if (dataMaskSelected[id]) {
+        if (filter.controlValues?.enableEmptyFilter) {
+          dispatchAllowed = false;
+        }
+        clearDataMaskIds.push(id);
         setDataMaskSelected(draft => {
-          if (draft[filterId].filterState?.value !== undefined) {
-            draft[filterId].filterState!.value = undefined;
+          if (draft[id].filterState?.value !== undefined) {
+            draft[id].filterState!.value = undefined;
           }
         });
       }
     });
-  }, [dataMaskSelected, dispatch, setDataMaskSelected]);
+    if (dispatchAllowed) {
+      clearDataMaskIds.forEach(id => dispatch(clearDataMask(id)));
+    }
+  }, [dataMaskSelected, dispatch, filtersInScope, setDataMaskSelected]);
 
   useFilterUpdates(dataMaskSelected, setDataMaskSelected);
   const isApplyDisabled = checkIsApplyDisabled(
     dataMaskSelected,
     dataMaskApplied,
-    nativeFilterValues,
+    filtersInScope.filter(isNativeFilter),
   );
   const isInitialized = useInitialization();
 
diff --git a/superset-frontend/src/dashboard/components/nativeFilters/state.ts b/superset-frontend/src/dashboard/components/nativeFilters/state.ts
index 030b65859b..38a50c7b06 100644
--- a/superset-frontend/src/dashboard/components/nativeFilters/state.ts
+++ b/superset-frontend/src/dashboard/components/nativeFilters/state.ts
@@ -89,7 +89,7 @@ function useSelectChartTabParents() {
   };
 }
 
-function useIsFilterInScope() {
+export function useIsFilterInScope() {
   const activeTabs = useActiveDashboardTabs();
   const selectChartTabParents = useSelectChartTabParents();