in torchci/pages/hud/[repoOwner]/[repoName]/[branch]/[page].tsx [145:207]
function FilterableHudTable({
params,
jobNames,
children,
}: {
params: HudParams;
jobNames: string[];
children: React.ReactNode;
}) {
const router = useRouter();
const [jobFilter, setJobFilter] = useState<string | null>(null);
// null and empty string both correspond to no filter; otherwise lowercase it
// to make the filter case-insensitive.
const normalizedJobFilter =
jobFilter === null || jobFilter === "" ? null : jobFilter.toLowerCase();
useEffect(() => {
document.addEventListener("keydown", (e) => {
if (e.code === "Escape") {
setJobFilter(null);
}
});
}, []);
const handleInput = useCallback((f) => setJobFilter(f), []);
const handleSubmit = useCallback(() => {
if (jobFilter === "") {
router.push(formatHudURL("hud", params), undefined, { shallow: true });
} else {
router.push(
formatHudURL("hud", params) + `?name_filter=${jobFilter}`,
undefined,
{
shallow: true,
}
);
}
}, [params, router, jobFilter]);
// We have to use an effect hook here because query params are undefined at
// static generation time; they only become available after hydration.
useEffect(() => {
const filterValue = (router.query.name_filter as string) || "";
setJobFilter(filterValue);
handleInput(filterValue);
}, [router.query.name_filter, handleInput]);
return (
<>
<JobFilterInput
currentFilter={jobFilter}
handleSubmit={handleSubmit}
handleInput={handleInput}
/>
<table className={styles.hudTable}>
<HudTableColumns filter={normalizedJobFilter} names={jobNames} />
<HudTableHeader filter={normalizedJobFilter} names={jobNames} />
{children}
</table>
</>
);
}