(() => { const { Icon, Badge, Avatar } = window.TaskFlowDesignSystem_dd53c2; /* Cari global: satu input di top bar untuk task, project, dokumen, dan user. Pencarian dibatasi 6 hasil per kelompok dan hanya jalan bila kata ≥ 2 huruf, sehingga tetap ringan meski data ribuan baris. */ function GlobalSearch({ tasks = [], isAdmin, meId, onOpenTask, onNavigate, onOpenDocument }) { const compact = useBreakpoint() !== "desktop"; const [q, setQ] = React.useState(""); const [open, setOpen] = React.useState(false); const box = React.useRef(null); React.useEffect(() => { const away = (e) => { if (box.current && !box.current.contains(e.target)) setOpen(false); }; document.addEventListener("mousedown", away); return () => document.removeEventListener("mousedown", away); }, []); const scope = React.useMemo(() => (isAdmin ? tasks : tasks.filter((t) => t.user === meId)), [tasks, isAdmin, meId]); const res = React.useMemo(() => { const s = q.trim().toLowerCase(); if (s.length < 2) return null; const hit = (v) => String(v || "").toLowerCase().includes(s); const taskHits = scope.filter((t) => hit(t.type) || hit(t.category)).slice(0, 6); const projects = [...new Set(scope.filter((t) => t.project && hit(t.project)).map((t) => t.project))].slice(0, 4); const docs = scope.filter((t) => t.status === "done" && t.evidence && (hit(t.evidence.name) || hit(t.type))).slice(0, 4); const users = isAdmin ? USERS.filter((u) => hit(u.name) || hit(u.email) || hit(u.role)).slice(0, 4) : []; return { taskHits, projects, docs, users, total: taskHits.length + projects.length + docs.length + users.length }; }, [q, scope, isAdmin]); const row = (key, icon, title, sub, right, onClick) => ( ); const group = (label) => ( {label} ); return ( { setQ(e.target.value); setOpen(true); }} onFocus={() => setOpen(true)} placeholder="Cari task, project, dokumen…" aria-label="Cari global" style={{ width: compact ? 118 : 178, minWidth: 0, border: "none", outline: "none", background: "transparent", font: "var(--text-body-default)", color: "var(--text-strong)" }} /> {q && } {open && res && (
{res.total === 0 && Tidak ada hasil untuk “{q}”.} {res.taskHits.length > 0 && group("Task")} {res.taskHits.map((t) => row("t" + t.id, "clipboard-list", t.type, `${nameOf(t.user)} · target ${t.target}`, {t.status.replace(/_/g, " ")}, () => onOpenTask && onOpenTask(t)))} {res.projects.length > 0 && group("Project")} {res.projects.map((p) => row("p" + p, "folder", p, `${scope.filter((t) => t.project === p).length} task`, null, () => onNavigate && onNavigate("tasks")))} {res.docs.length > 0 && group("Dokumen")} {res.docs.map((t) => row("d" + t.id, "file-text", t.evidence.name, `${t.type} · diterima ${t.done}`, t.signature ? TTD : null, () => onOpenDocument && onOpenDocument(t)))} {res.users.length > 0 && group("User")} {res.users.map((u) => ( ))}
)}
); } Object.assign(window, { GlobalSearch }); })();