diff --git a/src/Holding/CreateHolding/CreateHolding.js b/src/Holding/CreateHolding/CreateHolding.js index e0830461e..ee29fcea3 100644 --- a/src/Holding/CreateHolding/CreateHolding.js +++ b/src/Holding/CreateHolding/CreateHolding.js @@ -10,9 +10,7 @@ import { stripesConnect, stripesShape, } from '@folio/stripes/core'; -import { - LoadingView, -} from '@folio/stripes/components'; +import { LoadingView } from '@folio/stripes/components'; import { useInstance, @@ -22,24 +20,29 @@ import HoldingsForm from '../../edit/holdings/HoldingsForm'; import { switchAffiliation } from '../../utils'; const CreateHolding = ({ + history, location, instanceId, referenceData, stripes, mutator, - tenantFrom, }) => { const callout = useCallout(); const { instance, isLoading: isInstanceLoading } = useInstance(instanceId); const sourceId = referenceData.holdingsSourcesByName?.FOLIO?.id; const goBack = useCallback(() => { - window.location.href = `/inventory/view/${instanceId}${location.search}`; + history.push({ + pathname: `/inventory/view/${instanceId}`, + search: location.search, + }); }, [location.search, instanceId]); const onCancel = useCallback(() => { - switchAffiliation(stripes.okapi, tenantFrom, goBack).then(); - }, [stripes.okapi, tenantFrom, goBack]); + const { location: { state: { tenantFrom } } } = history; + + switchAffiliation(stripes, tenantFrom, goBack).then(); + }, [stripes, goBack]); const onSubmit = useCallback((newHolding) => { return mutator.holding.POST(newHolding) @@ -94,11 +97,11 @@ CreateHolding.manifest = Object.freeze({ CreateHolding.propTypes = { location: PropTypes.object.isRequired, + history: PropTypes.object.isRequired, instanceId: PropTypes.string.isRequired, mutator: PropTypes.object.isRequired, referenceData: PropTypes.object.isRequired, stripes: stripesShape.isRequired, - tenantFrom: PropTypes.string, }; export default withRouter(stripesConnect(CreateHolding)); diff --git a/src/Instance/HoldingsList/Holding/HoldingButtonsGroup.js b/src/Instance/HoldingsList/Holding/HoldingButtonsGroup.js index 1d6f2192a..7437816cb 100644 --- a/src/Instance/HoldingsList/Holding/HoldingButtonsGroup.js +++ b/src/Instance/HoldingsList/Holding/HoldingButtonsGroup.js @@ -47,7 +47,7 @@ const HoldingButtonsGroup = ({ diff --git a/src/Item/CreateItem/CreateItem.js b/src/Item/CreateItem/CreateItem.js index b8c572d90..55f6b8fdd 100644 --- a/src/Item/CreateItem/CreateItem.js +++ b/src/Item/CreateItem/CreateItem.js @@ -3,13 +3,11 @@ import React, { useMemo, } from 'react'; import PropTypes from 'prop-types'; -import { useLocation } from 'react-router-dom'; +import { useHistory } from 'react-router-dom'; import { FormattedMessage } from 'react-intl'; import { useStripes } from '@folio/stripes/core'; -import { - LoadingView, -} from '@folio/stripes/components'; +import { LoadingView } from '@folio/stripes/components'; import { useInstanceQuery, @@ -24,10 +22,17 @@ const CreateItem = ({ referenceData, instanceId, holdingId, - tenantTo, - tenantFrom, }) => { - const location = useLocation(); + const { + push, + location: { + search, + state: { + tenantTo, + tenantFrom, + }, + }, + } = useHistory(); const { isLoading: isInstanceLoading, instance } = useInstanceQuery(instanceId, { tenantId: tenantTo }); const { isLoading: isHoldingLoading, holding } = useHolding(holdingId, { tenantId: tenantTo }); @@ -40,12 +45,15 @@ const CreateItem = ({ }), [holding.id]); const goBack = useCallback(() => { - window.location.href = `/inventory/view/${instanceId}${location.search}`; - }, [instanceId, location.search]); + push({ + pathname: `/inventory/view/${instanceId}`, + search, + }); + }, [instanceId, search]); const onCancel = useCallback(() => { - switchAffiliation(stripes.okapi, tenantFrom, goBack).then(); - }, [stripes.okapi, tenantFrom, goBack]); + switchAffiliation(stripes, tenantFrom, goBack).then(); + }, [stripes, tenantFrom]); const onSuccess = useCallback(async (response) => { const { hrid } = await response.json(); @@ -91,8 +99,6 @@ CreateItem.propTypes = { instanceId: PropTypes.string.isRequired, holdingId: PropTypes.string.isRequired, referenceData: PropTypes.object.isRequired, - tenantTo: PropTypes.string, - tenantFrom: PropTypes.string, }; export default CreateItem; diff --git a/src/Item/CreateItem/CreateItem.test.js b/src/Item/CreateItem/CreateItem.test.js index 8761679ce..f116a1b5d 100644 --- a/src/Item/CreateItem/CreateItem.test.js +++ b/src/Item/CreateItem/CreateItem.test.js @@ -1,8 +1,9 @@ import '../../../test/jest/__mock__'; -import { MemoryRouter } from 'react-router-dom'; +import { Router } from 'react-router-dom'; import { render, screen } from '@folio/jest-config-stripes/testing-library/react'; import { QueryClient, QueryClientProvider } from 'react-query'; +import { createMemoryHistory } from 'history'; import { instance } from '../../../test/fixtures/instance'; import { @@ -19,6 +20,16 @@ jest.mock('../../common/hooks', () => ({ useHolding: jest.fn().mockReturnValue({ holding: {}, isLoading: false }), })); +const history = createMemoryHistory(); +history.location = { + pathname: '/testPathName', + search: '?filters=test1', + state: { + tenantTo: 'testTenantToId', + tenantFrom: 'testTenantFromId', + } +}; + const defaultProps = { instanceId: instance.id, holdingId: 'holdingId', @@ -28,11 +39,11 @@ const defaultProps = { const queryClient = new QueryClient(); const wrapper = ({ children }) => ( - + {children} - + ); const renderCreateItem = (props = {}) => render( diff --git a/src/ViewHoldingsRecord.js b/src/ViewHoldingsRecord.js index 8192582a7..35c0bc150 100644 --- a/src/ViewHoldingsRecord.js +++ b/src/ViewHoldingsRecord.js @@ -81,7 +81,7 @@ class ViewHoldingsRecord extends React.Component { path: 'holdings-storage/holdings/:{holdingsrecordid}', resourceShouldRefresh: false, accumulate: true, - tenant: '!{tenantTo}' + tenant: '!{location.state.tenantTo}' }, items: { type: 'okapi', @@ -97,7 +97,7 @@ class ViewHoldingsRecord extends React.Component { type: 'okapi', path: 'inventory/instances/:{id}', accumulate: true, - tenant: '!{tenantTo}' + tenant: '!{location.state.tenantTo}' }, tagSettings: { type: 'okapi', @@ -198,22 +198,19 @@ class ViewHoldingsRecord extends React.Component { }); }; - goBack = () => { - const { - id, - location: { search, state: locationState }, - } = this.props; - const pathname = locationState?.backPathname ?? `/inventory/view/${id}`; - - window.location.href = `${pathname}${search}`; - } - onClose = (e) => { if (e) e.preventDefault(); - const { stripes, tenantFrom } = this.props; + const { + history, + location: { search, state: locationState }, + id, + } = this.props; - switchAffiliation(stripes.okapi, tenantFrom, this.goBack); + history.push({ + pathname: locationState?.backPathname ?? `/inventory/view/${id}`, + search, + }); } // Edit Holdings records handlers @@ -482,6 +479,7 @@ class ViewHoldingsRecord extends React.Component { referenceTables, goTo, stripes, + location: { state: { tenantFrom } }, } = this.props; const { instance } = this.state; @@ -728,7 +726,7 @@ class ViewHoldingsRecord extends React.Component { updatedDate: getDate(holdingsRecord?.metadata?.updatedDate), })} dismissible - onClose={this.onClose} + onClose={() => switchAffiliation(stripes, tenantFrom, this.onClose)} actionMenu={this.getPaneHeaderActionMenu} > @@ -1138,7 +1136,6 @@ ViewHoldingsRecord.propTypes = { query: PropTypes.object.isRequired, }), goTo: PropTypes.func.isRequired, - tenantFrom: PropTypes.string, }; export default flowRight( diff --git a/src/ViewHoldingsRecord.test.js b/src/ViewHoldingsRecord.test.js index a3292643b..5287c07bb 100644 --- a/src/ViewHoldingsRecord.test.js +++ b/src/ViewHoldingsRecord.test.js @@ -17,7 +17,6 @@ import { translationsProperties, } from '../test/jest/helpers'; -import { switchAffiliation } from './utils'; import ViewHoldingsRecord from './ViewHoldingsRecord'; jest.mock('./withLocation', () => jest.fn(c => c)); @@ -27,11 +26,6 @@ jest.mock('./common', () => ({ useTenantKy: jest.fn(), })); -jest.mock('./utils', () => ({ - ...jest.requireActual('./utils'), - switchAffiliation: jest.fn(), -})); - const spyOncollapseAllSections = jest.spyOn(require('@folio/stripes/components'), 'collapseAllSections'); const spyOnexpandAllSections = jest.spyOn(require('@folio/stripes/components'), 'expandAllSections'); @@ -87,7 +81,11 @@ const defaultProps = { }, location: { search: '/', - pathname: 'pathname' + pathname: 'pathname', + state: { + tenantTo: 'testTenantToId', + tenantFrom: 'testTenantFromId', + } }, }; @@ -118,7 +116,7 @@ describe('ViewHoldingsRecord actions', () => { it('should close view holding page', async () => { renderViewHoldingsRecord(); fireEvent.click(await screen.findByRole('button', { name: 'confirm' })); - expect(switchAffiliation).toHaveBeenCalled(); + expect(defaultProps.history.push).toHaveBeenCalled(); }); it('should translate to edit holding form page', async () => { diff --git a/src/routes/CreateHoldingRoute.js b/src/routes/CreateHoldingRoute.js index 82e8bb2fd..06ef018a0 100644 --- a/src/routes/CreateHoldingRoute.js +++ b/src/routes/CreateHoldingRoute.js @@ -2,22 +2,16 @@ import React, { useContext } from 'react'; import PropTypes from 'prop-types'; import { withRouter } from 'react-router'; -import { useStripes } from '@folio/stripes/core'; - import { CreateHolding } from '../Holding'; import { DataContext } from '../contexts'; -import { getItem } from '../storage'; const CreateHoldingRoute = ({ match }) => { - const { okapi } = useStripes(); const referenceData = useContext(DataContext); - const tenantIds = getItem('tenantIds'); return ( ); }; diff --git a/src/routes/CreateItemRoute.js b/src/routes/CreateItemRoute.js index 0583aa447..6efb904bb 100644 --- a/src/routes/CreateItemRoute.js +++ b/src/routes/CreateItemRoute.js @@ -1,25 +1,18 @@ import React, { useContext } from 'react'; import { useParams } from 'react-router-dom'; -import { useStripes } from '@folio/stripes/core'; - import { CreateItem } from '../Item'; import { DataContext } from '../contexts'; -import { getItem } from '../storage'; const CreateItemRoute = () => { - const { okapi } = useStripes(); const referenceData = useContext(DataContext); const { id, holdingId } = useParams(); - const tenantIds = getItem('tenantIds'); return ( ); }; diff --git a/src/routes/ItemRoute.js b/src/routes/ItemRoute.js index dda8db1b6..c30e17d37 100644 --- a/src/routes/ItemRoute.js +++ b/src/routes/ItemRoute.js @@ -13,11 +13,7 @@ import withLocation from '../withLocation'; import { ItemView } from '../views'; import { PaneLoading } from '../components'; import { DataContext } from '../contexts'; -import { getItem } from '../storage'; -import { - TENANT_IDS_KEY, - switchAffiliation, -} from '../utils'; +import { switchAffiliation } from '../utils'; const getRequestsPath = `circulation/requests?query=(itemId==:{itemid}) and status==(${requestsStatusString}) sortby requestDate desc&limit=1`; @@ -29,6 +25,7 @@ class ItemRoute extends React.Component { path: 'inventory/items/:{itemid}', POST: { path: 'inventory/items' }, resourceShouldRefresh: true, + tenant: '!{location.state.tenantTo}', }, markItemAsWithdrawn: { type: 'okapi', @@ -105,6 +102,7 @@ class ItemRoute extends React.Component { holdingsRecords: { type: 'okapi', path: 'holdings-storage/holdings/:{holdingsrecordid}', + tenant: '!{location.state.tenantTo}', }, instanceRecords: { type: 'okapi', @@ -164,18 +162,22 @@ class ItemRoute extends React.Component { const { match: { params: { id } }, location: { search }, + history, } = this.props; - window.location.href = `/inventory/view/${id}${search}`; + history.push({ + pathname: `/inventory/view/${id}`, + search, + }); } onClose = () => { - const { stripes: { okapi } } = this.props; - const tenantIds = getItem(TENANT_IDS_KEY); - - const tenantFrom = tenantIds ? tenantIds.tenantFrom : okapi.tenant; + const { + stripes, + location: { state: { tenantFrom } }, + } = this.props; - switchAffiliation(okapi, tenantFrom, this.goBack).then(); + switchAffiliation(stripes, tenantFrom, this.goBack).then(); } isLoading = () => { @@ -222,6 +224,7 @@ ItemRoute.propTypes = { resources: PropTypes.object, stripes: PropTypes.object, tenantFrom: PropTypes.string, + history: PropTypes.object, }; export default flowRight( diff --git a/src/routes/ViewHoldingRoute.js b/src/routes/ViewHoldingRoute.js index ffdaae0f6..7ad407a93 100644 --- a/src/routes/ViewHoldingRoute.js +++ b/src/routes/ViewHoldingRoute.js @@ -1,26 +1,18 @@ import { useContext } from 'react'; import { useParams } from 'react-router-dom'; -import { useStripes } from '@folio/stripes/core'; - import { DataContext } from '../contexts'; import ViewHoldingsRecord from '../ViewHoldingsRecord'; -import { getItem } from '../storage'; -import { TENANT_IDS_KEY } from '../utils'; const ViewHoldingRoute = () => { - const { okapi } = useStripes(); const { id: instanceId, holdingsrecordid } = useParams(); const referenceTables = useContext(DataContext); - const tenantIds = getItem(TENANT_IDS_KEY); return ( ); }; diff --git a/src/utils.js b/src/utils.js index 6cc44fedd..0868e17a5 100644 --- a/src/utils.js +++ b/src/utils.js @@ -22,6 +22,7 @@ import { import moment from 'moment'; import { updateTenant } from '@folio/stripes/core'; +import { validateUser } from '@folio/stripes-core/src/loginServices'; import { FormattedUTCDate } from '@folio/stripes/components'; import { @@ -39,7 +40,6 @@ import { CONTENT_TYPE_HEADER, OKAPI_TOKEN_HEADER, } from './constants'; -import { getItem, removeItem, setItem } from './storage'; export const areAllFieldsEmpty = fields => fields.every(item => (isArray(item) ? (isEmpty(item) || item.every(element => !element || element === '-')) @@ -828,19 +828,20 @@ export const hasMemberTenantPermission = (permissions = [], permissionName, tena return hasPermission; }; -export const TENANT_IDS_KEY = 'tenantIds'; +export const switchAffiliation = async (stripes, tenantId, move) => { + if (stripes.okapi.tenant !== tenantId) { + await updateTenant(stripes.okapi, tenantId); -export const switchAffiliation = async (okapi, tenantId, move) => { - if (okapi.tenant !== tenantId) { - await updateTenant(okapi, tenantId); - - const tenantIds = getItem(TENANT_IDS_KEY); - - if (tenantIds) { - removeItem(TENANT_IDS_KEY); - } else { - setItem(TENANT_IDS_KEY, { tenantTo: tenantId, tenantFrom: okapi.tenant }); - } + validateUser( + stripes.okapi.url, + stripes.store, + tenantId, + { + token: stripes.okapi.token, + user: stripes.user.user, + perms: stripes.user.perms, + }, + ); move(); } else {