From 31f95e9842aa534968751dbd872ddac9103ebd5d Mon Sep 17 00:00:00 2001 From: Alisher Musurmonov Date: Wed, 15 Nov 2023 17:01:53 +0500 Subject: [PATCH 1/8] UISACQCOMP-168: extend `` component props --- CHANGELOG.md | 1 + lib/Donors/Donors.js | 23 +++++++++++++++++++---- lib/Donors/DonorsContainer.js | 15 ++++++++++----- lib/Donors/index.js | 1 + lib/Donors/utils.js | 8 +++++++- lib/Donors/utils.test.js | 1 + 6 files changed, 39 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a01447d..4d3862fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Add `inputType` prop to ``. Refs UISACQCOMP-165. * View the list of donors. Refs UISACQCOMP-166. * Added `indexRef` and `inputRef` props to ``. Refs UISACQCOMP-167. +* Extend Donors component functionality. Refs UISACQCOMP-168. ## [5.0.0](https://github.com/folio-org/stripes-acq-components/tree/v5.0.0) (2023-10-12) [Full Changelog](https://github.com/folio-org/stripes-acq-components/compare/v4.0.2...v5.0.0) diff --git a/lib/Donors/Donors.js b/lib/Donors/Donors.js index 6c314c6b..ba15fa1b 100644 --- a/lib/Donors/Donors.js +++ b/lib/Donors/Donors.js @@ -1,6 +1,7 @@ +import { noop } from 'lodash'; import PropTypes from 'prop-types'; import { FieldArray } from 'react-final-form-arrays'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { Col, @@ -12,10 +13,19 @@ import { defaultColumnMapping } from './constants'; import { DonorsContainer } from './DonorsContainer'; import { useFetchDonors } from './hooks'; -export function Donors({ name, donorOrganizationIds, ...rest }) { +export function Donors({ name, donorOrganizationIds, onChange, ...rest }) { const [donorIds, setDonorIds] = useState(donorOrganizationIds); const { donors, isLoading } = useFetchDonors(donorIds); + useEffect(() => { + setDonorIds(donorOrganizationIds); + }, [donorOrganizationIds]); + + const onSetDonorIds = (values = []) => { + setDonorIds(values); + onChange(values); + }; + if (isLoading) { return ; } @@ -27,8 +37,9 @@ export function Donors({ name, donorOrganizationIds, ...rest }) { name={name} id={name} component={DonorsContainer} - setDonorIds={setDonorIds} + setDonorIds={onSetDonorIds} donors={donors} + donorIds={donorIds} {...rest} /> @@ -41,13 +52,17 @@ Donors.propTypes = { columnWidths: PropTypes.object, donorOrganizationIds: PropTypes.arrayOf(PropTypes.string), name: PropTypes.string, + onChange: PropTypes.func, + onRemove: PropTypes.func, searchLabel: PropTypes.node, showTriggerButton: PropTypes.bool, visibleColumns: PropTypes.arrayOf(PropTypes.string), }; Donors.defaultProps = { + columnMapping: defaultColumnMapping, donorOrganizationIds: [], name: 'donorOrganizationIds', - columnMapping: defaultColumnMapping, + onChange: noop, + onRemove: noop, }; diff --git a/lib/Donors/DonorsContainer.js b/lib/Donors/DonorsContainer.js index 60add8db..65e2ae08 100644 --- a/lib/Donors/DonorsContainer.js +++ b/lib/Donors/DonorsContainer.js @@ -1,4 +1,4 @@ -import { map, sortBy } from 'lodash'; +import { map, noop, sortBy } from 'lodash'; import PropTypes from 'prop-types'; import { useMemo } from 'react'; import { useIntl } from 'react-intl'; @@ -14,9 +14,11 @@ export function DonorsContainer({ columnMapping, columnWidths, donors, + donorIds, fields, formatter, id, + onRemove, setDonorIds, searchLabel, showTriggerButton, @@ -35,7 +37,7 @@ export function DonorsContainer({ }, {}); }, [donors]); - const listOfDonors = useMemo(() => (fields.value || []) + const listOfDonors = useMemo(() => (donorIds || []) .map((contactId, _index) => { const contact = donorsMap?.[contactId]; @@ -43,13 +45,13 @@ export function DonorsContainer({ ...(contact || { isDeleted: true }), _index, }; - }), [donorsMap, fields.value]); + }), [donorIds, donorsMap]); const contentData = useMemo(() => sortBy(listOfDonors, [({ lastName }) => lastName?.toLowerCase()]), [listOfDonors]); const resultsFormatter = useMemo(() => { - return formatter || getDonorsFormatter({ intl, fields, canViewOrganizations }); - }, [canViewOrganizations, fields, formatter, intl]); + return formatter || getDonorsFormatter({ intl, fields, canViewOrganizations, onRemove }); + }, [canViewOrganizations, fields, formatter, intl, onRemove]); const onAddDonors = (values = []) => { const addedDonorIds = new Set(fields.value); @@ -91,9 +93,11 @@ DonorsContainer.propTypes = { columnWidths: PropTypes.object, columnMapping: PropTypes.object, donors: PropTypes.arrayOf(PropTypes.object), + donorIds: PropTypes.arrayOf(PropTypes.string), fields: PropTypes.object, formatter: PropTypes.object, id: PropTypes.string, + onRemove: PropTypes.func, searchLabel: PropTypes.node, setDonorIds: PropTypes.func.isRequired, showTriggerButton: PropTypes.bool, @@ -101,6 +105,7 @@ DonorsContainer.propTypes = { }; DonorsContainer.defaultProps = { + onRemove: noop, showTriggerButton: true, visibleColumns: defaultContainerVisibleColumns, }; diff --git a/lib/Donors/index.js b/lib/Donors/index.js index f625423c..0a0e73f6 100644 --- a/lib/Donors/index.js +++ b/lib/Donors/index.js @@ -1,4 +1,5 @@ export { Donors } from './Donors'; export { DonorsList } from './DonorsList'; export { DonorsListContainer } from './DonorsListContainer'; +export { DonorsLookup } from './DonorsLookup'; export { useFetchDonors } from './hooks/useFetchDonors'; diff --git a/lib/Donors/utils.js b/lib/Donors/utils.js index 8381f8f2..946fa2ce 100644 --- a/lib/Donors/utils.js +++ b/lib/Donors/utils.js @@ -17,7 +17,12 @@ export const getDonorsListFormatter = ({ canViewOrganizations }) => ({ code: donor => donor.code, }); -export const getDonorsFormatter = ({ canViewOrganizations, fields, intl }) => ({ +export const getDonorsFormatter = ({ + canViewOrganizations, + fields, + intl, + onRemove, +}) => ({ ...getDonorsListFormatter({ canViewOrganizations }), unassignDonor: donor => ( + )), +})); + jest.mock('./hooks', () => ({ useFetchDonors: jest.fn().mockReturnValue({ donors: [], @@ -66,4 +78,16 @@ describe('Donors', () => { expect(screen.getByText('Loading')).toBeDefined(); }); + + it('should call onChange when donorOrganizationIds changed', () => { + const onChange = jest.fn(); + + renderComponent({ onChange }); + + const addDonorButton = screen.getByText('Add donor'); + + user.click(addDonorButton); + + expect(onChange).toHaveBeenCalled(); + }); }); From f733e86552ad4041e66ac771b80941eb6c9a468d Mon Sep 17 00:00:00 2001 From: Alisher Musurmonov Date: Thu, 16 Nov 2023 11:54:04 +0500 Subject: [PATCH 6/8] fix: select all and sorting issue --- lib/Donors/DonorsContainer.js | 1 + lib/Donors/DonorsLookup.js | 4 ++++ lib/Donors/constants.js | 2 ++ 3 files changed, 7 insertions(+) diff --git a/lib/Donors/DonorsContainer.js b/lib/Donors/DonorsContainer.js index 13122016..a5b61748 100644 --- a/lib/Donors/DonorsContainer.js +++ b/lib/Donors/DonorsContainer.js @@ -86,6 +86,7 @@ export function DonorsContainer({ name={id} searchLabel={searchLabel} visibleColumns={pluginVisibleColumnsProp} + {...rest} /> ) } diff --git a/lib/Donors/DonorsLookup.js b/lib/Donors/DonorsLookup.js index 0fed2002..3a853834 100644 --- a/lib/Donors/DonorsLookup.js +++ b/lib/Donors/DonorsLookup.js @@ -12,6 +12,7 @@ import { pluginVisibleColumns, resultsPaneTitle, searchableIndexes, + sortableColumns, visibleFilters, } from './constants'; @@ -20,6 +21,7 @@ export const DonorsLookup = ({ onAddDonors, searchLabel, visibleColumns, + ...rest }) => { const stripes = useStripes(); @@ -41,6 +43,8 @@ export const DonorsLookup = ({ searchableIndexes={searchableIndexes} visibleFilters={visibleFilters} isMultiSelect + sortableColumns={sortableColumns} + {...rest} > diff --git a/lib/Donors/constants.js b/lib/Donors/constants.js index f0b0d217..68ba2fdf 100644 --- a/lib/Donors/constants.js +++ b/lib/Donors/constants.js @@ -11,6 +11,8 @@ export const defaultVisibleColumns = [ 'code', ]; +export const sortableColumns = ['name', 'code']; + export const defaultContainerVisibleColumns = [ ...defaultVisibleColumns, 'unassignDonor', From 00d15f70d231290792153fdb95b162ba0274104c Mon Sep 17 00:00:00 2001 From: Alisher Musurmonov Date: Thu, 16 Nov 2023 14:53:11 +0500 Subject: [PATCH 7/8] update loading for donors list --- lib/Donors/Donors.js | 7 +------ lib/Donors/Donors.test.js | 16 ---------------- lib/Donors/DonorsContainer.js | 8 +++----- lib/Donors/DonorsContainer.test.js | 16 +++++++++------- 4 files changed, 13 insertions(+), 34 deletions(-) diff --git a/lib/Donors/Donors.js b/lib/Donors/Donors.js index ba15fa1b..32d34c5b 100644 --- a/lib/Donors/Donors.js +++ b/lib/Donors/Donors.js @@ -5,7 +5,6 @@ import { useEffect, useState } from 'react'; import { Col, - Loading, Row, } from '@folio/stripes/components'; @@ -26,10 +25,6 @@ export function Donors({ name, donorOrganizationIds, onChange, ...rest }) { onChange(values); }; - if (isLoading) { - return ; - } - return ( @@ -39,7 +34,7 @@ export function Donors({ name, donorOrganizationIds, onChange, ...rest }) { component={DonorsContainer} setDonorIds={onSetDonorIds} donors={donors} - donorIds={donorIds} + loading={isLoading} {...rest} /> diff --git a/lib/Donors/Donors.test.js b/lib/Donors/Donors.test.js index 1133a03f..504e7d88 100644 --- a/lib/Donors/Donors.test.js +++ b/lib/Donors/Donors.test.js @@ -7,11 +7,6 @@ import stripesFinalForm from '@folio/stripes/final-form'; import { Donors } from './Donors'; import { useFetchDonors } from './hooks'; -jest.mock('@folio/stripes/components', () => ({ - ...jest.requireActual('@folio/stripes/components'), - Loading: jest.fn(() => 'Loading'), -})); - jest.mock('./DonorsLookup', () => ({ DonorsLookup: jest.fn(({ onAddDonors }) => (