Skip to content

Commit

Permalink
Merge pull request #2403 from Josephalexantony-aot/Feature/FWF-4012-W…
Browse files Browse the repository at this point in the history
…orkflow-migration

FWF-4012:[Feature] - Migration-UI and API integration
  • Loading branch information
arun-s-aot authored Dec 9, 2024
2 parents 58d9c10 + 48662f8 commit a2344e1
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 63 deletions.
1 change: 1 addition & 0 deletions forms-flow-web/src/apiManager/endpoints/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const API = {
FORM_IMPORT: `${WEB_BASE_URL}/import`,
PUBLISH: `${WEB_BASE_URL}/form/<mapper_id>/publish`,
UN_PUBLISH: `${WEB_BASE_URL}/form/<mapper_id>/unpublish`,
PROCESS_MIGRATE: `${WEB_BASE_URL}/process/migrate`,
FORM_HISTORY: `${WEB_BASE_URL}/form/form-history`,
LANG_UPDATE: `${WEB_BASE_URL}/user/locale`,
FORM_PROCESSES: `${WEB_BASE_URL}/form/formid`,
Expand Down
5 changes: 5 additions & 0 deletions forms-flow-web/src/apiManager/services/FormServices.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ export const formUpdate = (form_id,formData) => {
return RequestService.httpPUTRequest(`${API.FORM_DESIGN}/${form_id}`, formData);
};

export const processMigrate = (migrationData) => {
return RequestService.httpPOSTRequest(API.PROCESS_MIGRATE, migrationData );
};


export const getFormHistory = (form_id, page = null, limit = null) => {
let url = `${API.FORM_HISTORY}/${form_id}`;
if (page !== null && limit !== null) {
Expand Down
21 changes: 13 additions & 8 deletions forms-flow-web/src/apiManager/services/processServices.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,16 +295,21 @@ export const getFormProcesses = (formId, ...rest) => {
};
};

export const getProcessDetails = (processKey, tenant_key) => {
const api = API.GET_PROCESS_XML;
let url = replaceUrl(api, "<process_key>", processKey);
export const getProcessDetails = (processKey, tenant_key = null, mapperId = null) => {
const api = API.GET_PROCESS_XML;
let url = replaceUrl(api, "<process_key>", processKey);

if (tenant_key) {
url = url + `?tenantId=${tenant_key}`;
}
const params = [];
if (tenant_key) params.push(`tenantId=${tenant_key}`);
if (mapperId) params.push(`mapperId=${mapperId}`);

if (params.length) {
url += `?${params.join("&")}`;
}

return RequestService.httpGETRequest(url);
};

return RequestService.httpGETRequest(url);
};


export const updateProcess = ({id,data,type}) => {
Expand Down
161 changes: 137 additions & 24 deletions forms-flow-web/src/components/Form/EditForm/FlowEdit.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, {
useImperativeHandle,
useRef,
useState,
useEffect
} from "react";
import {
CustomButton,
Expand All @@ -18,6 +19,8 @@ import { useMutation } from "react-query";
import { setProcessData } from "../../../actions/processActions.js";
import BpmnEditor from "../../Modeler/Editors/BpmnEditor/BpmEditor";
import LoadingOverlay from "react-loading-overlay-ts";
import { push } from "connected-react-router";
import { processMigrate } from "../../../apiManager/services/FormServices";
import {
updateProcess,
getProcessHistory,
Expand All @@ -34,7 +37,9 @@ import userRoles from "../../../constants/permissions.js";
import BPMNViewer from "../../BPMN/BpmnViewer.js";
import TaskVariableModal from "../../Modals/TaskVariableModal.js";

const FlowEdit = forwardRef(({ isPublished = false, CategoryType, setWorkflowIsChanged }, ref) => {
const FlowEdit = forwardRef(({ isPublished = false, CategoryType,
setWorkflowIsChanged, migration, setMigration, redirectUrl,
isMigrated = true, mapperId }, ref) => {
const { t } = useTranslation();
const dispatch = useDispatch();
const bpmnRef = useRef();
Expand All @@ -47,8 +52,11 @@ const FlowEdit = forwardRef(({ isPublished = false, CategoryType, setWorkflowIsC
const { createDesigns } = userRoles();
const [showTaskVarModal, setShowTaskVarModal] = useState(false);
const [isWorkflowChanged, setIsWorkflowChanged] = useState(false);
const formData = useSelector((state) => state.form?.form || {});
/* --------- fetching all process history when click history button --------- */
const formData = useSelector((state) => state.form?.form || {});
const [isMigrationChecked, setIsMigrationChecked] = useState(false);
const [showMigrationModal, setShowMigrationModal] = useState(false);
const [isMigraionLoading, setIsMigraionLoading] = useState(false);
/* --------- fetching all process history when click history button --------- */
const {
data: { data: historiesData } = {}, // response data destructured
mutate: fetchHistories, // mutate function used to call the api function and here mutate renamed to fetch histories
Expand All @@ -75,16 +83,42 @@ const FlowEdit = forwardRef(({ isPublished = false, CategoryType, setWorkflowIsC
const handleDiscardModal = () => setShowDiscardModal(!showDiscardModal);
const handleToggleHistoryModal = () => setShowHistoryModal(!showHistoryModal);

const enableWorkflowChange = ()=>{
const enableWorkflowChange = () => {
setIsWorkflowChanged(true);
setWorkflowIsChanged(true); // this function passed from parent
};

const disableWorkflowChange = ()=>{
const disableWorkflowChange = () => {
setIsWorkflowChanged(false);
setWorkflowIsChanged(false); // this function passed from parent
};

useEffect(() => {
if (migration) {
setShowMigrationModal(true);
setMigration(false);
}
}, [migration]);

const handleMigraion = () => {
setIsMigraionLoading(true);
const migrationData = {
mapperId: mapperId,
processKey: processData.processKey
};
processMigrate(migrationData)
.then(() => {
dispatch(push(`${redirectUrl}formflow`));
})
.catch((err) => {
console.log(err);
})
.finally(() => {
setIsMigraionLoading(false);
setShowMigrationModal(false);
});
};

//handle discard changes
const handleDiscardConfirm = () => {
if (bpmnRef.current) {
Expand All @@ -108,6 +142,17 @@ const FlowEdit = forwardRef(({ isPublished = false, CategoryType, setWorkflowIsC
const loadMoreBtnAction = () => {
fetchHistories({ parentProcessKey: processData.parentProcessKey });
};
const handleSaveFlowClick = () => {
//On clicking the save flow it checks if the current flow has already been migrated, if not, it tries to migrate first.
if (shouldShowMigrationModal()) {
setShowMigrationModal(true);
} else {
saveFlow();
}
};
const shouldShowMigrationModal = () => {
return !isMigrated;
};

const saveFlow = async (showToast = true) => {
try {
Expand Down Expand Up @@ -144,7 +189,7 @@ const FlowEdit = forwardRef(({ isPublished = false, CategoryType, setWorkflowIsC

useImperativeHandle(ref, () => ({
saveFlow,
handleImport: (xml)=>{bpmnRef.current?.handleImport(xml);}
handleImport: (xml) => { bpmnRef.current?.handleImport(xml); }
}));
const handlePreviewAndVariables = () => {
setShowTaskVarModal(true);
Expand All @@ -153,6 +198,10 @@ const FlowEdit = forwardRef(({ isPublished = false, CategoryType, setWorkflowIsC
setShowTaskVarModal(false);
};

const handleCloseMigration = () => {
setShowMigrationModal(false);
};

return (
<>
<Card>
Expand Down Expand Up @@ -205,7 +254,7 @@ const FlowEdit = forwardRef(({ isPublished = false, CategoryType, setWorkflowIsC
size="md"
className="mx-2"
label={t("Save Flow")}
onClick={saveFlow}
onClick={handleSaveFlowClick}
disabled={isPublished || !isWorkflowChanged}
dataTestid="save-flow-layout"
ariaLabel={t("Save Flow Layout")}
Expand All @@ -231,24 +280,83 @@ const FlowEdit = forwardRef(({ isPublished = false, CategoryType, setWorkflowIsC
text={t("Loading...")}
>
<div className="flow-builder">
{!createDesigns ? (
{!createDesigns ? (
<BPMNViewer bpmnXml={processData?.processData || null} />
) : (
<BpmnEditor
onChange={enableWorkflowChange} //handled is workflow changed or not
ref={bpmnRef}
setLintErrors={setLintErrors}
bpmnXml={
isReverted
? historyData?.processData
: processData?.processData
}
/>
)}
</div>
) : (
<BpmnEditor
onChange={enableWorkflowChange} //handled is workflow changed or not
ref={bpmnRef}
setLintErrors={setLintErrors}
bpmnXml={
isReverted
? historyData?.processData
: processData?.processData
}
/>
)}
</div>
</LoadingOverlay>
</Card.Body>
</Card>
{showMigrationModal && <ConfirmModal
show={showMigrationModal}
title={t("***Migration Notice***")}
message={
<div>
<div className="message-primary mb-3">
{t(`We have switched to a new 1-to-1 relationship structure,
where 1 form contains both the layout (visual of the form)
and the flow (the actions that get executed after the
form's submission). Due to this 1-to-1 relationship,
each layout (previously known as "form") will have a
flow associated with it, so you cannot reuse flows -
one flow cannot be executed by different forms.`)}
</div>
<div className="message-primary mb-3">
{t(`This form shares a flow with a few other forms. As this is
not allowed under the new structure, we will permanently
link this flow with this form. For the other forms reusing
this flow, we will automatically duplicate the flow. When
flows are duplicated, their history is not carried over.
You need to pick which form keeps the history and which
forms get duplicates without history.`)}
</div>
<div className="message-primary mb-3">
{t(`If this is the form you wish to keep the flow's history with,
confirm below. If this is not the form, then hit cancel, find
the form you want, make a minor change, press "Save Layout"
or "Save Flow," and confirm it there.`)}
</div>
<div className="d-flex justify-content-between align-items-center">
<label className="message-primary">
{t(`This is the form that will keep the current
flow and its history.`)}
{" "}
</label>
<div className="dashed-line"></div>
<div className="custom-checkbox d-flex justify-content-between align-items-center gap-2">
<input
type="checkbox"
className="form-check-input mb-2"
onChange={() => setIsMigrationChecked(prev => !prev)}
checked={isMigrationChecked}
/>
<label className="message-primary">{t(`I confirm`)}</label>
</div>
</div>
</div >
}
primaryBtnDisable={!isMigrationChecked}
messageSecondary={null} // You can set this to `null` or remove it entirely if unused
primaryBtnAction={handleMigraion}
onClose={handleCloseMigration}
primaryBtnText={t("Link this form that will keep the current flow and its history")}
secondaryBtnText={t("Cancel")}
secondayBtnAction={handleCloseMigration}
buttonLoading={isMigraionLoading}
size="sm"
/>}

<HistoryModal
show={showHistoryModal}
onClose={handleToggleHistoryModal}
Expand All @@ -267,9 +375,9 @@ const FlowEdit = forwardRef(({ isPublished = false, CategoryType, setWorkflowIsC
form={formData}
showTaskVarModal={showTaskVarModal}
onClose={CloseTaskVarModal}
isPublished={isPublished}
isPublished={isPublished}
/>
)}
)}
</>
);
});
Expand All @@ -279,7 +387,12 @@ FlowEdit.propTypes = {
WORKFLOW: PropTypes.string.isRequired,
}).isRequired,
isPublished: PropTypes.bool.isRequired,
setWorkflowIsChanged: PropTypes.func
setWorkflowIsChanged: PropTypes.func,
migration: PropTypes.bool,
setMigration: PropTypes.func,
redirectUrl: PropTypes.string,
isMigrated: PropTypes.bool,
mapperId: PropTypes.string
};

export default FlowEdit;
Loading

0 comments on commit a2344e1

Please sign in to comment.