Skip to content

Commit

Permalink
Release v11.0.3 (#2467)
Browse files Browse the repository at this point in the history
  • Loading branch information
mariia-aloshyna committed Apr 26, 2024
1 parent ec3a92f commit 92c229a
Show file tree
Hide file tree
Showing 42 changed files with 1,602 additions and 811 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Change history for ui-inventory

## [11.0.3](https://github.com/folio-org/ui-inventory/tree/v11.0.3) (2024-04-26)
[Full Changelog](https://github.com/folio-org/ui-inventory/compare/v11.0.2...v11.0.3)

* Fetch facets with the same query as `Contributor` records when the search is done by selecting browse result. Refs UIIN-2859.
* Change the `Effective location` call numbers facet query to not see locations assigned to items with an empty `Effective call number` field. Refs UIIN-2871.
* Do not remove field from the form when its value is an empty string. Fixes UIIN-2787.
* Update Permission name for Inventory: Set records for deletion and staff suppress. Refs UIIN-2855.

## [11.0.2](https://github.com/folio-org/ui-inventory/tree/v11.0.2) (2024-04-19)
[Full Changelog](https://github.com/folio-org/ui-inventory/compare/v11.0.1...v11.0.2)

Expand Down
22 changes: 11 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@folio/inventory",
"version": "11.0.2",
"version": "11.0.3",
"description": "Inventory manager",
"repository": "folio-org/ui-inventory",
"publishConfig": {
Expand Down Expand Up @@ -711,7 +711,7 @@
},
{
"permissionName": "ui-inventory.instance.set-deletion-and-staff-suppress",
"displayName": "Inventory: Set records for deletion and staff suppress",
"displayName": "Inventory: Set records for deletion",
"subPermissions": [
"ui-inventory.instance.view",
"source-storage.records.update"
Expand Down Expand Up @@ -877,13 +877,13 @@
"@babel/preset-react": "^7.9.0",
"@folio/eslint-config-stripes": "^7.0.0",
"@folio/jest-config-stripes": "^2.0.0",
"@folio/stripes": "^9.0.0",
"@folio/stripes-cli": "^3.0.0",
"@folio/stripes-components": "^12.0.0",
"@folio/stripes-connect": "^9.0.0",
"@folio/stripes-core": "^10.0.0",
"@folio/stripes-marc-components": "^1.0.0",
"@folio/stripes-smart-components": "^9.0.0",
"@folio/stripes": "^9.1.2",
"@folio/stripes-cli": "^3.1.0",
"@folio/stripes-components": "^12.1.2",
"@folio/stripes-connect": "^9.1.0",
"@folio/stripes-core": "^10.1.1",
"@folio/stripes-marc-components": "^1.0.1",
"@folio/stripes-smart-components": "^9.1.1",
"@folio/stripes-testing": "^4.6.0",
"@folio/stripes-util": "^6.0.0",
"@formatjs/cli": "^6.1.3",
Expand Down Expand Up @@ -924,8 +924,8 @@
"use-session-storage-state": "^18.2.0"
},
"peerDependencies": {
"@folio/stripes": "^9.0.0",
"@folio/stripes-marc-components": "^1.0.0",
"@folio/stripes": "^9.1.2",
"@folio/stripes-marc-components": "^1.0.1",
"react": "^18.2.0",
"react-intl": "^6.4.4",
"react-query": "^3.6.0",
Expand Down
10 changes: 9 additions & 1 deletion src/common/hooks/useFacets.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ import { useFacetSettings } from '../../stores/facetsStore';
// - when the user places the cursor in a facet's input field, all options for it must be fetched;
// - when multiple facets are open and the user enters a value in the search box, options must be fetched for all open facets.
// - when multiple facets are open and the user selects an option of any facet, options must be fetched for all open facets.
// - when a facet option is selected, and then another is selected from another facet, the first selected facet option may
// become with count 0, and it should still be visible and moved to the bottom of the provided options. This is done in `getFacetOptions`.
// - the "Contributor" search utilizes distinct queries for the "Search" lookup and the "Browse" search. When a user
// selects a contributor record from the "Browse" search, they are redirected to the "Search" lookup. This redirection
// request uses one specific query. If the user then clicks the search button again, without making any changes,
// a different query is generated because the `selectedBrowseResult` parameter is removed. Therefore, even if the only
// change made is to the `selectedBrowseResult`, all open facets need to be fetched.

const useFacets = (
segmentAccordions,
Expand All @@ -24,6 +31,7 @@ const useFacets = (
query,
qindex,
filters = '',
selectedBrowseResult,
},
onFetchFacets,
parentResources: { facets },
Expand Down Expand Up @@ -242,7 +250,7 @@ const useFacets = (
handleFetchFacets();
prevUrl.current.all = location.search;
}
}, [query]);
}, [query, selectedBrowseResult]);

return [
accordions,
Expand Down
65 changes: 65 additions & 0 deletions src/common/hooks/useFacets.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,71 @@ describe('useFacets', () => {
});
});

describe('when a user hits a Browse result then redirects to the Search lookup and a request is made', () => {
describe('and then hits the search button (the only change is to the `selectedBrowseResult` parameter)', () => {
it('should call onFetchFacets for all open facets', () => {
const search = '?filters=searchContributors.2b4007a7-2d96-4262-a360-c9f760e355c3&qindex=contributor&query=test&selectedBrowseResult=true';

useFacetSettings.mockReturnValue([{}, jest.fn()]);
useLocation.mockReturnValue({ search });

const { result, rerender } = renderHook(({ newData, newSelectedFacetFilters }) => useFacets(
_segmentAccordions,
_segmentOptions,
newSelectedFacetFilters,
_getNewRecords,
newData,
), {
initialProps: {
newData: {
..._data,
query: {
..._data.query,
query: 'test',
qindex: 'contributor',
filters: 'searchContributors.2b4007a7-2d96-4262-a360-c9f760e355c3',
selectedBrowseResult: 'true',
},
},
newSelectedFacetFilters: _selectedFacetFilters,
},
});

const onToggleSection = result.current[1];

act(() => { onToggleSection({ id: 'resource' }); });

_data.onFetchFacets.mockClear();

useLocation.mockReturnValue({
search: search.replace('&selectedBrowseResult=true', ''),
});

rerender({
newData: {
..._data,
query: {
..._data.query,
query: 'test',
qindex: 'contributor',
filters: 'searchContributors.2b4007a7-2d96-4262-a360-c9f760e355c3',
},
},
newSelectedFacetFilters: _selectedFacetFilters,
});

expect(_data.onFetchFacets).toHaveBeenCalledTimes(1);
expect(_data.onFetchFacets).toHaveBeenCalledWith({
accordions: {
format: false,
resource: true,
},
accordionsData: expect.any(Object),
});
});
});
});

describe('when the "Browse" lookup and there is a value in the search box and facet option is selected', () => {
describe('and the user reset the search', () => {
it('should not call onFetchFacets', () => {
Expand Down
11 changes: 4 additions & 7 deletions src/edit/electronicAccessFields.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {
Label,
} from '@folio/stripes/components';

import { parseEmptyFormValue } from '../utils';

const ElectronicAccessFields = props => {
const { formatMessage } = useIntl();

Expand Down Expand Up @@ -82,6 +84,7 @@ const ElectronicAccessFields = props => {
aria-label={uriLabel}
name={`${field}.uri`}
component={TextArea}
parse={parseEmptyFormValue}
rows={1}
disabled={!canEdit}
/>
Expand Down Expand Up @@ -122,13 +125,7 @@ const ElectronicAccessFields = props => {
component={RepeatableField}
legend={<FormattedMessage id="ui-inventory.electronicAccess" />}
addLabel={<FormattedMessage id="ui-inventory.addElectronicAccess" />}
onAdd={fields => fields.push({
relationshipId: '',
uri: '',
linkText: '',
materialsSpecification: '',
publicNote: '',
})}
onAdd={fields => fields.push({ uri: '' })}
headLabels={headLabels}
renderField={renderField}
canAdd={canAdd}
Expand Down
12 changes: 4 additions & 8 deletions src/routes/buildManifestObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ import {
getQueryTemplate,
getIsbnIssnTemplate,
replaceFilter,
getTemplateForSelectedFromBrowseRecord,
} from '../utils';
import { getFilterConfig } from '../filterConfig';

const INITIAL_RESULT_COUNT = 100;
const DEFAULT_SORT = 'title';

const getQueryTemplateContributor = (queryValue) => `contributors.name==/string "${queryValue}"`;
const getAdvancedSearchQueryTemplate = (queryIndex, matchOption) => fieldSearchConfigurations[queryIndex]?.[matchOption];

export const getAdvancedSearchTemplate = (queryValue) => {
Expand Down Expand Up @@ -68,14 +68,10 @@ export function buildQuery(queryParams, pathComponents, resourceData, logger, pr
const queryValue = get(queryParams, 'query', '');
let queryTemplate = getQueryTemplate(queryIndex, indexes);

if (queryParams?.selectedBrowseResult) {
if (queryIndex === queryIndexes.CONTRIBUTOR) {
const escapedQueryValue = queryValue.replaceAll('"', '\\"');
const template = getTemplateForSelectedFromBrowseRecord(queryParams, queryIndex, queryValue);

queryTemplate = getQueryTemplateContributor(escapedQueryValue);
}

query.selectedBrowseResult = null; // reset this parameter so the next search uses `=` instead of `==/string`
if (template) {
queryTemplate = template;
}

if (queryIndex === queryIndexes.ADVANCED_SEARCH) {
Expand Down
17 changes: 17 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
OKAPI_TOKEN_HEADER,
AUTHORITY_LINKED_FIELDS,
segments,
queryIndexes,
} from './constants';
import { removeItem } from './storage';

Expand Down Expand Up @@ -926,3 +927,19 @@ export const setRecordForDeletion = async (okapi, id, tenantId) => {

return response;
};

export const parseEmptyFormValue = value => value;

export const getTemplateForSelectedFromBrowseRecord = (queryParams, queryIndex, queryValue) => {
if (!queryParams?.selectedBrowseResult) {
return null;
}

if (queryIndex === queryIndexes.CONTRIBUTOR) {
const escapedQueryValue = queryValue.replaceAll('"', '\\"');

return `contributors.name==/string "${escapedQueryValue}"`;
}

return null;
};
27 changes: 27 additions & 0 deletions src/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
getQueryTemplate,
switchAffiliation,
setRecordForDeletion,
parseEmptyFormValue,
} from './utils';
import {
CONTENT_TYPE_HEADER,
Expand Down Expand Up @@ -251,3 +252,29 @@ describe('setRecordForDeletion', () => {
});
});
});

describe('parseEmptyFormValue', () => {
it('should return the same value when not empty', () => {
const value = 'test';

expect(parseEmptyFormValue(value)).toEqual(value);
});

it('should return empty string when value is empty', () => {
const value = '';

expect(parseEmptyFormValue(value)).toEqual('');
});

it('should return null when value is null', () => {
const value = null;

expect(parseEmptyFormValue(value)).toEqual(null);
});

it('should return undefined when value is undefined', () => {
const value = undefined;

expect(parseEmptyFormValue(value)).toEqual(undefined);
});
});
24 changes: 16 additions & 8 deletions src/withFacets.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { buildFilterQuery } from '@folio/stripes-acq-components';

import {
getQueryTemplate,
getTemplateForSelectedFromBrowseRecord,
} from './utils';
import {
browseConfig,
Expand All @@ -33,6 +34,12 @@ function buildQuery(queryParams, pathComponents, resourceData, logger, props) {
const { indexes, filters } = browseModeMap[queryIndex] ? browseConfig : getFilterConfig(queryParams.segment);
let queryTemplate = getQueryTemplate(queryIndex, indexes);

const template = getTemplateForSelectedFromBrowseRecord(queryParams, queryIndex, queryValue);

if (template) {
queryTemplate = template;
}

if (queryIndex === queryIndexes.ADVANCED_SEARCH) {
queryTemplate = getAdvancedSearchTemplate(queryValue);
}
Expand Down Expand Up @@ -147,14 +154,15 @@ function withFacets(WrappedComponent) {

const isTypedCallNumber = Object.values(browseCallNumberOptions).includes(queryIndex)
&& queryIndex !== browseCallNumberOptions.CALL_NUMBERS;

if (hasSelectedFacetOption) {
if (isTypedCallNumber) {
queryForBrowseFacets = `callNumberType="${queryIndex}"`;
}
} else if (isTypedCallNumber) {
queryForBrowseFacets = `callNumberType="${queryIndex}"`;
} else {
// We shouldn’t count "Instances" with "Holdings": 1) without "Items"
// or 2) with "Items" with empty "Effective call number" field.
const itemsEffectiveShelvingOrder = 'items.effectiveShelvingOrder="" NOT items.effectiveShelvingOrder==""';

if (isTypedCallNumber) {
queryForBrowseFacets = `callNumberType="${queryIndex}" and ${itemsEffectiveShelvingOrder}`;
} else if (queryIndex === browseCallNumberOptions.CALL_NUMBERS) {
queryForBrowseFacets = itemsEffectiveShelvingOrder;
} else if (!hasSelectedFacetOption) {
queryForBrowseFacets = 'cql.allRecords=1';
}

Expand Down
Loading

0 comments on commit 92c229a

Please sign in to comment.