addd serach poject field both projects

This commit is contained in:
pramod.mahajan 2025-11-19 10:42:12 +05:30
parent ed87e3f11b
commit 3fe533c8e3
5 changed files with 155 additions and 86 deletions

View File

@ -1,56 +0,0 @@
import React from 'react'
const InputFieldSuggesstion = () => {
return (
<div className="position-relative">
<input
className="form-control form-control-sm"
value={value}
onChange={handleInputChange}
onBlur={() => setTimeout(() => setShowSuggestions(false), 150)}
onFocus={() => {
if (value) setShowSuggestions(true);
}}
disabled={disabled}
/>
{showSuggestions && filteredList.length > 0 && (
<ul
className="list-group shadow-sm position-absolute w-100 bg-white border zindex-tooltip"
style={{
maxHeight: "180px",
overflowY: "auto",
marginTop: "2px",
zIndex: 1000,
borderRadius:"0px"
}}
>
{filteredList.map((org) => (
<li
key={org}
className="list-group-item list-group-item-action border-none "
style={{
cursor: "pointer",
padding: "5px 12px",
fontSize: "14px",
transition: "background-color 0.2s",
}}
onMouseDown={() => handleSelectSuggestion(org)}
onMouseEnter={(e) =>
(e.currentTarget.style.backgroundColor = "#f8f9fa")
}
onMouseLeave={(e) =>
(e.currentTarget.style.backgroundColor = "transparent")
}
>
{org}
</li>
))}
</ul>
)}
{error && <small className="danger-text">{error}</small>}
</div>
)
}
export default InputFieldSuggesstion

View File

@ -0,0 +1,90 @@
import React, { useEffect, useRef, useState } from "react";
import Label from "../Label";
const InputSuggessionField = ({
organizationList = [],
value,
onChange,
error,
disabled=false
}) => {
const [open, setOpen] = useState(false);
const dropdownRef = useRef(null);
useEffect(() => {
const handleClickOutside = (event) => {
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
setOpen(false);
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => document.removeEventListener("mousedown", handleClickOutside);
}, []);
const selectedOption = options.find((opt) => opt[valueKey] === value);
const displayText = selectedOption ? selectedOption[labelKey] : placeholder;
const handleSelect = (option) => {
onChange(option[valueKey]);
setOpen(false);
};
const toggleDropdown = () => setOpen((prev) => !prev);
return (
<div className="mb-3 position-relative" ref={dropdownRef}>
{label && (
<Label className="form-label" required={required}>
{label}
</Label>
)}
<button
type="button"
className={`select2-icons form-select d-flex align-items-center justify-content-between ${
open ? "show" : ""
}`}
onClick={toggleDropdown}
disabled={isLoading}
>
<span
className={`text-truncate ${!selectedOption ? "text-muted" : ""}`}
>
{isLoading ? "Loading..." : displayText}
</span>
</button>
{open && !isLoading && (
<ul
className="dropdown-menu w-100 shadow-sm show animate__fadeIn"
style={{
position: "absolute",
top: "100%",
left: 0,
zIndex: 1050,
marginTop: "4px",
borderRadius: "0.375rem",
overflow: "hidden",
}}
>
{options.map((option, i) => (
<li key={i}>
<button
type="button"
className={`dropdown-item ${
option[valueKey] === value ? "active" : ""
}`}
onClick={() => handleSelect(option)}
>
{option[labelKey]}
</button>
</li>
))}
</ul>
)}
</div>
);
};
export default InputSuggessionField;

View File

@ -2,6 +2,7 @@ import React, { useEffect, useRef, useState } from "react";
import Label from "../Label"; import Label from "../Label";
import { useDebounce } from "../../../utils/appUtils"; import { useDebounce } from "../../../utils/appUtils";
import { useEmployeesName } from "../../../hooks/useEmployees"; import { useEmployeesName } from "../../../hooks/useEmployees";
import { useProjectBothName } from "../../../hooks/useProjects";
const SelectEmployeeServerSide = ({ const SelectEmployeeServerSide = ({
label = "Select", label = "Select",
@ -154,7 +155,9 @@ const SelectEmployeeServerSide = ({
)} )}
{!isLoading && options.length === 0 && ( {!isLoading && options.length === 0 && (
<li className="dropdown-item text-muted text-center">No results found</li> <li className="dropdown-item text-muted text-center">
No results found
</li>
)} )}
{!isLoading && {!isLoading &&
@ -183,24 +186,29 @@ const SelectEmployeeServerSide = ({
}; };
export default SelectEmployeeServerSide; export default SelectEmployeeServerSide;
export const SelectProjectField = ({
export const SelectProjectField = ()=>{ label = "Select",
placeholder = "Select Project",
required = false,
value = null,
onChange,
valueKey = "id",
isFullObject = false,
isMultiple = false,
isAllProject = false,
}) => {
const [searchText, setSearchText] = useState(""); const [searchText, setSearchText] = useState("");
const debounce = useDebounce(searchText, 300); const debounce = useDebounce(searchText, 300);
const { data, isLoading } = useEmployeesName( const { data, isLoading } = useProjectBothName(debounce);
projectId,
debounce,
isAllEmployee
);
const options = data?.data ?? []; const options = data ?? [];
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const dropdownRef = useRef(null); const dropdownRef = useRef(null);
const getDisplayName = (emp) => { const getDisplayName = (project) => {
if (!emp) return ""; if (!project) return "";
return `${emp.firstName || ""} ${emp.lastName || ""}`.trim(); return `${project.name || ""}`.trim();
}; };
/** ----------------------------- /** -----------------------------
@ -304,7 +312,7 @@ export const SelectProjectField = ()=>{
top: "100%", top: "100%",
left: 0, left: 0,
zIndex: 1050, zIndex: 1050,
marginTop: "4px", marginTop: "2px",
borderRadius: "0.375rem", borderRadius: "0.375rem",
overflow: "hidden", overflow: "hidden",
}} }}
@ -324,7 +332,9 @@ export const SelectProjectField = ()=>{
)} )}
{!isLoading && options.length === 0 && ( {!isLoading && options.length === 0 && (
<li className="dropdown-item text-muted text-center">No results found</li> <li className="dropdown-item text-muted text-center">
No results found
</li>
)} )}
{!isLoading && {!isLoading &&

View File

@ -25,7 +25,10 @@ export const useProjects = (pageSize,pageNumber) => {
return useQuery({ return useQuery({
queryKey: ["ProjectsList", pageSize, pageNumber], queryKey: ["ProjectsList", pageSize, pageNumber],
queryFn: async () => { queryFn: async () => {
const response = await ProjectRepository.getProjectList(pageSize,pageNumber); const response = await ProjectRepository.getProjectList(
pageSize,
pageNumber
);
return response?.data; return response?.data;
}, },
enabled: !!loggedUser, enabled: !!loggedUser,
@ -179,6 +182,19 @@ export const useProjectName = (provideAll=false) => {
}; };
}; };
export const useProjectBothName = (searchString) => {
return useQuery({
queryKey: ["basic_bothProject", searchString],
queryFn: async () => {
const res = await ProjectRepository.projectNameListAll(searchString);
return res.data || res;
},
onError: (error) => {
showToast(error.message || "Error while Fetching project Name", "error");
},
});
};
export const useProjectInfra = (projectId, serviceId) => { export const useProjectInfra = (projectId, serviceId) => {
const { const {
data: projectInfra, data: projectInfra,

View File

@ -1,17 +1,24 @@
import { api } from "../utils/axiosClient"; import { api } from "../utils/axiosClient";
const ProjectRepository = { const ProjectRepository = {
getProjectList: (pageSize,pageNumber) => api.get(`/api/project/list?pageSize=${pageSize}&pageNumber=${pageNumber}`), getProjectList: (pageSize, pageNumber) =>
api.get(`/api/project/list?pageSize=${pageSize}&pageNumber=${pageNumber}`),
getProjectByprojectId: (projetid) => getProjectByprojectId: (projetid) =>
api.get(`/api/project/details/${projetid}`), api.get(`/api/project/details/${projetid}`),
getProjectAllocation: (projectId, serviceId, organizationId, employeeStatus) => { getProjectAllocation: (
projectId,
serviceId,
organizationId,
employeeStatus
) => {
let url = `/api/project/allocation/${projectId}`; let url = `/api/project/allocation/${projectId}`;
const params = []; const params = [];
if (organizationId) params.push(`organizationId=${organizationId}`); if (organizationId) params.push(`organizationId=${organizationId}`);
if (serviceId) params.push(`serviceId=${serviceId}`); if (serviceId) params.push(`serviceId=${serviceId}`);
if (employeeStatus !== undefined) params.push(`includeInactive=${employeeStatus}`); if (employeeStatus !== undefined)
params.push(`includeInactive=${employeeStatus}`);
if (params.length > 0) { if (params.length > 0) {
url += `?${params.join("&")}`; url += `?${params.join("&")}`;
@ -20,7 +27,6 @@ const ProjectRepository = {
return api.get(url); return api.get(url);
}, },
getEmployeesByProject: (projectId) => getEmployeesByProject: (projectId) =>
api.get(`/api/Project/employees/get/${projectId}`), api.get(`/api/Project/employees/get/${projectId}`),
@ -40,7 +46,10 @@ const ProjectRepository = {
api.get(`/api/project/allocation-histery/${id}`), api.get(`/api/project/allocation-histery/${id}`),
updateProjectsByEmployee: (id, data) => updateProjectsByEmployee: (id, data) =>
api.post(`/api/project/assign-projects/${id}`, data), api.post(`/api/project/assign-projects/${id}`, data),
projectNameList: (provideAll) => api.get(`/api/project/list/basic?provideAll=${provideAll}`), projectNameList: (provideAll) =>
api.get(`/api/project/list/basic?provideAll=${provideAll}`),
projectNameListAll: (searchString) =>
api.get(`/api/project/list/basic/all?searchString=${searchString}`),
getProjectDetails: (id) => api.get(`/api/project/details/${id}`), getProjectDetails: (id) => api.get(`/api/project/details/${id}`),