Skip to content

Commit f78a276

Browse files
committed
Add url param support to runners page
1 parent e58a6f1 commit f78a276

3 files changed

Lines changed: 48 additions & 22 deletions

File tree

torchci/lib/ParamSelector.tsx

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,35 +15,33 @@ export function ParamSelector({
1515
return (
1616
<form
1717
className={styles.branchForm}
18-
onSubmit={(e) => {
18+
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
1919
e.preventDefault();
20-
// @ts-ignore
21-
handleSubmit(e.target[0].value);
20+
const form = e.currentTarget;
21+
const input = form.elements[0] as HTMLInputElement;
22+
handleSubmit(input.value);
2223
}}
2324
>
2425
<input
25-
onChange={(e) => {
26-
// @ts-ignore
26+
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
2727
setVal(e.target.value);
2828
}}
29-
onFocus={(e) => {
29+
onFocus={(e: React.FocusEvent<HTMLInputElement>) => {
3030
e.target.select();
31-
console.log(e.target.value);
3231
}}
3332
onBlur={(e) => {
3433
if (e.target.value !== value && e.target.value.length > 0) {
3534
e.preventDefault();
3635
handleSubmit(e.target.value);
3736
}
3837
}}
39-
onKeyDown={(e) => {
38+
onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) => {
4039
if (e.key === "Escape") {
4140
e.preventDefault();
42-
// @ts-ignore
43-
e.target.value = value;
41+
const input = e.currentTarget;
42+
input.value = value;
4443
setVal(value);
45-
// @ts-ignore
46-
e.target.blur();
44+
input.blur();
4745
}
4846
}}
4947
size={val.length || 0}

torchci/pages/api/runners/[org].ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@ export const ALLOWED_ORGS = ["pytorch", "meta-pytorch"];
1818

1919
// Shared function to map GitHub API runner response to our format
2020
function mapRunnerFromGitHubAPI(runner: any): RunnerData {
21-
// Debug: Log full runner object for runners with no labels
22-
if (!runner.labels || runner.labels.length === 0) {
23-
console.log("Runner with no labels:", JSON.stringify(runner, null, 2));
24-
}
2521

2622
return {
2723
id: runner.id,
@@ -187,9 +183,7 @@ export default async function handler(
187183
// Check if org is allowed
188184
if (!ALLOWED_ORGS.includes(org.toLowerCase())) {
189185
return res.status(403).json({
190-
error: `Access denied. Only ${ALLOWED_ORGS.join(
191-
", "
192-
)} organizations are supported.`,
186+
error: "Access denied. This organization is not supported.",
193187
});
194188
}
195189

torchci/pages/runners/[org].tsx

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ import { ParamSelector } from "lib/ParamSelector";
4242
import { RunnersApiResponse, unknownGoesLast } from "lib/runnerUtils";
4343
import { useSession } from "next-auth/react";
4444
import { useRouter } from "next/router";
45-
import { useMemo, useState } from "react";
45+
import { useCallback, useEffect, useMemo, useState } from "react";
46+
import debounce from "lodash/debounce";
47+
import type { ParsedUrlQuery } from "querystring";
4648
import useSWR from "swr";
4749

4850
// Define sort order constants to prevent typos
@@ -71,10 +73,38 @@ export default function RunnersPage() {
7173
const orgParam = typeof org === "string" ? org : null;
7274

7375
const { data: _session, status: _status } = useSession();
74-
const [searchTerm, setSearchTerm] = useState("");
76+
77+
// Utility function to extract search term from URL query
78+
const getSearchFromQuery = (query: ParsedUrlQuery): string => {
79+
return typeof query.search === "string" ? query.search : "";
80+
};
81+
82+
// Get search term from URL parameters
83+
const [searchTerm, setSearchTerm] = useState(getSearchFromQuery(router.query));
7584
const [sortOrder, setSortOrder] = useState<SortOrder>(SORT_ALPHABETICAL);
7685
const [expandedGroup, setExpandedGroup] = useState<string | null>(null);
7786

87+
// Sync search state with URL changes
88+
useEffect(() => {
89+
const searchParam = router.query.search;
90+
const newSearchTerm = getSearchFromQuery({ search: searchParam });
91+
setSearchTerm(newSearchTerm);
92+
}, [router.query.search]);
93+
94+
// Debounced function to update search in URL
95+
const updateSearchInUrl = useCallback(
96+
debounce((newSearchTerm: string) => {
97+
const query = { ...router.query };
98+
if (newSearchTerm) {
99+
query.search = newSearchTerm;
100+
} else {
101+
delete query.search;
102+
}
103+
router.push({ pathname: router.pathname, query }, undefined, { shallow: true });
104+
}, 300),
105+
[router]
106+
);
107+
78108
// Handle URL editing for organization
79109
const handleOrgSubmit = (newOrg: string) => {
80110
if (!newOrg) return;
@@ -192,7 +222,11 @@ export default function RunnersPage() {
192222
variant="outlined"
193223
placeholder="Search runners by name, ID, OS, or labels..."
194224
value={searchTerm}
195-
onChange={(e) => setSearchTerm(e.target.value)}
225+
onChange={(e) => {
226+
const value = e.target.value;
227+
setSearchTerm(value); // Immediate UI update
228+
updateSearchInUrl(value); // Debounced URL update
229+
}}
196230
sx={{ maxWidth: 600, mb: 2 }}
197231
/>
198232

0 commit comments

Comments
 (0)