diff --git a/CHANGELOG.md b/CHANGELOG.md index 63248f9c9..7b3cc585d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ * Display holdings names in `Consortial holdings` accordion for user without inventory permissions in member tenants. Fixes UIIN-3159. * Remove the ability to share local instance when `Inventory: View, create instances` permission is assigned. Fixes UIIN-3166. +* *BREAKING* Use `browse` `1.5` interface that provides new Call Number Browse endpoints. Refs UIIN-3162. ## [12.0.7](https://github.com/folio-org/ui-inventory/tree/v12.0.7) (2024-12-17) [Full Changelog](https://github.com/folio-org/ui-inventory/compare/v12.0.6...v12.0.7) diff --git a/package.json b/package.json index 0f7e8990b..b0ebed4ba 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@folio/inventory", - "version": "13.0.0", + "version": "13.1.0", "description": "Inventory manager", "repository": "folio-org/ui-inventory", "publishConfig": { @@ -54,7 +54,7 @@ "okapiInterfaces": { "alternative-title-types": "1.0", "call-number-types": "1.0", - "browse": "0.6 1.0", + "browse": "1.5", "circulation": "9.0 10.0 11.0 12.0 13.0 14.0", "classification-types": "1.1", "configuration": "2.0", diff --git a/src/components/BrowseResultsList/BrowseResultsList.js b/src/components/BrowseResultsList/BrowseResultsList.js index d43d8398b..12cbf7667 100644 --- a/src/components/BrowseResultsList/BrowseResultsList.js +++ b/src/components/BrowseResultsList/BrowseResultsList.js @@ -14,13 +14,9 @@ import { MCLPagingTypes, MultiColumnList, } from '@folio/stripes/components'; -import { - useItemToView, -} from '@folio/stripes-acq-components'; +import { useItemToView } from '@folio/stripes-acq-components'; -import { - BROWSE_RESULTS_COUNT, -} from '../../constants'; +import { BROWSE_RESULTS_COUNT } from '../../constants'; import { DataContext } from '../../contexts'; import { COLUMNS_MAPPING, diff --git a/src/components/BrowseResultsList/BrowseResultsList.test.js b/src/components/BrowseResultsList/BrowseResultsList.test.js index 15db2edc0..3558fb84f 100644 --- a/src/components/BrowseResultsList/BrowseResultsList.test.js +++ b/src/components/BrowseResultsList/BrowseResultsList.test.js @@ -11,7 +11,6 @@ import { import { createMemoryHistory } from 'history'; import { Router } from 'react-router-dom'; -import { instance } from '../../../test/fixtures/instance'; import { renderWithIntl, translationsProperties, @@ -37,21 +36,19 @@ const defaultProps = { browseData: [ { fullCallNumber: 'Aaa', - shelfKey: 'Aa 1', + callNumber: 'Aaa', isAnchor: true, totalRecords: 0, }, { fullCallNumber: 'A 1958 A 8050', - shelfKey: '41958 A 48050', + callNumber: 'A 1958 A 8050', totalRecords: 1, - instance, }, { fullCallNumber: 'ABBA', - shelfKey: '41918 A 64243', + callNumber: 'ABBA', totalRecords: 2, - instance, }, ], isEmptyMessage: 'Empty Message', @@ -133,13 +130,13 @@ describe('BrowseResultsList', () => { it('should render browse data', () => { renderBrowseResultsList(); - expect(screen.getByText(defaultProps.browseData[1].fullCallNumber)).toBeInTheDocument(); + expect(screen.getByText(defaultProps.browseData[1].callNumber)).toBeInTheDocument(); }); it('should navigate to instance Search page and show related instances', async () => { renderBrowseResultsList(); - await act(async () => fireEvent.click(screen.getByText(defaultProps.browseData[2].fullCallNumber))); + await act(async () => fireEvent.click(screen.getByText(defaultProps.browseData[2].callNumber))); const { pathname, search } = history.location; @@ -180,7 +177,7 @@ describe('BrowseResultsList', () => { }, }); - fireEvent.click(screen.getByText(defaultProps.browseData[2].fullCallNumber)); + fireEvent.click(screen.getByText(defaultProps.browseData[2].callNumber)); expect(history.location.search).toContain('?filters=shared.true%2Cshared.false%2CtenantId.college'); }); diff --git a/src/components/BrowseResultsList/getBrowseResultsFormatter.js b/src/components/BrowseResultsList/getBrowseResultsFormatter.js index d0ff7b668..8b9242785 100644 --- a/src/components/BrowseResultsList/getBrowseResultsFormatter.js +++ b/src/components/BrowseResultsList/getBrowseResultsFormatter.js @@ -15,6 +15,7 @@ import { INVENTORY_ROUTE, } from '../../constants'; import { + getFullCallNumber, getSearchParams, isRowPreventsClick, } from './utils'; @@ -112,7 +113,7 @@ const getBrowseResultsFormatter = ({ const commonTargetRecordArgs = [browseOption, filters, namespace, data]; return { - title: r => getFullMatchRecord(r.instance?.title, r.isAnchor), + title: r => getFullMatchRecord(r.instanceTitle, r.isAnchor), subject: r => { if (!r?.totalRecords && r?.isAnchor) { return ; @@ -138,8 +139,10 @@ const getBrowseResultsFormatter = ({ return typeName || ; }, callNumber: r => { - if (r?.instance || r?.totalRecords) { - return getTargetRecord(r?.fullCallNumber, r, ...commonTargetRecordArgs); + const fullCallNumber = getFullCallNumber(r); + + if (r?.totalRecords) { + return getTargetRecord(fullCallNumber, r, ...commonTargetRecordArgs); } return ; }, diff --git a/src/components/BrowseResultsList/getBrowseResultsFormatter.test.js b/src/components/BrowseResultsList/getBrowseResultsFormatter.test.js index ba9c4ec3f..4e9faf1ec 100644 --- a/src/components/BrowseResultsList/getBrowseResultsFormatter.test.js +++ b/src/components/BrowseResultsList/getBrowseResultsFormatter.test.js @@ -87,11 +87,13 @@ describe('getBrowseResultsFormatter', () => { const missedMatchRecord = { isAnchor: true, fullCallNumber: 'bla bla', + callNumber: 'bla bla', totalRecords: 0, }; const contentData = [ { fullCallNumber: 'A 1958 A 8050', + callNumber: 'A 1958 A 8050', shelfKey: '41958 A 48050', isAnchor: true, totalRecords: 1, @@ -99,6 +101,7 @@ describe('getBrowseResultsFormatter', () => { }, { fullCallNumber: 'AAA', + callNumber: 'AAA', shelfKey: '123456', totalRecords: 2, instance: { id: 'ce9dd893-c812-49d5-8973-d55d018894c4', title: 'Test title 2' }, @@ -117,19 +120,17 @@ describe('getBrowseResultsFormatter', () => { renderCallNumberList(); // Anchor row - expect(screen.getByText(anchorRecord.fullCallNumber).tagName.toLowerCase()).toBe('strong'); + expect(screen.getByText(anchorRecord.callNumber).tagName.toLowerCase()).toBe('strong'); expect(screen.getByText(anchorRecord.totalRecords).tagName.toLowerCase()).toBe('strong'); - expect(screen.getByText(anchorRecord.instance.title).tagName.toLowerCase()).toBe('strong'); // Default row - expect(screen.getByText(nonAnchorRecord.fullCallNumber).tagName.toLowerCase()).not.toBe('strong'); + expect(screen.getByText(nonAnchorRecord.callNumber).tagName.toLowerCase()).not.toBe('strong'); expect(screen.getByText(nonAnchorRecord.totalRecords).tagName.toLowerCase()).not.toBe('strong'); - expect(screen.getByText(nonAnchorRecord.instance.title).tagName.toLowerCase()).not.toBe('strong'); }); it('should render \'Missed match item\' row', () => { renderCallNumberList({ contentData: [missedMatchRecord] }); - expect(screen.getByText(missedMatchRecord.fullCallNumber)).toBeInTheDocument(); + expect(screen.getByText(missedMatchRecord.callNumber)).toBeInTheDocument(); expect(screen.getByText(missedMatchText)).toBeInTheDocument(); }); @@ -138,7 +139,7 @@ describe('getBrowseResultsFormatter', () => { expect(history.location.pathname).toEqual(BROWSE_INVENTORY_ROUTE); - await act(async () => fireEvent.click(screen.getByText(anchorRecord.fullCallNumber))); + await act(async () => fireEvent.click(screen.getByText(anchorRecord.callNumber))); expect(history.location.pathname).toEqual(INVENTORY_ROUTE); }); diff --git a/src/components/BrowseResultsList/utils.js b/src/components/BrowseResultsList/utils.js index 884853987..c98aa556f 100644 --- a/src/components/BrowseResultsList/utils.js +++ b/src/components/BrowseResultsList/utils.js @@ -7,6 +7,7 @@ import { browseClassificationIndexToId, FACETS, queryIndexes, + segments, } from '@folio/stripes-inventory-components'; export const isRowPreventsClick = (row, browseOption) => { @@ -21,7 +22,6 @@ export const isRowPreventsClick = (row, browseOption) => { const isItemHasNoRecords = row.totalRecords === 0; return isItemHasNoRecords || ( - (browseOption === browseModeOptions.CALL_NUMBERS && !row.shelfKey) || (browseOption === browseModeOptions.CONTRIBUTORS && !row.contributorNameTypeId) || (browseOption === browseModeOptions.SUBJECTS && !row.totalRecords) ); @@ -97,6 +97,12 @@ const getClassificationQuery = (qindex, data, row) => { return query; }; +export const getFullCallNumber = (row) => { + const fullCallNumber = [row.callNumberPrefix, row.callNumber, row.callNumberSuffix].filter(Boolean).join(' '); + + return fullCallNumber; +}; + export const getSearchParams = (row, qindex, allFilters, data) => { const filters = getExtraFilters(row, qindex, allFilters); const classificationQuery = getClassificationQuery(qindex, data, row); @@ -107,42 +113,23 @@ export const getSearchParams = (row, qindex, allFilters, data) => { ...filters, }; + const fullCallNumber = getFullCallNumber(row); + + const callNumberOption = { + qindex: queryIndexes.ITEM_NORMALIZED_CALL_NUMBERS, + query: fullCallNumber, + segment: segments.items, + ...filters, + }; + 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.CALL_NUMBERS]: callNumberOption, + [browseModeOptions.DEWEY]: callNumberOption, + [browseModeOptions.LIBRARY_OF_CONGRESS]: callNumberOption, + [browseModeOptions.LOCAL]: callNumberOption, + [browseModeOptions.NATIONAL_LIBRARY_OF_MEDICINE]: callNumberOption, + [browseModeOptions.OTHER]: callNumberOption, + [browseModeOptions.SUPERINTENDENT]: callNumberOption, [browseModeOptions.CLASSIFICATION_ALL]: classificationOption, [browseModeOptions.DEWEY_CLASSIFICATION]: classificationOption, [browseModeOptions.LC_CLASSIFICATION]: classificationOption, diff --git a/src/components/InstanceFiltersBrowse/InstanceFiltersBrowse.js b/src/components/InstanceFiltersBrowse/InstanceFiltersBrowse.js index 5940fbc0f..ffa648692 100644 --- a/src/components/InstanceFiltersBrowse/InstanceFiltersBrowse.js +++ b/src/components/InstanceFiltersBrowse/InstanceFiltersBrowse.js @@ -39,7 +39,7 @@ const InstanceFiltersBrowse = props => { [FACETS.CONTRIBUTORS_HELD_BY]: false, [FACETS.SUBJECTS_SHARED]: false, [FACETS.SUBJECTS_HELD_BY]: false, - [FACETS.EFFECTIVE_LOCATION]: false, + [FACETS.CALL_NUMBERS_EFFECTIVE_LOCATION]: false, [FACETS.NAME_TYPE]: false, [FACETS.SUBJECT_SOURCE]: false, [FACETS.SUBJECT_TYPE]: false, @@ -91,7 +91,7 @@ const InstanceFiltersBrowse = props => { {renderSharedFacet(FACETS.SHARED)} {renderHeldByFacet(FACETS.CALL_NUMBERS_HELD_BY)} ])/i; +export const regExp = /^((callNumber|subject|name|fullCallNumber) [<|>])/i; export const PRECEDING_RECORDS_COUNT = 5; export const FIVE_MINUTES = 5 * 60 * 1000; export const PATH_MAP = { [browseModeOptions.SUBJECTS]: 'browse/subjects/instances', - [browseModeOptions.CALL_NUMBERS]: 'browse/call-numbers/instances', - [browseModeOptions.DEWEY]: 'browse/call-numbers/instances', - [browseModeOptions.LIBRARY_OF_CONGRESS]: 'browse/call-numbers/instances', - [browseModeOptions.LOCAL]: 'browse/call-numbers/instances', - [browseModeOptions.NATIONAL_LIBRARY_OF_MEDICINE]: 'browse/call-numbers/instances', - [browseModeOptions.OTHER]: 'browse/call-numbers/instances', + [browseModeOptions.CALL_NUMBERS]: 'browse/call-numbers/all/instances', + [browseModeOptions.DEWEY]: 'browse/call-numbers/dewey/instances', + [browseModeOptions.LIBRARY_OF_CONGRESS]: 'browse/call-numbers/lc/instances', + [browseModeOptions.LOCAL]: 'browse/call-numbers/instances', // not supported, option disabled + [browseModeOptions.NATIONAL_LIBRARY_OF_MEDICINE]: 'browse/call-numbers/nlm/instances', + [browseModeOptions.OTHER]: 'browse/call-numbers/other/instances', + [browseModeOptions.SUPERINTENDENT]: 'browse/call-numbers/sudoc/instances', [browseModeOptions.CLASSIFICATION_ALL]: 'browse/classification-numbers/all/instances', [browseModeOptions.DEWEY_CLASSIFICATION]: 'browse/classification-numbers/dewey/instances', [browseModeOptions.LC_CLASSIFICATION]: 'browse/classification-numbers/lc/instances', - [browseModeOptions.SUPERINTENDENT]: 'browse/call-numbers/instances', [browseModeOptions.CONTRIBUTORS]: 'browse/contributors/instances', }; export const INITIAL_SEARCH_PARAMS_MAP = { [browseModeOptions.SUBJECTS]: 'value', - [browseModeOptions.CALL_NUMBERS]: 'callNumber', - [browseModeOptions.DEWEY]: 'typedCallNumber', - [browseModeOptions.LIBRARY_OF_CONGRESS]: 'typedCallNumber', - [browseModeOptions.LOCAL]: 'typedCallNumber', - [browseModeOptions.NATIONAL_LIBRARY_OF_MEDICINE]: 'typedCallNumber', - [browseModeOptions.OTHER]: 'typedCallNumber', + [browseModeOptions.CALL_NUMBERS]: 'fullCallNumber', + [browseModeOptions.DEWEY]: 'fullCallNumber', + [browseModeOptions.LIBRARY_OF_CONGRESS]: 'fullCallNumber', + [browseModeOptions.LOCAL]: 'fullCallNumber', + [browseModeOptions.NATIONAL_LIBRARY_OF_MEDICINE]: 'fullCallNumber', + [browseModeOptions.OTHER]: 'fullCallNumber', [browseModeOptions.CLASSIFICATION_ALL]: 'number', [browseModeOptions.DEWEY_CLASSIFICATION]: 'number', [browseModeOptions.LC_CLASSIFICATION]: 'number', - [browseModeOptions.SUPERINTENDENT]: 'typedCallNumber', + [browseModeOptions.SUPERINTENDENT]: 'fullCallNumber', [browseModeOptions.CONTRIBUTORS]: 'name', }; export const PAGINATION_SEARCH_PARAMS_MAP = { [browseModeOptions.SUBJECTS]: INITIAL_SEARCH_PARAMS_MAP[browseModeOptions.SUBJECTS], - [browseModeOptions.CALL_NUMBERS]: 'itemEffectiveShelvingOrder', - [browseModeOptions.DEWEY]: 'itemEffectiveShelvingOrder', - [browseModeOptions.LIBRARY_OF_CONGRESS]: 'itemEffectiveShelvingOrder', - [browseModeOptions.LOCAL]: 'itemEffectiveShelvingOrder', - [browseModeOptions.NATIONAL_LIBRARY_OF_MEDICINE]: 'itemEffectiveShelvingOrder', - [browseModeOptions.OTHER]: 'itemEffectiveShelvingOrder', - [browseModeOptions.SUPERINTENDENT]: 'itemEffectiveShelvingOrder', + [browseModeOptions.CALL_NUMBERS]: 'fullCallNumber', + [browseModeOptions.DEWEY]: 'fullCallNumber', + [browseModeOptions.LIBRARY_OF_CONGRESS]: 'fullCallNumber', + [browseModeOptions.LOCAL]: 'fullCallNumber', + [browseModeOptions.NATIONAL_LIBRARY_OF_MEDICINE]: 'fullCallNumber', + [browseModeOptions.OTHER]: 'fullCallNumber', + [browseModeOptions.SUPERINTENDENT]: 'fullCallNumber', [browseModeOptions.CLASSIFICATION_ALL]: INITIAL_SEARCH_PARAMS_MAP[browseModeOptions.CLASSIFICATION_ALL], [browseModeOptions.DEWEY_CLASSIFICATION]: INITIAL_SEARCH_PARAMS_MAP[browseModeOptions.DEWEY_CLASSIFICATION], [browseModeOptions.LC_CLASSIFICATION]: INITIAL_SEARCH_PARAMS_MAP[browseModeOptions.LC_CLASSIFICATION],