@@ -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. */
1010const 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). */
1317function 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 ( / ^ w w w \. / , "" ) ;
344- } catch {
345- return null ;
346- }
347- }
348-
349339function 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