Compare commits
No commits in common. "93c1fb18449b12f72b035c00f3478d5ff30718e3" and "379d9ecb8bcae5365b154908416a742c59bcadf5" have entirely different histories.
93c1fb1844
...
379d9ecb8b
@ -21,7 +21,7 @@ export const ReportTask = ({ report, closeModal, refetch }) => {
|
|||||||
required_error: "Completed Work must be a number",
|
required_error: "Completed Work must be a number",
|
||||||
invalid_type_error: "Completed Work must be a number",
|
invalid_type_error: "Completed Work must be a number",
|
||||||
})
|
})
|
||||||
.min(0, "Completed Work must be greater than 0")
|
.min(1, "Completed Work must be greater than 0")
|
||||||
.max(maxPending, {
|
.max(maxPending, {
|
||||||
message: `Completed task cannot exceed total pending tasks: ${maxPending}`,
|
message: `Completed task cannot exceed total pending tasks: ${maxPending}`,
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,79 +0,0 @@
|
|||||||
import React from "react";
|
|
||||||
import ReactApexChart from "react-apexcharts";
|
|
||||||
|
|
||||||
const ProgressDonutChart = ({ completed = 0, planned = 1 }) => {
|
|
||||||
const percentage = planned > 0 ? Math.round((completed / planned) * 100) : 0;
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
chart: {
|
|
||||||
height: 10,
|
|
||||||
type: "radialBar",
|
|
||||||
toolbar: { show: false },
|
|
||||||
},
|
|
||||||
plotOptions: {
|
|
||||||
radialBar: {
|
|
||||||
startAngle: 0,
|
|
||||||
endAngle: 360,
|
|
||||||
hollow: {
|
|
||||||
margin: 0,
|
|
||||||
size: "10%",
|
|
||||||
background: "#fff",
|
|
||||||
dropShadow: {
|
|
||||||
enabled: true,
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
blur: 3,
|
|
||||||
opacity: 0.45,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
track: {
|
|
||||||
background: "#f5f5f5",
|
|
||||||
strokeWidth: "10%",
|
|
||||||
dropShadow: { enabled: false },
|
|
||||||
},
|
|
||||||
dataLabels: {
|
|
||||||
show: true,
|
|
||||||
name: {
|
|
||||||
offsetY: -10,
|
|
||||||
color: "#888",
|
|
||||||
fontSize: "14px",
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
formatter: (val) => `${val}%`,
|
|
||||||
color: "#111",
|
|
||||||
fontSize: "11px",
|
|
||||||
show: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
fill: {
|
|
||||||
type: "gradient",
|
|
||||||
gradient: {
|
|
||||||
shade: "dark",
|
|
||||||
type: "horizontal",
|
|
||||||
shadeIntensity: 0.5,
|
|
||||||
gradientToColors: ["#ABE5A1"],
|
|
||||||
opacityFrom: 1,
|
|
||||||
opacityTo: 1,
|
|
||||||
stops: [0, 100],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
stroke: {
|
|
||||||
lineCap: "round",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div id="chart">
|
|
||||||
<ReactApexChart
|
|
||||||
options={options}
|
|
||||||
series={[percentage]}
|
|
||||||
type="radialBar"
|
|
||||||
height={100}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ProgressDonutChart;
|
|
||||||
@ -5,13 +5,12 @@ import useMaster from "../../hooks/masterHook/useMaster";
|
|||||||
import { useForm, Controller } from "react-hook-form";
|
import { useForm, Controller } from "react-hook-form";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { clearCacheKey, getCachedData } from "../../slices/apiDataManager";
|
import { getCachedData } from "../../slices/apiDataManager";
|
||||||
import { useEmployeesAllOrByProjectId } from "../../hooks/useEmployees";
|
import { useEmployeesAllOrByProjectId } from "../../hooks/useEmployees";
|
||||||
import { TasksRepository } from "../../repositories/ProjectRepository";
|
import { TasksRepository } from "../../repositories/ProjectRepository";
|
||||||
import showToast from "../../services/toastService";
|
import showToast from "../../services/toastService";
|
||||||
import { useProjectDetails } from "../../hooks/useProjects";
|
|
||||||
|
|
||||||
const AssignRoleModel = ({ assignData, onClose, setAssigned }) => {
|
const AssignRoleModel = ({ assignData, onClose }) => {
|
||||||
// Calculate maxPlanned based on assignData
|
// Calculate maxPlanned based on assignData
|
||||||
const maxPlanned =
|
const maxPlanned =
|
||||||
assignData?.workItem?.workItem?.plannedWork -
|
assignData?.workItem?.workItem?.plannedWork -
|
||||||
@ -51,11 +50,11 @@ const AssignRoleModel = ({ assignData, onClose, setAssigned }) => {
|
|||||||
// Initialize Bootstrap Popovers on component mount
|
// Initialize Bootstrap Popovers on component mount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Check if Bootstrap is available globally
|
// Check if Bootstrap is available globally
|
||||||
if (typeof bootstrap !== "undefined") {
|
if (typeof bootstrap !== 'undefined') {
|
||||||
if (infoRef.current) {
|
if (infoRef.current) {
|
||||||
new bootstrap.Popover(infoRef.current, {
|
new bootstrap.Popover(infoRef.current, {
|
||||||
trigger: "focus",
|
trigger: 'focus',
|
||||||
placement: "right",
|
placement: 'right',
|
||||||
html: true,
|
html: true,
|
||||||
content: `<div>Total Pending tasks of the Activity</div>`,
|
content: `<div>Total Pending tasks of the Activity</div>`,
|
||||||
});
|
});
|
||||||
@ -63,8 +62,8 @@ const AssignRoleModel = ({ assignData, onClose, setAssigned }) => {
|
|||||||
|
|
||||||
if (infoRef1.current) {
|
if (infoRef1.current) {
|
||||||
new bootstrap.Popover(infoRef1.current, {
|
new bootstrap.Popover(infoRef1.current, {
|
||||||
trigger: "focus",
|
trigger: 'focus',
|
||||||
placement: "right",
|
placement: 'right',
|
||||||
html: true,
|
html: true,
|
||||||
content: `<div>Target task for today</div>`,
|
content: `<div>Target task for today</div>`,
|
||||||
});
|
});
|
||||||
@ -73,6 +72,7 @@ const AssignRoleModel = ({ assignData, onClose, setAssigned }) => {
|
|||||||
console.warn("Bootstrap is not available. Popovers might not function.");
|
console.warn("Bootstrap is not available. Popovers might not function.");
|
||||||
}
|
}
|
||||||
}, []); // Empty dependency array ensures this runs once on mount
|
}, []); // Empty dependency array ensures this runs once on mount
|
||||||
|
|
||||||
// Redux state and hooks
|
// Redux state and hooks
|
||||||
const selectedProject = useSelector(
|
const selectedProject = useSelector(
|
||||||
(store) => store.localVariables.projectId
|
(store) => store.localVariables.projectId
|
||||||
@ -173,8 +173,6 @@ const AssignRoleModel = ({ assignData, onClose, setAssigned }) => {
|
|||||||
await TasksRepository.assignTask(formattedData);
|
await TasksRepository.assignTask(formattedData);
|
||||||
showToast("Task Successfully Assigned", "success"); // Show success toast
|
showToast("Task Successfully Assigned", "success"); // Show success toast
|
||||||
reset(); // Reset form fields
|
reset(); // Reset form fields
|
||||||
clearCacheKey("projectInfo");
|
|
||||||
setAssigned(formattedData.plannedTask)
|
|
||||||
onClose(); // Close the modal
|
onClose(); // Close the modal
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error assigning task:", error); // Log the full error for debugging
|
console.error("Error assigning task:", error); // Log the full error for debugging
|
||||||
@ -207,7 +205,7 @@ const AssignRoleModel = ({ assignData, onClose, setAssigned }) => {
|
|||||||
<div className="mb-1">
|
<div className="mb-1">
|
||||||
<p className="mb-0">
|
<p className="mb-0">
|
||||||
<span className="text-dark text-start d-flex align-items-center flex-wrap form-text">
|
<span className="text-dark text-start d-flex align-items-center flex-wrap form-text">
|
||||||
<span className="me-2 m-0 font-bold">Work Location :</span>
|
<p className="me-2 m-0 font-bold">Work Location :</p>
|
||||||
{[
|
{[
|
||||||
assignData?.building?.name,
|
assignData?.building?.name,
|
||||||
assignData?.floor?.floorName,
|
assignData?.floor?.floorName,
|
||||||
@ -305,9 +303,7 @@ const AssignRoleModel = ({ assignData, onClose, setAssigned }) => {
|
|||||||
type="checkbox"
|
type="checkbox"
|
||||||
id={`employee-${emp?.id}`}
|
id={`employee-${emp?.id}`}
|
||||||
value={emp.id}
|
value={emp.id}
|
||||||
checked={field.value?.includes(
|
checked={field.value?.includes(emp.id)}
|
||||||
emp.id
|
|
||||||
)}
|
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
handleCheckboxChange(e, emp);
|
handleCheckboxChange(e, emp);
|
||||||
}}
|
}}
|
||||||
@ -315,10 +311,7 @@ const AssignRoleModel = ({ assignData, onClose, setAssigned }) => {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<div className="flex-grow-1">
|
<div className="flex-grow-1">
|
||||||
<p
|
<p className="mb-0" style={{ fontSize: "13px" }}>
|
||||||
className="mb-0"
|
|
||||||
style={{ fontSize: "13px" }}
|
|
||||||
>
|
|
||||||
{emp.firstName} {emp.lastName}
|
{emp.firstName} {emp.lastName}
|
||||||
</p>
|
</p>
|
||||||
<small
|
<small
|
||||||
@ -340,9 +333,7 @@ const AssignRoleModel = ({ assignData, onClose, setAssigned }) => {
|
|||||||
})
|
})
|
||||||
) : (
|
) : (
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
<p className="text-center">
|
<p className="text-center">No employees found for the selected role.</p>
|
||||||
No employees found for the selected role.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -396,37 +387,23 @@ const AssignRoleModel = ({ assignData, onClose, setAssigned }) => {
|
|||||||
|
|
||||||
{!loading && errors.selectedEmployees && (
|
{!loading && errors.selectedEmployees && (
|
||||||
<div className="danger-text mt-1">
|
<div className="danger-text mt-1">
|
||||||
<p>{errors.selectedEmployees.message}</p>{" "}
|
<p>{errors.selectedEmployees.message}</p> {/* Use message from Zod schema */}
|
||||||
{/* Use message from Zod schema */}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Pending Task of Activity section */}
|
{/* Pending Task of Activity section */}
|
||||||
<div className="col-md text-start mx-0 px-0">
|
<div className="col-md text-start mx-0 px-0">
|
||||||
<div className="form-check form-check-inline mt-3 px-1">
|
<div className="form-check form-check-inline mt-3 px-1">
|
||||||
<label
|
<label className="form-text text-dark align-items-center d-flex" htmlFor="inlineCheckbox1">
|
||||||
className="form-text text-dark align-items-center d-flex"
|
|
||||||
htmlFor="inlineCheckbox1"
|
|
||||||
>
|
|
||||||
Pending Task of Activity :
|
Pending Task of Activity :
|
||||||
<label
|
<label className="form-check-label fs-7 ms-4" htmlFor="inlineCheckbox1">
|
||||||
className="form-check-label fs-7 ms-4"
|
|
||||||
htmlFor="inlineCheckbox1"
|
|
||||||
>
|
|
||||||
<strong>
|
<strong>
|
||||||
{assignData?.workItem?.workItem?.plannedWork -
|
{assignData?.workItem?.workItem?.plannedWork - assignData?.workItem?.workItem?.completedWork}
|
||||||
assignData?.workItem?.workItem?.completedWork}
|
|
||||||
</strong>{" "}
|
</strong>{" "}
|
||||||
<u>
|
<u>{assignData?.workItem?.workItem?.activityMaster?.unitOfMeasurement}</u>
|
||||||
{
|
|
||||||
assignData?.workItem?.workItem?.activityMaster
|
|
||||||
?.unitOfMeasurement
|
|
||||||
}
|
|
||||||
</u>
|
|
||||||
</label>
|
</label>
|
||||||
<div
|
|
||||||
style={{ display: "flex", alignItems: "center" }}
|
<div style={{ display: "flex", alignItems: "center" }}>
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
ref={infoRef}
|
ref={infoRef}
|
||||||
tabIndex="0"
|
tabIndex="0"
|
||||||
@ -462,14 +439,10 @@ const AssignRoleModel = ({ assignData, onClose, setAssigned }) => {
|
|||||||
className="text-dark text-start d-flex align-items-center flex-wrap form-text"
|
className="text-dark text-start d-flex align-items-center flex-wrap form-text"
|
||||||
htmlFor="inlineCheckbox1"
|
htmlFor="inlineCheckbox1"
|
||||||
>
|
>
|
||||||
<span>Target for Today</span>
|
<span>Target for Today</span> <span style={{ marginLeft: '46px' }}>:</span>
|
||||||
<span style={{ marginLeft: "46px" }}>:</span>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div className="form-check form-check-inline col-sm-3 mt-2" style={{ marginLeft: '-28px' }}>
|
||||||
className="form-check form-check-inline col-sm-3 mt-2"
|
|
||||||
style={{ marginLeft: "-28px" }}
|
|
||||||
>
|
|
||||||
<Controller
|
<Controller
|
||||||
name="plannedTask"
|
name="plannedTask"
|
||||||
control={control}
|
control={control}
|
||||||
@ -482,18 +455,10 @@ const AssignRoleModel = ({ assignData, onClose, setAssigned }) => {
|
|||||||
id="defaultFormControlInput"
|
id="defaultFormControlInput"
|
||||||
aria-describedby="defaultFormControlHelp"
|
aria-describedby="defaultFormControlHelp"
|
||||||
/>
|
/>
|
||||||
<span style={{ paddingLeft: "6px" }}>
|
<span style={{ paddingLeft: '6px' }}>
|
||||||
{
|
{assignData?.workItem?.workItem?.activityMaster?.unitOfMeasurement}
|
||||||
assignData?.workItem?.workItem?.activityMaster
|
|
||||||
?.unitOfMeasurement
|
|
||||||
}
|
|
||||||
</span>
|
</span>
|
||||||
<div
|
<div style={{ display: "flex", alignItems: "center" }}>
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
ref={infoRef1}
|
ref={infoRef1}
|
||||||
tabIndex="0"
|
tabIndex="0"
|
||||||
@ -524,20 +489,16 @@ const AssignRoleModel = ({ assignData, onClose, setAssigned }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{errors.plannedTask && (
|
{errors.plannedTask && (
|
||||||
<div className="danger-text mt-1">
|
<div className="danger-text mt-1">{errors.plannedTask.message}</div>
|
||||||
{errors.plannedTask.message}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{isHelpVisible && (
|
{isHelpVisible && (
|
||||||
<div
|
<div
|
||||||
className="position-absolute bg-white border p-2 rounded shadow"
|
className="position-absolute bg-white border p-2 rounded shadow"
|
||||||
style={{ zIndex: 10, marginLeft: "10px" }}
|
style={{ zIndex: 10, marginLeft: '10px' }}
|
||||||
>
|
>
|
||||||
{/* Add your help content here */}
|
{/* Add your help content here */}
|
||||||
<p className="mb-0">
|
<p className="mb-0">Enter the target value for today's task.</p>
|
||||||
Enter the target value for today's task.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -25,7 +25,7 @@ const Floor = ({ floor, workAreas, forBuilding }) => {
|
|||||||
</div> */}
|
</div> */}
|
||||||
<div className="col-12 ps-8">
|
<div className="col-12 ps-8">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="d-flex col-5">
|
<div className="col">
|
||||||
{" "}
|
{" "}
|
||||||
<span className="fw-semibold text-primary">
|
<span className="fw-semibold text-primary">
|
||||||
Floor:
|
Floor:
|
||||||
@ -34,13 +34,6 @@ const Floor = ({ floor, workAreas, forBuilding }) => {
|
|||||||
{floor.floorName}
|
{floor.floorName}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-start col-5">
|
|
||||||
{" "}
|
|
||||||
<span className="fw-semibold text-primary">
|
|
||||||
Work Area:
|
|
||||||
</span>{" "}
|
|
||||||
<span className="fw-normal text-danger">Not Available</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -68,6 +68,7 @@ const InfraTable = ({ buildings }) => {
|
|||||||
showToast("Failed to save floor", "error");
|
showToast("Failed to save floor", "error");
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
||||||
showToast("Error occurred while saving floor", "error");
|
showToast("Error occurred while saving floor", "error");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -94,14 +95,14 @@ const InfraTable = ({ buildings }) => {
|
|||||||
No floors have been added yet. Start by adding floors to manage
|
No floors have been added yet. Start by adding floors to manage
|
||||||
this building.
|
this building.
|
||||||
</p>
|
</p>
|
||||||
{/* <button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-xs btn-primary"
|
className="btn btn-xs btn-primary"
|
||||||
onClick={() => handleAddFloor(building)}
|
onClick={() => handleAddFloor(building)}
|
||||||
>
|
>
|
||||||
<i className="bx bx-plus-circle me-2"></i>
|
<i className="bx bx-plus-circle me-2"></i>
|
||||||
Add Floors
|
Add Floors
|
||||||
</button> */}
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@ -6,46 +6,20 @@ import { useDispatch } from "react-redux";
|
|||||||
import { refreshData } from "../../../slices/localVariablesSlice";
|
import { refreshData } from "../../../slices/localVariablesSlice";
|
||||||
import ProjectRepository from "../../../repositories/ProjectRepository";
|
import ProjectRepository from "../../../repositories/ProjectRepository";
|
||||||
import showToast from "../../../services/toastService";
|
import showToast from "../../../services/toastService";
|
||||||
import { useHasUserPermission } from "../../../hooks/useHasUserPermission";
|
import {useHasUserPermission} from "../../../hooks/useHasUserPermission";
|
||||||
import {
|
import {ASSIGN_REPORT_TASK, MANAGE_PROJECT_INFRA, MANAGE_TASK} from "../../../utils/constants";
|
||||||
ASSIGN_REPORT_TASK,
|
import {useParams} from "react-router-dom";
|
||||||
MANAGE_PROJECT_INFRA,
|
|
||||||
MANAGE_TASK,
|
|
||||||
} from "../../../utils/constants";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import ProgressDonutChart from "../../Charts/ProgressDonutChart";
|
|
||||||
import ProgressBar from "../../common/ProgressBar";
|
|
||||||
import { componentsToColor } from "pdf-lib";
|
|
||||||
|
|
||||||
const WorkArea = ({ workArea, floor, forBuilding }) => {
|
const WorkArea = ({ workArea, floor, forBuilding }) => {
|
||||||
const [workItems, setWorkItems] = useState([]);
|
const [workItems, setWorkItems] = useState([]);
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const [Project, setProject] = useState();
|
const [ Project, setProject ] = useState();
|
||||||
const { projectId } = useParams();
|
const {projectId} = useParams();
|
||||||
|
|
||||||
const ManageTasks = useHasUserPermission(MANAGE_TASK);
|
const ManageTasks = useHasUserPermission(MANAGE_TASK);
|
||||||
const ManageInfra = useHasUserPermission(MANAGE_PROJECT_INFRA);
|
const ManageInfra = useHasUserPermission(MANAGE_PROJECT_INFRA);
|
||||||
const ManageAndAssignTak = useHasUserPermission(ASSIGN_REPORT_TASK);
|
const ManageAndAssignTak = useHasUserPermission( ASSIGN_REPORT_TASK );
|
||||||
|
|
||||||
const [workAreaStatus, setWorkAreaStatus] = useState({
|
|
||||||
completed: 0,
|
|
||||||
planned: 100,
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const totalCompleted = workItems.reduce(
|
|
||||||
(sum, i) => sum + (i.workItem?.completedWork || 0),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
const totalPlanned = workItems.reduce(
|
|
||||||
(sum, i) => sum + (i.workItem?.plannedWork || 0),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
const percent =
|
|
||||||
totalPlanned > 0 ? (totalCompleted / totalPlanned) * 100 : 0;
|
|
||||||
//setPercentComplete(Math.min(percent, 100)); // cap at 100%
|
|
||||||
setWorkAreaStatus({ completed: totalCompleted, planned: totalPlanned });
|
|
||||||
}, [workItems]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const project = getCachedData("projectInfo");
|
const project = getCachedData("projectInfo");
|
||||||
@ -179,32 +153,21 @@ const WorkArea = ({ workArea, floor, forBuilding }) => {
|
|||||||
}}
|
}}
|
||||||
></i>
|
></i>
|
||||||
|
|
||||||
<div className="d-flex justify-content-start row w-100 align-items-center">
|
<div className="d-flex justify-content-start gap-12">
|
||||||
<div className="d-flex col-5">
|
<div className="d-flex">
|
||||||
<span className="fw-semibold text-primary small">
|
<span className="fw-semibold small">Floor: </span>
|
||||||
Floor:
|
<span className="fw-normal text-darkgreen small">
|
||||||
</span>
|
|
||||||
<span className="fw-normal text-darkgreen small px-2">
|
|
||||||
{floor.floorName}
|
{floor.floorName}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-start col-5">
|
<div className="text-start ">
|
||||||
<span className="fw-semibold text-primary small">
|
<span className="fw-semibold text-primary small">
|
||||||
Work Area:
|
Work Area:
|
||||||
</span>
|
</span>
|
||||||
<span className="fw-normal text-darkgreen small px-2">
|
<span className="fw-normal text-darkgreen small">
|
||||||
{workArea.areaName}
|
{workArea.areaName}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{workArea?.workItems?.length > 0 && (
|
|
||||||
<div className="col-2">
|
|
||||||
<ProgressBar
|
|
||||||
completedWork={workAreaStatus.completed}
|
|
||||||
plannedWork={workAreaStatus.planned}
|
|
||||||
className="m-0 text-info"
|
|
||||||
></ProgressBar>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
@ -232,14 +195,10 @@ const WorkArea = ({ workArea, floor, forBuilding }) => {
|
|||||||
<th className="infra-activity-table-header d-none d-md-table-cell">
|
<th className="infra-activity-table-header d-none d-md-table-cell">
|
||||||
Completed/Planned
|
Completed/Planned
|
||||||
</th>
|
</th>
|
||||||
<th className="infra-activity-table-header d-none d-md-table-cell">
|
|
||||||
Today's Planned
|
|
||||||
</th>
|
|
||||||
<th className="infra-activity-table-header">
|
<th className="infra-activity-table-header">
|
||||||
Progress
|
Progress
|
||||||
</th>
|
</th>
|
||||||
{(ManageInfra ||
|
{( ManageInfra || ( !projectId && ManageAndAssignTak ) ) && (
|
||||||
(!projectId && ManageAndAssignTak)) && (
|
|
||||||
<th className="infra-activity-table-header text-end">
|
<th className="infra-activity-table-header text-end">
|
||||||
<span className="px-2">Actions</span>
|
<span className="px-2">Actions</span>
|
||||||
</th>
|
</th>
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import { useDispatch } from "react-redux";
|
|||||||
import { refreshData } from "../../../slices/localVariablesSlice";
|
import { refreshData } from "../../../slices/localVariablesSlice";
|
||||||
|
|
||||||
const WorkItem = ({
|
const WorkItem = ({
|
||||||
|
key,
|
||||||
workItem,
|
workItem,
|
||||||
forBuilding,
|
forBuilding,
|
||||||
forFloor,
|
forFloor,
|
||||||
@ -54,15 +55,6 @@ const WorkItem = ({
|
|||||||
setNewWorkItem(workItem);
|
setNewWorkItem(workItem);
|
||||||
}, [workItem]);
|
}, [workItem]);
|
||||||
|
|
||||||
const refreshWorkItem = (plannedTask) =>{
|
|
||||||
if (workItem) {
|
|
||||||
const updated = {
|
|
||||||
...workItem,
|
|
||||||
todaysAssigned: (workItem.todaysAssigned || 0) + plannedTask,
|
|
||||||
};
|
|
||||||
setNewWorkItem(updated);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let assigndata = {
|
let assigndata = {
|
||||||
building: forBuilding,
|
building: forBuilding,
|
||||||
floor: forFloor,
|
floor: forFloor,
|
||||||
@ -105,7 +97,7 @@ const WorkItem = ({
|
|||||||
style={{ display: isModalOpen ? "block" : "none" }}
|
style={{ display: isModalOpen ? "block" : "none" }}
|
||||||
aria-hidden={!isModalOpen}
|
aria-hidden={!isModalOpen}
|
||||||
>
|
>
|
||||||
<AssignRoleModel assignData={assigndata} onClose={closeModal} setAssigned={refreshWorkItem} />
|
<AssignRoleModel assignData={assigndata} onClose={closeModal} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -149,7 +141,7 @@ const WorkItem = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<tr key={NewWorkItem?.workItemId}>
|
<tr key={key}>
|
||||||
{/* Activity Name - always visible */}
|
{/* Activity Name - always visible */}
|
||||||
<td className="text-start table-cell-small">
|
<td className="text-start table-cell-small">
|
||||||
<i className="bx bx-right-arrow-alt"></i>
|
<i className="bx bx-right-arrow-alt"></i>
|
||||||
@ -199,16 +191,6 @@ const WorkItem = ({
|
|||||||
: "NA"}
|
: "NA"}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td className="text-center d-none d-md-table-cell">
|
|
||||||
{hasWorkItem
|
|
||||||
? `${
|
|
||||||
NewWorkItem?.todaysAssigned ??
|
|
||||||
workItem?.todaysAssigned ??
|
|
||||||
"0"
|
|
||||||
}`
|
|
||||||
: "NA"}
|
|
||||||
</td>
|
|
||||||
|
|
||||||
{/* Progress Bar - always visible */}
|
{/* Progress Bar - always visible */}
|
||||||
<td className="text-center " style={{ width: "15%" }}>
|
<td className="text-center " style={{ width: "15%" }}>
|
||||||
<div className="progress p-0">
|
<div className="progress p-0">
|
||||||
|
|||||||
@ -99,17 +99,9 @@ const Teams = ({ project }) => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
submitAllocations(items, true);
|
submitAllocations( items ,true);
|
||||||
|
|
||||||
// Force switch to active view after assignment
|
|
||||||
setActiveEmployee(true);
|
|
||||||
setFilteredEmployees(employees.filter((emp) => emp.isActive));
|
|
||||||
|
|
||||||
// Also update dropdown select if needed
|
|
||||||
const dropdown = document.querySelector('select[name="DataTables_Table_0_length"]');
|
|
||||||
if (dropdown) dropdown.value = "true";
|
|
||||||
};
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
const getRole = (jobRoleId) => {
|
const getRole = (jobRoleId) => {
|
||||||
if (loading) return "Loading...";
|
if (loading) return "Loading...";
|
||||||
@ -341,12 +333,8 @@ const Teams = ({ project }) => {
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
)}
|
)}
|
||||||
{!employeeLodaing && filteredEmployees.length === 0 && (
|
{(!employeeLodaing && employees.length == 0 )&& (
|
||||||
<div className="text-center text-muted py-3">
|
<span>No employees assigned to the project</span>
|
||||||
{activeEmployee
|
|
||||||
? "No active employees assigned to the project"
|
|
||||||
: "No inactive employees assigned to the project"}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -25,6 +25,7 @@ const MasterModal = ({ modaldata, closeModal }) => {
|
|||||||
const handleSelectedMasterDeleted = async () =>
|
const handleSelectedMasterDeleted = async () =>
|
||||||
{
|
{
|
||||||
const deleteFn = MasterRespository[modaldata.masterType];
|
const deleteFn = MasterRespository[modaldata.masterType];
|
||||||
|
|
||||||
if (!deleteFn) {
|
if (!deleteFn) {
|
||||||
showToast(`No delete strategy defined for master type`,"error");
|
showToast(`No delete strategy defined for master type`,"error");
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -59,28 +59,13 @@ const AttendancesEmployeeRecords = ({ employee }) => {
|
|||||||
.sort(sortByName);
|
.sort(sortByName);
|
||||||
const group5 = data.filter((d) => d.activity === 5).sort(sortByName);
|
const group5 = data.filter((d) => d.activity === 5).sort(sortByName);
|
||||||
|
|
||||||
// const sortedFinalList = [
|
const sortedFinalList = [
|
||||||
// ...group1,
|
...group1,
|
||||||
// ...group2,
|
...group2,
|
||||||
// ...group3,
|
...group3,
|
||||||
// ...group4,
|
...group4,
|
||||||
// ...group5,
|
...group5,
|
||||||
// ];
|
];
|
||||||
|
|
||||||
const uniqueMap = new Map();
|
|
||||||
|
|
||||||
[...group1, ...group2, ...group3, ...group4, ...group5].forEach((rec) => {
|
|
||||||
const date = moment(rec.checkInTime || rec.checkOutTime).format("YYYY-MM-DD");
|
|
||||||
const key = `${rec.employeeId}-${date}`;
|
|
||||||
const existing = uniqueMap.get(key);
|
|
||||||
if (!existing || new Date(rec.checkInTime || rec.checkOutTime) > new Date(existing.checkInTime || existing.checkOutTime)) {
|
|
||||||
uniqueMap.set(key, rec);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const sortedFinalList = [...uniqueMap.values()].sort((a, b) =>
|
|
||||||
new Date(b.checkInTime || b.checkOutTime) - new Date(a.checkInTime || a.checkOutTime)
|
|
||||||
);
|
|
||||||
|
|
||||||
const currentDate = new Date().toLocaleDateString("en-CA");
|
const currentDate = new Date().toLocaleDateString("en-CA");
|
||||||
const { currentPage, totalPages, currentItems, paginate } = usePagination(
|
const { currentPage, totalPages, currentItems, paginate } = usePagination(
|
||||||
|
|||||||
@ -398,7 +398,7 @@ const EmployeeList = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={`text-end mb-2 ${selectedProject ? 'd-none' : ''}`}>
|
<div className="text-end mb-2">
|
||||||
<label className="switch switch-primary">
|
<label className="switch switch-primary">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
|||||||
@ -41,7 +41,7 @@ export const MasterRespository = {
|
|||||||
"Activity": ( id ) => api.delete( `/api/master/activity/delete/${ id }` ),
|
"Activity": ( id ) => api.delete( `/api/master/activity/delete/${ id }` ),
|
||||||
"Application Role":(id)=>api.delete(`/api/roles/${id}`),
|
"Application Role":(id)=>api.delete(`/api/roles/${id}`),
|
||||||
"Work Category": ( id ) => api.delete( `api/master/work-category/${ id }` ),
|
"Work Category": ( id ) => api.delete( `api/master/work-category/${ id }` ),
|
||||||
"Contact Category": ( id ) => api.delete( `/api/master/contact-category` ),
|
"Contact Category": ( id ) => api.delete( `/api/master/contact-category/${id}` ),
|
||||||
"Contact Tag" :(id)=>api.delete(`/api/master/contact-tag/${id}`),
|
"Contact Tag" :(id)=>api.delete(`/api/master/contact-tag/${id}`),
|
||||||
|
|
||||||
getWorkCategory:() => api.get(`/api/master/work-categories`),
|
getWorkCategory:() => api.get(`/api/master/work-categories`),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user