Skip to content

Commit 0efb884

Browse files
fix: Validation of out of scope filters and interaction with Clear All (apache#24610)
1 parent 65291a0 commit 0efb884

File tree

5 files changed

+32
-22
lines changed

5 files changed

+32
-22
lines changed

superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterControl.tsx

+8-5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { FilterCard } from '../../FilterCard';
3232
import { FilterBarScrollContext } from '../Vertical';
3333
import { FilterControlProps } from './types';
3434
import { FilterCardPlacement } from '../../FilterCard/types';
35+
import { useIsFilterInScope } from '../../state';
3536

3637
const StyledIcon = styled.div`
3738
position: absolute;
@@ -233,10 +234,11 @@ const FilterControl = ({
233234

234235
const { name = '<undefined>' } = filter;
235236

236-
const isMissingRequiredValue = checkIsMissingRequiredValue(
237-
filter,
238-
filter.dataMask?.filterState,
239-
);
237+
const isFilterInScope = useIsFilterInScope();
238+
const isMissingRequiredValue =
239+
isFilterInScope(filter) &&
240+
checkIsMissingRequiredValue(filter, filter.dataMask?.filterState);
241+
const validateStatus = isMissingRequiredValue ? 'error' : undefined;
240242
const isRequired = !!filter.controlValues?.enableEmptyFilter;
241243

242244
const {
@@ -293,6 +295,7 @@ const FilterControl = ({
293295
setFilterActive={setIsFilterActive}
294296
orientation={orientation}
295297
overflow={overflow}
298+
validateStatus={validateStatus}
296299
/>
297300
</InPortal>
298301
<FilterControlContainer
@@ -311,7 +314,7 @@ const FilterControl = ({
311314
<FormItem
312315
label={label}
313316
required={filter?.controlValues?.enableEmptyFilter}
314-
validateStatus={isMissingRequiredValue ? 'error' : undefined}
317+
validateStatus={validateStatus}
315318
>
316319
<OutPortal node={portalNode} />
317320
</FormItem>

superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/FilterValue.tsx

+3-8
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ import { dispatchHoverAction, dispatchFocusAction } from './utils';
5757
import { FilterControlProps } from './types';
5858
import { getFormData } from '../../utils';
5959
import { useFilterDependencies } from './state';
60-
import { checkIsMissingRequiredValue } from '../utils';
6160
import { useFilterOutlined } from '../useFilterOutlined';
6261

6362
const HEIGHT = 32;
@@ -95,6 +94,7 @@ const FilterValue: React.FC<FilterControlProps> = ({
9594
setFilterActive,
9695
orientation = FilterBarOrientation.VERTICAL,
9796
overflow = false,
97+
validateStatus,
9898
}) => {
9999
const { id, targets, filterType, adhoc_filters, time_range } = filter;
100100
const metadata = getChartMetadataRegistry().get(filterType);
@@ -281,17 +281,12 @@ const FilterValue: React.FC<FilterControlProps> = ({
281281
],
282282
);
283283

284-
const isMissingRequiredValue = checkIsMissingRequiredValue(
285-
filter,
286-
filter.dataMask?.filterState,
287-
);
288-
289284
const filterState = useMemo(
290285
() => ({
291286
...filter.dataMask?.filterState,
292-
validateStatus: isMissingRequiredValue && 'error',
287+
validateStatus,
293288
}),
294-
[filter.dataMask?.filterState, isMissingRequiredValue],
289+
[filter.dataMask?.filterState, validateStatus],
295290
);
296291

297292
const displaySettings = useMemo(

superset-frontend/src/dashboard/components/nativeFilters/FilterBar/FilterControls/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,5 @@ export interface FilterControlProps extends BaseFilterProps {
4242
showOverflow?: boolean;
4343
parentRef?: RefObject<any>;
4444
setFilterActive?: (isActive: boolean) => void;
45+
validateStatus?: string;
4546
}

superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx

+19-8
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import { createFilterKey, updateFilterKey } from './keyValue';
5151
import ActionButtons from './ActionButtons';
5252
import Horizontal from './Horizontal';
5353
import Vertical from './Vertical';
54+
import { useSelectFiltersInScope } from '../state';
5455

5556
// FilterBar is just being hidden as it must still
5657
// render fully due to encapsulated logics
@@ -141,6 +142,8 @@ const FilterBar: React.FC<FiltersBarProps> = ({
141142
({ dashboardInfo }) => dashboardInfo.dash_edit_perm,
142143
);
143144

145+
const [filtersInScope] = useSelectFiltersInScope(nativeFilterValues);
146+
144147
const handleFilterSelectionChange = useCallback(
145148
(
146149
filter: Pick<Filter, 'id'> & Partial<Filter>,
@@ -222,24 +225,32 @@ const FilterBar: React.FC<FiltersBarProps> = ({
222225
}, [dataMaskSelected, dispatch]);
223226

224227
const handleClearAll = useCallback(() => {
225-
const filterIds = Object.keys(dataMaskSelected);
226-
filterIds.forEach(filterId => {
227-
if (dataMaskSelected[filterId]) {
228-
dispatch(clearDataMask(filterId));
228+
const clearDataMaskIds: string[] = [];
229+
let dispatchAllowed = false;
230+
filtersInScope.filter(isNativeFilter).forEach(filter => {
231+
const { id } = filter;
232+
if (dataMaskSelected[id]) {
233+
if (filter.controlValues?.enableEmptyFilter) {
234+
dispatchAllowed = false;
235+
}
236+
clearDataMaskIds.push(id);
229237
setDataMaskSelected(draft => {
230-
if (draft[filterId].filterState?.value !== undefined) {
231-
draft[filterId].filterState!.value = undefined;
238+
if (draft[id].filterState?.value !== undefined) {
239+
draft[id].filterState!.value = undefined;
232240
}
233241
});
234242
}
235243
});
236-
}, [dataMaskSelected, dispatch, setDataMaskSelected]);
244+
if (dispatchAllowed) {
245+
clearDataMaskIds.forEach(id => dispatch(clearDataMask(id)));
246+
}
247+
}, [dataMaskSelected, dispatch, filtersInScope, setDataMaskSelected]);
237248

238249
useFilterUpdates(dataMaskSelected, setDataMaskSelected);
239250
const isApplyDisabled = checkIsApplyDisabled(
240251
dataMaskSelected,
241252
dataMaskApplied,
242-
nativeFilterValues,
253+
filtersInScope.filter(isNativeFilter),
243254
);
244255
const isInitialized = useInitialization();
245256

superset-frontend/src/dashboard/components/nativeFilters/state.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ function useSelectChartTabParents() {
8989
};
9090
}
9191

92-
function useIsFilterInScope() {
92+
export function useIsFilterInScope() {
9393
const activeTabs = useActiveDashboardTabs();
9494
const selectChartTabParents = useSelectChartTabParents();
9595

0 commit comments

Comments
 (0)