From ca1bfa348b801f890c44037d9bf3e668f7fe5fac Mon Sep 17 00:00:00 2001 From: JulienM Date: Mon, 9 Mar 2020 10:48:12 +0100 Subject: [PATCH 1/8] Remove unselected items from list in Reference Array input --- examples/simple/src/posts/PostEdit.js | 11 ++--- .../simple/src/posts/TagReferenceInput.js | 46 +++++++++++++++++++ .../input/useReferenceArrayInputController.ts | 5 +- 3 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 examples/simple/src/posts/TagReferenceInput.js diff --git a/examples/simple/src/posts/PostEdit.js b/examples/simple/src/posts/PostEdit.js index c97042246b9..7350e37e0fe 100644 --- a/examples/simple/src/posts/PostEdit.js +++ b/examples/simple/src/posts/PostEdit.js @@ -2,7 +2,6 @@ import RichTextInput from 'ra-input-rich-text'; import React from 'react'; import { TopToolbar, - AutocompleteArrayInput, AutocompleteInput, ArrayInput, BooleanInput, @@ -18,7 +17,6 @@ import { ImageField, ImageInput, NumberInput, - ReferenceArrayInput, ReferenceManyField, ReferenceInput, SelectInput, @@ -32,6 +30,7 @@ import { FormDataConsumer, } from 'react-admin'; // eslint-disable-line import/no-unresolved import PostTitle from './PostTitle'; +import TagReferenceInput from './TagReferenceInput'; const EditActions = ({ basePath, data, hasShow }) => ( @@ -121,13 +120,11 @@ const PostEdit = ({ permissions, ...props }) => ( /> - - - + label="Tags" + /> diff --git a/examples/simple/src/posts/TagReferenceInput.js b/examples/simple/src/posts/TagReferenceInput.js new file mode 100644 index 00000000000..a21fa7e0566 --- /dev/null +++ b/examples/simple/src/posts/TagReferenceInput.js @@ -0,0 +1,46 @@ +import React, { useState } from 'react'; +import { useForm } from 'react-final-form'; +import { AutocompleteArrayInput, ReferenceArrayInput } from 'react-admin'; +import Button from '@material-ui/core/Button'; +import { makeStyles } from '@material-ui/core/styles'; + +const useStyles = makeStyles({ + button: { + margin: '0 24px', + position: 'relative', + }, + input: { + display: 'flex', + flexDirection: 'row', + justifyContent: 'flex-start', + width: '50%', + }, +}); + +const TagReferenceInput = ({ ...props }) => { + const classes = useStyles(); + const { change } = useForm(); + const [filter, setFilter] = useState(true); + + const handleAddFilter = () => { + setFilter(!filter); + change('tags', []); + }; + + return ( +
+ + + + +
+ ); +}; + +export default TagReferenceInput; diff --git a/packages/ra-core/src/controller/input/useReferenceArrayInputController.ts b/packages/ra-core/src/controller/input/useReferenceArrayInputController.ts index e8da163c4f3..b615db6f872 100644 --- a/packages/ra-core/src/controller/input/useReferenceArrayInputController.ts +++ b/packages/ra-core/src/controller/input/useReferenceArrayInputController.ts @@ -105,7 +105,10 @@ const useReferenceArrayInputController = ({ : referenceRecordsFromStore; // filter out not found references - happens when the dataProvider doesn't guarantee referential integrity - const finalReferenceRecords = referenceRecords.filter(Boolean); + // filter out not selected items - happens when the form value is changed by script (i.e. Filtering button) + const finalReferenceRecords = referenceRecords + .filter(Boolean) + .filter(item => item === undefined || input.value.includes(item.id)); const { data: matchingReferences } = useGetMatching( reference, From b69c477b17a87da9612703157931e461f036a347 Mon Sep 17 00:00:00 2001 From: JulienM Date: Mon, 9 Mar 2020 11:14:53 +0100 Subject: [PATCH 2/8] clean --- cypress/integration/list.js | 2 +- .../src/controller/input/useReferenceArrayInputController.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cypress/integration/list.js b/cypress/integration/list.js index 62261f4abf6..71985adefef 100644 --- a/cypress/integration/list.js +++ b/cypress/integration/list.js @@ -96,7 +96,7 @@ describe('List Page', () => { ListPagePosts.setFilterValue('q', ''); }); - it('should keep added filters when emptying it after navigating away and back', () => { + it.only('should keep added filters when emptying it after navigating away and back', () => { ListPagePosts.logout(); LoginPage.login('admin', 'password'); ListPagePosts.showFilter('title'); diff --git a/packages/ra-core/src/controller/input/useReferenceArrayInputController.ts b/packages/ra-core/src/controller/input/useReferenceArrayInputController.ts index b615db6f872..696b1ee25b8 100644 --- a/packages/ra-core/src/controller/input/useReferenceArrayInputController.ts +++ b/packages/ra-core/src/controller/input/useReferenceArrayInputController.ts @@ -105,10 +105,10 @@ const useReferenceArrayInputController = ({ : referenceRecordsFromStore; // filter out not found references - happens when the dataProvider doesn't guarantee referential integrity - // filter out not selected items - happens when the form value is changed by script (i.e. Filtering button) + // filter out not selected items - happens when the form value is changed by script (i.e. with a filtering Button) const finalReferenceRecords = referenceRecords .filter(Boolean) - .filter(item => item === undefined || input.value.includes(item.id)); + .filter(item => input.value.includes(item.id)); const { data: matchingReferences } = useGetMatching( reference, From 7ede23d1c9029afde2e98e23c1bd922d58279708 Mon Sep 17 00:00:00 2001 From: JulienM Date: Mon, 9 Mar 2020 11:26:21 +0100 Subject: [PATCH 3/8] remove .only --- cypress/integration/list.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/integration/list.js b/cypress/integration/list.js index 71985adefef..62261f4abf6 100644 --- a/cypress/integration/list.js +++ b/cypress/integration/list.js @@ -96,7 +96,7 @@ describe('List Page', () => { ListPagePosts.setFilterValue('q', ''); }); - it.only('should keep added filters when emptying it after navigating away and back', () => { + it('should keep added filters when emptying it after navigating away and back', () => { ListPagePosts.logout(); LoginPage.login('admin', 'password'); ListPagePosts.showFilter('title'); From bb5f7f86b386b5725fdb9c79d65626a4e6e6fa4c Mon Sep 17 00:00:00 2001 From: JulienM Date: Mon, 9 Mar 2020 15:33:36 +0100 Subject: [PATCH 4/8] test --- cypress/integration/edit.js | 35 +++++++++++++++++++ cypress/support/EditPage.js | 7 ++-- .../simple/src/posts/TagReferenceInput.js | 2 +- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/cypress/integration/edit.js b/cypress/integration/edit.js index c16a2fac369..64a882113fb 100644 --- a/cypress/integration/edit.js +++ b/cypress/integration/edit.js @@ -68,6 +68,41 @@ describe('Edit Page', () => { expect(el).to.have.value(date) ); }); + + it('should change reference list correctly when changing filter', () => { + const EditPostTagsPage = editPageFactory('/#/posts/13'); + EditPostTagsPage.navigate(); + EditPostTagsPage.gotoTab(3); + + // Music is selected by default + cy.get( + EditPostTagsPage.elements.input('tags', 'reference-array-input') + ) + .get(`div[role=button]`) + .contains('Music') + .should('exist'); + + EditPostTagsPage.clickInput('change-filter'); + + // Music should not be selected anymore after filter reset + cy.get( + EditPostTagsPage.elements.input('tags', 'reference-array-input') + ) + .get(`div[role=button]`) + .contains('Music') + .should('not.exist'); + + EditPostTagsPage.clickInput('tags', 'reference-array-input'); + + // Music should not be visible in the list after filter reset + cy.get('div[role=listbox]') + .contains('Music') + .should('not.exist'); + + cy.get('div[role=listbox]') + .contains('Photo') + .should('exist'); + }); }); it('should fill form correctly even when switching from one form type to another', () => { diff --git a/cypress/support/EditPage.js b/cypress/support/EditPage.js index 61c896d106c..c6084bfed06 100644 --- a/cypress/support/EditPage.js +++ b/cypress/support/EditPage.js @@ -6,6 +6,9 @@ export default url => ({ if (type === 'rich-text-input') { return `.ra-input-${name} .ql-editor`; } + if (type === 'reference-array-input') { + return `.ra-input div[role=combobox]`; + } return `.edit-page [name='${name}']`; }, inputs: `.ra-input`, @@ -37,8 +40,8 @@ export default url => ({ } }, - clickInput(name) { - cy.get(this.elements.input(name)).click(); + clickInput(name, type = 'input') { + cy.get(this.elements.input(name, type)).click(); }, gotoTab(index) { diff --git a/examples/simple/src/posts/TagReferenceInput.js b/examples/simple/src/posts/TagReferenceInput.js index a21fa7e0566..f529879ac90 100644 --- a/examples/simple/src/posts/TagReferenceInput.js +++ b/examples/simple/src/posts/TagReferenceInput.js @@ -33,7 +33,7 @@ const TagReferenceInput = ({ ...props }) => {