Skip to content

Commit

Permalink
UIREQ-1190 - Add "Retrieval service point" filter (#1244)
Browse files Browse the repository at this point in the history
* UIREQ-1190 - initial commit

* UIREQ-1190 - Add "Retrieval service point" filter

* fix failed tests

* fix test

* refine and fix tests

* UIREQ-1190 - remove unnecessary mock

* UIREQ-1190 - duplicate existing Request filters in deprecated folder so that 'Retrieval service point" filter is not available from deprecated folder path

* update translation id

* Update src/hooks/useRetrievalServicePoints/useRetrievalServicePoints.js

Co-authored-by: Mariia Aloshyna <[email protected]>

* move RequestFilters to components and remove unnecessary code from deprecated folder

* fix tests

* fix test failures and review comments

---------

Co-authored-by: Mariia Aloshyna <[email protected]>
  • Loading branch information
Terala-Priyanka and mariia-aloshyna authored Dec 17, 2024
1 parent 039a9ea commit dac2d58
Show file tree
Hide file tree
Showing 22 changed files with 1,121 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Cleanup retrieval service point implementation from deprecated folder. Refs UIREQ-1211.
* Increase code coverage for src/ViewRequest.js by Jest/RTL tests. Refs UIREQ-1046.
* React v19: refactor away from default props for functional components. Refs UIREQ-1101.
* Add "Retrieval service point" filter. Refs UIREQ-1190.

## [11.0.2] (https://github.com/folio-org/ui-requests/tree/v11.0.2) (2024-12-10)
[Full Changelog](https://github.com/folio-org/ui-requests/compare/v11.0.1...v11.0.2)
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@
"inflected": "^2.0.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-query": "^3.39.0",
"react-intl": "^6.4.4",
"react-router-dom": "^5.2.0",
"regenerator-runtime": "^0.13.9"
Expand All @@ -220,6 +221,7 @@
"@folio/stripes": "^9.2.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-query": "^3.39.0",
"react-intl": "^6.4.4",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0"
Expand Down
9 changes: 9 additions & 0 deletions src/components/RequestsFilters/RequestsFilters.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
} from '../../constants';

import { PickupServicePointFilter } from './PickupServicePointFilter';
import { RetrievalServicePointFilter } from './RetrievalServicePointFilter';
import { RequestLevelFilter } from './RequestLevelFilter';

export default class RequestsFilters extends React.Component {
Expand All @@ -35,6 +36,7 @@ export default class RequestsFilters extends React.Component {
requestType: PropTypes.arrayOf(PropTypes.string),
tags: PropTypes.arrayOf(PropTypes.string),
pickupServicePoints: PropTypes.arrayOf(PropTypes.string),
retrievalServicePoints: PropTypes.arrayOf(PropTypes.string),
printStatus: PropTypes.arrayOf(PropTypes.string),
}).isRequired,
resources: PropTypes.object.isRequired,
Expand Down Expand Up @@ -65,6 +67,7 @@ export default class RequestsFilters extends React.Component {
requestType = [],
requestStatus = [],
pickupServicePoints = [],
retrievalServicePoints = [],
requestLevels = [],
printStatus = [],
},
Expand Down Expand Up @@ -146,6 +149,12 @@ export default class RequestsFilters extends React.Component {
onChange={onChange}
onClear={onClear}
/>
<RetrievalServicePointFilter
data-testid="retrievalServicePointFilter"
activeValues={retrievalServicePoints}
onChange={onChange}
onClear={onClear}
/>
{isViewPrintDetailsEnabled && (
<Accordion
displayClearButton={!isEmpty(printStatus)}
Expand Down
21 changes: 21 additions & 0 deletions src/components/RequestsFilters/RequestsFilters.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import RequestsFilters from './RequestsFilters';
import { RequestLevelFilter } from './RequestLevelFilter';
import { PickupServicePointFilter } from './PickupServicePointFilter';
import { RetrievalServicePointFilter } from './RetrievalServicePointFilter';

import {
requestFilterTypes,
Expand All @@ -26,6 +27,9 @@ jest.mock('./RequestLevelFilter', () => ({
jest.mock('./PickupServicePointFilter', () => ({
PickupServicePointFilter: jest.fn((props) => (<div {...props} />)),
}));
jest.mock('./RetrievalServicePointFilter', () => ({
RetrievalServicePointFilter: jest.fn((props) => (<div {...props} />)),
}));
jest.mock('@folio/stripes/smart-components', () => ({
CheckboxFilter: jest.fn((props) => (<div {...props} />)),
MultiSelectionFilter: jest.fn((props) => (<div {...props} />)),
Expand All @@ -38,6 +42,7 @@ const props = {
requestStatus: ['Open'],
requestType: ['Hold'],
pickupServicePoints: ['1'],
retrievalServicePoints: ['1', '2'],
tags: ['Urgent'],
requestLevels: [],
printStatus: ['Printed'],
Expand Down Expand Up @@ -71,6 +76,7 @@ const testIds = {
requestLevelFilter: 'requestLevelFilter',
multiSelectionFilter: 'multiSelectionFilter',
pickupServicePointFilter: 'pickupServicePointFilter',
retrievalServicePointFilter: 'retrievalServicePointFilter',
};
const labelIds = {
[requestFilterTypes.REQUEST_TYPE]: 'ui-requests.requestMeta.type',
Expand Down Expand Up @@ -261,6 +267,21 @@ describe('RequestsFilters', () => {
});
});

describe('RetrievalServicePointFilter', () => {
it('should render RetrievalServicePointFilter', () => {
expect(screen.getByTestId(testIds.retrievalServicePointFilter)).toBeInTheDocument();
});

it('should trigger retrievalServicePointFilter with correct props', () => {
expect(RetrievalServicePointFilter).toHaveBeenCalledWith(expect.objectContaining({
'data-testid': testIds.retrievalServicePointFilter,
activeValues: props.activeFilters.retrievalServicePoints,
onChange,
onClear,
}), {});
});
});

describe('When activeFilters prop is empty', () => {
const propsWithoutFilters = {
...props,
Expand Down
6 changes: 6 additions & 0 deletions src/components/RequestsFilters/RequestsFiltersConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ export default [
values: [],
operator: '==',
},
{
name: requestFilterTypes.RETRIEVAL_SERVICE_POINT,
cql: 'item.retrievalServicePointId',
values: [],
operator: '==',
},
{
name: requestFilterTypes.PRINT_STATUS,
cql: 'printStatus',
Expand Down
12 changes: 12 additions & 0 deletions src/components/RequestsFilters/RequestsFiltersConfig.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ describe('RequestsFiltersConfig', () => {
expect(pickupServicePointFilter).toEqual(expectedResult);
});

it('should have a filter for retrieval service point', () => {
const retrievalServicePointFilter = filtersConfig.find(f => f.name === requestFilterTypes.RETRIEVAL_SERVICE_POINT);
const expectedResult = {
name: 'retrievalServicePoints',
cql: 'item.retrievalServicePointId',
values: [],
operator: '==',
};

expect(retrievalServicePointFilter).toEqual(expectedResult);
});

describe('Print Status Filter configuration', () => {
it('should correctly match the filter configuration for printStatus', () => {
const printStatusFilter = filtersConfig.find(f => f.name === 'printStatus');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { useCallback } from 'react';
import { FormattedMessage } from 'react-intl';
import { isEmpty } from 'lodash';
import PropTypes from 'prop-types';

import {
Accordion,
FilterAccordionHeader,
} from '@folio/stripes/components';
import {
MultiSelectionFilter,
} from '@folio/stripes/smart-components';

import {
requestFilterTypes,
} from '../../../constants';

import { useRetrievalServicePoints } from '../../../hooks';

const RetrievalServicePointFilter = ({
activeValues,
onChange,
onClear,
}) => {
const name = requestFilterTypes.RETRIEVAL_SERVICE_POINT;
const clearFilter = useCallback(() => {
onClear(name);
}, [name, onClear]);

const { retrievalSPsOptions } = useRetrievalServicePoints();

return (
<div>
<Accordion
data-testid="retrievalServicePointAccordion"
displayClearButton={!isEmpty(activeValues)}
id={name}
header={FilterAccordionHeader}
label={<FormattedMessage id="ui-requests.requests.retrievalServicePoint" />}
name={name}
separator={false}
onClearFilter={clearFilter}
>
<MultiSelectionFilter
ariaLabelledBy={`accordion-toggle-button-${name}`}
dataOptions={retrievalSPsOptions}
id="req-retrieval-service-point-filter"
name={name}
onChange={onChange}
selectedValues={activeValues}
/>
</Accordion>
</div>
);
};

RetrievalServicePointFilter.propTypes = {
activeValues: PropTypes.arrayOf(PropTypes.string),
onChange: PropTypes.func.isRequired,
onClear: PropTypes.func.isRequired,
};
export default RetrievalServicePointFilter;
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import {
render,
screen,
} from '@folio/jest-config-stripes/testing-library/react';
import userEvent from '@folio/jest-config-stripes/testing-library/user-event';

import {
Accordion,
FilterAccordionHeader,
} from '@folio/stripes/components';

import RetrievalServicePointFilter from './RetrievalServicePointFilter';
import { requestFilterTypes } from '../../../constants';

jest.mock('../../../hooks', () => ({
...jest.requireActual('../../../hooks'),
useRetrievalServicePoints: jest.fn().mockReturnValue([
{
value: '3a40852d-49fd-4df2-a1f9-6e2641a6e91f',
label: 'Circ desk 1',
},
{
value: '9d1b77e8-f02e-4b7f-b296-3f2042ddac54',
label: 'Circ desk 2',
},
]),
}));

const activeValues = ['test', 'test2'];
const onChange = jest.fn();
const onClear = jest.fn();
const testIds = {
retrievalServicePointAccordionButton: 'retrievalServicePointAccordionButton',
};

describe('RetrievalServicePointFilter', () => {
beforeEach(() => {
onChange.mockClear();
onClear.mockClear();
render(
<RetrievalServicePointFilter
activeValues={activeValues}
onChange={onChange}
onClear={onClear}
/>
);
});

it('should render "Accordion" with correct props', () => {
const expectedProps = {
id: requestFilterTypes.RETRIEVAL_SERVICE_POINT,
name: requestFilterTypes.RETRIEVAL_SERVICE_POINT,
header: FilterAccordionHeader,
separator: false,
onClearFilter: expect.any(Function),
};

expect(Accordion).toHaveBeenCalledWith(expect.objectContaining(expectedProps), {});
});

it('should render MultiSelectionFilter', () => {
const MultiSelectionFilter = screen.getByText('MultiSelectionFilter');

expect(MultiSelectionFilter).toBeInTheDocument();
});

it('should perform onClear event', async () => {
const retrievalServicePointsButton = screen.getByTestId(testIds.retrievalServicePointAccordionButton);

await userEvent.click(retrievalServicePointsButton);

expect(onClear).toHaveBeenCalledWith(requestFilterTypes.RETRIEVAL_SERVICE_POINT);
});

describe('MultiSelectionFilter activeValues', () => {
activeValues.forEach(value => {
it(`should render "${value}"`, () => {
const activeValue = screen.getByText(value, {
exact: false,
});

expect(activeValue).toBeInTheDocument();
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as RetrievalServicePointFilter } from './RetrievalServicePointFilter';
4 changes: 4 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ export const requestFilterTypes = {
REQUEST_STATUS: 'requestStatus',
REQUEST_LEVELS: 'requestLevels',
PICKUP_SERVICE_POINT: 'pickupServicePoints',
RETRIEVAL_SERVICE_POINT: 'retrievalServicePoints',
PRINT_STATUS: 'printStatus',
};

Expand Down Expand Up @@ -429,3 +430,6 @@ export const SETTINGS_SCOPES = {
export const SETTINGS_KEYS = {
GENERAL_TLR: 'generalTlr',
};

export const LOCATIONS_API = 'locations';
export const SERVICE_POINTS_API = 'service-points';
Loading

0 comments on commit dac2d58

Please sign in to comment.