diff --git a/CHANGELOG.md b/CHANGELOG.md
index 26bba0ab..5ef5558f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@
* Show in version history record view, which fields have been edited. Refs UIORGS-356.
* Adapt organization metadata fields to version history mechanism. Refs UIORGS-359.
* Add claiming to organization integration details. Refs UIORGS-442.
+* Add "Duplicate" integration action to organization integration view. Refs UIORGS-441.
## [5.2.0](https://github.com/folio-org/ui-organizations/tree/v5.2.0) (2024-10-31)
[Full Changelog](https://github.com/folio-org/ui-organizations/compare/v5.1.1...v5.2.0)
diff --git a/src/OrganizationIntegration/OrganizationIntegrationView/OrganizationIntegrationView.js b/src/OrganizationIntegration/OrganizationIntegrationView/OrganizationIntegrationView.js
index f134e1e4..7634d867 100644
--- a/src/OrganizationIntegration/OrganizationIntegrationView/OrganizationIntegrationView.js
+++ b/src/OrganizationIntegration/OrganizationIntegrationView/OrganizationIntegrationView.js
@@ -1,7 +1,21 @@
-import React, { useCallback, useRef } from 'react';
+import cloneDeep from 'lodash/cloneDeep';
+import get from 'lodash/get';
+import omit from 'lodash/omit';
+import set from 'lodash/set';
import PropTypes from 'prop-types';
-import { FormattedMessage } from 'react-intl';
-import { useHistory, useParams, useLocation } from 'react-router';
+import {
+ useCallback,
+ useRef,
+} from 'react';
+import {
+ FormattedMessage,
+ useIntl,
+} from 'react-intl';
+import {
+ useHistory,
+ useParams,
+ useLocation,
+} from 'react-router-dom';
import { AppIcon } from '@folio/stripes/core';
import {
@@ -34,24 +48,32 @@ import {
useIntegrationConfig,
useIntegrationConfigMutation,
} from '../../common/hooks';
-import { isClaimingIntegration } from '../utils';
+import {
+ getDuplicateTimestamp,
+ isClaimingIntegration,
+} from '../utils';
import { IntegrationInfoView } from './IntegrationInfoView';
import { EdiView } from './EdiView';
import { FtpView } from './FtpView';
import { SchedulingView } from './SchedulingView';
+const CONFIG_NAME_PATH = 'exportTypeSpecificParameters.vendorEdiOrdersExportConfig.configName';
+
const OrganizationIntegrationView = ({ orgId }) => {
+ const intl = useIntl();
const history = useHistory();
const location = useLocation();
const accordionStatusRef = useRef();
const { id } = useParams();
const showCallout = useShowCallout();
+ const [isDuplicateConfirmation, toggleDuplicateConfirmation] = useModalToggle();
const [isRemoveConfirmation, toggleRemoveConfirmation] = useModalToggle();
const { integrationConfig, isLoading } = useIntegrationConfig(id);
const { acqMethods, isLoading: isAcqMethodsLoading } = useAcqMethods();
+ const configName = get(integrationConfig, CONFIG_NAME_PATH);
const isClaimingType = isClaimingIntegration(integrationConfig);
const onEdit = useCallback(
@@ -74,6 +96,10 @@ const OrganizationIntegrationView = ({ orgId }) => {
[history, location.search, orgId],
);
+ const {
+ mutateIntegrationConfig: createIntegrationConfig,
+ } = useIntegrationConfigMutation({ method: 'post' });
+
const { mutateIntegrationConfig } = useIntegrationConfigMutation({
method: 'delete',
onSuccess: () => {
@@ -90,6 +116,50 @@ const OrganizationIntegrationView = ({ orgId }) => {
},
});
+ const onDuplicate = useCallback(async () => {
+ toggleDuplicateConfirmation();
+
+ const integrationConfigCloned = omit(cloneDeep(integrationConfig), 'id');
+ const configNameCloned = `${configName} (${getDuplicateTimestamp({ intl })})`;
+
+ set(
+ integrationConfigCloned,
+ CONFIG_NAME_PATH,
+ intl.formatMessage(
+ { id: 'ui-organizations.integrationDetails.duplicate.name' },
+ { term: configNameCloned },
+ ),
+ );
+
+ try {
+ await createIntegrationConfig(integrationConfigCloned);
+
+ showCallout({
+ messageId: 'ui-organizations.integrationDetails.duplicate.success',
+ values: { term: configNameCloned },
+ });
+ history.push({
+ pathname: `/organizations/view/${orgId}`,
+ search: location.search,
+ });
+ } catch {
+ showCallout({
+ messageId: 'ui-organizations.integrationDetails.duplicate.error',
+ type: 'error',
+ });
+ }
+ }, [
+ configName,
+ createIntegrationConfig,
+ history,
+ integrationConfig,
+ intl,
+ location.search,
+ orgId,
+ showCallout,
+ toggleDuplicateConfirmation,
+ ]);
+
const onRemove = useCallback(
() => mutateIntegrationConfig(integrationConfig),
[integrationConfig, mutateIntegrationConfig],
@@ -111,6 +181,22 @@ const OrganizationIntegrationView = ({ orgId }) => {
+
+
+