From 201d74a576833bbb0a650a8e638e29f474356a7e Mon Sep 17 00:00:00 2001 From: Denys Bohdan Date: Thu, 7 Dec 2023 10:19:51 +0100 Subject: [PATCH] UIQM-588 Use Authority search to get Authority linked records count. (#625) * UIQM-588 Use Authority search to get Authority linked records count. * UIQM-588 Updated tests * UIQM-588 Added search interface * Update CHANGELOG.md --- CHANGELOG.md | 4 +++ package.json | 3 +- .../QuickMarcEditorContainer.js | 14 +-------- .../QuickMarcEditorContainer.test.js | 8 +---- .../useAuthorityLinksCount.js | 30 ++++++++++++++----- .../useAuthorityLinksCount.test.js | 29 ++++++++++-------- 6 files changed, 46 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18dcad32..ca3c6f81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change history for ui-quick-marc +## [7.0.5] (IN PROGRESS) + +* [UIQM-588](https://issues.folio.org/browse/UIQM-588) Use Authority search to get Authority linked records count. + ## [7.0.4](https://github.com/folio-org/ui-quick-marc/tree/v7.0.4) (2023-11-09) * [UIQM-582](https://issues.folio.org/browse/UIQM-582) Show correct message if record not found. diff --git a/package.json b/package.json index 1608b7c9..e8174855 100644 --- a/package.json +++ b/package.json @@ -125,7 +125,8 @@ "marc-records-editor.item.get", "marc-records-editor.item.put", "inventory-storage.locations.collection.get", - "marc-specifications.item.get" + "marc-specifications.item.get", + "search.authorities.collection.get" ], "visible": true }, diff --git a/src/QuickMarcEditor/QuickMarcEditorContainer.js b/src/QuickMarcEditor/QuickMarcEditorContainer.js index ddd4927f..3e66a0ed 100644 --- a/src/QuickMarcEditor/QuickMarcEditorContainer.js +++ b/src/QuickMarcEditor/QuickMarcEditorContainer.js @@ -85,7 +85,6 @@ const QuickMarcEditorContainer = ({ const [marcRecord, setMarcRecord] = useState(); const [locations, setLocations] = useState(); const [isLoading, setIsLoading] = useState(true); - const [linksCount, setLinksCount] = useState(0); const [fixedFieldSpec, setFixedFieldSpec] = useState(); const searchParams = new URLSearchParams(location.search); @@ -96,7 +95,7 @@ const QuickMarcEditorContainer = ({ && action !== QUICK_MARC_ACTIONS.CREATE; const showCallout = useShowCallout(); - const { fetchLinksCount } = useAuthorityLinksCount(); + const { linksCount } = useAuthorityLinksCount({ id: marcType === MARC_TYPES.AUTHORITY && externalId }); const closeEditor = useCallback((id) => { if (marcType === MARC_TYPES.HOLDINGS && action !== QUICK_MARC_ACTIONS.CREATE) { @@ -144,10 +143,6 @@ const QuickMarcEditorContainer = ({ // must be with the central tenant id when user derives shared record const linkingRulesPromise = mutator.linkingRules.GET(headers); - const linksCountPromise = marcType === MARC_TYPES.AUTHORITY - ? fetchLinksCount([externalId]) - : Promise.resolve(); - const fixedFieldSpecPromise = mutator.fixedFieldSpec.GET({ path: `${MARC_SPEC_API}/${marcType}/008`, ...headers, @@ -157,7 +152,6 @@ const QuickMarcEditorContainer = ({ instancePromise, marcRecordPromise, locationsPromise, - linksCountPromise, linkingRulesPromise, fixedFieldSpecPromise, ]) @@ -165,14 +159,9 @@ const QuickMarcEditorContainer = ({ instanceResponse, marcRecordResponse, locationsResponse, - linksCountResponse, linkingRulesResponse, fixedFieldSpecResponse, ]) => { - if (marcType === MARC_TYPES.AUTHORITY) { - setLinksCount(linksCountResponse.links[0].totalLinks); - } - if (action !== QUICK_MARC_ACTIONS.CREATE) { searchParams.set('relatedRecordVersion', instanceResponse._version); @@ -208,7 +197,6 @@ const QuickMarcEditorContainer = ({ externalId, history, marcType, - fetchLinksCount, centralTenantId, token, locale, diff --git a/src/QuickMarcEditor/QuickMarcEditorContainer.test.js b/src/QuickMarcEditor/QuickMarcEditorContainer.test.js index abf60c10..3ffa30d8 100644 --- a/src/QuickMarcEditor/QuickMarcEditorContainer.test.js +++ b/src/QuickMarcEditor/QuickMarcEditorContainer.test.js @@ -24,8 +24,6 @@ import buildStripes from '../../test/jest/__mock__/stripesCore.mock'; import { useAuthorityLinksCount } from '../queries'; import { applyCentralTenantInHeaders } from './utils'; -const mockFetchLinksCount = jest.fn().mockResolvedValue(); - const match = { path: '/marc-authorities/quick-marc/edit-authority/:externalId', url: '/marc-authorities/quick-marc/edit-authority/external-id', @@ -156,10 +154,6 @@ describe('Given Quick Marc Editor Container', () => { describe('when the marc type is authority', () => { it('should make a request to get the number of links', async () => { - useAuthorityLinksCount.mockClear().mockReturnValue({ - fetchLinksCount: mockFetchLinksCount, - }); - await act(async () => { await renderQuickMarcEditorContainer({ mutator, @@ -170,7 +164,7 @@ describe('Given Quick Marc Editor Container', () => { }); }); - expect(mockFetchLinksCount).toHaveBeenCalledWith([match.params.externalId]); + expect(useAuthorityLinksCount).toHaveBeenCalledWith({ id: match.params.externalId }); }); }); diff --git a/src/queries/useAuthorityLinksCount/useAuthorityLinksCount.js b/src/queries/useAuthorityLinksCount/useAuthorityLinksCount.js index 6dbec4fc..cba372f6 100644 --- a/src/queries/useAuthorityLinksCount/useAuthorityLinksCount.js +++ b/src/queries/useAuthorityLinksCount/useAuthorityLinksCount.js @@ -1,15 +1,29 @@ -import { useMutation } from 'react-query'; -import { useTenantKy } from '../../temp'; +import { useQuery } from 'react-query'; -const useAuthorityLinksCount = ({ tenantId } = {}) => { - const ky = useTenantKy({ tenantId }); +import { + useNamespace, + useOkapiKy, +} from '@folio/stripes/core'; - const { mutateAsync, isLoading } = useMutation({ - mutationFn: ids => ky.post('links/authorities/bulk/count', { json: { ids } }).json(), - }); +const useAuthorityLinksCount = ({ id } = {}) => { + const ky = useOkapiKy(); + const [namespace] = useNamespace(); + + const searchParams = { + query: `(id==${id} and authRefType==("Authorized"))`, // only Authorized records have links counts, so we need to get them + }; + + const { data = {}, isLoading } = useQuery( + [namespace, 'authority', id], + () => ky.get('search/authorities', { searchParams }).json(), + { + keepPreviousData: true, + enabled: Boolean(id), + }, + ); return { - fetchLinksCount: mutateAsync, + linksCount: data.authorities?.[0]?.numberOfTitles || 0, isLoading, }; }; diff --git a/src/queries/useAuthorityLinksCount/useAuthorityLinksCount.test.js b/src/queries/useAuthorityLinksCount/useAuthorityLinksCount.test.js index 541bd6db..59b066f5 100644 --- a/src/queries/useAuthorityLinksCount/useAuthorityLinksCount.test.js +++ b/src/queries/useAuthorityLinksCount/useAuthorityLinksCount.test.js @@ -4,16 +4,11 @@ import { } from 'react-query'; import { renderHook } from '@folio/jest-config-stripes/testing-library/react'; -import '../../../test/jest/__mock__'; - import { useOkapiKy } from '@folio/stripes/core'; import useAuthorityLinksCount from './useAuthorityLinksCount'; -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), - useLocation: jest.fn(), -})); +import '../../../test/jest/__mock__'; const queryClient = new QueryClient(); @@ -23,22 +18,30 @@ const wrapper = ({ children }) => ( ); -const mockPost = jest.fn().mockReturnValue({ - json: jest.fn().mockResolvedValue({ links: [] }), +const mockGet = jest.fn().mockReturnValue({ + json: jest.fn().mockResolvedValue({ authorities: [{ numberOfTitles: 2 }] }), }); describe('Given useAuthorityLinksCount', () => { beforeEach(() => { useOkapiKy.mockClear().mockReturnValue({ - post: mockPost, + get: mockGet, }); }); - it('should fetch links count', async () => { - const { result } = renderHook(() => useAuthorityLinksCount(), { wrapper }); + it('should fetch authorities', async () => { + renderHook(() => useAuthorityLinksCount({ id: 'fakeId' }), { wrapper }); + + expect(mockGet).toHaveBeenCalledWith('search/authorities', { + searchParams: { + query: '(id==fakeId and authRefType==("Authorized"))', + }, + }); + }); - await result.current.fetchLinksCount(['fakeId']); + it('should return links count', async () => { + const { result } = renderHook(() => useAuthorityLinksCount({ id: 'fakeId' }), { wrapper }); - expect(mockPost).toHaveBeenCalledWith('links/authorities/bulk/count', { json: { ids: ['fakeId'] } }); + expect(result.current.linksCount).toEqual(2); }); });