Skip to content

Apache Superset 6.0.0 - fix(native-filters): clear all functionality #37069

@ypandey-fluidata

Description

@ypandey-fluidata

Bug description

Hi I have found this issue #36882 , in which the user correct the functionality of clear all button for native filters in Superset 5.0+ --

#Original Code:

`const handleClearAll = useCallback(() => {
const newClearAllTriggers = { ...clearAllTriggers };
// Clear all native filters, not just those in scope
// This ensures dependent filters are cleared even if parent was cleared first
nativeFilterValues.forEach(filter => {
const { id } = filter;
if (dataMaskSelected[id]) {
setDataMaskSelected(draft => {
if (draft[id].filterState?.value !== undefined) {
draft[id].filterState!.value = undefined;
}
draft[id].extraFormData = {};
});
newClearAllTriggers[id] = true;
}
});

let hasChartCustomizationsToClear = false;

const allDataMasks = { ...dataMaskSelected, ...dataMaskApplied };

Object.keys(allDataMasks).forEach(key => {
  if (key.startsWith('chart_customization_')) {
    hasChartCustomizationsToClear = true;
  }
});

if (!hasChartCustomizationsToClear && chartCustomizationItems.length > 0) {
  chartCustomizationItems.forEach(item => {
    if (item.customization?.column) {
      const customizationFilterId = `chart_customization_${item.id}`;
      const dataMask = {
        filterState: {
          value: item.customization.column,
        },
        ownState: {
          column: item.customization.column,
        },
        extraFormData: {},
      };

      dispatch(updateDataMask(customizationFilterId, dataMask));
      hasChartCustomizationsToClear = true;
    }
  });
}

if (hasChartCustomizationsToClear) {
  dispatch(clearAllPendingChartCustomizations());
  dispatch(clearAllChartCustomizationsFromMetadata());
  setHasClearedChartCustomizations(true);
}

setClearAllTriggers(newClearAllTriggers);

}, [
dataMaskSelected,
nativeFilterValues,
setDataMaskSelected,
clearAllTriggers,
dataMaskApplied,
chartCustomizationItems,
dispatch,
]);

const handleClearAllComplete = useCallback((filterId: string) => {
setClearAllTriggers(prev => {
const newTriggers = { ...prev };
delete newTriggers[filterId];
return newTriggers;
});
}, []);`

#Corrected Code:

`const handleClearAll = useCallback(() => {
dispatch(logEvent(LOG_ACTIONS_CHANGE_DASHBOARD_FILTER, {}));
setUpdateKey(1);
const newClearAllTriggers = { ...clearAllTriggers };
// Clear all native filters, not just those in scope
const updates: Record<string, DataMaskWithId> = {};
nativeFilterValues.forEach(filter => {
const { id } = filter;
if (dataMaskSelected[id]) {
updates[id] = {
...dataMaskSelected[id],
filterState: {
...dataMaskSelected[id].filterState,
value: null,
},
extraFormData: {},
};
newClearAllTriggers[id] = true;
}
});

setDataMaskSelected(draft => {
  Object.entries(updates).forEach(([id, mask]) => {
    draft[id] = mask;
  });
});

Object.entries(updates).forEach(([id, mask]) => {
  dispatch(updateDataMask(id, mask));
});

let hasChartCustomizationsToClear = false;

const allDataMasks = { ...dataMaskSelected, ...dataMaskApplied };

Object.keys(allDataMasks).forEach(key => {
  if (key.startsWith('chart_customization_')) {
    hasChartCustomizationsToClear = true;
  }
});

if (!hasChartCustomizationsToClear && chartCustomizationItems.length > 0) {
  chartCustomizationItems.forEach(item => {
    if (item.customization?.column) {
      const customizationFilterId = `chart_customization_${item.id}`;
      const dataMask = {
        filterState: {
          value: item.customization.column,
        },
        ownState: {
          column: item.customization.column,
        },
        extraFormData: {},
      };

      dispatch(updateDataMask(customizationFilterId, dataMask));
      hasChartCustomizationsToClear = true;
    }
  });
}

if (hasChartCustomizationsToClear) {
  dispatch(clearAllPendingChartCustomizations());
  dispatch(clearAllChartCustomizationsFromMetadata());
  setHasClearedChartCustomizations(true);

  const clearedChartCustomizations = chartCustomizationItems.map(item => ({
    ...item,
    customization: {
      ...item.customization,
      column: null,
    },
  }));

  dispatch(saveChartCustomization(clearedChartCustomizations));
}

setClearAllTriggers(newClearAllTriggers);

}, [
dataMaskSelected,
nativeFilterValues,
setDataMaskSelected,
clearAllTriggers,
dataMaskApplied,
chartCustomizationItems,
dispatch,
]);

const handleClearAllComplete = useCallback((filterId: string) => {
setClearAllTriggers(prev => {
const newTriggers = { ...prev };
delete newTriggers[filterId];
return newTriggers;
});
}, []);`


Now as i am trying to implement the same in Superset 6.0 but it is having a different code structure--

#Apache Superset 6.0 Native Filters:

` const handleClearAll = useCallback(() => {
const newClearAllTriggers = { ...clearAllTriggers };
filtersInScope.filter(isNativeFilter).forEach(filter => {
const { id } = filter;
if (dataMaskSelected[id]) {
setDataMaskSelected(draft => {
if (draft[id].filterState?.value !== undefined) {
draft[id].filterState!.value = undefined;
}
draft[id].extraFormData = {};
});
newClearAllTriggers[id] = true;
}
});
setClearAllTriggers(newClearAllTriggers);
}, [dataMaskSelected, filtersInScope, setDataMaskSelected, clearAllTriggers]);

const handleClearAllComplete = useCallback((filterId: string) => {
setClearAllTriggers(prev => {
const newTriggers = { ...prev };
delete newTriggers[filterId];
return newTriggers;
});
}, []);

useFilterUpdates(dataMaskSelected, setDataMaskSelected);
const isApplyDisabled = checkIsApplyDisabled(
dataMaskSelected,
dataMaskApplied,
filtersInScope.filter(isNativeFilter),
);
const isInitialized = useInitialization();

const actions = useMemo(
() => (

),
[
orientation,
verticalConfig?.width,
handleApply,
handleClearAll,
dataMaskSelected,
dataMaskAppliedText,
isApplyDisabled,
],
);

const filterBarComponent =
orientation === FilterBarOrientation.Horizontal ? (

) : verticalConfig ? (

) : null;

return hidden ? (
{filterBarComponent}
) : (
filterBarComponent
);
};
export default memo(FilterBar);`

Screenshots/recordings

No response

Superset version

master / latest-dev

Python version

3.9

Node version

16

Browser

Chrome

Additional context

No response

Checklist

  • I have searched Superset docs and Slack and didn't find a solution to my problem.
  • I have searched the GitHub issue tracker and didn't find a similar bug report.
  • 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    New

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions