Skip to content

Commit

Permalink
UIIN-2608: If Shared & Held by facets were selected in the Browse sea…
Browse files Browse the repository at this point in the history
…rch, then retain them in the Search lookup after clicking the record. (#2307)
  • Loading branch information
Dmytro-Melnyshyn authored Oct 18, 2023
1 parent 1b6dca3 commit 79771fb
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* Reset CheckboxFacet state.more when user resets search form and fewer facet options are loaded. Fixes UIIN-2531.
* Edit instance success toast no longer shows the instance HRID. Fixes UIIN-2588.
* Show facet options, if they exist, after clicking the +More button. Refs UIIN-2533.
* If Shared & Held by facets were selected in the Browse search, then retain them in the Search lookup after clicking the record. Refs UIIN-2608.

## [10.0.0](https://github.com/folio-org/ui-inventory/tree/v10.0.0) (2023-10-13)
[Full Changelog](https://github.com/folio-org/ui-inventory/compare/v9.4.12...v10.0.0)
Expand Down
4 changes: 3 additions & 1 deletion src/components/BrowseResultsList/BrowseResultsList.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const BrowseResultsList = ({
onNeedMoreData,
},
totalRecords,
filters,
}) => {
const data = useContext(DataContext);
const { search } = useLocation();
Expand All @@ -75,7 +76,7 @@ const BrowseResultsList = ({
id={listId}
totalCount={totalRecords}
contentData={browseData}
formatter={getBrowseResultsFormatter({ data, browseOption })}
formatter={getBrowseResultsFormatter({ data, browseOption, filters })}
visibleColumns={VISIBLE_COLUMNS_MAP[browseOption]}
isEmptyMessage={isEmptyMessage}
isSelected={isSelected}
Expand All @@ -101,6 +102,7 @@ const BrowseResultsList = ({

BrowseResultsList.propTypes = {
browseData: PropTypes.arrayOf(PropTypes.object),
filters: PropTypes.object.isRequired,
isEmptyMessage: PropTypes.node.isRequired,
isLoading: PropTypes.bool,
pagination: PropTypes.shape({
Expand Down
113 changes: 113 additions & 0 deletions src/components/BrowseResultsList/BrowseResultsList.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
browseModeOptions,
BROWSE_INVENTORY_ROUTE,
INVENTORY_ROUTE,
browseCallNumberOptions,
FACETS,
} from '../../constants';
import { DataContext } from '../../contexts';
import BrowseResultsList from './BrowseResultsList';
Expand Down Expand Up @@ -59,14 +61,37 @@ const defaultProps = {
pageConfig: [0, null, null],
},
totalRecords: 1,
filters: {},
};

const mockContext = {
contributorNameTypes: [{
id: '2b94c631-fca9-4892-a730-03ee529ffe2a',
}],
contributorTypes: [{
id: '6e09d47d-95e2-4d8a-831b-f777b8ef6d81',
name: 'Author',
}],
};

const contributorsData = [
{
'name': 'Toth, Josh',
'contributorTypeId': [
'6e09d47d-95e2-4d8a-831b-f777b8ef6d81'
],
'contributorNameTypeId': '2b94c631-fca9-4892-a730-03ee529ffe2a',
'isAnchor': false,
'totalRecords': 1
},
];
const subjectsData = [
{
'value': 'Trivia and miscellanea',
'totalRecords': 8
},
];

const renderBrowseResultsList = (props = {}) => renderWithIntl(
<Router history={history}>
<DataContext.Provider value={mockContext}>
Expand Down Expand Up @@ -103,6 +128,94 @@ describe('BrowseResultsList', () => {
);
});

describe.each([
{ searchOption: browseCallNumberOptions.CALL_NUMBERS, shared: FACETS.SHARED, heldBy: FACETS.CALL_NUMBERS_HELD_BY },
{ searchOption: browseCallNumberOptions.DEWEY, shared: FACETS.SHARED, heldBy: FACETS.CALL_NUMBERS_HELD_BY },
{ searchOption: browseCallNumberOptions.LIBRARY_OF_CONGRESS, shared: FACETS.SHARED, heldBy: FACETS.CALL_NUMBERS_HELD_BY },
{ searchOption: browseCallNumberOptions.LOCAL, shared: FACETS.SHARED, heldBy: FACETS.CALL_NUMBERS_HELD_BY },
{ searchOption: browseCallNumberOptions.NATIONAL_LIBRARY_OF_MEDICINE, shared: FACETS.SHARED, heldBy: FACETS.CALL_NUMBERS_HELD_BY },
{ searchOption: browseCallNumberOptions.OTHER, shared: FACETS.SHARED, heldBy: FACETS.CALL_NUMBERS_HELD_BY },
{ searchOption: browseCallNumberOptions.SUPERINTENDENT, shared: FACETS.SHARED, heldBy: FACETS.CALL_NUMBERS_HELD_BY },
])('when the search option is $searchOption and the Shared and/or HeldBy facets are selected', ({ searchOption, shared, heldBy }) => {
describe('and the user clicks on a record in the list', () => {
it('should be navigated to the Search lookup with those filters', async () => {
history = createMemoryHistory({
initialEntries: [{
pathname: BROWSE_INVENTORY_ROUTE,
search: `${heldBy}=college&qindex=${searchOption}&query=a&${shared}=true&${shared}=false`,
}],
});

renderBrowseResultsList({
filters: {
qindex: searchOption,
query: 'a',
[shared]: ['true', 'false'],
[heldBy]: ['college'],
},
});

fireEvent.click(screen.getByText(defaultProps.browseData[2].fullCallNumber));

expect(history.location.search).toContain('?filters=shared.true%2Cshared.false%2CtenantId.college');
});
});
});

describe('when the search option is Contributors and the Shared and/or HeldBy facets are selected', () => {
describe('and the user clicks on a record in the list', () => {
it('should be navigated to the Search lookup with those filters', async () => {
history = createMemoryHistory({
initialEntries: [{
pathname: BROWSE_INVENTORY_ROUTE,
search: 'contributorsShared=true&contributorsShared=false&contributorsTenantId=college&qindex=contributors',
}],
});

renderBrowseResultsList({
filters: {
qindex: 'contributors',
contributorsShared: ['true', 'false'],
contributorsTenantId: ['college'],
},
browseData: contributorsData,
});

fireEvent.click(screen.getByText(contributorsData[0].name));

expect(history.location.search).toContain(
'?filters=searchContributors.2b94c631-fca9-4892-a730-03ee529ffe2a%2Cshared.true%2Cshared.false%2CtenantId.college'
);
});
});
});

describe('when the search option is Subjects and the Shared and/or HeldBy facets are selected', () => {
describe('and the user clicks on a record in the list', () => {
it('should be navigated to the Search lookup with those filters', async () => {
history = createMemoryHistory({
initialEntries: [{
pathname: BROWSE_INVENTORY_ROUTE,
search: 'qindex=browseSubjects&subjectsShared=true&subjectsShared=false&subjectsTenantId=college',
}],
});

renderBrowseResultsList({
filters: {
qindex: 'browseSubjects',
subjectsShared: ['true', 'false'],
subjectsTenantId: ['college'],
},
browseData: subjectsData,
});

fireEvent.click(screen.getByText(subjectsData[0].value));

expect(history.location.search).toContain('?filters=shared.true%2Cshared.false%2CtenantId.college');
});
});
});

describe('when Instance record is linked to an authority record', () => {
describe('by clicking on the icon of an authority app', () => {
const record = {
Expand Down
10 changes: 6 additions & 4 deletions src/components/BrowseResultsList/getBrowseResultsFormatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ const getTargetRecord = (
item,
row,
browseOption,
filters,
) => {
const record = getFullMatchRecord(item, row.isAnchor);
const searchParams = getSearchParams(row, browseOption);
const searchParams = getSearchParams(row, browseOption, filters);
const isNotClickable = isRowPreventsClick(row, browseOption);

if (isNotClickable) return record;
Expand Down Expand Up @@ -98,12 +99,13 @@ const renderMarcAuthoritiesLink = (authorityId, content) => {
const getBrowseResultsFormatter = ({
data,
browseOption,
filters,
}) => {
return {
title: r => getFullMatchRecord(r.instance?.title, r.isAnchor),
subject: r => {
if (r?.totalRecords) {
const subject = getTargetRecord(r?.value, r, browseOption);
const subject = getTargetRecord(r?.value, r, browseOption, filters);
if (browseOption === browseModeOptions.SUBJECTS && r.authorityId) {
return renderMarcAuthoritiesLink(r.authorityId, subject);
}
Expand All @@ -114,13 +116,13 @@ const getBrowseResultsFormatter = ({
},
callNumber: r => {
if (r?.instance || r?.totalRecords) {
return getTargetRecord(r?.fullCallNumber, r, browseOption);
return getTargetRecord(r?.fullCallNumber, r, browseOption, filters);
}
return <MissedMatchItem query={r.fullCallNumber} />;
},
contributor: r => {
if (r?.totalRecords) {
const fullMatchRecord = getTargetRecord(r.name, r, browseOption);
const fullMatchRecord = getTargetRecord(r.name, r, browseOption, filters);

if (browseOption === browseModeOptions.CONTRIBUTORS && r.authorityId) {
return renderMarcAuthoritiesLink(r.authorityId, fullMatchRecord);
Expand Down
53 changes: 50 additions & 3 deletions src/components/BrowseResultsList/utils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import omit from 'lodash/omit';

import {
browseCallNumberOptions,
browseModeOptions,
FACETS,
queryIndexes,
Expand All @@ -14,45 +17,89 @@ export const isRowPreventsClick = (row, browseOption) => {
);
};

export const getSearchParams = (row, qindex) => {
const facetsToString = (filters, facetNameInBrowse, facetNameInSearch) => {
return filters[facetNameInBrowse]?.map(value => `${facetNameInSearch}.${value}`).join(',');
};

const getExtraFilters = (row, qindex, allFilters) => {
const filtersOnly = omit(allFilters, 'qindex', 'query');
const extraFacets = [];

let sharedFacetName;
let heldByFacetName;

if (qindex === browseModeOptions.SUBJECTS) {
sharedFacetName = FACETS.SUBJECTS_SHARED;
heldByFacetName = FACETS.SUBJECTS_HELD_BY;

if (row.authorityId) {
extraFacets.push(`${FACETS.AUTHORITY_ID}.${row.authorityId}`);
}
} else if (qindex === browseModeOptions.CONTRIBUTORS) {
sharedFacetName = FACETS.CONTRIBUTORS_SHARED;
heldByFacetName = FACETS.CONTRIBUTORS_HELD_BY;

extraFacets.push(`${FACETS.SEARCH_CONTRIBUTORS}.${row.contributorNameTypeId}`);
} else if (Object.values(browseCallNumberOptions).includes(qindex)) {
sharedFacetName = FACETS.SHARED;
heldByFacetName = FACETS.CALL_NUMBERS_HELD_BY;
}

const sharedExtraFacets = facetsToString(filtersOnly, sharedFacetName, FACETS.SHARED);
const heldByExtraFacets = facetsToString(filtersOnly, heldByFacetName, FACETS.HELD_BY);
const extraFacetsString = [...extraFacets, sharedExtraFacets, heldByExtraFacets].filter(Boolean).join(',');

return extraFacetsString ? { filters: extraFacetsString } : {};
};

export const getSearchParams = (row, qindex, allFilters) => {
const filters = getExtraFilters(row, qindex, allFilters);

const optionsMap = {
[browseModeOptions.CALL_NUMBERS]: {
qindex: queryIndexes.CALL_NUMBER,
query: row.shelfKey,
...filters,
},
[browseModeOptions.DEWEY]: {
qindex: queryIndexes.CALL_NUMBER,
query: row.shelfKey,
...filters,
},
[browseModeOptions.LIBRARY_OF_CONGRESS]: {
qindex: queryIndexes.CALL_NUMBER,
query: row.shelfKey,
...filters,
},
[browseModeOptions.LOCAL]: {
qindex: queryIndexes.CALL_NUMBER,
query: row.shelfKey,
...filters,
},
[browseModeOptions.NATIONAL_LIBRARY_OF_MEDICINE]: {
qindex: queryIndexes.CALL_NUMBER,
query: row.shelfKey,
...filters,
},
[browseModeOptions.OTHER]: {
qindex: queryIndexes.CALL_NUMBER,
query: row.shelfKey,
...filters,
},
[browseModeOptions.SUPERINTENDENT]: {
qindex: queryIndexes.CALL_NUMBER,
query: row.shelfKey,
...filters,
},
[browseModeOptions.CONTRIBUTORS]: {
qindex: queryIndexes.CONTRIBUTOR,
query: row.name,
filters: `${FACETS.SEARCH_CONTRIBUTORS}.${row.contributorNameTypeId}`,
...filters,
},
[browseModeOptions.SUBJECTS]: {
qindex: queryIndexes.SUBJECT,
query: row.value,
...(row.authorityId && { filters: `${FACETS.AUTHORITY_ID}.${row.authorityId}` }),
...filters,
},
};

Expand Down
1 change: 1 addition & 0 deletions src/components/BrowseResultsPane/BrowseResultsPane.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ const BrowseResultsPane = ({
isLoading={isFetching}
pagination={pagination}
totalRecords={totalRecords}
filters={filters}
/>
</Pane>
);
Expand Down

0 comments on commit 79771fb

Please sign in to comment.