Compare commits
14 Commits
d06cfd97a7
...
4b3f8cc50f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b3f8cc50f | ||
|
|
8de7b4b5c3 | ||
|
|
498665c811 | ||
|
|
9ef09f9536 | ||
|
|
04a25d58f4 | ||
|
|
148f4b79e7 | ||
|
|
8607dbb49b | ||
|
|
8be60953ba | ||
|
|
4055a4532c | ||
|
|
4b9f5d737a | ||
|
|
e86d43c6e9 | ||
|
|
a96fa8efc7 | ||
|
|
294c13878d | ||
|
|
b3906f460e |
@ -104,7 +104,8 @@ const TaskModel = ({
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmitForm = async (data) => {
|
const onSubmitForm = async ( data ) =>
|
||||||
|
{
|
||||||
setIsSubmitting(true);
|
setIsSubmitting(true);
|
||||||
await onSubmit(data);
|
await onSubmit(data);
|
||||||
setValue("plannedWork", 0);
|
setValue("plannedWork", 0);
|
||||||
@ -114,9 +115,9 @@ const TaskModel = ({
|
|||||||
|
|
||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
setFormData(defaultModel);
|
setFormData(defaultModel);
|
||||||
setSelectedBuilding("0");
|
setSelectedBuilding(null); // not "0"
|
||||||
setSelectedFloor("0");
|
setSelectedFloor(null);
|
||||||
setSelectedWorkArea("0");
|
setSelectedWorkArea(null);
|
||||||
setSelectedActivity(null);
|
setSelectedActivity(null);
|
||||||
reset(defaultModel);
|
reset(defaultModel);
|
||||||
};
|
};
|
||||||
@ -255,25 +256,28 @@ const TaskModel = ({
|
|||||||
onChange={handleActivityChange}
|
onChange={handleActivityChange}
|
||||||
>
|
>
|
||||||
<option value="0">Select Activity</option>
|
<option value="0">Select Activity</option>
|
||||||
{activityData && activityData.length > 0 ? (
|
{activityData && activityData.length > 0 && (
|
||||||
activityData
|
activityData
|
||||||
?.slice()
|
?.slice()
|
||||||
?.sort((a, b) => {
|
?.sort( ( a, b ) =>
|
||||||
|
{
|
||||||
const nameA = a?.activityName || "";
|
const nameA = a?.activityName || "";
|
||||||
const nameB = b?.activityName || "";
|
const nameB = b?.activityName || "";
|
||||||
return nameA.localeCompare(nameB);
|
return nameA.localeCompare( nameB );
|
||||||
})
|
} )
|
||||||
?.map((activity) => (
|
?.map( ( activity ) => (
|
||||||
<option key={activity.id} value={activity.id}>
|
<option key={activity.id} value={activity.id}>
|
||||||
{
|
{
|
||||||
activity.activityName ||
|
activity.activityName ||
|
||||||
|
|
||||||
`Unnamed (id: ${activity.id})`}
|
`Unnamed (id: ${ activity.id })`}
|
||||||
</option>
|
</option>
|
||||||
))
|
) )
|
||||||
) : (
|
) }
|
||||||
|
{(!loading && activities.length === 0 )&& (
|
||||||
<option disabled>No activities available</option>
|
<option disabled>No activities available</option>
|
||||||
)}
|
)}
|
||||||
|
{loading && ( <option disabled>Loading...</option>)}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
{errors.activityID && (
|
{errors.activityID && (
|
||||||
@ -337,8 +341,6 @@ const TaskModel = ({
|
|||||||
<button type="submit" className="btn btn-sm btn-primary me-3">
|
<button type="submit" className="btn btn-sm btn-primary me-3">
|
||||||
{isSubmitting
|
{isSubmitting
|
||||||
? "Please Wait.."
|
? "Please Wait.."
|
||||||
: formData.id !== "0" && formData.id !== ""
|
|
||||||
? "Edit Task"
|
|
||||||
: "Add Task"}
|
: "Add Task"}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@ -140,7 +140,7 @@ const WorkItem = ({ workItem, forBuilding, forFloor, forWorkArea }) => {
|
|||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{projectId && ManageInfra && (
|
{ ManageInfra && (
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
aria-label="Modify"
|
aria-label="Modify"
|
||||||
|
|||||||
@ -11,10 +11,12 @@ const MapUsers = ({
|
|||||||
empJobRoles,
|
empJobRoles,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
allocation,
|
allocation,
|
||||||
|
assignedLoading,
|
||||||
|
setAssignedLoading,
|
||||||
}) => {
|
}) => {
|
||||||
const { employeesList, loading:employeeLoading, error } = useAllEmployees();
|
const { employeesList, loading: employeeLoading, error } = useAllEmployees();
|
||||||
const [selectedEmployees, setSelectedEmployees] = useState([]);
|
const [selectedEmployees, setSelectedEmployees] = useState([]);
|
||||||
const [searchText, setSearchText] = useState("");
|
const [ searchText, setSearchText ] = useState( "" );
|
||||||
|
|
||||||
const handleAllocationData = Array.isArray(allocation) ? allocation : [];
|
const handleAllocationData = Array.isArray(allocation) ? allocation : [];
|
||||||
|
|
||||||
@ -94,17 +96,19 @@ const MapUsers = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () =>
|
||||||
|
{
|
||||||
|
setAssignedLoading(true)
|
||||||
const selected = selectedEmployees
|
const selected = selectedEmployees
|
||||||
.filter((emp) => emp.isSelected)
|
.filter((emp) => emp.isSelected)
|
||||||
.map((emp) => ({ empID: emp.id, jobRoleId: emp.jobRoleId }));
|
.map((emp) => ({ empID: emp.id, jobRoleId: emp.jobRoleId }));
|
||||||
if (selected.length > 0) {
|
if (selected.length > 0) {
|
||||||
console.log(selected);
|
|
||||||
onSubmit(selected);
|
onSubmit(selected);
|
||||||
setSelectedEmployees([]);
|
setSelectedEmployees([]);
|
||||||
} else {
|
} else {
|
||||||
showToast("Please select Employee", "error");
|
showToast("Please select Employee", "error");
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -112,14 +116,17 @@ const MapUsers = ({
|
|||||||
<div className="modal-content">
|
<div className="modal-content">
|
||||||
<div className="modal-header">
|
<div className="modal-header">
|
||||||
<div className="md-2 mb-1">
|
<div className="md-2 mb-1">
|
||||||
<div className="input-group">
|
{(filteredData.length > 0 ||
|
||||||
<input
|
allocationEmployeesData.length > 0)&& (
|
||||||
type="search"
|
<div className="input-group">
|
||||||
className="form-control form-control-sm"
|
<input
|
||||||
placeholder="Search employees.."
|
type="search"
|
||||||
onChange={(e) => setSearchQuery(e.target.value)}
|
className="form-control form-control-sm"
|
||||||
/>
|
placeholder="Search employees..."
|
||||||
</div>
|
onChange={(e) => setSearchQuery(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="modal-body p-sm-4 p-0">
|
<div className="modal-body p-sm-4 p-0">
|
||||||
@ -131,19 +138,22 @@ const MapUsers = ({
|
|||||||
>
|
>
|
||||||
<thead></thead>
|
<thead></thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{(employeeLoading && allocationEmployeesData.length === 0 ) && <p>Loading...</p>}
|
{employeeLoading && allocationEmployeesData.length === 0 && (
|
||||||
|
<p>Loading...</p>
|
||||||
|
)}
|
||||||
|
|
||||||
{!employeeLoading &&
|
{!employeeLoading &&
|
||||||
allocationEmployeesData.length === 0 &&
|
allocationEmployeesData.length === 0 &&
|
||||||
filteredData.length === 0 && <p>No employees available.</p>}
|
|
||||||
|
|
||||||
{!employeeLoading &&
|
|
||||||
allocationEmployeesData.length > 0 &&
|
|
||||||
filteredData.length === 0 && (
|
filteredData.length === 0 && (
|
||||||
<p>No matching employees found.</p>
|
<p>All employee assigned to Project.</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{filteredData.length > 0 &&
|
{!employeeLoading && allocationEmployeesData.length > 0 && filteredData.length === 0 && (
|
||||||
|
<p>No matching employees found.</p>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{(filteredData.length > 0 ||
|
||||||
|
allocationEmployeesData.length > 0) &&
|
||||||
filteredData.map((emp) => (
|
filteredData.map((emp) => (
|
||||||
<AssignEmployeeTable
|
<AssignEmployeeTable
|
||||||
key={emp.id}
|
key={emp.id}
|
||||||
@ -158,9 +168,16 @@ const MapUsers = ({
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div className="modal-footer">
|
<div className="modal-footer">
|
||||||
<button className="btn btn-sm btn-success" onClick={handleSubmit}>
|
{(filteredData.length > 0 ||
|
||||||
Assign to Project
|
allocationEmployeesData.length > 0) && (
|
||||||
</button>
|
<button
|
||||||
|
className="btn btn-sm btn-success"
|
||||||
|
onClick={handleSubmit}
|
||||||
|
>
|
||||||
|
{assignedLoading ? "Please Wait...":"Assign to Project"}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-sm btn-secondary"
|
className="btn btn-sm btn-secondary"
|
||||||
|
|||||||
@ -8,8 +8,11 @@ import ProjectRepository from "../../repositories/ProjectRepository";
|
|||||||
import { cacheData, getCachedData } from "../../slices/apiDataManager";
|
import { cacheData, getCachedData } from "../../slices/apiDataManager";
|
||||||
import showToast from "../../services/toastService";
|
import showToast from "../../services/toastService";
|
||||||
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
|
||||||
import {MANAGE_PROJECT} from "../../utils/constants";
|
import { MANAGE_PROJECT } from "../../utils/constants";
|
||||||
import { getProjectStatusColor,getProjectStatusName } from "../../utils/projectStatus";
|
import {
|
||||||
|
getProjectStatusColor,
|
||||||
|
getProjectStatusName,
|
||||||
|
} from "../../utils/projectStatus";
|
||||||
|
|
||||||
const ProjectCard = ({ projectData }) => {
|
const ProjectCard = ({ projectData }) => {
|
||||||
const [projectInfo, setProjectInfo] = useState(projectData);
|
const [projectInfo, setProjectInfo] = useState(projectData);
|
||||||
@ -17,13 +20,16 @@ const ProjectCard = ({ projectData }) => {
|
|||||||
const [showModal, setShowModal] = useState(false);
|
const [showModal, setShowModal] = useState(false);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const ManageProject = useHasUserPermission(MANAGE_PROJECT);
|
const ManageProject = useHasUserPermission(MANAGE_PROJECT);
|
||||||
|
const [modifyProjectLoading, setMdifyProjectLoading] = useState(false);
|
||||||
|
|
||||||
const handleShow = async () => {
|
const handleShow = async () => {
|
||||||
try {
|
try {
|
||||||
|
setMdifyProjectLoading(true);
|
||||||
const response = await ProjectRepository.getProjectByprojectId(
|
const response = await ProjectRepository.getProjectByprojectId(
|
||||||
projectInfo.id
|
projectInfo.id
|
||||||
);
|
);
|
||||||
setProjectDetails(response.data);
|
setProjectDetails(response.data);
|
||||||
|
setMdifyProjectLoading(false);
|
||||||
setShowModal(true);
|
setShowModal(true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showToast("Failed to load project details", "error");
|
showToast("Failed to load project details", "error");
|
||||||
@ -39,7 +45,6 @@ const ProjectCard = ({ projectData }) => {
|
|||||||
|
|
||||||
const handleClose = () => setShowModal(false);
|
const handleClose = () => setShowModal(false);
|
||||||
|
|
||||||
|
|
||||||
const handleViewProject = () => {
|
const handleViewProject = () => {
|
||||||
navigate(`/projects/${projectData.id}`);
|
navigate(`/projects/${projectData.id}`);
|
||||||
};
|
};
|
||||||
@ -64,9 +69,11 @@ const ProjectCard = ({ projectData }) => {
|
|||||||
if (projects_list) {
|
if (projects_list) {
|
||||||
const updatedProjectsList = projects_list.map((project) =>
|
const updatedProjectsList = projects_list.map((project) =>
|
||||||
project.id === projectInfo.id
|
project.id === projectInfo.id
|
||||||
? { ...project, ...response.data,
|
? {
|
||||||
// tenant: project.tenant
|
...project,
|
||||||
}
|
...response.data,
|
||||||
|
// tenant: project.tenant
|
||||||
|
}
|
||||||
: project
|
: project
|
||||||
);
|
);
|
||||||
cacheData("projectslist", updatedProjectsList);
|
cacheData("projectslist", updatedProjectsList);
|
||||||
@ -81,6 +88,7 @@ const ProjectCard = ({ projectData }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{showModal && projectDetails && (
|
{showModal && projectDetails && (
|
||||||
@ -133,14 +141,17 @@ const ProjectCard = ({ projectData }) => {
|
|||||||
data-bs-toggle="dropdown"
|
data-bs-toggle="dropdown"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
>
|
>
|
||||||
<i
|
{modifyProjectLoading? <div class="spinner-border spinner-border-sm text-secondary" role="status">
|
||||||
className="bx bx-dots-vertical-rounded bx-sm text-muted"
|
<span class="visually-hidden">Loading...</span>
|
||||||
data-bs-toggle="tooltip"
|
</div> :
|
||||||
data-bs-offset="0,8"
|
<i
|
||||||
data-bs-placement="top"
|
className="bx bx-dots-vertical-rounded bx-sm text-muted"
|
||||||
data-bs-custom-class="tooltip-dark"
|
data-bs-toggle="tooltip"
|
||||||
title="More Action"
|
data-bs-offset="0,8"
|
||||||
></i>
|
data-bs-placement="top"
|
||||||
|
data-bs-custom-class="tooltip-dark"
|
||||||
|
title="More Action"
|
||||||
|
></i>}
|
||||||
</button>
|
</button>
|
||||||
<ul className="dropdown-menu dropdown-menu-end">
|
<ul className="dropdown-menu dropdown-menu-end">
|
||||||
<li>
|
<li>
|
||||||
|
|||||||
@ -21,7 +21,7 @@ const ProjectInfra = ({
|
|||||||
eachSiteEngineer,
|
eachSiteEngineer,
|
||||||
}) => {
|
}) => {
|
||||||
const [expandedBuildings, setExpandedBuildings] = useState([]);
|
const [expandedBuildings, setExpandedBuildings] = useState([]);
|
||||||
const { projects_Details,refetch, loading } = useProjectDetails(data.id);
|
const { projects_Details,refetch, loading } = useProjectDetails(data?.id);
|
||||||
const [project, setProject] = useState(projects_Details);
|
const [project, setProject] = useState(projects_Details);
|
||||||
const [modalConfig, setModalConfig] = useState({ type: null, data: null });
|
const [modalConfig, setModalConfig] = useState({ type: null, data: null });
|
||||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
|
|||||||
@ -18,23 +18,30 @@ const Teams = ({ project }) => {
|
|||||||
const [isModalOpen, setIsModelOpen] = useState(false);
|
const [isModalOpen, setIsModelOpen] = useState(false);
|
||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
const [empJobRoles, setEmpJobRoles] = useState(null);
|
const [empJobRoles, setEmpJobRoles] = useState(null);
|
||||||
const [clearFormTrigger, setClearFormTrigger] = useState(false);
|
|
||||||
const [employees, setEmployees] = useState([]);
|
const [employees, setEmployees] = useState([]);
|
||||||
const [filteredEmployees, setFilteredEmployees] = useState([]);
|
const [filteredEmployees, setFilteredEmployees] = useState([]);
|
||||||
|
const [ removingEmployeeId, setRemovingEmployeeId ] = useState( null );
|
||||||
|
const [ assignedLoading, setAssignedLoading ] = useState( false )
|
||||||
|
const [employeeLodaing,setEmployeeLoading] = useState(false)
|
||||||
|
|
||||||
const HasAssignUserPermission = useHasUserPermission(ASSIGN_TO_PROJECT);
|
const HasAssignUserPermission = useHasUserPermission(ASSIGN_TO_PROJECT);
|
||||||
|
|
||||||
const fetchEmployees = async () => {
|
const fetchEmployees = async () => {
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
|
setEmployeeLoading(true)
|
||||||
|
|
||||||
// if (!empRoles) {
|
// if (!empRoles) {
|
||||||
ProjectRepository.getProjectAllocation(project.id)
|
ProjectRepository.getProjectAllocation(project.id)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
setEmployees(response.data);
|
setEmployees(response.data);
|
||||||
setFilteredEmployees(response.data.filter((emp) => emp.isActive));
|
setFilteredEmployees( response.data.filter( ( emp ) => emp.isActive ) );
|
||||||
|
setEmployeeLoading(false)
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
setError("Failed to fetch data.");
|
setError( "Failed to fetch data." );
|
||||||
|
setEmployeeLoading(false)
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError("Failed to fetch activities.");
|
setError("Failed to fetch activities.");
|
||||||
@ -45,8 +52,9 @@ const Teams = ({ project }) => {
|
|||||||
ProjectRepository.manageProjectAllocation(items)
|
ProjectRepository.manageProjectAllocation(items)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
showToast("Details updated successfully.", "success");
|
showToast("Details updated successfully.", "success");
|
||||||
setClearFormTrigger(true);
|
|
||||||
fetchEmployees();
|
fetchEmployees();
|
||||||
|
setRemovingEmployeeId( null );
|
||||||
|
setAssignedLoading(false)
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
showToast(error.message, "error");
|
showToast(error.message, "error");
|
||||||
@ -54,6 +62,7 @@ const Teams = ({ project }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const removeAllocation = (item) => {
|
const removeAllocation = (item) => {
|
||||||
|
setRemovingEmployeeId(item.id);
|
||||||
submitAllocations([
|
submitAllocations([
|
||||||
{
|
{
|
||||||
empID: item.employeeId,
|
empID: item.employeeId,
|
||||||
@ -134,13 +143,13 @@ const Teams = ({ project }) => {
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
<MapUsers
|
<MapUsers
|
||||||
projectId={project.id}
|
projectId={project?.id}
|
||||||
onClose={onModelClose}
|
onClose={onModelClose}
|
||||||
empJobRoles={empJobRoles}
|
empJobRoles={empJobRoles}
|
||||||
onSubmit={handleEmpAlicationFormSubmit}
|
onSubmit={handleEmpAlicationFormSubmit}
|
||||||
allocation={employees}
|
allocation={employees}
|
||||||
clearTrigger={clearFormTrigger}
|
assignedLoading={assignedLoading}
|
||||||
onClearComplete={() => setClearFormTrigger(false)}
|
setAssignedLoading={setAssignedLoading}
|
||||||
></MapUsers>
|
></MapUsers>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -181,7 +190,8 @@ const Teams = ({ project }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="table-responsive text-nowrap">
|
<div className="table-responsive text-nowrap">
|
||||||
{employees && employees.length > 0 ? (
|
{employeeLodaing && (<p>Loading..</p>)}
|
||||||
|
{!employeeLodaing && employees && employees.length > 0 && (
|
||||||
<table className="table ">
|
<table className="table ">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -194,7 +204,7 @@ const Teams = ({ project }) => {
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody className="table-border-bottom-0">
|
<tbody className="table-border-bottom-0">
|
||||||
{filteredEmployees &&
|
{filteredEmployees &&
|
||||||
filteredEmployees.map((item) => (
|
filteredEmployees.map( ( item ) => (
|
||||||
<tr key={item.id}>
|
<tr key={item.id}>
|
||||||
<td>
|
<td>
|
||||||
<div className="d-flex justify-content-start align-items-center">
|
<div className="d-flex justify-content-start align-items-center">
|
||||||
@ -205,7 +215,8 @@ const Teams = ({ project }) => {
|
|||||||
<div className="d-flex flex-column">
|
<div className="d-flex flex-column">
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
onClick={(e) => {
|
onClick={( e ) =>
|
||||||
|
{
|
||||||
e.preventDefault(); // Prevent default link behavior
|
e.preventDefault(); // Prevent default link behavior
|
||||||
window.location.href =
|
window.location.href =
|
||||||
"/employee/" + item.employee.id;
|
"/employee/" + item.employee.id;
|
||||||
@ -221,20 +232,20 @@ const Teams = ({ project }) => {
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{" "}
|
{" "}
|
||||||
{moment(item.allocationDate).format(
|
{moment( item.allocationDate ).format(
|
||||||
"DD-MMM-YYYY"
|
"DD-MMM-YYYY"
|
||||||
)}{" "}
|
)}{" "}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{item.reAllocationDate
|
{item.reAllocationDate
|
||||||
? moment(item.reAllocationDate).format(
|
? moment( item.reAllocationDate ).format(
|
||||||
"DD-MMM-YYYY"
|
"DD-MMM-YYYY"
|
||||||
)
|
)
|
||||||
: "Present"}
|
: "Present"}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span className="badge bg-label-primary me-1">
|
<span className="badge bg-label-primary me-1">
|
||||||
{getRole(item.jobRoleId)}
|
{getRole( item.jobRoleId )}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@ -244,19 +255,26 @@ const Teams = ({ project }) => {
|
|||||||
type="button"
|
type="button"
|
||||||
title="Remove from project"
|
title="Remove from project"
|
||||||
className="btn p-0 dropdown-toggle hide-arrow"
|
className="btn p-0 dropdown-toggle hide-arrow"
|
||||||
onClick={() => removeAllocation(item)}
|
onClick={() => removeAllocation( item )}
|
||||||
>
|
>
|
||||||
{" "}
|
{" "}
|
||||||
<i className="bx bx-trash me-1 text-danger"></i>{" "}
|
{removingEmployeeId === item.id ? <div
|
||||||
|
class="spinner-border spinner-border-sm text-primary"
|
||||||
|
role="status"
|
||||||
|
>
|
||||||
|
<span class="visually-hidden">Loading...</span>
|
||||||
|
</div> : <i className="bx bx-trash me-1 text-danger"></i>}
|
||||||
|
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{!item.isActive && <span>Not in project</span>}
|
{!item.isActive && <span>Not in project</span>}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
) )}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
) : (
|
)}
|
||||||
|
{(!employeeLodaing && employees.length == 0 ) && (
|
||||||
<span>No employees assigned to the project</span>
|
<span>No employees assigned to the project</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -267,4 +285,3 @@ const Teams = ({ project }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default Teams;
|
export default Teams;
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ export const useProjects = () => {
|
|||||||
const { profile } = useProfile();
|
const { profile } = useProfile();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const [projects, setProjects] = useState([]);
|
const [projects, setProjects] = useState([]);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(true);
|
||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
|
|
||||||
const projects_cache = getCachedData("projectslist");
|
const projects_cache = getCachedData("projectslist");
|
||||||
@ -38,7 +38,8 @@ export const useProjects = () => {
|
|||||||
} else {
|
} else {
|
||||||
if (!projects.length) {
|
if (!projects.length) {
|
||||||
const filtered = filterProjects(projects_cache);
|
const filtered = filterProjects(projects_cache);
|
||||||
setProjects(filtered);
|
setProjects( filtered );
|
||||||
|
setLoading(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -27,7 +27,12 @@ const ProjectList = () => {
|
|||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const [itemsPerPage] = useState(6);
|
const [itemsPerPage] = useState(6);
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
const [selectedStatuses, setSelectedStatuses] = useState(["b74da4c2-d07e-46f2-9919-e75e49b12731","603e994b-a27f-4e5d-a251-f3d69b0498ba","ef1c356e-0fe0-42df-a5d3-8daee355492d","33deaef9-9af1-4f2a-b443-681ea0d04f81",]);
|
const [selectedStatuses, setSelectedStatuses] = useState([
|
||||||
|
"b74da4c2-d07e-46f2-9919-e75e49b12731",
|
||||||
|
"603e994b-a27f-4e5d-a251-f3d69b0498ba",
|
||||||
|
"ef1c356e-0fe0-42df-a5d3-8daee355492d",
|
||||||
|
"33deaef9-9af1-4f2a-b443-681ea0d04f81",
|
||||||
|
]);
|
||||||
|
|
||||||
const handleShow = () => setShowModal(true);
|
const handleShow = () => setShowModal(true);
|
||||||
const handleClose = () => setShowModal(false);
|
const handleClose = () => setShowModal(false);
|
||||||
@ -41,8 +46,8 @@ const ProjectList = () => {
|
|||||||
grouped[statusId].push(project);
|
grouped[statusId].push(project);
|
||||||
});
|
});
|
||||||
|
|
||||||
const sortedGrouped = Object.keys(grouped)
|
const sortedGrouped = selectedStatuses
|
||||||
.sort()
|
.filter((statusId) => grouped[statusId])
|
||||||
.flatMap((statusId) =>
|
.flatMap((statusId) =>
|
||||||
grouped[statusId].sort((a, b) =>
|
grouped[statusId].sort((a, b) =>
|
||||||
a.name.toLowerCase().localeCompare(b.name.toLowerCase())
|
a.name.toLowerCase().localeCompare(b.name.toLowerCase())
|
||||||
@ -171,7 +176,7 @@ const ProjectList = () => {
|
|||||||
data-bs-custom-class="tooltip"
|
data-bs-custom-class="tooltip"
|
||||||
title="Card View"
|
title="Card View"
|
||||||
>
|
>
|
||||||
<i className="bx bx-grid-alt"></i>
|
<i className="bx bx-grid-alt bx-sm"></i>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@ -185,9 +190,52 @@ const ProjectList = () => {
|
|||||||
data-bs-custom-class="tooltip"
|
data-bs-custom-class="tooltip"
|
||||||
title="List View"
|
title="List View"
|
||||||
>
|
>
|
||||||
<i className="bx bx-list-ul"></i>
|
<i className="bx bx-list-ul bx-sm"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
{!listView && (
|
||||||
|
<div className="dropdown ms-3">
|
||||||
|
<a
|
||||||
|
className="dropdown-toggle hide-arrow cursor-pointer"
|
||||||
|
data-bs-toggle="dropdown"
|
||||||
|
aria-expanded="false"
|
||||||
|
>
|
||||||
|
<i className="bx bx-filter bx-lg"></i>
|
||||||
|
</a>
|
||||||
|
<ul className="dropdown-menu p-2 text-capitalize">
|
||||||
|
{[
|
||||||
|
{
|
||||||
|
id: "b74da4c2-d07e-46f2-9919-e75e49b12731",
|
||||||
|
label: "Active",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "603e994b-a27f-4e5d-a251-f3d69b0498ba",
|
||||||
|
label: "On Hold",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "ef1c356e-0fe0-42df-a5d3-8daee355492d",
|
||||||
|
label: "Inactive",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "33deaef9-9af1-4f2a-b443-681ea0d04f81",
|
||||||
|
label: "Completed",
|
||||||
|
},
|
||||||
|
].map(({ id, label }) => (
|
||||||
|
<li key={id}>
|
||||||
|
<div className="form-check">
|
||||||
|
<input
|
||||||
|
className="form-check-input "
|
||||||
|
type="checkbox"
|
||||||
|
checked={selectedStatuses.includes(id)}
|
||||||
|
onChange={() => handleStatusChange(id)}
|
||||||
|
/>
|
||||||
|
<label className="form-check-label">{label}</label>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
@ -234,10 +282,22 @@ const ProjectList = () => {
|
|||||||
</a>
|
</a>
|
||||||
<ul className="dropdown-menu p-2 text-capitalize">
|
<ul className="dropdown-menu p-2 text-capitalize">
|
||||||
{[
|
{[
|
||||||
{ id: "b74da4c2-d07e-46f2-9919-e75e49b12731", label: "Active" },
|
{
|
||||||
{ id: "603e994b-a27f-4e5d-a251-f3d69b0498ba", label: "On Hold" },
|
id: "b74da4c2-d07e-46f2-9919-e75e49b12731",
|
||||||
{ id: "ef1c356e-0fe0-42df-a5d3-8daee355492d", label: "Inactive" },
|
label: "Active",
|
||||||
{ id: "33deaef9-9af1-4f2a-b443-681ea0d04f81", label: "Completed" },
|
},
|
||||||
|
{
|
||||||
|
id: "603e994b-a27f-4e5d-a251-f3d69b0498ba",
|
||||||
|
label: "On Hold",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "ef1c356e-0fe0-42df-a5d3-8daee355492d",
|
||||||
|
label: "Inactive",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "33deaef9-9af1-4f2a-b443-681ea0d04f81",
|
||||||
|
label: "Completed",
|
||||||
|
},
|
||||||
].map(({ id, label }) => (
|
].map(({ id, label }) => (
|
||||||
<li key={id}>
|
<li key={id}>
|
||||||
<div className="form-check">
|
<div className="form-check">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user