refactor(ui): dedupe usage session rows

This commit is contained in:
Peter Steinberger
2026-02-15 20:59:13 +00:00
parent 02ff9f43ea
commit 4920ca65db
2 changed files with 74 additions and 153 deletions

View File

@@ -500,35 +500,39 @@ function renderObject(params: {
const additional = schema.additionalProperties;
const allowExtra = Boolean(additional) && typeof additional === "object";
const fields = html`
${sorted.map(([propKey, node]) =>
renderNode({
schema: node,
value: obj[propKey],
path: [...path, propKey],
hints,
unsupported,
disabled,
onPatch,
}),
)}
${
allowExtra
? renderMapField({
schema: additional,
value: obj,
path,
hints,
unsupported,
disabled,
reservedKeys: reserved,
onPatch,
})
: nothing
}
`;
// For top-level, don't wrap in collapsible
if (path.length === 1) {
return html`
<div class="cfg-fields">
${sorted.map(([propKey, node]) =>
renderNode({
schema: node,
value: obj[propKey],
path: [...path, propKey],
hints,
unsupported,
disabled,
onPatch,
}),
)}
${
allowExtra
? renderMapField({
schema: additional,
value: obj,
path,
hints,
unsupported,
disabled,
reservedKeys: reserved,
onPatch,
})
: nothing
}
${fields}
</div>
`;
}
@@ -542,31 +546,7 @@ function renderObject(params: {
</summary>
${help ? html`<div class="cfg-object__help">${help}</div>` : nothing}
<div class="cfg-object__content">
${sorted.map(([propKey, node]) =>
renderNode({
schema: node,
value: obj[propKey],
path: [...path, propKey],
hints,
unsupported,
disabled,
onPatch,
}),
)}
${
allowExtra
? renderMapField({
schema: additional,
value: obj,
path,
hints,
unsupported,
disabled,
reservedKeys: reserved,
onPatch,
})
: nothing
}
${fields}
</div>
</details>
`;

View File

@@ -649,6 +649,38 @@ function renderSessionsCard(
0,
);
const renderSessionBarRow = (s: UsageSessionEntry, isSelected: boolean) => {
const value = getSessionValue(s);
const displayLabel = formatSessionListLabel(s);
const meta = buildSessionMeta(s);
return html`
<div
class="session-bar-row ${isSelected ? "selected" : ""}"
@click=${(e: MouseEvent) => onSelectSession(s.key, e.shiftKey)}
title="${s.key}"
>
<div class="session-bar-label">
<div class="session-bar-title">${displayLabel}</div>
${meta.length > 0 ? html`<div class="session-bar-meta">${meta.join(" · ")}</div>` : nothing}
</div>
<div class="session-bar-track" style="display: none;"></div>
<div class="session-bar-actions">
<button
class="session-copy-btn"
title="Copy session name"
@click=${(e: MouseEvent) => {
e.stopPropagation();
void copySessionName(s);
}}
>
Copy
</button>
<div class="session-bar-value">${isTokenMode ? formatTokens(value) : formatCost(value)}</div>
</div>
</div>
`;
};
const selectedSet = new Set(selectedSessions);
const selectedEntries = sortedWithDir.filter((s) => selectedSet.has(s.key));
const selectedCount = selectedEntries.length;
@@ -720,83 +752,22 @@ function renderSessionsCard(
<div class="muted" style="padding: 20px; text-align: center">No recent sessions</div>
`
: html`
<div class="session-bars" style="max-height: 220px; margin-top: 6px;">
${recentEntries.map((s) => {
const value = getSessionValue(s);
const isSelected = selectedSet.has(s.key);
const displayLabel = formatSessionListLabel(s);
const meta = buildSessionMeta(s);
return html`
<div
class="session-bar-row ${isSelected ? "selected" : ""}"
@click=${(e: MouseEvent) => onSelectSession(s.key, e.shiftKey)}
title="${s.key}"
>
<div class="session-bar-label">
<div class="session-bar-title">${displayLabel}</div>
${meta.length > 0 ? html`<div class="session-bar-meta">${meta.join(" · ")}</div>` : nothing}
</div>
<div class="session-bar-track" style="display: none;"></div>
<div class="session-bar-actions">
<button
class="session-copy-btn"
title="Copy session name"
@click=${(e: MouseEvent) => {
e.stopPropagation();
void copySessionName(s);
}}
>
Copy
</button>
<div class="session-bar-value">${isTokenMode ? formatTokens(value) : formatCost(value)}</div>
</div>
</div>
`;
})}
</div>
`
<div class="session-bars" style="max-height: 220px; margin-top: 6px;">
${recentEntries.map((s) => renderSessionBarRow(s, selectedSet.has(s.key)))}
</div>
`
: sessions.length === 0
? html`
<div class="muted" style="padding: 20px; text-align: center">No sessions in range</div>
`
: html`
<div class="session-bars">
${sortedWithDir.slice(0, 50).map((s) => {
const value = getSessionValue(s);
const isSelected = selectedSessions.includes(s.key);
const displayLabel = formatSessionListLabel(s);
const meta = buildSessionMeta(s);
return html`
<div
class="session-bar-row ${isSelected ? "selected" : ""}"
@click=${(e: MouseEvent) => onSelectSession(s.key, e.shiftKey)}
title="${s.key}"
>
<div class="session-bar-label">
<div class="session-bar-title">${displayLabel}</div>
${meta.length > 0 ? html`<div class="session-bar-meta">${meta.join(" · ")}</div>` : nothing}
</div>
<div class="session-bar-track" style="display: none;"></div>
<div class="session-bar-actions">
<button
class="session-copy-btn"
title="Copy session name"
@click=${(e: MouseEvent) => {
e.stopPropagation();
void copySessionName(s);
}}
>
Copy
</button>
<div class="session-bar-value">${isTokenMode ? formatTokens(value) : formatCost(value)}</div>
</div>
</div>
`;
})}
${sessions.length > 50 ? html`<div class="muted" style="padding: 8px; text-align: center; font-size: 11px;">+${sessions.length - 50} more</div>` : nothing}
</div>
`
<div class="session-bars">
${sortedWithDir
.slice(0, 50)
.map((s) => renderSessionBarRow(s, selectedSet.has(s.key)))}
${sessions.length > 50 ? html`<div class="muted" style="padding: 8px; text-align: center; font-size: 11px;">+${sessions.length - 50} more</div>` : nothing}
</div>
`
}
${
selectedCount > 1
@@ -804,37 +775,7 @@ function renderSessionsCard(
<div style="margin-top: 10px;">
<div class="sessions-card-count">Selected (${selectedCount})</div>
<div class="session-bars" style="max-height: 160px; margin-top: 6px;">
${selectedEntries.map((s) => {
const value = getSessionValue(s);
const displayLabel = formatSessionListLabel(s);
const meta = buildSessionMeta(s);
return html`
<div
class="session-bar-row selected"
@click=${(e: MouseEvent) => onSelectSession(s.key, e.shiftKey)}
title="${s.key}"
>
<div class="session-bar-label">
<div class="session-bar-title">${displayLabel}</div>
${meta.length > 0 ? html`<div class="session-bar-meta">${meta.join(" · ")}</div>` : nothing}
</div>
<div class="session-bar-track" style="display: none;"></div>
<div class="session-bar-actions">
<button
class="session-copy-btn"
title="Copy session name"
@click=${(e: MouseEvent) => {
e.stopPropagation();
void copySessionName(s);
}}
>
Copy
</button>
<div class="session-bar-value">${isTokenMode ? formatTokens(value) : formatCost(value)}</div>
</div>
</div>
`;
})}
${selectedEntries.map((s) => renderSessionBarRow(s, true))}
</div>
</div>
`