From e5836008f6dfd32baab98fd7453f296bb8687986 Mon Sep 17 00:00:00 2001 From: Oleksandr Hladchenko <85172747+OleksandrHladchenko1@users.noreply.github.com> Date: Fri, 27 Oct 2023 14:57:07 +0300 Subject: [PATCH] UIIN-2452: Fix creating/editing/duplicating holdings/items for different member tenants (follow-up) (#2319) * Consortial holdings acc * UIIN-2410: Adjustments * UIIN-2410: Add new hook * UIIN-2410: Add tests * UIIN-2452: Disable buttons when member tenant does not have permissions * UIIN-2410: Instance 3rd pane: Add consortial holdings/item accordion * UIIN-2452: Add unit tests & switching affiliation when view holdings and add item * UIIN-2410: Fix tests * UIIN-2452: Add switching affiliation when click on item barcode & Add holdings button * UIIN-2452: Fix tests * Update HoldingAccordion.js * Update HoldingButtonsGroup.js * UIIN-2452: Fix tests * Update HoldingsListMovement.js * Update HoldingContainer.js * UIIN-2452: Add returning to the previous affiliation * UIIN-2452: Add tenantId to props validation * UIIN-2452: Add behaviour for non-consortial tenant * Fix some comments * Fix perms handling * Fix warnings * Adjust tests * Fix tests * UIIN-2452: Switch user affiliation using validateUser * Update HoldingAccordion.js * Supress Add holding & Add item & View holdings buttons if user doesn't have permissions * UIIN-2452: Fix comments & add unit tests * UIIN-2452: Fixes after review * UIIN-2452: Fix code smells * UIIN-2452: Change permissions to view/create holdings and items * UIIN-2452: Change permissions to view/create holdings and items * UIIN-2452: Instance 3rd pane: Enable/disable consortial holdings/item actions based on User permissions (follow-up) * UIIN-2452: Fixes in CreateHoldings component * UIIN-2452: Fix test * UIIN-2452: fix creating holdings/items for different member tenants * UIIN-2452: Fix code smells * UIIN-2452: Fix tests * UIIN-2452: Remove excessive permission checking --------- Co-authored-by: Mariia_Aloshyna Co-authored-by: Mariia Aloshyna <55138456+mariia-aloshyna@users.noreply.github.com> --- src/Holding/CreateHolding/CreateHolding.js | 11 ++--- .../DuplicateHolding/DuplicateHolding.js | 25 +++++++++-- src/Holding/EditHolding/EditHolding.js | 25 ++++++++--- .../Holding/HoldingButtonsGroup.js | 8 +++- .../HoldingsList/HoldingsListContainer.js | 13 +++--- .../InstanceDetails/InstanceDetails.js | 2 +- .../InstanceNewHolding/InstanceNewHolding.js | 35 +++++++--------- .../InstanceNewHolding.test.js | 2 +- .../MemberTenantHoldings.js | 11 +++-- .../MemberTenantHoldings.test.js | 2 +- src/Instance/ItemsList/ItemBarcode.js | 4 +- src/Item/CreateItem/CreateItem.js | 10 ++--- src/Item/DuplicateItem/DuplicateItem.js | 19 +++++++-- src/Item/EditItem/EditItem.js | 13 ++++-- src/ViewHoldingsRecord.js | 36 +++++++++++++--- src/ViewHoldingsRecord.test.js | 35 +++++++++++----- src/routes/ItemRoute.js | 25 ----------- src/utils.js | 2 +- src/views/ItemView.js | 42 +++++++++++++++++-- 19 files changed, 210 insertions(+), 110 deletions(-) diff --git a/src/Holding/CreateHolding/CreateHolding.js b/src/Holding/CreateHolding/CreateHolding.js index 1cfcceef9..d778690ee 100644 --- a/src/Holding/CreateHolding/CreateHolding.js +++ b/src/Holding/CreateHolding/CreateHolding.js @@ -30,7 +30,7 @@ const CreateHolding = ({ const callout = useCallout(); const { instance, isLoading: isInstanceLoading } = useInstance(instanceId); const sourceId = referenceData.holdingsSourcesByName?.FOLIO?.id; - const { location: { state: { tenantFrom } } } = history; + const tenantFrom = location?.state?.tenantFrom || stripes.okapi.tenant; const goBack = useCallback(() => { history.push({ @@ -39,13 +39,15 @@ const CreateHolding = ({ }); }, [location.search, instanceId]); - const onCancel = useCallback(() => { - switchAffiliation(stripes, tenantFrom, goBack); + const onCancel = useCallback(async () => { + await switchAffiliation(stripes, tenantFrom, goBack); }, [stripes, tenantFrom, goBack]); const onSubmit = useCallback((newHolding) => { return mutator.holding.POST(newHolding) - .then((holdingsRecord) => { + .then(async (holdingsRecord) => { + await onCancel(); + callout.sendCallout({ type: 'success', message: , }); - onCancel(); }); }, [onCancel, callout]); diff --git a/src/Holding/DuplicateHolding/DuplicateHolding.js b/src/Holding/DuplicateHolding/DuplicateHolding.js index 96fb49f32..eac3e2078 100644 --- a/src/Holding/DuplicateHolding/DuplicateHolding.js +++ b/src/Holding/DuplicateHolding/DuplicateHolding.js @@ -16,13 +16,20 @@ import { } from '../../hooks'; import HoldingsForm from '../../edit/holdings/HoldingsForm'; import withLocation from '../../withLocation'; +import { switchAffiliation } from '../../utils'; const DuplicateHolding = ({ goTo, history, instanceId, holdingId, - location: { search, state: locationState }, + location: { + search, + state: { + backPathname: locationState, + tenantFrom, + } = {}, + }, referenceTables, }) => { const callout = useCallout(); @@ -37,10 +44,18 @@ const DuplicateHolding = ({ sourceId, }), [holding, sourceId]); + const goToDuplicatedHolding = useCallback((id) => { + history.push({ + pathname: `/inventory/view/${instanceId}/${id}`, + search, + state: { tenantTo: stripes.okapi.tenant }, + }); + }, [search, instanceId]); + const onSuccess = useCallback(async (response) => { const { id, hrid } = await response.json(); - goTo(`/inventory/view/${instanceId}/${id}`); + await switchAffiliation(stripes, tenantFrom, () => goToDuplicatedHolding(id)); return callout.sendCallout({ type: 'success', @@ -53,13 +68,17 @@ const DuplicateHolding = ({ const { mutateHolding } = useHoldingMutation({ onSuccess }); - const onCancel = useCallback(() => { + const goBack = useCallback(() => { history.push({ pathname: locationState?.backPathname ?? `/inventory/view/${instanceId}`, search, }); }, [search, instanceId]); + const onCancel = useCallback(async () => { + await switchAffiliation(stripes, tenantFrom, goBack); + }, [stripes, tenantFrom, goBack]); + const onSubmit = useCallback(holdingValues => ( mutateHolding(holdingValues) ), [mutateHolding]); diff --git a/src/Holding/EditHolding/EditHolding.js b/src/Holding/EditHolding/EditHolding.js index bb9e3432e..4a855213f 100644 --- a/src/Holding/EditHolding/EditHolding.js +++ b/src/Holding/EditHolding/EditHolding.js @@ -17,7 +17,10 @@ import { } from '../../hooks'; import HoldingsForm from '../../edit/holdings/HoldingsForm'; import withLocation from '../../withLocation'; -import { parseHttpError } from '../../utils'; +import { + parseHttpError, + switchAffiliation, +} from '../../utils'; const EditHolding = ({ goTo, @@ -28,7 +31,13 @@ const EditHolding = ({ referenceTables, }) => { const callout = useCallout(); - const { search, state: locationState } = location; + const { + search, + state: { + backPathname: locationState, + tenantFrom, + } = {}, + } = location; const stripes = useStripes(); const [httpError, setHttpError] = useState(); const { instance, isLoading: isInstanceLoading } = useInstanceQuery(instanceId); @@ -42,17 +51,21 @@ const EditHolding = ({ referenceTables?.holdingsSources?.find(source => source.id === holding?.sourceId)?.name === 'MARC' ), [holding]); - const onCancel = useCallback(() => { + const goBack = useCallback(() => { history.push({ pathname: locationState?.backPathname ?? `/inventory/view/${instanceId}`, search, }); }, [search, instanceId]); - const onSuccess = useCallback(() => { - onCancel(); + const onCancel = useCallback(async () => { + await switchAffiliation(stripes, tenantFrom, goBack); + }, [stripes, tenantFrom, goBack]); + + const onSuccess = useCallback(async () => { + await onCancel(); - return callout.sendCallout({ + callout.sendCallout({ type: 'success', message: switchAffiliation(stripes, tenantId, onViewHolding)} + onClick={async () => { + await switchAffiliation(stripes, tenantId, onViewHolding); + }} > @@ -58,7 +60,9 @@ const HoldingButtonsGroup = ({ - - - + + + + + ); }; diff --git a/src/Instance/InstanceDetails/InstanceNewHolding/InstanceNewHolding.test.js b/src/Instance/InstanceDetails/InstanceNewHolding/InstanceNewHolding.test.js index 8cffc1fae..991186359 100644 --- a/src/Instance/InstanceDetails/InstanceNewHolding/InstanceNewHolding.test.js +++ b/src/Instance/InstanceDetails/InstanceNewHolding/InstanceNewHolding.test.js @@ -43,7 +43,7 @@ describe('InstanceNewHolding', () => { const { getByText } = renderInstanceNewHolding(); fireEvent.click(getByText(/ui-inventory.addHoldings/i)); - expect(mockPush).toHaveBeenCalledWith(); + expect(mockPush).toHaveBeenCalled(); }); }); }); diff --git a/src/Instance/InstanceDetails/MemberTenantHoldings/MemberTenantHoldings.js b/src/Instance/InstanceDetails/MemberTenantHoldings/MemberTenantHoldings.js index 347164e0f..4ce0b7829 100644 --- a/src/Instance/InstanceDetails/MemberTenantHoldings/MemberTenantHoldings.js +++ b/src/Instance/InstanceDetails/MemberTenantHoldings/MemberTenantHoldings.js @@ -40,10 +40,9 @@ const MemberTenantHoldings = ({ const { holdingsRecords, isLoading } = useInstanceHoldingsQuery(instance?.id, { tenantId: id }); const isUserInCentralTenant = checkIfUserInCentralTenant(stripes); - const canViewHoldings = hasMemberTenantPermission('ui-inventory.instance.view', id, userTenantPermissions); - const canCreateItem = hasMemberTenantPermission('ui-inventory.item.edit', id, userTenantPermissions); - const canCreateHoldings = hasMemberTenantPermission('ui-inventory.holdings.edit', id, userTenantPermissions); - const canViewItems = hasMemberTenantPermission('ui-inventory.instance.view', id, userTenantPermissions); + const canViewHoldingsAndItems = hasMemberTenantPermission('ui-inventory.instance.view', id, userTenantPermissions); + const canCreateItem = hasMemberTenantPermission('ui-inventory.item.create', id, userTenantPermissions); + const canCreateHoldings = hasMemberTenantPermission('ui-inventory.holdings.create', id, userTenantPermissions); if (isEmpty(holdingsRecords)) return null; @@ -66,9 +65,9 @@ const MemberTenantHoldings = ({ tenantId={id} draggable={false} droppable={false} - showViewHoldingsButton={canViewHoldings} + showViewHoldingsButton={canViewHoldingsAndItems} showAddItemButton={canCreateItem} - isBarcodeAsHotlink={canViewItems} + isBarcodeAsHotlink={canViewHoldingsAndItems} pathToAccordionsState={pathToHoldingsAccordion} /> diff --git a/src/Instance/InstanceDetails/MemberTenantHoldings/MemberTenantHoldings.test.js b/src/Instance/InstanceDetails/MemberTenantHoldings/MemberTenantHoldings.test.js index f6271d607..93b09e8a6 100644 --- a/src/Instance/InstanceDetails/MemberTenantHoldings/MemberTenantHoldings.test.js +++ b/src/Instance/InstanceDetails/MemberTenantHoldings/MemberTenantHoldings.test.js @@ -33,7 +33,7 @@ const mockMemberTenant = { const userTenantPermissions = [{ tenantId: 'college', permissionNames: [{ - permissionName: 'ui-inventory.holdings.edit', + permissionName: 'ui-inventory.holdings.create', subPermissions: ['test subPermission 1'] }], }]; diff --git a/src/Instance/ItemsList/ItemBarcode.js b/src/Instance/ItemsList/ItemBarcode.js index a009ff090..5178842a2 100644 --- a/src/Instance/ItemsList/ItemBarcode.js +++ b/src/Instance/ItemsList/ItemBarcode.js @@ -76,7 +76,9 @@ const ItemBarcode = ({ diff --git a/src/Item/CreateItem/CreateItem.js b/src/Item/CreateItem/CreateItem.js index d538783f4..ae24cecc2 100644 --- a/src/Item/CreateItem/CreateItem.js +++ b/src/Item/CreateItem/CreateItem.js @@ -30,8 +30,8 @@ const CreateItem = ({ state: { tenantTo, tenantFrom, - }, - }, + } = {}, + } = {}, } = useHistory(); const { isLoading: isInstanceLoading, instance } = useInstanceQuery(instanceId, { tenantId: tenantTo }); @@ -51,14 +51,14 @@ const CreateItem = ({ }); }, [instanceId, search]); - const onCancel = useCallback(() => { - switchAffiliation(stripes, tenantFrom, goBack); + const onCancel = useCallback(async () => { + await switchAffiliation(stripes, tenantFrom, goBack); }, [stripes, tenantFrom]); const onSuccess = useCallback(async (response) => { const { hrid } = await response.json(); - onCancel(); + await onCancel(); return callout.sendCallout({ type: 'success', diff --git a/src/Item/DuplicateItem/DuplicateItem.js b/src/Item/DuplicateItem/DuplicateItem.js index 47f19556a..caa2664ad 100644 --- a/src/Item/DuplicateItem/DuplicateItem.js +++ b/src/Item/DuplicateItem/DuplicateItem.js @@ -27,6 +27,7 @@ import { } from '../hooks'; import { itemStatusesMap } from '../../constants'; +import { switchAffiliation } from '../../utils'; const OMITTED_INITIAL_FIELDS = ['id', 'hrid', 'barcode', 'lastCheckIn']; @@ -53,13 +54,18 @@ const DuplicateItem = ({ return duplicatedItem; }, [item]); - const onSuccess = useCallback(async (response) => { - const { id, hrid } = await response.json(); - + const goToDuplicatedItem = useCallback((id) => { history.push({ pathname: `/inventory/view/${instanceId}/${holdingId}/${id}`, search: location.search, + state: { tenantTo: stripes.okapi.tenant }, }); + }, [location.search, instanceId]); + + const onSuccess = useCallback(async (response) => { + const { id, hrid } = await response.json(); + + await switchAffiliation(stripes, location?.state?.tenantFrom, () => goToDuplicatedItem(id)); return callout.sendCallout({ type: 'success', @@ -72,13 +78,18 @@ const DuplicateItem = ({ const { mutateItem } = useItemMutation({ onSuccess }); - const onCancel = useCallback(() => { + const goBack = useCallback(() => { history.push({ pathname: `/inventory/view/${instanceId}/${holdingId}/${itemId}`, search: location.search, + state: { tenantTo: stripes.okapi.tenant }, }); }, [location.search, instanceId, holdingId, itemId]); + const onCancel = useCallback(async () => { + await switchAffiliation(stripes, location?.state?.tenantFrom, goBack); + }, [stripes, location?.state?.tenantFrom, goBack]); + const onSubmit = useCallback((values) => { if (!values.barcode) { delete values.barcode; diff --git a/src/Item/EditItem/EditItem.js b/src/Item/EditItem/EditItem.js index 2099f6c7b..43702cbc8 100644 --- a/src/Item/EditItem/EditItem.js +++ b/src/Item/EditItem/EditItem.js @@ -18,7 +18,7 @@ import { } from '../../common'; import ItemForm from '../../edit/items/ItemForm'; import useCallout from '../../hooks/useCallout'; -import { parseHttpError } from '../../utils'; +import { parseHttpError, switchAffiliation } from '../../utils'; import { useItem, useItemMutation, @@ -40,16 +40,21 @@ const EditItem = ({ const callout = useCallout(); const stripes = useStripes(); - const onCancel = useCallback(() => { + const goBack = useCallback(() => { history.push({ pathname: `/inventory/view/${instanceId}/${holdingId}/${itemId}`, search: location.search, + state: { tenantTo: stripes.okapi.tenant }, }); }, [location.search, instanceId, holdingId, itemId]); + const onCancel = useCallback(async () => { + await switchAffiliation(stripes, location?.state?.tenantFrom, goBack); + }, [stripes, location?.state?.tenantFrom, goBack]); - const onSuccess = useCallback(() => { - onCancel(); + + const onSuccess = useCallback(async () => { + await onCancel(); return callout.sendCallout({ type: 'success', diff --git a/src/ViewHoldingsRecord.js b/src/ViewHoldingsRecord.js index 8684f4f6d..81d06a913 100644 --- a/src/ViewHoldingsRecord.js +++ b/src/ViewHoldingsRecord.js @@ -198,9 +198,7 @@ class ViewHoldingsRecord extends React.Component { }); }; - onClose = (e) => { - if (e) e.preventDefault(); - + goToInstanceView = () => { const { history, location: { search, state: locationState }, @@ -213,6 +211,18 @@ class ViewHoldingsRecord extends React.Component { }); } + onClose = async (e) => { + if (e) e.preventDefault(); + + const { + stripes, + location, + } = this.props; + const tenantFrom = location?.state?.tenantFrom || stripes.okapi.tenant; + + await switchAffiliation(stripes, tenantFrom, this.goToInstanceView); + } + // Edit Holdings records handlers onEditHolding = (e) => { if (e) e.preventDefault(); @@ -222,12 +232,18 @@ class ViewHoldingsRecord extends React.Component { location, id, holdingsrecordid, + stripes, } = this.props; + const tenantFrom = location?.state?.tenantFrom || stripes.okapi.tenant; + history.push({ pathname: `/inventory/edit/${id}/${holdingsrecordid}`, search: location.search, - state: { backPathname: location.pathname }, + state: { + backPathname: location.pathname, + tenantFrom, + }, }); } @@ -239,12 +255,18 @@ class ViewHoldingsRecord extends React.Component { location, id, holdingsrecordid, + stripes, } = this.props; + const tenantFrom = location?.state?.tenantFrom || stripes.okapi.tenant; + history.push({ pathname: `/inventory/copy/${id}/${holdingsrecordid}`, search: location.search, - state: { backPathname: location.pathname }, + state: { + backPathname: location.pathname, + tenantFrom, + }, }); } @@ -727,7 +749,9 @@ class ViewHoldingsRecord extends React.Component { updatedDate: getDate(holdingsRecord?.metadata?.updatedDate), })} dismissible - onClose={() => switchAffiliation(stripes, tenantFrom, this.onClose)} + onClose={async () => { + await switchAffiliation(stripes, tenantFrom, this.onClose); + }} actionMenu={this.getPaneHeaderActionMenu} > diff --git a/src/ViewHoldingsRecord.test.js b/src/ViewHoldingsRecord.test.js index 5287c07bb..172fe7233 100644 --- a/src/ViewHoldingsRecord.test.js +++ b/src/ViewHoldingsRecord.test.js @@ -9,6 +9,7 @@ import { act, fireEvent, } from '@folio/jest-config-stripes/testing-library/react'; +import { createMemoryHistory } from 'history'; import '../test/jest/__mock__'; import buildStripes from '../test/jest/__mock__/stripesCore.mock'; @@ -19,6 +20,11 @@ import { import ViewHoldingsRecord from './ViewHoldingsRecord'; +const mockPush = jest.fn(); + +const history = createMemoryHistory(); +history.push = mockPush; + jest.mock('./withLocation', () => jest.fn(c => c)); jest.mock('./common', () => ({ @@ -26,6 +32,11 @@ jest.mock('./common', () => ({ useTenantKy: jest.fn(), })); +jest.mock('./utils', () => ({ + ...jest.requireActual('./utils'), + switchAffiliation: jest.fn(() => mockPush()), +})); + const spyOncollapseAllSections = jest.spyOn(require('@folio/stripes/components'), 'collapseAllSections'); const spyOnexpandAllSections = jest.spyOn(require('@folio/stripes/components'), 'expandAllSections'); @@ -76,9 +87,7 @@ const defaultProps = { query: {}, }, stripes: buildStripes(), - history: { - push: jest.fn(), - }, + history, location: { search: '/', pathname: 'pathname', @@ -116,21 +125,21 @@ describe('ViewHoldingsRecord actions', () => { it('should close view holding page', async () => { renderViewHoldingsRecord(); fireEvent.click(await screen.findByRole('button', { name: 'confirm' })); - expect(defaultProps.history.push).toHaveBeenCalled(); + expect(mockPush).toHaveBeenCalled(); }); it('should translate to edit holding form page', async () => { renderViewHoldingsRecord(); const editHoldingBtn = await screen.findByTestId('edit-holding-btn'); fireEvent.click(editHoldingBtn); - expect(defaultProps.history.push).toHaveBeenCalled(); + expect(mockPush).toHaveBeenCalled(); }); it('should translate to duplicate holding form page', async () => { renderViewHoldingsRecord(); const duplicatHoldingBtn = await screen.findByTestId('duplicate-holding-btn'); fireEvent.click(duplicatHoldingBtn); - expect(defaultProps.history.push).toHaveBeenCalled(); + expect(mockPush).toHaveBeenCalled(); }); it('should display "inactive" by an inactive temporary location', async () => { @@ -158,21 +167,27 @@ describe('ViewHoldingsRecord actions', () => { const data = { pathname: `/inventory/copy/${defaultProps.id}/${defaultProps.holdingsrecordid}`, search: defaultProps.location.search, - state: { backPathname: defaultProps.location.pathname }, + state: { + backPathname: defaultProps.location.pathname, + tenantFrom: 'testTenantFromId', + }, }; renderViewHoldingsRecord(); fireEvent.click(await screen.findByRole('button', { name: 'duplicateRecord' })); - expect(defaultProps.history.push).toBeCalledWith(data); + expect(mockPush).toBeCalledWith(data); }); it('"onEditHolding" function to be triggered on clicking edit button', async () => { const data = { pathname: `/inventory/edit/${defaultProps.id}/${defaultProps.holdingsrecordid}`, search: defaultProps.location.search, - state: { backPathname: defaultProps.location.pathname }, + state: { + backPathname: defaultProps.location.pathname, + tenantFrom: 'testTenantFromId', + }, }; renderViewHoldingsRecord(); fireEvent.click(await screen.findByRole('button', { name: 'edit' })); - expect(defaultProps.history.push).toBeCalledWith(data); + expect(mockPush).toBeCalledWith(data); }); it('"goTo" function to be triggered on clicking duplicateRecord button', async () => { renderViewHoldingsRecord(); diff --git a/src/routes/ItemRoute.js b/src/routes/ItemRoute.js index c55ec7d76..729e04133 100644 --- a/src/routes/ItemRoute.js +++ b/src/routes/ItemRoute.js @@ -13,7 +13,6 @@ import withLocation from '../withLocation'; import { ItemView } from '../views'; import { PaneLoading } from '../components'; import { DataContext } from '../contexts'; -import { switchAffiliation } from '../utils'; const getRequestsPath = `circulation/requests?query=(itemId==:{itemid}) and status==(${requestsStatusString}) sortby requestDate desc&limit=1`; @@ -158,29 +157,6 @@ class ItemRoute extends React.Component { }, }); - goBack = () => { - const { - match: { params: { id } }, - location: { search }, - history, - } = this.props; - - history.push({ - pathname: `/inventory/view/${id}`, - search, - }); - } - - onClose = () => { - const { - stripes, - location, - } = this.props; - const tenantFrom = location?.state?.tenantFrom || stripes.okapi.tenant; - - switchAffiliation(stripes, tenantFrom, this.goBack); - } - isLoading = () => { const { resources: { @@ -209,7 +185,6 @@ class ItemRoute extends React.Component { {data => ( )} diff --git a/src/utils.js b/src/utils.js index 0de843be4..88c1a9eb4 100644 --- a/src/utils.js +++ b/src/utils.js @@ -834,7 +834,7 @@ export const switchAffiliation = async (stripes, tenantId, move) => { if (stripes.okapi.tenant !== tenantId) { await updateTenant(stripes.okapi, tenantId); - validateUser( + await validateUser( stripes.okapi.url, stripes.store, tenantId, diff --git a/src/views/ItemView.js b/src/views/ItemView.js index a613e1c90..30f224f74 100644 --- a/src/views/ItemView.js +++ b/src/views/ItemView.js @@ -69,6 +69,7 @@ import { getDateWithTime, checkIfArrayIsEmpty, handleKeyCommand, + switchAffiliation, } from '../utils'; import withLocation from '../withLocation'; import { @@ -109,11 +110,17 @@ class ItemView extends React.Component { onClickEditItem = e => { if (e) e.preventDefault(); + const { + stripes, + location, + } = this.props; + const tenantFrom = location?.state?.tenantFrom || stripes.okapi.tenant; const { id, holdingsrecordid, itemid } = this.props.match.params; this.props.history.push({ pathname: `/inventory/edit/${id}/${holdingsrecordid}/${itemid}`, search: this.props.location.search, + state: { tenantFrom } }); }; @@ -149,17 +156,44 @@ class ItemView extends React.Component { }); }; + goBack = (tenantTo) => { + const { + match: { params: { id } }, + location: { search }, + history, + } = this.props; + + history.push({ + pathname: `/inventory/view/${id}`, + search, + state: { tenantTo }, + }); + } + + onCloseViewItem = async () => { + const { + stripes, + location, + } = this.props; + const tenantFrom = location?.state?.tenantFrom || stripes.okapi.tenant; + + await switchAffiliation(stripes, tenantFrom, () => this.goBack(tenantFrom)); + } + deleteItem = item => { - this.props.onCloseViewItem(); + this.onCloseViewItem(); this.props.mutator.itemsResource.DELETE(item); }; onCopy() { + const { stripes, location } = this.props; const { itemid, id, holdingsrecordid } = this.props.match.params; + const tenantFrom = location?.state?.tenantFrom || stripes.okapi.tenant; this.props.history.push({ pathname: `/inventory/copy/${id}/${holdingsrecordid}/${itemid}`, search: this.props.location.search, + state: { tenantFrom }, }); } @@ -827,7 +861,7 @@ class ItemView extends React.Component { /> )} dismissible - onClose={this.props.onCloseViewItem} + onClose={this.onCloseViewItem} actionMenu={this.getActionMenu} > @@ -1497,6 +1531,9 @@ class ItemView extends React.Component { ItemView.propTypes = { stripes: PropTypes.shape({ hasPerm: PropTypes.func.isRequired, + okapi: PropTypes.shape({ + tenant: PropTypes.string, + }) }).isRequired, resources: PropTypes.shape({ instanceRecords: PropTypes.shape({ records: PropTypes.arrayOf(PropTypes.object) }), @@ -1553,7 +1590,6 @@ ItemView.propTypes = { requests: PropTypes.shape({ PUT: PropTypes.func.isRequired }), requestOnItem: PropTypes.shape({ replace: PropTypes.func.isRequired }), }), - onCloseViewItem: PropTypes.func.isRequired, updateLocation: PropTypes.func.isRequired, goTo: PropTypes.func.isRequired, match: PropTypes.object.isRequired,