/** * Case-insensitive substring match for Overview "Workplans by Repository". * Matches title, repo, domain, filename, owner, and id. * * @param {object} workplan Row from overview workplan_rows * @param {string} query Free-text filter * @returns {boolean} */ export function workplanMatchesSearch(workplan, query) { const q = String(query ?? "").trim().toLowerCase(); if (!q) return true; if (!workplan || typeof workplan !== "object") return false; const haystack = [ workplan.title, workplan.repo_label, workplan.domain, workplan.workplan_filename, workplan.owner, workplan.id, ].filter(Boolean).join("\n").toLowerCase(); return haystack.includes(q); }