From 09b0d1bdc9e8b46557f98f8dd43fdef9742d0620 Mon Sep 17 00:00:00 2001
From: Mariia Aloshyna <55138456+mariia-aloshyna@users.noreply.github.com>
Date: Thu, 26 Oct 2023 16:39:11 +0300
Subject: [PATCH] UIIN-2617: Add immediate warning message when a local
instance is shared (#2321)
---
CHANGELOG.md | 1 +
.../InstanceDetails/InstanceDetails.js | 97 ++++++++++++-------
.../InstanceDetails/InstanceDetails.test.js | 7 ++
src/ViewInstance.js | 16 ++-
src/ViewInstanceWrapper.js | 3 +-
src/common/hooks/useInstance.js | 6 +-
translations/ui-inventory/en.json | 1 +
7 files changed, 87 insertions(+), 44 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a2e12fcb6..e89d912fc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,7 @@
* User receives an error when searching for an item in the Inventory app. Fixes UIIN-2634.
* Create new instance success toast no longer shows the instance HRID. Fixes UIIN-2635.
* Optimistic locking message not working for instances in non-consortial tenant. Fixes UIIN-2628.
+* Add immediate warning message when a local instance is shared. Refs UIIN-2617.
## [10.0.0](https://github.com/folio-org/ui-inventory/tree/v10.0.0) (2023-10-13)
[Full Changelog](https://github.com/folio-org/ui-inventory/compare/v9.4.12...v10.0.0)
diff --git a/src/Instance/InstanceDetails/InstanceDetails.js b/src/Instance/InstanceDetails/InstanceDetails.js
index b903fc236..954d66086 100644
--- a/src/Instance/InstanceDetails/InstanceDetails.js
+++ b/src/Instance/InstanceDetails/InstanceDetails.js
@@ -72,6 +72,7 @@ const InstanceDetails = forwardRef(({
userTenantPermissions,
isShared,
isLoading,
+ isInstanceSharing,
...rest
}, ref) => {
const intl = useIntl();
@@ -85,12 +86,15 @@ const InstanceDetails = forwardRef(({
const accordionState = useMemo(() => getAccordionState(instance, accordions), [instance]);
const [helperApp, setHelperApp] = useState();
+ const isBasicPane = isInstanceSharing || isLoading;
const tags = instance?.tags?.tagList;
const isUserInCentralTenant = checkIfUserInCentralTenant(stripes);
const canCreateHoldings = stripes.hasPerm('ui-inventory.holdings.edit');
const detailsLastMenu = useMemo(() => {
+ if (isBasicPane) return null;
+
return (
{
@@ -106,31 +110,15 @@ const InstanceDetails = forwardRef(({
}
);
- }, [tagsEnabled, tags, intl]);
-
- if (isLoading) {
- return (
- }
- dismissible
- onClose={onClose}
- >
-
-
-
-
- );
- }
-
- const isConsortialHoldingsVisible = instance?.shared || isInstanceShadowCopy(instance?.source);
+ }, [isBasicPane, tagsEnabled, tags, intl]);
+ const detailsActionMenu = useMemo(
+ () => (isBasicPane ? null : actionMenu),
+ [isBasicPane, actionMenu],
+ );
const renderPaneTitle = () => {
+ if (isBasicPane) return intl.formatMessage({ id: 'ui-inventory.edit' });
+
const isInstanceShared = Boolean(isShared || isInstanceShadowCopy(instance?.source));
return (
@@ -146,6 +134,8 @@ const InstanceDetails = forwardRef(({
};
const renderPaneSubtitle = () => {
+ if (isBasicPane) return null;
+
return (
- }
- paneTitle={renderPaneTitle()}
- paneSub={renderPaneSubtitle()}
- dismissible
- onClose={onClose}
- actionMenu={actionMenu}
- defaultWidth="fill"
- lastMenu={detailsLastMenu}
- >
+ const renderDetails = () => {
+ if (isInstanceSharing) {
+ return (
+
+
+
+
+
+ );
+ }
+
+ if (isLoading) {
+ return (
+
+
+
+ );
+ }
+
+ const isConsortialHoldingsVisible = instance?.shared || isInstanceShadowCopy(instance?.source);
+
+ return (
+ <>
@@ -291,6 +293,25 @@ const InstanceDetails = forwardRef(({
/>
+ >
+ );
+ };
+
+ return (
+ <>
+ }
+ paneTitle={renderPaneTitle()}
+ paneSub={renderPaneSubtitle()}
+ actionMenu={detailsActionMenu}
+ lastMenu={detailsLastMenu}
+ dismissible
+ onClose={onClose}
+ defaultWidth="fill"
+ >
+ {renderDetails()}
{ helperApp && }
>
@@ -306,6 +327,7 @@ InstanceDetails.propTypes = {
tagsEnabled: PropTypes.bool,
userTenantPermissions: PropTypes.arrayOf(PropTypes.object),
isLoading: PropTypes.bool,
+ isInstanceSharing: PropTypes.bool,
isShared: PropTypes.bool,
};
@@ -313,6 +335,7 @@ InstanceDetails.defaultProps = {
instance: {},
tagsEnabled: false,
isLoading: false,
+ isInstanceSharing: false,
isShared: false,
};
diff --git a/src/Instance/InstanceDetails/InstanceDetails.test.js b/src/Instance/InstanceDetails/InstanceDetails.test.js
index daf483dcd..e8cd22f7e 100644
--- a/src/Instance/InstanceDetails/InstanceDetails.test.js
+++ b/src/Instance/InstanceDetails/InstanceDetails.test.js
@@ -112,6 +112,13 @@ describe('InstanceDetails', () => {
expect(screen.getByText('Instance relationship (analytics and bound-with)')).toBeInTheDocument();
});
+ it('should show a correct Warning message banner when instance sharing is in progress', () => {
+ renderInstanceDetails({ isInstanceSharing: true });
+
+ expect(screen.getByText('Sharing this local instance will take a few moments.' +
+ ' A success message and updated details will be displayed upon completion.')).toBeInTheDocument();
+ });
+
it('should show a correct Warning message banner when staff suppressed', () => {
const staffSuppressedInstance = {
...instance,
diff --git a/src/ViewInstance.js b/src/ViewInstance.js
index beeed1f4d..f687c918a 100644
--- a/src/ViewInstance.js
+++ b/src/ViewInstance.js
@@ -176,7 +176,7 @@ class ViewInstance extends React.Component {
this.log = logger.log.bind(logger);
this.state = {
- isLoading: false,
+ isInstanceSharing: false,
marcRecord: null,
findInstancePluginOpened: false,
isItemsMovement: false,
@@ -493,14 +493,14 @@ class ViewInstance extends React.Component {
this.setState({
isUnlinkAuthoritiesModalOpen: false,
isShareLocalInstanceModalOpen: false,
- isLoading: true
+ isInstanceSharing: true,
});
await this.waitForInstanceSharingComplete({ sourceTenantId, instanceIdentifier, instanceTitle });
})
.then(async () => {
await this.props.refetchInstance();
- this.setState({ isLoading: false });
+ this.setState({ isInstanceSharing: false });
this.calloutRef.current.sendCallout({
type: 'success',
message: ,
@@ -883,8 +883,12 @@ class ViewInstance extends React.Component {
canUseSingleRecordImport,
isCentralTenantPermissionsLoading,
isShared,
+ isLoading,
} = this.props;
- const { linkedAuthoritiesLength } = this.state;
+ const {
+ linkedAuthoritiesLength,
+ isInstanceSharing,
+ } = this.state;
const ci = makeConnectedInstance(this.props, stripes.logger);
const instance = ci.instance();
@@ -918,7 +922,7 @@ class ViewInstance extends React.Component {
handler: (e) => collapseAllSections(e, this.accordionStatusRef),
},
];
- const isInstanceLoading = this.state.isLoading || !instance || isCentralTenantPermissionsLoading;
+ const isInstanceLoading = isLoading || !instance || isCentralTenantPermissionsLoading;
const keyInStorageToHoldingsAccsState = ['holdings'];
return (
@@ -938,6 +942,7 @@ class ViewInstance extends React.Component {
ref={this.accordionStatusRef}
userTenantPermissions={this.state.userTenantPermissions}
isLoading={isInstanceLoading}
+ isInstanceSharing={isInstanceSharing}
isShared={isShared}
>
{
@@ -1093,6 +1098,7 @@ ViewInstance.propTypes = {
}).isRequired,
tagsEnabled: PropTypes.bool,
updateLocation: PropTypes.func.isRequired,
+ isLoading: PropTypes.bool,
};
export default flowRight(
diff --git a/src/ViewInstanceWrapper.js b/src/ViewInstanceWrapper.js
index 2fb8b2caa..170ed5ef1 100644
--- a/src/ViewInstanceWrapper.js
+++ b/src/ViewInstanceWrapper.js
@@ -17,7 +17,7 @@ const ViewInstanceWrapper = (props) => {
const userId = stripes?.user?.user?.id;
const centralTenantId = stripes.user.user?.consortium?.centralTenantId;
const consortiumId = stripes.user.user?.consortium?.id;
- const { instance, refetch } = useInstance(id);
+ const { instance, isLoading, refetch } = useInstance(id);
const isShared = Boolean(instance?.shared);
const tenantId = instance?.tenantId ?? stripes.okapi.tenant;
@@ -41,6 +41,7 @@ const ViewInstanceWrapper = (props) => {
consortiumId={consortiumId}
refetchInstance={refetch}
selectedInstance={instance}
+ isLoading={isLoading}
centralTenantPermissions={centralTenantPermissions}
isCentralTenantPermissionsLoading={isCentralTenantPermissionsLoading}
/>
diff --git a/src/common/hooks/useInstance.js b/src/common/hooks/useInstance.js
index b60cfc3bc..686408d17 100644
--- a/src/common/hooks/useInstance.js
+++ b/src/common/hooks/useInstance.js
@@ -9,7 +9,7 @@ const useInstance = (id) => {
const instanceTenantId = _instance?.tenantId;
const isShared = _instance?.shared;
- const { isLoading, instance: data, refetch } = useInstanceQuery(
+ const { isLoading: isInstanceLoading, instance: data, refetch } = useInstanceQuery(
id,
{ tenantId: instanceTenantId },
{ enabled: Boolean(id && !isSearchInstanceByIdLoading) }
@@ -23,6 +23,10 @@ const useInstance = (id) => {
}),
[data, isShared, instanceTenantId],
);
+ const isLoading = useMemo(
+ () => isSearchInstanceByIdLoading || isInstanceLoading,
+ [isSearchInstanceByIdLoading, isInstanceLoading],
+ );
return {
instance,
diff --git a/translations/ui-inventory/en.json b/translations/ui-inventory/en.json
index afa026c97..91e1ac580 100644
--- a/translations/ui-inventory/en.json
+++ b/translations/ui-inventory/en.json
@@ -798,6 +798,7 @@
"warning.instance.suppressedFromDiscovery": "Warning: Instance is marked suppressed from discovery",
"warning.instance.staffSuppressed": "Warning: Instance is marked staff suppressed",
"warning.instance.suppressedFromDiscoveryAndStaffSuppressed": "Warning: Instance is marked suppressed from discovery and staff suppressed",
+ "warning.instance.sharingLocalInstance": "Sharing this local instance will take a few moments. A success message and updated details will be displayed upon completion.",
"warning.holdingsRecord.suppressedFromDiscovery": "Warning: Holdings is marked suppressed from discovery",
"warning.item.suppressedFromDiscovery": "Warning: Item is marked suppressed from discovery",
"discoverySuppressed": "Suppressed from discovery",