Skip to content

Commit 60142f4

Browse files
committed
fix(tanstack-migrator): queue widget — hide suggestions in 1 column, slimmer rows + thin scrollbar
- 1 column: show only the migration queue; suggestions appear only in 2-column mode - suggestion rows reduced to logo + TOP + name + ≈cost/mo + add (dropped the repo and domain lines) - thin styled scrollbars on all scroll regions
1 parent cdcc0ff commit 60142f4

1 file changed

Lines changed: 27 additions & 65 deletions

File tree

  • tanstack-migrator/web/tools/widget-queue

tanstack-migrator/web/tools/widget-queue/index.tsx

Lines changed: 27 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import { ACTIVE_STATUSES_SET } from "@/lib/status.ts";
99
/** Show queue + suggestions side by side once the tile is at least this wide. */
1010
const WIDE_PX = 520;
1111

12+
/** Thin, unobtrusive scrollbar (Firefox + WebKit). */
13+
const THIN_SCROLL =
14+
"[scrollbar-width:thin] [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar]:h-1.5 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-muted-foreground/25 [&::-webkit-scrollbar-track]:bg-transparent";
15+
1216
/** Grafana stores the raw 7-day COGS; show it extrapolated to ~monthly (×30/7). */
1317
function estMonthly(cogs7d: number): string {
1418
return `≈$${Math.round((cogs7d * 30) / 7).toLocaleString()}/mo`;
@@ -79,25 +83,27 @@ export default function WidgetQueuePage() {
7983
queueEmpty ? "grid-cols-[0.8fr_1.2fr]" : "grid-cols-2",
8084
)}
8185
>
82-
<div className="min-h-0 overflow-y-auto pr-1">
86+
<div className={cn("min-h-0 overflow-y-auto pr-1", THIN_SCROLL)}>
8387
<QueueContent
8488
active={active}
8589
next={next}
8690
q={q}
8791
onEnqueue={enqueue}
8892
/>
8993
</div>
90-
<div className="min-h-0 overflow-y-auto border-l border-border pl-3">
91-
<SuggestionsContent onAdded={refresh} wide />
94+
<div
95+
className={cn(
96+
"min-h-0 overflow-y-auto border-l border-border pl-3",
97+
THIN_SCROLL,
98+
)}
99+
>
100+
<SuggestionsContent onAdded={refresh} />
92101
</div>
93102
</div>
94103
) : (
95-
// narrow: single scroll column, queue then suggestions stacked
96-
<div className="flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto">
104+
// narrow: queue only — suggestions appear once there's room for 2 columns
105+
<div className={cn("min-h-0 flex-1 overflow-y-auto", THIN_SCROLL)}>
97106
<QueueContent active={active} next={next} q={q} onEnqueue={enqueue} />
98-
<div className="border-t border-border pt-3">
99-
<SuggestionsContent onAdded={refresh} />
100-
</div>
101107
</div>
102108
)}
103109
</div>
@@ -214,13 +220,7 @@ interface Suggestion {
214220
top3: boolean;
215221
}
216222

217-
function SuggestionsContent({
218-
onAdded,
219-
wide = false,
220-
}: {
221-
onAdded: () => void;
222-
wide?: boolean;
223-
}) {
223+
function SuggestionsContent({ onAdded }: { onAdded: () => void }) {
224224
const { data, loading, refresh } = usePollingTool<{
225225
configured: boolean;
226226
sites: Suggestion[];
@@ -266,7 +266,6 @@ function SuggestionsContent({
266266
<SuggestionRow
267267
key={s.repo}
268268
s={s}
269-
wide={wide}
270269
busy={adding === s.repo}
271270
onAdd={() => add(s)}
272271
/>
@@ -337,69 +336,32 @@ function SiteIcon({
337336
);
338337
}
339338

340-
function prodHost(prodUrl: string | null): string | null {
341-
if (!prodUrl) return null;
342-
try {
343-
return new URL(prodUrl).hostname.replace(/^www\./, "");
344-
} catch {
345-
return null;
346-
}
347-
}
348-
349339
function SuggestionRow({
350340
s,
351-
wide,
352341
busy,
353342
onAdd,
354343
}: {
355344
s: Suggestion;
356-
wide: boolean;
357345
busy: boolean;
358346
onAdd: () => void;
359347
}) {
360-
const host = prodHost(s.prodUrl);
361348
return (
362349
<div className="flex items-center gap-2 px-2.5 py-1.5">
363350
<SiteIcon prodUrl={s.prodUrl} thumbUrl={s.thumbUrl} name={s.name} />
364-
<div className="flex min-w-0 flex-1 flex-col">
365-
<span className="flex items-center gap-1 truncate text-xs font-medium">
366-
{s.top3 && (
367-
<span className="shrink-0 rounded-full bg-amber-500/15 px-1 text-[9px] font-bold text-amber-600 dark:text-amber-400">
368-
TOP
369-
</span>
370-
)}
371-
<span className="truncate" title={s.name}>
372-
{s.name}
351+
<div className="flex min-w-0 flex-1 items-center gap-1.5">
352+
{s.top3 && (
353+
<span className="shrink-0 rounded-full bg-amber-500/15 px-1 text-[9px] font-bold text-amber-600 dark:text-amber-400">
354+
TOP
373355
</span>
374-
{/* repo alongside the name when there's room */}
375-
{wide && (
376-
<span
377-
className="truncate text-[10px] font-normal text-muted-foreground"
378-
title={s.repo}
379-
>
380-
· {s.repo}
381-
</span>
382-
)}
356+
)}
357+
<span className="truncate text-xs font-medium" title={s.name}>
358+
{s.name}
383359
</span>
384-
<span className="flex items-center gap-2 text-[10px] text-muted-foreground tabular-nums">
385-
<span
386-
className="font-semibold text-foreground/80"
387-
title={`$${Math.round(s.cogsUsd).toLocaleString()}/7d (Grafana)`}
388-
>
389-
{estMonthly(s.cogsUsd)}
390-
</span>
391-
{wide && host && (
392-
<a
393-
href={s.prodUrl ?? "#"}
394-
target="_blank"
395-
rel="noreferrer"
396-
onClick={(e) => e.stopPropagation()}
397-
className="truncate hover:text-foreground hover:underline"
398-
title={s.prodUrl ?? ""}
399-
>
400-
{host}
401-
</a>
402-
)}
360+
<span
361+
className="ml-auto shrink-0 text-[10px] font-semibold tabular-nums text-muted-foreground"
362+
title={`$${Math.round(s.cogsUsd).toLocaleString()}/7d (Grafana)`}
363+
>
364+
{estMonthly(s.cogsUsd)}
403365
</span>
404366
</div>
405367
<button

0 commit comments

Comments
 (0)