272 lines
7.6 KiB
JavaScript
272 lines
7.6 KiB
JavaScript
import React, { useEffect, useState } from "react";
|
|
import Breadcrumb from "../common/Breadcrumb";
|
|
import Label from "../common/Label";
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
import { defaultJobValue, jobSchema } from "./ServiceProjectSchema";
|
|
import {
|
|
useCreateServiceProjectJob,
|
|
useJobTags,
|
|
useServiceProjectJobDetails,
|
|
useServiceProjects,
|
|
useUpdateServiceProjectJob,
|
|
} from "../../hooks/useServiceProject";
|
|
import { ITEMS_PER_PAGE } from "../../utils/constants";
|
|
import DatePicker from "../common/DatePicker";
|
|
import PmsEmployeeInputTag from "../common/PmsEmployeeInputTag";
|
|
import TagInput from "../common/TagInput";
|
|
import { localToUtc } from "../../utils/appUtils";
|
|
import SelectField from "../common/Forms/SelectField";
|
|
import {
|
|
AppFormController,
|
|
AppFormProvider,
|
|
useAppForm,
|
|
} from "../../hooks/appHooks/useAppForm";
|
|
import { useParams } from "react-router-dom";
|
|
import { useDispatch } from "react-redux";
|
|
import { useJobStatus } from "../../hooks/masterHook/useMaster";
|
|
import { useServiceProjectJobContext } from "./Jobs";
|
|
|
|
const ManageJob = ({ Job }) => {
|
|
const { setManageJob, setSelectedJob } = useServiceProjectJobContext();
|
|
const { projectId } = useParams();
|
|
const dispatch = useDispatch();
|
|
const methods = useAppForm({
|
|
resolver: zodResolver(jobSchema),
|
|
defaultValues: defaultJobValue,
|
|
});
|
|
const {
|
|
register,
|
|
control,
|
|
watch,
|
|
handleSubmit,
|
|
reset,
|
|
formState: { errors },
|
|
} = methods;
|
|
|
|
const {
|
|
data: JobTags,
|
|
isLoading: isTagLoading,
|
|
isError: isTagError,
|
|
error: tagError,
|
|
} = useJobTags();
|
|
const {
|
|
data: JobData,
|
|
isLoading: isJobLoading,
|
|
isError: isJobError,
|
|
error: jobError,
|
|
} = useServiceProjectJobDetails(Job);
|
|
|
|
const { data, isLoading, isError, error } = useJobStatus(
|
|
JobData?.status?.id,
|
|
projectId
|
|
);
|
|
const { mutate: CreateJob, isPending } = useCreateServiceProjectJob(() => {
|
|
reset();
|
|
});
|
|
const { mutate: UpdateJob, isPending: Updating } = useUpdateServiceProjectJob(
|
|
() => {
|
|
setManageJob({ isOpen: false, jobId: null });
|
|
setSelectedJob({ showCanvas: true, job: Job });
|
|
}
|
|
);
|
|
const onSubmit = (formData) => {
|
|
if (Job) {
|
|
const existingEmployeeIds = JobData?.assignees?.map((e) => e.id) || [];
|
|
|
|
const oldEmployees = JobData.assignees.map((e) => ({
|
|
employeeId: e.id,
|
|
isActive: formData.assignees.includes(e.id),
|
|
}));
|
|
|
|
const newEmployees = formData.assignees
|
|
.filter((id) => !existingEmployeeIds.includes(id))
|
|
.map((id) => ({
|
|
employeeId: id,
|
|
isActive: true,
|
|
}));
|
|
|
|
const updatedEmployees = [...oldEmployees, ...newEmployees];
|
|
|
|
const payload = [
|
|
{
|
|
op: "replace",
|
|
path: "/title",
|
|
value: formData.title,
|
|
},
|
|
{
|
|
op: "replace",
|
|
path: "/description",
|
|
value: formData.description,
|
|
},
|
|
{
|
|
op: "replace",
|
|
path: "/startDate",
|
|
value: localToUtc(formData.startDate) ?? JobData.startDate,
|
|
},
|
|
{
|
|
op: "replace",
|
|
path: "/dueDate",
|
|
value: localToUtc(formData.dueDate) ?? JobData.dueDate,
|
|
},
|
|
{
|
|
op: "replace",
|
|
path: "/tags",
|
|
value: formData.tags,
|
|
},
|
|
|
|
{
|
|
op: "replace",
|
|
path: "/assignees",
|
|
value: updatedEmployees,
|
|
},
|
|
{
|
|
op: "replace",
|
|
path: "/statusId",
|
|
value: formData.statusId,
|
|
},
|
|
];
|
|
UpdateJob({ id: Job, payload });
|
|
} else {
|
|
formData.assignees = formData.assignees.map((emp) => ({
|
|
employeeId: emp,
|
|
isActive: true,
|
|
}));
|
|
|
|
formData.startDate = localToUtc(formData.startDate);
|
|
formData.dueDate = localToUtc(formData.dueDate);
|
|
formData.projectId = projectId;
|
|
|
|
CreateJob(formData);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (!JobData && !Job) {
|
|
reset({
|
|
...defaultJobValue,
|
|
projectId: projectId,
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (!JobData || !Job) return;
|
|
|
|
const assignedEmployees = (JobData.assignees || []).map((e) => e.id);
|
|
|
|
reset({
|
|
title: JobData.title ?? "",
|
|
description: JobData.description ?? "",
|
|
projectId: JobData.project?.id ?? projectId,
|
|
assignees: assignedEmployees,
|
|
startDate: JobData.startDate ?? null,
|
|
dueDate: JobData.dueDate ?? null,
|
|
tags: JobData.tags ?? [],
|
|
statusId: JobData.status.id,
|
|
});
|
|
}, [JobData, Job, projectId]);
|
|
return (
|
|
<div className="container">
|
|
<AppFormProvider {...methods}>
|
|
<form className="row text-start" onSubmit={handleSubmit(onSubmit)}>
|
|
<div className="col-12 col-md-12 mb-2 ">
|
|
<Label required>Title</Label>
|
|
<input
|
|
type="text"
|
|
{...register("title")}
|
|
className="form-control form-control"
|
|
placeholder="Enter Title"
|
|
/>
|
|
</div>
|
|
|
|
<div className="col-12 col-md-6 mb-2 mb-md-4">
|
|
<Label required>Start Date</Label>
|
|
<DatePicker
|
|
name="startDate"
|
|
control={control}
|
|
placeholder="DD-MM-YYYY"
|
|
className="w-full"
|
|
size="md"
|
|
/>
|
|
</div>
|
|
<div className="col-12 col-md-6 mb-2 mb-md-4">
|
|
<Label required>Due Date</Label>
|
|
<DatePicker
|
|
control={control}
|
|
minDate={watch("startDate")}
|
|
name="dueDate"
|
|
className="w-full"
|
|
size="md"
|
|
/>
|
|
</div>
|
|
<div className="col-12 col-md-6 mb-2 mb-md-4">
|
|
<Label required>Select Employee</Label>
|
|
<PmsEmployeeInputTag
|
|
control={control}
|
|
name="assignees"
|
|
placeholder="Select employee"
|
|
/>
|
|
</div>
|
|
{Job && (
|
|
<div className="col-12 col-md-6 mb-2 mb-md-4">
|
|
<AppFormController
|
|
name="statusId"
|
|
control={control}
|
|
render={({ field }) => (
|
|
<SelectField
|
|
label="Select Status"
|
|
options={data ?? []}
|
|
placeholder="Choose a Status"
|
|
required
|
|
labelKeyKey="name"
|
|
valueKeyKey="id"
|
|
value={field.value}
|
|
onChange={field.onChange}
|
|
isLoading={isLoading}
|
|
className="m-0"
|
|
/>
|
|
)}
|
|
/>
|
|
|
|
{errors.statusId && (
|
|
<small className="danger-text">{errors.statusId.message}</small>
|
|
)}
|
|
</div>
|
|
)}
|
|
<div className="col-12 col-md-6 mb-2 mb-md-4">
|
|
<TagInput
|
|
options={JobTags?.data}
|
|
name="tags"
|
|
label="Tag"
|
|
placeholder="Enter Tag"
|
|
required
|
|
/>
|
|
</div>
|
|
<div className="col-12">
|
|
<Label required>Description</Label>
|
|
<textarea
|
|
{...register("description")}
|
|
className="form-control form-control-sm"
|
|
rows={3}
|
|
/>
|
|
</div>
|
|
<div className="d-flex flex-row-reverse my-4">
|
|
<button
|
|
type="submit"
|
|
className="btn btn-sm btn-primary"
|
|
disabled={isPending || Updating}
|
|
>
|
|
{isPending || Updating
|
|
? "Please wait..."
|
|
: Job
|
|
? "Update"
|
|
: "Submit"}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</AppFormProvider>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ManageJob;
|