From 9763c455923cfc55210694173e814d05fded336c Mon Sep 17 00:00:00 2001 From: "kartik.sharma" Date: Mon, 26 May 2025 12:54:24 +0530 Subject: [PATCH 01/16] In Report Popup from Daily Progress Report where validation message not showing properly in Completed Work Text box. --- src/components/Activities/ReportTask.jsx | 37 +++++++++++++++++------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/components/Activities/ReportTask.jsx b/src/components/Activities/ReportTask.jsx index 58d8ccd5..1b1f0188 100644 --- a/src/components/Activities/ReportTask.jsx +++ b/src/components/Activities/ReportTask.jsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useState,useEffect } from "react"; import { formatDate } from "../../utils/dateUtils"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; @@ -13,15 +13,23 @@ export const ReportTask = ({ report, closeModal, refetch }) => { report?.workItem?.plannedWork - report?.workItem?.completedWork; const schema = z.object({ - completedTask: z - .number() - .min(0, "Completed Work must be greater than 0") - .max(maxPending, { - message: `Completed task cannot exceed total pending tasks: ${maxPending}`, - }) - .optional(), - comment: z.string().min(1, "Comment cannot be empty"), - }); + completedTask: z + .preprocess( + (val) => (val === "" || val === null || Number.isNaN(val) ? undefined : Number(val)), + z + .number({ + required_error: "Completed Work must be a number", + invalid_type_error: "Completed Work must be a number", + }) + .min(1, "Completed Work must be greater than 0") + .max(maxPending, { + message: `Completed task cannot exceed total pending tasks: ${maxPending}`, + }) + ), + comment: z.string().min(1, "Comment cannot be empty"), +}); + + const { register, handleSubmit, @@ -32,6 +40,14 @@ export const ReportTask = ({ report, closeModal, refetch }) => { defaultValues: { completedTask: 0, comment: "" }, }); + +useEffect(() => { + if (report) { + reset({ completedTask: 0, comment: "" }); // optional: customize default if needed + } +}, [report, reset]); + + const onSubmit = async (data) => { try { setloading(true); @@ -56,6 +72,7 @@ export const ReportTask = ({ report, closeModal, refetch }) => { }; const handleClose = () => { closeModal(); + reset(); }; return ( From 126ed3809f68cec77427de9cf399c82949ffe026 Mon Sep 17 00:00:00 2001 From: "kartik.sharma" Date: Tue, 27 May 2025 09:58:20 +0530 Subject: [PATCH 02/16] In Assign Role popup double loading is visible. --- src/components/Project/AssignRole.jsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/components/Project/AssignRole.jsx b/src/components/Project/AssignRole.jsx index a639abc8..65badfb7 100644 --- a/src/components/Project/AssignRole.jsx +++ b/src/components/Project/AssignRole.jsx @@ -273,13 +273,6 @@ const AssignRoleModel = ({ assignData, onClose }) => { - {employeeLoading &&
Loading employees...
} - {!employeeLoading && - filteredEmployees?.length === 0 && - employees && ( -
No employees found for the selected role.
- )} -
{selectedRole !== "" && ( From 50d5c69db1edab5d40e28a78cec25c4693eba67c Mon Sep 17 00:00:00 2001 From: "kartik.sharma" Date: Tue, 27 May 2025 11:53:56 +0530 Subject: [PATCH 03/16] Convert all date to DD-MM-YYYY accross all component. --- src/components/Activities/AttendcesLogs.jsx | 4 +-- src/components/common/DateRangePicker.jsx | 2 +- src/pages/Activities/DailyTask.jsx | 38 +++++++++++---------- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/components/Activities/AttendcesLogs.jsx b/src/components/Activities/AttendcesLogs.jsx index b57a9c75..feda6c77 100644 --- a/src/components/Activities/AttendcesLogs.jsx +++ b/src/components/Activities/AttendcesLogs.jsx @@ -127,7 +127,7 @@ const AttendanceLog = ({ handleModalData, projectId, showOnlyCheckout }) => { id="DataTables_Table_0_length" >
- +
{ acc.push( - {moment(currentDate).format("YYYY-MM-DD")} + {moment(currentDate).format("DD-MM-YYYY")} ); diff --git a/src/components/common/DateRangePicker.jsx b/src/components/common/DateRangePicker.jsx index 07c36e11..c56e742e 100644 --- a/src/components/common/DateRangePicker.jsx +++ b/src/components/common/DateRangePicker.jsx @@ -12,7 +12,7 @@ const DateRangePicker = ({ onRangeChange, DateDifference = 7, defaultStartDate = const fp = flatpickr(inputRef.current, { mode: "range", - dateFormat: "Y-m-d", + dateFormat: "d-m-Y", defaultDate: [fifteenDaysAgo, today], static: true, clickOpens: true, diff --git a/src/pages/Activities/DailyTask.jsx b/src/pages/Activities/DailyTask.jsx index 5b69c596..58e7d57e 100644 --- a/src/pages/Activities/DailyTask.jsx +++ b/src/pages/Activities/DailyTask.jsx @@ -6,7 +6,7 @@ import { useTaskList } from "../../hooks/useTasks"; import { useProjects } from "../../hooks/useProjects"; import { setProjectId } from "../../slices/localVariablesSlice"; import { useProfile } from "../../hooks/useProfile"; -import { formatDate } from "../../utils/dateUtils"; +// import { formatDate } from "../../utils/dateUtils"; // Removed this import import GlobalModel from "../../components/common/GlobalModel"; import AssignRoleModel from "../../components/Project/AssignRole"; import { ReportTask } from "../../components/Activities/ReportTask"; @@ -14,6 +14,7 @@ import ReportTaskComments from "../../components/Activities/ReportTaskComments"; import DateRangePicker from "../../components/common/DateRangePicker"; import DatePicker from "../../components/common/DatePicker"; import { useSearchParams } from "react-router-dom"; +import moment from "moment"; const DailyTask = () => { const [searchParams] = useSearchParams(); @@ -141,6 +142,7 @@ const DailyTask = () => {
@@ -188,7 +190,7 @@ const DailyTask = () => { )} {!task_loading && TaskList.length === 0 && ( - +

No Reports Found

@@ -199,7 +201,7 @@ const DailyTask = () => { - {date} + {moment(date).format("DD-MM-YYYY")} {TaskLists.filter((task) => @@ -246,7 +248,7 @@ const DailyTask = () => { task.workItem.completedWork} {task.completedTask} - {formatDate(task.assignmentDate)} + {moment(task.assignmentDate).format("DD-MM-YYYY")}
{ ${task.teamMembers .map( (member) => ` -
-
- - ${ - member?.firstName?.charAt( - 0 - ) || "" - }${ +
+
+ + ${ + member?.firstName?.charAt( + 0 + ) || "" + }${ member?.lastName?.charAt(0) || "" } - -
- ${member.firstName} ${ + +
+ ${member.firstName} ${ member.lastName } -
- ` +
+ ` ) .join("")}
@@ -362,4 +364,4 @@ const DailyTask = () => { ); }; -export default DailyTask; +export default DailyTask; \ No newline at end of file From 235ddb58baae3a642a62639c896b3c84834dcfd8 Mon Sep 17 00:00:00 2001 From: "kartik.sharma" Date: Tue, 27 May 2025 15:06:12 +0530 Subject: [PATCH 04/16] In Create New Project form is not empty when we click on cancel button or cross. --- src/components/Project/ManageProjectInfo.jsx | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/components/Project/ManageProjectInfo.jsx b/src/components/Project/ManageProjectInfo.jsx index 41d2cb24..a03077f9 100644 --- a/src/components/Project/ManageProjectInfo.jsx +++ b/src/components/Project/ManageProjectInfo.jsx @@ -102,13 +102,21 @@ const ManageProjectInfo = ({ project, handleSubmitForm, onClose }) => { const onSubmitForm = (updatedProject) => { setLoading(true); handleSubmitForm( updatedProject, setLoading,reset ); - - + }; + const handleCancel = () => { + reset({ + id: project?.id || "", + name: project?.name || "", + contactPerson: project?.contactPerson || "", + projectAddress: project?.projectAddress || "", + startDate: formatDate(project?.startDate) || currentDate, + endDate: formatDate(project?.endDate) || currentDate, + projectStatusId: String(project?.projectStatusId || "00000000-0000-0000-0000-000000000000"), + }); + onClose(); }; - - return (
{
@@ -280,7 +288,7 @@ const ManageProjectInfo = ({ project, handleSubmitForm, onClose }) => { -

Activity Summary

+
+ Activity Summary +
+ +

- {comments && comments[0]?.comment} + {commentsData?.workItem?.workArea?.floor?.building?.description}

+

Assigned By : @@ -126,7 +140,7 @@ const ReportTaskComments = ({ commentsData, closeModal }) => { Completed Work : {commentsData?.completedTask}

-

Team:

+

Team :

{commentsData?.teamMembers?.map((member, idx) => ( @@ -147,7 +161,7 @@ const ReportTaskComments = ({ commentsData, closeModal }) => { {...register("comment")} className="form-control" id="exampleFormControlTextarea1" - rows="1" + // rows="2" placeholder="Enter comment" /> {errors.comment && ( @@ -170,8 +184,8 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
    {comments && comments @@ -196,9 +210,9 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
-
-

{fullName}

-

+

+

{fullName}

+

{moment.utc(data?.commentDate).local().fromNow()}

From 94c943040637af2f71d71014390d84782e5b455f Mon Sep 17 00:00:00 2001 From: "kartik.sharma" Date: Tue, 27 May 2025 17:24:14 +0530 Subject: [PATCH 06/16] Changes in Comment popup --- src/components/Activities/ReportTaskComments.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Activities/ReportTaskComments.jsx b/src/components/Activities/ReportTaskComments.jsx index 5b494758..91399b79 100644 --- a/src/components/Activities/ReportTaskComments.jsx +++ b/src/components/Activities/ReportTaskComments.jsx @@ -212,7 +212,7 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {

{fullName}

-

+

{moment.utc(data?.commentDate).local().fromNow()}

From 08805405606de51d92d7a764977a281bd9dc1cf5 Mon Sep 17 00:00:00 2001 From: "kartik.sharma" Date: Wed, 28 May 2025 12:03:36 +0530 Subject: [PATCH 07/16] Comments popup submit button issue. --- .../Activities/ReportTaskComments.jsx | 84 +++++++++++-------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/src/components/Activities/ReportTaskComments.jsx b/src/components/Activities/ReportTaskComments.jsx index 91399b79..9db42b3a 100644 --- a/src/components/Activities/ReportTaskComments.jsx +++ b/src/components/Activities/ReportTaskComments.jsx @@ -25,12 +25,11 @@ const schema = z.object({ const ReportTaskComments = ({ commentsData, closeModal }) => { const [loading, setloading] = useState(false); const [comments, setComment] = useState([]); - const [bgClass, setBgClass] = useState(""); const { register, handleSubmit, formState: { errors }, - reset, + reset, // Destructure reset from useForm } = useForm({ resolver: zodResolver(schema), }); @@ -38,19 +37,28 @@ const ReportTaskComments = ({ commentsData, closeModal }) => { const containerRef = useRef(null); const firstRender = useRef(true); - useEffect(() => { - setComment(commentsData?.comments); + const taskList = getCachedData("taskList"); + if (taskList && taskList.data && commentsData?.id) { + const currentTask = taskList.data.find(task => task.id === commentsData.id); + if (currentTask && currentTask.comments) { + setComment(currentTask.comments); + } else { + setComment(commentsData?.comments || []); + } + } else { + setComment(commentsData?.comments || []); + } + firstRender.current = true; }, [commentsData]); - // Scroll logic: scroll to bottom when new comments are added useEffect(() => { if (!firstRender.current && containerRef.current) { containerRef.current.scrollTop = containerRef.current.scrollHeight; } else { - firstRender.current = false; // Mark the first render as complete + firstRender.current = false; } - }, [comments]); // Run this when comments array is updated + }, [comments]); const onSubmit = async (data) => { let sendComment = { @@ -61,34 +69,40 @@ const ReportTaskComments = ({ commentsData, closeModal }) => { try { setloading(true); const resp = await TasksRepository.taskComments(sendComment); + setComment((prevItems) => [...prevItems, resp.data]); + const taskList = getCachedData("taskList"); - const updatedTaskList = taskList.data.map((task) => { - if (task.id === resp.data.taskAllocationId) { - const existingComments = Array.isArray(task.comments) - ? task.comments - : []; - return { - ...task, - comments: [...existingComments, resp.data], - }; - } - return task; - }); - cacheData("taskList", { - data: updatedTaskList, - projectId: taskList.projectId, - }); - reset(); + + if (taskList && taskList.data) { + const updatedTaskList = taskList.data.map((task) => { + if (task.id === resp.data.taskAllocationId) { + const existingComments = Array.isArray(task.comments) + ? task.comments + : []; + return { + ...task, + comments: [...existingComments, resp.data], + }; + } + return task; + }); + + cacheData("taskList", { + data: updatedTaskList, + projectId: taskList.projectId, + }); + } + + reset(); setloading(false); showToast("Successfully Sent", "success"); - // closeModal(); } catch (error) { setloading(false); showToast(error.response.data?.message || "Something went wrong", "error"); } }; - console.log("Kartik", commentsData) + return (
{ Activity Summary -

{commentsData?.workItem?.workArea?.floor?.building?.description}

@@ -114,9 +127,9 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {

Assigned By : - {commentsData?.assignedBy.firstName + + {commentsData?.assignedBy?.firstName + " " + - commentsData?.assignedBy.lastName} + commentsData?.assignedBy?.lastName} {" "}

@@ -161,7 +174,6 @@ const ReportTaskComments = ({ commentsData, closeModal }) => { {...register("comment")} className="form-control" id="exampleFormControlTextarea1" - // rows="2" placeholder="Enter comment" /> {errors.comment && ( @@ -176,7 +188,7 @@ const ReportTaskComments = ({ commentsData, closeModal }) => { > Close -
@@ -184,23 +196,21 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
    {comments && comments ?.slice() - .reverse() + .reverse() .map((data, idx) => { const fullName = `${data?.employee?.firstName} ${data?.employee?.lastName}`; - const bgClass = getBgClassFromHash(fullName); return (
  • {
    -
    +

    {fullName}

    {moment.utc(data?.commentDate).local().fromNow()} From 627d4f898e28db3ed933670c09d01757d01a923d Mon Sep 17 00:00:00 2001 From: "kartik.sharma" Date: Wed, 28 May 2025 13:06:03 +0530 Subject: [PATCH 08/16] Adding new Weidget in Dashboadr name is "Pending Attendance". --- src/components/Dashboard/Dashboard.jsx | 15 +++++++-- .../Dashboard/PendingAttendance.jsx | 32 +++++++++++++++++++ src/hooks/useDashboard_Data.jsx | 28 ++++++++++++++++ src/repositories/GlobalRepository.jsx | 3 ++ 4 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 src/components/Dashboard/PendingAttendance.jsx diff --git a/src/components/Dashboard/Dashboard.jsx b/src/components/Dashboard/Dashboard.jsx index 1e4cceaf..cb8e7e74 100644 --- a/src/components/Dashboard/Dashboard.jsx +++ b/src/components/Dashboard/Dashboard.jsx @@ -3,36 +3,45 @@ import { useDashboardProjectsCardData, useDashboardTeamsCardData, useDashboardTasksCardData, + useDashboardPendingAttendenceData, } from "../../hooks/useDashboard_Data"; import Projects from "./Projects"; import Teams from "./Teams"; import TasksCard from "./Tasks"; import ProjectCompletionChart from "./ProjectCompletionChart"; import ProjectProgressChart from "./ProjectProgressChart"; +import PendingAttendance from "./PendingAttendance"; const Dashboard = () => { const { projectsCardData } = useDashboardProjectsCardData(); const { teamsCardData } = useDashboardTeamsCardData(); const { tasksCardData } = useDashboardTasksCardData(); + const {PendingAttendenceData} = useDashboardPendingAttendenceData(); + return (

    {/* Projects Card */} -
    +
    {/* Teams Card */} -
    +
    {/* Tasks Card */} -
    +
    + {/* Pending Attendance */} +
    + +
    + {/* Bar Chart (Project Completion) */}
    diff --git a/src/components/Dashboard/PendingAttendance.jsx b/src/components/Dashboard/PendingAttendance.jsx new file mode 100644 index 00000000..f3f1ec04 --- /dev/null +++ b/src/components/Dashboard/PendingAttendance.jsx @@ -0,0 +1,32 @@ +import React from "react"; +import { useDashboardPendingAttendenceData } from "../../hooks/useDashboard_Data"; + +const PendingAttendance = () => { + const { PendingAttendenceData } = useDashboardPendingAttendenceData(); + + return ( +
    +
    +
    + Pending Attendence +
    +
    +
    +
    +

    + {PendingAttendenceData.pendingCheckOut?.toLocaleString()} +

    + Checkout +
    +
    +

    + {PendingAttendenceData.pendingRegularization?.toLocaleString()} +

    + Regularization +
    +
    +
    + ); +}; + +export default PendingAttendance; \ No newline at end of file diff --git a/src/hooks/useDashboard_Data.jsx b/src/hooks/useDashboard_Data.jsx index 5cf03f91..e3e86dac 100644 --- a/src/hooks/useDashboard_Data.jsx +++ b/src/hooks/useDashboard_Data.jsx @@ -120,3 +120,31 @@ export const useDashboardTasksCardData = () => { return { tasksCardData, loading, error }; }; + +export const useDashboardPendingAttendenceData = () => { + const [PendingAttendenceData, setPendingAttendence] = useState([]); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(""); + + useEffect(() => { + const fetchPendingAttendence = async () => { + setLoading(true); + setError(""); + + try { + const response = await GlobalRepository.getDashboardPendingAttendence(); + setPendingAttendence(response.data); + } catch (err) { + setError("Failed to fetch Pending Attendence card data."); + console.error(err); + } finally { + setLoading(false); + } + }; + + fetchPendingAttendence(); + }, []); + + return { PendingAttendenceData, loading, error }; +}; + diff --git a/src/repositories/GlobalRepository.jsx b/src/repositories/GlobalRepository.jsx index 31468b66..5ee67f01 100644 --- a/src/repositories/GlobalRepository.jsx +++ b/src/repositories/GlobalRepository.jsx @@ -27,6 +27,9 @@ const GlobalRepository = { getDashboardTasksCardData: () => { return api.get(`/api/Dashboard/tasks`); }, +getDashboardPendingAttendence: () => { + return api.get(`/api/dashboard/pending-attendance`); + }, }; From d16675bf71667ed13eb5bb192ba8f3effac2410f Mon Sep 17 00:00:00 2001 From: "kartik.sharma" Date: Fri, 30 May 2025 16:19:20 +0530 Subject: [PATCH 09/16] Adding New Weidge in Dashboard Name is "Activity". --- src/components/Charts/Circlechart.jsx | 85 +++++++++++ src/components/Dashboard/Activity.jsx | 194 +++++++++++++++++++++++++ src/components/Dashboard/Dashboard.jsx | 8 +- src/components/common/DatePicker.jsx | 4 +- src/hooks/useDashboard_Data.jsx | 58 ++++++++ src/repositories/GlobalRepository.jsx | 17 +++ 6 files changed, 363 insertions(+), 3 deletions(-) create mode 100644 src/components/Charts/Circlechart.jsx create mode 100644 src/components/Dashboard/Activity.jsx diff --git a/src/components/Charts/Circlechart.jsx b/src/components/Charts/Circlechart.jsx new file mode 100644 index 00000000..ab1c1116 --- /dev/null +++ b/src/components/Charts/Circlechart.jsx @@ -0,0 +1,85 @@ +import React from "react"; +import ReactApexChart from "react-apexcharts"; + +const ApexChart = () => { + const [state] = React.useState({ + series: [75], // Replace this with dynamic value if needed + options: { + chart: { + height: 200, // Smaller height + type: "radialBar", + toolbar: { + show: false, // Hide toolbar + }, + }, + plotOptions: { + radialBar: { + startAngle: -135, + endAngle: 225, + hollow: { + margin: 0, + size: "60%", // Smaller inner circle + background: "#fff", + dropShadow: { + enabled: true, + top: 2, + left: 0, + blur: 3, + opacity: 0.45, + }, + }, + track: { + background: "#f5f5f5", + strokeWidth: "67%", + dropShadow: { + enabled: false, + }, + }, + dataLabels: { + show: true, + name: { + offsetY: -10, + color: "#888", + fontSize: "14px", + }, + value: { + formatter: (val) => parseInt(val), + color: "#111", + fontSize: "24px", // Smaller number + 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", + }, + labels: ["Percent"], + }, + }); + + return ( +
    + +
    + ); +}; + +export default ApexChart; diff --git a/src/components/Dashboard/Activity.jsx b/src/components/Dashboard/Activity.jsx new file mode 100644 index 00000000..a1f9c5fc --- /dev/null +++ b/src/components/Dashboard/Activity.jsx @@ -0,0 +1,194 @@ +import React, { useState, useEffect } from "react"; +import LineChart from "../Charts/LineChart"; +import { useProjects } from "../../hooks/useProjects"; +import { useDashboard_ActivityData } from "../../hooks/useDashboard_Data"; +import ApexChart from "../Charts/Circlechart"; + +const LOCAL_STORAGE_PROJECT_KEY = "selectedActivityProjectId"; + +const Activity = () => { + const { projects } = useProjects(); + const today = new Date().toISOString().split("T")[0]; // Format: YYYY-MM-DD + const [selectedDate, setSelectedDate] = useState(today); + const storedProjectId = localStorage.getItem(LOCAL_STORAGE_PROJECT_KEY); + const initialProjectId = storedProjectId || "all"; + const [selectedProjectId, setSelectedProjectId] = useState(initialProjectId); + const [displayedProjectName, setDisplayedProjectName] = useState("Select Project"); + const [activeTab, setActiveTab] = useState("all"); + + const { dashboard_Activitydata: ActivityData, isLoading, error: isError } = + useDashboard_ActivityData(selectedDate, selectedProjectId); + + useEffect(() => { + if (selectedProjectId === "all") { + setDisplayedProjectName("All Projects"); + } else if (projects) { + const foundProject = projects.find((p) => p.id === selectedProjectId); + setDisplayedProjectName(foundProject ? foundProject.name : "Select Project"); + } else { + setDisplayedProjectName("Select Project"); + } + + localStorage.setItem(LOCAL_STORAGE_PROJECT_KEY, selectedProjectId); + }, [selectedProjectId, projects]); + + const handleProjectSelect = (projectId) => { + setSelectedProjectId(projectId); + }; + + const handleDateChange = (e) => { + setSelectedDate(e.target.value); + }; + + return ( +
    +
    +
    +
    +
    Activity
    +

    Activity Progress Chart

    +
    + +
    + +
      +
    • + +
    • + {projects?.map((project) => ( +
    • + +
    • + ))} +
    +
    +
    +
    + + {/* ✅ Date Picker Aligned Left with Padding */} +
    +
    + +
    +
    + + {/* Tabs */} +
      +
    • + +
    • +
    • + +
    • +
    + +
    + {activeTab === "all" && ( +
    +
    + {isLoading ? ( +

    Loading activity data...

    + ) : isError ? ( +

    No data available.

    + ) : ( + ActivityData && ( + <> +
    + Allocated Task +
    +

    + {ActivityData.totalCompletedWork?.toLocaleString()}/ + {ActivityData.totalPlannedWork?.toLocaleString()} +

    + Completed / Assigned +
    + +
    + + ) + )} +
    + +
    + {!isLoading && !isError && ActivityData && ( + <> +
    + Activities +
    +

    + {ActivityData.totalCompletedWork?.toLocaleString()}/ + {ActivityData.totalPlannedWork?.toLocaleString()} +

    + Pending / Assigned +
    + +
    + + )} +
    +
    + )} + + {activeTab === "logs" && ( +
    + + + + + + + + + {[{ + activity: "Code Review / Remote", + assignedToday: 3, + completed: 2 + }].map((log, index) => ( + + + + + ))} + +
    Activity / LocationAssigned / Completed
    {log.activity}{log.assignedToday} / {log.completed}
    +
    + )} +
    +
    + ); +}; + +export default Activity; diff --git a/src/components/Dashboard/Dashboard.jsx b/src/components/Dashboard/Dashboard.jsx index 1e4cceaf..93e9f18e 100644 --- a/src/components/Dashboard/Dashboard.jsx +++ b/src/components/Dashboard/Dashboard.jsx @@ -9,12 +9,14 @@ import Teams from "./Teams"; import TasksCard from "./Tasks"; import ProjectCompletionChart from "./ProjectCompletionChart"; import ProjectProgressChart from "./ProjectProgressChart"; +import Activity from "./Activity"; const Dashboard = () => { const { projectsCardData } = useDashboardProjectsCardData(); const { teamsCardData } = useDashboardTeamsCardData(); const { tasksCardData } = useDashboardTasksCardData(); - + // const { ActivityData } = useDashboardActivityData(); + return (
    @@ -42,6 +44,10 @@ const Dashboard = () => {
    + +
    + +
    ); diff --git a/src/components/common/DatePicker.jsx b/src/components/common/DatePicker.jsx index 7003ab78..728b14fb 100644 --- a/src/components/common/DatePicker.jsx +++ b/src/components/common/DatePicker.jsx @@ -23,9 +23,9 @@ const DatePicker = ({ onDateChange }) => { return (
    - */} { return { dashboard_data, loading: isLineChartLoading, error }; }; +export const useDashboard_ActivityData = (date, projectId) => { + const [dashboard_Activitydata, setDashboard_ActivityData] = useState([]); + const [isLineChartLoading, setLoading] = useState(false); + const [error, setError] = useState(""); + + useEffect(() => { + const fetchData = async () => { + setLoading(true); + setError(""); + + try { + const response = await GlobalRepository.getDashboardActivityData(date,projectId); // date in 2nd param + setDashboard_ActivityData(response.data); + } catch (err) { + setError("Failed to fetch dashboard data."); + console.error(err); + } finally { + setLoading(false); + } + }; + + if (date && projectId !== null) { + fetchData(); + } + }, [date, projectId]); + + return { dashboard_Activitydata, isLineChartLoading: isLineChartLoading, error }; +}; + + // 🔹 Dashboard Projects Card Data Hook export const useDashboardProjectsCardData = () => { const [projectsCardData, setProjectsData] = useState([]); @@ -120,3 +150,31 @@ export const useDashboardTasksCardData = () => { return { tasksCardData, loading, error }; }; + + +// export const useDashboardActivityData = () => { +// const [ActivityData, setActivityData] = useState([]); +// const [loading, setLoading] = useState(false); +// const [error, setError] = useState(""); + +// useEffect(() => { +// const fetchTasksData = async () => { +// setLoading(true); +// setError(""); + +// try { +// const response = await GlobalRepository.getDashboardActivityData(); +// setActivityData(response.data); +// } catch (err) { +// setError("Failed to fetch tasks card data."); +// console.error(err); +// } finally { +// setLoading(false); +// } +// }; + +// fetchTasksData(); +// }, []); + +// return { ActivityData, loading, error }; +// }; diff --git a/src/repositories/GlobalRepository.jsx b/src/repositories/GlobalRepository.jsx index 31468b66..54034d7c 100644 --- a/src/repositories/GlobalRepository.jsx +++ b/src/repositories/GlobalRepository.jsx @@ -18,6 +18,23 @@ const GlobalRepository = { return api.get(`/api/Dashboard/Progression?${params.toString()}`); }, + + + getDashboardActivityData: ( date,projectId ) => { + + return api.get(`/api/Dashboard/activities/${projectId}?date=${date}`); +}, + +// getDashboardActivityData: (date, projectId) => { +// let url = `/api/Dashboard/activities`; +// if (projectId) { +// url += `/${projectId}?date=${date}`; +// } else { +// url += `?date=${date}`; // Fetch for all projects +// } +// return api.get(url); +// }, + getDashboardProjectsCardData: () => { return api.get(`/api/Dashboard/projects`); }, From dbc9bbffa2afa9a3e74137163d8ccd89fd1f4b50 Mon Sep 17 00:00:00 2001 From: "kartik.sharma" Date: Sat, 31 May 2025 11:39:15 +0530 Subject: [PATCH 10/16] Create a new Weidget in Dashboard name "Attendance" and Adding a features to show chart and Table on it. --- src/components/Charts/Circle.jsx | 80 ++++++++++ src/components/Dashboard/Attendance.jsx | 188 ++++++++++++++++++++++++ src/components/Dashboard/Dashboard.jsx | 5 + src/hooks/useDashboard_Data.jsx | 31 ++++ src/repositories/GlobalRepository.jsx | 5 + 5 files changed, 309 insertions(+) create mode 100644 src/components/Charts/Circle.jsx create mode 100644 src/components/Dashboard/Attendance.jsx diff --git a/src/components/Charts/Circle.jsx b/src/components/Charts/Circle.jsx new file mode 100644 index 00000000..6b0669bf --- /dev/null +++ b/src/components/Charts/Circle.jsx @@ -0,0 +1,80 @@ +import React from "react"; +import ReactApexChart from "react-apexcharts"; + +const ApexChart = ({ completed = 0, planned = 1 }) => { +const percentage = planned > 0 ? Math.round((completed / planned) * 100) : 0; + +const options = { +chart: { +height: 200, +type: "radialBar", +toolbar: { show: false }, +}, +plotOptions: { +radialBar: { +startAngle: -135, +endAngle: 225, +hollow: { +margin: 0, +size: "60%", +background: "#fff", +dropShadow: { +enabled: true, +top: 2, +left: 0, +blur: 3, +opacity: 0.45, +}, +}, +track: { +background: "#f5f5f5", +strokeWidth: "67%", +dropShadow: { enabled: false }, +}, +dataLabels: { +show: true, +name: { +offsetY: -10, +color: "#888", +fontSize: "14px", +}, +value: { +formatter: (val) => `${val}%`, +color: "#111", +fontSize: "24px", +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", +}, +labels: ["Progress"], +}; + +return ( +
    + +
    +); +}; + +export default ApexChart; \ No newline at end of file diff --git a/src/components/Dashboard/Attendance.jsx b/src/components/Dashboard/Attendance.jsx new file mode 100644 index 00000000..b7e5a3b2 --- /dev/null +++ b/src/components/Dashboard/Attendance.jsx @@ -0,0 +1,188 @@ +import React, { useState, useEffect } from "react"; +import LineChart from "../Charts/LineChart"; +import { useProjects } from "../../hooks/useProjects"; +import { useDashboard_AttendanceData } from "../../hooks/useDashboard_Data"; +import ApexChart from "../Charts/Circle"; + +const LOCAL_STORAGE_PROJECT_KEY = "selectedAttendanceProjectId"; + +const Attendance = () => { + const { projects } = useProjects(); + const today = new Date().toISOString().split("T")[0]; // Format: YYYY-MM-DD + const [selectedDate, setSelectedDate] = useState(today); + const storedProjectId = localStorage.getItem(LOCAL_STORAGE_PROJECT_KEY); + const initialProjectId = storedProjectId || "all"; + const [selectedProjectId, setSelectedProjectId] = useState(initialProjectId); + const [displayedProjectName, setDisplayedProjectName] = useState("Select Project"); + const [activeTab, setActiveTab] = useState("all"); + + const { dashboard_Attendancedata: AttendanceData, isLoading, error: isError } = + useDashboard_AttendanceData(selectedDate, selectedProjectId); + + useEffect(() => { + if (selectedProjectId === "all") { + setDisplayedProjectName("All Projects"); + } else if (projects) { + const foundProject = projects.find((p) => p.id === selectedProjectId); + setDisplayedProjectName(foundProject ? foundProject.name : "Select Project"); + } else { + setDisplayedProjectName("Select Project"); + } + + localStorage.setItem(LOCAL_STORAGE_PROJECT_KEY, selectedProjectId); + }, [selectedProjectId, projects]); + + const handleProjectSelect = (projectId) => { + setSelectedProjectId(projectId); + }; + + const handleDateChange = (e) => { + setSelectedDate(e.target.value); + }; + + return ( +
    +
    +
    +
    +
    Attendance
    +

    Attendance Progress Chart

    +
    + +
    + +
      +
    • + +
    • + {projects?.map((project) => ( +
    • + +
    • + ))} +
    +
    +
    +
    + + {/* ✅ Date Picker Aligned Left with Padding */} +
    +
    + +
    +
    + + + {/* Tabs */} +
      +
    • + +
    • +
    • + +
    • +
    + +
    + {activeTab === "Summary" && ( +
    +
    + {isLoading ? ( +

    Loading Attendance data...

    + ) : isError ? ( +

    No data available.

    + ) : ( + AttendanceData && ( + <> +
    + Attendance +
    +

    + {AttendanceData.checkedInEmployee?.toLocaleString()}/ + {AttendanceData.assignedEmployee?.toLocaleString()} +

    + Checked-In / Assigned +
    + +
    + + ) + )} +
    +
    + + )} + + {activeTab === "Details" && ( +
    + + + + + + + + + + {AttendanceData?.attendanceTable && AttendanceData.attendanceTable.length > 0 ? ( + AttendanceData.attendanceTable.map((record, index) => ( + + + + + + + )) + ) : ( + + + + )} + +
    NameCheckinCheckout
    {record.firstName} {record.lastName}{new Date(record.inTime).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}{new Date(record.outTime).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
    No attendance data available
    +
    + )} + +
    +
    + ); +}; + +export default Attendance; diff --git a/src/components/Dashboard/Dashboard.jsx b/src/components/Dashboard/Dashboard.jsx index 1e4cceaf..6bbdd11f 100644 --- a/src/components/Dashboard/Dashboard.jsx +++ b/src/components/Dashboard/Dashboard.jsx @@ -9,6 +9,7 @@ import Teams from "./Teams"; import TasksCard from "./Tasks"; import ProjectCompletionChart from "./ProjectCompletionChart"; import ProjectProgressChart from "./ProjectProgressChart"; +import Attendance from "./Attendance"; const Dashboard = () => { const { projectsCardData } = useDashboardProjectsCardData(); @@ -42,6 +43,10 @@ const Dashboard = () => {
    + +
    + +
    ); diff --git a/src/hooks/useDashboard_Data.jsx b/src/hooks/useDashboard_Data.jsx index 5cf03f91..a46aa0c8 100644 --- a/src/hooks/useDashboard_Data.jsx +++ b/src/hooks/useDashboard_Data.jsx @@ -37,6 +37,37 @@ export const useDashboard_Data = ({ days, FromDate, projectId }) => { return { dashboard_data, loading: isLineChartLoading, error }; }; + +export const useDashboard_AttendanceData = (date, projectId) => { + const [dashboard_Attendancedata, setDashboard_AttendanceData] = useState([]); + const [isLineChartLoading, setLoading] = useState(false); + const [error, setError] = useState(""); + + useEffect(() => { + const fetchData = async () => { + setLoading(true); + setError(""); + + try { + const response = await GlobalRepository.getDashboardAttendanceData(date,projectId); // date in 2nd param + setDashboard_AttendanceData(response.data); + } catch (err) { + setError("Failed to fetch dashboard data."); + console.error(err); + } finally { + setLoading(false); + } + }; + + if (date && projectId !== null) { + fetchData(); + } + }, [date, projectId]); + + return { dashboard_Attendancedata, isLineChartLoading: isLineChartLoading, error }; +}; + + // 🔹 Dashboard Projects Card Data Hook export const useDashboardProjectsCardData = () => { const [projectsCardData, setProjectsData] = useState([]); diff --git a/src/repositories/GlobalRepository.jsx b/src/repositories/GlobalRepository.jsx index 31468b66..eda5312e 100644 --- a/src/repositories/GlobalRepository.jsx +++ b/src/repositories/GlobalRepository.jsx @@ -18,6 +18,11 @@ const GlobalRepository = { return api.get(`/api/Dashboard/Progression?${params.toString()}`); }, + + getDashboardAttendanceData: ( date,projectId ) => { + + return api.get(`/api/Dashboard/project-attendance/${projectId}?date=${date}`); +}, getDashboardProjectsCardData: () => { return api.get(`/api/Dashboard/projects`); }, From d80082bc9b438ff0df1eaf69e184a16c0534bb10 Mon Sep 17 00:00:00 2001 From: "kartik.sharma" Date: Wed, 28 May 2025 16:03:35 +0530 Subject: [PATCH 11/16] Status code 400 showing on Logs tab and Daily Progress Report datepicker issue. --- src/components/common/DateRangePicker.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/common/DateRangePicker.jsx b/src/components/common/DateRangePicker.jsx index c56e742e..36fa61d8 100644 --- a/src/components/common/DateRangePicker.jsx +++ b/src/components/common/DateRangePicker.jsx @@ -12,7 +12,9 @@ const DateRangePicker = ({ onRangeChange, DateDifference = 7, defaultStartDate = const fp = flatpickr(inputRef.current, { mode: "range", - dateFormat: "d-m-Y", + dateFormat: "Y-m-d", // Format for backend (actual input value) + altInput: true, // Enables a visually different field + altFormat: "d-m-Y", defaultDate: [fifteenDaysAgo, today], static: true, clickOpens: true, From ccbe89f407596e22e10f84f8a6aac55c21964f19 Mon Sep 17 00:00:00 2001 From: Vikas Nale Date: Sat, 31 May 2025 15:30:41 +0530 Subject: [PATCH 12/16] Cosmatic changes for Attendance Widget --- src/components/Dashboard/Attendance.jsx | 362 +++++++++++++----------- 1 file changed, 196 insertions(+), 166 deletions(-) diff --git a/src/components/Dashboard/Attendance.jsx b/src/components/Dashboard/Attendance.jsx index b7e5a3b2..168fb065 100644 --- a/src/components/Dashboard/Attendance.jsx +++ b/src/components/Dashboard/Attendance.jsx @@ -7,182 +7,212 @@ import ApexChart from "../Charts/Circle"; const LOCAL_STORAGE_PROJECT_KEY = "selectedAttendanceProjectId"; const Attendance = () => { - const { projects } = useProjects(); - const today = new Date().toISOString().split("T")[0]; // Format: YYYY-MM-DD - const [selectedDate, setSelectedDate] = useState(today); - const storedProjectId = localStorage.getItem(LOCAL_STORAGE_PROJECT_KEY); - const initialProjectId = storedProjectId || "all"; - const [selectedProjectId, setSelectedProjectId] = useState(initialProjectId); - const [displayedProjectName, setDisplayedProjectName] = useState("Select Project"); - const [activeTab, setActiveTab] = useState("all"); + const { projects } = useProjects(); + const today = new Date().toISOString().split("T")[0]; // Format: YYYY-MM-DD + const [selectedDate, setSelectedDate] = useState(today); + const storedProjectId = localStorage.getItem(LOCAL_STORAGE_PROJECT_KEY); + const initialProjectId = storedProjectId || "all"; + const [selectedProjectId, setSelectedProjectId] = useState(initialProjectId); + const [displayedProjectName, setDisplayedProjectName] = + useState("Select Project"); + const [activeTab, setActiveTab] = useState("Summary"); - const { dashboard_Attendancedata: AttendanceData, isLoading, error: isError } = - useDashboard_AttendanceData(selectedDate, selectedProjectId); + const { + dashboard_Attendancedata: AttendanceData, + isLoading, + error: isError, + } = useDashboard_AttendanceData(selectedDate, selectedProjectId); - useEffect(() => { - if (selectedProjectId === "all") { - setDisplayedProjectName("All Projects"); - } else if (projects) { - const foundProject = projects.find((p) => p.id === selectedProjectId); - setDisplayedProjectName(foundProject ? foundProject.name : "Select Project"); - } else { - setDisplayedProjectName("Select Project"); - } + useEffect(() => { + if (selectedProjectId === "all") { + setDisplayedProjectName("All Projects"); + } else if (projects) { + const foundProject = projects.find((p) => p.id === selectedProjectId); + setDisplayedProjectName( + foundProject ? foundProject.name : "Select Project" + ); + } else { + setDisplayedProjectName("Select Project"); + } - localStorage.setItem(LOCAL_STORAGE_PROJECT_KEY, selectedProjectId); - }, [selectedProjectId, projects]); + localStorage.setItem(LOCAL_STORAGE_PROJECT_KEY, selectedProjectId); + }, [selectedProjectId, projects]); - const handleProjectSelect = (projectId) => { - setSelectedProjectId(projectId); - }; + const handleProjectSelect = (projectId) => { + setSelectedProjectId(projectId); + }; - const handleDateChange = (e) => { - setSelectedDate(e.target.value); - }; + const handleDateChange = (e) => { + setSelectedDate(e.target.value); + }; - return ( -
    -
    -
    -
    -
    Attendance
    -

    Attendance Progress Chart

    -
    + return ( +
    +
    +
    +
    +
    Attendance
    +

    Daily Attendance Data

    +
    -
    - -
      -
    • - -
    • - {projects?.map((project) => ( -
    • - -
    • - ))} -
    -
    -
    -
    - - {/* ✅ Date Picker Aligned Left with Padding */} -
    -
    - -
    -
    - - - {/* Tabs */} -
      -
    • - -
    • -
    • - +
      + +
        +
      • + +
      • + {projects?.map((project) => ( +
      • +
      • + ))}
      - -
      - {activeTab === "Summary" && ( -
      -
      - {isLoading ? ( -

      Loading Attendance data...

      - ) : isError ? ( -

      No data available.

      - ) : ( - AttendanceData && ( - <> -
      - Attendance -
      -

      - {AttendanceData.checkedInEmployee?.toLocaleString()}/ - {AttendanceData.assignedEmployee?.toLocaleString()} -

      - Checked-In / Assigned -
      - -
      - - ) - )} -
      -
      - - )} - - {activeTab === "Details" && ( -
      - - - - - - - - - - {AttendanceData?.attendanceTable && AttendanceData.attendanceTable.length > 0 ? ( - AttendanceData.attendanceTable.map((record, index) => ( - - - - - - - )) - ) : ( - - - - )} - -
      NameCheckinCheckout
      {record.firstName} {record.lastName}{new Date(record.inTime).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}{new Date(record.outTime).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
      No attendance data available
      -
      - )} - -
      +
    - ); +
    + +
    + {/* Tabs */} +
    +
      +
    • + +
    • +
    • + +
    • +
    +
    + {/* ✅ Date Picker Aligned Left with Padding */} +
    +
    + +
    +
    +
    + +
    + {activeTab === "Summary" && ( +
    +
    + {isLoading ? ( +

    Loading Attendance data...

    + ) : isError ? ( +

    No data available.

    + ) : ( + AttendanceData && ( + <> +
    + Attendance +
    +

    + {AttendanceData.checkedInEmployee?.toLocaleString()}/ + {AttendanceData.assignedEmployee?.toLocaleString()} +

    + Checked-In / Assigned +
    + +
    + + ) + )} +
    +
    + )} + + {activeTab === "Details" && ( +
    + + + + + + + + + + {AttendanceData?.attendanceTable && + AttendanceData.attendanceTable.length > 0 ? ( + AttendanceData.attendanceTable.map((record, index) => ( + + + + + + )) + ) : ( + + + + )} + +
    NameCheckinCheckout
    + {record.firstName} {record.lastName} + + {new Date(record.inTime).toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + })} + + {new Date(record.outTime).toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + })} +
    + No attendance data available +
    +
    + )} +
    +
    + ); }; export default Attendance; From f72c309c0cf96184ff31ab020854840db4b17854 Mon Sep 17 00:00:00 2001 From: "kartik.sharma" Date: Sat, 31 May 2025 15:35:36 +0530 Subject: [PATCH 13/16] Comment code in Dashboard. --- src/components/Dashboard/Dashboard.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Dashboard/Dashboard.jsx b/src/components/Dashboard/Dashboard.jsx index 6bbdd11f..b2c6b904 100644 --- a/src/components/Dashboard/Dashboard.jsx +++ b/src/components/Dashboard/Dashboard.jsx @@ -9,7 +9,7 @@ import Teams from "./Teams"; import TasksCard from "./Tasks"; import ProjectCompletionChart from "./ProjectCompletionChart"; import ProjectProgressChart from "./ProjectProgressChart"; -import Attendance from "./Attendance"; +// import Attendance from "./Attendance"; const Dashboard = () => { const { projectsCardData } = useDashboardProjectsCardData(); @@ -44,9 +44,9 @@ const Dashboard = () => {
    -
    + {/*
    -
    +
    */}
    ); From 14b851b87e5bfeb2b4f85d99e489930e6c418706 Mon Sep 17 00:00:00 2001 From: Pramod Mahajan Date: Sat, 31 May 2025 15:03:34 +0530 Subject: [PATCH 14/16] added modal name- Assign Employee --- src/components/Project/MapUsers.jsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/components/Project/MapUsers.jsx b/src/components/Project/MapUsers.jsx index bb429789..c72c1c0d 100644 --- a/src/components/Project/MapUsers.jsx +++ b/src/components/Project/MapUsers.jsx @@ -144,17 +144,24 @@ const MapUsers = ({ {employeeLoading && allocationEmployeesData.length === 0 && ( -

    Loading...

    + + Loading.. + )} {!employeeLoading && allocationEmployeesData.length === 0 && filteredData.length === 0 && ( -

    All employee assigned to Project.

    + + + All employee assigned to Project. + )} {!employeeLoading && allocationEmployeesData.length > 0 && filteredData.length === 0 && ( -

    No matching employees found.

    + + No matching employees found. + )} {(filteredData.length > 0 || From d10d47e64204a6b3d97f1693c7cc7f2c1990b348 Mon Sep 17 00:00:00 2001 From: Pramod Mahajan Date: Sat, 31 May 2025 15:15:42 +0530 Subject: [PATCH 15/16] added title name for assign employee modal --- src/components/Project/MapUsers.jsx | 87 +++++++++++++++-------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/src/components/Project/MapUsers.jsx b/src/components/Project/MapUsers.jsx index c72c1c0d..512b0985 100644 --- a/src/components/Project/MapUsers.jsx +++ b/src/components/Project/MapUsers.jsx @@ -14,9 +14,13 @@ const MapUsers = ({ assignedLoading, setAssignedLoading, }) => { - const { employeesList, loading: employeeLoading, error } = useAllEmployees(false); + const { + employeesList, + loading: employeeLoading, + error, + } = useAllEmployees(false); const [selectedEmployees, setSelectedEmployees] = useState([]); - const [ searchText, setSearchText ] = useState( "" ); + const [searchText, setSearchText] = useState(""); const handleAllocationData = Array.isArray(allocation) ? allocation : []; @@ -96,9 +100,8 @@ const MapUsers = ({ }); }; - const handleSubmit = () => - { - setAssignedLoading(true) + const handleSubmit = () => { + setAssignedLoading(true); const selected = selectedEmployees .filter((emp) => emp.isSelected) .map((emp) => ({ empID: emp.id, jobRoleId: emp.jobRoleId })); @@ -108,32 +111,33 @@ const MapUsers = ({ } else { showToast("Please select Employee", "error"); } - }; return ( <>
    -
    -
    - {(filteredData.length > 0 || - allocationEmployeesData.length > 0)&& ( -
    - setSearchQuery(e.target.value)} - /> -
    - )} -
    +
    +
    -
    -
    - Select Employee -
    -
    +

    Assign Employee

    + +
    + {(filteredData.length > 0 || + allocationEmployeesData.length > 0) && ( +
    + setSearchQuery(e.target.value)} + /> +
    + )} + +

    Select Employee

    +
    +
    - {employeeLoading && allocationEmployeesData.length === 0 && ( - + )} @@ -152,17 +155,18 @@ const MapUsers = ({ {!employeeLoading && allocationEmployeesData.length === 0 && filteredData.length === 0 && ( - - - - + + + )} - {!employeeLoading && allocationEmployeesData.length > 0 && filteredData.length === 0 && ( + {!employeeLoading && + allocationEmployeesData.length > 0 && + filteredData.length === 0 && ( - - - )} + + + )} {(filteredData.length > 0 || allocationEmployeesData.length > 0) && @@ -181,14 +185,11 @@ const MapUsers = ({
    {(filteredData.length > 0 || - allocationEmployeesData.length > 0) && ( - - )} + allocationEmployeesData.length > 0) && ( + + )}
    Loading..
    All employee assigned to Project.
    All employee assigned to Project.
    No matching employees found.
    No matching employees found.