import { useMemo, useRef, useState } from "react"; import { X } from "lucide-react"; import { normalize } from "../lib/normalize"; import { cn } from "../lib/utils"; import { useClickOutside } from "./useClickOutside"; export interface ProjectOption { id: string; name: string; } // چند-انتخابیِ جست‌وجوپذیرِ پروژه‌ها (1:N — مدیر پروژه ↔ پروژه‌ها): // - چیپ‌های پروژه با دکمه‌ی × (جداسازی فوری مدیر از پروژه) // - جست‌وجوی زنده‌ی فارسی (normalize: ی/ك عربی، نیم‌فاصله و فاصله‌ها) // - پروژه‌های انتخاب‌شده از فهرست پنهان می‌شوند تا انتخاب تکراری رخ ندهد export function ProjectMultiSelect({ options, values, onChange, placeholder = "انتخاب پروژه(ها)...", disabled = false, }: { options: ProjectOption[]; values: string[]; onChange: (ids: string[]) => void; placeholder?: string; disabled?: boolean; }) { const [text, setText] = useState(""); const [open, setOpen] = useState(false); const inputRef = useRef(null); const ref = useClickOutside(() => { setOpen(false); setText(""); }); const byId = useMemo(() => new Map(options.map((o) => [o.id, o])), [options]); const selected = values.map((id) => byId.get(id)).filter(Boolean) as ProjectOption[]; const q = normalize(text); const available = useMemo( () => options.filter((o) => !values.includes(o.id) && (!q || normalize(o.name).includes(q))), [options, values, q], ); const add = (id: string) => { onChange([...values, id]); setText(""); inputRef.current?.focus(); }; const remove = (id: string) => onChange(values.filter((v) => v !== id)); return (
{ if (!disabled) { setOpen(true); inputRef.current?.focus(); } }} > {selected.map((p) => ( {p.name} {!disabled && ( )} ))} { setText(e.target.value); setOpen(true); }} onFocus={() => setOpen(true)} placeholder={selected.length ? "" : placeholder} className="h-7 min-w-24 flex-1 border-0 bg-transparent px-1 text-[12px] outline-none placeholder:text-muted/70" />
{open && !disabled && (
{available.length ? ( available.map((o) => ( )) ) : (
{options.length === 0 ? "پروژه‌ای وجود ندارد" : q ? "پروژه‌ای یافت نشد" : "همه‌ی پروژه‌ها متصل شده‌اند"}
)}
)}
); }