Skip to content

Commit

Permalink
Merge branch 'UIIN-2793' of https://github.com/folio-org/ui-inventory
Browse files Browse the repository at this point in the history
…into UIIN-2793
  • Loading branch information
OleksandrHladchenko1 committed May 10, 2024
2 parents 4d6473c + fd32763 commit 0142a7d
Show file tree
Hide file tree
Showing 30 changed files with 241 additions and 150 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Expand Up @@ -3,7 +3,6 @@
## [11.1.0] (IN PROGRESS)

* Remove unused code related to auto-open record detail view. Refs UIIN-2819.
* Replace `all` with the `=` operator to get correct results when using the `All` search option. Refs UIIN-2816.
* Keyboard shortcuts modal: Add quickMARC shortcuts to modal. Refs UIIN-2795.
* Create new settings for classification type sorting. Refs UIIN-2775.
* Add "Display to public" column to receiving history on Holdings. Refs UIIN-2826.
Expand All @@ -16,6 +15,13 @@
* Jest/RTL: Cover InstancePlugin component with unit tests. Refs UIIN-2668.
* Jest/RTL: Cover ImportRecord component with unit test. Refs UIIN-2667.
* Jest/RTL: Cover MoveHoldingContext component with unit tests. Refs UIIN-2664.
* Use consolidated locations endpoint to fetch all locations when in central tenant context. Refs UIIN-2811.
* Change label of eye-readable call number search option in holdings/items. Refs UIIN-2797.

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

* Replace `all` with the `=` operator to get correct results when using the `All` search option. Refs UIIN-2816.

## [11.0.3](https://github.com/folio-org/ui-inventory/tree/v11.0.3) (2024-04-26)
[Full Changelog](https://github.com/folio-org/ui-inventory/compare/v11.0.2...v11.0.3)
Expand Down
9 changes: 5 additions & 4 deletions package.json
@@ -1,6 +1,6 @@
{
"name": "@folio/inventory",
"version": "11.0.3",
"version": "11.0.4",
"description": "Inventory manager",
"repository": "folio-org/ui-inventory",
"publishConfig": {
Expand Down Expand Up @@ -569,7 +569,8 @@
"browse.subjects.instances.collection.get",
"browse.classification-numbers.instances.collection.get",
"perms.users.get",
"inventory-storage.bound-with-parts.collection.get"
"inventory-storage.bound-with-parts.collection.get",
"consortium-search.locations.collection.get"
],
"visible": true
},
Expand Down Expand Up @@ -889,7 +890,7 @@
"@babel/preset-react": "^7.9.0",
"@folio/eslint-config-stripes": "^7.0.0",
"@folio/jest-config-stripes": "^2.0.0",
"@folio/stripes": "^9.1.0",
"@folio/stripes": "^9.1.2",
"@folio/stripes-cli": "^3.1.0",
"@folio/stripes-components": "^12.1.2",
"@folio/stripes-connect": "^9.1.0",
Expand Down Expand Up @@ -936,7 +937,7 @@
"use-session-storage-state": "^18.2.0"
},
"peerDependencies": {
"@folio/stripes": "^9.1.0",
"@folio/stripes": "^9.1.2",
"@folio/stripes-marc-components": "^1.0.1",
"react": "^18.2.0",
"react-intl": "^6.4.4",
Expand Down
22 changes: 18 additions & 4 deletions src/hooks/useLocationsForTenants/useLocationsForTenants.js
@@ -1,9 +1,13 @@
import { useQueries } from 'react-query';
import {
useQueries,
useQuery,
} from 'react-query';

import {
useNamespace,
useOkapiKy,
useStripes,
checkIfUserInCentralTenant,
} from '@folio/stripes/core';

import { isUserInConsortiumMode } from '../../utils';
Expand All @@ -18,9 +22,11 @@ const useLocationsForTenants = ({ tenantIds = [] }) => {
const stripes = useStripes();
const ky = useOkapiKy();

const isUserInCentralTenant = checkIfUserInCentralTenant(stripes);

const queries = useQueries(tenantIds.map(tenantId => {
return {
enabled: Boolean(tenantIds.length && isUserInConsortiumMode(stripes)),
enabled: Boolean(tenantIds.length && isUserInConsortiumMode(stripes) && !isUserInCentralTenant),
queryKey: [namespace, 'locations', tenantId],
queryFn: () => ky.get('locations', {
searchParams: {
Expand All @@ -38,10 +44,18 @@ const useLocationsForTenants = ({ tenantIds = [] }) => {
};
}));

const locationsFromAllTenants = queries.map(({ data }) => data?.locations).filter(Boolean).flat();
const { data: consolidatedLocations } = useQuery({
queryKey: [namespace, 'consolidatedLocations'],
queryFn: () => ky.get('search/consortium/locations').json(),
enabled: Boolean(isUserInConsortiumMode(stripes) && isUserInCentralTenant),
});

const locationsFromAllTenants = isUserInCentralTenant
? consolidatedLocations?.locations
: queries.map(({ data }) => data?.locations).filter(Boolean).flat();

return {
data: locationsFromAllTenants,
data: locationsFromAllTenants || [],
isLoading: queries.some(({ isFetching }) => isFetching),
};
};
Expand Down
65 changes: 53 additions & 12 deletions src/hooks/useLocationsForTenants/useLocationsForTenants.test.js
Expand Up @@ -3,7 +3,10 @@ import {
QueryClientProvider,
} from 'react-query';

import { useOkapiKy } from '@folio/stripes/core';
import {
useOkapiKy,
checkIfUserInCentralTenant,
} from '@folio/stripes/core';

import {
renderHook,
Expand Down Expand Up @@ -37,22 +40,60 @@ describe('useLocationsForTenants', () => {

const tenantIds = ['cs00000int', 'cs00000int_0002'];

it('should fetch locations of all tenants', async () => {
const { result } = renderHook(() => useLocationsForTenants({ tenantIds }), { wrapper });
describe('when user is in a member tenant', () => {
it('should fetch locations of all tenants via multiple requests', async () => {
const { result } = renderHook(() => useLocationsForTenants({ tenantIds }), { wrapper });

await act(() => !result.current.isLoading);

expect(mockGet.mock.calls[0][0]).toBe('locations');
expect(mockGet.mock.calls[1][0]).toBe('locations');
expect(result.current.data).toEqual([
{ id: 'location-id' },
{ id: 'location-id' },
]);
});

it('should not call consolidated locations endpoint', async () => {
const { result } = renderHook(() => useLocationsForTenants({ tenantIds }), { wrapper });

await act(() => !result.current.isLoading);
await act(() => !result.current.isLoading);

expect(result.current.data).toEqual([
{ id: 'location-id' },
{ id: 'location-id' },
]);
expect(mockGet).not.toHaveBeenCalledWith('search/consortium/locations');
});

describe('when tenantIds is empty', () => {
it('should not make a request', () => {
renderHook(() => useLocationsForTenants({ tenantIds: [] }), { wrapper });

expect(mockGet).not.toHaveBeenCalled();
});
});
});

describe('when tenantIds is empty', () => {
it('should not make a request', () => {
renderHook(() => useLocationsForTenants({ tenantIds: [] }), { wrapper });
describe('when user is in a central tenant', () => {
beforeEach(() => {
checkIfUserInCentralTenant.mockClear().mockReturnValue(true);
});

it('should fetch locations of all tenants via consolidated endpoint', async () => {
const { result } = renderHook(() => useLocationsForTenants({ tenantIds }), { wrapper });

await act(() => !result.current.isLoading);

expect(mockGet).toHaveBeenCalledWith('search/consortium/locations');

expect(result.current.data).toEqual([
{ id: 'location-id' },
]);
});

it('should not call multiple locations endpoints', async () => {
const { result } = renderHook(() => useLocationsForTenants({ tenantIds }), { wrapper });

await act(() => !result.current.isLoading);

expect(mockGet).not.toHaveBeenCalled();
expect(mockGet).not.toHaveBeenCalledWith('locations');
});
});
});
29 changes: 29 additions & 0 deletions src/providers/DataProvider.js
Expand Up @@ -47,6 +47,10 @@ const DataProvider = ({
const { data: locationsOfAllTenants } = useLocationsForTenants({ tenantIds });

useEffect(() => {
if (isUserInConsortiumMode(stripes)) {
return;
}

mutator.locations.GET({ tenant: stripes.okapi.tenant });
}, [stripes.okapi.tenant]);

Expand Down Expand Up @@ -134,42 +138,49 @@ DataProvider.manifest = {
records: 'identifierTypes',
path: 'identifier-types?limit=1000&query=cql.allRecords=1 sortby name',
resourceShouldRefresh: true,
throwErrors: false,
},
contributorTypes: {
type: 'okapi',
records: 'contributorTypes',
path: 'contributor-types?limit=400&query=cql.allRecords=1 sortby name',
resourceShouldRefresh: true,
throwErrors: false,
},
contributorNameTypes: {
type: 'okapi',
records: 'contributorNameTypes',
path: 'contributor-name-types?limit=1000&query=cql.allRecords=1 sortby ordering',
resourceShouldRefresh: true,
throwErrors: false,
},
instanceFormats: {
type: 'okapi',
records: 'instanceFormats',
path: 'instance-formats?limit=1000&query=cql.allRecords=1 sortby name',
resourceShouldRefresh: true,
throwErrors: false,
},
instanceTypes: {
type: 'okapi',
records: 'instanceTypes',
path: 'instance-types?limit=1000&query=cql.allRecords=1 sortby name',
resourceShouldRefresh: true,
throwErrors: false,
},
classificationTypes: {
type: 'okapi',
records: 'classificationTypes',
path: 'classification-types?limit=1000&query=cql.allRecords=1 sortby name',
resourceShouldRefresh: true,
throwErrors: false,
},
alternativeTitleTypes: {
type: 'okapi',
records: 'alternativeTitleTypes',
path: 'alternative-title-types?limit=1000&query=cql.allRecords=1 sortby name',
resourceShouldRefresh: true,
throwErrors: false,
},
locations: {
type: 'okapi',
Expand All @@ -181,24 +192,28 @@ DataProvider.manifest = {
},
accumulate: true,
resourceShouldRefresh: true,
throwErrors: false,
},
instanceRelationshipTypes: {
type: 'okapi',
records: 'instanceRelationshipTypes',
path: 'instance-relationship-types?limit=1000&query=cql.allRecords=1 sortby name',
resourceShouldRefresh: true,
throwErrors: false,
},
instanceStatuses: {
type: 'okapi',
records: 'instanceStatuses',
path: 'instance-statuses?limit=1000&query=cql.allRecords=1 sortby name',
resourceShouldRefresh: true,
throwErrors: false,
},
modesOfIssuance: {
type: 'okapi',
records: 'issuanceModes',
path: 'modes-of-issuance?limit=1000&query=cql.allRecords=1 sortby name',
resourceShouldRefresh: true,
throwErrors: false,
},
instanceNoteTypes: {
type: 'okapi',
Expand All @@ -209,48 +224,56 @@ DataProvider.manifest = {
},
records: 'instanceNoteTypes',
resourceShouldRefresh: true,
throwErrors: false,
},
electronicAccessRelationships: {
type: 'okapi',
records: 'electronicAccessRelationships',
path: 'electronic-access-relationships?limit=1000&query=cql.allRecords=1 sortby name',
resourceShouldRefresh: true,
throwErrors: false,
},
statisticalCodeTypes: {
type: 'okapi',
records: 'statisticalCodeTypes',
path: 'statistical-code-types?limit=1000&query=cql.allRecords=1 sortby name',
resourceShouldRefresh: true,
throwErrors: false,
},
statisticalCodes: {
type: 'okapi',
records: 'statisticalCodes',
path: 'statistical-codes?limit=2000&query=cql.allRecords=1 sortby name',
resourceShouldRefresh: true,
throwErrors: false,
},
illPolicies: {
type: 'okapi',
path: 'ill-policies?limit=1000&query=cql.allRecords=1 sortby name',
records: 'illPolicies',
resourceShouldRefresh: true,
throwErrors: false,
},
holdingsTypes: {
type: 'okapi',
path: 'holdings-types?limit=1000&query=cql.allRecords=1 sortby name',
records: 'holdingsTypes',
resourceShouldRefresh: true,
throwErrors: false,
},
callNumberTypes: {
type: 'okapi',
path: 'call-number-types?limit=1000&query=cql.allRecords=1 sortby name',
records: 'callNumberTypes',
resourceShouldRefresh: true,
throwErrors: false,
},
holdingsNoteTypes: {
type: 'okapi',
path: 'holdings-note-types?limit=1000&query=cql.allRecords=1 sortby name',
records: 'holdingsNoteTypes',
resourceShouldRefresh: true,
throwErrors: false,
},
itemNoteTypes: {
type: 'okapi',
Expand All @@ -261,18 +284,21 @@ DataProvider.manifest = {
},
records: 'itemNoteTypes',
resourceShouldRefresh: true,
throwErrors: false,
},
itemDamagedStatuses: {
type: 'okapi',
path: 'item-damaged-statuses?limit=1000&query=cql.allRecords=1 sortby name',
records: 'itemDamageStatuses',
resourceShouldRefresh: true,
throwErrors: false,
},
natureOfContentTerms: {
type: 'okapi',
path: 'nature-of-content-terms?limit=1000&query=cql.allRecords=1 sortby name',
records: 'natureOfContentTerms',
resourceShouldRefresh: true,
throwErrors: false,
},
materialTypes: {
type: 'okapi',
Expand All @@ -283,6 +309,7 @@ DataProvider.manifest = {
},
records: 'mtypes',
resourceShouldRefresh: true,
throwErrors: false,
},
loanTypes: {
type: 'okapi',
Expand All @@ -293,6 +320,7 @@ DataProvider.manifest = {
},
records: 'loantypes',
resourceShouldRefresh: true,
throwErrors: false,
},
tags: {
path: 'tags?limit=10000', // the same as Tags component in stripes-smart-components
Expand All @@ -310,6 +338,7 @@ DataProvider.manifest = {
},
records: 'holdingsRecordsSources',
resourceShouldRefresh: true,
throwErrors: false,
}
};

Expand Down
4 changes: 2 additions & 2 deletions translations/ui-inventory/ber.json
Expand Up @@ -465,8 +465,8 @@
"reports.inTransitItem.copyNumber": "Copy number",
"settings.goBack": "Go back to inventory settings",
"item.status.awaitingDelivery": "Awaiting delivery",
"callNumberEyeReadable": "Call number, eye readable",
"itemEffectiveCallNumberEyeReadable": "Effective call number (item), eye readable",
"callNumberEyeReadable": "Call number, not normalized",
"itemEffectiveCallNumberEyeReadable": "Effective call number (item), not normalized",
"notAvailable": "N/A",
"findInstancePluginNotFound": "find-instance plugin not found",
"precedingField.title": "Title",
Expand Down

0 comments on commit 0142a7d

Please sign in to comment.