Skip to content

Commit

Permalink
Merge pull request #8637 from marmelab/fix-filterform-with-objects
Browse files Browse the repository at this point in the history
Fix `FilterForm` cannot clear filter with complex object value
  • Loading branch information
fzaninotto authored Feb 10, 2023
2 parents e0e9472 + 0fc8bdc commit 31b242d
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 14 deletions.
46 changes: 46 additions & 0 deletions packages/ra-ui-materialui/src/list/filter/FilterButton.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,79 +34,118 @@ const data = {
'Accusantium qui nihil voluptatum quia voluptas maxime ab similique',
body:
'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.',
nested: {
foo: 'bar',
},
},
{
id: 2,
title: 'Sint dignissimos in architecto aut',
body:
'Quam earum itaque corrupti labore quas nihil sed. Dolores sunt culpa voluptates exercitationem eveniet totam rerum. Molestias perspiciatis rem numquam accusamus.',
nested: {
foo: 'bar',
},
},
{
id: 3,
title: 'Perspiciatis adipisci vero qui ipsam iure porro',
body:
'Ut ad consequatur esse illum. Ex dolore porro et ut sit. Commodi qui sed et voluptatibus laudantium.',
nested: {
foo: 'bar',
},
},
{
id: 4,
title: 'Maiores et itaque aut perspiciatis',
body:
'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.',
nested: {
foo: 'bar',
},
},
{
id: 5,
title: 'Sed quo et et fugiat modi',
body:
'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.',
nested: {
foo: 'bar',
},
},
{
id: 6,
title: 'Minima ea vero omnis odit officiis aut',
body:
'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.',
nested: {
foo: 'bar',
},
},
{
id: 7,
title: 'Illum veritatis corrupti exercitationem sed velit',
body:
'Omnis hic quo aperiam fugiat iure amet est. Molestias ratione aut et dolor earum magnam placeat. Ad a quam ea amet hic omnis rerum.',
nested: {
foo: 'bar',
},
},
{
id: 8,
title:
'Culpa possimus quibusdam nostrum enim tempore rerum odit excepturi',
body:
'Qui quos exercitationem itaque quia. Repellat libero ut recusandae quidem repudiandae ipsam laudantium. Eveniet quos et quo omnis aut commodi incidunt.',
nested: {
foo: 'baz',
},
},
{
id: 9,
title: 'A voluptas eius eveniet ut commodi dolor',
body:
'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.',
nested: {
foo: 'baz',
},
},
{
id: 10,
title: 'Totam vel quasi a odio et nihil',
body:
'Excepturi veritatis velit rerum nemo voluptatem illum tempora eos. Et impedit sed qui et iusto. A alias asperiores quia quo.',
nested: {
foo: 'baz',
},
},
{
id: 11,
title: 'Omnis voluptate enim similique est possimus',
body:
'Velit eos vero reprehenderit ut assumenda saepe qui. Quasi aut laboriosam quas voluptate voluptatem. Et eos officia repudiandae quaerat. Mollitia libero numquam laborum eos.',
nested: {
foo: 'baz',
},
},
{
id: 12,
title: 'Qui tempore rerum et voluptates',
body:
'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.',
nested: {
foo: 'baz',
},
},
{
id: 13,
title: 'Fusce massa lorem, pulvinar a posuere ut, accumsan ac nisi',
body:
'Quam earum itaque corrupti labore quas nihil sed. Dolores sunt culpa voluptates exercitationem eveniet totam rerum. Molestias perspiciatis rem numquam accusamus.',
nested: {
foo: 'baz',
},
},
],
};
Expand Down Expand Up @@ -151,6 +190,13 @@ export const Basic = (args: { disableSaveQuery?: boolean }) => {
source="title"
defaultValue="Accusantium qui nihil voluptatum quia voluptas maxime ab similique"
/>,
<TextInput
label="Nested"
source="nested"
defaultValue={{ foo: 'bar' }}
format={v => v?.foo || ''}
parse={v => ({ foo: v })}
/>,
];
return (
<Admin dataProvider={fakerestDataProvider(data)}>
Expand Down
34 changes: 28 additions & 6 deletions packages/ra-ui-materialui/src/list/filter/FilterForm.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import * as React from 'react';
import expect from 'expect';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import expect from 'expect';
import {
ListContext,
minLength,
ResourceContextProvider,
testDataProvider,
} from 'ra-core';
import * as React from 'react';

import { AdminContext } from '../../AdminContext';
import { ReferenceInput, SelectInput, TextInput } from '../../input';
import { Filter } from './Filter';
import { Basic } from './FilterButton.stories';
import {
FilterForm,
getFilterFormValues,
mergeInitialValuesWithDefaultValues,
} from './FilterForm';
import { ReferenceInput, SelectInput, TextInput } from '../../input';
import { AdminContext } from '../../AdminContext';
import { Filter } from './Filter';

describe('<FilterForm />', () => {
const defaultProps = {
Expand Down Expand Up @@ -172,6 +173,27 @@ describe('<FilterForm />', () => {
});
});

it('should allow to add and clear a filter with a complex object value', async () => {
render(<Basic />);

const addFilterButton = await screen.findByText('Add filter');
fireEvent.click(addFilterButton);

fireEvent.click(await screen.findByText('Nested'));
await screen.findByDisplayValue('bar');
await screen.findByText('1-7 of 7');

fireEvent.change(screen.getByLabelText('Nested'), {
target: { value: 'baz' },
});
await screen.findByText('1-6 of 6');

fireEvent.click(await screen.findByTitle('Remove this filter'));
await screen.findByText('1-10 of 13');
expect(screen.queryByText('Nested')).toBeNull();
expect(screen.queryByLabelText('Nested')).toBeNull();
});

describe('mergeInitialValuesWithDefaultValues', () => {
it('should correctly merge initial values with the default values of the alwaysOn filters', () => {
const initialValues = {
Expand Down Expand Up @@ -233,7 +255,7 @@ describe('<FilterForm />', () => {
getFilterFormValues(currentFormValues, newFilterValues)
).toEqual({
classicToClear: '',
nestedToClear: { nestedValue: '' },
nestedToClear: '',
classicUpdated: 'ghi2',
nestedUpdated: { nestedValue: 'jkl2' },
published_at: '2022-01-01T03:00:00.000Z',
Expand Down
25 changes: 17 additions & 8 deletions packages/ra-ui-materialui/src/list/filter/FilterForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,23 @@ const getInputValue = (
return lodashGet(filterValues, key, '');
}
if (typeof formValues[key] === 'object') {
return Object.keys(formValues[key]).reduce((acc, innerKey) => {
acc[innerKey] = getInputValue(
formValues[key],
innerKey,
(filterValues || {})[key] ?? {}
);
return acc;
}, {});
const inputValues = Object.keys(formValues[key]).reduce(
(acc, innerKey) => {
const nestedInputValue = getInputValue(
formValues[key],
innerKey,
(filterValues || {})[key] ?? {}
);
if (nestedInputValue === '') {
return acc;
}
acc[innerKey] = nestedInputValue;
return acc;
},
{}
);
if (!Object.keys(inputValues).length) return '';
return inputValues;
}
return lodashGet(filterValues, key, '');
};

0 comments on commit 31b242d

Please sign in to comment.