Compare commits
26 Commits
1598842436
...
284d36e5ac
| Author | SHA1 | Date | |
|---|---|---|---|
| 284d36e5ac | |||
| ba763f986d | |||
| e856220173 | |||
|
|
9ac15d3cf7 | ||
| 9a885c2b72 | |||
|
|
3161288871 | ||
| 2242569e48 | |||
|
|
7fa502f44c | ||
| 1ae1a45cb1 | |||
|
|
4175fb67c6 | ||
| 670efbe1bf | |||
|
|
865cc7a366 | ||
| 4fe09330c1 | |||
|
|
b004fe8c15 | ||
| 505c9a46db | |||
|
|
6c4c6db0d7 | ||
| d81482583e | |||
|
|
6c9fd4d20a | ||
| ddf9e86235 | |||
| a3867dfb2f | |||
| 0180793456 | |||
|
|
4f9d2f091a | ||
| 5fa7d563f9 | |||
|
|
8a1cbebced | ||
| ef2fdf899c | |||
| e61ba5b53a |
@ -194,7 +194,8 @@ const ManageEmployee = () => {
|
||||
navigation("/employees");
|
||||
})
|
||||
.catch((error) => {
|
||||
showToast(error.message, "error");
|
||||
const message = error?.response?.data?.message || error?.message || "Error occured during api calling"
|
||||
showToast(message, "error");
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
@ -157,9 +157,9 @@ const ManageRole = ( {employeeId, onClosed} ) =>
|
||||
reset();
|
||||
onClosed();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
showToast(err.message, "error");
|
||||
.catch((error) => {
|
||||
const message = error?.response?.data?.message || error?.message || "Error occured during api calling"
|
||||
showToast(message, "error");
|
||||
setIsLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
@ -110,6 +110,7 @@ const TaskModel = ({
|
||||
await onSubmit(data);
|
||||
setValue("plannedWork", 0);
|
||||
setValue( "completedWork", 0 );
|
||||
setValue("activityID",0)
|
||||
setIsSubmitting(false);
|
||||
};
|
||||
|
||||
@ -246,7 +247,7 @@ const TaskModel = ({
|
||||
|
||||
{selectedWorkArea && (
|
||||
<div className="col-12 col-md-12">
|
||||
<label className="form-label" htmlFor="activityID">
|
||||
<label className="form-label" >
|
||||
Select Activity
|
||||
</label>
|
||||
<select
|
||||
|
||||
@ -28,7 +28,10 @@ const ManageProjectInfo = ({ project, handleSubmitForm, onClose }) => {
|
||||
name: z.string().min(1, { message: "Project Name is required" }),
|
||||
contactPerson: z
|
||||
.string()
|
||||
.min(1, { message: "Contact Person Name is required" }),
|
||||
.min( 1, {message: "Contact Person Name is required"} )
|
||||
.regex(/^[A-Za-z\s]+$/, {
|
||||
message: "Contact Person must contain only letters",
|
||||
}),
|
||||
projectAddress: z
|
||||
.string()
|
||||
.min(1, { message: "Address is required" })
|
||||
@ -98,12 +101,13 @@ const ManageProjectInfo = ({ project, handleSubmitForm, onClose }) => {
|
||||
|
||||
const onSubmitForm = (updatedProject) => {
|
||||
setLoading(true);
|
||||
handleSubmitForm(updatedProject);
|
||||
|
||||
handleSubmitForm( updatedProject ,setLoading);
|
||||
|
||||
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
return () => setLoading(false);
|
||||
}, []);
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
@ -155,6 +159,7 @@ const ManageProjectInfo = ({ project, handleSubmitForm, onClose }) => {
|
||||
name="contactPerson"
|
||||
className="form-control"
|
||||
placeholder="Contact Person"
|
||||
maxLength={50}
|
||||
{...register("contactPerson")}
|
||||
/>
|
||||
{errors.contactPerson && (
|
||||
@ -269,8 +274,8 @@ const ManageProjectInfo = ({ project, handleSubmitForm, onClose }) => {
|
||||
)}
|
||||
</div>
|
||||
<div className="col-12 text-center">
|
||||
<button type="submit" className="btn btn-sm btn-primary me-3">
|
||||
{isloading ? "Please Wait" : project?.id ? "Update" : "Submit"}
|
||||
<button type="submit" className="btn btn-sm btn-primary me-3" disabled={isloading}>
|
||||
{isloading ? "Please Wait..." : project?.id ? "Update" : "Submit"}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@ -21,7 +21,7 @@ const ProjectBanner = ( {project_data} ) =>
|
||||
const handleShow = () => setShowModal(true);
|
||||
const handleClose = () => setShowModal(false);
|
||||
|
||||
const handleFormSubmit = ( updatedProject ) =>
|
||||
const handleFormSubmit = ( updatedProject,setLoading ) =>
|
||||
{
|
||||
|
||||
if ( CurrentProject?.id )
|
||||
@ -51,7 +51,7 @@ const ProjectBanner = ( {project_data} ) =>
|
||||
}
|
||||
|
||||
showToast( "Project updated successfully.", "success" );
|
||||
|
||||
setLoading(false)
|
||||
setShowModal(false)
|
||||
})
|
||||
.catch((error) => {
|
||||
|
||||
@ -6,3 +6,6 @@
|
||||
td {
|
||||
padding: 0.182rem;
|
||||
}
|
||||
.table > :not(caption) > * > * {
|
||||
padding: 0.1rem !important;
|
||||
}
|
||||
@ -24,7 +24,8 @@ const Teams = ({ project }) => {
|
||||
const [filteredEmployees, setFilteredEmployees] = useState([]);
|
||||
const [removingEmployeeId, setRemovingEmployeeId] = useState(null);
|
||||
const [assignedLoading, setAssignedLoading] = useState(false);
|
||||
const [employeeLodaing, setEmployeeLoading] = useState(false);
|
||||
const [ employeeLodaing, setEmployeeLoading ] = useState( false );
|
||||
const [activeEmployee,setActiveEmployee] = useState(true)
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
@ -129,10 +130,13 @@ const Teams = ({ project }) => {
|
||||
|
||||
const handleFilterEmployee = (e) => {
|
||||
const filterValue = e.target.value;
|
||||
if (filterValue === "true") {
|
||||
if ( filterValue === "true" )
|
||||
{
|
||||
setActiveEmployee(true)
|
||||
setFilteredEmployees(employees.filter((emp) => emp.isActive));
|
||||
} else {
|
||||
setFilteredEmployees(employees.filter((emp) => !emp.isActive));
|
||||
setFilteredEmployees( employees.filter( ( emp ) => !emp.isActive ) );
|
||||
setActiveEmployee(false)
|
||||
}
|
||||
};
|
||||
|
||||
@ -200,8 +204,8 @@ const Teams = ({ project }) => {
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Assigned Date</th>
|
||||
<th>Release Date</th>
|
||||
<th>Role</th>
|
||||
{!activeEmployee && <th>Release Date</th>}
|
||||
<th>Project Role</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -236,13 +240,13 @@ const Teams = ({ project }) => {
|
||||
"DD-MMM-YYYY"
|
||||
)}{" "}
|
||||
</td>
|
||||
<td>
|
||||
{!activeEmployee && <td>
|
||||
{item.reAllocationDate
|
||||
? moment(item.reAllocationDate).format(
|
||||
"DD-MMM-YYYY"
|
||||
)
|
||||
: "Present"}
|
||||
</td>
|
||||
</td>}
|
||||
<td>
|
||||
<span className="badge bg-label-primary me-1">
|
||||
{getRole(item.jobRoleId)}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
|
||||
import CreateRole from "./CreateRole";
|
||||
import DeleteMaster from "./DeleteMaster";
|
||||
@ -7,8 +7,41 @@ import CreateJobRole from "./CreateJobRole";
|
||||
import EditJobRole from "./EditJobRole";
|
||||
import CreateActivity from "./CreateActivity";
|
||||
import EditActivity from "./EditActivity";
|
||||
import ConfirmModal from "../common/ConfirmModal";
|
||||
|
||||
const MasterModal = ({ modaldata, closeModal }) => {
|
||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (modaldata?.modalType === "delete") {
|
||||
setIsDeleteModalOpen(true);
|
||||
}
|
||||
}, [modaldata]);
|
||||
|
||||
const handleCloseDeleteModal = () => {
|
||||
setIsDeleteModalOpen(false);
|
||||
closeModal();
|
||||
};
|
||||
|
||||
if (modaldata?.modalType === "delete" && isDeleteModalOpen) {
|
||||
return (
|
||||
<div
|
||||
className="modal fade show"
|
||||
tabIndex="-1"
|
||||
role="dialog"
|
||||
style={{ display: "block", backgroundColor: "rgba(0,0,0,0.5)" }}
|
||||
aria-hidden="false"
|
||||
>
|
||||
<ConfirmModal
|
||||
type="delete"
|
||||
header={`Delete ${modaldata.masterType}`}
|
||||
message={"comming soon.."}
|
||||
onClose={handleCloseDeleteModal}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="modal fade"
|
||||
@ -20,9 +53,7 @@ const MasterModal = ({ modaldata, closeModal }) => {
|
||||
>
|
||||
<div
|
||||
className={`modal-dialog mx-sm-auto mx-1 ${
|
||||
["Application Role", "Edit-Application Role"].includes(
|
||||
modaldata?.modalType
|
||||
)
|
||||
["Application Role", "Edit-Application Role"].includes(modaldata?.modalType)
|
||||
? "modal-lg"
|
||||
: "modal-md"
|
||||
} modal-simple`}
|
||||
@ -36,33 +67,24 @@ const MasterModal = ({ modaldata, closeModal }) => {
|
||||
aria-label="Close"
|
||||
onClick={closeModal}
|
||||
></button>
|
||||
<div className="text-center mb-2"></div>
|
||||
{modaldata?.modalType === "Application Role" && (
|
||||
<CreateRole
|
||||
masmodalType={modaldata.masterType}
|
||||
onClose={closeModal}
|
||||
/>
|
||||
|
||||
{modaldata.modalType === "Application Role" && (
|
||||
<CreateRole masmodalType={modaldata.masterType} onClose={closeModal} />
|
||||
)}
|
||||
{modaldata?.modalType === "Edit-Application Role" && (
|
||||
{modaldata.modalType === "Edit-Application Role" && (
|
||||
<EditRole master={modaldata} onClose={closeModal} />
|
||||
)}
|
||||
{modaldata?.modalType === "delete" && (
|
||||
<DeleteMaster master={modaldata} onClose={closeModal} />
|
||||
)}
|
||||
{modaldata?.modalType === "Job Role" && (
|
||||
{modaldata.modalType === "Job Role" && (
|
||||
<CreateJobRole onClose={closeModal} />
|
||||
)}
|
||||
{modaldata?.modalType === "Edit-Job Role" && (
|
||||
{modaldata.modalType === "Edit-Job Role" && (
|
||||
<EditJobRole data={modaldata.item} onClose={closeModal} />
|
||||
)}
|
||||
{modaldata?.modalType === "Activity" && (
|
||||
{modaldata.modalType === "Activity" && (
|
||||
<CreateActivity onClose={closeModal} />
|
||||
)}
|
||||
{modaldata?.modalType === "Edit-Activity" && (
|
||||
<EditActivity
|
||||
activityData={modaldata.item}
|
||||
onClose={closeModal}
|
||||
/>
|
||||
{modaldata.modalType === "Edit-Activity" && (
|
||||
<EditActivity activityData={modaldata.item} onClose={closeModal} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -24,13 +24,11 @@
|
||||
"available": true,
|
||||
"link": "/employees"
|
||||
},
|
||||
|
||||
{
|
||||
"text": "Project Status",
|
||||
"text": "Directory",
|
||||
"available": true,
|
||||
"link": "#"
|
||||
"link": "/directory"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -67,7 +65,7 @@
|
||||
{
|
||||
"text": "Daily Expenses",
|
||||
"available": true,
|
||||
"link": "/dashboard/"
|
||||
"link": "/activities/gallary"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@ -16,7 +16,7 @@ export const useAllEmployees = () => {
|
||||
setLoading(true);
|
||||
const response = await EmployeeRepository.getAllEmployeeList();
|
||||
cacheData("AllEmployees", response.data);
|
||||
setEmployeeList( response.data );
|
||||
setEmployeeList(response.data);
|
||||
setLoading(false);
|
||||
} else {
|
||||
setEmployeeList(EmployeeList_cached);
|
||||
@ -137,15 +137,14 @@ export const useEmployeesByProject = (projectId) => {
|
||||
return { employees, loading, error, recallProjectEmplloyee: fetchData };
|
||||
};
|
||||
|
||||
export const useEmployeesAllOrByProjectId = (projectId) => {
|
||||
export const useEmployeesAllOrByProjectId = (projectId, showInactive) => {
|
||||
const [employees, setEmployees] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
const fetchData = async () => {
|
||||
const fetchData = async (showInactive) => {
|
||||
if (projectId) {
|
||||
const Employees_cache = getCachedData("employeeListByProject");
|
||||
|
||||
if (!Employees_cache || Employees_cache.projectId !== projectId) {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
@ -168,30 +167,35 @@ export const useEmployeesAllOrByProjectId = (projectId) => {
|
||||
setLoading(false);
|
||||
}
|
||||
} else {
|
||||
const employeesCache = getCachedData("allEmployeeList");
|
||||
const cacheKey = showInactive
|
||||
? "allInactiveEmployeeList"
|
||||
: "allEmployeeList";
|
||||
const employeesCache = getCachedData(cacheKey);
|
||||
|
||||
if (!employeesCache) {
|
||||
if (employeesCache) {
|
||||
setEmployees(employeesCache.data);
|
||||
setLoading(false);
|
||||
} else {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const response = await EmployeeRepository.getAllEmployeeList();
|
||||
const response = await EmployeeRepository.getAllEmployeeList(
|
||||
showInactive
|
||||
);
|
||||
setEmployees(response.data);
|
||||
cacheData("allEmployeeList", { data: response.data });
|
||||
cacheData(cacheKey, { data: response.data });
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
setError("Failed to fetch data.");
|
||||
setLoading(false);
|
||||
}
|
||||
} else {
|
||||
setEmployees(employeesCache.data);
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchData(); // Fetch data when the component mounts or projectId changes
|
||||
fetchData(showInactive); // Fetch data when the component mounts or projectId changes
|
||||
}, [projectId]); // Re-fetch when projectId changes
|
||||
|
||||
return {
|
||||
|
||||
@ -13,7 +13,7 @@ const Directory = () => {
|
||||
<Breadcrumb
|
||||
data={[
|
||||
{ label: "Home", link: "/dashboard" },
|
||||
{ label: "Directory", link: null },
|
||||
{ label: "Directory (Comming Soon)", link: null },
|
||||
]}
|
||||
></Breadcrumb>
|
||||
|
||||
@ -126,7 +126,7 @@ const Directory = () => {
|
||||
<tbody className="table-border-bottom-0 overflow-auto ">
|
||||
<tr>
|
||||
<td colSpan="12" className="text-center py-4">
|
||||
No projects found
|
||||
comming soon....
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@ -25,10 +25,11 @@ const EmployeeList = () => {
|
||||
const { profile: loginUser } = useProfile();
|
||||
const [selectedProject, setSelectedProject] = useState("");
|
||||
const { projects, loading: projectLoading } = useProjects();
|
||||
const [showInactive, setShowInactive] = useState(false);
|
||||
const ManageEmployee = useHasUserPermission(MANAGE_EMPLOYEES);
|
||||
|
||||
const { employees, loading, setLoading, error, recallEmployeeData } =
|
||||
useEmployeesAllOrByProjectId(selectedProject);
|
||||
useEmployeesAllOrByProjectId(selectedProject,showInactive);
|
||||
const [projectsList, setProjectsList] = useState(projects || []);
|
||||
|
||||
const [employeeList, setEmployeeList] = useState([]);
|
||||
@ -48,11 +49,10 @@ const EmployeeList = () => {
|
||||
|
||||
if (!employeeList.length) return;
|
||||
|
||||
const results = employeeList.filter((item) =>
|
||||
Object.values(item).some(
|
||||
(field) => field && field.toString().toLowerCase().includes(value)
|
||||
)
|
||||
);
|
||||
const results = employeeList.filter((item) => {
|
||||
const fullName = `${item.firstName} ${item.lastName}`.toLowerCase();
|
||||
return fullName.includes(value);
|
||||
});
|
||||
|
||||
setFilteredData(results);
|
||||
};
|
||||
@ -109,9 +109,10 @@ const EmployeeList = () => {
|
||||
showToast("Employee deleted successfully.", "success");
|
||||
clearCacheKey("employeeListByProject");
|
||||
clearCacheKey("allEmployeeList");
|
||||
clearCacheKey("allInactiveEmployeeList");
|
||||
clearCacheKey("employeeProfile");
|
||||
setEmployeeList([]);
|
||||
recallEmployeeData();
|
||||
recallEmployeeData(showInactive);
|
||||
})
|
||||
.catch((error) => {
|
||||
const message =
|
||||
@ -154,6 +155,12 @@ const EmployeeList = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleToggle = (e) => {
|
||||
setShowInactive(e.target.checked);
|
||||
recallEmployeeData(e.target.checked);
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{isCreateModalOpen && (
|
||||
@ -317,6 +324,25 @@ const EmployeeList = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-end mb-2">
|
||||
<label class="switch switch-primary">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="switch-input"
|
||||
checked={showInactive}
|
||||
onChange={handleToggle}
|
||||
/>
|
||||
<span class="switch-toggle-slider">
|
||||
<span class="switch-on">
|
||||
<i class="icon-base bx bx-check"></i>
|
||||
</span>
|
||||
<span class="switch-off">
|
||||
<i class="icon-base bx bx-x"></i>
|
||||
</span>
|
||||
</span>
|
||||
<span class="switch-label">Show Inactive Employees</span>
|
||||
</label>
|
||||
</div>
|
||||
<table
|
||||
className="datatables-users table border-top dataTable no-footer dtr-column text-nowrap"
|
||||
id="DataTables_Table_0"
|
||||
@ -448,7 +474,9 @@ const EmployeeList = () => {
|
||||
<div className="d-flex flex-column">
|
||||
<a
|
||||
onClick={() =>
|
||||
navigate(`/employee/${item.id}?for=attendance`)
|
||||
navigate(
|
||||
`/employee/${item.id}?for=attendance`
|
||||
)
|
||||
}
|
||||
className="text-heading text-truncate cursor-pointer"
|
||||
>
|
||||
@ -490,12 +518,19 @@ const EmployeeList = () => {
|
||||
{moment(item.joiningDate).format("DD-MMM-YYYY")}
|
||||
</td>
|
||||
<td>
|
||||
{showInactive ? <span
|
||||
className="badge bg-label-danger"
|
||||
text-capitalized=""
|
||||
>
|
||||
Inactive
|
||||
</span>
|
||||
:
|
||||
<span
|
||||
className="badge bg-label-success"
|
||||
text-capitalized=""
|
||||
>
|
||||
Active
|
||||
</span>
|
||||
</span>}
|
||||
</td>
|
||||
{ManageEmployee && (
|
||||
<td className="text-end">
|
||||
@ -521,7 +556,7 @@ const EmployeeList = () => {
|
||||
>
|
||||
<i className="bx bx-edit bx-sm"></i> Edit
|
||||
</Link>
|
||||
<button
|
||||
{!item.isSystem && (<><button
|
||||
className="dropdown-item py-1"
|
||||
onClick={() => suspendEmployee(item.id)}
|
||||
>
|
||||
@ -537,7 +572,7 @@ const EmployeeList = () => {
|
||||
>
|
||||
<i className="bx bx-cog bx-sm"></i> Manage
|
||||
Role
|
||||
</button>
|
||||
</button></>)}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
@ -25,7 +25,7 @@ const ProjectList = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [itemsPerPage] = useState(6);
|
||||
const [itemsPerPage] = useState(10);
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [selectedStatuses, setSelectedStatuses] = useState([
|
||||
"b74da4c2-d07e-46f2-9919-e75e49b12731",
|
||||
@ -193,7 +193,7 @@ const ProjectList = () => {
|
||||
<i className="bx bx-list-ul bx-sm"></i>
|
||||
</button>
|
||||
</div>
|
||||
{!listView && (
|
||||
|
||||
<div className="dropdown ms-3">
|
||||
<a
|
||||
className="dropdown-toggle hide-arrow cursor-pointer"
|
||||
@ -235,7 +235,7 @@ const ProjectList = () => {
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { api } from "../utils/axiosClient";
|
||||
|
||||
const EmployeeRepository = {
|
||||
getAllEmployeeList:()=>api.get(`api/employee/list`),
|
||||
getAllEmployeeList:(showInactive)=>api.get(`api/employee/list?showInactive=${showInactive}`),
|
||||
getEmployeeListByproject: (projectid) =>
|
||||
api.get(`/api/employee/list/${projectid}`),
|
||||
searchEmployees: (query) =>
|
||||
|
||||
@ -15,7 +15,7 @@ export const RolesRepository = {
|
||||
|
||||
|
||||
getEmployeeRoles:(id)=>api.get(`/api/employee/roles/${id}`),
|
||||
createEmployeeRoles:(data)=>api.post("/api/employee/roles",data)
|
||||
createEmployeeRoles:(data)=>api.post("/api/roles/assign-roles",data)
|
||||
};
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user