From ae4ab68caa23f80156233b990eabf032b3fe39af Mon Sep 17 00:00:00 2001 From: Yury Saukou Date: Tue, 10 Oct 2023 23:23:13 +0400 Subject: [PATCH 1/3] UIOR-1159 Use a provided tenantId when loading an instance in a PO line form --- CHANGELOG.md | 1 + src/common/constants/constants.js | 1 + src/common/hooks/index.js | 1 + src/common/hooks/useInstance/useInstance.js | 20 ++++++--- src/common/hooks/useTenantKy/index.js | 1 + src/common/hooks/useTenantKy/useTenantKy.js | 19 +++++++++ .../hooks/useTenantKy/useTenantKy.test.js | 41 +++++++++++++++++++ src/components/LayerCollection/LayerPOLine.js | 2 +- 8 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 src/common/hooks/useTenantKy/index.js create mode 100644 src/common/hooks/useTenantKy/useTenantKy.js create mode 100644 src/common/hooks/useTenantKy/useTenantKy.test.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 403645de5..ddaab9b2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ * When order line contains bad product IDs - the save & close does not work. Refs UIOR-1141. * Upgrade `ui-plugin-find-po-line` and `ui-plugin-find-organization` plugins to `5` version. Refs UIOR-1154. * POL - Display only active account numbers in dropdown list. Refs UIOR-1142. +* Use a provided `tenantId` when loading an instance in a PO line form. Refs UIOR-1159. ## [4.0.2](https://github.com/folio-org/ui-orders/tree/v4.0.2) (2023-03-17) [Full Changelog](https://github.com/folio-org/ui-orders/compare/v4.0.1...v4.0.2) diff --git a/src/common/constants/constants.js b/src/common/constants/constants.js index ff85c96d0..7353995bd 100644 --- a/src/common/constants/constants.js +++ b/src/common/constants/constants.js @@ -45,3 +45,4 @@ export const UNOPEN_ORDER_ABANDONED_HOLDINGS_TYPES = { }; export const FIELD_ARRAY_ITEM_IDENTIFIER_KEY = '__key__'; +export const OKAPI_TENANT_HEADER = 'X-Okapi-Tenant'; diff --git a/src/common/hooks/index.js b/src/common/hooks/index.js index a4b5fd0d7..e6b4308be 100644 --- a/src/common/hooks/index.js +++ b/src/common/hooks/index.js @@ -15,5 +15,6 @@ export * from './useOrderLinesAbandonedHoldingsCheck'; export * from './useOrderTemplate'; export * from './usePOLineRelatedItems'; export * from './useReexport'; +export * from './useTenantKy'; export * from './useTitleMutation'; export * from './useVendor'; diff --git a/src/common/hooks/useInstance/useInstance.js b/src/common/hooks/useInstance/useInstance.js index d4f2228cb..455a4ffc5 100644 --- a/src/common/hooks/useInstance/useInstance.js +++ b/src/common/hooks/useInstance/useInstance.js @@ -1,13 +1,23 @@ import { useQuery } from 'react-query'; -import { useOkapiKy, useNamespace } from '@folio/stripes/core'; +import { useNamespace } from '@folio/stripes/core'; -export const useInstance = (instanceId) => { - const ky = useOkapiKy(); +import { useTenantKy } from '../useTenantKy'; + +const DEFAULT_DATA = {}; +const DEFAULT_OPTIONS = {}; + +export const useInstance = (instanceId, options = DEFAULT_OPTIONS) => { + const { tenantId } = options; + + const ky = useTenantKy({ tenantId }); const [namespace] = useNamespace({ key: 'instance' }); - const { isLoading, data: instance = {} } = useQuery( - [namespace, instanceId], + const { + isLoading, + data: instance = DEFAULT_DATA, + } = useQuery( + [namespace, instanceId, tenantId], () => ky.get(`inventory/instances/${instanceId}`).json(), { enabled: Boolean(instanceId) }, ); diff --git a/src/common/hooks/useTenantKy/index.js b/src/common/hooks/useTenantKy/index.js new file mode 100644 index 000000000..70fc58fa3 --- /dev/null +++ b/src/common/hooks/useTenantKy/index.js @@ -0,0 +1 @@ +export { useTenantKy } from './useTenantKy'; diff --git a/src/common/hooks/useTenantKy/useTenantKy.js b/src/common/hooks/useTenantKy/useTenantKy.js new file mode 100644 index 000000000..d12c9679e --- /dev/null +++ b/src/common/hooks/useTenantKy/useTenantKy.js @@ -0,0 +1,19 @@ +import { useOkapiKy } from '@folio/stripes/core'; + +import { OKAPI_TENANT_HEADER } from '../../constants'; + +export const useTenantKy = ({ tenantId } = {}) => { + const ky = useOkapiKy(); + + return tenantId + ? ky.extend({ + hooks: { + beforeRequest: [ + request => { + request.headers.set(OKAPI_TENANT_HEADER, tenantId); + }, + ], + }, + }) + : ky; +}; diff --git a/src/common/hooks/useTenantKy/useTenantKy.test.js b/src/common/hooks/useTenantKy/useTenantKy.test.js new file mode 100644 index 000000000..5541db2fc --- /dev/null +++ b/src/common/hooks/useTenantKy/useTenantKy.test.js @@ -0,0 +1,41 @@ +import { renderHook } from '@folio/jest-config-stripes/testing-library/react'; +import { useOkapiKy } from '@folio/stripes/core'; + +import { OKAPI_TENANT_HEADER } from '../../constants'; +import { useTenantKy } from './useTenantKy'; + +const reqMock = { + headers: { + set: jest.fn(), + }, +}; +const kyMock = { + extend: jest.fn(({ hooks: { beforeRequest } }) => { + beforeRequest[0](reqMock); + + return kyMock; + }), +}; + +describe('useTenantKy', () => { + beforeEach(() => { + reqMock.headers.set.mockClear(); + kyMock.extend.mockClear(); + useOkapiKy.mockClear().mockReturnValue(kyMock); + }); + + it('should set provided okapi tenant header and return \'ky\' client', async () => { + const tenantId = 'college'; + const { result } = renderHook(() => useTenantKy({ tenantId })); + + expect(result.current).toBe(kyMock); + expect(reqMock.headers.set).toHaveBeenCalledWith(OKAPI_TENANT_HEADER, tenantId); + }); + + it('should use current tenant in the headers if there is no provided tenant ID', async () => { + const { result } = renderHook(() => useTenantKy()); + + expect(result.current).toBe(kyMock); + expect(reqMock.headers.set).not.toHaveBeenCalled(); + }); +}); diff --git a/src/components/LayerCollection/LayerPOLine.js b/src/components/LayerCollection/LayerPOLine.js index 827ca7ca6..637f68403 100644 --- a/src/components/LayerCollection/LayerPOLine.js +++ b/src/components/LayerCollection/LayerPOLine.js @@ -120,7 +120,7 @@ function LayerPOLine({ const { isLoading: isLinesLimitLoading, linesLimit } = useLinesLimit(!(lineId || poLine)); const [isCreateAnotherChecked, setCreateAnotherChecked] = useState(locationState?.isCreateAnotherChecked); const { isFetching: isConfigsFetching, integrationConfigs } = useIntegrationConfigs({ organizationId: vendor?.id }); - const { instance, isLoading: isInstanceLoading } = useInstance(locationState?.instanceId); + const { instance, isLoading: isInstanceLoading } = useInstance(locationState?.instanceId, { tenantId: locationState?.instanceTenantId }); const { mutateTitle } = useTitleMutation(); // eslint-disable-next-line react-hooks/exhaustive-deps From 7e290cb3f795643bcd5ef7b84c613e5d35a5a06d Mon Sep 17 00:00:00 2001 From: Yury Saukou Date: Tue, 10 Oct 2023 23:43:14 +0400 Subject: [PATCH 2/3] fix lint error --- src/components/LayerCollection/LayerPOLine.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/LayerCollection/LayerPOLine.js b/src/components/LayerCollection/LayerPOLine.js index 637f68403..85696b747 100644 --- a/src/components/LayerCollection/LayerPOLine.js +++ b/src/components/LayerCollection/LayerPOLine.js @@ -120,7 +120,12 @@ function LayerPOLine({ const { isLoading: isLinesLimitLoading, linesLimit } = useLinesLimit(!(lineId || poLine)); const [isCreateAnotherChecked, setCreateAnotherChecked] = useState(locationState?.isCreateAnotherChecked); const { isFetching: isConfigsFetching, integrationConfigs } = useIntegrationConfigs({ organizationId: vendor?.id }); - const { instance, isLoading: isInstanceLoading } = useInstance(locationState?.instanceId, { tenantId: locationState?.instanceTenantId }); + const { instance, isLoading: isInstanceLoading } = useInstance( + locationState?.instanceId, + { + tenantId: locationState?.instanceTenantId + }, + ); const { mutateTitle } = useTitleMutation(); // eslint-disable-next-line react-hooks/exhaustive-deps From 9d8e026f5735e6a8f09487dde98221597756a1fb Mon Sep 17 00:00:00 2001 From: Yury Saukou Date: Wed, 11 Oct 2023 22:35:42 +0400 Subject: [PATCH 3/3] fix lint errors --- src/components/LayerCollection/LayerPOLine.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/LayerCollection/LayerPOLine.js b/src/components/LayerCollection/LayerPOLine.js index 85696b747..a38afe8c8 100644 --- a/src/components/LayerCollection/LayerPOLine.js +++ b/src/components/LayerCollection/LayerPOLine.js @@ -121,9 +121,9 @@ function LayerPOLine({ const [isCreateAnotherChecked, setCreateAnotherChecked] = useState(locationState?.isCreateAnotherChecked); const { isFetching: isConfigsFetching, integrationConfigs } = useIntegrationConfigs({ organizationId: vendor?.id }); const { instance, isLoading: isInstanceLoading } = useInstance( - locationState?.instanceId, + locationState?.instanceId, { - tenantId: locationState?.instanceTenantId + tenantId: locationState?.instanceTenantId, }, ); const { mutateTitle } = useTitleMutation();