Skip to content

Commit

Permalink
UIIN-2452: Fix creating/editing/duplicating holdings/items for differ…
Browse files Browse the repository at this point in the history
…ent 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 <[email protected]>
Co-authored-by: Mariia Aloshyna <[email protected]>
  • Loading branch information
3 people authored Oct 27, 2023
1 parent 09b0d1b commit e583600
Show file tree
Hide file tree
Showing 19 changed files with 210 additions and 110 deletions.
11 changes: 6 additions & 5 deletions src/Holding/CreateHolding/CreateHolding.js
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand All @@ -39,21 +39,22 @@ 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: <FormattedMessage
id="ui-inventory.holdingsRecord.successfullySaved"
values={{ hrid: holdingsRecord.hrid }}
/>,
});
onCancel();
});
}, [onCancel, callout]);

Expand Down
25 changes: 22 additions & 3 deletions src/Holding/DuplicateHolding/DuplicateHolding.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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',
Expand All @@ -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]);
Expand Down
25 changes: 19 additions & 6 deletions src/Holding/EditHolding/EditHolding.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);
Expand All @@ -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: <FormattedMessage
id="ui-inventory.holdingsRecord.successfullySaved"
Expand Down
8 changes: 6 additions & 2 deletions src/Instance/HoldingsList/Holding/HoldingButtonsGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ const HoldingButtonsGroup = ({
<Button
id={`clickable-view-holdings-${holding.id}`}
data-test-view-holdings
onClick={() => switchAffiliation(stripes, tenantId, onViewHolding)}
onClick={async () => {
await switchAffiliation(stripes, tenantId, onViewHolding);
}}
>
<FormattedMessage id="ui-inventory.viewHoldings" />
</Button>
Expand All @@ -58,7 +60,9 @@ const HoldingButtonsGroup = ({
<Button
id={`clickable-new-item-${holding.id}`}
data-test-add-item
onClick={() => switchAffiliation(stripes, tenantId, onAddItem)}
onClick={async () => {
await switchAffiliation(stripes, tenantId, onAddItem);
}}
buttonStyle="primary paneHeaderNewButton"
>
<FormattedMessage id="ui-inventory.addItem" />
Expand Down
13 changes: 6 additions & 7 deletions src/Instance/HoldingsList/HoldingsListContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ const HoldingsListContainer = ({
const stripes = useStripes();
const { holdingsRecords: holdings, isLoading } = useInstanceHoldingsQuery(instance.id, { tenantId });

const canViewHoldings = stripes.hasPerm('ui-inventory.instance.view');
const canCreateItem = stripes.hasPerm('ui-inventory.item.edit');
const canViewItems = stripes.hasPerm('ui-inventory.instance.view');
const canViewHoldingsAndItems = stripes.hasPerm('ui-inventory.instance.view');
const canCreateItem = stripes.hasPerm('ui-inventory.item.create');

if (isLoading) return <Loading size="large" />;

Expand All @@ -31,9 +30,9 @@ const HoldingsListContainer = ({
holdings={holdings}
instance={instance}
tenantId={tenantId}
showViewHoldingsButton={canViewHoldings}
showViewHoldingsButton={canViewHoldingsAndItems}
showAddItemButton={canCreateItem}
isBarcodeAsHotlink={canViewItems}
isBarcodeAsHotlink={canViewHoldingsAndItems}
pathToAccordionsState={pathToAccordionsState}
/>
) : (
Expand All @@ -42,9 +41,9 @@ const HoldingsListContainer = ({
holdings={holdings}
instance={instance}
tenantId={tenantId}
showViewHoldingsButton={canViewHoldings}
showViewHoldingsButton={canViewHoldingsAndItems}
showAddItemButton={canCreateItem}
isBarcodeAsHotlink={canViewItems}
isBarcodeAsHotlink={canViewHoldingsAndItems}
pathToAccordionsState={pathToAccordionsState}
/>
)
Expand Down
2 changes: 1 addition & 1 deletion src/Instance/InstanceDetails/InstanceDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const InstanceDetails = forwardRef(({
const tags = instance?.tags?.tagList;
const isUserInCentralTenant = checkIfUserInCentralTenant(stripes);

const canCreateHoldings = stripes.hasPerm('ui-inventory.holdings.edit');
const canCreateHoldings = stripes.hasPerm('ui-inventory.holdings.create');

const detailsLastMenu = useMemo(() => {
if (isBasicPane) return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import PropTypes from 'prop-types';
import { withRouter } from 'react-router';
import { useHistory } from 'react-router-dom';

import {
IfPermission,
useStripes,
} from '@folio/stripes/core';
import { useStripes } from '@folio/stripes/core';
import {
Row,
Col,
Expand Down Expand Up @@ -39,21 +36,21 @@ const InstanceNewHolding = ({
}, [location.search, instance.id]);

return (
<IfPermission perm="ui-inventory.holdings.create">
<Row>
<Col sm={12}>
<Button
id="clickable-new-holdings-record"
aria-label={label}
buttonStyle="primary"
fullWidth
onClick={() => switchAffiliation(stripes, tenantId, onNewHolding)}
>
{label}
</Button>
</Col>
</Row>
</IfPermission>
<Row>
<Col sm={12}>
<Button
id="clickable-new-holdings-record"
aria-label={label}
buttonStyle="primary"
fullWidth
onClick={async () => {
await switchAffiliation(stripes, tenantId, onNewHolding);
}}
>
{label}
</Button>
</Col>
</Row>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ describe('InstanceNewHolding', () => {
const { getByText } = renderInstanceNewHolding();
fireEvent.click(getByText(/ui-inventory.addHoldings/i));

expect(mockPush).toHaveBeenCalledWith();
expect(mockPush).toHaveBeenCalled();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -66,9 +65,9 @@ const MemberTenantHoldings = ({
tenantId={id}
draggable={false}
droppable={false}
showViewHoldingsButton={canViewHoldings}
showViewHoldingsButton={canViewHoldingsAndItems}
showAddItemButton={canCreateItem}
isBarcodeAsHotlink={canViewItems}
isBarcodeAsHotlink={canViewHoldingsAndItems}
pathToAccordionsState={pathToHoldingsAccordion}
/>
</MoveItemsContext>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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']
}],
}];
Expand Down
4 changes: 3 additions & 1 deletion src/Instance/ItemsList/ItemBarcode.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ const ItemBarcode = ({
<Button
buttonStyle="link"
buttonClass={css.linkWithoutBorder}
onClick={() => switchAffiliation(stripes, tenantId, onViewItem)}
onClick={async () => {
await switchAffiliation(stripes, tenantId, onViewItem);
}}
>
{itemBarcode}
</Button>
Expand Down
10 changes: 5 additions & 5 deletions src/Item/CreateItem/CreateItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ const CreateItem = ({
state: {
tenantTo,
tenantFrom,
},
},
} = {},
} = {},
} = useHistory();

const { isLoading: isInstanceLoading, instance } = useInstanceQuery(instanceId, { tenantId: tenantTo });
Expand All @@ -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',
Expand Down
19 changes: 15 additions & 4 deletions src/Item/DuplicateItem/DuplicateItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
} from '../hooks';

import { itemStatusesMap } from '../../constants';
import { switchAffiliation } from '../../utils';

const OMITTED_INITIAL_FIELDS = ['id', 'hrid', 'barcode', 'lastCheckIn'];

Expand All @@ -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',
Expand All @@ -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;
Expand Down
Loading

0 comments on commit e583600

Please sign in to comment.