updated PmsEmployeeInputTag for getting all exiten employee for update
This commit is contained in:
parent
b68f8306fd
commit
937531afb6
@ -1,7 +1,7 @@
|
||||
import { useState, useEffect, useRef, useMemo } from "react";
|
||||
import { useController } from "react-hook-form";
|
||||
import { useDebounce } from "../../utils/appUtils";
|
||||
import { useEmployeesName } from "../../hooks/useEmployees";
|
||||
import { useEmployeesName, useUserCache } from "../../hooks/useEmployees";
|
||||
import Avatar from "./Avatar";
|
||||
|
||||
const PmsEmployeeInputTag = ({
|
||||
@ -11,16 +11,17 @@ const PmsEmployeeInputTag = ({
|
||||
projectId,
|
||||
forAll,
|
||||
isApplicationUser = false,
|
||||
disabled
|
||||
disabled,
|
||||
}) => {
|
||||
const {
|
||||
field: { value = [], onChange },
|
||||
} = useController({ name, control });
|
||||
|
||||
const { getUser, addToCache, userCache } = useUserCache();
|
||||
|
||||
const [search, setSearch] = useState("");
|
||||
const [showDropdown, setShowDropdown] = useState(false);
|
||||
const [filteredUsers, setFilteredUsers] = useState([]);
|
||||
const [userCache, setUserCache] = useState({});
|
||||
const dropdownRef = useRef(null);
|
||||
const inputRef = useRef(null);
|
||||
const activeIndexRef = useRef(-1);
|
||||
@ -32,26 +33,28 @@ const PmsEmployeeInputTag = ({
|
||||
forAll
|
||||
);
|
||||
|
||||
// Keep both filtered list and cache updated
|
||||
useEffect(() => {
|
||||
if (employees?.data?.length) {
|
||||
setFilteredUsers(employees.data);
|
||||
activeIndexRef.current = -1;
|
||||
|
||||
// cache all fetched users by id
|
||||
setUserCache((prev) => {
|
||||
const updated = { ...prev };
|
||||
employees.data.forEach((u) => {
|
||||
updated[u.id] = u;
|
||||
});
|
||||
return updated;
|
||||
});
|
||||
employees.data.forEach((u) => addToCache(u.id, u));
|
||||
} else {
|
||||
setFilteredUsers([]);
|
||||
}
|
||||
}, [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(() => {
|
||||
const onDocClick = (e) => {
|
||||
if (
|
||||
@ -66,7 +69,6 @@ const PmsEmployeeInputTag = ({
|
||||
return () => document.removeEventListener("mousedown", onDocClick);
|
||||
}, []);
|
||||
|
||||
// select a user
|
||||
const handleSelect = (user) => {
|
||||
if (value.includes(user.id)) return;
|
||||
const updated = [...value, user.id];
|
||||
@ -76,13 +78,11 @@ const PmsEmployeeInputTag = ({
|
||||
setTimeout(() => inputRef.current?.focus(), 0);
|
||||
};
|
||||
|
||||
// remove selected user
|
||||
const handleRemove = (id) => {
|
||||
const updated = value.filter((uid) => uid !== id);
|
||||
onChange(updated);
|
||||
};
|
||||
|
||||
// keyboard navigation
|
||||
const onInputKeyDown = (e) => {
|
||||
if (!showDropdown) return;
|
||||
const max = Math.max(0, filteredUsers.length - 1);
|
||||
@ -103,7 +103,6 @@ const PmsEmployeeInputTag = ({
|
||||
}
|
||||
};
|
||||
|
||||
// scroll active dropdown item into view
|
||||
const scrollToActive = () => {
|
||||
const wrapper = dropdownRef.current?.querySelector(
|
||||
".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) => {
|
||||
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 baseList = isApplicationUser
|
||||
? (filteredUsers || []).filter((u) => u?.email)
|
||||
: filteredUsers || [];
|
||||
|
||||
// also include selected users even if missing from current API
|
||||
const selectedUsers =
|
||||
Array.isArray(value) && value.length
|
||||
? value.map((uid) => userCache[uid]).filter(Boolean)
|
||||
: [];
|
||||
|
||||
// merge unique
|
||||
const merged = [
|
||||
...selectedUsers,
|
||||
...baseList.filter((u) => !selectedUsers.some((s) => s.id === u.id)),
|
||||
@ -148,10 +144,9 @@ const PmsEmployeeInputTag = ({
|
||||
|
||||
return (
|
||||
<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}
|
||||
>
|
||||
{/* Selected tags (chips) */}
|
||||
{value.map((id) => {
|
||||
const u = resolveUserById(id);
|
||||
if (!u) return null;
|
||||
@ -190,8 +185,6 @@ const PmsEmployeeInputTag = ({
|
||||
type="button"
|
||||
className="tagify__tag__removeBtn border-none"
|
||||
onClick={() => handleRemove(id)}
|
||||
aria-label={`Remove ${u.firstName}`}
|
||||
title="Remove"
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user