updated PmsEmployeeInputTag for getting all exiten employee for update

This commit is contained in:
pramod.mahajan 2025-11-17 12:44:56 +05:30
parent b68f8306fd
commit 937531afb6

View File

@ -1,7 +1,7 @@
import { useState, useEffect, useRef, useMemo } from "react"; import { useState, useEffect, useRef, useMemo } from "react";
import { useController } from "react-hook-form"; import { useController } from "react-hook-form";
import { useDebounce } from "../../utils/appUtils"; import { useDebounce } from "../../utils/appUtils";
import { useEmployeesName } from "../../hooks/useEmployees"; import { useEmployeesName, useUserCache } from "../../hooks/useEmployees";
import Avatar from "./Avatar"; import Avatar from "./Avatar";
const PmsEmployeeInputTag = ({ const PmsEmployeeInputTag = ({
@ -11,16 +11,17 @@ const PmsEmployeeInputTag = ({
projectId, projectId,
forAll, forAll,
isApplicationUser = false, isApplicationUser = false,
disabled disabled,
}) => { }) => {
const { const {
field: { value = [], onChange }, field: { value = [], onChange },
} = useController({ name, control }); } = useController({ name, control });
const { getUser, addToCache, userCache } = useUserCache();
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
const [showDropdown, setShowDropdown] = useState(false); const [showDropdown, setShowDropdown] = useState(false);
const [filteredUsers, setFilteredUsers] = useState([]); const [filteredUsers, setFilteredUsers] = useState([]);
const [userCache, setUserCache] = useState({});
const dropdownRef = useRef(null); const dropdownRef = useRef(null);
const inputRef = useRef(null); const inputRef = useRef(null);
const activeIndexRef = useRef(-1); const activeIndexRef = useRef(-1);
@ -32,26 +33,28 @@ const PmsEmployeeInputTag = ({
forAll forAll
); );
// Keep both filtered list and cache updated
useEffect(() => { useEffect(() => {
if (employees?.data?.length) { if (employees?.data?.length) {
setFilteredUsers(employees.data); setFilteredUsers(employees.data);
activeIndexRef.current = -1; activeIndexRef.current = -1;
// cache all fetched users by id employees.data.forEach((u) => addToCache(u.id, u));
setUserCache((prev) => {
const updated = { ...prev };
employees.data.forEach((u) => {
updated[u.id] = u;
});
return updated;
});
} else { } else {
setFilteredUsers([]); setFilteredUsers([]);
} }
}, [employees]); }, [employees]);
// close dropdown when clicking outside // load selected employees not in filtered list
useEffect(() => {
if (!Array.isArray(value) || value.length === 0) return;
value.forEach(async (id) => {
if (!userCache[id]) {
await getUser(id); // fetch and cache
}
});
}, [value]);
useEffect(() => { useEffect(() => {
const onDocClick = (e) => { const onDocClick = (e) => {
if ( if (
@ -66,7 +69,6 @@ const PmsEmployeeInputTag = ({
return () => document.removeEventListener("mousedown", onDocClick); return () => document.removeEventListener("mousedown", onDocClick);
}, []); }, []);
// select a user
const handleSelect = (user) => { const handleSelect = (user) => {
if (value.includes(user.id)) return; if (value.includes(user.id)) return;
const updated = [...value, user.id]; const updated = [...value, user.id];
@ -76,13 +78,11 @@ const PmsEmployeeInputTag = ({
setTimeout(() => inputRef.current?.focus(), 0); setTimeout(() => inputRef.current?.focus(), 0);
}; };
// remove selected user
const handleRemove = (id) => { const handleRemove = (id) => {
const updated = value.filter((uid) => uid !== id); const updated = value.filter((uid) => uid !== id);
onChange(updated); onChange(updated);
}; };
// keyboard navigation
const onInputKeyDown = (e) => { const onInputKeyDown = (e) => {
if (!showDropdown) return; if (!showDropdown) return;
const max = Math.max(0, filteredUsers.length - 1); const max = Math.max(0, filteredUsers.length - 1);
@ -103,7 +103,6 @@ const PmsEmployeeInputTag = ({
} }
}; };
// scroll active dropdown item into view
const scrollToActive = () => { const scrollToActive = () => {
const wrapper = dropdownRef.current?.querySelector( const wrapper = dropdownRef.current?.querySelector(
".tagify__dropdown__wrapper" ".tagify__dropdown__wrapper"
@ -120,24 +119,21 @@ const PmsEmployeeInputTag = ({
} }
}; };
// resolve user details by ID (for rendering tags) // FIX: allow null (not found yet)
const resolveUserById = (id) => { const resolveUserById = (id) => {
return userCache[id] || filteredUsers.find((u) => u.id === id); return userCache[id] || filteredUsers.find((u) => u.id === id) || null;
}; };
// main visible users list (memoized)
const visibleUsers = useMemo(() => { const visibleUsers = useMemo(() => {
const baseList = isApplicationUser const baseList = isApplicationUser
? (filteredUsers || []).filter((u) => u?.email) ? (filteredUsers || []).filter((u) => u?.email)
: filteredUsers || []; : filteredUsers || [];
// also include selected users even if missing from current API
const selectedUsers = const selectedUsers =
Array.isArray(value) && value.length Array.isArray(value) && value.length
? value.map((uid) => userCache[uid]).filter(Boolean) ? value.map((uid) => userCache[uid]).filter(Boolean)
: []; : [];
// merge unique
const merged = [ const merged = [
...selectedUsers, ...selectedUsers,
...baseList.filter((u) => !selectedUsers.some((s) => s.id === u.id)), ...baseList.filter((u) => !selectedUsers.some((s) => s.id === u.id)),
@ -148,10 +144,9 @@ const PmsEmployeeInputTag = ({
return ( return (
<div <div
className="tagify form-control d-flex align-items-center flex-wrap position-relative " className="tagify form-control d-flex align-items-center flex-wrap position-relative"
ref={dropdownRef} ref={dropdownRef}
> >
{/* Selected tags (chips) */}
{value.map((id) => { {value.map((id) => {
const u = resolveUserById(id); const u = resolveUserById(id);
if (!u) return null; if (!u) return null;
@ -190,8 +185,6 @@ const PmsEmployeeInputTag = ({
type="button" type="button"
className="tagify__tag__removeBtn border-none" className="tagify__tag__removeBtn border-none"
onClick={() => handleRemove(id)} onClick={() => handleRemove(id)}
aria-label={`Remove ${u.firstName}`}
title="Remove"
/> />
</span> </span>
); );