Skip to content

Commit 31b242d

Browse files
authored
Merge pull request #8637 from marmelab/fix-filterform-with-objects
Fix `FilterForm` cannot clear filter with complex object value
2 parents e0e9472 + 0fc8bdc commit 31b242d

File tree

3 files changed

+91
-14
lines changed

3 files changed

+91
-14
lines changed

packages/ra-ui-materialui/src/list/filter/FilterButton.stories.tsx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,79 +34,118 @@ const data = {
3434
'Accusantium qui nihil voluptatum quia voluptas maxime ab similique',
3535
body:
3636
'In facilis aut aut odit hic doloribus. Fugit possimus perspiciatis sit molestias in. Sunt dignissimos sed quis at vitae veniam amet. Sint sunt perspiciatis quis doloribus aperiam numquam consequatur et. Blanditiis aut earum incidunt eos magnam et voluptatem. Minima iure voluptatum autem. At eaque sit aperiam minima aut in illum.',
37+
nested: {
38+
foo: 'bar',
39+
},
3740
},
3841
{
3942
id: 2,
4043
title: 'Sint dignissimos in architecto aut',
4144
body:
4245
'Quam earum itaque corrupti labore quas nihil sed. Dolores sunt culpa voluptates exercitationem eveniet totam rerum. Molestias perspiciatis rem numquam accusamus.',
46+
nested: {
47+
foo: 'bar',
48+
},
4349
},
4450
{
4551
id: 3,
4652
title: 'Perspiciatis adipisci vero qui ipsam iure porro',
4753
body:
4854
'Ut ad consequatur esse illum. Ex dolore porro et ut sit. Commodi qui sed et voluptatibus laudantium.',
55+
nested: {
56+
foo: 'bar',
57+
},
4958
},
5059
{
5160
id: 4,
5261
title: 'Maiores et itaque aut perspiciatis',
5362
body:
5463
'Et quo voluptas odit veniam omnis dolores. Odit commodi consequuntur necessitatibus dolorem officia. Reiciendis quas exercitationem libero sed. Itaque non facilis sit tempore aut doloribus.',
64+
nested: {
65+
foo: 'bar',
66+
},
5567
},
5668
{
5769
id: 5,
5870
title: 'Sed quo et et fugiat modi',
5971
body:
6072
'Consequuntur id aut soluta aspernatur sit. Aut doloremque recusandae sit saepe ut quas earum. Quae pariatur iure et ducimus non. Cupiditate dolorem itaque in sit.',
73+
nested: {
74+
foo: 'bar',
75+
},
6176
},
6277
{
6378
id: 6,
6479
title: 'Minima ea vero omnis odit officiis aut',
6580
body:
6681
'Omnis rerum voluptatem illum. Amet totam minus id qui aspernatur. Adipisci commodi velit sapiente architecto et molestias. Maiores doloribus quis occaecati quidem laborum. Quae quia quaerat est itaque. Vero assumenda quia tempora libero dicta quis asperiores magnam. Necessitatibus accusantium saepe commodi ut.',
82+
nested: {
83+
foo: 'bar',
84+
},
6785
},
6886
{
6987
id: 7,
7088
title: 'Illum veritatis corrupti exercitationem sed velit',
7189
body:
7290
'Omnis hic quo aperiam fugiat iure amet est. Molestias ratione aut et dolor earum magnam placeat. Ad a quam ea amet hic omnis rerum.',
91+
nested: {
92+
foo: 'bar',
93+
},
7394
},
7495
{
7596
id: 8,
7697
title:
7798
'Culpa possimus quibusdam nostrum enim tempore rerum odit excepturi',
7899
body:
79100
'Qui quos exercitationem itaque quia. Repellat libero ut recusandae quidem repudiandae ipsam laudantium. Eveniet quos et quo omnis aut commodi incidunt.',
101+
nested: {
102+
foo: 'baz',
103+
},
80104
},
81105
{
82106
id: 9,
83107
title: 'A voluptas eius eveniet ut commodi dolor',
84108
body:
85109
'Sed necessitatibus nesciunt nesciunt aut non sunt. Quam ut in a sed ducimus eos qui sint. Commodi illo necessitatibus sint explicabo maiores. Maxime voluptates sit distinctio quo excepturi. Qui aliquid debitis repellendus distinctio et aut. Ex debitis et quasi id.',
110+
nested: {
111+
foo: 'baz',
112+
},
86113
},
87114
{
88115
id: 10,
89116
title: 'Totam vel quasi a odio et nihil',
90117
body:
91118
'Excepturi veritatis velit rerum nemo voluptatem illum tempora eos. Et impedit sed qui et iusto. A alias asperiores quia quo.',
119+
nested: {
120+
foo: 'baz',
121+
},
92122
},
93123
{
94124
id: 11,
95125
title: 'Omnis voluptate enim similique est possimus',
96126
body:
97127
'Velit eos vero reprehenderit ut assumenda saepe qui. Quasi aut laboriosam quas voluptate voluptatem. Et eos officia repudiandae quaerat. Mollitia libero numquam laborum eos.',
128+
nested: {
129+
foo: 'baz',
130+
},
98131
},
99132
{
100133
id: 12,
101134
title: 'Qui tempore rerum et voluptates',
102135
body:
103136
'Occaecati rem perferendis dolor aut numquam cupiditate. At tenetur dolores pariatur et libero asperiores porro voluptas. Officiis corporis sed eos repellendus perferendis distinctio hic consequatur.',
137+
nested: {
138+
foo: 'baz',
139+
},
104140
},
105141
{
106142
id: 13,
107143
title: 'Fusce massa lorem, pulvinar a posuere ut, accumsan ac nisi',
108144
body:
109145
'Quam earum itaque corrupti labore quas nihil sed. Dolores sunt culpa voluptates exercitationem eveniet totam rerum. Molestias perspiciatis rem numquam accusamus.',
146+
nested: {
147+
foo: 'baz',
148+
},
110149
},
111150
],
112151
};
@@ -151,6 +190,13 @@ export const Basic = (args: { disableSaveQuery?: boolean }) => {
151190
source="title"
152191
defaultValue="Accusantium qui nihil voluptatum quia voluptas maxime ab similique"
153192
/>,
193+
<TextInput
194+
label="Nested"
195+
source="nested"
196+
defaultValue={{ foo: 'bar' }}
197+
format={v => v?.foo || ''}
198+
parse={v => ({ foo: v })}
199+
/>,
154200
];
155201
return (
156202
<Admin dataProvider={fakerestDataProvider(data)}>

packages/ra-ui-materialui/src/list/filter/FilterForm.spec.tsx

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
1-
import * as React from 'react';
2-
import expect from 'expect';
31
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
2+
import expect from 'expect';
43
import {
54
ListContext,
65
minLength,
76
ResourceContextProvider,
87
testDataProvider,
98
} from 'ra-core';
9+
import * as React from 'react';
1010

11+
import { AdminContext } from '../../AdminContext';
12+
import { ReferenceInput, SelectInput, TextInput } from '../../input';
13+
import { Filter } from './Filter';
14+
import { Basic } from './FilterButton.stories';
1115
import {
1216
FilterForm,
1317
getFilterFormValues,
1418
mergeInitialValuesWithDefaultValues,
1519
} from './FilterForm';
16-
import { ReferenceInput, SelectInput, TextInput } from '../../input';
17-
import { AdminContext } from '../../AdminContext';
18-
import { Filter } from './Filter';
1920

2021
describe('<FilterForm />', () => {
2122
const defaultProps = {
@@ -172,6 +173,27 @@ describe('<FilterForm />', () => {
172173
});
173174
});
174175

176+
it('should allow to add and clear a filter with a complex object value', async () => {
177+
render(<Basic />);
178+
179+
const addFilterButton = await screen.findByText('Add filter');
180+
fireEvent.click(addFilterButton);
181+
182+
fireEvent.click(await screen.findByText('Nested'));
183+
await screen.findByDisplayValue('bar');
184+
await screen.findByText('1-7 of 7');
185+
186+
fireEvent.change(screen.getByLabelText('Nested'), {
187+
target: { value: 'baz' },
188+
});
189+
await screen.findByText('1-6 of 6');
190+
191+
fireEvent.click(await screen.findByTitle('Remove this filter'));
192+
await screen.findByText('1-10 of 13');
193+
expect(screen.queryByText('Nested')).toBeNull();
194+
expect(screen.queryByLabelText('Nested')).toBeNull();
195+
});
196+
175197
describe('mergeInitialValuesWithDefaultValues', () => {
176198
it('should correctly merge initial values with the default values of the alwaysOn filters', () => {
177199
const initialValues = {
@@ -233,7 +255,7 @@ describe('<FilterForm />', () => {
233255
getFilterFormValues(currentFormValues, newFilterValues)
234256
).toEqual({
235257
classicToClear: '',
236-
nestedToClear: { nestedValue: '' },
258+
nestedToClear: '',
237259
classicUpdated: 'ghi2',
238260
nestedUpdated: { nestedValue: 'jkl2' },
239261
published_at: '2022-01-01T03:00:00.000Z',

packages/ra-ui-materialui/src/list/filter/FilterForm.tsx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -256,14 +256,23 @@ const getInputValue = (
256256
return lodashGet(filterValues, key, '');
257257
}
258258
if (typeof formValues[key] === 'object') {
259-
return Object.keys(formValues[key]).reduce((acc, innerKey) => {
260-
acc[innerKey] = getInputValue(
261-
formValues[key],
262-
innerKey,
263-
(filterValues || {})[key] ?? {}
264-
);
265-
return acc;
266-
}, {});
259+
const inputValues = Object.keys(formValues[key]).reduce(
260+
(acc, innerKey) => {
261+
const nestedInputValue = getInputValue(
262+
formValues[key],
263+
innerKey,
264+
(filterValues || {})[key] ?? {}
265+
);
266+
if (nestedInputValue === '') {
267+
return acc;
268+
}
269+
acc[innerKey] = nestedInputValue;
270+
return acc;
271+
},
272+
{}
273+
);
274+
if (!Object.keys(inputValues).length) return '';
275+
return inputValues;
267276
}
268277
return lodashGet(filterValues, key, '');
269278
};

0 commit comments

Comments
 (0)