added confirmation modal inside serviceproject employee list
This commit is contained in:
parent
8761c128e6
commit
b68f8306fd
@ -54,6 +54,7 @@ const ManageJob = ({ Job }) => {
|
|||||||
isError: isJobError,
|
isError: isJobError,
|
||||||
error: jobError,
|
error: jobError,
|
||||||
} = useServiceProjectJobDetails(Job);
|
} = useServiceProjectJobDetails(Job);
|
||||||
|
// const {} = useSer
|
||||||
|
|
||||||
const { mutate: CreateJob, isPending } = useCreateServiceProjectJob(() => {
|
const { mutate: CreateJob, isPending } = useCreateServiceProjectJob(() => {
|
||||||
reset();
|
reset();
|
||||||
@ -67,7 +68,7 @@ const ManageJob = ({ Job }) => {
|
|||||||
|
|
||||||
formData.startDate = localToUtc(formData.startDate);
|
formData.startDate = localToUtc(formData.startDate);
|
||||||
formData.dueDate = localToUtc(formData.dueDate);
|
formData.dueDate = localToUtc(formData.dueDate);
|
||||||
CreateJob(formData)
|
CreateJob(formData);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -80,7 +81,7 @@ const ManageJob = ({ Job }) => {
|
|||||||
assignees: assignedEmployees,
|
assignees: assignedEmployees,
|
||||||
startDate: JobData.startDate ?? null,
|
startDate: JobData.startDate ?? null,
|
||||||
dueDate: JobData.dueDate ?? null,
|
dueDate: JobData.dueDate ?? null,
|
||||||
tags: [],
|
tags: JobData.tags ?? [],
|
||||||
});
|
});
|
||||||
}, [JobData]);
|
}, [JobData]);
|
||||||
|
|
||||||
@ -102,9 +103,9 @@ const ManageJob = ({ Job }) => {
|
|||||||
control={control}
|
control={control}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<SelectField
|
<SelectField
|
||||||
label="Project"
|
label="Status"
|
||||||
options={data?.data}
|
options={data?.data}
|
||||||
placeholder="Choose a Project"
|
placeholder="Choose a Status"
|
||||||
required
|
required
|
||||||
labelKeyKey="name"
|
labelKeyKey="name"
|
||||||
valueKeyKey="id"
|
valueKeyKey="id"
|
||||||
@ -121,7 +122,8 @@ const ManageJob = ({ Job }) => {
|
|||||||
name="startDate"
|
name="startDate"
|
||||||
control={control}
|
control={control}
|
||||||
placeholder="DD-MM-YYYY"
|
placeholder="DD-MM-YYYY"
|
||||||
className="w-full form-control-md"
|
className="w-full"
|
||||||
|
size="md"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12 col-md-6 mb-2 mb-md-4">
|
<div className="col-12 col-md-6 mb-2 mb-md-4">
|
||||||
@ -131,6 +133,7 @@ const ManageJob = ({ Job }) => {
|
|||||||
minDate={watch("startDate")}
|
minDate={watch("startDate")}
|
||||||
name="dueDate"
|
name="dueDate"
|
||||||
className="w-full"
|
className="w-full"
|
||||||
|
size="md"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12 col-md-6 mb-2 mb-md-4">
|
<div className="col-12 col-md-6 mb-2 mb-md-4">
|
||||||
|
|||||||
@ -3,15 +3,9 @@ import { PROJECT_STATUS } from "../../utils/constants";
|
|||||||
|
|
||||||
//#region Service Project
|
//#region Service Project
|
||||||
export const projectSchema = z.object({
|
export const projectSchema = z.object({
|
||||||
name: z
|
name: z.string().trim().min(1, "Name is required"),
|
||||||
.string()
|
|
||||||
.trim()
|
|
||||||
.min(1, "Name is required"),
|
|
||||||
|
|
||||||
shortName: z
|
shortName: z.string().trim().min(1, "Short name is required"),
|
||||||
.string()
|
|
||||||
.trim()
|
|
||||||
.min(1, "Short name is required"),
|
|
||||||
|
|
||||||
clientId: z.string().trim().min(1, { message: "Client is required" }),
|
clientId: z.string().trim().min(1, { message: "Client is required" }),
|
||||||
|
|
||||||
@ -38,10 +32,7 @@ export const projectSchema = z.object({
|
|||||||
.min(7, "Invalid phone number")
|
.min(7, "Invalid phone number")
|
||||||
.max(15, "Phone number too long"),
|
.max(15, "Phone number too long"),
|
||||||
|
|
||||||
contactEmail: z
|
contactEmail: z.string().trim().email("Invalid email address"),
|
||||||
.string()
|
|
||||||
.trim()
|
|
||||||
.email("Invalid email address"),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const defaultProjectValues = {
|
export const defaultProjectValues = {
|
||||||
|
|||||||
@ -15,17 +15,21 @@ import {
|
|||||||
} from "../../../hooks/useServiceProject";
|
} from "../../../hooks/useServiceProject";
|
||||||
import { SpinnerLoader } from "../../common/Loader";
|
import { SpinnerLoader } from "../../common/Loader";
|
||||||
import showToast from "../../../services/toastService";
|
import showToast from "../../../services/toastService";
|
||||||
|
import ConfirmModal from "../../common/ConfirmModal";
|
||||||
|
|
||||||
const ServiceProjectTeamAllocation = () => {
|
const ServiceProjectTeamAllocation = () => {
|
||||||
const { isOpen, onClose, data: Project } = useModal("ServiceTeamAllocation");
|
const { isOpen, onClose, data: Project } = useModal("ServiceTeamAllocation");
|
||||||
const [deletingId, setSeletingId] = useState(null);
|
const [deletingEmp, setSeletingEmp] = useState({
|
||||||
|
employee: null,
|
||||||
|
isOpen: false,
|
||||||
|
});
|
||||||
const {
|
const {
|
||||||
data: Team,
|
data: Team,
|
||||||
isLoading: isTeamLoading,
|
isLoading: isTeamLoading,
|
||||||
isError: isTeamError,
|
isError: isTeamError,
|
||||||
error: teamError,
|
error: teamError,
|
||||||
} = useServiceProjectTeam(Project?.projectId, true);
|
} = useServiceProjectTeam(Project?.projectId, true);
|
||||||
const [isManageEmployee, setIsMenageEmployee] = useState(false);
|
const [isAddEmployee, setIsAddEmployee] = useState(false);
|
||||||
const [nonDuplicateEmployee, setNonDuplicateEmployee] = useState([]);
|
const [nonDuplicateEmployee, setNonDuplicateEmployee] = useState([]);
|
||||||
const [selectedTeam, setSelectTeam] = useState(null);
|
const [selectedTeam, setSelectTeam] = useState(null);
|
||||||
const [selectedEmployees, setSelectedEmployees] = useState([]);
|
const [selectedEmployees, setSelectedEmployees] = useState([]);
|
||||||
@ -44,7 +48,10 @@ const ServiceProjectTeamAllocation = () => {
|
|||||||
const { mutate: AllocationTeam, isPending } = useAllocationServiceProjectTeam(
|
const { mutate: AllocationTeam, isPending } = useAllocationServiceProjectTeam(
|
||||||
() => {
|
() => {
|
||||||
setSelectedEmployees([]);
|
setSelectedEmployees([]);
|
||||||
setSeletingId(null);
|
setSeletingEmp({
|
||||||
|
employee: null,
|
||||||
|
isOpen: false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -61,7 +68,6 @@ const ServiceProjectTeamAllocation = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleDeAllocation = (emp) => {
|
const handleDeAllocation = (emp) => {
|
||||||
setSeletingId(emp?.id);
|
|
||||||
let payload = [
|
let payload = [
|
||||||
{
|
{
|
||||||
projectId: Project?.projectId,
|
projectId: Project?.projectId,
|
||||||
@ -76,7 +82,7 @@ const ServiceProjectTeamAllocation = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedEmployees?.length > 0 && !selectedTeam) {
|
if (selectedEmployees?.length > 0 && !selectedTeam) {
|
||||||
handleRemove(selectedEmployees[0]?.id);
|
handleRemove(selectedEmployees[0]?.id);
|
||||||
showToast(`Please select a first role`, "warning");
|
showToast(`Please select a role`, "warning");
|
||||||
}
|
}
|
||||||
if (Team?.length > 0 && selectedEmployees?.length > 0) {
|
if (Team?.length > 0 && selectedEmployees?.length > 0) {
|
||||||
setNonDuplicateEmployee((prev) => {
|
setNonDuplicateEmployee((prev) => {
|
||||||
@ -103,18 +109,29 @@ const ServiceProjectTeamAllocation = () => {
|
|||||||
}, [Team, selectedEmployees, selectedTeam]);
|
}, [Team, selectedEmployees, selectedTeam]);
|
||||||
|
|
||||||
const TeamAllocationBody = (
|
const TeamAllocationBody = (
|
||||||
|
<>
|
||||||
|
<ConfirmModal
|
||||||
|
type="delete"
|
||||||
|
header="Remove Employee"
|
||||||
|
message="Are you sure you want remove?"
|
||||||
|
onSubmit={handleDeAllocation}
|
||||||
|
onClose={() => setSeletingEmp({ employee: null, isOpen: false })}
|
||||||
|
loading={isPending}
|
||||||
|
paramData={deletingEmp.employee}
|
||||||
|
isOpen={deletingEmp.isOpen}
|
||||||
|
/>
|
||||||
<div className=" text-start">
|
<div className=" text-start">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="d-flex justify-content-end">
|
<div className="d-flex justify-content-end">
|
||||||
<button
|
{!isAddEmployee && <button
|
||||||
className="btn btn-sm btn-primary"
|
className="btn btn-sm btn-primary"
|
||||||
onClick={() => setIsMenageEmployee(!isManageEmployee)}
|
onClick={() => setIsAddEmployee(!isAddEmployee)}
|
||||||
>
|
>
|
||||||
<i className="bx bx-plus-circle me-2"></i>Add Employee
|
<i className="bx bx-plus-circle me-2"></i>Add Employee
|
||||||
</button>
|
</button>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{isManageEmployee && (
|
{isAddEmployee && (
|
||||||
<>
|
<>
|
||||||
<div className="col-12 col-md-6 mb-3">
|
<div className="col-12 col-md-6 mb-3">
|
||||||
<SelectField
|
<SelectField
|
||||||
@ -149,15 +166,24 @@ const ServiceProjectTeamAllocation = () => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{selectedEmployees?.length > 0 && isManageEmployee && (
|
{ isAddEmployee && (
|
||||||
<div className="d-flex justify-content-end">
|
<div className="d-flex justify-content-end">
|
||||||
{" "}
|
{" "}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn btn-label-secondary btn-sm me-2"
|
||||||
|
onClick={()=>setIsAddEmployee(false)}
|
||||||
|
aria-label="Close"
|
||||||
|
disabled={isPending }
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
className="btn btn-sm btn-primary"
|
className="btn btn-sm btn-primary"
|
||||||
disabled={isPending}
|
disabled={isPending}
|
||||||
onClick={AssignEmployee}
|
onClick={AssignEmployee}
|
||||||
>
|
>
|
||||||
{isPending && !deletingId ? "Please wait..." : "Save"}
|
{isPending && !deletingEmp.employee ? "Please wait..." : "Save"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -188,13 +214,15 @@ const ServiceProjectTeamAllocation = () => {
|
|||||||
</td>
|
</td>
|
||||||
<td>{emp?.teamRole?.name}</td>
|
<td>{emp?.teamRole?.name}</td>
|
||||||
<td className="">
|
<td className="">
|
||||||
{deletingId === emp.id ? (
|
{deletingEmp?.emplyee?.id === emp.id && isPending ? (
|
||||||
<div className="spinner-border spinner-border-sm "></div>
|
<div className="spinner-border spinner-border-sm "></div>
|
||||||
) : (
|
) : (
|
||||||
<span disabled={isPending}>
|
<span disabled={isPending}>
|
||||||
<i
|
<i
|
||||||
className="bx bx-trash bx-sm text-danger cursor-pointer"
|
className="bx bx-trash bx-sm text-danger cursor-pointer"
|
||||||
onClick={() => handleDeAllocation(emp)}
|
onClick={() =>
|
||||||
|
setSeletingEmp({ employee: emp, isOpen: true })
|
||||||
|
}
|
||||||
></i>
|
></i>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
@ -212,7 +240,10 @@ const ServiceProjectTeamAllocation = () => {
|
|||||||
) : (
|
) : (
|
||||||
<div className="bg-light-secondary py-3 w-50 m-auto my-2">
|
<div className="bg-light-secondary py-3 w-50 m-auto my-2">
|
||||||
<i className="bx bx-box bx-md text-primary"></i>
|
<i className="bx bx-box bx-md text-primary"></i>
|
||||||
<p className="fw-medium mt-3"> Please Add a Employee </p>
|
<p className="fw-medium mt-3">
|
||||||
|
{" "}
|
||||||
|
Please Add a Employee{" "}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
@ -222,6 +253,7 @@ const ServiceProjectTeamAllocation = () => {
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { useController } from "react-hook-form";
|
|||||||
const DatePicker = ({
|
const DatePicker = ({
|
||||||
name,
|
name,
|
||||||
control,
|
control,
|
||||||
|
size="sm",
|
||||||
placeholder = "DD-MM-YYYY",
|
placeholder = "DD-MM-YYYY",
|
||||||
className = "",
|
className = "",
|
||||||
allowText = false,
|
allowText = false,
|
||||||
@ -51,7 +52,7 @@ const DatePicker = ({
|
|||||||
<div className={`position-relative ${className} w-max `}>
|
<div className={`position-relative ${className} w-max `}>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="form-control form-control form-control-sm"
|
className={`form-control form-control form-control-${size}`}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
value={displayValue}
|
value={displayValue}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState,useCallback } from "react";
|
||||||
import { cacheData, getCachedData } from "../slices/apiDataManager";
|
import { cacheData, getCachedData } from "../slices/apiDataManager";
|
||||||
import { RolesRepository } from "../repositories/MastersRepository";
|
import { RolesRepository } from "../repositories/MastersRepository";
|
||||||
import EmployeeRepository from "../repositories/EmployeeRepository";
|
import EmployeeRepository from "../repositories/EmployeeRepository";
|
||||||
@ -9,6 +9,36 @@ import { useSelector } from "react-redux";
|
|||||||
import { store } from "../store/store";
|
import { store } from "../store/store";
|
||||||
import { queryClient } from "../layouts/AuthLayout";
|
import { queryClient } from "../layouts/AuthLayout";
|
||||||
|
|
||||||
|
|
||||||
|
export const useUserCache = () => {
|
||||||
|
const [userCache, setUserCache] = useState({});
|
||||||
|
|
||||||
|
const addToCache = (id, user) => {
|
||||||
|
setUserCache((prev) => ({ ...prev, [id]: user }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUser = async (id) => {
|
||||||
|
if (userCache[id]) return userCache[id];
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await EmployeeRepository.getEmployeeProfile(id);
|
||||||
|
if (res?.data) {
|
||||||
|
addToCache(id, res.data);
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("User not found", id);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
userCache,
|
||||||
|
getUser,
|
||||||
|
addToCache,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
// Query ---------------------------------------------------------------------------
|
// Query ---------------------------------------------------------------------------
|
||||||
|
|
||||||
export const useEmployee = (employeeId) => {
|
export const useEmployee = (employeeId) => {
|
||||||
@ -342,7 +372,6 @@ export const useUpdateEmployeeRoles = ({
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export const useOrganizationHierarchy = (employeeId) => {
|
export const useOrganizationHierarchy = (employeeId) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ["organizationHierarchy", employeeId],
|
queryKey: ["organizationHierarchy", employeeId],
|
||||||
@ -350,17 +379,18 @@ return useQuery({
|
|||||||
const resp = await EmployeeRepository.getOrganizaionHierarchy(employeeId);
|
const resp = await EmployeeRepository.getOrganizaionHierarchy(employeeId);
|
||||||
return resp.data;
|
return resp.data;
|
||||||
},
|
},
|
||||||
enabled:!!employeeId
|
enabled: !!employeeId,
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const useManageEmployeeHierarchy = (employeeId, onSuccessCallBack) => {
|
export const useManageEmployeeHierarchy = (employeeId, onSuccessCallBack) => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async (payload) => {
|
mutationFn: async (payload) => {
|
||||||
return await EmployeeRepository.manageOrganizationHierarchy(employeeId, payload);
|
return await EmployeeRepository.manageOrganizationHierarchy(
|
||||||
|
employeeId,
|
||||||
|
payload
|
||||||
|
);
|
||||||
},
|
},
|
||||||
onSuccess: (_, variables) => {
|
onSuccess: (_, variables) => {
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
|
|||||||
@ -132,7 +132,7 @@ export const useAllocationServiceProjectTeam = (onSuccessCallback) => {
|
|||||||
"success"
|
"success"
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
showToast(`Employee DeAllocated successfully`, "success");
|
showToast(`Employee removed successfully`, "success");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user