added gobal create project,change paid by at expense create

This commit is contained in:
pramod.mahajan 2025-09-30 17:27:20 +05:30
parent d5df200ede
commit 4ddb8415cc
13 changed files with 204 additions and 212 deletions

View File

@ -3,15 +3,19 @@ import { useOrganizationModal } from "./hooks/useOrganization";
import OrganizationModal from "./components/Organization/OrganizationModal";
import { useAuthModal } from "./hooks/useAuth";
import SwitchTenant from "./pages/authentication/SwitchTenant";
import { useProjectModal } from "./hooks/useProjects";
import { ProjectModal } from "./components/Project/ManageProjectInfo";
const ModalProvider = () => {
const { isOpen, onClose } = useOrganizationModal();
const { isOpen: isAuthOpen } = useAuthModal();
const {isOpen:isOpenProject} = useProjectModal()
return (
<>
{isOpen && <OrganizationModal />}
{isAuthOpen && <SwitchTenant />}
{isOpenProject && <ProjectModal/>}
</>
);
};

View File

@ -19,8 +19,11 @@ const AssignedBucket = ({ selectedBucket, handleClose }) => {
}
}, [selectedBucket, employeesList]);
const { mutate: AssignEmployee, isPending } = useAssignEmpToBucket(() =>
const { mutate: AssignEmployee, isPending } = useAssignEmpToBucket(() =>{
setSelectedEmployees([])
handleClose()
}
);
const handleSubmit = async (e) => {

View File

@ -90,7 +90,7 @@ export const employeeSchema =
.min(1, { message: "Phone Number is required" })
.regex(mobileNumberRegex, { message: "Invalid phone number " }),
jobRoleId: z.string().min(1, { message: "Role is required" }),
organizationId:z.string().min(1,{message:"Organization is required"}),
// organizationId:z.string().min(1,{message:"Organization is required"}), // hide temp. for version 1
hasApplicationAccess:z.boolean().default(false),
}).refine((data) => {
if (data.hasApplicationAccess) {
@ -119,6 +119,6 @@ export const defatEmployeeObj = {
permanentAddress: "",
phoneNumber: "",
jobRoleId: null,
organizationId:"",
// organizationId:"",
hasApplicationAccess:false
}

View File

@ -15,18 +15,18 @@ import {
import Label from "../common/Label";
import DatePicker from "../common/DatePicker";
import { defatEmployeeObj, employeeSchema } from "./EmployeeSchema";
import { useOrganizationsList } from "../../hooks/useOrganization";
// import { useOrganizationsList } from "../../hooks/useOrganization";
import { ITEMS_PER_PAGE } from "../../utils/constants";
const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
const dispatch = useDispatch();
const { mutate: updateEmployee, isPending } = useUpdateEmployee();
const {
data: organzationList,
isLoading,
isError,
error: EempError,
} = useOrganizationsList(ITEMS_PER_PAGE, 1, true);
// const {
// data: organzationList,
// isLoading,
// isError,
// error: EempError,
// } = useOrganizationsList(ITEMS_PER_PAGE, 1, true);
const {
employee,
error,
@ -113,7 +113,7 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
permanentAddress: currentEmployee.permanentAddress || "",
phoneNumber: currentEmployee.phoneNumber || "",
jobRoleId: currentEmployee.jobRoleId?.toString() || "",
organizationId: currentEmployee.organizationId || "",
// organizationId: currentEmployee.organizationId || "", // Hide temp. for version 1
hasApplicationAccess: currentEmployee.hasApplicationAccess || false,
}
: {}
@ -413,9 +413,10 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
</div>
</div>
{/* -------------- */}
<div className="row mb-3">
<div className="col-sm-6">
{/* -------------- Temp hide for Version---------------*/}
{/* <div className="col-sm-6">
<Label className="form-text text-start" required>
Organization
</Label>
@ -446,9 +447,10 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
{errors.organizationId.message}
</div>
)}
</div>
</div> */}
{/* --------------------------------------------------- */}
<div className="col-sm-6 d-flex align-items-center mt-2">
<div className="col-12 d-flex align-items-center mt-2">
<label className="form-check-label d-flex align-items-center">
<input
type="checkbox"
@ -584,15 +586,14 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
)}
</div>
</div>
<div className="row text-end">
<div className="col-sm-12">
<div className="d-flex flex-row gap-3 justify-content-end">
<button
aria-label="manage employee"
type="reset"
className="btn btn-sm btn-label-secondary me-2"
disabled={isPending}
onClick={()=>onClosed()}
>
Clear
Close
</button>
<button
aria-label="manage employee"
@ -600,9 +601,8 @@ const ManageEmployee = ({ employeeId, onClosed, IsAllEmployee }) => {
className="btn btn-sm btn-primary"
disabled={isPending}
>
{isPending ? "Please Wait..." : employeeId ? "Update" : "Create"}
{isPending ? "Please Wait..." : employeeId ? "Update" : "Submit"}
</button>
</div>
</div>
</form>
</>

View File

@ -28,6 +28,7 @@ import moment from "moment";
import DatePicker from "../common/DatePicker";
import ErrorPage from "../../pages/ErrorPage";
import Label from "../common/Label";
import EmployeeSearchInput from "../common/EmployeeSearchInput";
const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
const {
@ -57,7 +58,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
});
const selectedproject = watch("projectId");
const {
projectNames,
loading: projectLoading,
@ -142,8 +143,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
};
useEffect(() => {
if (expenseToEdit && data ) {
if (expenseToEdit && data) {
reset({
projectId: data.project.id || "",
expensesTypeId: data.expensesType.id || "",
@ -156,7 +156,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
supplerName: data.supplerName || "",
amount: data.amount || "",
noOfPersons: data.noOfPersons || "",
gstNumber:data.gstNumber || "",
gstNumber: data.gstNumber || "",
billAttachments: data.documents
? data.documents.map((doc) => ({
fileName: doc.fileName,
@ -183,8 +183,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
const onSubmit = (fromdata) => {
let payload = {
...fromdata,
transactionDate: localToUtc(fromdata.transactionDate)
transactionDate: localToUtc(fromdata.transactionDate),
};
if (expenseToEdit) {
const editPayload = { ...payload, id: data.id };
@ -206,7 +205,6 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
if (StatusLoadding || projectLoading || ExpenseLoading || isLoading)
return <ExpenseSkeleton />;
return (
<div className="container p-3">
<h5 className="m-0">
@ -215,7 +213,9 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
<form id="expenseForm" onSubmit={handleSubmit(onSubmit)}>
<div className="row my-2 text-start">
<div className="col-md-6">
<Label className="form-label" required>Select Project</Label>
<Label className="form-label" required>
Select Project
</Label>
<select
className="form-select form-select-sm"
{...register("projectId")}
@ -296,7 +296,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
)}
</div>
<div className="col-md-6">
{/* <div className="col-md-6">
<Label htmlFor="paidById" className="form-label" required>
Paid By
</Label>
@ -322,6 +322,15 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
{errors.paidById && (
<small className="danger-text">{errors.paidById.message}</small>
)}
</div> */}
<div className="col-12 col-md-6 text-start">
<label className="form-label">Paid By </label>
<EmployeeSearchInput
control={control}
name="paidById"
projectId={null}
/>
</div>
</div>
@ -330,7 +339,11 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
<Label htmlFor="transactionDate" className="form-label" required>
Transaction Date
</Label>
<DatePicker name="transactionDate" control={control} maxDate={new Date()}/>
<DatePicker
name="transactionDate"
control={control}
maxDate={new Date()}
/>
{errors.transactionDate && (
<small className="danger-text">
@ -409,9 +422,9 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
</small>
)}
</div>
<div className="col-md-6">
<div className="col-md-6">
<label htmlFor="statusId" className="form-label ">
GST Number
GST Number
</label>
<input
type="text"
@ -421,9 +434,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
{...register("gstNumber")}
/>
{errors.gstNumber && (
<small className="danger-text">
{errors.gstNumber.message}
</small>
<small className="danger-text">{errors.gstNumber.message}</small>
)}
</div>
@ -448,7 +459,9 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
<div className="row my-2 text-start">
<div className="col-md-12">
<Label htmlFor="description" className="form-label" required>Description</Label>
<Label htmlFor="description" className="form-label" required>
Description
</Label>
<textarea
id="description"
className="form-control form-control-sm"
@ -465,7 +478,9 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
<div className="row my-2 text-start">
<div className="col-md-12">
<Label className="form-label" required>Upload Bill </Label>
<Label className="form-label" required>
Upload Bill{" "}
</Label>
<div
className="border border-secondary border-dashed rounded p-4 text-center bg-textMuted position-relative"
@ -549,7 +564,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
<div className="d-flex justify-content-end gap-3">
{" "}
<button
<button
type="reset"
disabled={isPending || createPending}
onClick={handleClose}
@ -568,7 +583,6 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => {
? "Update"
: "Submit"}
</button>
</div>
</form>
</div>

View File

@ -13,7 +13,7 @@ import { useProfile } from "../../hooks/useProfile";
import { useLocation, useNavigate, useParams } from "react-router-dom";
import Avatar from "../../components/common/Avatar";
import { useChangePassword } from "../Context/ChangePasswordContext";
import { useProjects } from "../../hooks/useProjects";
import { useProjectModal, useProjects } from "../../hooks/useProjects";
import { useCallback, useEffect, useState } from "react";
import { useProjectName } from "../../hooks/useProjects";
import eventBus from "../../services/eventBus";
@ -27,9 +27,10 @@ const Header = () => {
const dispatch = useDispatch();
const { data, loading } = useMaster();
const navigate = useNavigate();
const {onOpen} = useAuthModal()
const { onOpen } = useAuthModal();
const HasManageProjectPermission = useHasUserPermission(MANAGE_PROJECT);
const { mutate : logout,isPending:logouting} = useLogout()
const { mutate: logout, isPending: logouting } = useLogout();
const { openModal } = useProjectModal();
const isDashboardPath =
/^\/dashboard$/.test(location.pathname) || /^\/$/.test(location.pathname);
@ -59,10 +60,6 @@ const Header = () => {
return role ? role.name : "User";
};
const handleProfilePage = () => {
navigate(`/employee/${profile?.employeeInfo?.id}`);
};
@ -249,111 +246,15 @@ const Header = () => {
)}
<ul className="navbar-nav flex-row align-items-center ms-md-auto">
<li className="nav-item dropdown-shortcuts navbar-dropdown dropdown me-2 me-xl-0">
<a
className="nav-link dropdown-toggle hide-arrow"
data-bs-toggle="dropdown"
data-bs-auto-close="true"
aria-expanded="false"
<li className="nav-item navbar-dropdown dropdown-user dropdown">
<button
className="btn btn-sm btn-primary"
type="button"
onClick={()=>openModal(null)}
>
<i className="icon-base bx bx-grid-alt icon-md"></i>
</a>
<div className="dropdown-menu dropdown-menu-end p-0">
<div className="dropdown-menu-header border-bottom">
<div className="dropdown-header d-flex align-items-center py-3">
<h6 className="mb-0 me-auto">Shortcuts</h6>
<a
className="dropdown-shortcuts-add py-2 cusror-pointer"
data-bs-toggle="tooltip"
data-bs-placement="top"
aria-label="Add shortcuts"
data-bs-original-title="Add shortcuts"
>
<i className="icon-base bx bx-plus-circle text-heading"></i>
</a>
</div>
</div>
<div className="dropdown-shortcuts-list scrollable-container ps">
<div className="row row-bordered overflow-visible g-0">
<div className="dropdown-shortcuts-item col">
<a
onClick={() => navigate(`/dashboard`)}
className="text-heading text-truncate cursor-pointer"
>
<span className="dropdown-shortcuts-icon rounded-circle mb-3">
<i className="icon-base bx bx-home icon-26px text-heading"></i>
</span>
Dashboard
</a>
<small>User Dashboard</small>
</div>
<div className="dropdown-shortcuts-item col">
<a
onClick={() => navigate(`/projects`)}
className="text-heading text-truncate cursor-pointer"
>
<span className="dropdown-shortcuts-icon rounded-circle mb-3">
<i className="icon-base bx bx-building-house icon-26px text-heading"></i>
</span>
Projects
</a>
<small>Projects List</small>
</div>
</div>
<div className="row row-bordered overflow-visible g-0">
<div className="dropdown-shortcuts-item col">
<a
onClick={() => navigate(`/employees`)}
className="text-heading text-truncate cursor-pointer"
>
<span className="dropdown-shortcuts-icon rounded-circle mb-3">
<i className="icon-base bx bxs-user-account icon-26px text-heading"></i>
</span>
Employees
</a>
<small>Manage Employees</small>
</div>
<div className="dropdown-shortcuts-item col">
<a
onClick={() => navigate(`/activities/attendance`)}
className="text-heading text-truncate cursor-pointer"
>
<span className="dropdown-shortcuts-icon rounded-circle mb-3">
<i className="icon-base bx bx-user-check icon-26px text-heading"></i>
</span>
Attendance
</a>
<small>Manage Attendance</small>
</div>
</div>
<div className="row row-bordered overflow-visible g-0">
<div className="dropdown-shortcuts-item col">
<a
onClick={() => navigate(`/activities/task`)}
className="text-heading text-truncate cursor-pointer"
>
<span className="dropdown-shortcuts-icon rounded-circle mb-3">
<i className="icon-base bx bxs-wrench icon-26px text-heading"></i>
</span>
Allocate Work
</a>
<small>Work Allocations</small>
</div>
<div className="dropdown-shortcuts-item col">
<a
onClick={() => navigate(`/activities/records`)}
className="text-heading text-truncate cursor-pointer"
>
<span className="dropdown-shortcuts-icon rounded-circle mb-3">
<i className="icon-base bx bx-list-ul icon-26px text-heading"></i>
</span>
Daily Work Log
</a>
<small>Daily Work Allocations</small>
</div>
</div>
</div>
</div>
<i className="bx bx-plus-circle me-2"></i>
<span className="d-none d-md-inline-block">Add New Project</span>
</button>
</li>
<li className="nav-item navbar-dropdown dropdown-user dropdown">
<a
@ -395,11 +296,9 @@ const Header = () => {
<li>
<div className="dropdown-divider"></div>
</li>
<li onClick={()=>onOpen()}>
<li onClick={() => onOpen()}>
{" "}
<a
className="dropdown-item cusor-pointer"
>
<a className="dropdown-item cusor-pointer">
<i className="bx bx-transfer-alt me-2"></i>
<span className="align-middle">Switch Workspace</span>
</a>
@ -433,7 +332,6 @@ const Header = () => {
</a>
</li>
<li>
<div className="dropdown-divider"></div>
</li>
@ -441,10 +339,17 @@ const Header = () => {
<a
aria-label="click to log out"
className="dropdown-item cusor-pointer"
onClick={()=>logout()}
onClick={() => logout()}
>
{logouting ? "Please Wait":<> <i className="bx bx-log-out me-2"></i>
<span className="align-middle">SignOut</span></>}
{logouting ? (
"Please Wait"
) : (
<>
{" "}
<i className="bx bx-log-out me-2"></i>
<span className="align-middle">SignOut</span>
</>
)}
</a>
</li>
</ul>
@ -454,4 +359,4 @@ const Header = () => {
</nav>
);
};
export default Header;
export default Header;

View File

@ -5,7 +5,12 @@ import { zodResolver } from "@hookform/resolvers/zod";
import Label from "../common/Label";
import DatePicker from "../common/DatePicker";
import { useCreateProject, useProjectDetails, useUpdateProject } from "../../hooks/useProjects";
import {
useCreateProject,
useProjectDetails,
useProjectModal,
useUpdateProject,
} from "../../hooks/useProjects";
import {
DEFAULT_EMPTY_STATUS_ID,
@ -17,6 +22,7 @@ import {
useOrganizationsList,
} from "../../hooks/useOrganization";
import { localToUtc } from "../../utils/appUtils";
import Modal from "../common/Modal";
const currentDate = new Date().toLocaleDateString("en-CA");
const formatDate = (date) => {
@ -37,13 +43,19 @@ const ManageProjectInfo = ({ project, onClose }) => {
const ACTIVE_STATUS_ID = "b74da4c2-d07e-46f2-9919-e75e49b12731";
const { projects_Details, loading } = useProjectDetails(project);
const { data, isLoading, isError, error } = useOrganizationsList(
ITEMS_PER_PAGE,
1,
true
// const { data, isLoading, isError, error } = useOrganizationsList(
// ITEMS_PER_PAGE,
// 1,
// true
// );
const { mutate: UpdateProject, isPending } = useUpdateProject(() => {
onClose?.();
});
const { mutate: CeateProject, isPending: isCreating } = useCreateProject(
() => {
onClose?.();
}
);
const { mutate: UpdateProject, isPending } = useUpdateProject(() => {onClose?.()});
const {mutate:CeateProject,isPending:isCreating} = useCreateProject(()=>{onClose?.()})
const {
register,
@ -70,11 +82,11 @@ const ManageProjectInfo = ({ project, onClose }) => {
projectStatusId:
String(projects_Details?.projectStatus?.id) ||
DEFAULT_EMPTY_STATUS_IDF,
promoterId: projects_Details?.promoter?.id || "",
pmcId: projects_Details?.pmc?.id || "",
// promoterId: projects_Details?.promoter?.id || "", // hide temp. for version 1
// pmcId: projects_Details?.pmc?.id || "",
});
setAddressLength(projects_Details?.projectAddress?.length || 0);
}, [project, projects_Details, reset,data]);
}, [project, projects_Details, reset]);
const onSubmitForm = (formData) => {
if (project) {
@ -85,13 +97,13 @@ const ManageProjectInfo = ({ project, onClose }) => {
id: project,
};
UpdateProject({ projectId: project, payload: payload });
}else{
let payload = {
} else {
let payload = {
...formData,
startDate: localToUtc(formData.startDate),
endDate: localToUtc(formData.endDate),
};
CeateProject(payload)
CeateProject(payload);
}
};
@ -104,7 +116,6 @@ const ManageProjectInfo = ({ project, onClose }) => {
onOpen({ startStep: 2, flowType: "default" });
};
return (
<div className="p-sm-2 p-2">
<div className="text-center mb-2">
@ -254,7 +265,7 @@ const ManageProjectInfo = ({ project, onClose }) => {
</div>
)}
</div>
<div className="col-12 ">
{/* <div className="col-12 ">
<label className="form-label" htmlFor="modalEditUserStatus">
Promoter
</label>
@ -330,7 +341,7 @@ const ManageProjectInfo = ({ project, onClose }) => {
<small className="cursor-pointer" onClick={handleOrganizaioFinder}>
<i className="bx bx-plus-circle text-primary"></i>
</small>
</div>
</div> */}
<div className="col-12 col-md-12">
<Label htmlFor="projectAddress" required>
@ -376,7 +387,11 @@ const ManageProjectInfo = ({ project, onClose }) => {
className="btn btn-primary btn-sm"
disabled={isPending || isCreating}
>
{isPending||isCreating ? "Please Wait..." : project ? "Update" : "Submit"}
{isPending || isCreating
? "Please Wait..."
: project
? "Update"
: "Submit"}
</button>
</div>
</form>
@ -385,3 +400,15 @@ const ManageProjectInfo = ({ project, onClose }) => {
};
export default ManageProjectInfo;
export const ProjectModal = () => {
const { isOpen, data, closeModal } = useProjectModal();
return (
<Modal
isOpen={isOpen}
body={<ManageProjectInfo project={data} onClose={closeModal} />}
onClose={closeModal}
/>
);
};

View File

@ -11,8 +11,8 @@ export const projectDefault = {
startDate: currentDate.toISOString().split("T")[0],
endDate: currentDate.toISOString().split("T")[0],
projectStatusId: DEFAULT_EMPTY_STATUS_ID,
promoterId: "",
pmcId: "",
// promoterId: "",
// pmcId: "",
};
@ -39,8 +39,8 @@ export const projectSchema = z
.min(1, { message: "End Date is required" })
.default(projectDefault),
projectStatusId: z.string().min(1, { message: "Status is required" }),
promoterId: z.string().min(1, { message: "Promoter is required" }),
pmcId: z.string().min(1, { message: "PMC is required" }),
// promoterId: z.string().min(1, { message: "Promoter is required" }),
// pmcId: z.string().min(1, { message: "PMC is required" }),
})
.refine(
(data) => {

View File

@ -29,7 +29,6 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
error,
isPending,
} = useCreateTenant(() => {
debugger
onNext()
});
@ -134,7 +133,6 @@ const OrganizationInfo = ({ onNext, onPrev, onSubmitTenant }) => {
control={control}
placeholder="DD-MM-YYYY"
maxDate={new Date()}
className={errors.onBoardingDate ? "is-invalid" : ""}
/>
{errors.onBoardingDate && (
<div className="invalid-feedback">

View File

@ -1,13 +1,11 @@
import { useState, useEffect } from "react";
import { useState, useEffect, useRef } from "react";
import { useEmployeesName } from "../../hooks/useEmployees";
import { useDebounce } from "../../utils/appUtils";
import { useController } from "react-hook-form";
import Avatar from "./Avatar";
const EmployeeSearchInput = ({ control, name, projectId,placeholder }) => {
const EmployeeSearchInput = ({ control, name, projectId, placeholder }) => {
const {
field: { onChange, value, ref },
fieldState: { error },
@ -17,6 +15,8 @@ const EmployeeSearchInput = ({ control, name, projectId,placeholder }) => {
const [showDropdown, setShowDropdown] = useState(false);
const debouncedSearch = useDebounce(search, 500);
const wrapperRef = useRef(null);
const {
data: employees,
isLoading,
@ -29,6 +29,19 @@ const EmployeeSearchInput = ({ control, name, projectId,placeholder }) => {
}
}, [value, employees]);
useEffect(() => {
const handleClickOutside = (e) => {
if (wrapperRef.current && !wrapperRef.current.contains(e.target)) {
setShowDropdown(false);
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, []);
const handleSelect = (employee) => {
onChange(employee.id);
setSearch(employee.firstName + " " + employee.lastName);
@ -36,17 +49,17 @@ const EmployeeSearchInput = ({ control, name, projectId,placeholder }) => {
};
return (
<div className="position-relative">
<div className="position-relative" ref={wrapperRef}>
<input
type="text"
ref={ref}
className={`form-control form-control-sm`}
className="form-control form-control-sm"
placeholder={placeholder}
value={search}
onChange={(e) => {
setSearch(e.target.value);
setShowDropdown(true);
onChange("");
onChange("");
}}
onFocus={() => {
if (search) setShowDropdown(true);
@ -55,34 +68,33 @@ const EmployeeSearchInput = ({ control, name, projectId,placeholder }) => {
{showDropdown && (employees?.data?.length > 0 || isLoading) && (
<ul
className="list-group position-absolute bg-white w-100 shadow z-3 rounded-none px-0"
className="list-group position-absolute bg-white w-100 shadow z-3 px-0"
style={{ maxHeight: 200, overflowY: "auto" }}
>
{isLoading ? (
<li className="list-group-item">
<a>Searching...</a>
</li>
) : (
employees?.data?.map((emp) => (
<li
key={emp.id}
className="list-group-item list-group-item-action py-1 px-1"
style={{ cursor: "pointer" }}
onClick={() => handleSelect(emp)}
>
<div className="d-flex align-items-center px-0">
<Avatar
size="xs"
classAvatar="m-0 me-2"
firstName={emp.firstName}
lastName={emp.lastName}
/>
<span className="text-muted">
{`${emp?.firstName} ${emp?.lastName}`.trim()}
</span>
</div>
</li>
<li
key={emp.id}
className="list-group-item list-group-item-action py-1 px-1"
style={{ cursor: "pointer" }}
onClick={() => handleSelect(emp)}
>
<div className="d-flex align-items-center px-0">
<Avatar
size="xs"
classAvatar="m-0 me-2"
firstName={emp.firstName}
lastName={emp.lastName}
/>
<span className="text-muted">
{`${emp?.firstName} ${emp?.lastName}`.trim()}
</span>
</div>
</li>
))
)}
</ul>
@ -94,3 +106,4 @@ const EmployeeSearchInput = ({ control, name, projectId,placeholder }) => {
};
export default EmployeeSearchInput;

View File

@ -415,7 +415,7 @@ export const useUpdateBucket = (onSuccessCallBack) => {
});
};
export const useAssignEmpToBucket = () => {
export const useAssignEmpToBucket = (onSuccessCallBack) => {
return useMutation({
mutationFn: async ({ bucketId, EmployeePayload }) =>
await DirectoryRepository.AssignedBuckets(bucketId, EmployeePayload),

View File

@ -3,7 +3,7 @@ import { cacheData, getCachedData } from "../slices/apiDataManager";
import ProjectRepository from "../repositories/ProjectRepository";
import { useProfile } from "./useProfile";
import { useDispatch, useSelector } from "react-redux";
import { setProjectId } from "../slices/localVariablesSlice";
import { closeProjectModal, openProjectModal, setProjectId } from "../slices/localVariablesSlice";
import EmployeeList from "../components/Directory/EmployeeList";
import eventBus from "../services/eventBus";
import {
@ -18,6 +18,18 @@ export const useCurrentService = () => {
return useSelector((store) => store.globalVariables.selectedServiceId);
};
export const useProjectModal = () => {
const dispatch = useDispatch();
const { isOpen, data } = useSelector((state) => state.localVariables.ProjectModal);
return {
isOpen,
data,
openModal: (payload = null) => dispatch(openProjectModal(payload)),
closeModal: () => dispatch(closeProjectModal()),
};
};
// ------------------------------Query-------------------
export const useProjects = () => {

View File

@ -19,6 +19,10 @@ const localVariablesSlice = createSlice({
startStep: 1,
flowType: "default",
},
ProjectModal:{
isOpen: false,
data: null,
},
AuthModal: {
isOpen: false,
@ -70,6 +74,17 @@ const localVariablesSlice = createSlice({
closeAuthModal: (state, action) => {
state.AuthModal.isOpen = false;
},
// project modal
openProjectModal: (state, action) => {
state.ProjectModal.isOpen = true;
state.ProjectModal.data = action.payload || null;
},
closeProjectModal: (state) => {
state.ProjectModal.isOpen = false;
state.ProjectModal.data = null;
},
},
});
@ -84,5 +99,6 @@ export const {
toggleOrgModal,
openAuthModal,
closeAuthModal,
openProjectModal, closeProjectModal
} = localVariablesSlice.actions;
export default localVariablesSlice.reducer;