Skip to content

Commit 249c686

Browse files
feat: update font imports, improve jobs search bar UI, add stale repo cleanup
1 parent 1d476ef commit 249c686

5 files changed

Lines changed: 95 additions & 16 deletions

File tree

src/client/app.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300..700&family=JetBrains+Mono:ital,wght@0,400;0,500;1,400&display=swap');
1+
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;500;600;700&family=JetBrains+Mono:ital,wght@0,400;0,500;1,400&display=swap');
22

33
@import "tailwindcss";
44

@@ -134,7 +134,7 @@
134134
Tailwind v4 theme tokens (@theme inline = dynamic)
135135
───────────────────────────────────────────────────── */
136136
@theme inline {
137-
--font-sans: 'Space Grotesk', 'Segoe UI', system-ui, sans-serif;
137+
--font-sans: 'IBM Plex Sans', 'Segoe UI', system-ui, sans-serif;
138138
--font-mono: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;
139139

140140
--color-background: var(--background);

src/client/components/ui/dropdown-menu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const DropdownMenuSub = DropdownMenuPrimitive.Sub;
1616
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
1717

1818
const menuContentClass =
19-
'z-50 min-w-[8rem] overflow-hidden rounded-lg border border-zinc-200 bg-white p-1 text-zinc-900 shadow-lg shadow-black/[0.06] dark:border-border dark:bg-popover dark:text-popover-foreground dark:shadow-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 duration-200';
19+
'z-50 min-w-[8rem] overflow-hidden rounded-lg border border-zinc-200 bg-white p-1 text-zinc-900 shadow-sm shadow-black/[0.02] dark:border-border dark:bg-popover dark:text-popover-foreground dark:shadow-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 duration-200';
2020

2121
const menuItemClass =
2222
'relative flex cursor-default select-none items-center rounded-md text-sm outline-none transition-colors hover:bg-zinc-200 hover:text-zinc-900 focus:bg-zinc-200 focus:text-zinc-900 data-[highlighted]:bg-zinc-200 data-[highlighted]:text-zinc-900 dark:hover:bg-primary/[0.12] dark:hover:text-foreground dark:focus:bg-primary/[0.12] dark:focus:text-foreground dark:data-[highlighted]:bg-primary/[0.12] dark:data-[highlighted]:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50';

src/client/pages/jobs.tsx

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -113,17 +113,57 @@ export function JobsPage() {
113113
}
114114
/>
115115

116-
{/* ── Search bar (Beetle-style below header) ─── */}
117-
<div className="relative">
118-
<Search size={14} className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground pointer-events-none" />
119-
<input
120-
type="text"
121-
id="pr-search"
122-
placeholder="Search PRs, title, repo, number"
123-
value={filters.search}
124-
onChange={(e) => setFilters((f) => ({ ...f, search: e.target.value, page: 1 }))}
125-
className="h-9 w-full max-w-sm rounded-md border border-border bg-background pl-9 pr-3 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring"
126-
/>
116+
{/* ── Search bar ─── */}
117+
<div className="surface p-4 flex flex-col sm:flex-row gap-4">
118+
{/* Search Input */}
119+
<div className="flex flex-col gap-1.5 flex-1">
120+
<label htmlFor="pr-search" className="text-[10px] font-bold uppercase tracking-wider text-muted-foreground/70">
121+
Search
122+
</label>
123+
<input
124+
type="text"
125+
id="pr-search"
126+
placeholder="Title or #number..."
127+
value={filters.search}
128+
onChange={(e) => setFilters((f) => ({ ...f, search: e.target.value, page: 1 }))}
129+
className="h-9 w-full rounded-md border border-border bg-transparent px-3 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring"
130+
/>
131+
</div>
132+
133+
{/* Status Dropdown */}
134+
<div className="w-full sm:w-48">
135+
<Select
136+
label="Status"
137+
value={filters.status}
138+
onValueChange={(v) => setFilters((f) => ({ ...f, status: v, page: 1 }))}
139+
placeholder="All statuses"
140+
options={[
141+
{ value: '', label: 'All statuses' },
142+
{ value: 'queued', label: 'Queued' },
143+
{ value: 'running', label: 'Running' },
144+
{ value: 'done', label: 'Done' },
145+
{ value: 'failed', label: 'Failed' },
146+
{ value: 'superseded', label: 'Superseded' }
147+
]}
148+
triggerClassName="bg-transparent"
149+
/>
150+
</div>
151+
152+
{/* Verdict Dropdown */}
153+
<div className="w-full sm:w-48">
154+
<Select
155+
label="Verdict"
156+
value={filters.verdict}
157+
onValueChange={(v) => setFilters((f) => ({ ...f, verdict: v, page: 1 }))}
158+
placeholder="All verdicts"
159+
options={[
160+
{ value: '', label: 'All verdicts' },
161+
{ value: 'approve', label: 'Approve' },
162+
{ value: 'comment', label: 'Comment' }
163+
]}
164+
triggerClassName="bg-transparent"
165+
/>
166+
</div>
127167
</div>
128168

129169
{/* System Failures (DLQ) Section */}

src/server/db/repo-configs.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,39 @@ export async function syncRepoConfig(
105105
);
106106
}
107107

108+
export async function deleteStaleRepoConfigs(
109+
env: Pick<AppBindings, 'HYPERDRIVE'>,
110+
installationId: string,
111+
activeRepoFullNames: string[]
112+
) {
113+
if (activeRepoFullNames.length === 0) {
114+
await queryRows(
115+
env,
116+
`
117+
DELETE FROM repo_configs
118+
WHERE repository_id IN (
119+
SELECT id FROM repositories WHERE installation_id = $1
120+
)
121+
`,
122+
[installationId]
123+
);
124+
return;
125+
}
126+
127+
await queryRows(
128+
env,
129+
`
130+
DELETE FROM repo_configs
131+
WHERE repository_id IN (
132+
SELECT id FROM repositories
133+
WHERE installation_id = $1
134+
AND owner || '/' || repo != ALL($2::text[])
135+
)
136+
`,
137+
[installationId, activeRepoFullNames]
138+
);
139+
}
140+
108141
export async function updateRepoConfigEnabled(
109142
env: Pick<AppBindings, 'HYPERDRIVE'>,
110143
input: {

src/server/routes/api/repos.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Hono } from 'hono';
22
import { z } from 'zod';
33
import type { AppEnv } from '@server/env';
4-
import { getRepoConfigRecord, listRepoConfigs, upsertRepoConfig, syncRepoConfig, updateRepoConfigEnabled } from '@server/db/repo-configs';
4+
import { getRepoConfigRecord, listRepoConfigs, upsertRepoConfig, syncRepoConfig, updateRepoConfigEnabled, deleteStaleRepoConfigs } from '@server/db/repo-configs';
55
import { jsonError } from '@server/core/http';
66
import { GitHubClient, type GitHubRepository } from '@server/core/github';
77
import { invalidateRepoConfigCache } from '@server/core/config';
@@ -83,9 +83,15 @@ export function createReposRouter() {
8383
},
8484
);
8585

86+
const installationSynced: string[] = [];
8687
for (const res of results) {
87-
if (res) synced.push(res);
88+
if (res) {
89+
synced.push(res);
90+
installationSynced.push(res);
91+
}
8892
}
93+
94+
await deleteStaleRepoConfigs(c.env, String(inst.id), installationSynced);
8995
}
9096

9197
return c.json({ ok: true, synced });

0 commit comments

Comments
 (0)