From 60ac7359a8d11739e4b4f4643d232d83f1e04f0c Mon Sep 17 00:00:00 2001 From: Brijesh Date: Tue, 25 Jun 2024 14:34:14 -0700 Subject: [PATCH] copy plan implementation - copy plan functionality - added confirmation modal provider - refactored code --- src/components/App.js | 5 +- src/components/rangeUsePlanPage/ActionBtns.js | 1 - .../CopyPlanMenuItem.js | 18 +++++ .../CreateReplacementPlan.js | 1 - .../selectRangeUsePlanPage/ExtensionColumn.js | 52 +++++--------- .../PastePlanMenuItem.js | 61 +++++++++++++++++ .../selectRangeUsePlanPage/PlanActions.js | 16 +++++ .../PlanExtensionConfirmationModal.js | 60 ----------------- src/constants/api.js | 2 + src/constants/strings.js | 6 ++ src/providers/ConfrimationModalProvider.js | 67 +++++++++++++++++++ 11 files changed, 191 insertions(+), 98 deletions(-) create mode 100644 src/components/selectRangeUsePlanPage/CopyPlanMenuItem.js create mode 100644 src/components/selectRangeUsePlanPage/PastePlanMenuItem.js delete mode 100644 src/components/selectRangeUsePlanPage/PlanExtensionConfirmationModal.js create mode 100644 src/providers/ConfrimationModalProvider.js diff --git a/src/components/App.js b/src/components/App.js index 91998703..da155d0e 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -29,6 +29,7 @@ import EditableProvider from '../providers/EditableProvider'; import PlanProvider from '../providers/PlanProvider'; import theme from './theme'; import { SWRConfig } from 'swr'; +import { ConfirmationModalProvider } from '../providers/ConfrimationModalProvider'; const store = configureStore(); @@ -50,7 +51,9 @@ class App extends Component { - + + + diff --git a/src/components/rangeUsePlanPage/ActionBtns.js b/src/components/rangeUsePlanPage/ActionBtns.js index ec7a0438..1c1c6f6b 100644 --- a/src/components/rangeUsePlanPage/ActionBtns.js +++ b/src/components/rangeUsePlanPage/ActionBtns.js @@ -123,7 +123,6 @@ const ActionBtns = ({ ...permissionsOptions, }; - console.log(permissions); return ( <>
diff --git a/src/components/selectRangeUsePlanPage/CopyPlanMenuItem.js b/src/components/selectRangeUsePlanPage/CopyPlanMenuItem.js new file mode 100644 index 00000000..222293e7 --- /dev/null +++ b/src/components/selectRangeUsePlanPage/CopyPlanMenuItem.js @@ -0,0 +1,18 @@ +import React from 'react'; +import { MenuItem } from '@material-ui/core'; +import { saveDataInLocalStorage } from '../../utils'; + +const CopyPlanMenuItem = ({ planId, agreementId, menuText }) => { + return ( + { + saveDataInLocalStorage('copyPlanInfo', { planId, agreementId }); + e.stopPropagation(); + }} + > + {menuText} + + ); +}; + +export default CopyPlanMenuItem; diff --git a/src/components/selectRangeUsePlanPage/CreateReplacementPlan.js b/src/components/selectRangeUsePlanPage/CreateReplacementPlan.js index 6f835b9c..6a3d0bff 100644 --- a/src/components/selectRangeUsePlanPage/CreateReplacementPlan.js +++ b/src/components/selectRangeUsePlanPage/CreateReplacementPlan.js @@ -11,7 +11,6 @@ const CreateReplacementPlan = ({ planId }) => { onClick={async (e) => { e.stopPropagation(); const replacementPlan = await createReplacementPlan(planId); - console.log(replacementPlan); history.push(`${RANGE_USE_PLAN}/${replacementPlan.id}`); }} > diff --git a/src/components/selectRangeUsePlanPage/ExtensionColumn.js b/src/components/selectRangeUsePlanPage/ExtensionColumn.js index 2cd6cc07..959d5bd1 100644 --- a/src/components/selectRangeUsePlanPage/ExtensionColumn.js +++ b/src/components/selectRangeUsePlanPage/ExtensionColumn.js @@ -17,8 +17,8 @@ import * as API from '../../constants/api'; import DatePickerDialog from './DatePickerDialog'; import { PLAN_EXTENSION_STATUS } from '../../constants/variables'; import { Button } from 'formik-semantic-ui'; -import PlanExtensionConfirmationModal from './PlanExtensionConfirmationModal'; import { PLAN_EXTENSION_CONFIRMATION_QUESTION } from '../../constants/strings'; +import useConfirm from '../../providers/ConfrimationModalProvider'; export default function ExtensionColumn({ user, currentPage, agreement }) { const history = useHistory(); @@ -26,7 +26,7 @@ export default function ExtensionColumn({ user, currentPage, agreement }) { const [voting, setVoting] = useState(false); const [futureDate, setFutureDate] = useState(null); const [dialogOpen, setDialogOpen] = useState(false); - const [confirmationModal, setConfirmationModal] = useState({ open: false }); + const confirm = useConfirm(); const getPlanFutureDate = (planEndDate) => { if (isNaN(Date.parse(planEndDate))) planEndDate = new Date(); @@ -49,15 +49,12 @@ export default function ExtensionColumn({ user, currentPage, agreement }) { }; const handleRecommend = async (planId) => { - setConfirmationModal({ - open: true, - header: 'Confirm', - content: PLAN_EXTENSION_CONFIRMATION_QUESTION('recommend'), - onConfirm: () => { - recommendExtension(planId); - setConfirmationModal({ open: false }); - }, + const choice = await confirm({ + contentText: PLAN_EXTENSION_CONFIRMATION_QUESTION('recommend'), }); + if (choice) { + recommendExtension(planId); + } }; const extendPlan = async (planId) => { @@ -93,15 +90,12 @@ export default function ExtensionColumn({ user, currentPage, agreement }) { }; const handleApprove = async (planId) => { - setConfirmationModal({ - open: true, - header: 'Confirm', - content: PLAN_EXTENSION_CONFIRMATION_QUESTION('approve'), - onConfirm: () => { - approveExtension(planId); - setConfirmationModal({ open: false }); - }, + const choice = await confirm({ + contentText: PLAN_EXTENSION_CONFIRMATION_QUESTION('approve'), }); + if (choice) { + approveExtension(planId); + } }; const rejectExtension = async (planId) => { setVoting(true); @@ -120,15 +114,12 @@ export default function ExtensionColumn({ user, currentPage, agreement }) { }; const handleReject = async (planId) => { - setConfirmationModal({ - open: true, - header: 'Confirm', - content: PLAN_EXTENSION_CONFIRMATION_QUESTION('reject'), - onConfirm: () => { - rejectExtension(planId); - setConfirmationModal({ open: false }); - }, + const choice = await confirm({ + contentText: PLAN_EXTENSION_CONFIRMATION_QUESTION('reject'), }); + if (choice) { + rejectExtension(planId); + } }; const renderExtensionForDecisionMaker = (user, agreement) => { @@ -376,15 +367,6 @@ export default function ExtensionColumn({ user, currentPage, agreement }) { extendPlan(agreement.plan.id, futureDate); }} /> - { - setConfirmationModal({ open: false }); - }} - /> ); } diff --git a/src/components/selectRangeUsePlanPage/PastePlanMenuItem.js b/src/components/selectRangeUsePlanPage/PastePlanMenuItem.js new file mode 100644 index 00000000..c53a4658 --- /dev/null +++ b/src/components/selectRangeUsePlanPage/PastePlanMenuItem.js @@ -0,0 +1,61 @@ +import React from 'react'; +import { MenuItem } from '@material-ui/core'; +import { + axios, + getAuthHeaderConfig, + getDataFromLocalStorage, +} from '../../utils'; +import useConfirm from '../../providers/ConfrimationModalProvider'; +import { PLAN_PASTE_CONFIRMATION_QUESTION } from '../../constants/strings'; +import * as API from '../../constants/api'; +import { useToast } from '../../providers/ToastProvider'; +import { useHistory } from 'react-router-dom'; + +const PastePlanMenuItem = ({ agreementId, menuText, currentPage }) => { + const history = useHistory(); + const { errorToast } = useToast(); + const confirm = useConfirm(); + const sourcePlan = getDataFromLocalStorage('copyPlanInfo'); + if (!sourcePlan?.agreementId) { + return null; + } + return ( + { + if (!sourcePlan?.agreementId) { + errorToast('You need to copy a plan.'); + return; + } + const choice = await confirm({ + contentText: PLAN_PASTE_CONFIRMATION_QUESTION( + sourcePlan.agreementId, + agreementId, + ), + }); + if (choice) { + try { + const response = await axios.put( + API.COPY_PLAN(sourcePlan.planId, agreementId), + {}, + getAuthHeaderConfig(), + ); + history.push({ + pathname: `/range-use-plan/${response.data.planId}`, + state: { + page: currentPage, + prevSearch: location.search, + }, + }); + } catch (e) { + errorToast('Error creating plan'); + return; + } + } + }} + > + {menuText} + + ); +}; + +export default PastePlanMenuItem; diff --git a/src/components/selectRangeUsePlanPage/PlanActions.js b/src/components/selectRangeUsePlanPage/PlanActions.js index 9ac3cdfe..4de12285 100644 --- a/src/components/selectRangeUsePlanPage/PlanActions.js +++ b/src/components/selectRangeUsePlanPage/PlanActions.js @@ -8,9 +8,11 @@ import KeyboardArrowDown from '@material-ui/icons/KeyboardArrowDown'; import React from 'react'; import * as strings from '../../constants/strings'; import { PLAN_EXTENSION_STATUS } from '../../constants/variables'; +import CopyPlanMenuItem from './CopyPlanMenuItem'; import CreateReplacementPlan from './CreateReplacementPlan'; import NewPlanMenuItem from './NewPlanMenuItem'; import ViewPlanMenuItem from './ViewPlanMenuItem'; +import PastePlanMenuItem from './PastePlanMenuItem'; export default function PlanActions({ agreement, @@ -72,9 +74,23 @@ export default function PlanActions({ menuText={canEdit ? strings.EDIT : strings.VIEW} /> )} + {planId && ( + + )} {canCreatePlan && !planId && ( )} + {canCreatePlan && !planId && ( + + )} {[ PLAN_EXTENSION_STATUS.AGREEMENT_HOLDER_REJECTED, PLAN_EXTENSION_STATUS.STAFF_REJECTED, diff --git a/src/components/selectRangeUsePlanPage/PlanExtensionConfirmationModal.js b/src/components/selectRangeUsePlanPage/PlanExtensionConfirmationModal.js deleted file mode 100644 index 877bdbe5..00000000 --- a/src/components/selectRangeUsePlanPage/PlanExtensionConfirmationModal.js +++ /dev/null @@ -1,60 +0,0 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import { Modal, Icon } from 'semantic-ui-react'; -import { PrimaryButton } from '../common'; - -class PlanExtensionConfirmationModal extends Component { - static propTypes = { - header: PropTypes.string, - content: PropTypes.string, - open: PropTypes.bool.isRequired, - }; - - static defaultProps = { - header: '', - content: '', - }; - - onClose = () => { - this.props.onClose(); - }; - onConfirm = () => { - this.props.onConfirm(); - }; - - render() { - const { header, content, onClose, onConfirm, open } = this.props; - - return ( - e.stopPropagation()} - onClick={(e) => e.stopPropagation()} - closeIcon={} - > - - -
{content}
-
- - - Cancel - - - - Confirm - -
-
-
- ); - } -} - -export default PlanExtensionConfirmationModal; diff --git a/src/constants/api.js b/src/constants/api.js index 68693ebb..1a4cab3b 100644 --- a/src/constants/api.js +++ b/src/constants/api.js @@ -111,6 +111,8 @@ export const REPLACEMENT_PLAN = (planId) => export const REJECT_VOTE = (planId) => `/v1/plan/${planId}/extension/reject`; export const UPDATE_CONFIRMATION = (planId, confirmationId) => `/v1/plan/${planId}/confirmation/${confirmationId}`; +export const COPY_PLAN = (planId, agreementId) => + `/v1/plan/${planId}/copy/${agreementId}`; export const DISCARD_AMENDMENT = (planId) => `v1/plan/${planId}/discard-amendment`; diff --git a/src/constants/strings.js b/src/constants/strings.js index e8f5c7b9..8a2ae296 100644 --- a/src/constants/strings.js +++ b/src/constants/strings.js @@ -345,3 +345,9 @@ export const MANUAL_SIGNING_FAILUTE = export const PLAN_EXTENSION_CONFIRMATION_QUESTION = (action) => `Are you sure you want to ${action} extension?`; + +export const PLAN_PASTE_CONFIRMATION_QUESTION = ( + sourceAgreement, + destinationAgreement, +) => + `Are you sure you want to paste content of ${sourceAgreement} and create a new plan ${destinationAgreement}?`; diff --git a/src/providers/ConfrimationModalProvider.js b/src/providers/ConfrimationModalProvider.js new file mode 100644 index 00000000..e9c25612 --- /dev/null +++ b/src/providers/ConfrimationModalProvider.js @@ -0,0 +1,67 @@ +import { + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, +} from '@material-ui/core'; +import React, { + createContext, + useCallback, + useContext, + useRef, + useState, +} from 'react'; +import { PrimaryButton } from '../components/common'; +const ConfirmationModal = createContext(); + +export function ConfirmationModalProvider({ children }) { + const [state, setState] = useState({ isOpen: false }); + const fn = useRef(); + + const confirm = useCallback( + (data) => { + return new Promise((resolve) => { + setState({ ...data, isOpen: true }); + fn.current = (choice) => { + resolve(choice); + setState({ isOpen: false }); + }; + }); + }, + [setState], + ); + + return ( + + {children} + fn.current(false)} + aria-labelledby="alert-dialog-title" + aria-describedby="alert-dialog-description" + > + + {state.titleText || 'Confirm'} + + + + {state.contentText} + + + + fn.current(false)}> + {state.cancelText || 'Cancel'} + + fn.current(true)} autoFocus> + {state.confirmText || 'Confirm'} + + + + + ); +} + +export default function useConfirm() { + return useContext(ConfirmationModal); +}