style(ui): flat menu sheets, digests folded with job runs, shorter spend caption

This commit is contained in:
hh
2026-09-02 04:43:04 +02:00
parent 99bcec2ba0
commit 836cd60bd8
4 changed files with 78 additions and 12 deletions
+51
View File
@@ -211,3 +211,54 @@
left: 1.125rem; left: 1.125rem;
} }
} }
/* Menus and selects: one quiet sheet, rows that stay inside it. Unlayered
on purpose - the generated components carry pill utilities of their own. */
[data-slot="dropdown-menu-content"],
[data-slot="context-menu-content"],
[data-slot="select-content"] {
--tw-ring-shadow: 0 0 #0000;
--tw-ring-offset-shadow: 0 0 #0000;
padding: 0.25rem;
background: var(--popover);
border: 1px solid var(--border);
border-radius: 0.625rem;
box-shadow: var(--shadow-float);
}
[data-slot="dropdown-menu-content"]::before,
[data-slot="context-menu-content"]::before,
[data-slot="select-content"]::before {
display: none;
}
[data-slot="dropdown-menu-item"],
[data-slot="dropdown-menu-checkbox-item"],
[data-slot="context-menu-item"],
[data-slot="context-menu-checkbox-item"],
[data-slot="select-item"] {
min-height: 1.75rem;
padding: 0.375rem 0.5rem;
font-weight: 400;
border-radius: 0.375rem;
}
[data-slot="select-item"] {
padding-right: 2rem;
}
[data-slot="dropdown-menu-checkbox-item"],
[data-slot="context-menu-checkbox-item"] {
padding-right: 2rem;
}
[data-slot$="-item"]:focus,
[data-slot$="-item"][data-highlighted] {
color: var(--accent-foreground);
background: var(--accent);
}
[data-slot$="-item"][data-variant="destructive"]:focus,
[data-slot$="-item"][data-variant="destructive"][data-highlighted] {
color: var(--destructive);
background: color-mix(in oklab, var(--destructive) 12%, transparent);
}
[data-slot="dropdown-menu-separator"],
[data-slot="context-menu-separator"] {
margin: 0.25rem -0.25rem;
background: var(--border);
}
+1 -1
View File
@@ -136,7 +136,7 @@ export function daySummary(group: DayGroup, today: boolean): string {
parts.push(count(group.deep.length, "deep", "deep")); parts.push(count(group.deep.length, "deep", "deep"));
} }
if (group.forks.length) { if (group.forks.length) {
parts.push(count(group.forks.length, "fork")); parts.push(count(group.forks.length, "digest"));
} }
if (group.jobs.length) { if (group.jobs.length) {
parts.push(count(group.jobs.length, "job run")); parts.push(count(group.jobs.length, "job run"));
+25 -10
View File
@@ -133,6 +133,22 @@
const refresh = () => index.load().catch(() => undefined); const refresh = () => index.load().catch(() => undefined);
// What the agent did on its own that day: digests and scheduled runs.
function quietSummary(group: DayGroup): string {
const parts: string[] = [];
if (group.forks.length) {
parts.push(
`${group.forks.length} ${group.forks.length === 1 ? "digest" : "digests"}`
);
}
if (group.jobs.length) {
parts.push(
`${group.jobs.length} ${group.jobs.length === 1 ? "job run" : "job runs"}`
);
}
return parts.join(" · ");
}
const linkOf = (id: string) => href?.(id); const linkOf = (id: string) => href?.(id);
</script> </script>
@@ -294,7 +310,7 @@
{row} {row}
/> />
{/each} {/each}
{#each [...group.forks, ...group.others] as row (row.id)} {#each group.others as row (row.id)}
<Strip <Strip
{client} {client}
current={row.id === selected} current={row.id === selected}
@@ -306,28 +322,27 @@
{row} {row}
/> />
{/each} {/each}
{#if group.jobs.length > 0} {#if group.forks.length + group.jobs.length > 0}
{@const shownJobs = jobsOpen.has(group.day)} {@const shownQuiet = jobsOpen.has(group.day)}
<button <button
aria-expanded={shownJobs} aria-expanded={shownQuiet}
class="strip w-full text-left text-muted-foreground text-xs" class="strip w-full text-left text-muted-foreground text-xs"
onclick={() => toggleJobs(group.day)} onclick={() => toggleJobs(group.day)}
type="button" type="button"
> >
<span class="size-5"></span> <span class="size-5"></span>
<span> <span>
{group.jobs.length} {quietSummary(group)}
{group.jobs.length === 1 ? "job run" : "job runs"} · {shownQuiet ? "hide" : "show"}
· {shownJobs ? "hide" : "show"}
</span> </span>
<span></span> <span></span>
</button> </button>
{#if shownJobs} {#if shownQuiet}
{#each group.jobs as row (row.id)} {#each [...group.forks, ...group.jobs] as row (row.id)}
<Strip <Strip
{client} {client}
current={row.id === selected} current={row.id === selected}
detail={row.last_item?.text ?? ""} detail={row.last_item?.text ?? `${row.kind} · ${row.status}`}
href={linkOf(row.id)} href={linkOf(row.id)}
{now} {now}
onChanged={refresh} onChanged={refresh}
+1 -1
View File
@@ -129,7 +129,7 @@
<span class="tabular font-semibold text-2xl leading-none tracking-tight"> <span class="tabular font-semibold text-2xl leading-none tracking-tight">
{fmtMoney(spend)} {fmtMoney(spend)}
</span> </span>
<span class="text-muted-foreground text-xs">API-price equivalent</span> <span class="text-muted-foreground text-xs">in API price</span>
</div> </div>
{/if} {/if}
</div> </div>