Skip to content

Commit 08734eb

Browse files
committed
polish(webapp): tighten smart-column dialog copy and display popover layout
- Trim the Add smart column dialog copy: one-line display-only callout, example-only path hint, drop redundant field helpers, remove an em dash from the sample header. - Move the sample header and run picker outside the box to match the Preview header, and collapse the doubled box into one panel. - Clear the path and label fields when the source changes. - Rework the Display popover smart-column row: labels stay flush-left, the bolt marker sits inline after the label, and the edit/remove/grip controls are a right-aligned group with larger hit targets.
1 parent 14bda31 commit 08734eb

3 files changed

Lines changed: 80 additions & 70 deletions

File tree

apps/webapp/app/components/runs/v3/AddSmartColumnDialog.tsx

Lines changed: 45 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ export function AddSmartColumnDialog({
9494
setSampleIndex(0);
9595
}, [source]);
9696

97+
const handleSourceChange = (next: SmartColumnSource) => {
98+
if (next === source) return;
99+
setSource(next);
100+
setPath("");
101+
setLabel("");
102+
setLabelEdited(false);
103+
};
104+
97105
const effectiveLabel = labelEdited ? label : labelFromPath(path);
98106

99107
const sampleLoaded = sample.data !== undefined && sample.state === "idle";
@@ -145,8 +153,7 @@ export function AddSmartColumnDialog({
145153
<DialogHeader>{editing ? "Edit smart column" : "Add smart column"}</DialogHeader>
146154
<div className="flex flex-col gap-5 p-1">
147155
<Callout variant="info">
148-
Display only. A smart column shows you a value from a run, but you can't sort or filter
149-
the list by it. To narrow the list, use tags or the query editor.
156+
Smart columns are display only. You can't sort or filter by them.
150157
</Callout>
151158

152159
<div className="grid grid-cols-1 gap-5 md:grid-cols-[minmax(0,1fr)_260px_220px]">
@@ -160,7 +167,7 @@ export function AddSmartColumnDialog({
160167
label={card.label}
161168
description={card.description}
162169
selected={source === card.value}
163-
onSelect={() => setSource(card.value)}
170+
onSelect={() => handleSourceChange(card.value)}
164171
/>
165172
))}
166173
</div>
@@ -175,10 +182,9 @@ export function AddSmartColumnDialog({
175182
placeholder="$.order.total"
176183
spellCheck={false}
177184
/>
178-
<Paragraph variant="extra-small" className="text-text-dimmed">
179-
Dot and bracket notation, e.g. <code>$.order.total</code> or{" "}
180-
<code>$.items[0].sku</code>. Use <code>.length</code> for an array, string, or
181-
key count.
185+
<Paragraph variant="extra-small" className="text-balance text-text-dimmed">
186+
e.g. <code>$.order.total</code>, <code>$.items[0].sku</code>,{" "}
187+
<code>$.items.length</code>
182188
</Paragraph>
183189
</div>
184190
<div className="flex flex-col gap-1.5">
@@ -191,9 +197,6 @@ export function AddSmartColumnDialog({
191197
}}
192198
placeholder={labelFromPath(path)}
193199
/>
194-
<Paragraph variant="extra-small" className="text-text-dimmed">
195-
Defaults to the last part of the path.
196-
</Paragraph>
197200
</div>
198201
</div>
199202

@@ -216,16 +219,12 @@ export function AddSmartColumnDialog({
216219
</button>
217220
))}
218221
</div>
219-
<Paragraph variant="extra-small" className="text-text-dimmed">
220-
Number right-aligns the column and uses tabular figures. Anything that doesn't
221-
parse falls back to text.
222-
</Paragraph>
223222
</div>
224223
</div>
225224

226-
<div className="flex flex-col gap-1.5 self-start rounded-lg border border-grid-dimmed bg-background-dimmed p-3">
227-
<div className="flex items-center justify-between gap-2">
228-
<Paragraph variant="extra-extra-small/dimmed/caps">Sample {source}</Paragraph>
225+
<div className="flex flex-col gap-1.5 self-start">
226+
<div className="flex h-5 items-center justify-between gap-2">
227+
<Paragraph variant="extra-extra-small/dimmed/caps">Sample {source}</Paragraph>
229228
{usable.length > 1 && (
230229
<SampleRunPicker
231230
index={activeIndex}
@@ -235,33 +234,37 @@ export function AddSmartColumnDialog({
235234
/>
236235
)}
237236
</div>
238-
{!sampleLoaded ? (
239-
<Paragraph variant="extra-small" className="text-text-dimmed">
240-
Loading…
241-
</Paragraph>
242-
) : activeSample ? (
243-
<SmartColumnSample
244-
value={activeSample.value}
245-
activePath={path.trim()}
246-
onSelectPath={setPath}
247-
/>
248-
) : runCount === 0 ? (
249-
<Paragraph variant="extra-small" className="text-text-dimmed">
250-
No runs to sample.
251-
</Paragraph>
252-
) : anyOffloaded ? (
253-
<Paragraph variant="extra-small" className="text-text-dimmed">
254-
Recent {source}s are offloaded to object storage, too large to sample here.
255-
</Paragraph>
256-
) : (
257-
<Paragraph variant="extra-small" className="text-text-dimmed">
258-
No recent run has a {source} value to sample.
259-
</Paragraph>
260-
)}
237+
<div className="overflow-hidden rounded-lg border border-grid-dimmed bg-charcoal-900 p-3">
238+
{!sampleLoaded ? (
239+
<Paragraph variant="extra-small" className="text-text-dimmed">
240+
Loading…
241+
</Paragraph>
242+
) : activeSample ? (
243+
<SmartColumnSample
244+
value={activeSample.value}
245+
activePath={path.trim()}
246+
onSelectPath={setPath}
247+
/>
248+
) : runCount === 0 ? (
249+
<Paragraph variant="extra-small" className="text-text-dimmed">
250+
No runs to sample yet.
251+
</Paragraph>
252+
) : anyOffloaded ? (
253+
<Paragraph variant="extra-small" className="text-text-dimmed">
254+
Recent {source}s are too large to sample here.
255+
</Paragraph>
256+
) : (
257+
<Paragraph variant="extra-small" className="text-text-dimmed">
258+
No recent run has a {source} to sample.
259+
</Paragraph>
260+
)}
261+
</div>
261262
</div>
262263

263264
<div className="flex flex-col gap-1.5 self-start">
264-
<Paragraph variant="extra-extra-small/dimmed/caps">Preview</Paragraph>
265+
<div className="flex h-5 items-center">
266+
<Paragraph variant="extra-extra-small/dimmed/caps">Preview</Paragraph>
267+
</div>
265268
<SmartColumnPreview rows={perRun} def={previewDef} loaded={sampleLoaded} />
266269
</div>
267270
</div>
@@ -377,7 +380,7 @@ function SmartColumnPreview({
377380
{!loaded ? (
378381
<div className="px-2.5 py-2 text-xs text-text-dimmed">Loading…</div>
379382
) : rows.length === 0 ? (
380-
<div className="px-2.5 py-2 text-xs text-text-dimmed">No runs</div>
383+
<div className="px-2.5 py-2 text-xs text-text-dimmed">No runs yet</div>
381384
) : (
382385
rows.map((row, index) => {
383386
const cell = def.path

apps/webapp/app/components/runs/v3/RunsDisplayOptions.tsx

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ function ColumnRow({
199199
col,
200200
checked,
201201
locked,
202+
reserveIcon,
202203
dragging,
203204
isOver,
204205
onToggle,
@@ -227,7 +228,7 @@ function ColumnRow({
227228
return (
228229
<div
229230
className={cn(
230-
"group relative flex h-8 items-center gap-2 px-3 transition-colors hover:bg-charcoal-750",
231+
"group relative flex h-8 items-center gap-2 pl-3 pr-1.5 transition-colors hover:bg-charcoal-750",
231232
dragging && "opacity-40"
232233
)}
233234
draggable
@@ -239,33 +240,39 @@ function ColumnRow({
239240
>
240241
{isOver && <div className="absolute inset-x-0 top-0 h-0.5 bg-blue-500" />}
241242
{locked ? <Checkbox checked disabled /> : <Checkbox checked={checked} onChange={onToggle} />}
242-
{isSmart && <BoltIcon className="size-4 flex-none text-text-dimmed" />}
243-
<span
244-
className={cn("flex-1 truncate text-sm", checked ? "text-text-bright" : "text-text-dimmed")}
245-
>
246-
{col.def.label}
247-
</span>
248-
{onEdit && (
249-
<button
250-
type="button"
251-
onClick={onEdit}
252-
aria-label={`Edit ${col.def.label}`}
253-
className="flex size-5 items-center justify-center rounded text-text-dimmed opacity-0 transition hover:text-text-bright focus-custom group-hover:opacity-100"
254-
>
255-
<PencilSquareIcon className="size-3.5" />
256-
</button>
257-
)}
258-
{onRemove && (
259-
<button
260-
type="button"
261-
onClick={onRemove}
262-
aria-label={`Remove ${col.def.label}`}
263-
className="flex size-5 items-center justify-center rounded text-text-dimmed opacity-0 transition hover:text-error focus-custom group-hover:opacity-100"
243+
<span className="flex min-w-0 flex-1 items-center gap-1.5">
244+
<span
245+
className={cn("truncate text-sm", checked ? "text-text-bright" : "text-text-dimmed")}
264246
>
265-
<XMarkIcon className="size-3.5" />
266-
</button>
267-
)}
268-
<GripVerticalIcon className="size-4 flex-none cursor-grab text-text-dimmed opacity-0 transition group-hover:opacity-100 active:cursor-grabbing" />
247+
{col.def.label}
248+
</span>
249+
{isSmart && <BoltIcon className="size-3.5 flex-none text-text-dimmed" />}
250+
</span>
251+
<div className="flex flex-none items-center gap-0.5">
252+
{onEdit && (
253+
<button
254+
type="button"
255+
onClick={onEdit}
256+
aria-label={`Edit ${col.def.label}`}
257+
className="flex size-6 items-center justify-center rounded text-text-dimmed opacity-0 transition hover:bg-charcoal-700 hover:text-text-bright focus-custom group-hover:opacity-100"
258+
>
259+
<PencilSquareIcon className="size-4" />
260+
</button>
261+
)}
262+
{onRemove && (
263+
<button
264+
type="button"
265+
onClick={onRemove}
266+
aria-label={`Remove ${col.def.label}`}
267+
className="flex size-6 items-center justify-center rounded text-text-dimmed opacity-0 transition hover:bg-charcoal-700 hover:text-error focus-custom group-hover:opacity-100"
268+
>
269+
<XMarkIcon className="size-4" />
270+
</button>
271+
)}
272+
<span className="flex size-6 cursor-grab items-center justify-center text-text-dimmed opacity-0 transition group-hover:opacity-100 active:cursor-grabbing">
273+
<GripVerticalIcon className="size-4" />
274+
</span>
275+
</div>
269276
</div>
270277
);
271278
}

apps/webapp/app/components/runs/v3/SmartColumnSample.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export function SmartColumnSample({
2020
onSelectPath: (path: string) => void;
2121
}) {
2222
return (
23-
<div className="max-h-80 overflow-auto rounded bg-charcoal-900 p-2 font-mono text-xs leading-relaxed scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
23+
<div className="max-h-80 overflow-auto font-mono text-xs leading-relaxed scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
2424
<JsonNode
2525
name={undefined}
2626
path="$"

0 commit comments

Comments
 (0)