// The search in the header: trending environments before you type, matching ones as you type (yours first, when // signed in), and any dataset id opened directly, including a private one you can read. import { $, esc, fmt, nav } from "./util.js"; import { icon } from "./icons.js"; import { api } from "./util.js"; import { myDatasets } from "./data.js"; const compact = new Intl.NumberFormat("en-US", { notation: "compact", maximumFractionDigits: 1 }); const enc = (s) => s.split("/").map(encodeURIComponent).join("/"); const ID = /^[A-Za-z0-9][\w.-]*\/[\w.-]+$/; export function wireTopSearch() { const box = $("#top-search"), input = $("#top-q"), pop = $("#top-sug"); let rows = [], active = -1, seq = 0; const row = (d, i) => ` ${icon(d.private ? "shield" : d.kind === "space" ? "globe" : "database", 14)}${esc(d.id.split("/")[0])}/${esc(d.id.split("/")[1])} `; let ctrl = null; async function render() { const my = ++seq; const q = input.value.trim(), ql = q.toLowerCase(); ctrl?.abort(); ctrl = new AbortController(); let found, mine; try { // the server searches every environment (/api/search): eight cards, not the whole listing [found, mine] = await Promise.all([api(`/api/search?size=8&facets=0${q ? `&q=${encodeURIComponent(q)}` : ""}`, { signal: ctrl.signal }), myDatasets()]); } catch { return; } if (my !== seq) return; const sections = []; if (!q) { sections.push(["Trending environments", found.rows]); if (mine.length) sections.push(["Yours", mine.slice(0, 4)]); } else { const ours = mine.filter((d) => d.id.toLowerCase().includes(ql)); const rest = found.rows.filter((d) => !ours.some((o) => o.id === d.id)); if (ours.length) sections.push(["Yours", ours.slice(0, 4)]); sections.push([rest.length ? "Environments, trending first" : "", rest]); } const all = [...mine, ...found.rows]; rows = sections.flatMap(([, list]) => list); let i = 0; const open = ID.test(q) && !all.some((d) => d.id.toLowerCase() === ql); // any dataset by id, a private one too pop.innerHTML = sections.filter(([, list]) => list.length).map(([title, list]) => `${title ? `