From dbe440c4b0fad7a0664456b1793d473c55966443 Mon Sep 17 00:00:00 2001 From: MonireRasouli Date: Tue, 17 Dec 2024 21:33:25 +0000 Subject: [PATCH 1/3] ERM-3452, Centralise content filter array used in Licenses and Agreements --- index.js | 1 + lib/DocumentFilter/DocumentFilterArray.js | 136 ++++++++++++++++++++ translations/stripes-erm-components/en.json | 2 + 3 files changed, 139 insertions(+) create mode 100644 lib/DocumentFilter/DocumentFilterArray.js diff --git a/index.js b/index.js index a70394da..0761d899 100644 --- a/index.js +++ b/index.js @@ -7,6 +7,7 @@ export { default as DocumentCard } from './lib/DocumentCard'; export { default as DocumentFilter } from './lib/DocumentFilter'; export { default as DocumentFilterForm } from './lib/DocumentFilter/DocumentFilterForm'; export { default as DocumentFilterFieldArray } from './lib/DocumentFilter/DocumentFilterFieldArray'; +export { default as DocumentFilterArray } from './lib/DocumentFilter/DocumentFilterArray'; export { default as DocumentsFieldArray } from './lib/DocumentsFieldArray'; export { default as DuplicateModal } from './lib/DuplicateModal'; export { default as EditCard } from './lib/EditCard'; diff --git a/lib/DocumentFilter/DocumentFilterArray.js b/lib/DocumentFilter/DocumentFilterArray.js new file mode 100644 index 00000000..a4a04763 --- /dev/null +++ b/lib/DocumentFilter/DocumentFilterArray.js @@ -0,0 +1,136 @@ +import PropTypes from 'prop-types'; +import { useState } from 'react'; +import { Field, useForm, useFormState } from 'react-final-form'; +import { FieldArray } from 'react-final-form-arrays'; +import { FormattedMessage, useIntl } from 'react-intl'; +import { + Dropdown, + DropdownMenu, + MultiSelection, + Select, + Button, + Label, + IconButton, + Row, + Col, +} from '@folio/stripes/components'; + +const DocumentFilterArray = ({ translatedContentOptions, handleSubmit, name }) => { + const [open, setOpen] = useState(false); + const { values } = useFormState(); + const { change } = useForm(); + + const intl = useIntl(); + + return ( + + {({ fields }) => ( + <> + {fields?.map((filter, index) => { + return ( +
+ {values?.[name][index]?.grouping === '&&' && ( + + )} + {values?.[name][index]?.grouping === '||' && ( + + )} + + + { + change(`${filter}.attribute`, e?.target?.value); + handleSubmit(); + }} + /> + { + change(`${filter}.content`, e); + handleSubmit(); + }} + /> + + {index !== 0 && ( + + { + e.stopPropagation(); + fields.remove(index); + handleSubmit(); + }} + /> + + )} + +
+ ); + })} + + } + onToggle={() => setOpen(!open)} + open={open} + > + + + + + + + )} +
+ ); +}; + +DocumentFilterArray.propTypes = { + translatedContentOptions: PropTypes.arrayOf(PropTypes.object), + handleSubmit: PropTypes.func, + name: PropTypes.string, +}; + +export default DocumentFilterArray; diff --git a/translations/stripes-erm-components/en.json b/translations/stripes-erm-components/en.json index 1daed908..abd01b51 100644 --- a/translations/stripes-erm-components/en.json +++ b/translations/stripes-erm-components/en.json @@ -218,6 +218,8 @@ "documentFilter.comparator": "Comparator", "documentFilter.addRule": "Add rule", "documentFilter.removeRule": "Remove rule {number}", + "documentFilter.has": "Has", + "documentFilter.hasNot": "Has not", "comparator": "Operator", "value": "Value", "contentType": "Content type", From 95f91f4f2b8323185b82f82f3a7b45b1ff85b534 Mon Sep 17 00:00:00 2001 From: MonireRasouli Date: Fri, 20 Dec 2024 16:13:44 +0000 Subject: [PATCH 2/3] add test for DocumentFilterArray --- .../DocumentFilterArray.test.js | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 lib/DocumentFilter/DocumentFilterArray.test.js diff --git a/lib/DocumentFilter/DocumentFilterArray.test.js b/lib/DocumentFilter/DocumentFilterArray.test.js new file mode 100644 index 00000000..ba1b4d4e --- /dev/null +++ b/lib/DocumentFilter/DocumentFilterArray.test.js @@ -0,0 +1,124 @@ +import { MemoryRouter } from 'react-router-dom'; +import { screen } from'@testing-library/react'; +import { waitFor } from '@folio/jest-config-stripes/testing-library/react'; +import { renderWithIntl, Button, TestForm, Dropdown} from '@folio/stripes-erm-testing'; + +import { translationsProperties } from '../../test/jest/helpers'; + +import DocumentFilterArray from './DocumentFilterArray'; +const handleSubmit = jest.fn(); +const translatedContentOptions = [ + { + "value": "alternateNames", + "label": "Alternative names" + }, + { + "value": "agreementContentTypes", + "label": "Content types" + }, + { + "value": "contacts", + "label": "Internal contacts" + }, + { + "value": "orgs", + "label": "Organizations" + }, + { + "value": "items", + "label": "Agreement lines" + }, + { + "value": "linkedLicenses", + "label": "Linked licenses" + }, + { + "value": "externalLicenseDocs", + "label": "External licenses" + }, + { + "value": "supplementaryDocs", + "label": "Supplementary documents" + }, + { + "value": "usageDataProviders", + "label": "Usage data" + }, + { + "value": "relatedAgreements", + "label": "Related agreements" + }, + { + "value": "tags", + "label": "Tags" + } +]; +const onSubmit = jest.fn(); +jest.mock('./DocumentFilterField', () => () =>
DocumentFilterField
); + +let renderComponent; +describe('DocumentFilterArray', () => { + beforeEach(() => { + renderComponent = renderWithIntl( + + + + , + , + translationsProperties + ); + }); + + test('renders the And/Or dropdown button', async () => { + await Dropdown('Add filter').exists(); + }); + + describe('clicking \'Add filter\' button', () => { + beforeEach(async () => { + await waitFor(async () => { + await Button('Add filter').click(); + }); + }); + + it('should render the \'AND\' and \'OR\' dropdown buttons', async () => { + await Button('AND').exists(); + await Button('OR').exists(); + }); + }); + + describe('clicking \'OR\' button', () => { + beforeEach(async () => { + await waitFor(async () => { + await Button('Add filter').click(); + await Button('OR').click(); + }); + }); + + it('should display the OR label', async () => { + const { getAllByText } = renderComponent; + await waitFor(async () => { + expect(getAllByText('OR').length).toEqual(2); + }); + }); + }); + + describe('clicking \'AND\' button', () => { + beforeEach(async () => { + await waitFor(async () => { + await Button('Add filter').click(); + await Button('AND').click(); + }); + }); + + it('should display the AND label', async () => { + const { getAllByText } = renderComponent; + await waitFor(async () => { + expect(getAllByText('AND').length).toEqual(2); + }); + }); + }); +}); From c4d0eecde2879bf2b5b9e2105f50d4b95a14c3e2 Mon Sep 17 00:00:00 2001 From: MonireRasouli Date: Wed, 15 Jan 2025 11:56:50 +0000 Subject: [PATCH 3/3] lint --- .../DocumentFilterArray.test.js | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/lib/DocumentFilter/DocumentFilterArray.test.js b/lib/DocumentFilter/DocumentFilterArray.test.js index ba1b4d4e..419559a5 100644 --- a/lib/DocumentFilter/DocumentFilterArray.test.js +++ b/lib/DocumentFilter/DocumentFilterArray.test.js @@ -1,56 +1,56 @@ import { MemoryRouter } from 'react-router-dom'; -import { screen } from'@testing-library/react'; import { waitFor } from '@folio/jest-config-stripes/testing-library/react'; -import { renderWithIntl, Button, TestForm, Dropdown} from '@folio/stripes-erm-testing'; +import { renderWithIntl, Button, TestForm, Dropdown } from '@folio/stripes-erm-testing'; import { translationsProperties } from '../../test/jest/helpers'; import DocumentFilterArray from './DocumentFilterArray'; + const handleSubmit = jest.fn(); const translatedContentOptions = [ { - "value": "alternateNames", - "label": "Alternative names" + 'value': 'alternateNames', + 'label': 'Alternative names' }, { - "value": "agreementContentTypes", - "label": "Content types" + 'value': 'agreementContentTypes', + 'label': 'Content types' }, { - "value": "contacts", - "label": "Internal contacts" + 'value': 'contacts', + 'label': 'Internal contacts' }, { - "value": "orgs", - "label": "Organizations" + 'value': 'orgs', + 'label': 'Organizations' }, { - "value": "items", - "label": "Agreement lines" + 'value': 'items', + 'label': 'Agreement lines' }, { - "value": "linkedLicenses", - "label": "Linked licenses" + 'value': 'linkedLicenses', + 'label': 'Linked licenses' }, { - "value": "externalLicenseDocs", - "label": "External licenses" + 'value': 'externalLicenseDocs', + 'label': 'External licenses' }, { - "value": "supplementaryDocs", - "label": "Supplementary documents" + 'value': 'supplementaryDocs', + 'label': 'Supplementary documents' }, { - "value": "usageDataProviders", - "label": "Usage data" + 'value': 'usageDataProviders', + 'label': 'Usage data' }, { - "value": "relatedAgreements", - "label": "Related agreements" + 'value': 'relatedAgreements', + 'label': 'Related agreements' }, { - "value": "tags", - "label": "Tags" + 'value': 'tags', + 'label': 'Tags' } ]; const onSubmit = jest.fn(); @@ -63,9 +63,9 @@ describe('DocumentFilterArray', () => { , ,