mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
fix(site): inline dl/dt/dd classNames and use justify-between layout in session tables (#24118)
When we refactored into definition lists for tables, we lost the ability to have the rows extend beyond the vertical line between `<dt>` and `<dd>` This adds a wrapping `<div>` to make each row independent, which is [a-ok per MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/dl#wrapping_name-value_groups_in_div_elements), an also is implied in the Figma: <img width="477" height="182" alt="Screenshot 2026-04-07 at 4 29 14 PM" src="https://github.com/user-attachments/assets/524acfc3-c614-479e-9a13-36107c158ee8" /> --- Before <img width="420" height="266" alt="Screenshot 2026-04-07 at 4 24 22 PM" src="https://github.com/user-attachments/assets/7001c17c-05da-4f90-b6d4-a9c6cab695cb" /> After <img width="410" height="355" alt="Screenshot 2026-04-07 at 4 24 36 PM" src="https://github.com/user-attachments/assets/3d1d278d-0080-44be-8d32-bb5dff879969" />
This commit is contained in:
@@ -3,7 +3,6 @@ import { Avatar } from "#/components/Avatar/Avatar";
|
||||
import { Badge } from "#/components/Badge/Badge";
|
||||
import { AIBridgeClientIcon } from "#/pages/AIBridgePage/RequestLogsPage/icons/AIBridgeClientIcon";
|
||||
import { AIBridgeProviderIcon } from "#/pages/AIBridgePage/RequestLogsPage/icons/AIBridgeProviderIcon";
|
||||
import { cn } from "#/utils/cn";
|
||||
import { formatDateTime } from "#/utils/time";
|
||||
import { TokenBadges } from "../TokenBadges";
|
||||
import { getProviderDisplayName, getProviderIconName } from "../utils";
|
||||
@@ -43,105 +42,130 @@ export const SessionSummaryTable = ({
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<dl
|
||||
className={cn(
|
||||
"text-sm text-content-secondary m-0 whitespace-nowrap",
|
||||
"grid grid-cols-[auto_1fr] gap-y-2 [&_dd]:ml-0 [&_dd]:text-content-primary",
|
||||
"[&_dd]:h-6 [&_dd]:flex [&_dd]:min-w-0 [&_dd]:items-center [&_dd]:justify-end",
|
||||
"[&_dt]:h-6 [&_dt]:inline-flex [&_dt]:items-center [&_dt]:font-normal",
|
||||
)}
|
||||
>
|
||||
<dt>Session ID</dt>
|
||||
<dd className="text-xs font-mono min-w-0" title={sessionId}>
|
||||
<span className="truncate w-full text-right">{sessionId}</span>
|
||||
</dd>
|
||||
<dl className="text-sm text-content-secondary m-0 flex flex-col gap-y-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<dt className="shrink-0 font-normal whitespace-nowrap">Session ID</dt>
|
||||
<dd
|
||||
className="ml-4 min-w-0 truncate text-content-primary text-xs font-mono"
|
||||
title={sessionId}
|
||||
>
|
||||
{sessionId}
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<dt>Start time</dt>
|
||||
<dd className="text-xs font-mono" title={formatDateTime(startTime)}>
|
||||
{formatDateTime(startTime)}
|
||||
</dd>
|
||||
<div className="flex items-center justify-between">
|
||||
<dt className="shrink-0 font-normal whitespace-nowrap">Start time</dt>
|
||||
<dd
|
||||
className="ml-4 min-w-0 truncate text-content-primary text-xs font-mono"
|
||||
title={formatDateTime(startTime)}
|
||||
>
|
||||
{formatDateTime(startTime)}
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<dt>End time</dt>
|
||||
<dd className="text-xs font-mono">
|
||||
{endTime ? formatDateTime(endTime) : "—"}
|
||||
</dd>
|
||||
<div className="flex items-center justify-between">
|
||||
<dt className="shrink-0 font-normal whitespace-nowrap">End time</dt>
|
||||
<dd className="ml-4 min-w-0 truncate text-content-primary text-xs font-mono">
|
||||
{endTime ? formatDateTime(endTime) : "—"}
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<dt>Duration</dt>
|
||||
<dd
|
||||
className="text-xs font-mono"
|
||||
title={durationInMs !== undefined ? `${durationInMs} ms` : undefined}
|
||||
>
|
||||
{durationInMs !== undefined
|
||||
? `${Math.round(durationInMs / 1000)} s`
|
||||
: "—"}
|
||||
</dd>
|
||||
<div className="flex items-center justify-between">
|
||||
<dt className="shrink-0 font-normal whitespace-nowrap">Duration</dt>
|
||||
<dd
|
||||
className="ml-4 min-w-0 truncate text-content-primary text-xs font-mono"
|
||||
title={durationInMs !== undefined ? `${durationInMs} ms` : undefined}
|
||||
>
|
||||
{durationInMs !== undefined
|
||||
? `${Math.round(durationInMs / 1000)} s`
|
||||
: "—"}
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<dt>Initiator</dt>
|
||||
<dd>
|
||||
<div className="flex w-full min-w-0 items-center justify-end gap-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<dt className="shrink-0 font-normal whitespace-nowrap">Initiator</dt>
|
||||
<dd className="ml-4 min-w-0 truncate text-content-primary flex items-center gap-2">
|
||||
<Avatar
|
||||
size="sm"
|
||||
src={initiator.avatar_url}
|
||||
fallback={initiator.name}
|
||||
/>
|
||||
<span className="truncate min-w-0 text-right" title={initiator.name}>
|
||||
<span className="truncate min-w-0" title={initiator.name}>
|
||||
{initiator.name}
|
||||
</span>
|
||||
</div>
|
||||
</dd>
|
||||
|
||||
<dt>Client</dt>
|
||||
<dd>
|
||||
<Badge className="gap-1.5 max-w-full min-w-0 overflow-hidden">
|
||||
<div className="flex-shrink-0 flex items-center">
|
||||
<AIBridgeClientIcon client={client} className="size-icon-xs" />
|
||||
</div>
|
||||
<span className="truncate min-w-0 flex-1" title={client ?? "Unknown"}>
|
||||
{client ?? "Unknown"}
|
||||
</span>
|
||||
</Badge>
|
||||
</dd>
|
||||
|
||||
<dt className="self-start">Provider</dt>
|
||||
<dd>
|
||||
{providers.map((p) => (
|
||||
<Badge key={p} className="gap-1.5 max-w-full min-w-0 overflow-hidden">
|
||||
<AIBridgeProviderIcon
|
||||
provider={getProviderIconName(p)}
|
||||
className="size-icon-xs"
|
||||
/>
|
||||
<span
|
||||
className="truncate min-w-0 flex-1"
|
||||
title={getProviderDisplayName(p)}
|
||||
>
|
||||
{getProviderDisplayName(p)}
|
||||
</span>
|
||||
</Badge>
|
||||
))}
|
||||
</dd>
|
||||
|
||||
<div className="col-span-2">
|
||||
<Separator />
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<dt>In / out tokens</dt>
|
||||
<dd>
|
||||
<TokenBadges
|
||||
inputTokens={inputTokens}
|
||||
outputTokens={outputTokens}
|
||||
tokenUsageMetadata={tokenUsageMetadata}
|
||||
/>
|
||||
</dd>
|
||||
<div className="flex items-center justify-between">
|
||||
<dt className="shrink-0 font-normal whitespace-nowrap">Client</dt>
|
||||
<dd className="ml-4 min-w-0 truncate text-content-primary">
|
||||
<Badge className="gap-1.5 max-w-full min-w-0 overflow-hidden">
|
||||
<div className="flex-shrink-0 flex items-center">
|
||||
<AIBridgeClientIcon client={client} className="size-icon-xs" />
|
||||
</div>
|
||||
<span
|
||||
className="truncate min-w-0 flex-1"
|
||||
title={client ?? "Unknown"}
|
||||
>
|
||||
{client ?? "Unknown"}
|
||||
</span>
|
||||
</Badge>
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<dt>Threads</dt>
|
||||
<dd>
|
||||
<Badge>{threadCount}</Badge>
|
||||
</dd>
|
||||
<div className="flex items-start justify-between">
|
||||
<dt className="shrink-0 font-normal whitespace-nowrap mt-1">
|
||||
Provider
|
||||
</dt>
|
||||
<dd className="ml-4 min-w-0 truncate text-content-primary flex flex-wrap gap-1">
|
||||
{providers.map((p) => (
|
||||
<Badge
|
||||
key={p}
|
||||
className="gap-1.5 max-w-full min-w-0 overflow-hidden"
|
||||
>
|
||||
<AIBridgeProviderIcon
|
||||
provider={getProviderIconName(p)}
|
||||
className="size-icon-xs"
|
||||
/>
|
||||
<span
|
||||
className="truncate min-w-0 flex-1"
|
||||
title={getProviderDisplayName(p)}
|
||||
>
|
||||
{getProviderDisplayName(p)}
|
||||
</span>
|
||||
</Badge>
|
||||
))}
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<dt>Tool calls</dt>
|
||||
<dd>
|
||||
<Badge>{toolCallCount}</Badge>
|
||||
</dd>
|
||||
<Separator />
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<dt className="shrink-0 font-normal whitespace-nowrap">
|
||||
In / out tokens
|
||||
</dt>
|
||||
<dd className="ml-4 min-w-0 truncate text-content-primary">
|
||||
<TokenBadges
|
||||
inputTokens={inputTokens}
|
||||
outputTokens={outputTokens}
|
||||
tokenUsageMetadata={tokenUsageMetadata}
|
||||
/>
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<dt className="shrink-0 font-normal whitespace-nowrap">Threads</dt>
|
||||
<dd className="ml-4 min-w-0 truncate text-content-primary">
|
||||
<Badge>{threadCount}</Badge>
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<dt className="shrink-0 font-normal whitespace-nowrap">Tool calls</dt>
|
||||
<dd className="ml-4 min-w-0 truncate text-content-primary">
|
||||
<Badge>{toolCallCount}</Badge>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -31,46 +31,47 @@ export const PromptTable: FC<PromptTableProps> = ({
|
||||
return (
|
||||
<dl
|
||||
className={cn(
|
||||
"text-sm text-content-secondary font-normal m-0 grid grid-cols-[auto_1fr] gap-x-4 gap-y-2 items-center",
|
||||
"[&_dt]:whitespace-nowrap py-1",
|
||||
"[&_dt]:pr-4 [&_dt]:flex [&_dt]:items-center [&_dt]:h-6",
|
||||
"[&_dd]:m-0 [&_dd]:min-w-0 [&_dd]:h-6",
|
||||
"text-sm text-content-secondary font-normal m-0 flex flex-col gap-y-2 py-1",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<dt>Timestamp</dt>
|
||||
<dd
|
||||
className="text-right flex items-center justify-end"
|
||||
title={formatDate(timestamp)}
|
||||
>
|
||||
<span className="block font-mono text-xs whitespace-nowrap truncate">
|
||||
<div className="flex items-center justify-between">
|
||||
<dt className="shrink-0 whitespace-nowrap">Timestamp</dt>
|
||||
<dd
|
||||
className="ml-4 min-w-0 truncate font-mono text-xs"
|
||||
title={formatDate(timestamp)}
|
||||
>
|
||||
{formatDate(timestamp)}
|
||||
</span>
|
||||
</dd>
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<dt>Model</dt>
|
||||
<dd className="flex justify-end">
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Badge className="gap-1.5 max-w-full min-w-0 overflow-hidden">
|
||||
<AIBridgeModelIcon model={model} className="size-icon-xs" />
|
||||
<span className="truncate min-w-0 flex-1">{model}</span>
|
||||
</Badge>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{model}</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</dd>
|
||||
<div className="flex items-center justify-between">
|
||||
<dt className="shrink-0 whitespace-nowrap">Model</dt>
|
||||
<dd className="ml-4 min-w-0 truncate flex justify-end">
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Badge className="gap-1.5 max-w-full min-w-0 overflow-hidden">
|
||||
<AIBridgeModelIcon model={model} className="size-icon-xs" />
|
||||
<span className="truncate min-w-0 flex-1">{model}</span>
|
||||
</Badge>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{model}</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<dt>In / out tokens</dt>
|
||||
<dd className="flex justify-end">
|
||||
<TokenBadges
|
||||
inputTokens={inputTokens}
|
||||
outputTokens={outputTokens}
|
||||
tokenUsageMetadata={tokenUsageMetadata}
|
||||
/>
|
||||
</dd>
|
||||
<div className="flex items-center justify-between">
|
||||
<dt className="shrink-0 whitespace-nowrap">In / out tokens</dt>
|
||||
<dd className="ml-4 min-w-0 truncate flex justify-end">
|
||||
<TokenBadges
|
||||
inputTokens={inputTokens}
|
||||
outputTokens={outputTokens}
|
||||
tokenUsageMetadata={tokenUsageMetadata}
|
||||
/>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -29,7 +29,7 @@ export const ToolCallTable: FC<ToolCallTableProps> = ({
|
||||
)}
|
||||
>
|
||||
<div className="flex items-center justify-between whitespace-nowrap">
|
||||
<span className="pr-4">In / out tokens</span>
|
||||
<span className="pr-4 whitespace-nowrap">In / out tokens</span>
|
||||
<TokenBadges
|
||||
inputTokens={inputTokens}
|
||||
outputTokens={outputTokens}
|
||||
@@ -37,7 +37,7 @@ export const ToolCallTable: FC<ToolCallTableProps> = ({
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="pr-4">Started at</span>
|
||||
<span className="pr-4 whitespace-nowrap">Started at</span>
|
||||
<span
|
||||
className="font-mono text-xs whitespace-nowrap truncate"
|
||||
title={formatDate(timestamp)}
|
||||
@@ -47,7 +47,7 @@ export const ToolCallTable: FC<ToolCallTableProps> = ({
|
||||
</div>
|
||||
{serverURL && (
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="pr-4">MCP server</span>
|
||||
<span className="pr-4 whitespace-nowrap">MCP server</span>
|
||||
<span className="font-mono truncate">{serverURL}</span>
|
||||
<CopyButton text={serverURL} label="Copy MCP server URL" />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user