Browse Source

Add actualStart actualEnd date in edit project

tags/Baseline_180220205_Frontend
Wayne 11 months ago
parent
commit
2bbfdb8d3b
1 changed files with 169 additions and 124 deletions
  1. +169
    -124
      src/components/CreateProject/CreateProject.tsx

+ 169
- 124
src/components/CreateProject/CreateProject.tsx View File

@@ -16,7 +16,6 @@ import TaskSetup from "./TaskSetup";
import StaffAllocation from "./StaffAllocation"; import StaffAllocation from "./StaffAllocation";
import Milestone from "./Milestone"; import Milestone from "./Milestone";
import { Task, TaskTemplate } from "@/app/api/tasks"; import { Task, TaskTemplate } from "@/app/api/tasks";
import AssignIcon from '@mui/icons-material/AssignmentIndOutlined';
import { import {
FieldErrors, FieldErrors,
FormProvider, FormProvider,
@@ -54,6 +53,7 @@ import {
} from "../Swal/CustomAlerts"; } from "../Swal/CustomAlerts";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { DELETE_PROJECT } from "@/middleware"; import { DELETE_PROJECT } from "@/middleware";
import { OUTPUT_DATE_FORMAT } from "@/app/utils/formatUtil";


export interface Props { export interface Props {
isEditMode: boolean; isEditMode: boolean;
@@ -137,8 +137,8 @@ const CreateProject: React.FC<Props> = ({
title: t("Do you want to submit?"), title: t("Do you want to submit?"),
confirmButtonText: t("Submit"), confirmButtonText: t("Submit"),
successTitle: t("Submit Success"), successTitle: t("Submit Success"),
errorTitle: t("Submit Fail")
}
errorTitle: t("Submit Fail"),
};
const [buttonData, setButtonData] = useState<{ const [buttonData, setButtonData] = useState<{
buttonName: string; buttonName: string;
title: string; title: string;
@@ -147,26 +147,23 @@ const CreateProject: React.FC<Props> = ({
errorTitle: string; errorTitle: string;
buttonText: string; buttonText: string;
buttonIcon: any; buttonIcon: any;
buttonColor: any
}> ({
buttonColor: any;
}>({
...defaultBtn, ...defaultBtn,
buttonText: t("Submit Project"), buttonText: t("Submit Project"),
buttonIcon: <Check />, buttonIcon: <Check />,
buttonColor : "success"
})

buttonColor: "success",
});


const disableChecking = () => { const disableChecking = () => {
return (loading ||
formProps.getValues("projectDeleted") === true ||
formProps.getValues("projectStatus")?.toLowerCase() ===
"deleted" ||
// !!formProps.getValues("projectActualStart") &&
!!(
formProps.getValues("projectStatus")?.toLowerCase() ===
"completed"
))
}
return (
loading ||
formProps.getValues("projectDeleted") === true ||
formProps.getValues("projectStatus")?.toLowerCase() === "deleted" ||
// !!formProps.getValues("projectActualStart") &&
!!(formProps.getValues("projectStatus")?.toLowerCase() === "completed")
);
};


const handleCancel = () => { const handleCancel = () => {
router.replace("/projects"); router.replace("/projects");
@@ -200,7 +197,11 @@ const CreateProject: React.FC<Props> = ({
let hasErrors = false; let hasErrors = false;


// Tab - Staff Allocation and Resource // Tab - Staff Allocation and Resource
if (data.totalManhour === null || data.totalManhour <= 0 || Number.isNaN(data.totalManhour)) {
if (
data.totalManhour === null ||
data.totalManhour <= 0 ||
Number.isNaN(data.totalManhour)
) {
formProps.setError("totalManhour", { formProps.setError("totalManhour", {
message: "totalManhour value is not valid", message: "totalManhour value is not valid",
type: "required", type: "required",
@@ -209,7 +210,11 @@ const CreateProject: React.FC<Props> = ({
hasErrors = true; hasErrors = true;
} }


if (data.ratePerManhour === null || data.ratePerManhour <= 0 || Number.isNaN(data.ratePerManhour)) {
if (
data.ratePerManhour === null ||
data.ratePerManhour <= 0 ||
Number.isNaN(data.ratePerManhour)
) {
formProps.setError("ratePerManhour", { formProps.setError("ratePerManhour", {
message: "ratePerManhour value is not valid", message: "ratePerManhour value is not valid",
type: "required", type: "required",
@@ -316,17 +321,28 @@ const CreateProject: React.FC<Props> = ({
data.taskTemplateId = data.taskTemplateId =
data.taskTemplateId === "All" ? undefined : data.taskTemplateId; data.taskTemplateId === "All" ? undefined : data.taskTemplateId;
const response = await saveProject(data); const response = await saveProject(data);
if ( if (
response.id > 0 && response.id > 0 &&
response.message?.toLowerCase() === "success" && response.message?.toLowerCase() === "success" &&
response.errorPosition === null response.errorPosition === null
) { ) {
successDialog(buttonName==="submit"? defaultBtn.successTitle : buttonData.successTitle, t).then(() => {
successDialog(
buttonName === "submit"
? defaultBtn.successTitle
: buttonData.successTitle,
t,
).then(() => {
router.replace("/projects"); router.replace("/projects");
}); });
} else { } else {
errorDialog(response.message ?? (buttonName==="submit"? defaultBtn.errorTitle : buttonData.errorTitle), t).then(() => {
errorDialog(
response.message ??
(buttonName === "submit"
? defaultBtn.errorTitle
: buttonData.errorTitle),
t,
).then(() => {
if ( if (
response.errorPosition !== null && response.errorPosition !== null &&
response.errorPosition === "projectCode" response.errorPosition === "projectCode"
@@ -337,34 +353,29 @@ const CreateProject: React.FC<Props> = ({
}); });
setTabIndex(0); setTabIndex(0);
} }
return false; return false;
}); });
} }
}
};


if (buttonName === "complete") { if (buttonName === "complete") {
submitDialogWithWarning(
handleSubmit,
t,
{ title: buttonData.title,
confirmButtonText: buttonData.confirmButtonText,
text: "<b style='color:red'>Completing project will restrict any further changes to the project, are you sure to proceed?</b>"
},)
submitDialogWithWarning(handleSubmit, t, {
title: buttonData.title,
confirmButtonText: buttonData.confirmButtonText,
text: "<b style='color:red'>Completing project will restrict any further changes to the project, are you sure to proceed?</b>",
});
} else if (buttonName === "submit") { } else if (buttonName === "submit") {
submitDialog(
handleSubmit,
t,
{ title: defaultBtn.title, confirmButtonText: defaultBtn.confirmButtonText },
);
submitDialog(handleSubmit, t, {
title: defaultBtn.title,
confirmButtonText: defaultBtn.confirmButtonText,
});
} else { } else {
submitDialog(
handleSubmit,
t,
{ title: buttonData.title, confirmButtonText: buttonData.confirmButtonText },
);
submitDialog(handleSubmit, t, {
title: buttonData.title,
confirmButtonText: buttonData.confirmButtonText,
});
} }

} catch (e) { } catch (e) {
setServerError(t("An error has occurred. Please try again later.")); setServerError(t("An error has occurred. Please try again later."));
} }
@@ -432,77 +443,86 @@ const CreateProject: React.FC<Props> = ({
const errors = formProps.formState.errors; const errors = formProps.formState.errors;


// auto calculate the total project manhour // auto calculate the total project manhour
const expectedProjectFee = formProps.watch("expectedProjectFee")
const ratePerManhour = formProps.watch("ratePerManhour")
const totalManhour = formProps.watch("totalManhour")
const [firstLoaded, setFirstLoaded] = useState(false)
const expectedProjectFee = formProps.watch("expectedProjectFee");
const ratePerManhour = formProps.watch("ratePerManhour");
const totalManhour = formProps.watch("totalManhour");
const [firstLoaded, setFirstLoaded] = useState(false);
React.useMemo(() => { React.useMemo(() => {
if ((firstLoaded && expectedProjectFee > 0 && ratePerManhour > 0)) {
console.log(ratePerManhour, formProps.watch("totalManhour"))
formProps.setValue("totalManhour", Math.ceil(expectedProjectFee / ratePerManhour))
if (firstLoaded && expectedProjectFee > 0 && ratePerManhour > 0) {
console.log(ratePerManhour, formProps.watch("totalManhour"));
formProps.setValue(
"totalManhour",
Math.ceil(expectedProjectFee / ratePerManhour),
);
} else { } else {
setFirstLoaded(true)
setFirstLoaded(true);
} }
}, [expectedProjectFee, ratePerManhour])
}, [expectedProjectFee, ratePerManhour]);


React.useMemo(() => { React.useMemo(() => {
if ((expectedProjectFee > 0 && ratePerManhour > 0) && (totalManhour === null || Number.isNaN(totalManhour) || totalManhour <= 0)) {
formProps.setValue("totalManhour", Math.ceil(expectedProjectFee / ratePerManhour))
if (
expectedProjectFee > 0 &&
ratePerManhour > 0 &&
(totalManhour === null || Number.isNaN(totalManhour) || totalManhour <= 0)
) {
formProps.setValue(
"totalManhour",
Math.ceil(expectedProjectFee / ratePerManhour),
);
} }
}, [totalManhour])
}, [totalManhour]);


const updateButtonData = () => { const updateButtonData = () => {
const status = formProps.getValues("projectStatus")?.toLowerCase(); const status = formProps.getValues("projectStatus")?.toLowerCase();


//Button Parameters// //Button Parameters//
switch (status) { switch (status) {
case "pending to start" :
case "pending to start":
setButtonData({ setButtonData({
buttonName: "start", buttonName: "start",
title : t("Do you want to start?"),
confirmButtonText : t("Start"),
successTitle : t("Start Success"),
errorTitle : t("Start Fail"),
buttonText : t("Start Project"),
buttonIcon : <PlayArrow />,
buttonColor: "success"
})
title: t("Do you want to start?"),
confirmButtonText: t("Start"),
successTitle: t("Start Success"),
errorTitle: t("Start Fail"),
buttonText: t("Start Project"),
buttonIcon: <PlayArrow />,
buttonColor: "success",
});
break; break;
case "on-going" :
case "on-going":
setButtonData({ setButtonData({
buttonName: "complete", buttonName: "complete",
title : t("Do you want to complete?"),
confirmButtonText : t("Complete"),
successTitle : t("Complete Success"),
errorTitle : t("Complete Fail"),
buttonText : t("Complete Project"),
buttonIcon : <DoneIcon />,
buttonColor: "info"
})
title: t("Do you want to complete?"),
confirmButtonText: t("Complete"),
successTitle: t("Complete Success"),
errorTitle: t("Complete Fail"),
buttonText: t("Complete Project"),
buttonIcon: <DoneIcon />,
buttonColor: "info",
});
break; break;
case "completed" :
case "completed":
setButtonData({ setButtonData({
buttonName: "reopen", buttonName: "reopen",
title : t("Do you want to reopen?"),
confirmButtonText : t("Reopen"),
successTitle : t("Reopen Success"),
errorTitle : t("Reopen Fail"),
buttonText : t("Reopen Project"),
buttonIcon : <AutorenewIcon />,
buttonColor: "secondary"
})
title: t("Do you want to reopen?"),
confirmButtonText: t("Reopen"),
successTitle: t("Reopen Success"),
errorTitle: t("Reopen Fail"),
buttonText: t("Reopen Project"),
buttonIcon: <AutorenewIcon />,
buttonColor: "secondary",
});
} }
}
};


useEffect(() => { useEffect(() => {
if (!isEditMode) { if (!isEditMode) {
setLoading(false); setLoading(false);
}
else if (formProps?.getValues("projectName")) {
} else if (formProps?.getValues("projectName")) {
setLoading(false); setLoading(false);
updateButtonData(); updateButtonData();
}}, [formProps]
)
}
}, [formProps]);


return ( return (
<> <>
@@ -512,43 +532,70 @@ const CreateProject: React.FC<Props> = ({
component="form" component="form"
onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)} onSubmit={formProps.handleSubmit(onSubmit, onSubmitError)}
> >
{isEditMode && !(formProps.getValues("projectDeleted") === true) && !loading && (
<Grid>
<Typography mb={2} variant="h4">{t("Edit Project")}: {`<${defaultInputs?.projectCode}>`}</Typography>
<Stack direction="row" gap={1}>
{/* {!formProps.getValues("projectActualStart") && ( */}
<Button
name={buttonData.buttonName}
type="submit"
variant="contained"
startIcon={buttonData.buttonIcon}
color={buttonData.buttonColor}
>
{t(buttonData.buttonText)}
</Button>
{!(
// formProps.getValues("projectActualStart") &&
// formProps.getValues("projectActualEnd")
(
formProps.getValues("projectStatus")?.toLowerCase() ===
"completed" ||
formProps.getValues("projectStatus")?.toLowerCase() ===
"deleted"
)
) &&
abilities.includes(DELETE_PROJECT) && (
{isEditMode &&
!(formProps.getValues("projectDeleted") === true) &&
!loading && (
<Grid>
<Typography mb={2} variant="h4">
{t("Edit Project")}: {`<${defaultInputs?.projectCode}>`}
</Typography>
{(defaultInputs?.projectActualEnd ||
defaultInputs?.projectActualStart) && (
<Stack mb={2}>
{defaultInputs?.projectActualStart && (
<Typography variant="caption">
{t("Project Start Date: {{date}}", {
date: dayjs(defaultInputs.projectActualStart).format(
OUTPUT_DATE_FORMAT,
),
})}
</Typography>
)}
{defaultInputs?.projectActualEnd && (
<Typography variant="caption">
{t("Project End Date: {{date}}", {
date: dayjs(defaultInputs.projectActualEnd).format(
OUTPUT_DATE_FORMAT,
),
})}
</Typography>
)}
</Stack>
)}
<Stack direction="row" gap={1}>
{/* {!formProps.getValues("projectActualStart") && ( */}
<Button <Button
variant="outlined"
startIcon={<Delete />}
color="error"
onClick={handleDelete}
name={buttonData.buttonName}
type="submit"
variant="contained"
startIcon={buttonData.buttonIcon}
color={buttonData.buttonColor}
> >
{t("Delete Project")}
{t(buttonData.buttonText)}
</Button> </Button>
)}
</Stack>
</Grid>
)}
{!(
// formProps.getValues("projectActualStart") &&
// formProps.getValues("projectActualEnd")
(
formProps.getValues("projectStatus")?.toLowerCase() ===
"completed" ||
formProps.getValues("projectStatus")?.toLowerCase() ===
"deleted"
)
) &&
abilities.includes(DELETE_PROJECT) && (
<Button
variant="outlined"
startIcon={<Delete />}
color="error"
onClick={handleDelete}
>
{t("Delete Project")}
</Button>
)}
</Stack>
</Grid>
)}
<Tabs <Tabs
value={tabIndex} value={tabIndex}
onChange={handleTabChange} onChange={handleTabChange}
@@ -658,9 +705,7 @@ const CreateProject: React.FC<Props> = ({
variant="contained" variant="contained"
startIcon={<Check />} startIcon={<Check />}
type="submit" type="submit"
disabled={
disableChecking()
}
disabled={disableChecking()}
> >
{isEditMode ? t("Save") : t("Confirm")} {isEditMode ? t("Save") : t("Confirm")}
</Button> </Button>


Loading…
Cancel
Save