diff --git a/CHANGELOG.md b/CHANGELOG.md
index a8fc9be68..fdc138cf7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,8 @@
# Change history for ui-inventory
+## 10.0.1 IN PROGRESS
+* Enable/disable consortial holdings/item actions based on User permissions. Refs UIIN-2452.
+
## 10.0.0 IN PROGRESS
* Added a new option in the "Actions" dropdown within the Inventory app search page for "+New MARC Bib Record". Refs UIIN-2356.
* Change the url for the "New MARC Bib Record" page. Refs UIIN-2380.
@@ -100,7 +103,11 @@
* Instance 3rd pane: Add consortial holdings/item accordion. Refs UIIN-2410.
* Consortial Central Tenant: Handling Holdings and Item actions on the Instance detail view. Refs UIIN-2523.
* Hide Held by facet in Inventory contributor and subject browse. Refs UIIN-2591.
-* Enable/disable consortial holdings/item actions based on User permissions. Refs UIIN-2452.
+* Use `==` for exact phrase search in Advanced Search for all full-text and term fields. Refs UIIN-2612.
+* Provide an instance `tenantId` to the PO line form when creating an order from the instance. Refs UIIN-2614.
+* Bump @folio/stripes-acq-components dependency version to 5.0.0. Refs UIIN-2620.
+* ECS: Check when sharing instance with source=MARC is complete before re-fetching it. Refs UIIN-2605.
+* Update all facets after changing a term or selecting a facet option. Refs UIIN-2610.
## [9.4.12](https://github.com/folio-org/ui-inventory/tree/v9.4.12) (2023-09-21)
[Full Changelog](https://github.com/folio-org/ui-inventory/compare/v9.4.11...v9.4.12)
diff --git a/package.json b/package.json
index c005c64bc..285aa1008 100644
--- a/package.json
+++ b/package.json
@@ -871,7 +871,7 @@
"eslint-plugin-filenames": "^1.3.2",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jest": "^24.0.0",
- "inflected": "^2.0.4",
+ "inflected": "^2.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-intl": "^6.4.4",
@@ -883,7 +883,7 @@
},
"dependencies": {
"@folio/quick-marc": "^7.0.0",
- "@folio/stripes-acq-components": "^4.0.0",
+ "@folio/stripes-acq-components": "^5.0.0",
"classnames": "^2.3.2",
"file-saver": "^2.0.0",
"final-form": "^4.18.2",
diff --git a/src/Instance/InstanceDetails/InstanceDetails.js b/src/Instance/InstanceDetails/InstanceDetails.js
index 7c0d0c7de..f24701aca 100644
--- a/src/Instance/InstanceDetails/InstanceDetails.js
+++ b/src/Instance/InstanceDetails/InstanceDetails.js
@@ -19,6 +19,7 @@ import {
PaneMenu,
Row,
MessageBanner,
+ Icon,
} from '@folio/stripes/components';
import { InstanceTitle } from './InstanceTitle';
@@ -36,9 +37,17 @@ import { InstanceNewHolding } from './InstanceNewHolding';
import { InstanceAcquisition } from './InstanceAcquisition';
import HelperApp from '../../components/HelperApp';
-import { getAccordionState } from './utils';
import { DataContext } from '../../contexts';
import { ConsortialHoldings } from './ConsortialHoldings';
+import {
+ getAccordionState,
+ getPublishingInfo,
+} from './utils';
+import {
+ getDate,
+ isInstanceShadowCopy,
+ isUserInConsortiumMode,
+} from '../../utils';
const accordions = {
administrative: 'acc01',
@@ -57,23 +66,25 @@ const accordions = {
const InstanceDetails = forwardRef(({
children,
instance,
- paneTitle,
- paneSubtitle,
onClose,
actionMenu,
tagsEnabled,
userTenantPermissions,
+ isShared,
+ isLoading,
...rest
}, ref) => {
+ const intl = useIntl();
const stripes = useStripes();
const { okapi: { tenant: tenantId } } = stripes;
- const intl = useIntl();
+
const location = useLocation();
const searchParams = new URLSearchParams(location.search);
const referenceData = useContext(DataContext);
const accordionState = useMemo(() => getAccordionState(instance, accordions), [instance]);
const [helperApp, setHelperApp] = useState();
+
const tags = instance?.tags?.tagList;
const isUserInCentralTenant = checkIfUserInCentralTenant(stripes);
@@ -97,14 +108,61 @@ const InstanceDetails = forwardRef(({
);
}, [tagsEnabled, tags, intl]);
+ if (isLoading) {
+ return (
+ }
+ dismissible
+ onClose={onClose}
+ >
+
+
+
+
+ );
+ }
+
+ const renderPaneTitle = () => {
+ const isInstanceShared = Boolean(isShared || isInstanceShadowCopy(instance?.source));
+
+ return (
+
+ );
+ };
+
+ const renderPaneSubtitle = () => {
+ return (
+
+ );
+ };
+
return (
<>
}
- paneTitle={paneTitle}
- paneSub={paneSubtitle}
+ paneTitle={renderPaneTitle()}
+ paneSub={renderPaneSubtitle()}
dismissible
onClose={onClose}
actionMenu={actionMenu}
@@ -243,16 +301,18 @@ InstanceDetails.propTypes = {
actionMenu: PropTypes.func,
onClose: PropTypes.func.isRequired,
instance: PropTypes.object,
- paneTitle: PropTypes.object,
- paneSubtitle: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
tagsToggle: PropTypes.func,
tagsEnabled: PropTypes.bool,
userTenantPermissions: PropTypes.arrayOf(PropTypes.object),
+ isLoading: PropTypes.bool,
+ isShared: PropTypes.bool,
};
InstanceDetails.defaultProps = {
instance: {},
tagsEnabled: false,
+ isLoading: false,
+ isShared: false,
};
export default InstanceDetails;
diff --git a/src/Instance/InstanceDetails/utils.js b/src/Instance/InstanceDetails/utils.js
index 1d9b3bbbb..b97ad2555 100644
--- a/src/Instance/InstanceDetails/utils.js
+++ b/src/Instance/InstanceDetails/utils.js
@@ -20,7 +20,7 @@ export const getPublishingInfo = instance => {
return undefined;
};
-export const getAccordionState = (instance, accordions) => {
+export const getAccordionState = (instance = {}, accordions = {}) => {
const instanceData = pick(
instance,
['hrid', 'source', 'catalogedDate', 'statusId', 'statusUpdatedDate', 'modeOfIssuanceId', 'statisticalCodeIds'],
@@ -48,13 +48,13 @@ export const getAccordionState = (instance, accordions) => {
return ({
[accordions.administrative]: !areAllFieldsEmpty(values(instanceData)),
[accordions.title]: !areAllFieldsEmpty(values(titleData)),
- [accordions.identifiers]: !areAllFieldsEmpty([instance.identifiers ?? []]),
- [accordions.contributors]: !areAllFieldsEmpty([instance.contributors ?? []]),
+ [accordions.identifiers]: !areAllFieldsEmpty([instance?.identifiers ?? []]),
+ [accordions.contributors]: !areAllFieldsEmpty([instance?.contributors ?? []]),
[accordions.descriptiveData]: !areAllFieldsEmpty(values(descriptiveData)),
[accordions.notes]: !areAllFieldsEmpty([instance?.notes ?? []]),
- [accordions.electronicAccess]: !areAllFieldsEmpty([instance.electronicAccess ?? []]),
- [accordions.subjects]: !areAllFieldsEmpty([instance.subjects ?? []]),
- [accordions.classifications]: !areAllFieldsEmpty([instance.classifications ?? []]),
+ [accordions.electronicAccess]: !areAllFieldsEmpty([instance?.electronicAccess ?? []]),
+ [accordions.subjects]: !areAllFieldsEmpty([instance?.subjects ?? []]),
+ [accordions.classifications]: !areAllFieldsEmpty([instance?.classifications ?? []]),
[accordions.relationship]: !areAllFieldsEmpty(values(instanceRelationship)),
});
};
diff --git a/src/ViewInstance.js b/src/ViewInstance.js
index 6f1251da9..e736d5cf2 100644
--- a/src/ViewInstance.js
+++ b/src/ViewInstance.js
@@ -9,18 +9,16 @@ import {
import {
flowRight,
isEmpty,
+ pick,
} from 'lodash';
import {
- AppIcon,
Pluggable,
stripesConnect,
checkIfUserInMemberTenant,
checkIfUserInCentralTenant,
} from '@folio/stripes/core';
import {
- Pane,
- Icon,
MenuSection,
Callout,
checkScope,
@@ -34,18 +32,19 @@ import ViewHoldingsRecord from './ViewHoldingsRecord';
import makeConnectedInstance from './ConnectedInstance';
import withLocation from './withLocation';
import InstancePlugin from './components/InstancePlugin';
-import { getPublishingInfo } from './Instance/InstanceDetails/utils';
import {
getDate,
getUserTenantsPermissions,
handleKeyCommand,
isInstanceShadowCopy,
isMARCSource,
- isUserInConsortiumMode,
} from './utils';
import {
+ AUTHORITY_LINKED_FIELDS,
indentifierTypeNames,
+ INSTANCE_SHARING_STATUSES,
layers,
+ OKAPI_TENANT_HEADER,
REQUEST_OPEN_STATUSES,
} from './constants';
import { DataContext } from './contexts';
@@ -177,18 +176,22 @@ class ViewInstance extends React.Component {
this.log = logger.log.bind(logger);
this.state = {
+ isLoading: false,
marcRecord: null,
findInstancePluginOpened: false,
isItemsMovement: false,
isImportRecordModalOpened: false,
isCopyrightModalOpened: false,
isShareLocalInstanceModalOpen: false,
+ isUnlinkAuthoritiesModalOpen: false,
+ linkedAuthoritiesLength: 0,
isNewOrderModalOpen: false,
afterCreate: false,
instancesQuickExportInProgress: false,
userTenantPermissions: [],
};
this.instanceId = null;
+ this.intervalId = null;
this.cViewHoldingsRecord = this.props.stripes.connect(ViewHoldingsRecord);
this.calloutRef = createRef();
@@ -253,6 +256,7 @@ class ViewInstance extends React.Component {
componentWillUnmount() {
this.props.mutator.allInstanceItems.reset();
+ clearInterval(this.intervalId);
}
getCurrentTenantPermissions = () => {
@@ -432,6 +436,48 @@ class ViewInstance extends React.Component {
this.setState({ isImportRecordModalOpened: false });
}
+ checkInstanceSharingProgress = ({ sourceTenantId, instanceIdentifier }) => {
+ return this.props.mutator.shareInstance.GET({
+ params: { sourceTenantId, instanceIdentifier },
+ headers: {
+ [OKAPI_TENANT_HEADER]: this.props.centralTenantId,
+ 'Content-Type': 'application/json',
+ ...(this.props.okapi.token && { 'X-Okapi-Token': this.props.okapi.token }),
+ },
+ });
+ }
+
+ waitForInstanceSharingComplete = ({ sourceTenantId, instanceIdentifier, instanceTitle }) => {
+ return new Promise((resolve, reject) => {
+ this.intervalId = setInterval(() => {
+ const onError = error => {
+ this.calloutRef.current.sendCallout({
+ type: 'error',
+ message: ,
+ });
+ clearInterval(this.intervalId);
+ reject(error);
+ };
+ const onSuccess = response => {
+ const sharingStatus = response?.sharingInstances[0]?.status;
+
+ if (sharingStatus === INSTANCE_SHARING_STATUSES.COMPLETE) {
+ clearInterval(this.intervalId);
+ resolve(response);
+ }
+
+ if (sharingStatus === INSTANCE_SHARING_STATUSES.ERROR) {
+ onError(response);
+ }
+ };
+
+ this.checkInstanceSharingProgress({ sourceTenantId, instanceIdentifier })
+ .then(onSuccess)
+ .catch(onError);
+ }, 2000);
+ });
+ }
+
handleShareLocalInstance = (instance = {}) => {
const centralTenantId = this.props.centralTenantId;
const sourceTenantId = this.props.okapi.tenant;
@@ -443,24 +489,66 @@ class ViewInstance extends React.Component {
instanceIdentifier,
targetTenantId: centralTenantId,
})
+ .then(async () => {
+ this.setState({
+ isUnlinkAuthoritiesModalOpen: false,
+ isShareLocalInstanceModalOpen: false,
+ isLoading: true
+ });
+
+ await this.waitForInstanceSharingComplete({ sourceTenantId, instanceIdentifier, instanceTitle });
+ })
.then(async () => {
await this.props.refetchInstance();
+ this.setState({ isLoading: false });
this.calloutRef.current.sendCallout({
type: 'success',
message: ,
});
})
.catch(() => {
- this.calloutRef.current.sendCallout({
+ this.setState({
+ isUnlinkAuthoritiesModalOpen: false,
+ isShareLocalInstanceModalOpen: false,
+ });
+ this.calloutRef.current?.sendCallout({
type: 'error',
message: ,
});
- })
- .finally(() => {
- this.setState({ isShareLocalInstanceModalOpen: false });
});
}
+ checkIfHasLinkedAuthorities = (instance = {}) => {
+ const linkedAuthorities = pick(this.props.selectedInstance, AUTHORITY_LINKED_FIELDS);
+
+ const findLinkedAuthorities = authorities => {
+ const linkedAuthoritiesLength = AUTHORITY_LINKED_FIELDS.reduce((total, field) => {
+ const authoritiesAmount = authorities[field].filter(item => item.authorityId).length;
+ return total + authoritiesAmount;
+ }, 0);
+
+ return {
+ hasLinkedAuthorities: !!linkedAuthoritiesLength,
+ linkedAuthoritiesLength,
+ };
+ };
+
+ const {
+ hasLinkedAuthorities,
+ linkedAuthoritiesLength,
+ } = findLinkedAuthorities(linkedAuthorities);
+
+ if (hasLinkedAuthorities) {
+ this.setState({
+ linkedAuthoritiesLength,
+ isShareLocalInstanceModalOpen: false,
+ isUnlinkAuthoritiesModalOpen: true,
+ });
+ } else {
+ this.handleShareLocalInstance(instance);
+ }
+ }
+
toggleCopyrightModal = () => {
this.setState(prevState => ({ isCopyrightModalOpened: !prevState.isCopyrightModalOpened }));
};
@@ -783,26 +871,6 @@ class ViewInstance extends React.Component {
);
};
- renderPaneTitle = (instance) => {
- const {
- stripes,
- isShared,
- } = this.props;
-
- const isInstanceShared = Boolean(isShared || isInstanceShadowCopy(instance?.source));
-
- return (
-
- );
- };
-
render() {
const {
match: { params: { id, holdingsrecordid, itemid } },
@@ -810,13 +878,13 @@ class ViewInstance extends React.Component {
okapi,
onCopy,
onClose,
- paneWidth,
tagsEnabled,
updateLocation,
canUseSingleRecordImport,
- intl,
isCentralTenantPermissionsLoading,
+ isShared,
} = this.props;
+ const { linkedAuthoritiesLength } = this.state;
const ci = makeConnectedInstance(this.props, stripes.logger);
const instance = ci.instance();
@@ -850,26 +918,7 @@ class ViewInstance extends React.Component {
handler: (e) => collapseAllSections(e, this.accordionStatusRef),
},
];
-
- if (!instance || isCentralTenantPermissionsLoading) {
- return (
- }
- dismissible
- onClose={onClose}
- >
-
-
-
-
- );
- }
+ const isInstanceLoading = this.state.isLoading || !instance || isCentralTenantPermissionsLoading;
return (
@@ -881,22 +930,14 @@ class ViewInstance extends React.Component {
>
- }
onClose={onClose}
actionMenu={this.createActionMenuGetter(instance, data)}
instance={instance}
tagsEnabled={tagsEnabled}
ref={this.accordionStatusRef}
userTenantPermissions={this.state.userTenantPermissions}
+ isLoading={isInstanceLoading}
+ isShared={isShared}
>
{
(!holdingsrecordid && !itemid) ?
@@ -919,7 +960,7 @@ class ViewInstance extends React.Component {
{this.state.afterCreate &&
}
+ message={}
/>
}
@@ -953,6 +994,15 @@ class ViewInstance extends React.Component {
message={}
confirmLabel={}
onCancel={() => this.setState({ isShareLocalInstanceModalOpen: false })}
+ onConfirm={() => this.checkIfHasLinkedAuthorities(instance)}
+ />
+
+ }
+ message={}
+ confirmLabel={}
+ onCancel={() => this.setState({ isUnlinkAuthoritiesModalOpen: false })}
onConfirm={() => this.handleShareLocalInstance(instance)}
/>
@@ -1005,11 +1055,13 @@ ViewInstance.propTypes = {
GET: PropTypes.func.isRequired,
reset: PropTypes.func.isRequired,
}).isRequired,
- shareInstance: PropTypes.shape({ POST: PropTypes.func.isRequired }).isRequired,
+ shareInstance: PropTypes.shape({
+ POST: PropTypes.func.isRequired,
+ GET: PropTypes.func.isRequired,
+ }).isRequired,
}),
onClose: PropTypes.func,
onCopy: PropTypes.func,
- paneWidth: PropTypes.string.isRequired,
resources: PropTypes.shape({
allInstanceItems: PropTypes.object.isRequired,
allInstanceHoldings: PropTypes.object.isRequired,
diff --git a/src/ViewInstance.test.js b/src/ViewInstance.test.js
index 9d8610088..188eb8000 100644
--- a/src/ViewInstance.test.js
+++ b/src/ViewInstance.test.js
@@ -186,7 +186,10 @@ const defaultProp = {
GET: jest.fn(() => Promise.resolve([])),
reset: jest.fn()
},
- shareInstance: { POST: jest.fn() },
+ shareInstance: {
+ POST: jest.fn(),
+ GET: jest.fn(() => Promise.resolve({ sharingInstances: [{ status: 'COMPLETE' }] })),
+ },
},
onClose: mockonClose,
onCopy: jest.fn(),
@@ -281,6 +284,7 @@ describe('ViewInstance', () => {
ok: true,
json: async () => ({}),
});
+ useStripes().hasInterface.mockReturnValue(true);
});
it('should display action menu items', () => {
renderViewInstance();
@@ -295,7 +299,7 @@ describe('ViewInstance', () => {
describe('instance header', () => {
describe('for non-consortia users', () => {
it('should render instance title, publisher, and publication date', () => {
- defaultProp.stripes.hasInterface.mockReturnValue(false);
+ useStripes().hasInterface.mockReturnValue(false);
const { getByText } = renderViewInstance();
const expectedTitle = 'Instance • #youthaction • Information Age Publishing, Inc. • 2015';
@@ -581,27 +585,65 @@ describe('ViewInstance', () => {
});
describe('when clicking Share local instance', () => {
- it('should show confirmation modal', () => {
- checkIfUserInMemberTenant.mockClear().mockReturnValue(true);
-
- renderViewInstance();
- fireEvent.click(screen.getByRole('button', { name: 'Actions' }));
- fireEvent.click(screen.getByRole('button', { name: 'Share local instance' }));
-
- expect(screen.getByText('Confirmation modal')).toBeInTheDocument();
- });
-
- describe('when confirming', () => {
- it('should make POST request to share local instance', () => {
- defaultProp.mutator.shareInstance.POST.mockResolvedValue({});
+ describe('and it has no linked MARC Authorities', () => {
+ it('should show confirmation modal', () => {
checkIfUserInMemberTenant.mockClear().mockReturnValue(true);
renderViewInstance();
fireEvent.click(screen.getByRole('button', { name: 'Actions' }));
fireEvent.click(screen.getByRole('button', { name: 'Share local instance' }));
- fireEvent.click(screen.getByRole('button', { name: 'Confirm' }));
- expect(defaultProp.mutator.shareInstance.POST).toHaveBeenCalled();
+ expect(screen.getByText('Confirmation modal')).toBeInTheDocument();
+ });
+ });
+
+ describe('when confirming', () => {
+ describe('and it has linked MARC Authorities', () => {
+ beforeEach(() => {
+ defaultProp.mutator.shareInstance.POST.mockResolvedValue({});
+ checkIfUserInMemberTenant.mockClear().mockReturnValue(true);
+
+ renderViewInstance({
+ selectedInstance: {
+ ...instances[0],
+ alternativeTitles: [{
+ alternativeTitleTypeId: 'fe19bae4-da28-472b-be90-d442e2428ead',
+ alternativeTitle: 'Hashtag youthaction',
+ authorityId: 'testAuthorityId'
+ }],
+ }
+ });
+ });
+
+ it('should render unlink local MARC Authorities modal', () => {
+ fireEvent.click(screen.getByRole('button', { name: 'Actions' }));
+ fireEvent.click(screen.getByRole('button', { name: 'Share local instance' }));
+ fireEvent.click(screen.getByRole('button', { name: 'Confirm' }));
+
+ expect(screen.getByText('Confirmation modal')).toBeInTheDocument();
+ });
+
+ describe('when proceed sharing', () => {
+ it('should make POST request to share local instance', () => {
+ fireEvent.click(screen.getByRole('button', { name: 'Actions' }));
+ fireEvent.click(screen.getByRole('button', { name: 'Share local instance' }));
+ fireEvent.click(screen.getByRole('button', { name: 'Confirm' }));
+ fireEvent.click(screen.getByRole('button', { name: 'Confirm' }));
+
+ expect(defaultProp.mutator.shareInstance.POST).toHaveBeenCalled();
+ });
+ });
+
+ describe('when cancel sharing', () => {
+ it('should hide confirmation modal', () => {
+ fireEvent.click(screen.getByRole('button', { name: 'Actions' }));
+ fireEvent.click(screen.getByRole('button', { name: 'Share local instance' }));
+ fireEvent.click(screen.getByRole('button', { name: 'Confirm' }));
+ fireEvent.click(screen.getByRole('button', { name: 'Cancel' }));
+
+ expect(screen.queryByText('Confirmation modal')).not.toBeInTheDocument();
+ });
+ });
});
});
});
diff --git a/src/common/hooks/useFacets.js b/src/common/hooks/useFacets.js
index 916259359..a8ef5e659 100644
--- a/src/common/hooks/useFacets.js
+++ b/src/common/hooks/useFacets.js
@@ -4,15 +4,27 @@ import _ from 'lodash';
import { useFacetSettings } from '../../stores/facetsStore';
+// Facets behavior (useFacets and withFacets):
+// - when the user opens a facet, the first 6 options must be fetched for it;
+// - when the user clicks the "+More" button under the options, all options for that facet must be fetched;
+// - 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.
+
const useFacets = (
segmentAccordions,
segmentOptions,
selectedFacetFilters,
getNewRecords,
data,
+ isFetchFacetsAfterReset = true,
) => {
const {
- query: { query, filters = '' },
+ query: {
+ query,
+ qindex,
+ filters = '',
+ },
onFetchFacets,
parentResources: { facets },
} = data;
@@ -30,7 +42,9 @@ const useFacets = (
const prevAccordionsState = useRef(accordions);
const prevFilters = useRef({});
const prevUrl = useRef({});
- const prevQuery = useRef('');
+ const prevQindex = useRef('');
+ const isSearchOptionChanged = useRef(false);
+ const isReset = useRef(false);
const onToggleSection = useCallback(({ id }) => {
setAccordions(curState => {
@@ -40,6 +54,15 @@ const useFacets = (
});
}, []);
+ const onUnregisterAccordion = useCallback((id) => {
+ setAccordions(curState => {
+ const newState = _.cloneDeep(curState);
+ newState[id] = false;
+ return newState;
+ });
+ delete prevUrl.current[id];
+ }, []);
+
const handleFilterSearch = useCallback((filter) => {
const {
name,
@@ -146,6 +169,12 @@ const useFacets = (
showLoadingForAllFacets
]);
+ useEffect(() => {
+ isSearchOptionChanged.current = !query && !filters && qindex && prevQindex.current && qindex !== prevQindex.current;
+ isReset.current = !query && !filters && !qindex;
+ prevQindex.current = qindex;
+ }, [qindex, filters, query]);
+
useEffect(() => {
if (!_.isEmpty(records)) {
const newRecords = getNewRecords(records);
@@ -155,17 +184,12 @@ const useFacets = (
useEffect(() => {
let facetToOpen = '';
- let facetToClose = '';
const isFacetOpened = _.some(prevAccordionsState.current, (prevFacetValue, facetName) => {
const curFacetValue = accordions[facetName];
- if (curFacetValue !== prevFacetValue) {
- if (curFacetValue) {
- facetToOpen = facetName;
- } else {
- facetToClose = facetName;
- }
+ if (curFacetValue !== prevFacetValue && curFacetValue) {
+ facetToOpen = facetName;
return curFacetValue;
}
return false;
@@ -180,8 +204,7 @@ const useFacets = (
!facetToOpen.match(/updatedDate/i)
) {
handleFetchFacets({ facetToOpen });
- } else {
- prevUrl.current[facetToClose] = location.search;
+ prevUrl.current[facetToOpen] = location.search;
}
prevAccordionsState.current = { ...accordions };
@@ -189,10 +212,16 @@ const useFacets = (
useEffect(() => {
if (!_.isEmpty(accordionsData)) {
- const isNoFilterSelected = _.every(accordionsData, value => !value?.isSelected);
- if (!query && prevQuery.current && isNoFilterSelected) return;
+ // When there is a value in the search box and any facet option is selected and the user resets the search,
+ // and `isFetchFacetsAfterReset` is true, then two useEffects are called, one is tracking `query` and another is
+ // tracking `accordionsData`, hence 2 calls are fired, so let's check url to make only 1 call.
+ const areOpenFacetsAlreadyFetched = prevUrl.current.all === location.search;
- handleFetchFacets({ focusedFacet: facetNameToOpen });
+ if (isSearchOptionChanged.current || (!isFetchFacetsAfterReset && isReset.current) || areOpenFacetsAlreadyFetched) {
+ return;
+ }
+ handleFetchFacets();
+ prevUrl.current.all = location.search;
}
}, [accordionsData]);
@@ -204,15 +233,14 @@ const useFacets = (
useEffect(() => {
const isSomeFacetOpened = _.some(accordions, isFacetOpened => isFacetOpened);
- const isValidQuery = (query && query !== prevQuery.current) || (query !== undefined && prevQuery.current);
+
+ if (isSearchOptionChanged.current || (!isFetchFacetsAfterReset && isReset.current)) {
+ return;
+ }
if (isSomeFacetOpened) {
- if (isValidQuery) {
- prevQuery.current = query;
- handleFetchFacets({ facetToOpen: facetNameToOpen });
- }
- } else if (isValidQuery) {
- prevQuery.current = query;
+ handleFetchFacets();
+ prevUrl.current.all = location.search;
}
}, [query]);
@@ -223,6 +251,7 @@ const useFacets = (
handleFilterSearch,
facetsOptions,
getIsPending,
+ onUnregisterAccordion,
];
};
diff --git a/src/common/hooks/useFacets.test.js b/src/common/hooks/useFacets.test.js
index 66f8bb28d..17d01ba0b 100644
--- a/src/common/hooks/useFacets.test.js
+++ b/src/common/hooks/useFacets.test.js
@@ -43,6 +43,378 @@ describe('useFacets', () => {
useFacetSettings.mockReturnValue([selectedFacetFilters, jest.fn()]);
});
+ describe('onFetchFacets', () => {
+ const _segmentAccordions = {
+ resource: false,
+ format: false,
+ };
+
+ const _segmentOptions = {
+ resourceTypeOptions: [],
+ instanceFormatOptions: [],
+ };
+
+ const _selectedFacetFilters = {
+ resource: undefined,
+ format: undefined,
+ };
+
+ const _getNewRecords = jest.fn();
+
+ const _data = {
+ instanceFormats: [
+ {
+ 'id': '8d511d33-5e85-4c5d-9bce-6e3c9cd0c324',
+ 'name': 'unmediated -- volume',
+ 'code': 'nc',
+ 'source': 'rdacarrier',
+ },
+ {
+ 'id': 'f5e8210f-7640-459b-a71f-552567f92369',
+ 'name': 'computer -- online resource',
+ 'code': 'cr',
+ 'source': 'rdacarrier',
+ }, {
+ 'id': '5cb91d15-96b1-4b8a-bf60-ec310538da66',
+ 'name': 'audio -- audio disc',
+ 'code': 'sd',
+ 'source': 'rdacarrier',
+ }
+ ],
+ resourceTypes: [
+ {
+ 'id': '6312d172-f0cf-40f6-b27d-9fa8feaf332f',
+ 'name': 'text',
+ 'code': 'txt',
+ 'source': 'rdacontent',
+ },
+ {
+ 'id': '30fffe0e-e985-4144-b2e2-1e8179bdb41f',
+ 'name': 'unspecified',
+ 'code': 'zzz',
+ 'source': 'rdacontent',
+ },
+ {
+ 'id': '535e3160-763a-42f9-b0c0-d8ed7df6e2a2',
+ 'name': 'still image',
+ 'code': 'sti',
+ 'source': 'rdacontent',
+ },
+ ],
+ query: {},
+ parentResources: {
+ facets: { records: [] },
+ },
+ onFetchFacets: jest.fn(),
+ };
+
+ describe('when user opens a facet', () => {
+ it('should fetch only 6 options for this facet', () => {
+ useLocation.mockReturnValue({ search: '?segment=instances&sort=title' });
+
+ const { result } = renderHook(() => useFacets(
+ _segmentAccordions,
+ _segmentOptions,
+ _selectedFacetFilters,
+ _getNewRecords,
+ _data,
+ ));
+
+ const onToggleSection = result.current[1];
+
+ act(() => { onToggleSection({ id: 'resource' }); });
+
+ expect(_data.onFetchFacets).toHaveBeenCalledWith({ facetToOpen: 'resource' });
+ });
+ });
+
+ describe('when user clicks the "+More" button under options', () => {
+ it('should fetch all options for this facet', () => {
+ const mockSetFacetSettings = jest.fn();
+ useFacetSettings.mockReturnValue([{}, mockSetFacetSettings]);
+
+ const { result } = renderHook(() => useFacets(
+ _segmentAccordions,
+ _segmentOptions,
+ _selectedFacetFilters,
+ _getNewRecords,
+ _data,
+ ));
+
+ const handleFetchFacets = result.current[2];
+ act(() => { handleFetchFacets({ onMoreClickedFacet: 'resource' }); });
+
+ expect(mockSetFacetSettings).toHaveBeenCalledWith('resource', { isOnMoreClicked: true });
+ expect(_data.onFetchFacets).toHaveBeenCalledWith({ onMoreClickedFacet: 'resource' });
+ });
+ });
+
+ describe('when user places the cursor in the facet`s input field', () => {
+ it('should fetch all options for this facet', () => {
+ const { result } = renderHook(() => useFacets(
+ _segmentAccordions,
+ _segmentOptions,
+ _selectedFacetFilters,
+ _getNewRecords,
+ _data,
+ ));
+
+ const handleFetchFacets = result.current[2];
+
+ act(() => { handleFetchFacets({ focusedFacet: 'resource' }); });
+
+ expect(_data.onFetchFacets).toHaveBeenCalledWith({ focusedFacet: 'resource' });
+ });
+ });
+
+ describe('when several facets are open and user enters a value in the search box', () => {
+ it('should fetch options for all open facets', () => {
+ useFacetSettings.mockReturnValue([{}, jest.fn()]);
+ useLocation.mockReturnValue({ search: '' });
+
+ const { result, rerender } = renderHook(({ newData }) => useFacets(
+ _segmentAccordions,
+ _segmentOptions,
+ _selectedFacetFilters,
+ _getNewRecords,
+ newData,
+ ), {
+ initialProps: { newData: _data },
+ });
+
+ const onToggleSection = result.current[1];
+
+ act(() => { onToggleSection({ id: 'resource' }); });
+ act(() => { onToggleSection({ id: 'format' }); });
+
+ _data.onFetchFacets.mockClear();
+
+ useLocation.mockReturnValue({ search: '?query=Mark' });
+
+ rerender({
+ newData: {
+ ..._data,
+ query: { ..._data.query, query: 'Mark' },
+ },
+ });
+
+ expect(_data.onFetchFacets).toHaveBeenCalledWith({
+ accordions: { resource: true, format: true },
+ accordionsData: {},
+ });
+ });
+ });
+
+ describe('when several facets are open and user selects an option of any facet', () => {
+ it('should fetch options for all open facets', () => {
+ useFacetSettings.mockReturnValue([{}, jest.fn()]);
+ useLocation.mockReturnValue({ search: '' });
+ const isFetchFacetsAfterReset = false;
+
+ const { result, rerender } = renderHook(({ newData, newSelectedFacetFilters }) => useFacets(
+ _segmentAccordions,
+ _segmentOptions,
+ newSelectedFacetFilters,
+ _getNewRecords,
+ newData,
+ isFetchFacetsAfterReset,
+ ), {
+ initialProps: {
+ newData: _data,
+ newSelectedFacetFilters: _selectedFacetFilters,
+ },
+ });
+
+ const onToggleSection = result.current[1];
+
+ act(() => { onToggleSection({ id: 'resource' }); });
+ act(() => { onToggleSection({ id: 'format' }); });
+
+ _data.onFetchFacets.mockClear();
+
+ useLocation.mockReturnValue({ search: '?callNumbersTenantId=university&qindex=callNumbers' });
+
+ rerender({
+ newData: {
+ ..._data,
+ query: { ..._data.query, filters: 'resource.6312d172-f0cf-40f6-b27d-9fa8feaf332f' },
+ },
+ newSelectedFacetFilters: { ..._selectedFacetFilters, resource: ['6312d172-f0cf-40f6-b27d-9fa8feaf332f'] },
+ });
+
+ expect(_data.onFetchFacets).toHaveBeenCalledWith({
+ accordions: { resource: true, format: true },
+ accordionsData: {
+ resource: { isSelected: true },
+ },
+ });
+ });
+ });
+
+ describe('when there is a value in the search box and any facet option is selected', () => {
+ describe('and the user selects another search option', () => {
+ it('should not call onFetchFacets', () => {
+ useFacetSettings.mockReturnValue([{}, jest.fn()]);
+ useLocation.mockReturnValue({ search: '?callNumbersTenantId=university&qindex=callNumbers&query=Mark' });
+ const isFetchFacetsAfterReset = false;
+
+ const { rerender } = renderHook(({ newData, newSelectedFacetFilters }) => useFacets(
+ _segmentAccordions,
+ _segmentOptions,
+ newSelectedFacetFilters,
+ _getNewRecords,
+ newData,
+ isFetchFacetsAfterReset,
+ ), {
+ initialProps: {
+ newData: {
+ ..._data,
+ query: {
+ ..._data.query,
+ query: 'Mark',
+ qindex: 'callNumbers',
+ filters: 'resource.6312d172-f0cf-40f6-b27d-9fa8feaf332f',
+ },
+ },
+ newSelectedFacetFilters: { ..._selectedFacetFilters, resource: ['6312d172-f0cf-40f6-b27d-9fa8feaf332f'] },
+ },
+ });
+
+ _data.onFetchFacets.mockClear();
+
+ useLocation.mockReturnValue('');
+
+ rerender({
+ newData: {
+ ..._data,
+ query: {
+ ..._data.query,
+ query: undefined,
+ qindex: 'local',
+ filters: undefined,
+ },
+ },
+ newSelectedFacetFilters: _selectedFacetFilters,
+ });
+
+ expect(_data.onFetchFacets).not.toHaveBeenCalled();
+ });
+ });
+ });
+
+ describe('when the "Search" lookup and there is a value in the search box and facet option is selected', () => {
+ describe('and the user reset the search', () => {
+ it('should call onFetchFacets for all open facets once', () => {
+ useFacetSettings.mockReturnValue([{}, jest.fn()]);
+ useLocation.mockReturnValue({ search: '?segment=instances&sort=title&query=Mark' });
+
+ const { result, rerender } = renderHook(({ newData, newSelectedFacetFilters }) => useFacets(
+ _segmentAccordions,
+ _segmentOptions,
+ newSelectedFacetFilters,
+ _getNewRecords,
+ newData,
+ ), {
+ initialProps: {
+ newData: {
+ ..._data,
+ query: {
+ ..._data.query,
+ query: 'Mark',
+ qindex: '',
+ filters: 'resource.6312d172-f0cf-40f6-b27d-9fa8feaf332f',
+ },
+ },
+ newSelectedFacetFilters: { ..._selectedFacetFilters, resource: ['6312d172-f0cf-40f6-b27d-9fa8feaf332f'] },
+ },
+ });
+
+ const onToggleSection = result.current[1];
+
+ act(() => { onToggleSection({ id: 'resource' }); });
+
+ _data.onFetchFacets.mockClear();
+
+ useLocation.mockReturnValue({ search: '' });
+
+ rerender({
+ newData: {
+ ..._data,
+ query: {
+ ..._data.query,
+ query: undefined,
+ qindex: undefined,
+ filters: undefined,
+ },
+ },
+ newSelectedFacetFilters: _selectedFacetFilters,
+ });
+
+ expect(_data.onFetchFacets).toHaveBeenCalledTimes(1);
+ expect(_data.onFetchFacets).toHaveBeenCalledWith({
+ accordions: { format: false, resource: true },
+ accordionsData: expect.anything(),
+ });
+ });
+ });
+ });
+
+ 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', () => {
+ useFacetSettings.mockReturnValue([{}, jest.fn()]);
+ useLocation.mockReturnValue({ search: '?query=Mark' });
+ const isFetchFacetsAfterReset = false;
+
+ const { result, rerender } = renderHook(({ newData, newSelectedFacetFilters }) => useFacets(
+ _segmentAccordions,
+ _segmentOptions,
+ newSelectedFacetFilters,
+ _getNewRecords,
+ newData,
+ isFetchFacetsAfterReset,
+ ), {
+ initialProps: {
+ newData: {
+ ..._data,
+ query: {
+ ..._data.query,
+ query: 'Mark',
+ qindex: '',
+ filters: 'resource.6312d172-f0cf-40f6-b27d-9fa8feaf332f',
+ },
+ },
+ newSelectedFacetFilters: { ..._selectedFacetFilters, resource: ['6312d172-f0cf-40f6-b27d-9fa8feaf332f'] },
+ },
+ });
+
+ const onToggleSection = result.current[1];
+
+ act(() => { onToggleSection({ id: 'resource' }); });
+
+ _data.onFetchFacets.mockClear();
+
+ useLocation.mockReturnValue({ search: '' });
+
+ rerender({
+ newData: {
+ ..._data,
+ query: {
+ ..._data.query,
+ query: undefined,
+ qindex: undefined,
+ filters: undefined,
+ },
+ },
+ newSelectedFacetFilters: _selectedFacetFilters,
+ });
+
+ expect(_data.onFetchFacets).not.toHaveBeenCalled();
+ });
+ });
+ });
+ });
+
it('returns initial state', () => {
const { result } = renderHook(() => useFacets(
segmentAccordions,
diff --git a/src/components/BrowseInventoryFilters/BrowseInventoryFilters.js b/src/components/BrowseInventoryFilters/BrowseInventoryFilters.js
index 55ad1ad28..d0e40898c 100644
--- a/src/components/BrowseInventoryFilters/BrowseInventoryFilters.js
+++ b/src/components/BrowseInventoryFilters/BrowseInventoryFilters.js
@@ -19,14 +19,16 @@ const BrowseInventoryFilters = ({
const data = useContext(DataContext);
const filters = omit(activeFilters || {}, ['qindex', 'query']);
+ const isBrowseLookup = true;
const filtersData = {
...data,
browseType: searchIndex,
- onFetchFacets: fetchFacets(data),
+ onFetchFacets: fetchFacets(data, isBrowseLookup),
parentResources: resources,
query: {
query: activeFilters.query,
filters: parseFiltersToStr(filters),
+ qindex: searchIndex,
}
};
diff --git a/src/components/CheckboxFacet/CheckboxFacet.js b/src/components/CheckboxFacet/CheckboxFacet.js
index 818a55f9a..aa169ecfc 100644
--- a/src/components/CheckboxFacet/CheckboxFacet.js
+++ b/src/components/CheckboxFacet/CheckboxFacet.js
@@ -49,10 +49,6 @@ export default class CheckboxFacet extends React.Component {
) {
this.updateMore();
}
-
- if (prevDataLength > currentDataLength && currentDataLength === DEFAULT_FILTERS_NUMBER) {
- this.setDefaultMore();
- }
}
onMoreClick = (totalOptions) => {
@@ -105,10 +101,6 @@ export default class CheckboxFacet extends React.Component {
});
}
- setDefaultMore = () => {
- this.setState(({ more: SHOW_OPTIONS_COUNT }));
- }
-
render() {
const {
dataOptions,
diff --git a/src/components/InstanceFilters/InstanceFiltersBrowse/InstanceFiltersBrowse.js b/src/components/InstanceFilters/InstanceFiltersBrowse/InstanceFiltersBrowse.js
index edfefba59..1fa52e953 100644
--- a/src/components/InstanceFilters/InstanceFiltersBrowse/InstanceFiltersBrowse.js
+++ b/src/components/InstanceFilters/InstanceFiltersBrowse/InstanceFiltersBrowse.js
@@ -113,16 +113,22 @@ const InstanceFiltersBrowse = props => {
handleFilterSearch,
facetsOptions,
getIsPending,
+ onUnregisterAccordion,
] = useFacets(
segmentAccordions,
segmentOptions,
selectedFacetFilters,
getNewRecords,
- props.data
+ props.data,
+ false,
);
return (
-
+
{Object.values(browseCallNumberOptions).includes(browseType) && (
<>
{isUserInMemberTenant && (
diff --git a/src/components/NewOrderModal/NewOrderModalContainer.js b/src/components/NewOrderModal/NewOrderModalContainer.js
index 2266554a3..71f527dd4 100644
--- a/src/components/NewOrderModal/NewOrderModalContainer.js
+++ b/src/components/NewOrderModal/NewOrderModalContainer.js
@@ -9,8 +9,12 @@ import {
useParams,
} from 'react-router-dom';
-import { useOkapiKy } from '@folio/stripes/core';
+import {
+ useOkapiKy,
+ useStripes,
+} from '@folio/stripes/core';
+import { useInstance } from '../../common';
import { ORDERS_API } from '../../constants';
import NewOrderModal from './NewOrderModal';
@@ -20,7 +24,9 @@ const NewOrderModalContainer = ({
}) => {
const history = useHistory();
const ky = useOkapiKy();
+ const stripes = useStripes();
const { id } = useParams();
+ const { instance } = useInstance(id);
const [orderId, setOrderId] = useState();
const validatePONumber = useCallback(async (poNumber) => {
@@ -45,9 +51,10 @@ const NewOrderModalContainer = ({
const onSubmit = useCallback(() => {
const route = orderId ? `/orders/view/${orderId}/po-line/create` : '/orders/create';
+ const instanceTenantId = instance?.tenantId || stripes.okapi.tenant;
- history.push(route, { instanceId: id });
- }, [orderId]);
+ history.push(route, { instanceId: instance?.id, instanceTenantId });
+ }, [instance, orderId, stripes.okapi.tenant]);
return (
({
...jest.requireActual('react-router-dom'),
useHistory: jest.fn()
}));
+jest.mock('../../common', () => ({
+ ...jest.requireActual('../../common'),
+ useInstance: jest.fn(),
+}));
+
+global.document.createRange = jest.fn(() => new Range());
const defaultProps = {
onCancel: jest.fn(),
@@ -44,18 +51,25 @@ describe('NewOrderModalContainer', () => {
const historyMock = {
push: jest.fn(),
};
+ const order = {
+ id: 'orderId',
+ };
const kyMock = {
get: jest.fn(() => ({
json: () => Promise.resolve({
- purchaseOrders: [{ id: 'orderId' }],
+ purchaseOrders: [order],
})
}))
};
beforeEach(() => {
+ historyMock.push.mockClear();
useHistory
.mockClear()
.mockReturnValue(historyMock);
+ useInstance
+ .mockClear()
+ .mockReturnValue({ instance });
useOkapiKy
.mockClear()
.mockReturnValue(kyMock);
@@ -70,7 +84,7 @@ describe('NewOrderModalContainer', () => {
it('should navigate to \'PO\' creation form when create btn was clicked and \'PO number\' field is empty', async () => {
renderNewOrderModalContainer();
- await act(async () => fireEvent.click(screen.getByText(/^Create$/)));
+ await userEvent.click(screen.getByText(/^Create$/));
expect(historyMock.push).toHaveBeenCalledWith('/orders/create', expect.anything());
});
@@ -78,9 +92,19 @@ describe('NewOrderModalContainer', () => {
it('should navigate to \'PO Line\' creation form when create btn was clicked and PO is exist', async () => {
renderNewOrderModalContainer();
- await act(async () => fireEvent.change(screen.getByLabelText(/PO number/i), { target: { value: '123' } }));
- await act(async () => fireEvent.click(screen.getByText(/^Create$/)));
+ await userEvent.type(screen.getByLabelText(/PO number/i), '123');
+ await userEvent.tab();
+
+ expect(screen.queryByText('ui-inventory.newOrder.modal.PONumber.doesNotExist')).not.toBeInTheDocument();
+
+ await userEvent.click(await screen.findByText(/^Create$/));
- expect(historyMock.push).toHaveBeenCalledWith('/orders/create', { 'instanceId': undefined });
+ expect(historyMock.push).toHaveBeenCalledWith(
+ `/orders/view/${order.id}/po-line/create`,
+ {
+ instanceId: instance.id,
+ instanceTenantId: 'diku',
+ },
+ );
});
});
diff --git a/src/constants.js b/src/constants.js
index f29ecd6f6..534d4d280 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -372,50 +372,6 @@ export const FACETS_TO_REQUEST = {
[FACETS.HOLDINGS_TYPE]: FACETS_CQL.HOLDINGS_TYPE,
};
-const INSTANCES_FACET_ENDPOINT = 'search/instances/facets';
-const CONTRIBUTORS_FACET_ENDPOINT = 'search/contributors/facets';
-const SUBJECTS_FACET_ENDPOINT = 'search/subjects/facets';
-
-export const FACETS_ENDPOINTS = {
- [FACETS.SHARED]: INSTANCES_FACET_ENDPOINT,
- [FACETS.CONTRIBUTORS_SHARED]: CONTRIBUTORS_FACET_ENDPOINT,
- [FACETS.SUBJECTS_SHARED]: SUBJECTS_FACET_ENDPOINT,
- [FACETS.HELD_BY]: INSTANCES_FACET_ENDPOINT,
- [FACETS.CALL_NUMBERS_HELD_BY]: INSTANCES_FACET_ENDPOINT,
- [FACETS.CONTRIBUTORS_HELD_BY]: CONTRIBUTORS_FACET_ENDPOINT,
- [FACETS.SUBJECTS_HELD_BY]: SUBJECTS_FACET_ENDPOINT,
- [FACETS.EFFECTIVE_LOCATION]: INSTANCES_FACET_ENDPOINT,
- [FACETS.LANGUAGE]: INSTANCES_FACET_ENDPOINT,
- [FACETS.RESOURCE]: INSTANCES_FACET_ENDPOINT,
- [FACETS.FORMAT]: INSTANCES_FACET_ENDPOINT,
- [FACETS.MODE]: INSTANCES_FACET_ENDPOINT,
- [FACETS.NATURE_OF_CONTENT]: INSTANCES_FACET_ENDPOINT,
- [FACETS.STAFF_SUPPRESS]: INSTANCES_FACET_ENDPOINT,
- [FACETS.INSTANCES_DISCOVERY_SUPPRESS]: INSTANCES_FACET_ENDPOINT,
- [FACETS.HOLDINGS_DISCOVERY_SUPPRESS]: INSTANCES_FACET_ENDPOINT,
- [FACETS.ITEMS_DISCOVERY_SUPPRESS]: INSTANCES_FACET_ENDPOINT,
- [FACETS.SOURCE]: INSTANCES_FACET_ENDPOINT,
- [FACETS.STATUS]: INSTANCES_FACET_ENDPOINT,
- [FACETS.INSTANCES_TAGS]: INSTANCES_FACET_ENDPOINT,
- [FACETS.ITEMS_TAGS]: INSTANCES_FACET_ENDPOINT,
- [FACETS.HOLDINGS_TAGS]: INSTANCES_FACET_ENDPOINT,
- [FACETS.MATERIAL_TYPE]: INSTANCES_FACET_ENDPOINT,
- [FACETS.ITEM_STATUS]: INSTANCES_FACET_ENDPOINT,
- [FACETS.HOLDINGS_PERMANENT_LOCATION]: INSTANCES_FACET_ENDPOINT,
- [FACETS.CREATED_DATE]: INSTANCES_FACET_ENDPOINT,
- [FACETS.UPDATED_DATE]: INSTANCES_FACET_ENDPOINT,
- [FACETS.HOLDINGS_CREATED_DATE]: INSTANCES_FACET_ENDPOINT,
- [FACETS.HOLDINGS_UPDATED_DATE]: INSTANCES_FACET_ENDPOINT,
- [FACETS.HOLDINGS_SOURCE]: INSTANCES_FACET_ENDPOINT,
- [FACETS.ITEMS_CREATED_DATE]: INSTANCES_FACET_ENDPOINT,
- [FACETS.ITEMS_UPDATED_DATE]: INSTANCES_FACET_ENDPOINT,
- [FACETS.STATISTICAL_CODE_IDS]: INSTANCES_FACET_ENDPOINT,
- [FACETS.HOLDINGS_STATISTICAL_CODE_IDS]: INSTANCES_FACET_ENDPOINT,
- [FACETS.ITEMS_STATISTICAL_CODE_IDS]: INSTANCES_FACET_ENDPOINT,
- [FACETS.NAME_TYPE]: CONTRIBUTORS_FACET_ENDPOINT,
- [FACETS.HOLDINGS_TYPE]: INSTANCES_FACET_ENDPOINT,
-};
-
export const FACETS_OPTIONS = {
SHARED_OPTIONS: 'sharedOptions',
HELD_BY_OPTIONS: 'heldByOptions',
@@ -507,17 +463,17 @@ export const SINGLE_ITEM_QUERY_TEMPLATES = {
export const fieldSearchConfigurations = {
keyword: {
- exactPhrase: 'keyword==/string "%{query.query}"',
+ exactPhrase: 'keyword=="%{query.query}"',
containsAll: 'keyword all "%{query.query}"',
startsWith: 'keyword all "%{query.query}*"',
},
contributor: {
- exactPhrase: 'contributors.name==/string "%{query.query}"',
+ exactPhrase: 'contributors.name=="%{query.query}"',
containsAll: 'contributors.name="*%{query.query}*"',
startsWith: 'contributors.name="%{query.query}*"',
},
title: {
- exactPhrase: 'title==/string "%{query.query}"',
+ exactPhrase: 'title=="%{query.query}"',
containsAll: 'title all "%{query.query}"',
startsWith: 'title all "%{query.query}*"',
},
@@ -542,24 +498,24 @@ export const fieldSearchConfigurations = {
startsWith: 'oclc="%{query.query}*"',
},
instanceNotes: {
- exactPhrase: 'notes.note==/string "%{query.query}" or administrativeNotes==/string "%{query.query}"',
+ exactPhrase: 'notes.note=="%{query.query}" or administrativeNotes=="%{query.query}"',
containsAll: 'notes.note all "%{query.query}" or administrativeNotes all "%{query.query}"',
startsWith: 'notes.note all "%{query.query}*" or administrativeNotes all "%{query.query}*"',
},
instanceAdministrativeNotes: {
- exactPhrase: 'administrativeNotes==/string "%{query.query}"',
+ exactPhrase: 'administrativeNotes=="%{query.query}"',
containsAll: 'administrativeNotes all "%{query.query}"',
startsWith: 'administrativeNotes all "%{query.query}*"',
},
subject: {
- exactPhrase: 'subjects.value==/string "%{query.query}"',
+ exactPhrase: 'subjects.value=="%{query.query}"',
containsAll: 'subjects.value all "%{query.query}"',
- startsWith: 'subjects.value==/string "%{query.query}*"',
+ startsWith: 'subjects.value=="%{query.query}*"',
},
callNumber: {
- exactPhrase: 'itemEffectiveShelvingOrder==/string "%{query.query}"',
+ exactPhrase: 'itemEffectiveShelvingOrder=="%{query.query}"',
containsAll: 'itemEffectiveShelvingOrder="*%{query.query}*"',
- startsWith: 'itemEffectiveShelvingOrder==/string "%{query.query}*"',
+ startsWith: 'itemEffectiveShelvingOrder=="%{query.query}*"',
},
hrid: {
exactPhrase: 'hrid=="%{query.query}"',
@@ -577,7 +533,7 @@ export const fieldSearchConfigurations = {
startsWith: 'authorityId=="%{query.query}*"',
},
allFields: {
- exactPhrase: 'cql.all==/string "%{query.query}"',
+ exactPhrase: 'cql.all=="%{query.query}"',
containsAll: 'cql.all all "%{query.query}"',
startsWith: 'cql.all all "%{query.query}*"',
},
@@ -592,12 +548,12 @@ export const fieldSearchConfigurations = {
startsWith: 'holdingsNormalizedCallNumbers="%{query.query}*"',
},
holdingsNotes: {
- exactPhrase: 'holdings.notes.note==/string "%{query.query}" or holdings.administrativeNotes==/string "%{query.query}"',
+ exactPhrase: 'holdings.notes.note=="%{query.query}" or holdings.administrativeNotes=="%{query.query}"',
containsAll: 'holdings.notes.note all "%{query.query}" or holdings.administrativeNotes all "%{query.query}"',
startsWith: 'holdings.notes.note all "%{query.query}*" or holdings.administrativeNotes all "%{query.query}*"',
},
holdingsAdministrativeNotes: {
- exactPhrase: 'holdings.administrativeNotes==/string "%{query.query}"',
+ exactPhrase: 'holdings.administrativeNotes=="%{query.query}"',
containsAll: 'holdings.administrativeNotes all "%{query.query}"',
startsWith: 'holdings.administrativeNotes all "%{query.query}*"',
},
@@ -627,17 +583,17 @@ export const fieldSearchConfigurations = {
startsWith: 'itemNormalizedCallNumbers="%{query.query}*"',
},
itemNotes: {
- exactPhrase: 'item.notes.note==/string "%{query.query}" or item.administrativeNotes==/string "%{query.query}"',
+ exactPhrase: 'item.notes.note=="%{query.query}" or item.administrativeNotes=="%{query.query}"',
containsAll: 'item.notes.note all "%{query.query}" or item.administrativeNotes all "%{query.query}"',
startsWith: 'item.notes.note all "%{query.query}*" or item.administrativeNotes all "%{query.query}*"',
},
itemAdministrativeNotes: {
- exactPhrase: 'item.administrativeNotes==/string "%{query.query}"',
+ exactPhrase: 'item.administrativeNotes=="%{query.query}"',
containsAll: 'item.administrativeNotes all "%{query.query}"',
startsWith: 'item.administrativeNotes all "%{query.query}*"',
},
itemCirculationNotes: {
- exactPhrase: 'item.circulationNotes.note==/string "%{query.query}"',
+ exactPhrase: 'item.circulationNotes.note=="%{query.query}"',
containsAll: 'item.circulationNotes.note all "%{query.query}"',
startsWith: 'item.circulationNotes.note all "%{query.query}*"',
},
@@ -679,3 +635,16 @@ export const OKAPI_TOKEN_HEADER = 'X-Okapi-Token';
export const CONTENT_TYPE_HEADER = 'Content-Type';
export const DEFAULT_ITEM_TABLE_SORTBY_FIELD = 'barcode';
+
+export const AUTHORITY_LINKED_FIELDS = [
+ 'alternativeTitles',
+ 'contributors',
+ 'subjects',
+ 'series',
+];
+
+export const INSTANCE_SHARING_STATUSES = {
+ COMPLETE: 'COMPLETE',
+ ERROR: 'ERROR',
+ IN_PROGRESS: 'IN_PROGRESS',
+};
diff --git a/src/routes/buildManifestObject.test.js b/src/routes/buildManifestObject.test.js
index 00867bbae..877c01783 100644
--- a/src/routes/buildManifestObject.test.js
+++ b/src/routes/buildManifestObject.test.js
@@ -79,7 +79,7 @@ describe('buildQuery', () => {
const cql = buildQuery(...getBuildQueryArgs({ queryParams }));
expect(cql).toContain(
- '(keyword all "test" or title==/string "hello")'
+ '(keyword all "test" or title=="hello")'
);
});
diff --git a/src/settings/CallNumberTypes.js b/src/settings/CallNumberTypes.js
index a2488588a..351e590a9 100644
--- a/src/settings/CallNumberTypes.js
+++ b/src/settings/CallNumberTypes.js
@@ -23,8 +23,8 @@ class CallNumberTypes extends React.Component {
}
actionSuppressor = {
- edit: getSourceSuppressor(RECORD_SOURCE.SYSTEM),
- delete: getSourceSuppressor(RECORD_SOURCE.SYSTEM),
+ edit: getSourceSuppressor([RECORD_SOURCE.SYSTEM, RECORD_SOURCE.CONSORTIUM]),
+ delete: getSourceSuppressor([RECORD_SOURCE.SYSTEM, RECORD_SOURCE.CONSORTIUM]),
}
render() {
diff --git a/src/settings/CallNumberTypes.test.js b/src/settings/CallNumberTypes.test.js
index 82ea0f527..99ab55675 100644
--- a/src/settings/CallNumberTypes.test.js
+++ b/src/settings/CallNumberTypes.test.js
@@ -45,8 +45,8 @@ describe('CallNumberTypes', () => {
renderCallNumberTypes();
const actionSuppressor = {
- delete: expect(getSourceSuppressor).toHaveBeenNthCalledWith(1, RECORD_SOURCE.SYSTEM),
- edit: expect(getSourceSuppressor).toHaveBeenNthCalledWith(2, RECORD_SOURCE.SYSTEM),
+ delete: expect(getSourceSuppressor).toHaveBeenNthCalledWith(1, [RECORD_SOURCE.SYSTEM, RECORD_SOURCE.CONSORTIUM]),
+ edit: expect(getSourceSuppressor).toHaveBeenNthCalledWith(2, [RECORD_SOURCE.SYSTEM, RECORD_SOURCE.CONSORTIUM]),
};
expect(ControlledVocab).toHaveBeenCalledWith(expect.objectContaining({ actionSuppressor }), {});
diff --git a/src/withFacets.js b/src/withFacets.js
index 85123e20d..1675d2fcf 100644
--- a/src/withFacets.js
+++ b/src/withFacets.js
@@ -1,8 +1,12 @@
-import { reduce } from 'lodash';
+import {
+ reduce,
+ omit,
+} from 'lodash';
import React from 'react';
import PropTypes from 'prop-types';
import { makeQueryFunction } from '@folio/stripes/smart-components';
+import { buildFilterQuery } from '@folio/stripes-acq-components';
import {
getQueryTemplate,
@@ -13,9 +17,7 @@ import {
} from './filterConfig';
import {
DEFAULT_FILTERS_NUMBER,
- FACETS,
FACETS_TO_REQUEST,
- FACETS_ENDPOINTS,
CQL_FIND_ALL,
browseModeOptions,
browseModeMap,
@@ -114,7 +116,62 @@ function withFacets(WrappedComponent) {
}, '');
};
- fetchFacets = (data) => async (properties = {}) => {
+ getEndpoint = (queryIndex) => {
+ if (queryIndex === browseModeOptions.CONTRIBUTORS) {
+ return 'search/contributors/facets';
+ }
+
+ if (queryIndex === browseModeOptions.SUBJECTS) {
+ return 'search/subjects/facets';
+ }
+
+ return 'search/instances/facets';
+ }
+
+ getCqlQuery = (isBrowseLookup, query, queryIndex, data) => {
+ if (isBrowseLookup) {
+ const normalizedFilters = {
+ ...Object.entries(query).reduce((acc, [key, value]) => ({
+ ...acc,
+ [FACETS_TO_REQUEST[key] || key]: value,
+ }), {}),
+ query: query.query || undefined,
+ };
+
+ const otherFilters = omit(normalizedFilters, 'query', 'qindex');
+ const hasSelectedFacetOption = Object.values(otherFilters).some(Boolean);
+
+ let queryForBrowseFacets = '';
+
+ 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 {
+ queryForBrowseFacets = 'cql.allRecords=1';
+ }
+
+ return buildFilterQuery(
+ {
+ query: queryForBrowseFacets,
+ qindex: normalizedFilters.qindex,
+ ...otherFilters,
+ },
+ _query => _query,
+ undefined,
+ false,
+ );
+ }
+
+ return buildQuery(query, {}, { ...data, query }, { log: () => null }) || '';
+ }
+
+ fetchFacets = (data, isBrowseLookup) => async (properties = {}) => {
const {
onMoreClickedFacet,
focusedFacet,
@@ -136,24 +193,13 @@ function withFacets(WrappedComponent) {
// temporary query value
const params = { query: 'id = *' };
- const cqlQuery = buildQuery(query, {}, { ...data, query }, { log: () => null }) || '';
const facetName = facetToOpen || onMoreClickedFacet || focusedFacet;
const facetNameToRequest = FACETS_TO_REQUEST[facetName];
const paramsUrl = new URLSearchParams(window.location.search);
const queryIndex = paramsUrl.get('qindex') || query?.qindex;
+ const cqlQuery = this.getCqlQuery(isBrowseLookup, query, queryIndex, data);
- if (facetName === FACETS.NAME_TYPE) {
- params.query = 'contributorNameTypeId=*';
- } else if ([FACETS.CONTRIBUTORS_SHARED, FACETS.CONTRIBUTORS_HELD_BY].includes(facetName)) {
- params.query = 'name=*';
- } else if ([FACETS.SUBJECTS_SHARED, FACETS.SUBJECTS_HELD_BY].includes(facetName)) {
- params.query = 'value=*';
- } else if (cqlQuery
- && Object.values(browseCallNumberOptions).includes(queryIndex)
- && queryIndex !== browseCallNumberOptions.CALL_NUMBERS
- ) {
- params.query = `callNumberType="${queryIndex}"`;
- } else if (cqlQuery && queryIndex !== browseModeOptions.CALL_NUMBERS) {
+ if (cqlQuery) {
params.query = cqlQuery;
}
@@ -174,7 +220,7 @@ function withFacets(WrappedComponent) {
try {
reset();
- const requestPath = FACETS_ENDPOINTS[facetName] || 'search/instances/facets';
+ const requestPath = this.getEndpoint(queryIndex);
await GET({ path: requestPath, params });
} catch (error) {
throw new Error(error);
diff --git a/src/withFacets.test.js b/src/withFacets.test.js
index 3fe138e1d..b8c789e99 100644
--- a/src/withFacets.test.js
+++ b/src/withFacets.test.js
@@ -9,17 +9,19 @@ import {
queryIndexes,
FACETS_CQL,
browseCallNumberOptions,
+ browseModeOptions,
} from './constants';
const WrappedComponent = ({
fetchFacets,
data = {},
properties = {},
+ isBrowseLookup,
}) => {
return (
@@ -36,12 +38,392 @@ const mutator = {
};
describe('withFacets', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
describe('when opening a contributots shared facet', () => {
- it('should make a request with correct params', () => {
+ describe('and there are no selected options in other facets', () => {
+ it('should make a request with correct request options', () => {
+ const resources = {
+ query: {
+ qindex: browseModeOptions.CONTRIBUTORS,
+ query: '',
+ },
+ };
+
+ const { getByText } = render(
+
+ );
+
+ fireEvent.click(getByText('fetchFacetsButton'));
+
+ expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
+ params: {
+ facet: `${FACETS_CQL.INSTANCES_SHARED}:6`,
+ query: '(cql.allRecords=1)',
+ },
+ path: 'search/contributors/facets',
+ }));
+ });
+ });
+
+ describe('and there is a selected option in another facet', () => {
+ it('should make a request with correct request options', () => {
+ const resources = {
+ query: {
+ qindex: browseModeOptions.CONTRIBUTORS,
+ query: '',
+ contributorsTenantId: ['college'],
+ },
+ };
+
+ const { getByText } = render(
+
+ );
+
+ fireEvent.click(getByText('fetchFacetsButton'));
+
+ expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
+ params: {
+ facet: `${FACETS_CQL.INSTANCES_SHARED}:6`,
+ query: 'instances.tenantId==("college")',
+ },
+ path: 'search/contributors/facets',
+ }));
+ });
+ });
+
+ describe('and there is a selected option in another facet and there is a value in the search box', () => {
+ it('should make a request with correct request options', () => {
+ const resources = {
+ query: {
+ qindex: browseModeOptions.CONTRIBUTORS,
+ query: 'Marc Twain',
+ contributorsTenantId: ['college'],
+ },
+ };
+
+ const { getByText } = render(
+
+ );
+
+ fireEvent.click(getByText('fetchFacetsButton'));
+
+ expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
+ params: {
+ facet: `${FACETS_CQL.INSTANCES_SHARED}:6`,
+ query: 'instances.tenantId==("college")',
+ },
+ path: 'search/contributors/facets',
+ }));
+ });
+ });
+ });
+
+ describe('when opening a subjects shared facet', () => {
+ describe('and there are no selected options in other facets', () => {
+ it('should make a request with correct request options', () => {
+ const resources = {
+ query: {
+ qindex: browseModeOptions.SUBJECTS,
+ query: '',
+ },
+ };
+
+ const { getByText } = render(
+
+ );
+
+ fireEvent.click(getByText('fetchFacetsButton'));
+
+ expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
+ params: {
+ facet: `${FACETS_CQL.INSTANCES_SHARED}:6`,
+ query: '(cql.allRecords=1)',
+ },
+ path: 'search/subjects/facets',
+ }));
+ });
+ });
+
+ describe('and there is a selected option in another facet', () => {
+ it('should make a request with correct request options', () => {
+ const resources = {
+ query: {
+ qindex: browseModeOptions.SUBJECTS,
+ query: '',
+ contributorsTenantId: ['college'],
+ },
+ };
+
+ const { getByText } = render(
+
+ );
+
+ fireEvent.click(getByText('fetchFacetsButton'));
+
+ expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
+ params: {
+ facet: `${FACETS_CQL.INSTANCES_SHARED}:6`,
+ query: 'instances.tenantId==("college")',
+ },
+ path: 'search/subjects/facets',
+ }));
+ });
+ });
+
+ describe('and there is a selected option in another facet and there is a value in the search box', () => {
+ it('should make a request with correct request options', () => {
+ const resources = {
+ query: {
+ qindex: browseModeOptions.SUBJECTS,
+ query: 'Marc Twain',
+ contributorsTenantId: ['college'],
+ },
+ };
+
+ const { getByText } = render(
+
+ );
+
+ fireEvent.click(getByText('fetchFacetsButton'));
+
+ expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
+ params: {
+ facet: `${FACETS_CQL.INSTANCES_SHARED}:6`,
+ query: 'instances.tenantId==("college")',
+ },
+ path: 'search/subjects/facets',
+ }));
+ });
+ });
+ });
+
+ describe('when opening call numbers browse shared facet', () => {
+ describe('and there are no selected options in other facets', () => {
+ it('should make a request with correct request options', () => {
+ const resources = {
+ query: {
+ qindex: browseCallNumberOptions.CALL_NUMBERS,
+ query: '',
+ },
+ };
+
+ const { getByText } = render(
+
+ );
+
+ fireEvent.click(getByText('fetchFacetsButton'));
+
+ expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
+ params: {
+ facet: `${FACETS_CQL.SHARED}:6`,
+ query: '(cql.allRecords=1)',
+ },
+ path: 'search/instances/facets',
+ }));
+ });
+ });
+
+ describe('and there is a selected option in another facet', () => {
+ it('should make a request with correct request options', () => {
+ const resources = {
+ query: {
+ qindex: browseCallNumberOptions.CALL_NUMBERS,
+ query: '',
+ contributorsTenantId: ['college'],
+ },
+ };
+
+ const { getByText } = render(
+
+ );
+
+ fireEvent.click(getByText('fetchFacetsButton'));
+
+ expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
+ params: {
+ facet: `${FACETS_CQL.SHARED}:6`,
+ query: 'instances.tenantId==("college")',
+ },
+ path: 'search/instances/facets',
+ }));
+ });
+ });
+
+ describe('and there is a selected option in another facet and there is a value in the search box', () => {
+ it('should make a request with correct request options', () => {
+ const resources = {
+ query: {
+ qindex: browseCallNumberOptions.CALL_NUMBERS,
+ query: 'Marc Twain',
+ contributorsTenantId: ['college'],
+ },
+ };
+
+ const { getByText } = render(
+
+ );
+
+ fireEvent.click(getByText('fetchFacetsButton'));
+
+ expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
+ params: {
+ facet: `${FACETS_CQL.SHARED}:6`,
+ query: 'instances.tenantId==("college")',
+ },
+ path: 'search/instances/facets',
+ }));
+ });
+ });
+ });
+
+ describe('when opening call numbers sub-type browse shared facet', () => {
+ describe('and there are no selected options in other facets', () => {
+ it('should make a request with correct request options', () => {
+ const resources = {
+ query: {
+ qindex: browseCallNumberOptions.DEWEY,
+ query: '',
+ },
+ };
+
+ const { getByText } = render(
+
+ );
+
+ fireEvent.click(getByText('fetchFacetsButton'));
+
+ expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
+ params: {
+ facet: `${FACETS_CQL.SHARED}:6`,
+ query: '(callNumberType="dewey")',
+ },
+ path: 'search/instances/facets',
+ }));
+ });
+ });
+
+ describe('and there is a selected option in another facet', () => {
+ it('should make a request with correct request options', () => {
+ const resources = {
+ query: {
+ qindex: browseCallNumberOptions.DEWEY,
+ query: '',
+ contributorsTenantId: ['college'],
+ },
+ };
+
+ const { getByText } = render(
+
+ );
+
+ fireEvent.click(getByText('fetchFacetsButton'));
+
+ expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
+ params: {
+ facet: `${FACETS_CQL.SHARED}:6`,
+ query: '(callNumberType="dewey") and instances.tenantId==("college")',
+ },
+ path: 'search/instances/facets',
+ }));
+ });
+ });
+
+ describe('and there is a selected option in another facet and there is a value in the search box', () => {
+ it('should make a request with correct request options', () => {
+ const resources = {
+ query: {
+ qindex: browseCallNumberOptions.DEWEY,
+ query: 'Marc Twain',
+ contributorsTenantId: ['college'],
+ },
+ };
+
+ const { getByText } = render(
+
+ );
+
+ fireEvent.click(getByText('fetchFacetsButton'));
+
+ expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
+ params: {
+ facet: `${FACETS_CQL.SHARED}:6`,
+ query: '(callNumberType="dewey") and instances.tenantId==("college")',
+ },
+ path: 'search/instances/facets',
+ }));
+ });
+ });
+ });
+
+ describe('when Advanced search is used', () => {
+ it('should fetch facets with the correct params', async () => {
const resources = {
query: {
- qindex: queryIndexes.CONTRIBUTOR,
- query: '',
+ qindex: queryIndexes.ADVANCED_SEARCH,
+ query: 'isbn containsAll test1 or title exactPhrase test2 or keyword startsWith test3',
},
};
@@ -49,7 +431,7 @@ describe('withFacets', () => {
);
@@ -57,27 +439,24 @@ describe('withFacets', () => {
expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
params: {
- facet: `${FACETS_CQL.INSTANCES_SHARED}:6`,
- query: 'name=*',
+ facet: 'source:6',
+ query: 'isbn="*test1*" or title=="test2" or keyword all "test3*"',
},
}));
});
});
- describe('when opening a subjects shared facet', () => {
- it('should make a request with correct params', () => {
+ describe('when user opens a facet', () => {
+ it('should fetch only 6 options for this facet', () => {
const resources = {
- query: {
- qindex: queryIndexes.SUBJECT,
- query: '',
- },
+ query: {},
};
const { getByText } = render(
);
@@ -85,27 +464,51 @@ describe('withFacets', () => {
expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
params: {
- facet: `${FACETS_CQL.INSTANCES_SHARED}:6`,
- query: 'value=*',
+ facet: `${FACETS_CQL.SHARED}:6`,
+ query: 'id = *',
},
+ path: 'search/instances/facets',
}));
});
});
- describe('when using call numbers browse', () => {
- it('should make a request with correct params', () => {
+ describe('when user clicks the "+More" button under options', () => {
+ it('should fetch all options for this facet', () => {
const resources = {
- query: {
- qindex: browseCallNumberOptions.CALL_NUMBERS,
- query: 'test',
+ query: {},
+ };
+
+ const { getByText } = render(
+
+ );
+
+ fireEvent.click(getByText('fetchFacetsButton'));
+
+ expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
+ params: {
+ facet: `${FACETS_CQL.INSTANCE_TYPE}`,
+ query: 'id = *',
},
+ path: 'search/instances/facets',
+ }));
+ });
+ });
+
+ describe('when user places the cursor in the facet`s input field', () => {
+ it('should fetch all options for this facet', () => {
+ const resources = {
+ query: {},
};
const { getByText } = render(
);
@@ -113,27 +516,33 @@ describe('withFacets', () => {
expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
params: {
- facet: `${FACETS_CQL.SHARED}:6`,
+ facet: `${FACETS_CQL.INSTANCE_TYPE}`,
query: 'id = *',
},
+ path: 'search/instances/facets',
}));
});
});
- describe('when using call numbers sub-type browse', () => {
- it('should make a request with correct params', () => {
+ describe('when several facets are open and user enters a value in the search box', () => {
+ it('should fetch options for all open facets', () => {
const resources = {
query: {
- qindex: browseCallNumberOptions.DEWEY,
- query: 'test',
+ qindex: 'title',
+ query: 'Marc',
},
};
+ const properties = {
+ accordions: { resource: true, format: true },
+ accordionsData: {},
+ };
+
const { getByText } = render(
);
@@ -141,19 +550,27 @@ describe('withFacets', () => {
expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
params: {
- facet: `${FACETS_CQL.SHARED}:6`,
- query: 'callNumberType="dewey"',
+ facet: `${FACETS_CQL.INSTANCE_TYPE}:6,${FACETS_CQL.INSTANCE_FORMAT}:6`,
+ query: 'title all "Marc"',
},
+ path: 'search/instances/facets',
}));
});
});
- describe('when Advanced search is used', () => {
- it('should fetch facets with the correct params', async () => {
+ describe('when several facets are open and user selects an option of any facet', () => {
+ it('should fetch options for all open facets', () => {
const resources = {
query: {
- qindex: queryIndexes.ADVANCED_SEARCH,
- query: 'isbn containsAll test1 or title exactPhrase test2 or keyword startsWith test3',
+ query: '',
+ filters: 'resource.6312d172-f0cf-40f6-b27d-9fa8feaf332f',
+ },
+ };
+
+ const properties = {
+ accordions: { resource: true, format: true },
+ accordionsData: {
+ resource: { isSelected: true },
},
};
@@ -161,7 +578,7 @@ describe('withFacets', () => {
);
@@ -169,10 +586,49 @@ describe('withFacets', () => {
expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
params: {
- facet: 'source:6',
- query: 'isbn="*test1*" or title==/string "test2" or keyword all "test3*"',
+ facet: `${FACETS_CQL.INSTANCE_TYPE},${FACETS_CQL.INSTANCE_FORMAT}:6`,
+ query: 'instanceTypeId=="6312d172-f0cf-40f6-b27d-9fa8feaf332f"',
},
+ path: 'search/instances/facets',
}));
});
});
+
+ describe('when several facets are open and user selects an option of one facet', () => {
+ describe('and for another one the "+More" button is clicked', () => {
+ it('should fetch all options for the facet with selected option and for the facet with +More clicked', () => {
+ const resources = {
+ query: {
+ query: '',
+ filters: 'format.8d511d33-5e85-4c5d-9bce-6e3c9cd0c324',
+ },
+ };
+
+ const properties = {
+ accordions: { shared: true, resource: true, format: true },
+ accordionsData: {
+ resource: { isOnMoreClicked: true },
+ format: { isSelected: true },
+ },
+ };
+
+ const { getByText } = render(
+
+ );
+
+ fireEvent.click(getByText('fetchFacetsButton'));
+
+ expect(mutator.facets.GET).toHaveBeenCalledWith(expect.objectContaining({
+ params: {
+ facet: `${FACETS_CQL.SHARED}:6,${FACETS_CQL.INSTANCE_TYPE},${FACETS_CQL.INSTANCE_FORMAT}`,
+ query: expect.anything(),
+ },
+ }));
+ });
+ });
+ });
});
diff --git a/translations/ui-inventory/ar.json b/translations/ui-inventory/ar.json
index 7965045e0..161a0e0b9 100644
--- a/translations/ui-inventory/ar.json
+++ b/translations/ui-inventory/ar.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/ber.json b/translations/ui-inventory/ber.json
index 55d6107eb..7350fadaa 100644
--- a/translations/ui-inventory/ber.json
+++ b/translations/ui-inventory/ber.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/ca.json b/translations/ui-inventory/ca.json
index 2045ca5d8..8383b2062 100644
--- a/translations/ui-inventory/ca.json
+++ b/translations/ui-inventory/ca.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/cs_CZ.json b/translations/ui-inventory/cs_CZ.json
index 60fcfc09a..7c5f19a7e 100644
--- a/translations/ui-inventory/cs_CZ.json
+++ b/translations/ui-inventory/cs_CZ.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/da.json b/translations/ui-inventory/da.json
index b49a45c57..045ab062d 100644
--- a/translations/ui-inventory/da.json
+++ b/translations/ui-inventory/da.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/de.json b/translations/ui-inventory/de.json
index f2a744f91..6c1959203 100644
--- a/translations/ui-inventory/de.json
+++ b/translations/ui-inventory/de.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/en.json b/translations/ui-inventory/en.json
index 4678d740c..afa026c97 100644
--- a/translations/ui-inventory/en.json
+++ b/translations/ui-inventory/en.json
@@ -54,6 +54,9 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
+ "unlinkLocalMarcAuthorities.modal.header": "Linked to local authorities",
+ "unlinkLocalMarcAuthorities.modal.message": "If you proceed with sharing this instance, then {linkedAuthoritiesLength} bibliographic fields linked to local authority records will retain authorized values but will become uncontrolled",
+ "unlinkLocalMarcAuthorities.modal.proceed": "Proceed",
"save": "Save",
"cancel": "Cancel",
"confirm": "Confirm",
diff --git a/translations/ui-inventory/en_GB.json b/translations/ui-inventory/en_GB.json
index 55d6107eb..7350fadaa 100644
--- a/translations/ui-inventory/en_GB.json
+++ b/translations/ui-inventory/en_GB.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/en_SE.json b/translations/ui-inventory/en_SE.json
index 55d6107eb..7350fadaa 100644
--- a/translations/ui-inventory/en_SE.json
+++ b/translations/ui-inventory/en_SE.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/en_US.json b/translations/ui-inventory/en_US.json
index 55d6107eb..7350fadaa 100644
--- a/translations/ui-inventory/en_US.json
+++ b/translations/ui-inventory/en_US.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/es.json b/translations/ui-inventory/es.json
index 9441746ac..abff5b97e 100644
--- a/translations/ui-inventory/es.json
+++ b/translations/ui-inventory/es.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/es_419.json b/translations/ui-inventory/es_419.json
index 3210353a8..a3fc24001 100644
--- a/translations/ui-inventory/es_419.json
+++ b/translations/ui-inventory/es_419.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Compartir",
"shareLocalInstance.toast.unsuccessful": "La instancia local {instanceTitle} no se compartió",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/es_ES.json b/translations/ui-inventory/es_ES.json
index 213e05c2e..42099fcb0 100644
--- a/translations/ui-inventory/es_ES.json
+++ b/translations/ui-inventory/es_ES.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/fr.json b/translations/ui-inventory/fr.json
index eeab84841..292eec37e 100644
--- a/translations/ui-inventory/fr.json
+++ b/translations/ui-inventory/fr.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/fr_FR.json b/translations/ui-inventory/fr_FR.json
index f8af0420d..02ab60902 100644
--- a/translations/ui-inventory/fr_FR.json
+++ b/translations/ui-inventory/fr_FR.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/he.json b/translations/ui-inventory/he.json
index c8c889012..32e4e2273 100644
--- a/translations/ui-inventory/he.json
+++ b/translations/ui-inventory/he.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/hi_IN.json b/translations/ui-inventory/hi_IN.json
index 55d6107eb..7350fadaa 100644
--- a/translations/ui-inventory/hi_IN.json
+++ b/translations/ui-inventory/hi_IN.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/hu.json b/translations/ui-inventory/hu.json
index 6ed0c9a9b..66785515d 100644
--- a/translations/ui-inventory/hu.json
+++ b/translations/ui-inventory/hu.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/it_IT.json b/translations/ui-inventory/it_IT.json
index c24e9c043..ebcb79611 100644
--- a/translations/ui-inventory/it_IT.json
+++ b/translations/ui-inventory/it_IT.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/ja.json b/translations/ui-inventory/ja.json
index 27bbe4214..0761df8f7 100644
--- a/translations/ui-inventory/ja.json
+++ b/translations/ui-inventory/ja.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/ko.json b/translations/ui-inventory/ko.json
index 671176c77..d396b651f 100644
--- a/translations/ui-inventory/ko.json
+++ b/translations/ui-inventory/ko.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/nb.json b/translations/ui-inventory/nb.json
index 55d6107eb..7350fadaa 100644
--- a/translations/ui-inventory/nb.json
+++ b/translations/ui-inventory/nb.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/nn.json b/translations/ui-inventory/nn.json
index 55d6107eb..7350fadaa 100644
--- a/translations/ui-inventory/nn.json
+++ b/translations/ui-inventory/nn.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/pl.json b/translations/ui-inventory/pl.json
index d79c0daf9..2c73cad99 100644
--- a/translations/ui-inventory/pl.json
+++ b/translations/ui-inventory/pl.json
@@ -652,7 +652,7 @@
"instance.successfullySaved": "The instance - HRID {hrid} has been successfully saved.",
"holdingsPaneTitle": "Holdings • {location} • {callNumber}",
"instanceRecordSubtitle": "{hrid} • Last updated: {updatedDate}",
- "instance.saveError": "Saving instance failed",
+ "instance.saveError": "Nie udał się zapis instancji",
"itemRecordWithDescriptionBW": "Item record ({materialType}, {status}, bound with)",
"acq.polNumber": "POL number",
"acq.orderStatus": "Order status",
@@ -693,7 +693,7 @@
"instance.suppressedFromDiscovery": "Suppressed from discovery",
"createMARCHoldings": "Add MARC holdings record",
"exportInProgress": "Export in progress",
- "acq.acqUnit": "Acquisition unit",
+ "acq.acqUnit": "Dział gromadzenia",
"showMoreOptions": "Show more options",
"more": "More",
"noMatchingOptions": "No matching options",
@@ -704,22 +704,22 @@
"administrativeNote": "Administrative note",
"administrativeNotes": "Administrative notes",
"browseCallNumbers": "Browse call numbers",
- "browseSubjects": "Browse subjects",
- "browse": "Browse",
- "notLoadedMessage.browseCall": "Browse for results entering a query or choosing a filter.",
- "title.browseCall": "Browse inventory",
- "title.subTitle.browseCall": "Enter search criteria to start browsing",
+ "browseSubjects": "Przeglądaj hasła przedmiotowe",
+ "browse": "Przeglądaj",
+ "notLoadedMessage.browseCall": "Przeglądaj wyniki, wprowadzając zapytanie lub wybierając filtr",
+ "title.browseCall": "Przeglądaj inwentarz",
+ "title.subTitle.browseCall": "Wprowadź kryteria wyszukiwania, aby zacząć przeglądanie",
"instances.columns.callNumber": "Call number",
"instances.columns.numberOfTitles": "Number of titles",
"viewAndReorderRequestsQueue": "View requests & reorder ({number})",
- "browseCallNumbers.missedMatch": "would be here",
- "search.allFields": "All",
+ "browseCallNumbers.missedMatch": "powinno być tutaj",
+ "search.allFields": "Wszystkie",
"acq.dateOpened": "Date opened",
"moveItems.selectHolding": "Select holdings",
- "browseContributors": "Browse contributors",
+ "browseContributors": "Przeglądaj twórców",
"newOrder": "New order",
"permission.instance.createOrder": "Inventory: Create order from instance",
- "search.oclc": "OCLC number, normalized",
+ "search.oclc": "Numer OCLC",
"newOrder.modal.create": "Create",
"newOrder.modal.label": "Create order",
"newOrder.modal.message": "Selecting an existing order before clicking \"Create\", will add a new order line to the selected order for this title. Leaving the order number field blank and clicking \"Create\" will allow you to create a new purchase order and purchase order line for this title.",
@@ -728,30 +728,30 @@
"instances.columns.contributor": "Contributor",
"instances.columns.contributorType": "Type",
"instances.columns.relatorTerm": "Relator term",
- "search.holdings.uuid": "Holdings UUID",
- "search.item.uuid": "Item UUID",
+ "search.holdings.uuid": "Identyfikator UUID zasobów",
+ "search.item.uuid": "Identyfikator UUID egzemplarza",
"filters.nameType": "Name type",
"instanceStatusShort": "Instance status",
"effectiveCallNumberShelving": "Effective call number (item), shelving order",
- "browseContributors.results.error": "Error returning results. Please retry or revise your search.",
+ "browseContributors.results.error": "Błąd podczas zwracania wyników. Ponów zapytanie lub zmień wyszukiwanie",
"remote.warning.common.items": "Item has been successfully moved in FOLIO. To complete removing this item from remote storage, run an exception report or communicate this directly to your remote storage location.",
- "search": "Search",
+ "search": "Szukaj",
"linkedToMarcAuthority": "Linked to MARC authority",
"browse.callNumbers": "Call numbers",
- "browse.contributors": "Contributors",
- "browse.searchableIndexesPlaceholder": "Select a browse option",
- "browse.subjects": "Subjects",
+ "browse.contributors": "Twórcy",
+ "browse.searchableIndexesPlaceholder": "Wybierz opcje przeglądania",
+ "browse.subjects": "Hasło przedmiotowe",
"noItemDeleteModal.awaitingPickupMessage": "Item HRID {hrid} with barcode {barcode} is checked out and can not be deleted until checked in again, and item status is 'Available'",
"noItemDeleteModal.statusMessage": "Item HRID {hrid} with barcode {barcode} has the item status {status} and cannot be deleted until the item status is set to 'Available'.",
- "search.instanceNotes": "Instance notes (all)",
- "search.holdingsNotes": "Holdings notes (all)",
- "search.itemNotes": "Item notes (all)",
- "search.instanceAdministrativeNotes": "Instance administrative notes",
- "search.holdingsAdministrativeNotes": "Holdings administrative notes",
- "search.itemAdministrativeNotes": "Item administrative notes",
- "inactive": "Inactive",
+ "search.instanceNotes": "Uwagi instancji (wszystkie)",
+ "search.holdingsNotes": "Uwagi zasobów (wszystkie)",
+ "search.itemNotes": "Uwagi egzemplarza (wszystkie)",
+ "search.instanceAdministrativeNotes": "Uwagi administracyjne instancji",
+ "search.holdingsAdministrativeNotes": "Uwagi administracyjne zasobów",
+ "search.itemAdministrativeNotes": "Uwagi administracyjne egzemplarza",
+ "inactive": "Nieaktywny",
"inactive.paneTitle": "Inactive {location}",
- "search.itemCirculationNotes": "Circulation notes",
+ "search.itemCirculationNotes": "Uwagi udostępniania",
"inactive.gridCell": "Inactive {location}",
"authorityId": "Authority UUID",
"appMenu.inventorySearch": "Inventory app search",
@@ -805,14 +805,14 @@
"item.status.unavailable.lowercase": "unavailable",
"item.status.unknown.lowercase": "unknown",
"item.status.withdrawn.lowercase": "withdrawn",
- "browse.callNumbersAll": "Call numbers (all)",
- "browse.dewey": "Dewey Decimal classification",
- "browse.libOfCongress": "Library of Congress classification",
+ "browse.callNumbersAll": "Sygnatury (wszystkie)",
+ "browse.dewey": "Klasyfikacja Dziesiętna Deweya",
+ "browse.libOfCongress": "Klasyfikacja Biblioteki Kongresu",
"browse.local": "Local",
- "browse.natLibOfMed": "National Library of Medicine classification",
+ "browse.natLibOfMed": "Klasyfikacja National Library of Medicine",
"browse.other": "Other scheme",
"browse.superintendent": "Superintendent of Documents classification",
- "advancedSearch": "Advanced search",
+ "advancedSearch": "Wyszukiwanie zaawansowane",
"filters.shared": "Shared",
"consortia.instanceRecordTitle": "{isShared, select, false {Local} true {Shared} other {}} instance • {title} {publisherAndDate}",
"editInstance.consortia.title": "Edit {isShared, select, false {local} true {shared} other {}} instance • {title}",
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/pt_BR.json b/translations/ui-inventory/pt_BR.json
index e21108f36..8c3b0eefd 100644
--- a/translations/ui-inventory/pt_BR.json
+++ b/translations/ui-inventory/pt_BR.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Compartilhar",
"shareLocalInstance.toast.unsuccessful": "A instância local {instanceTitle} não foi compartilhada",
"shareLocalInstance.toast.successful": "A instância local {instanceTitle} foi compartilhada com sucesso",
- "filters.tenantId": "Realizada por"
+ "filters.tenantId": "Realizada por",
+ "permission.consortia.inventory.share.local.instance": "Inventário: Compartilhar a instância local com o consórcio",
+ "consortialHoldings": "Participações em consórcios"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/pt_PT.json b/translations/ui-inventory/pt_PT.json
index e62bd2284..c6cf829fd 100644
--- a/translations/ui-inventory/pt_PT.json
+++ b/translations/ui-inventory/pt_PT.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/ru.json b/translations/ui-inventory/ru.json
index 301f8e044..68ae312ae 100644
--- a/translations/ui-inventory/ru.json
+++ b/translations/ui-inventory/ru.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/sv.json b/translations/ui-inventory/sv.json
index 55d6107eb..7350fadaa 100644
--- a/translations/ui-inventory/sv.json
+++ b/translations/ui-inventory/sv.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/ur.json b/translations/ui-inventory/ur.json
index 4b5d7e496..6de9761fb 100644
--- a/translations/ui-inventory/ur.json
+++ b/translations/ui-inventory/ur.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/zh_CN.json b/translations/ui-inventory/zh_CN.json
index 69ce11649..9d71eaea0 100644
--- a/translations/ui-inventory/zh_CN.json
+++ b/translations/ui-inventory/zh_CN.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "共享",
"shareLocalInstance.toast.unsuccessful": "本地实例 {instanceTitle} 未共享",
"shareLocalInstance.toast.successful": "本地实例 {instanceTitle} 已成功共享",
- "filters.tenantId": "持有者"
+ "filters.tenantId": "持有者",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file
diff --git a/translations/ui-inventory/zh_TW.json b/translations/ui-inventory/zh_TW.json
index 55ecb0e8c..84fa6f650 100644
--- a/translations/ui-inventory/zh_TW.json
+++ b/translations/ui-inventory/zh_TW.json
@@ -827,5 +827,7 @@
"shareLocalInstance.modal.confirmButton": "Share",
"shareLocalInstance.toast.unsuccessful": "Local instance {instanceTitle} was not shared",
"shareLocalInstance.toast.successful": "Local instance {instanceTitle} has been successfully shared",
- "filters.tenantId": "Held by"
+ "filters.tenantId": "Held by",
+ "permission.consortia.inventory.share.local.instance": "Inventory: Share local instance with consortium",
+ "consortialHoldings": "Consortial holdings"
}
\ No newline at end of file