Skip to content

Commit

Permalink
fix: warning message before project creation action is cancelled (#924)
Browse files Browse the repository at this point in the history
* feat: handleInput Change
Replaced handlecustomchange with handleinputchanges

* feat: SetIsUnsavedChanges added on first submit click

* feat: custom hook for handling form exit on create project

* feat: list of url to not block for form

* feat: isUnsavedChanges action added

* feat(CreateProject): prompt for blocking form exit
- Fixes Warning message before project creation action is cancelled #700
  • Loading branch information
varun2948 authored Oct 19, 2023
1 parent 8dd2831 commit 3a6c11d
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const ProjectDetailsForm = ({ flag }) => {
navigate('/upload-area');
};

const { handleSubmit, handleCustomChange, values, errors, checkValidationOnly }: any = useForm(
const { handleSubmit, handleChange, handleCustomChange, values, errors, checkValidationOnly }: any = useForm(
projectDetails,
submission,
CreateProjectValidation,
Expand Down Expand Up @@ -72,7 +72,10 @@ const ProjectDetailsForm = ({ flag }) => {
e.preventDefault();
}
};

const handleInputChanges = (e) => {
handleChange(e);
dispatch(CreateProjectActions.SetIsUnsavedChanges(true));
};
return (
<div className="fmtm-flex fmtm-gap-7 fmtm-flex-col lg:fmtm-flex-row">
<div className="fmtm-bg-white xl:fmtm-w-[17%] fmtm-px-5 fmtm-py-6">
Expand All @@ -92,45 +95,50 @@ const ProjectDetailsForm = ({ flag }) => {
<div className="fmtm-flex fmtm-flex-col fmtm-gap-6 md:fmtm-w-[50%]">
<InputTextField
id="name"
name="name"
label="Project Name"
value={values?.name}
onChange={(e) => handleCustomChange('name', e.target.value)}
onChange={handleInputChanges}
fieldType="text"
required
errorMsg={errors.name}
/>
<TextArea
id="short_description"
name="short_description"
label="Short Description"
rows={3}
value={values?.short_description}
onChange={(e) => handleCustomChange('short_description', e.target.value)}
onChange={handleInputChanges}
required
errorMsg={errors.short_description}
/>
<InputTextField
id="odk_central_url"
name="odk_central_url"
label="ODK Central URL"
value={values?.odk_central_url}
onChange={(e) => handleCustomChange('odk_central_url', e.target.value)}
onChange={handleChange}
fieldType="text"
required
errorMsg={errors.odk_central_url}
/>
<InputTextField
id="odk_central_user"
name="odk_central_user"
label="Central ODK Email/Username"
value={values?.odk_central_user}
onChange={(e) => handleCustomChange('odk_central_user', e.target.value)}
onChange={handleChange}
fieldType="text"
required
errorMsg={errors.odk_central_user}
/>
<InputTextField
id="odk_central_password"
name="odk_central_password"
label="Central ODK Password"
value={values?.odk_central_password}
onChange={(e) => handleCustomChange('odk_central_password', e.target.value)}
onChange={handleChange}
fieldType="password"
required
errorMsg={errors.odk_central_password}
Expand Down
2 changes: 2 additions & 0 deletions src/frontend/src/components/createnewproject/SplitTasks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ const SplitTasks = ({ flag, geojsonFile, setGeojsonFile, customLineUpload, custo
};

const submission = () => {
dispatch(CreateProjectActions.SetIsUnsavedChanges(false));

const blob = new Blob([JSON.stringify(dividedTaskGeojson || drawnGeojson)], { type: 'application/json' });

// Create a file object from the Blob
Expand Down
2 changes: 2 additions & 0 deletions src/frontend/src/constants/blockerUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const pathNotToBlock = ['/select-form', '/data-extract', '/split-tasks', '/upload-area', '/create-project'];
export default pathNotToBlock;
18 changes: 18 additions & 0 deletions src/frontend/src/hooks/Prompt.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import pathNotToBlock from '../constants/blockerUrl';
import { unstable_useBlocker as useBlocker } from 'react-router-dom';

function Prompt(props) {
const block = props.when;
useBlocker(({ nextLocation }) => {
console.log(nextLocation, 'next');
if (block && !pathNotToBlock.includes(nextLocation.pathname)) {
return !window.confirm(props.message);
}
return false;
});

return <div key={block} />;
}

export default Prompt;
5 changes: 5 additions & 0 deletions src/frontend/src/store/slices/CreateProjectSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const initialState: CreateProjectStateTypes = {
buildingGeojson: null,
lineGeojson: null,
createProjectValidations: {},
isUnsavedChanges: false,
};

const CreateProject = createSlice({
Expand Down Expand Up @@ -84,6 +85,7 @@ const CreateProject = createSlice({
state.drawnGeojson = null;
state.generateProjectLog = null;
state.generateProjectLogLoading = false;
state.isUnsavedChanges = false;
},
UploadAreaLoading(state, action) {
state.projectAreaLoading = action.payload;
Expand Down Expand Up @@ -201,6 +203,9 @@ const CreateProject = createSlice({
[action.payload.key]: action.payload.value,
};
},
SetIsUnsavedChanges(state, action) {
state.isUnsavedChanges = action.payload;
},
},
});

Expand Down
1 change: 1 addition & 0 deletions src/frontend/src/store/types/ICreateProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export type CreateProjectStateTypes = {
buildingGeojson: null;
lineGeojson: null;
createProjectValidations: {};
isUnsavedChanges: boolean;
};
export type ValidateCustomFormResponse = {
detail: { message: string; possible_reason: string };
Expand Down
7 changes: 5 additions & 2 deletions src/frontend/src/views/CreateNewProject.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ import SelectForm from '../components/createnewproject/SelectForm';
import { useLocation } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { CommonActions } from '.././store/slices/CommonSlice';

import { useAppSelector } from '../types/reduxTypes';
import Prompt from '../hooks/Prompt';
const CreateNewProject = () => {
const location = useLocation();
const dispatch = useDispatch();

const isUnsavedChanges = useAppSelector((state) => state.createproject.isUnsavedChanges);
const [geojsonFile, setGeojsonFile] = useState(null);
const [customLineUpload, setCustomLineUpload] = useState(null);
const [customPolygonUpload, setCustomPolygonUpload] = useState(null);
const [customFormFile, setCustomFormFile] = useState(null);

useEffect(() => {
switch (location.pathname) {
case '/create-project':
Expand Down Expand Up @@ -86,6 +87,8 @@ const CreateNewProject = () => {
return (
<div>
<CreateProjectHeader />
<Prompt when={isUnsavedChanges} message="Are you sure you want to leave, you have unsaved changes?" />

<div className="fmtm-min-h-[72vh] fmtm-bg-gray-100 fmtm-box-border fmtm-border-[1px] fmtm-border-t-white fmtm-border-t-[0px]">
<div className=" fmtm-w-full">
<div>
Expand Down

0 comments on commit 3a6c11d

Please sign in to comment.