implemented singlR
This commit is contained in:
parent
ae772d925a
commit
2aae7194b7
@ -189,12 +189,12 @@ const DocumentFilterPanel = ({ entityTypeId, onApply }) => {
|
|||||||
<div className="d-flex justify-content-end py-3 gap-2">
|
<div className="d-flex justify-content-end py-3 gap-2">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-label-secondary btn-xs"
|
className="btn btn-label-secondary btn-sm"
|
||||||
onClick={onClear}
|
onClick={onClear}
|
||||||
>
|
>
|
||||||
Clear
|
Clear
|
||||||
</button>
|
</button>
|
||||||
<button type="submit" className="btn btn-primary btn-xs">
|
<button type="submit" className="btn btn-primary btn-sm">
|
||||||
Apply
|
Apply
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,54 +17,56 @@ const SkeletonCell = ({
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
export const DocumentTableSkeleton = ({ rows = 5 }) => {
|
export const DocumentTableSkeleton = ({ rows = 10 }) => {
|
||||||
return (
|
return (
|
||||||
|
<table className="card-body table border-top dataTable no-footer dtr-column text-nowrap">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th className="text-start">Name</th>
|
||||||
|
<th className="text-start">Document Type</th>
|
||||||
|
<th className="text-start">Uploaded By</th>
|
||||||
|
<th className="text-center">Uploaded on</th>
|
||||||
|
<th className="text-center">Status</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
<table className="card-body table border-top dataTable no-footer dtr-column text-nowrap">
|
<tbody>
|
||||||
<thead>
|
{[...Array(rows)].map((_, idx) => (
|
||||||
<tr>
|
<tr key={idx} className={idx % 2 === 0 ? "odd" : "even"}>
|
||||||
<th className="text-start">Name</th>
|
{/* Name */}
|
||||||
<th className="text-start">Document Type</th>
|
<td className="text-start">
|
||||||
<th className="text-start">Uploaded By</th>
|
<SkeletonCell width="120px" height={16} />
|
||||||
<th className="text-center">Uploaded on</th>
|
</td>
|
||||||
<th className="text-center">Status</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
{/* Document Type */}
|
||||||
{[...Array(rows)].map((_, idx) => (
|
<td className="text-start">
|
||||||
<tr key={idx} className={idx % 2 === 0 ? "odd" : "even"}>
|
<SkeletonCell width="100px" height={16} />
|
||||||
{/* Name */}
|
</td>
|
||||||
<td className="text-start">
|
|
||||||
<SkeletonCell width="120px" height={16} />
|
|
||||||
</td>
|
|
||||||
|
|
||||||
{/* Document Type */}
|
{/* Uploaded By (Avatar + Name) */}
|
||||||
<td className="text-start">
|
<td className="text-start">
|
||||||
<SkeletonCell width="100px" height={16} />
|
<div className="d-flex align-items-center gap-2">
|
||||||
</td>
|
<SkeletonCell
|
||||||
|
width="30px"
|
||||||
{/* Uploaded By (Avatar + Name) */}
|
height={30}
|
||||||
<td className="text-start">
|
className="rounded-circle"
|
||||||
<div className="d-flex align-items-center gap-2">
|
/>
|
||||||
<SkeletonCell width="30px" height={30} className="rounded-circle" />
|
|
||||||
<SkeletonCell width="80px" height={16} />
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
{/* Uploaded on */}
|
|
||||||
<td className="text-center">
|
|
||||||
<SkeletonCell width="80px" height={16} />
|
<SkeletonCell width="80px" height={16} />
|
||||||
</td>
|
</div>
|
||||||
|
</td>
|
||||||
|
|
||||||
{/* Status */}
|
{/* Uploaded on */}
|
||||||
<td className="text-center">
|
<td className="text-center">
|
||||||
<SkeletonCell width="70px" height={20} className="rounded" />
|
<SkeletonCell width="80px" height={16} />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
|
||||||
))}
|
{/* Status */}
|
||||||
</tbody>
|
<td className="text-center">
|
||||||
</table>
|
<SkeletonCell width="70px" height={20} className="rounded" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -117,7 +117,7 @@ const Documents = ({ Document_Entity, Entity }) => {
|
|||||||
}, [Document_Entity]);
|
}, [Document_Entity]);
|
||||||
return (
|
return (
|
||||||
<DocumentContext.Provider value={contextValues}>
|
<DocumentContext.Provider value={contextValues}>
|
||||||
<div className="mt-5">
|
<div className="mt-2">
|
||||||
<div className="card page-min-h d-flex p-2">
|
<div className="card page-min-h d-flex p-2">
|
||||||
<div className="row align-items-center">
|
<div className="row align-items-center">
|
||||||
{/* Search */}
|
{/* Search */}
|
||||||
|
@ -82,9 +82,9 @@ const DocumentsList = ({
|
|||||||
if (isLoading || isFetching) return <DocumentTableSkeleton />;
|
if (isLoading || isFetching) return <DocumentTableSkeleton />;
|
||||||
if (isError)
|
if (isError)
|
||||||
return <div>Error: {error?.message || "Something went wrong"}</div>;
|
return <div>Error: {error?.message || "Something went wrong"}</div>;
|
||||||
if (isInitialEmpty) return <div>No documents found yet.</div>;
|
if (isInitialEmpty) return <div className="py-12 my-12">No documents found yet.</div>;
|
||||||
if (isSearchEmpty) return <div>No results found for "{debouncedSearch}"</div>;
|
if (isSearchEmpty) return <div className="py-12 my-12">No results found for "{debouncedSearch}"</div>;
|
||||||
if (isFilterEmpty) return <div>No documents match your filter.</div>;
|
if (isFilterEmpty) return <div className="py-12 my-12">No documents match your filter.</div>;
|
||||||
|
|
||||||
const handleDelete = () => {
|
const handleDelete = () => {
|
||||||
ActiveInActive(
|
ActiveInActive(
|
||||||
@ -180,10 +180,10 @@ const DocumentsList = ({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="table-responsive">
|
<div className="table-responsive p-2">
|
||||||
<table className="table border-top dataTable text-nowrap">
|
<table className="table border-top dataTable text-nowrap">
|
||||||
<thead>
|
<thead className="">
|
||||||
<tr className="shadow-sm">
|
<tr className="py-2 ">
|
||||||
{DocumentColumns.map((col) => (
|
{DocumentColumns.map((col) => (
|
||||||
<th key={col.key} className={`sorting ${col.align}`}>
|
<th key={col.key} className={`sorting ${col.align}`}>
|
||||||
{col.label}
|
{col.label}
|
||||||
|
@ -131,7 +131,7 @@ const EmpAttendance = ({ employee }) => {
|
|||||||
<AttendLogs Id={attendanceId} />
|
<AttendLogs Id={attendanceId} />
|
||||||
</GlobalModel>
|
</GlobalModel>
|
||||||
)}
|
)}
|
||||||
<div className="card px-4 mt-5 py-2 " style={{ minHeight: "500px" }}>
|
<div className="card px-4 mt-2 py-2 page-min-h ">
|
||||||
<div
|
<div
|
||||||
className="dataTables_length text-start py-2 d-flex justify-content-between "
|
className="dataTables_length text-start py-2 d-flex justify-content-between "
|
||||||
id="DataTables_Table_0_length"
|
id="DataTables_Table_0_length"
|
||||||
|
@ -12,11 +12,11 @@ const EmpDashboard = ({ profile }) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-12 col-sm-6 pt-5">
|
<div className="col-12 col-sm-6 pt-2">
|
||||||
{" "}
|
{" "}
|
||||||
<EmpOverview profile={profile}></EmpOverview>
|
<EmpOverview profile={profile}></EmpOverview>
|
||||||
</div>
|
</div>
|
||||||
<div className="col col-sm-6 pt-5">
|
{/* <div className="col col-sm-6 pt-5">
|
||||||
<div className="card ">
|
<div className="card ">
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<small className="card-text text-uppercase text-body-secondary small text-start d-block">
|
<small className="card-text text-uppercase text-body-secondary small text-start d-block">
|
||||||
@ -29,7 +29,6 @@ const EmpDashboard = ({ profile }) => {
|
|||||||
className="d-flex mb-4 align-items-start flex-wrap"
|
className="d-flex mb-4 align-items-start flex-wrap"
|
||||||
key={project.id}
|
key={project.id}
|
||||||
>
|
>
|
||||||
{/* Project Info */}
|
|
||||||
<div className="flex-grow-1">
|
<div className="flex-grow-1">
|
||||||
<div className="d-flex flex-wrap align-items-center justify-content-between gap-2">
|
<div className="d-flex flex-wrap align-items-center justify-content-between gap-2">
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
@ -70,7 +69,6 @@ const EmpDashboard = ({ profile }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Dates */}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@ -79,7 +77,7 @@ const EmpDashboard = ({ profile }) => {
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> */}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -24,7 +24,7 @@ const EmployeeNav = ({ onPillClick, activePill }) => {
|
|||||||
icon: "bx bx-file",
|
icon: "bx bx-file",
|
||||||
label: "Documents",
|
label: "Documents",
|
||||||
},
|
},
|
||||||
{ key: "activities", icon: "bx bx-grid-alt", label: "Activities" },
|
// { key: "activities", icon: "bx bx-grid-alt", label: "Activities" },
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
return (
|
return (
|
||||||
<div className="col-md-12">
|
<div className="col-md-12">
|
||||||
|
@ -45,8 +45,9 @@ const Header = () => {
|
|||||||
pathname
|
pathname
|
||||||
);
|
);
|
||||||
const isExpensePage = /^\/expenses$/.test(pathname);
|
const isExpensePage = /^\/expenses$/.test(pathname);
|
||||||
|
const isEmployeePage = /^\/employees$/.test(pathname)
|
||||||
|
|
||||||
return !(isDirectoryPath || isProfilePage || isExpensePage);
|
return !(isDirectoryPath || isProfilePage || isExpensePage || isEmployeePage);
|
||||||
};
|
};
|
||||||
const allowedProjectStatusIds = [
|
const allowedProjectStatusIds = [
|
||||||
"603e994b-a27f-4e5d-a251-f3d69b0498ba",
|
"603e994b-a27f-4e5d-a251-f3d69b0498ba",
|
||||||
@ -83,7 +84,7 @@ const Header = () => {
|
|||||||
currentProjectDisplayName = projectNames[0].name;
|
currentProjectDisplayName = projectNames[0].name;
|
||||||
} else {
|
} else {
|
||||||
if (selectedProject === null) {
|
if (selectedProject === null) {
|
||||||
currentProjectDisplayName = "All Projects";
|
currentProjectDisplayName = projectNames[0].name;
|
||||||
} else {
|
} else {
|
||||||
const selectedProjectObj = projectNames.find(
|
const selectedProjectObj = projectNames.find(
|
||||||
(p) => p?.id === selectedProject
|
(p) => p?.id === selectedProject
|
||||||
@ -135,14 +136,14 @@ const Header = () => {
|
|||||||
|
|
||||||
const newProjectHandler = useCallback(
|
const newProjectHandler = useCallback(
|
||||||
async (msg) => {
|
async (msg) => {
|
||||||
if (HasManageProjectPermission && msg.keyword === "Create_Project") {
|
if ( msg.keyword === "Create_Project") {
|
||||||
await fetchData();
|
await fetchData();
|
||||||
} else if (projectNames?.some((item) => item.id === msg.response.id)) {
|
} else if (projectNames?.some((item) => item.id === msg.response.id)) {
|
||||||
await fetchData();
|
await fetchData();
|
||||||
}
|
}
|
||||||
cacheData("hasReceived", false);
|
cacheData("hasReceived", false);
|
||||||
},
|
},
|
||||||
[HasManageProjectPermission, projectNames, fetchData]
|
[ projectNames, fetchData]
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -212,7 +213,7 @@ const Header = () => {
|
|||||||
className="dropdown-menu"
|
className="dropdown-menu"
|
||||||
style={{ overflow: "auto", maxHeight: "300px" }}
|
style={{ overflow: "auto", maxHeight: "300px" }}
|
||||||
>
|
>
|
||||||
{isDashboardPath && (
|
{isProjectPath && (
|
||||||
<li>
|
<li>
|
||||||
<button
|
<button
|
||||||
className="dropdown-item"
|
className="dropdown-item"
|
||||||
@ -247,16 +248,16 @@ const Header = () => {
|
|||||||
|
|
||||||
<ul className="navbar-nav flex-row align-items-center ms-md-auto">
|
<ul className="navbar-nav flex-row align-items-center ms-md-auto">
|
||||||
{/* {HasManageProjectPermission && ( */}
|
{/* {HasManageProjectPermission && ( */}
|
||||||
<li className="nav-item navbar-dropdown dropdown-user dropdown">
|
<li className="nav-item navbar-dropdown dropdown-user dropdown">
|
||||||
<button
|
<button
|
||||||
className="btn btn-sm btn-primary"
|
className="btn btn-sm btn-primary"
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => openModal(null)}
|
onClick={() => openModal(null)}
|
||||||
>
|
>
|
||||||
<i className="bx bx-plus-circle me-2"></i>
|
<i className="bx bx-plus-circle me-2"></i>
|
||||||
<span className="d-none d-md-inline-block">Create Project</span>
|
<span className="d-none d-md-inline-block">Create Project</span>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
{/* )} */}
|
{/* )} */}
|
||||||
<li className="nav-item navbar-dropdown dropdown-user dropdown">
|
<li className="nav-item navbar-dropdown dropdown-user dropdown">
|
||||||
<a
|
<a
|
||||||
|
@ -66,7 +66,7 @@ const ProjectCard = ({ project }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={`ms-auto ${!ManageProject && "d-none"}`}>
|
<div className={`ms-auto `}>
|
||||||
<div className="dropdown z-2">
|
<div className="dropdown z-2">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@ -106,12 +106,6 @@ const ProjectCard = ({ project }) => {
|
|||||||
<span className="align-left">Modify</span>
|
<span className="align-left">Modify</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li onClick={handleViewActivities}>
|
|
||||||
<a className="dropdown-item">
|
|
||||||
<i className="bx bx-task me-2"></i>
|
|
||||||
<span className="align-left">Activities</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,70 +1,62 @@
|
|||||||
import React from 'react'
|
import React from "react";
|
||||||
import { useProjects } from '../../hooks/useProjects'
|
import { useProjects } from "../../hooks/useProjects";
|
||||||
import Loader from '../common/Loader'
|
import Loader from "../common/Loader";
|
||||||
import ProjectCard from './ProjectCard'
|
import ProjectCard from "./ProjectCard";
|
||||||
|
|
||||||
const ProjectCardView = ({currentItems,setCurrentPage,totalPages }) => {
|
|
||||||
|
|
||||||
|
|
||||||
|
const ProjectCardView = ({ currentItems, setCurrentPage, totalPages }) => {
|
||||||
return (
|
return (
|
||||||
|
<div className="row page-min-h">
|
||||||
|
{currentItems.length === 0 && (
|
||||||
|
<p className="text-center text-muted">No projects found.</p>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="row page-min-h">
|
{currentItems.map((project) => (
|
||||||
|
<ProjectCard key={project.id} project={project} />
|
||||||
|
))}
|
||||||
|
|
||||||
{ currentItems.length === 0 && (
|
{totalPages > 1 && (
|
||||||
<p className="text-center text-muted">No projects found.</p>
|
<nav>
|
||||||
)}
|
<ul className="pagination pagination-sm justify-content-end py-2">
|
||||||
|
<li className={`page-item ${currentPage === 1 && "disabled"}`}>
|
||||||
{currentItems.map((project) => (
|
<button
|
||||||
<ProjectCard
|
className="page-link"
|
||||||
key={project.id}
|
onClick={() => setCurrentPage((p) => Math.max(1, p - 1))}
|
||||||
project={project}
|
>
|
||||||
/>
|
«
|
||||||
))}
|
</button>
|
||||||
|
</li>
|
||||||
|
{[...Array(totalPages)].map((_, i) => (
|
||||||
{ totalPages > 1 && (
|
|
||||||
<nav>
|
|
||||||
<ul className="pagination pagination-sm justify-content-end py-2">
|
|
||||||
<li className={`page-item ${currentPage === 1 && "disabled"}`}>
|
|
||||||
<button
|
|
||||||
className="page-link"
|
|
||||||
onClick={() => setCurrentPage((p) => Math.max(1, p - 1))}
|
|
||||||
>
|
|
||||||
«
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
{[...Array(totalPages)].map((_, i) => (
|
|
||||||
<li
|
|
||||||
key={i}
|
|
||||||
className={`page-item ${currentPage === i + 1 && "active"}`}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className="page-link"
|
|
||||||
onClick={() => setCurrentPage(i + 1)}
|
|
||||||
>
|
|
||||||
{i + 1}
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
<li
|
<li
|
||||||
className={`page-item ${currentPage === totalPages && "disabled"
|
key={i}
|
||||||
}`}
|
className={`page-item ${currentPage === i + 1 && "active"}`}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
className="page-link"
|
className="page-link"
|
||||||
onClick={() =>
|
onClick={() => setCurrentPage(i + 1)}
|
||||||
setCurrentPage((p) => Math.min(totalPages, p + 1))
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
»
|
{i + 1}
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
))}
|
||||||
</nav>
|
<li
|
||||||
)}
|
className={`page-item ${
|
||||||
</div>
|
currentPage === totalPages && "disabled"
|
||||||
|
}`}
|
||||||
)
|
>
|
||||||
}
|
<button
|
||||||
|
className="page-link"
|
||||||
|
onClick={() =>
|
||||||
|
setCurrentPage((p) => Math.min(totalPages, p + 1))
|
||||||
|
}
|
||||||
|
>
|
||||||
|
»
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default ProjectCardView
|
export default ProjectCardView;
|
||||||
|
@ -26,9 +26,8 @@ const ProjectListView = ({
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { setMangeProject } = useProjectContext();
|
const { setMangeProject } = useProjectContext();
|
||||||
// const { data, isLoading, isError, error } = useProjects();
|
// const { data, isLoading, isError, error } = useProjects();
|
||||||
|
|
||||||
// check Permissions
|
// check Permissions
|
||||||
const canManageProject = useHasUserPermission(MANAGE_PROJECT);
|
// const canManageProject = useHasUserPermission(MANAGE_PROJECT);
|
||||||
|
|
||||||
const projectColumns = [
|
const projectColumns = [
|
||||||
{
|
{
|
||||||
@ -125,11 +124,15 @@ const ProjectListView = ({
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const handleViewActivities = (project) => {
|
// const handleViewActivities = (project) => {
|
||||||
dispatch(setProjectId(project));
|
// dispatch(setProjectId(project));
|
||||||
navigate(`/activities/records?project=${project}`);
|
// navigate(`/activities/records?project=${project}`);
|
||||||
};
|
// };
|
||||||
|
|
||||||
|
const handleMoveDetails = (project) => {
|
||||||
|
dispatch(setProjectId(project));
|
||||||
|
navigate("/projects/details");
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<div className="card page-min-h py-4 px-6 shadow-sm">
|
<div className="card page-min-h py-4 px-6 shadow-sm">
|
||||||
<table className="table table-hover align-middle m-0">
|
<table className="table table-hover align-middle m-0">
|
||||||
@ -158,11 +161,7 @@ const ProjectListView = ({
|
|||||||
: project[col.key] || "N/A"}
|
: project[col.key] || "N/A"}
|
||||||
</td>
|
</td>
|
||||||
))}
|
))}
|
||||||
<td
|
<td className={`mx-2 ${"d-sm-table-cell"}`}>
|
||||||
className={`mx-2 ${
|
|
||||||
canManageProject ? "d-sm-table-cell" : "d-none"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<div className="dropdown z-2">
|
<div className="dropdown z-2">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@ -180,7 +179,7 @@ const ProjectListView = ({
|
|||||||
></i>
|
></i>
|
||||||
</button>
|
</button>
|
||||||
<ul className="dropdown-menu dropdown-menu-end">
|
<ul className="dropdown-menu dropdown-menu-end">
|
||||||
<li>
|
<li onClick={() => handleMoveDetails(project.id)}>
|
||||||
<a
|
<a
|
||||||
aria-label="click to View details"
|
aria-label="click to View details"
|
||||||
className="dropdown-item cursor-pointer"
|
className="dropdown-item cursor-pointer"
|
||||||
@ -204,12 +203,12 @@ const ProjectListView = ({
|
|||||||
<span className="align-left">Modify</span>
|
<span className="align-left">Modify</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li onClick={() => handleViewActivities(project.id)}>
|
{/* <li onClick={() => handleViewActivities(project.id)}>
|
||||||
<a className="dropdown-item cursor-pointer">
|
<a className="dropdown-item cursor-pointer">
|
||||||
<i className="bx bx-task me-2"></i>
|
<i className="bx bx-task me-2"></i>
|
||||||
<span className="align-left">Activities</span>
|
<span className="align-left">Activities</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li> */}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
@ -120,7 +120,7 @@ export const useUploadDocument = (onSuccessCallBack) => {
|
|||||||
DocumentRepository.uploadDocument(DocumentPayload),
|
DocumentRepository.uploadDocument(DocumentPayload),
|
||||||
onSuccess: (data, variables) => {
|
onSuccess: (data, variables) => {
|
||||||
queryClient.invalidateQueries({ queryKey: ["DocumentList"] });
|
queryClient.invalidateQueries({ queryKey: ["DocumentList"] });
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["Document"] });
|
||||||
if (onSuccessCallBack) onSuccessCallBack();
|
if (onSuccessCallBack) onSuccessCallBack();
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
@ -141,7 +141,7 @@ export const useUpdateDocument = (onSuccessCallBack) => {
|
|||||||
onSuccess: (data, variables) => {
|
onSuccess: (data, variables) => {
|
||||||
const { documentId } = variables;
|
const { documentId } = variables;
|
||||||
queryClient.invalidateQueries({ queryKey: ["DocumentList"] });
|
queryClient.invalidateQueries({ queryKey: ["DocumentList"] });
|
||||||
queryClient.invalidateQueries({ queryKey: ["Document", documentId] });
|
queryClient.invalidateQueries({ queryKey: ["Document"] });
|
||||||
if (onSuccessCallBack) onSuccessCallBack();
|
if (onSuccessCallBack) onSuccessCallBack();
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
@ -187,6 +187,7 @@ export const useActiveInActiveDocument = ()=>{
|
|||||||
onSuccess: (data, variables) => {
|
onSuccess: (data, variables) => {
|
||||||
const {isActive} = variables;
|
const {isActive} = variables;
|
||||||
queryClient.invalidateQueries({ queryKey: ["DocumentList"] });
|
queryClient.invalidateQueries({ queryKey: ["DocumentList"] });
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["Document"] });
|
||||||
showToast(`Document ${isActive ? "restored":"Deleted"} successfully`,"success")
|
showToast(`Document ${isActive ? "restored":"Deleted"} successfully`,"success")
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
|
@ -44,7 +44,7 @@ export default function DirectoryPage({ IsPage = true, projectId = null }) {
|
|||||||
const [searchNote, setSearchNote] = useState("");
|
const [searchNote, setSearchNote] = useState("");
|
||||||
const [activeTab, setActiveTab] = useState("notes");
|
const [activeTab, setActiveTab] = useState("notes");
|
||||||
const { setActions } = useFab();
|
const { setActions } = useFab();
|
||||||
const [gridView, setGridView] = useState(false);
|
const [gridView, setGridView] = useState(true);
|
||||||
const [isOpenBucket, setOpenBucket] = useState(false);
|
const [isOpenBucket, setOpenBucket] = useState(false);
|
||||||
const [isManageContact, setManageContact] = useState({
|
const [isManageContact, setManageContact] = useState({
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
@ -185,14 +185,7 @@ export default function DirectoryPage({ IsPage = true, projectId = null }) {
|
|||||||
value={searchContact}
|
value={searchContact}
|
||||||
onChange={(e) => setsearchContact(e.target.value)}
|
onChange={(e) => setsearchContact(e.target.value)}
|
||||||
/>
|
/>
|
||||||
<button
|
|
||||||
className={`btn btn-sm p-1 ${
|
|
||||||
!gridView ? "btn-primary" : "btn-outline-primary"
|
|
||||||
}`}
|
|
||||||
onClick={() => setGridView(false)}
|
|
||||||
>
|
|
||||||
<i className="bx bx-list-ul"></i>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className={`btn btn-sm p-1 ${
|
className={`btn btn-sm p-1 ${
|
||||||
@ -202,6 +195,15 @@ export default function DirectoryPage({ IsPage = true, projectId = null }) {
|
|||||||
>
|
>
|
||||||
<i className="bx bx-grid-alt"></i>
|
<i className="bx bx-grid-alt"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className={`btn btn-sm p-1 ${
|
||||||
|
!gridView ? "btn-primary" : "btn-outline-primary"
|
||||||
|
}`}
|
||||||
|
onClick={() => setGridView(false)}
|
||||||
|
>
|
||||||
|
<i className="bx bx-list-ul"></i>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-check form-switch d-flex align-items-center">
|
<div className="form-check form-switch d-flex align-items-center">
|
||||||
|
@ -60,12 +60,12 @@ const NoteFilterPanel = ({ onApply, clearFilter }) => {
|
|||||||
<div className="d-flex justify-content-end py-3 gap-2">
|
<div className="d-flex justify-content-end py-3 gap-2">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-label-secondary btn-xs"
|
className="btn btn-label-secondary btn-sm"
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
>
|
>
|
||||||
Clear
|
Clear
|
||||||
</button>
|
</button>
|
||||||
<button type="submit" className="btn btn-primary btn-xs">
|
<button type="submit" className="btn btn-primary btn-sm">
|
||||||
Apply
|
Apply
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -51,11 +51,7 @@ const EmployeeList = () => {
|
|||||||
const Manage_Employee = useHasUserPermission(MANAGE_EMPLOYEES);
|
const Manage_Employee = useHasUserPermission(MANAGE_EMPLOYEES);
|
||||||
|
|
||||||
const { employees, loading, setLoading, error, recallEmployeeData } =
|
const { employees, loading, setLoading, error, recallEmployeeData } =
|
||||||
useEmployeesAllOrByProjectId(
|
useEmployeesAllOrByProjectId(showAllEmployees, null, showInactive);
|
||||||
showAllEmployees,
|
|
||||||
null,
|
|
||||||
showInactive
|
|
||||||
);
|
|
||||||
|
|
||||||
const [employeeList, setEmployeeList] = useState([]);
|
const [employeeList, setEmployeeList] = useState([]);
|
||||||
const [modelConfig, setModelConfig] = useState();
|
const [modelConfig, setModelConfig] = useState();
|
||||||
@ -204,22 +200,16 @@ const EmployeeList = () => {
|
|||||||
|
|
||||||
setCurrentPage((prevPage) => (prevPage !== 1 ? 1 : prevPage));
|
setCurrentPage((prevPage) => (prevPage !== 1 ? 1 : prevPage));
|
||||||
}
|
}
|
||||||
}, [loading, employees, showAllEmployees]);
|
}, [loading, employees, showAllEmployees]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const handler = useCallback(
|
const handler = useCallback(
|
||||||
(msg) => {
|
(msg) => {
|
||||||
if (employees.some((item) => item.id == msg.employeeId)) {
|
if (employees.some((item) => item.id == msg.employeeId)) {
|
||||||
setEmployeeList([]);
|
setEmployeeList([]);
|
||||||
recallEmployeeData(
|
recallEmployeeData(showInactive, null, showAllEmployees);
|
||||||
showInactive,
|
|
||||||
null,
|
|
||||||
showAllEmployees
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[employees, showInactive, showAllEmployees]
|
[employees, showInactive, showAllEmployees]
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -289,18 +279,16 @@ const EmployeeList = () => {
|
|||||||
|
|
||||||
{ViewTeamMember ? (
|
{ViewTeamMember ? (
|
||||||
// <div className="row">
|
// <div className="row">
|
||||||
<div className="card page-min-h p-1">
|
<div className="card page-min-h ">
|
||||||
<div className="card-datatable table-responsive pt-5 mx-5 py-10">
|
<div
|
||||||
<div
|
id="DataTables_Table_0_wrapper"
|
||||||
id="DataTables_Table_0_wrapper"
|
className="dataTables_wrapper dt-bootstrap5 no-footer p-1 pt-5 mx-5 py-10"
|
||||||
className="dataTables_wrapper dt-bootstrap5 no-footer"
|
>
|
||||||
style={{ width: "100%" }}
|
<div className="d-flex flex-wrap align-items-center justify-content-between gap-3 mb-3">
|
||||||
>
|
{/* Switches: All Employees + Inactive */}
|
||||||
<div className="d-flex flex-wrap align-items-center justify-content-between gap-3 mb-3">
|
<div className="d-flex flex-wrap align-items-center gap-3">
|
||||||
{/* Switches: All Employees + Inactive */}
|
{/* All Employees Switch */}
|
||||||
<div className="d-flex flex-wrap align-items-center gap-3">
|
{/* {ViewAllEmployee && (
|
||||||
{/* All Employees Switch */}
|
|
||||||
{/* {ViewAllEmployee && (
|
|
||||||
<div className="form-check form-switch text-start">
|
<div className="form-check form-switch text-start">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@ -319,390 +307,380 @@ const EmployeeList = () => {
|
|||||||
</div>
|
</div>
|
||||||
)} */}
|
)} */}
|
||||||
|
|
||||||
{/* Show Inactive Employees Switch */}
|
{/* Show Inactive Employees Switch */}
|
||||||
{/* {showAllEmployees && ( */}
|
{/* {showAllEmployees && ( */}
|
||||||
<div className="form-check form-switch text-start">
|
<div className="form-check form-switch text-start">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
className="form-check-input"
|
className="form-check-input"
|
||||||
role="switch"
|
role="switch"
|
||||||
id="inactiveEmployeesCheckbox"
|
id="inactiveEmployeesCheckbox"
|
||||||
checked={showInactive}
|
checked={showInactive}
|
||||||
onChange={(e) => setShowInactive(e.target.checked)}
|
onChange={(e) => setShowInactive(e.target.checked)}
|
||||||
/>
|
/>
|
||||||
<label
|
<label
|
||||||
className="form-check-label ms-0"
|
className="form-check-label ms-0"
|
||||||
htmlFor="inactiveEmployeesCheckbox"
|
htmlFor="inactiveEmployeesCheckbox"
|
||||||
>
|
>
|
||||||
Show Inactive Employees
|
Show Inactive Employees
|
||||||
</label>
|
</label>
|
||||||
</div>
|
|
||||||
{/* )} */}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Right side: Search + Export + Add Employee */}
|
|
||||||
<div className="d-flex flex-wrap align-items-center justify-content-end gap-3 flex-grow-1">
|
|
||||||
{/* Search Input - ALWAYS ENABLED */}
|
|
||||||
<div className="dataTables_filter">
|
|
||||||
<label className="mb-0">
|
|
||||||
<input
|
|
||||||
type="search"
|
|
||||||
value={searchText}
|
|
||||||
onChange={handleSearch}
|
|
||||||
className="form-control form-control-sm"
|
|
||||||
placeholder="Search Employee"
|
|
||||||
aria-controls="DataTables_Table_0"
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Export Dropdown */}
|
|
||||||
<div className="dropdown">
|
|
||||||
<button
|
|
||||||
aria-label="Click me"
|
|
||||||
className="btn btn-sm btn-label-secondary dropdown-toggle"
|
|
||||||
type="button"
|
|
||||||
data-bs-toggle="dropdown"
|
|
||||||
aria-expanded="false"
|
|
||||||
>
|
|
||||||
<i className="bx bx-export me-2 bx-sm"></i>Export
|
|
||||||
</button>
|
|
||||||
<ul className="dropdown-menu">
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
className="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
onClick={() => handleExport("print")}
|
|
||||||
>
|
|
||||||
<i className="bx bx-printer me-1"></i> Print
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
className="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
onClick={() => handleExport("csv")}
|
|
||||||
>
|
|
||||||
<i className="bx bx-file me-1"></i> CSV
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
className="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
onClick={() => handleExport("excel")}
|
|
||||||
>
|
|
||||||
<i className="bx bxs-file-export me-1"></i> Excel
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
className="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
onClick={() => handleExport("pdf")}
|
|
||||||
>
|
|
||||||
<i className="bx bxs-file-pdf me-1"></i> PDF
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Add Employee Button */}
|
|
||||||
{Manage_Employee && (
|
|
||||||
<button
|
|
||||||
className="btn btn-sm btn-primary"
|
|
||||||
type="button"
|
|
||||||
onClick={() => handleEmployeeModel(null)}
|
|
||||||
>
|
|
||||||
<i className="bx bx-plus-circle me-2"></i>
|
|
||||||
<span className="d-none d-md-inline-block">
|
|
||||||
Add New Employee
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
{/* )} */}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table
|
{/* Right side: Search + Export + Add Employee */}
|
||||||
className="datatables-users table border-top dataTable no-footer dtr-column text-nowrap"
|
<div className="d-flex flex-wrap align-items-center justify-content-end gap-3 flex-grow-1">
|
||||||
id="DataTables_Table_0"
|
{/* Search Input - ALWAYS ENABLED */}
|
||||||
aria-describedby="DataTables_Table_0_info"
|
<div className="dataTables_filter">
|
||||||
style={{ width: "100%" }}
|
<label className="mb-0">
|
||||||
ref={tableRef}
|
<input
|
||||||
>
|
type="search"
|
||||||
<thead>
|
value={searchText}
|
||||||
<tr>
|
onChange={handleSearch}
|
||||||
<th
|
className="form-control form-control-sm"
|
||||||
className="sorting sorting_desc"
|
placeholder="Search Employee"
|
||||||
tabIndex="0"
|
|
||||||
aria-controls="DataTables_Table_0"
|
aria-controls="DataTables_Table_0"
|
||||||
rowSpan="1"
|
/>
|
||||||
colSpan="2"
|
</label>
|
||||||
aria-label="User: activate to sort column ascending"
|
</div>
|
||||||
aria-sort="descending"
|
|
||||||
>
|
|
||||||
<div className="text-start ms-6">Name</div>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
className="sorting sorting_desc d-none d-sm-table-cell"
|
|
||||||
tabIndex="0"
|
|
||||||
aria-controls="DataTables_Table_0"
|
|
||||||
rowSpan="1"
|
|
||||||
colSpan="1"
|
|
||||||
aria-label="User: activate to sort column ascending"
|
|
||||||
aria-sort="descending"
|
|
||||||
>
|
|
||||||
<div className="text-start ms-5">Email</div>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
className="sorting sorting_desc d-none d-sm-table-cell"
|
|
||||||
tabIndex="0"
|
|
||||||
aria-controls="DataTables_Table_0"
|
|
||||||
rowSpan="1"
|
|
||||||
colSpan="1"
|
|
||||||
aria-label="User: activate to sort column ascending"
|
|
||||||
aria-sort="descending"
|
|
||||||
>
|
|
||||||
<div className="text-start ms-5">Contact</div>
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
className="sorting sorting_desc d-none d-sm-table-cell"
|
|
||||||
tabIndex="0"
|
|
||||||
aria-controls="DataTables_Table_0"
|
|
||||||
rowSpan="1"
|
|
||||||
colSpan="1"
|
|
||||||
aria-label="User: activate to sort column ascending"
|
|
||||||
aria-sort="descending"
|
|
||||||
>
|
|
||||||
<div className="text-start ms-5">Designation</div>
|
|
||||||
</th>
|
|
||||||
|
|
||||||
<th
|
{/* Export Dropdown */}
|
||||||
className="sorting d-none d-md-table-cell"
|
<div className="dropdown">
|
||||||
tabIndex="0"
|
<button
|
||||||
aria-controls="DataTables_Table_0"
|
aria-label="Click me"
|
||||||
rowSpan="1"
|
className="btn btn-sm btn-label-secondary dropdown-toggle"
|
||||||
colSpan="1"
|
type="button"
|
||||||
aria-label="Plan: activate to sort column ascending"
|
data-bs-toggle="dropdown"
|
||||||
>
|
aria-expanded="false"
|
||||||
Joining Date
|
>
|
||||||
</th>
|
<i className="bx bx-export me-2 bx-sm"></i>Export
|
||||||
<th
|
</button>
|
||||||
className="sorting"
|
<ul className="dropdown-menu">
|
||||||
tabIndex="0"
|
<li>
|
||||||
aria-controls="DataTables_Table_0"
|
<a
|
||||||
rowSpan="1"
|
className="dropdown-item"
|
||||||
colSpan="1"
|
href="#"
|
||||||
aria-label="Billing: activate to sort column ascending"
|
onClick={() => handleExport("print")}
|
||||||
>
|
|
||||||
Status
|
|
||||||
</th>
|
|
||||||
<th
|
|
||||||
className={`sorting_disabled ${
|
|
||||||
!Manage_Employee && "d-none"
|
|
||||||
}`}
|
|
||||||
rowSpan="1"
|
|
||||||
colSpan="1"
|
|
||||||
style={{ width: "50px" }}
|
|
||||||
aria-label="Actions"
|
|
||||||
>
|
|
||||||
Actions
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{loading && (
|
|
||||||
<tr>
|
|
||||||
<td colSpan={8}>
|
|
||||||
<p>Loading...</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
{/* Conditional messages for no data or no search results */}
|
|
||||||
{!loading &&
|
|
||||||
displayData?.length === 0 &&
|
|
||||||
searchText &&
|
|
||||||
!showAllEmployees ? (
|
|
||||||
<tr>
|
|
||||||
<td colSpan={8}>
|
|
||||||
<small className="muted">
|
|
||||||
'{searchText}' employee not found
|
|
||||||
</small>{" "}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
) : null}
|
|
||||||
{!loading &&
|
|
||||||
displayData?.length === 0 &&
|
|
||||||
(!searchText || showAllEmployees) ? (
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
colSpan={8}
|
|
||||||
className="border-0"
|
|
||||||
>
|
>
|
||||||
<div className="py-1">
|
<i className="bx bx-printer me-1"></i> Print
|
||||||
No Employeee Found
|
</a>
|
||||||
</div>
|
</li>
|
||||||
</td>
|
<li>
|
||||||
</tr>
|
<a
|
||||||
) : null}
|
className="dropdown-item"
|
||||||
|
href="#"
|
||||||
|
onClick={() => handleExport("csv")}
|
||||||
|
>
|
||||||
|
<i className="bx bx-file me-1"></i> CSV
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
className="dropdown-item"
|
||||||
|
href="#"
|
||||||
|
onClick={() => handleExport("excel")}
|
||||||
|
>
|
||||||
|
<i className="bx bxs-file-export me-1"></i> Excel
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
className="dropdown-item"
|
||||||
|
href="#"
|
||||||
|
onClick={() => handleExport("pdf")}
|
||||||
|
>
|
||||||
|
<i className="bx bxs-file-pdf me-1"></i> PDF
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Render current items */}
|
{/* Add Employee Button */}
|
||||||
{currentItems &&
|
{Manage_Employee && (
|
||||||
!loading &&
|
<button
|
||||||
currentItems.map((item) => (
|
className="btn btn-sm btn-primary"
|
||||||
<tr className="odd" key={item.id}>
|
type="button"
|
||||||
<td className="sorting_1" colSpan={2}>
|
onClick={() => handleEmployeeModel(null)}
|
||||||
<div className="d-flex justify-content-start align-items-center user-name">
|
>
|
||||||
<Avatar
|
<i className="bx bx-plus-circle me-2"></i>
|
||||||
firstName={item.firstName}
|
<span className="d-none d-md-inline-block">
|
||||||
lastName={item.lastName}
|
Add New Employee
|
||||||
></Avatar>
|
</span>
|
||||||
<div className="d-flex flex-column">
|
</button>
|
||||||
<a
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table
|
||||||
|
className="datatables-users table border-top dataTable no-footer dtr-column text-nowrap"
|
||||||
|
id="DataTables_Table_0"
|
||||||
|
aria-describedby="DataTables_Table_0_info"
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
ref={tableRef}
|
||||||
|
>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th
|
||||||
|
className="sorting sorting_desc"
|
||||||
|
tabIndex="0"
|
||||||
|
aria-controls="DataTables_Table_0"
|
||||||
|
rowSpan="1"
|
||||||
|
colSpan="2"
|
||||||
|
aria-label="User: activate to sort column ascending"
|
||||||
|
aria-sort="descending"
|
||||||
|
>
|
||||||
|
<div className="text-start ms-6">Name</div>
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="sorting sorting_desc d-none d-sm-table-cell"
|
||||||
|
tabIndex="0"
|
||||||
|
aria-controls="DataTables_Table_0"
|
||||||
|
rowSpan="1"
|
||||||
|
colSpan="1"
|
||||||
|
aria-label="User: activate to sort column ascending"
|
||||||
|
aria-sort="descending"
|
||||||
|
>
|
||||||
|
<div className="text-start ms-5">Email</div>
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="sorting sorting_desc d-none d-sm-table-cell"
|
||||||
|
tabIndex="0"
|
||||||
|
aria-controls="DataTables_Table_0"
|
||||||
|
rowSpan="1"
|
||||||
|
colSpan="1"
|
||||||
|
aria-label="User: activate to sort column ascending"
|
||||||
|
aria-sort="descending"
|
||||||
|
>
|
||||||
|
<div className="text-start ms-5">Contact</div>
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="sorting sorting_desc d-none d-sm-table-cell"
|
||||||
|
tabIndex="0"
|
||||||
|
aria-controls="DataTables_Table_0"
|
||||||
|
rowSpan="1"
|
||||||
|
colSpan="1"
|
||||||
|
aria-label="User: activate to sort column ascending"
|
||||||
|
aria-sort="descending"
|
||||||
|
>
|
||||||
|
<div className="text-start ms-5">Designation</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th
|
||||||
|
className="sorting d-none d-md-table-cell"
|
||||||
|
tabIndex="0"
|
||||||
|
aria-controls="DataTables_Table_0"
|
||||||
|
rowSpan="1"
|
||||||
|
colSpan="1"
|
||||||
|
aria-label="Plan: activate to sort column ascending"
|
||||||
|
>
|
||||||
|
Joining Date
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className="sorting"
|
||||||
|
tabIndex="0"
|
||||||
|
aria-controls="DataTables_Table_0"
|
||||||
|
rowSpan="1"
|
||||||
|
colSpan="1"
|
||||||
|
aria-label="Billing: activate to sort column ascending"
|
||||||
|
>
|
||||||
|
Status
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
className={`sorting_disabled ${
|
||||||
|
!Manage_Employee && "d-none"
|
||||||
|
}`}
|
||||||
|
rowSpan="1"
|
||||||
|
colSpan="1"
|
||||||
|
style={{ width: "50px" }}
|
||||||
|
aria-label="Actions"
|
||||||
|
>
|
||||||
|
Actions
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{loading && (
|
||||||
|
<tr>
|
||||||
|
<td colSpan={8}>
|
||||||
|
<p>Loading...</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
|
{/* Conditional messages for no data or no search results */}
|
||||||
|
{!loading &&
|
||||||
|
displayData?.length === 0 &&
|
||||||
|
searchText ? (
|
||||||
|
<tr>
|
||||||
|
<td colSpan={8} className="border-0">
|
||||||
|
<div className="py-12">
|
||||||
|
<small className="muted">
|
||||||
|
'{searchText}' employee not found
|
||||||
|
</small>{" "}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
) : null}
|
||||||
|
{!loading &&
|
||||||
|
displayData?.length === 0 &&
|
||||||
|
(!searchText ) ? (
|
||||||
|
<tr>
|
||||||
|
<td colSpan={8} className="border-0">
|
||||||
|
<div className="py-12">{showInactive ? "No In-active Employeee Found" : "No Employeee Found" }</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{/* Render current items */}
|
||||||
|
{currentItems &&
|
||||||
|
!loading &&
|
||||||
|
currentItems.map((item) => (
|
||||||
|
<tr className="odd" key={item.id}>
|
||||||
|
<td className="sorting_1" colSpan={2}>
|
||||||
|
<div className="d-flex justify-content-start align-items-center user-name">
|
||||||
|
<Avatar
|
||||||
|
firstName={item.firstName}
|
||||||
|
lastName={item.lastName}
|
||||||
|
></Avatar>
|
||||||
|
<div className="d-flex flex-column">
|
||||||
|
<a
|
||||||
|
onClick={() => navigate(`/employee/${item.id}`)}
|
||||||
|
className="text-heading text-truncate cursor-pointer"
|
||||||
|
>
|
||||||
|
<span className="fw-normal">
|
||||||
|
{item.firstName} {item.middleName}{" "}
|
||||||
|
{item.lastName}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td className="text-start d-none d-sm-table-cell">
|
||||||
|
{item.email ? (
|
||||||
|
<span className="text-truncate">
|
||||||
|
<i className="bx bxs-envelope text-primary me-2"></i>
|
||||||
|
{item.email}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span className="text-truncate text-italic">-</span>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td className="text-start d-none d-sm-table-cell">
|
||||||
|
<span className="text-truncate">
|
||||||
|
<i className="bx bxs-phone-call text-primary me-2"></i>
|
||||||
|
{item.phoneNumber}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td className=" d-none d-sm-table-cell text-start">
|
||||||
|
<span className="text-truncate">
|
||||||
|
<i className="bx bxs-wrench text-success me-2"></i>
|
||||||
|
{item.jobRole || "Not Assign Yet"}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td className=" d-none d-md-table-cell">
|
||||||
|
{moment(item.joiningDate)?.format("DD-MMM-YYYY")}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{showInactive ? (
|
||||||
|
<span
|
||||||
|
className="badge bg-label-danger"
|
||||||
|
text-capitalized=""
|
||||||
|
>
|
||||||
|
Inactive
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span
|
||||||
|
className="badge bg-label-success"
|
||||||
|
text-capitalized=""
|
||||||
|
>
|
||||||
|
Active
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
{Manage_Employee && (
|
||||||
|
<td className="text-end">
|
||||||
|
<div className="dropdown">
|
||||||
|
<button
|
||||||
|
className="btn btn-icon dropdown-toggle hide-arrow"
|
||||||
|
data-bs-toggle="dropdown"
|
||||||
|
>
|
||||||
|
<i className="bx bx-dots-vertical-rounded bx-md"></i>
|
||||||
|
</button>
|
||||||
|
<div className="dropdown-menu dropdown-menu-end">
|
||||||
|
{/* View always visible */}
|
||||||
|
<button
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
navigate(`/employee/${item.id}`)
|
navigate(`/employee/${item.id}`)
|
||||||
}
|
}
|
||||||
className="text-heading text-truncate cursor-pointer"
|
className="dropdown-item py-1"
|
||||||
>
|
>
|
||||||
<span className="fw-normal">
|
<i className="bx bx-detail bx-sm"></i> View
|
||||||
{item.firstName} {item.middleName}{" "}
|
</button>
|
||||||
{item.lastName}
|
|
||||||
</span>
|
{/* If ACTIVE employee */}
|
||||||
</a>
|
{item.isActive && (
|
||||||
|
<>
|
||||||
|
<button
|
||||||
|
className="dropdown-item py-1"
|
||||||
|
onClick={() =>
|
||||||
|
handleEmployeeModel(item.id)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<i className="bx bx-edit bx-sm"></i> Edit
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Suspend only when active */}
|
||||||
|
{item.isActive && (
|
||||||
|
<button
|
||||||
|
className="dropdown-item py-1"
|
||||||
|
onClick={() => handleOpenDelete(item)}
|
||||||
|
>
|
||||||
|
<i className="bx bx-task-x bx-sm"></i>{" "}
|
||||||
|
Suspend
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="dropdown-item py-1"
|
||||||
|
type="button"
|
||||||
|
data-bs-toggle="modal"
|
||||||
|
data-bs-target="#managerole-modal"
|
||||||
|
onClick={() =>
|
||||||
|
setEmpForManageRole(item.id)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<i className="bx bx-cog bx-sm"></i> Manage
|
||||||
|
Role
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* If INACTIVE employee AND inactive toggle is ON */}
|
||||||
|
{!item.isActive && showInactive && (
|
||||||
|
<button
|
||||||
|
className="dropdown-item py-1"
|
||||||
|
onClick={() => handleOpenDelete(item)}
|
||||||
|
>
|
||||||
|
<i className="bx bx-refresh bx-sm me-1"></i>{" "}
|
||||||
|
Re-activate
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className="text-start d-none d-sm-table-cell">
|
)}
|
||||||
{item.email ? (
|
</tr>
|
||||||
<span className="text-truncate">
|
))}
|
||||||
<i className="bx bxs-envelope text-primary me-2"></i>
|
</tbody>
|
||||||
{item.email}
|
</table>
|
||||||
</span>
|
|
||||||
) : (
|
|
||||||
<span className="text-truncate text-italic">
|
|
||||||
-
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</td>
|
|
||||||
<td className="text-start d-none d-sm-table-cell">
|
|
||||||
<span className="text-truncate">
|
|
||||||
<i className="bx bxs-phone-call text-primary me-2"></i>
|
|
||||||
{item.phoneNumber}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td className=" d-none d-sm-table-cell text-start">
|
|
||||||
<span className="text-truncate">
|
|
||||||
<i className="bx bxs-wrench text-success me-2"></i>
|
|
||||||
{item.jobRole || "Not Assign Yet"}
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td className=" d-none d-md-table-cell">
|
{displayData.length > 0 && (
|
||||||
{moment(item.joiningDate)?.format("DD-MMM-YYYY")}
|
<Pagination
|
||||||
</td>
|
currentPage={currentPage}
|
||||||
<td>
|
totalPages={totalPages}
|
||||||
{showInactive ? (
|
onPageChange={paginate}
|
||||||
<span
|
/>
|
||||||
className="badge bg-label-danger"
|
)}
|
||||||
text-capitalized=""
|
|
||||||
>
|
|
||||||
Inactive
|
|
||||||
</span>
|
|
||||||
) : (
|
|
||||||
<span
|
|
||||||
className="badge bg-label-success"
|
|
||||||
text-capitalized=""
|
|
||||||
>
|
|
||||||
Active
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</td>
|
|
||||||
{Manage_Employee && (
|
|
||||||
<td className="text-end">
|
|
||||||
<div className="dropdown">
|
|
||||||
<button
|
|
||||||
className="btn btn-icon dropdown-toggle hide-arrow"
|
|
||||||
data-bs-toggle="dropdown"
|
|
||||||
>
|
|
||||||
<i className="bx bx-dots-vertical-rounded bx-md"></i>
|
|
||||||
</button>
|
|
||||||
<div className="dropdown-menu dropdown-menu-end">
|
|
||||||
{/* View always visible */}
|
|
||||||
<button
|
|
||||||
onClick={() =>
|
|
||||||
navigate(`/employee/${item.id}`)
|
|
||||||
}
|
|
||||||
className="dropdown-item py-1"
|
|
||||||
>
|
|
||||||
<i className="bx bx-detail bx-sm"></i> View
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{/* If ACTIVE employee */}
|
|
||||||
{item.isActive && (
|
|
||||||
<>
|
|
||||||
<button
|
|
||||||
className="dropdown-item py-1"
|
|
||||||
onClick={() =>
|
|
||||||
handleEmployeeModel(item.id)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<i className="bx bx-edit bx-sm"></i>{" "}
|
|
||||||
Edit
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{/* Suspend only when active */}
|
|
||||||
{item.isActive && (
|
|
||||||
<button
|
|
||||||
className="dropdown-item py-1"
|
|
||||||
onClick={() => handleOpenDelete(item)}
|
|
||||||
>
|
|
||||||
<i className="bx bx-task-x bx-sm"></i>{" "}
|
|
||||||
Suspend
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<button
|
|
||||||
className="dropdown-item py-1"
|
|
||||||
type="button"
|
|
||||||
data-bs-toggle="modal"
|
|
||||||
data-bs-target="#managerole-modal"
|
|
||||||
onClick={() =>
|
|
||||||
setEmpForManageRole(item.id)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<i className="bx bx-cog bx-sm"></i>{" "}
|
|
||||||
Manage Role
|
|
||||||
</button>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* If INACTIVE employee AND inactive toggle is ON */}
|
|
||||||
{!item.isActive && showInactive && (
|
|
||||||
<button
|
|
||||||
className="dropdown-item py-1"
|
|
||||||
onClick={() => handleOpenDelete(item)}
|
|
||||||
>
|
|
||||||
<i className="bx bx-refresh bx-sm me-1"></i>{" "}
|
|
||||||
Re-activate
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
)}
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
{displayData.length > 0 && (
|
|
||||||
<Pagination
|
|
||||||
currentPage={currentPage}
|
|
||||||
totalPages={totalPages}
|
|
||||||
onPageChange={paginate}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
@ -161,8 +161,8 @@ const MasterPage = () => {
|
|||||||
data={[{ label: "Home", link: "/dashboard" }, { label: "Masters" }]}
|
data={[{ label: "Home", link: "/dashboard" }, { label: "Masters" }]}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="row">
|
|
||||||
<div className="card">
|
<div className="card page-min-h">
|
||||||
<div
|
<div
|
||||||
className="card-datatable table-responsive py-10 mx-5 "
|
className="card-datatable table-responsive py-10 mx-5 "
|
||||||
style={{ overflow: "hidden" }}
|
style={{ overflow: "hidden" }}
|
||||||
@ -221,7 +221,6 @@ const MasterPage = () => {
|
|||||||
handleModalData={handleModalData}
|
handleModalData={handleModalData}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</MasterContext.Provider>
|
</MasterContext.Provider>
|
||||||
|
@ -109,11 +109,11 @@ const MasterTable = ({ data, columns, loading, handleModalData }) => {
|
|||||||
{currentItems.length > 0 ? (
|
{currentItems.length > 0 ? (
|
||||||
currentItems.map((item, index) => (
|
currentItems.map((item, index) => (
|
||||||
<tr key={index}>
|
<tr key={index}>
|
||||||
<td style={{ width: "20px" }}>
|
<td style={{ width: "20px", }} className="py-5">
|
||||||
<i className="bx bx-right-arrow-alt"></i>
|
<div className="py-2 px-3"><i className="bx bx-right-arrow-alt"></i></div>
|
||||||
</td>
|
</td>
|
||||||
{updatedColumns.map((col) => (
|
{updatedColumns.map((col) => (
|
||||||
<td className="text-start mx-2" key={col.key}>
|
<td className="text-start mx-2 p-3" key={col.key} style={{ padding: "12px 16px" }} >
|
||||||
{col.key === "description" ? (
|
{col.key === "description" ? (
|
||||||
item[col.key] !== undefined &&
|
item[col.key] !== undefined &&
|
||||||
item[col.key] !== null ? (
|
item[col.key] !== null ? (
|
||||||
|
@ -32,100 +32,104 @@ export function startSignalR(loggedUser) {
|
|||||||
.toISOString()
|
.toISOString()
|
||||||
.split("T")[0];
|
.split("T")[0];
|
||||||
connection.on("NotificationEventHandler", (data) => {
|
connection.on("NotificationEventHandler", (data) => {
|
||||||
if (data.loggedInUserId != loggedUser?.employeeInfo.id) {
|
const { loggedInUserId, keyword, response, employeeList, numberOfImages } = data;
|
||||||
// console.log("Notification received:", data);
|
const loggedInId = loggedUser?.employeeInfo?.id;
|
||||||
// if action taken on attendance module
|
|
||||||
if (data.keyword == "Attendance") {
|
|
||||||
const checkIn = data.response.checkInTime.substring(0, 10);
|
|
||||||
if (today === checkIn) {
|
|
||||||
eventBus.emit("attendance", data);
|
|
||||||
}
|
|
||||||
var onlyDate = Number(checkIn.substring(8, 10));
|
|
||||||
|
|
||||||
var afterTwoDay =
|
if (loggedInUserId === loggedInId) return;
|
||||||
checkIn.substring(0, 8) + (onlyDate + 2).toString().padStart(2, "0");
|
|
||||||
if (
|
|
||||||
afterTwoDay <= today &&
|
|
||||||
(data.response.activity == 4 || data.response.activity == 5)
|
|
||||||
) {
|
|
||||||
eventBus.emit("regularization", data);
|
|
||||||
}
|
|
||||||
eventBus.emit("attendance_log", data);
|
|
||||||
}
|
|
||||||
if(data.keyword == "Expanse"){
|
|
||||||
queryClient.invalidateQueries({queryKey:["Expenses"]})
|
|
||||||
}
|
|
||||||
// if create or update project
|
|
||||||
if (
|
|
||||||
data.keyword == "Create_Project" ||
|
|
||||||
data.keyword == "Update_Project"
|
|
||||||
) {
|
|
||||||
// clearCacheKey("projectslist");
|
|
||||||
queryClient.invalidateQueries(['projectslist']);
|
|
||||||
eventBus.emit("project", data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if assign or deassign employee to any project
|
// ---- Handlers for invalidate or remove ----
|
||||||
if (data.keyword == "Assign_Project") {
|
const queryInvalidators = {
|
||||||
if (
|
Expanse: () => {
|
||||||
data.employeeList.some((item) => item === loggedUser?.employeeInfo.id)
|
queryClient.invalidateQueries({ queryKey: ["Expenses"] }),
|
||||||
) {
|
queryClient.invalidateQueries({ queryKey: ["Expense"] })
|
||||||
try {
|
},
|
||||||
cacheData("hasReceived", false);
|
Create_Project: () => queryClient.invalidateQueries(["projectslist"]),
|
||||||
eventBus.emit("assign_project_one", data);
|
Update_Project: () => queryClient.invalidateQueries(["projectslist"]),
|
||||||
} catch (e) {
|
Infra: () => queryClient.removeQueries({ queryKey: ["ProjectInfra"] }),
|
||||||
// console.error("Error in cacheData:", e);
|
Task_Report: () => queryClient.invalidateQueries({ queryKey: ["Infra"] }),
|
||||||
}
|
WorkItem: () => queryClient.invalidateQueries({ queryKey: ["WorkItems"] }),
|
||||||
}
|
Directory_Notes:()=>{
|
||||||
eventBus.emit("assign_project_all", data);
|
queryClient.invalidateQueries({queryKey:["directoryNotes"]})
|
||||||
}
|
queryClient.invalidateQueries({queryKey:["Notes"]})
|
||||||
// if created or updated infra
|
},
|
||||||
if (data.keyword == "Infra") {
|
Directory_Buckets:()=>{
|
||||||
queryClient.removeQueries({queryKey:["ProjectInfra"]})
|
queryClient.invalidateQueries({queryKey:["bucketList"]})
|
||||||
// eventBus.emit("infra", data);
|
},
|
||||||
}
|
Directory:()=>{
|
||||||
if (data.keyword == "Task_Report") {
|
queryClient.invalidateQueries({queryKey:["contacts"]})
|
||||||
queryClient.removeQueries({queryKey:["Infra"]})
|
queryClient.invalidateQueries({queryKey:["Contact"]})
|
||||||
// eventBus.emit("infra", data);
|
queryClient.invalidateQueries({queryKey:["ContactProfile"]})
|
||||||
}
|
|
||||||
|
|
||||||
if ( data.keyword == "WorkItem" )
|
|
||||||
{
|
|
||||||
queryClient.removeQueries({queryKey:["WorkItems"]})
|
|
||||||
}
|
|
||||||
|
|
||||||
// if created or updated Employee
|
|
||||||
if (data.keyword == "Employee") {
|
|
||||||
// clearCacheKey("employeeListByProject");
|
|
||||||
// clearCacheKey("allEmployeeList");
|
|
||||||
// clearCacheKey("allInactiveEmployeeList");
|
|
||||||
// clearCacheKey("employeeProfile");
|
|
||||||
clearCacheKey("Attendance");
|
|
||||||
clearCacheKey("regularizedList")
|
|
||||||
clearCacheKey("AttendanceLogs")
|
|
||||||
|
|
||||||
// ---we can do also----
|
|
||||||
// queryClient.removeQueries(['allEmployee', true]);
|
|
||||||
// but best practies is refetch
|
|
||||||
queryClient.invalidateQueries(['allEmployee', true]);
|
|
||||||
queryClient.invalidateQueries(['allEmployee', false]);
|
|
||||||
queryClient.invalidateQueries(['employeeProfile', data.response?.employeeId]);
|
|
||||||
queryClient.invalidateQueries(['employeeListByProject']); // optional if scope
|
|
||||||
eventBus.emit("employee", data);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.keyword == "Task_Report") {
|
|
||||||
if(data.numberOfImages > 0){
|
|
||||||
eventBus.emit("image_gallery", data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data.keyword == "Task_Comment") {
|
|
||||||
if(data.numberOfImages > 0){
|
|
||||||
eventBus.emit("image_gallery", data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---- Keyword based event emitters ----
|
||||||
|
const emitters = {
|
||||||
|
employee: () => eventBus.emit("employee", data),
|
||||||
|
project: () => eventBus.emit("project", data),
|
||||||
|
infra: () => eventBus.emit("infra", data),
|
||||||
|
assign_project_all: () => eventBus.emit("assign_project_all", data),
|
||||||
|
image_gallery: () => eventBus.emit("image_gallery", data),
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---- Handle Attendance ----
|
||||||
|
if (keyword === "Attendance") {
|
||||||
|
const checkIn = response.checkInTime.substring(0, 10);
|
||||||
|
if (today === checkIn) eventBus.emit("attendance", data);
|
||||||
|
|
||||||
|
const onlyDate = Number(checkIn.substring(8, 10));
|
||||||
|
const afterTwoDay =
|
||||||
|
checkIn.substring(0, 8) + (onlyDate + 2).toString().padStart(2, "0");
|
||||||
|
|
||||||
|
if (
|
||||||
|
afterTwoDay <= today &&
|
||||||
|
(response.activity === 4 || response.activity === 5)
|
||||||
|
) {
|
||||||
|
eventBus.emit("regularization", data);
|
||||||
|
}
|
||||||
|
eventBus.emit("attendance_log", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Invalidate/Remove cache by keywords ----
|
||||||
|
if (queryInvalidators[keyword]) {
|
||||||
|
queryInvalidators[keyword]();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Project creation/update ----
|
||||||
|
if (keyword === "Create_Project" || keyword === "Update_Project") {
|
||||||
|
emitters.project();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Assign/deassign project ----
|
||||||
|
if (keyword === "Assign_Project") {
|
||||||
|
if (employeeList?.includes(loggedInId)) {
|
||||||
|
try {
|
||||||
|
cacheData("hasReceived", false);
|
||||||
|
eventBus.emit("assign_project_one", data);
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
emitters.assign_project_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Employee update ----
|
||||||
|
if (keyword === "Employee") {
|
||||||
|
clearCacheKey("Attendance");
|
||||||
|
clearCacheKey("regularizedList");
|
||||||
|
clearCacheKey("AttendanceLogs");
|
||||||
|
|
||||||
|
queryClient.invalidateQueries(["allEmployee", true]);
|
||||||
|
queryClient.invalidateQueries(["allEmployee", false]);
|
||||||
|
queryClient.invalidateQueries(["employeeProfile", response?.employeeId]);
|
||||||
|
queryClient.invalidateQueries(["employeeListByProject"]);
|
||||||
|
|
||||||
|
emitters.employee();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Image related events ----
|
||||||
|
if (["Task_Report", "Task_Comment"].includes(keyword) && numberOfImages > 0) {
|
||||||
|
emitters.image_gallery();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
connection
|
connection
|
||||||
.start();
|
.start();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user