added pre-fill updating
This commit is contained in:
parent
742337a3d0
commit
4d8af5da91
@ -3,6 +3,7 @@ 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";
|
import { useProjectBothName } from "../../../hooks/useProjects";
|
||||||
|
import EmployeeRepository from "../../../repositories/EmployeeRepository";
|
||||||
|
|
||||||
const SelectEmployeeServerSide = ({
|
const SelectEmployeeServerSide = ({
|
||||||
label = "Select",
|
label = "Select",
|
||||||
@ -18,6 +19,7 @@ const SelectEmployeeServerSide = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const [searchText, setSearchText] = useState("");
|
const [searchText, setSearchText] = useState("");
|
||||||
const debounce = useDebounce(searchText, 300);
|
const debounce = useDebounce(searchText, 300);
|
||||||
|
const [forcedSelected, setForcedSelected] = useState(null);
|
||||||
|
|
||||||
const { data, isLoading } = useEmployeesName(
|
const { data, isLoading } = useEmployeesName(
|
||||||
projectId,
|
projectId,
|
||||||
@ -34,22 +36,15 @@ const SelectEmployeeServerSide = ({
|
|||||||
return `${emp.firstName || ""} ${emp.lastName || ""}`.trim();
|
return `${emp.firstName || ""} ${emp.lastName || ""}`.trim();
|
||||||
};
|
};
|
||||||
|
|
||||||
/** -----------------------------
|
|
||||||
* SELECTED OPTION (SINGLE)
|
|
||||||
* ----------------------------- */
|
|
||||||
let selectedSingle = null;
|
let selectedSingle = null;
|
||||||
|
|
||||||
if (!isMultiple) {
|
if (!isMultiple) {
|
||||||
if (isFullObject && value) selectedSingle = value;
|
if (isFullObject && value) selectedSingle = value;
|
||||||
else if (!isFullObject && value)
|
else if (!isFullObject && value)
|
||||||
selectedSingle = options.find((o) => o[valueKey] === value);
|
selectedSingle =
|
||||||
|
options.find((o) => o[valueKey] === value) || forcedSelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** -----------------------------
|
|
||||||
* SELECTED OPTION (MULTIPLE)
|
|
||||||
* ----------------------------- */
|
|
||||||
let selectedList = [];
|
let selectedList = [];
|
||||||
|
|
||||||
if (isMultiple && Array.isArray(value)) {
|
if (isMultiple && Array.isArray(value)) {
|
||||||
if (isFullObject) selectedList = value;
|
if (isFullObject) selectedList = value;
|
||||||
else {
|
else {
|
||||||
@ -57,54 +52,61 @@ const SelectEmployeeServerSide = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Main button label */
|
|
||||||
const displayText = !isMultiple
|
const displayText = !isMultiple
|
||||||
? getDisplayName(selectedSingle) || placeholder
|
? getDisplayName(selectedSingle) || placeholder
|
||||||
: selectedList.length > 0
|
: selectedList.length > 0
|
||||||
? selectedList.map((e) => getDisplayName(e)).join(", ")
|
? selectedList.map((e) => getDisplayName(e)).join(", ")
|
||||||
: placeholder;
|
: placeholder;
|
||||||
|
|
||||||
/** -----------------------------
|
|
||||||
* HANDLE OUTSIDE CLICK
|
|
||||||
* ----------------------------- */
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleClickOutside = (e) => {
|
const handleClickOutside = (e) => {
|
||||||
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener("mousedown", handleClickOutside);
|
document.addEventListener("mousedown", handleClickOutside);
|
||||||
return () => document.removeEventListener("mousedown", handleClickOutside);
|
return () => document.removeEventListener("mousedown", handleClickOutside);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
/** -----------------------------
|
|
||||||
* HANDLE SELECT
|
|
||||||
* ----------------------------- */
|
|
||||||
const handleSelect = (option) => {
|
const handleSelect = (option) => {
|
||||||
if (!isMultiple) {
|
if (!isMultiple) {
|
||||||
// SINGLE SELECT
|
|
||||||
if (isFullObject) onChange(option);
|
if (isFullObject) onChange(option);
|
||||||
else onChange(option[valueKey]);
|
else onChange(option[valueKey]);
|
||||||
|
setOpen(false);
|
||||||
} else {
|
} else {
|
||||||
// MULTIPLE SELECT
|
|
||||||
let updated = [];
|
let updated = [];
|
||||||
|
|
||||||
const exists = selectedList.some((e) => e[valueKey] === option[valueKey]);
|
const exists = selectedList.some((e) => e[valueKey] === option[valueKey]);
|
||||||
|
updated = exists
|
||||||
if (exists) {
|
? selectedList.filter((e) => e[valueKey] !== option[valueKey])
|
||||||
// remove
|
: [...selectedList, option];
|
||||||
updated = selectedList.filter((e) => e[valueKey] !== option[valueKey]);
|
|
||||||
} else {
|
|
||||||
// add
|
|
||||||
updated = [...selectedList, option];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isFullObject) onChange(updated);
|
if (isFullObject) onChange(updated);
|
||||||
else onChange(updated.map((x) => x[valueKey]));
|
else onChange(updated.map((x) => x[valueKey]));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!value || isFullObject) return;
|
||||||
|
|
||||||
|
const exists = options.some((o) => o[valueKey] === value);
|
||||||
|
if (exists) return;
|
||||||
|
|
||||||
|
const loadSingleEmployee = async () => {
|
||||||
|
try {
|
||||||
|
const emp = await EmployeeRepository.getEmployeeName(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
value
|
||||||
|
);
|
||||||
|
setForcedSelected(emp.data[0]);
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Failed to load selected employee", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
loadSingleEmployee();
|
||||||
|
}, [value, options, isFullObject, valueKey]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mb-3 position-relative" ref={dropdownRef}>
|
<div className="mb-3 position-relative" ref={dropdownRef}>
|
||||||
{label && (
|
{label && (
|
||||||
@ -126,7 +128,6 @@ const SelectEmployeeServerSide = ({
|
|||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{/* DROPDOWN */}
|
|
||||||
{open && (
|
{open && (
|
||||||
<ul
|
<ul
|
||||||
className="dropdown-menu w-100 shadow-sm show animate__fadeIn h-64 overflow-auto rounded"
|
className="dropdown-menu w-100 shadow-sm show animate__fadeIn h-64 overflow-auto rounded"
|
||||||
@ -137,10 +138,10 @@ const SelectEmployeeServerSide = ({
|
|||||||
zIndex: 1050,
|
zIndex: 1050,
|
||||||
marginTop: "4px",
|
marginTop: "4px",
|
||||||
borderRadius: "0.375rem",
|
borderRadius: "0.375rem",
|
||||||
overflow: "hidden",
|
padding: 0,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="p-1">
|
<li className="p-1 sticky-top bg-white" style={{ zIndex: 10 }}>
|
||||||
<input
|
<input
|
||||||
type="search"
|
type="search"
|
||||||
value={searchText}
|
value={searchText}
|
||||||
@ -148,7 +149,7 @@ const SelectEmployeeServerSide = ({
|
|||||||
className="form-control form-control-sm"
|
className="form-control form-control-sm"
|
||||||
placeholder="Search..."
|
placeholder="Search..."
|
||||||
/>
|
/>
|
||||||
</div>
|
</li>
|
||||||
|
|
||||||
{isLoading && (
|
{isLoading && (
|
||||||
<li className="dropdown-item text-muted text-center">Loading...</li>
|
<li className="dropdown-item text-muted text-center">Loading...</li>
|
||||||
@ -168,10 +169,12 @@ const SelectEmployeeServerSide = ({
|
|||||||
selectedSingle[valueKey] === option[valueKey];
|
selectedSingle[valueKey] === option[valueKey];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li key={option[valueKey]}>
|
<li key={option[valueKey]} className="px-1 rounded">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`dropdown-item ${isActive ? "active" : ""}`}
|
className={`dropdown-item rounded ${
|
||||||
|
isActive ? "active" : ""
|
||||||
|
}`}
|
||||||
onClick={() => handleSelect(option)}
|
onClick={() => handleSelect(option)}
|
||||||
>
|
>
|
||||||
{getDisplayName(option)}
|
{getDisplayName(option)}
|
||||||
@ -184,6 +187,7 @@ const SelectEmployeeServerSide = ({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SelectEmployeeServerSide;
|
export default SelectEmployeeServerSide;
|
||||||
|
|
||||||
export const SelectProjectField = ({
|
export const SelectProjectField = ({
|
||||||
@ -211,9 +215,6 @@ export const SelectProjectField = ({
|
|||||||
return `${project.name || ""}`.trim();
|
return `${project.name || ""}`.trim();
|
||||||
};
|
};
|
||||||
|
|
||||||
/** -----------------------------
|
|
||||||
* SELECTED OPTION (SINGLE)
|
|
||||||
* ----------------------------- */
|
|
||||||
let selectedSingle = null;
|
let selectedSingle = null;
|
||||||
|
|
||||||
if (!isMultiple) {
|
if (!isMultiple) {
|
||||||
@ -222,9 +223,6 @@ export const SelectProjectField = ({
|
|||||||
selectedSingle = options.find((o) => o[valueKey] === value);
|
selectedSingle = options.find((o) => o[valueKey] === value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** -----------------------------
|
|
||||||
* SELECTED OPTION (MULTIPLE)
|
|
||||||
* ----------------------------- */
|
|
||||||
let selectedList = [];
|
let selectedList = [];
|
||||||
|
|
||||||
if (isMultiple && Array.isArray(value)) {
|
if (isMultiple && Array.isArray(value)) {
|
||||||
@ -345,10 +343,12 @@ export const SelectProjectField = ({
|
|||||||
selectedSingle[valueKey] === option[valueKey];
|
selectedSingle[valueKey] === option[valueKey];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li key={option[valueKey]}>
|
<li key={option[valueKey]} className="px-1 rounded w-full">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={`dropdown-item ${isActive ? "active" : ""}`}
|
className={`dropdown-item rounded d-block text-truncate w-100 ${
|
||||||
|
isActive ? "active" : ""
|
||||||
|
}`}
|
||||||
onClick={() => handleSelect(option)}
|
onClick={() => handleSelect(option)}
|
||||||
>
|
>
|
||||||
{getDisplayName(option)}
|
{getDisplayName(option)}
|
||||||
@ -514,7 +514,7 @@ export const SelectFieldSearch = ({
|
|||||||
{/* DROPDOWN */}
|
{/* DROPDOWN */}
|
||||||
{open && (
|
{open && (
|
||||||
<ul
|
<ul
|
||||||
className="dropdown-menu w-100 shadow-sm show animate__fadeIn h-64 overflow-auto rounded"
|
className="dropdown-menu w-100 shadow-sm show animate__fadeIn h-64 overflow-auto rounded overflow-x-hidden"
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
top: "100%",
|
top: "100%",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user