mirror of
https://github.com/apache/superset.git
synced 2026-04-16 06:34:52 +00:00
fix(native-filters): Filters with select first value not restored correctly from url (#37855)
This commit is contained in:
committed by
GitHub
parent
76aa91f5ea
commit
7ec5f1d7ec
@@ -1131,3 +1131,121 @@ test('Clear boolean TRUE value', async () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('preserves dependent filter value restored from URL when it exists in data', async () => {
|
||||
const setDataMaskMock = jest.fn();
|
||||
const testProps = {
|
||||
...selectMultipleProps,
|
||||
formData: {
|
||||
...selectMultipleProps.formData,
|
||||
defaultToFirstItem: true,
|
||||
multiSelect: false,
|
||||
// Non-empty extraFormData indicates parent filter dependency
|
||||
extraFormData: {
|
||||
filters: [{ col: 'region', op: 'IN', val: ['North America'] }],
|
||||
},
|
||||
},
|
||||
// 'girl' is NOT the first item but exists in data — simulates a
|
||||
// value restored from URL/permalink for a dependent filter
|
||||
filterState: { value: ['girl'] },
|
||||
};
|
||||
|
||||
render(
|
||||
// @ts-expect-error
|
||||
<SelectFilterPlugin
|
||||
// @ts-expect-error
|
||||
{...transformProps(testProps)}
|
||||
setDataMask={setDataMaskMock}
|
||||
showOverflow={false}
|
||||
/>,
|
||||
{
|
||||
useRedux: true,
|
||||
initialState: {
|
||||
nativeFilters: {
|
||||
filters: {
|
||||
'test-filter': {
|
||||
name: 'Test Filter',
|
||||
},
|
||||
},
|
||||
},
|
||||
dataMask: {
|
||||
'test-filter': {
|
||||
extraFormData: {},
|
||||
filterState: {
|
||||
value: ['girl'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(setDataMaskMock).toHaveBeenLastCalledWith(
|
||||
expect.objectContaining({
|
||||
filterState: expect.objectContaining({
|
||||
value: ['girl'],
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('resets dependent filter to first item when value does not exist in data', async () => {
|
||||
const setDataMaskMock = jest.fn();
|
||||
const testProps = {
|
||||
...selectMultipleProps,
|
||||
formData: {
|
||||
...selectMultipleProps.formData,
|
||||
defaultToFirstItem: true,
|
||||
multiSelect: false,
|
||||
extraFormData: {
|
||||
filters: [{ col: 'region', op: 'IN', val: ['North America'] }],
|
||||
},
|
||||
},
|
||||
// 'unknown' does NOT exist in data — simulates a stale value after
|
||||
// parent filter changed to a different selection
|
||||
filterState: { value: ['unknown'] },
|
||||
};
|
||||
|
||||
render(
|
||||
// @ts-expect-error
|
||||
<SelectFilterPlugin
|
||||
// @ts-expect-error
|
||||
{...transformProps(testProps)}
|
||||
setDataMask={setDataMaskMock}
|
||||
showOverflow={false}
|
||||
/>,
|
||||
{
|
||||
useRedux: true,
|
||||
initialState: {
|
||||
nativeFilters: {
|
||||
filters: {
|
||||
'test-filter': {
|
||||
name: 'Test Filter',
|
||||
},
|
||||
},
|
||||
},
|
||||
dataMask: {
|
||||
'test-filter': {
|
||||
extraFormData: {},
|
||||
filterState: {
|
||||
value: ['unknown'],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(setDataMaskMock).toHaveBeenLastCalledWith(
|
||||
expect.objectContaining({
|
||||
filterState: expect.objectContaining({
|
||||
// Should reset to first item ('boy') since 'unknown' is not in data
|
||||
value: ['boy'],
|
||||
}),
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -151,7 +151,6 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
|
||||
const [col] = groupby;
|
||||
const [initialColtypeMap] = useState(coltypeMap);
|
||||
const [search, setSearch] = useState('');
|
||||
const isChangedByUser = useRef(false);
|
||||
const prevDataRef = useRef(data);
|
||||
const [dataMask, dispatchDataMask] = useImmerReducer(reducer, {
|
||||
extraFormData: {},
|
||||
@@ -273,8 +272,6 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
|
||||
} else {
|
||||
updateDataMask(values);
|
||||
}
|
||||
|
||||
isChangedByUser.current = true;
|
||||
},
|
||||
[updateDataMask, formData.nativeFilterId, clearAllTrigger],
|
||||
);
|
||||
@@ -400,14 +397,12 @@ export default function PluginFilterSelect(props: PluginFilterSelectProps) {
|
||||
|
||||
// If data actually changed (e.g., due to parent filter), reset flag
|
||||
if (hasDataChanged) {
|
||||
isChangedByUser.current = false;
|
||||
prevDataRef.current = data;
|
||||
}
|
||||
}, [data, col]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
isChangedByUser.current &&
|
||||
filterState.value?.every((value?: any) =>
|
||||
data.some(row => row[col] === value),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user