Skip to content

Commit 349a36c

Browse files
committed
fix(webapp): scope smart-column sample, suppress columns in embedded tables, fix duplicate import
- Fix oxlint duplicate-import error (merge ListedRun into the existing runsRepository.server import). - Suppress URL-driven smart columns in embedded run tables that don't hydrate the source fields (schedule inspector, waitpoint, webhook) via an enableSmartColumns={false} prop, so they never render a permanently-empty column. - Scope the 'Add smart column' sample to the host page's runs: task/scheduled/agent pass their task slug, errors passes the error id (plus rootOnly=false), so the preview shows the shape of the runs the user will actually see instead of arbitrary environment runs.
1 parent 466aff4 commit 349a36c

11 files changed

Lines changed: 47 additions & 9 deletions

File tree

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ type AddSmartColumnDialogProps = {
3434
onOpenChange: (open: boolean) => void;
3535
onSubmit: (def: SmartColumnDef) => void;
3636
currentSearch: string;
37+
/**
38+
* Extra filters merged into the sample request so the preview samples the
39+
* runs the host page actually lists (e.g. its task or error), for pages that
40+
* carry that scope in the route path rather than the query string.
41+
*/
42+
sampleFilters?: Record<string, string>;
3743
};
3844

3945
const SOURCE_CARDS: { value: SmartColumnSource; label: string; description: string }[] = [
@@ -55,6 +61,7 @@ export function AddSmartColumnDialog({
5561
onOpenChange,
5662
onSubmit,
5763
currentSearch,
64+
sampleFilters,
5865
}: AddSmartColumnDialogProps) {
5966
const organization = useOrganization();
6067
const project = useProject();
@@ -78,10 +85,17 @@ export function AddSmartColumnDialog({
7885
setSampleIndex(0);
7986
}, [open, editing]);
8087

88+
const sampleFiltersKey = sampleFilters ? JSON.stringify(sampleFilters) : "";
8189
const sampleUrl = useMemo(() => {
8290
const base = `/resources/orgs/${organization.slug}/projects/${project.slug}/env/${environment.slug}/runs/smart-column-sample`;
83-
return currentSearch ? `${base}?${currentSearch.replace(/^\?/, "")}` : base;
84-
}, [organization.slug, project.slug, environment.slug, currentSearch]);
91+
const params = new URLSearchParams(currentSearch.replace(/^\?/, ""));
92+
if (sampleFilters) {
93+
for (const [key, val] of Object.entries(sampleFilters)) params.set(key, val);
94+
}
95+
const qs = params.toString();
96+
return qs ? `${base}?${qs}` : base;
97+
// eslint-disable-next-line react-hooks/exhaustive-deps
98+
}, [organization.slug, project.slug, environment.slug, currentSearch, sampleFiltersKey]);
8599

86100
useEffect(() => {
87101
if (open && sample.state === "idle") {

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ function keyFor(col: ResolvedColumn): string {
3333

3434
type SmartEditTarget = { index: number; def: SmartColumnDef };
3535

36-
export function RunsDisplayOptions() {
36+
export function RunsDisplayOptions({
37+
sampleFilters,
38+
}: {
39+
sampleFilters?: Record<string, string>;
40+
} = {}) {
3741
const environment = useEnvironment();
3842
const { isManagedCloud } = useFeatures();
3943
const location = useOptimisticLocation();
@@ -201,6 +205,7 @@ export function RunsDisplayOptions() {
201205
}}
202206
onSubmit={submitSmart}
203207
currentSearch={location.search}
208+
sampleFilters={sampleFilters}
204209
/>
205210
</>
206211
);

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

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ type RunsTableProps = {
9191
showTopBorder?: boolean;
9292
stickyHeader?: boolean;
9393
childrenStatusesBasePath?: string;
94+
/**
95+
* Whether URL-driven smart columns render here. Default true; embedded run
96+
* tables whose loader does not hydrate payload/metadata/output (schedule
97+
* inspector, waitpoint, webhook) pass false so they never show a column they
98+
* cannot fill.
99+
*/
100+
enableSmartColumns?: boolean;
94101
/**
95102
* Display-only write:runs flags from the caller's loader. Default true so
96103
* callers that don't pass them (and OSS, where the ability is permissive)
@@ -573,6 +580,7 @@ export function TaskRunsTable({
573580
showTopBorder = true,
574581
stickyHeader = false,
575582
childrenStatusesBasePath,
583+
enableSmartColumns = true,
576584
canCancelRuns = true,
577585
canReplayRuns = true,
578586
}: RunsTableProps) {
@@ -610,7 +618,10 @@ export function TaskRunsTable({
610618
// eslint-disable-next-line react-hooks/exhaustive-deps
611619
}, [colsParam, hideParam, scKey, isManagedCloud, isDevelopment]);
612620

613-
const visibleColumns = layout.visible;
621+
const visibleColumns = useMemo(
622+
() => (enableSmartColumns ? layout.visible : layout.visible.filter((c) => c.kind !== "smart")),
623+
[layout, enableSmartColumns]
624+
);
614625
const referencedSources = useMemo(() => visibleSmartSources(visibleColumns), [visibleColumns]);
615626

616627
const sourcesByRunId = useMemo(() => {

apps/webapp/app/components/schedules/ScheduleInspector.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ export function ScheduleInspector({
184184
<div className="flex flex-col gap-1">
185185
<Header3 className="pb-1 pl-3">Last 5 runs</Header3>
186186
<TaskRunsTable
187+
enableSmartColumns={false}
187188
total={schedule.runs.length}
188189
hasFilters={false}
189190
filters={{

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.agents.$agentParam/route.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ export default function Page() {
339339
</Suspense>
340340
) : (
341341
<>
342-
<RunsDisplayOptions />
342+
<RunsDisplayOptions sampleFilters={{ tasks: agent.slug, rootOnly: "false" }} />
343343
<Suspense fallback={null}>
344344
<TypedAwait resolve={runList} errorElement={null}>
345345
{(list) => (list ? <ListPagination list={list} /> : null)}

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.errors.$fingerprint/route.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,12 @@ function ErrorGroupDetail({
537537
>
538538
Bulk replay…
539539
</PermissionLink>
540-
<RunsDisplayOptions />
540+
<RunsDisplayOptions
541+
sampleFilters={{
542+
errorId: ErrorId.toFriendlyId(fingerprint),
543+
rootOnly: "false",
544+
}}
545+
/>
541546
<ListPagination list={runList} />
542547
</div>
543548
)}

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.tasks.scheduled.$taskParam/route.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ export default function Page() {
372372
onClick={() => showNewRunsRef.current()}
373373
/>
374374
) : null}
375-
<RunsDisplayOptions />
375+
<RunsDisplayOptions sampleFilters={{ tasks: task.slug, rootOnly: "false" }} />
376376
<Suspense fallback={null}>
377377
<TypedAwait resolve={runList} errorElement={null}>
378378
{(list) => (list ? <ListPagination list={list} /> : null)}

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.tasks.standard.$taskParam/route.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ export default function Page() {
269269
onClick={() => showNewRunsRef.current()}
270270
/>
271271
) : null}
272-
<RunsDisplayOptions />
272+
<RunsDisplayOptions sampleFilters={{ tasks: task.slug, rootOnly: "false" }} />
273273
<Suspense fallback={null}>
274274
<TypedAwait resolve={runList} errorElement={null}>
275275
{(list) => (list ? <ListPagination list={list} /> : null)}

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.waitpoints.tokens.$waitpointParam/route.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ export default function Page() {
136136
<InfoIconTooltip content="These runs have been blocked by this waitpoint." />
137137
</div>
138138
<TaskRunsTable
139+
enableSmartColumns={false}
139140
total={waitpoint.connectedRuns.length}
140141
hasFilters={false}
141142
filters={{

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.webhooks.$webhookParam/route.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,7 @@ function WebhookContentArea({
487487
list ? (
488488
<div className="h-full overflow-y-auto scrollbar-thin scrollbar-track-transparent scrollbar-thumb-charcoal-600">
489489
<TaskRunsTable
490+
enableSmartColumns={false}
490491
total={list.runs.length}
491492
hasFilters={list.hasFilters}
492493
filters={list.filters}

0 commit comments

Comments
 (0)