@shipfox/client-workflows 20.0.0 → 22.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +51 -0
- package/dist/components/job-detail/job-detail-view.d.ts.map +1 -1
- package/dist/components/job-detail/job-detail-view.js +232 -44
- package/dist/components/job-detail/job-detail-view.js.map +1 -1
- package/dist/components/job-detail/job-empty-states.js +2 -2
- package/dist/components/job-detail/job-empty-states.js.map +1 -1
- package/dist/components/job-detail/step-attempt-log-panel.d.ts +7 -1
- package/dist/components/job-detail/step-attempt-log-panel.d.ts.map +1 -1
- package/dist/components/job-detail/step-attempt-log-panel.js +37 -10
- package/dist/components/job-detail/step-attempt-log-panel.js.map +1 -1
- package/dist/components/job-graph/job-graph-content.js +2 -2
- package/dist/components/job-graph/job-graph-content.js.map +1 -1
- package/dist/components/step-list/step-list-model.d.ts +1 -0
- package/dist/components/step-list/step-list-model.d.ts.map +1 -1
- package/dist/components/step-list/step-list-model.js +1 -1
- package/dist/components/step-list/step-list-model.js.map +1 -1
- package/dist/components/step-list/step-list.d.ts +2 -1
- package/dist/components/step-list/step-list.d.ts.map +1 -1
- package/dist/components/step-list/step-list.js +25 -9
- package/dist/components/step-list/step-list.js.map +1 -1
- package/dist/components/workflow-run-list/job-status-strip.d.ts +9 -1
- package/dist/components/workflow-run-list/job-status-strip.d.ts.map +1 -1
- package/dist/components/workflow-run-list/job-status-strip.js +22 -11
- package/dist/components/workflow-run-list/job-status-strip.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-filters.js +1 -1
- package/dist/components/workflow-run-list/workflow-run-filters.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-content.d.ts.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-content.js +13 -7
- package/dist/components/workflow-run-list/workflow-run-list-content.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-states.d.ts.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-states.js +43 -38
- package/dist/components/workflow-run-list/workflow-run-list-states.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-view.d.ts.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-list-view.js +34 -22
- package/dist/components/workflow-run-list/workflow-run-list-view.js.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-row.d.ts +3 -3
- package/dist/components/workflow-run-list/workflow-run-row.d.ts.map +1 -1
- package/dist/components/workflow-run-list/workflow-run-row.js +25 -18
- package/dist/components/workflow-run-list/workflow-run-row.js.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.d.ts.map +1 -1
- package/dist/components/workflow-run-summary/workflow-run-summary.js +4 -4
- package/dist/components/workflow-run-summary/workflow-run-summary.js.map +1 -1
- package/dist/components/workflow-run-view/run-workspace-nav.d.ts.map +1 -1
- package/dist/components/workflow-run-view/run-workspace-nav.js +20 -7
- package/dist/components/workflow-run-view/run-workspace-nav.js.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-states.d.ts.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-states.js +1 -1
- package/dist/components/workflow-run-view/workflow-run-states.js.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-view.d.ts.map +1 -1
- package/dist/components/workflow-run-view/workflow-run-view.js +103 -78
- package/dist/components/workflow-run-view/workflow-run-view.js.map +1 -1
- package/dist/components/workflow-source-panel/workflow-source-content.js +1 -1
- package/dist/components/workflow-source-panel/workflow-source-content.js.map +1 -1
- package/dist/pages/project-workflows-page.d.ts.map +1 -1
- package/dist/pages/project-workflows-page.js +171 -158
- package/dist/pages/project-workflows-page.js.map +1 -1
- package/dist/pages/workflow-job-detail-page.d.ts.map +1 -1
- package/dist/pages/workflow-job-detail-page.js +3 -2
- package/dist/pages/workflow-job-detail-page.js.map +1 -1
- package/dist/pages/workflow-run-detail-page.js +2 -1
- package/dist/pages/workflow-run-detail-page.js.map +1 -1
- package/dist/pages/workflow-run-list-page.d.ts.map +1 -1
- package/dist/pages/workflow-run-list-page.js +9 -11
- package/dist/pages/workflow-run-list-page.js.map +1 -1
- package/dist/routes/job-detail.d.ts +1 -1
- package/dist/routes/job-detail.js +1 -1
- package/dist/routes/job-detail.js.map +1 -1
- package/dist/routes/run-detail.d.ts +1 -1
- package/dist/routes/run-detail.js +1 -1
- package/dist/routes/run-detail.js.map +1 -1
- package/dist/routes/runs.d.ts +1 -1
- package/dist/routes/runs.js +1 -1
- package/dist/routes/runs.js.map +1 -1
- package/dist/routes/workflows.d.ts +3 -0
- package/dist/routes/workflows.js +3 -0
- package/dist/routes/workflows.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/src/components/job-detail/job-detail-view.tsx +264 -49
- package/src/components/job-detail/job-empty-states.tsx +2 -2
- package/src/components/job-detail/step-attempt-log-panel.test.tsx +30 -12
- package/src/components/job-detail/step-attempt-log-panel.tsx +68 -10
- package/src/components/job-graph/job-graph-content.tsx +2 -2
- package/src/components/job-graph/job-graph.stories.tsx +1 -1
- package/src/components/job-graph/job-node.stories.tsx +1 -1
- package/src/components/step-list/step-list-model.ts +1 -1
- package/src/components/step-list/step-list.test.tsx +29 -1
- package/src/components/step-list/step-list.tsx +29 -11
- package/src/components/workflow-run-list/job-status-strip.tsx +25 -12
- package/src/components/workflow-run-list/workflow-run-filters.tsx +1 -1
- package/src/components/workflow-run-list/workflow-run-list-content.tsx +7 -2
- package/src/components/workflow-run-list/workflow-run-list-states.tsx +42 -41
- package/src/components/workflow-run-list/workflow-run-list-view.test.tsx +53 -4
- package/src/components/workflow-run-list/workflow-run-list-view.tsx +28 -22
- package/src/components/workflow-run-list/workflow-run-list.stories.tsx +9 -20
- package/src/components/workflow-run-list/workflow-run-row.tsx +26 -19
- package/src/components/workflow-run-summary/workflow-run-summary.stories.tsx +3 -3
- package/src/components/workflow-run-summary/workflow-run-summary.test.tsx +11 -2
- package/src/components/workflow-run-summary/workflow-run-summary.tsx +4 -7
- package/src/components/workflow-run-view/run-workspace-nav.test.tsx +40 -2
- package/src/components/workflow-run-view/run-workspace-nav.tsx +28 -9
- package/src/components/workflow-run-view/workflow-run-states.tsx +1 -4
- package/src/components/workflow-run-view/workflow-run-view.stories.tsx +142 -0
- package/src/components/workflow-run-view/workflow-run-view.test.tsx +42 -8
- package/src/components/workflow-run-view/workflow-run-view.tsx +112 -96
- package/src/components/workflow-source-panel/workflow-source-content.tsx +2 -2
- package/src/pages/project-workflows-page.tsx +135 -125
- package/src/pages/workflow-job-detail-page.test.tsx +32 -0
- package/src/pages/workflow-job-detail-page.tsx +5 -1
- package/src/pages/workflow-run-detail-page.tsx +1 -1
- package/src/pages/workflow-run-list-page.tsx +9 -11
- package/src/pages/workflow-run-pages.test.tsx +26 -0
- package/src/routes/job-detail.tsx +1 -1
- package/src/routes/run-detail.tsx +1 -1
- package/src/routes/runs.tsx +1 -1
- package/src/routes/workflows.tsx +1 -0
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { ApiError } from '@shipfox/client-api';
|
|
3
3
|
import { QueryLoadError } from '@shipfox/client-ui';
|
|
4
4
|
import { EmptyState } from '@shipfox/react-ui/empty-state';
|
|
5
|
+
import { Panel, PanelBody, PanelHeader } from '@shipfox/react-ui/panel';
|
|
5
6
|
import { RelativeTimeProvider } from '@shipfox/react-ui/relative-time';
|
|
6
7
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@shipfox/react-ui/select';
|
|
7
8
|
import { toast } from '@shipfox/react-ui/toast';
|
|
@@ -214,42 +215,46 @@ function RunViewContent({ workspaceSlug, projectSlug, query, annotations, rerunM
|
|
|
214
215
|
runData && query.isError ? /*#__PURE__*/ _jsx(WorkflowRunStaleError, {
|
|
215
216
|
query: query
|
|
216
217
|
}) : null,
|
|
217
|
-
/*#__PURE__*/
|
|
218
|
+
/*#__PURE__*/ _jsx("div", {
|
|
218
219
|
"data-run-workspace-layout": true,
|
|
219
|
-
className: "flex min-h-0 min-w-0 flex-1 flex-col border-t border-border-neutral-base
|
|
220
|
-
children:
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
activeSection: activeSection,
|
|
226
|
-
currentJobId: activeJobId,
|
|
227
|
-
jobSearch: jobSearch,
|
|
228
|
-
annotationSummary: annotationSummary
|
|
229
|
-
}) : /*#__PURE__*/ _jsx(RunWorkspaceNavSkeleton, {}),
|
|
230
|
-
/*#__PURE__*/ _jsx("div", {
|
|
231
|
-
"data-run-workspace-content": true,
|
|
232
|
-
className: "flex min-h-0 min-w-0 flex-1 flex-col bg-background-neutral-base",
|
|
233
|
-
children: runData && jobContent ? jobContent : runData ? /*#__PURE__*/ _jsx(RunSectionContent, {
|
|
234
|
-
section: activeSection,
|
|
235
|
-
run: runData,
|
|
236
|
-
annotations: annotations,
|
|
237
|
-
annotationSummary: annotationSummary,
|
|
220
|
+
className: "flex min-h-0 min-w-0 flex-1 flex-col border-t border-border-neutral-base",
|
|
221
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
222
|
+
"data-run-workspace-frame": true,
|
|
223
|
+
className: "flex min-h-0 min-w-0 w-full flex-1 flex-col min-[768px]:flex-row",
|
|
224
|
+
children: [
|
|
225
|
+
runData && workspaceSlug && projectSlug ? /*#__PURE__*/ _jsx(RunWorkspaceNav, {
|
|
238
226
|
workspaceSlug: workspaceSlug,
|
|
239
227
|
projectSlug: projectSlug,
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
className: "min-h-0 flex-1
|
|
249
|
-
children:
|
|
228
|
+
run: runData,
|
|
229
|
+
activeSection: activeSection,
|
|
230
|
+
currentJobId: activeJobId,
|
|
231
|
+
jobSearch: jobSearch,
|
|
232
|
+
annotationSummary: annotationSummary
|
|
233
|
+
}) : /*#__PURE__*/ _jsx(RunWorkspaceNavSkeleton, {}),
|
|
234
|
+
/*#__PURE__*/ _jsx("div", {
|
|
235
|
+
"data-run-workspace-content": true,
|
|
236
|
+
className: "flex min-h-0 min-w-0 flex-1 flex-col",
|
|
237
|
+
children: runData && jobContent ? jobContent : runData ? /*#__PURE__*/ _jsx(RunSectionContent, {
|
|
238
|
+
section: activeSection,
|
|
239
|
+
run: runData,
|
|
240
|
+
annotations: annotations,
|
|
241
|
+
annotationSummary: annotationSummary,
|
|
242
|
+
workspaceSlug: workspaceSlug,
|
|
243
|
+
projectSlug: projectSlug,
|
|
244
|
+
selection: selection,
|
|
245
|
+
selectedJobId: selection?.jobId,
|
|
246
|
+
onSelectGraphJob: selectGraphJob,
|
|
247
|
+
onSelectAnnotationJob: selectAnnotationJob,
|
|
248
|
+
onClearAnnotationFilters: clearAnnotationFilters,
|
|
249
|
+
sourceSnapshot: sourceSnapshot,
|
|
250
|
+
highlightedLineRange: highlightedLineRange
|
|
251
|
+
}) : /*#__PURE__*/ _jsx("div", {
|
|
252
|
+
className: "min-h-0 flex-1 overflow-auto p-panel",
|
|
253
|
+
children: loadingOrError
|
|
254
|
+
})
|
|
250
255
|
})
|
|
251
|
-
|
|
252
|
-
|
|
256
|
+
]
|
|
257
|
+
})
|
|
253
258
|
})
|
|
254
259
|
]
|
|
255
260
|
});
|
|
@@ -260,18 +265,24 @@ function RunSectionContent({ section, run, annotations, annotationSummary, works
|
|
|
260
265
|
"aria-label": "All jobs summary",
|
|
261
266
|
className: "min-h-0 flex-1 overflow-auto pb-panel pt-[16px]",
|
|
262
267
|
children: /*#__PURE__*/ _jsxs("div", {
|
|
263
|
-
className: "
|
|
268
|
+
className: "flex w-full flex-col gap-group",
|
|
264
269
|
children: [
|
|
265
270
|
/*#__PURE__*/ _jsx(Text, {
|
|
266
271
|
as: "h2",
|
|
267
272
|
className: "sr-only",
|
|
268
273
|
children: "All jobs summary"
|
|
269
274
|
}),
|
|
270
|
-
/*#__PURE__*/ _jsx(
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
+
/*#__PURE__*/ _jsx(Panel, {
|
|
276
|
+
className: "min-h-160",
|
|
277
|
+
children: /*#__PURE__*/ _jsx(PanelBody, {
|
|
278
|
+
className: "min-h-160 bg-background-components-base p-0",
|
|
279
|
+
children: /*#__PURE__*/ _jsx(JobGraph, {
|
|
280
|
+
run: run,
|
|
281
|
+
selectedJobId: selectedJobId,
|
|
282
|
+
onSelectedJobChange: onSelectGraphJob,
|
|
283
|
+
className: "min-h-160 overflow-hidden"
|
|
284
|
+
})
|
|
285
|
+
})
|
|
275
286
|
})
|
|
276
287
|
]
|
|
277
288
|
})
|
|
@@ -294,22 +305,29 @@ function RunSectionContent({ section, run, annotations, annotationSummary, works
|
|
|
294
305
|
"aria-label": "Workflow source",
|
|
295
306
|
className: "min-h-0 flex-1 overflow-auto pb-panel pt-[16px]",
|
|
296
307
|
children: /*#__PURE__*/ _jsxs("div", {
|
|
297
|
-
className: "
|
|
308
|
+
className: "flex min-h-full w-full flex-col",
|
|
298
309
|
children: [
|
|
299
310
|
/*#__PURE__*/ _jsx(Text, {
|
|
300
311
|
as: "h2",
|
|
301
312
|
className: "sr-only",
|
|
302
313
|
children: "Workflow source"
|
|
303
314
|
}),
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
315
|
+
/*#__PURE__*/ _jsx(Panel, {
|
|
316
|
+
className: "min-h-160 flex-1",
|
|
317
|
+
children: /*#__PURE__*/ _jsx(PanelBody, {
|
|
318
|
+
className: "min-h-160 flex-1 p-0",
|
|
319
|
+
children: sourceSnapshot ? /*#__PURE__*/ _jsx(WorkflowSourceContent, {
|
|
320
|
+
source: sourceSnapshot,
|
|
321
|
+
highlightedLineRange: highlightedLineRange,
|
|
322
|
+
scrollHighlightedIntoView: true
|
|
323
|
+
}) : /*#__PURE__*/ _jsx(EmptyState, {
|
|
324
|
+
variant: "panel",
|
|
325
|
+
className: "min-h-160",
|
|
326
|
+
icon: "fileDamageLine",
|
|
327
|
+
title: "Source snapshot unavailable",
|
|
328
|
+
description: run.isTemporary ? 'Temporary runs do not capture workflow source.' : 'This run was created before workflow source snapshots were captured.'
|
|
329
|
+
})
|
|
330
|
+
})
|
|
313
331
|
})
|
|
314
332
|
]
|
|
315
333
|
})
|
|
@@ -352,45 +370,52 @@ function RunAnnotationsSection({ run, annotations, annotationSummary, workspaceS
|
|
|
352
370
|
"aria-label": "Run annotations",
|
|
353
371
|
className: "min-h-0 flex-1 overflow-auto pb-panel pt-[16px]",
|
|
354
372
|
children: /*#__PURE__*/ _jsxs("div", {
|
|
355
|
-
className: "
|
|
373
|
+
className: "flex w-full flex-col",
|
|
356
374
|
children: [
|
|
357
375
|
/*#__PURE__*/ _jsx(Text, {
|
|
358
376
|
as: "h2",
|
|
359
377
|
className: "sr-only",
|
|
360
378
|
children: "Annotations"
|
|
361
379
|
}),
|
|
362
|
-
/*#__PURE__*/ _jsxs(
|
|
363
|
-
className: "flex flex-wrap items-center justify-between gap-inline",
|
|
380
|
+
/*#__PURE__*/ _jsxs(Panel, {
|
|
364
381
|
children: [
|
|
365
|
-
/*#__PURE__*/
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
382
|
+
/*#__PURE__*/ _jsxs(PanelHeader, {
|
|
383
|
+
className: "flex-wrap",
|
|
384
|
+
children: [
|
|
385
|
+
/*#__PURE__*/ _jsx(RunAnnotationSummaryLine, {
|
|
386
|
+
summary: annotationSummary,
|
|
387
|
+
workspaceSlug: workspaceSlug,
|
|
388
|
+
projectSlug: projectSlug,
|
|
389
|
+
workflowRunId: run.id,
|
|
390
|
+
search: selection
|
|
391
|
+
}),
|
|
392
|
+
/*#__PURE__*/ _jsx(AnnotationJobFilter, {
|
|
393
|
+
jobs: run.jobs,
|
|
394
|
+
selectedJobId: selectedJob?.id,
|
|
395
|
+
onSelect: onSelectAnnotationJob
|
|
396
|
+
})
|
|
397
|
+
]
|
|
371
398
|
}),
|
|
372
|
-
/*#__PURE__*/ _jsx(
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
399
|
+
/*#__PURE__*/ _jsx(PanelBody, {
|
|
400
|
+
className: "gap-group p-panel",
|
|
401
|
+
children: /*#__PURE__*/ _jsx(RunAnnotationList, {
|
|
402
|
+
query: annotations.query,
|
|
403
|
+
entries: entries,
|
|
404
|
+
derivedAnnotations: derivedAnnotations,
|
|
405
|
+
workspaceSlug: workspaceSlug,
|
|
406
|
+
projectSlug: projectSlug,
|
|
407
|
+
workflowRunId: run.id,
|
|
408
|
+
runAttempt: run.runAttempt.attempt,
|
|
409
|
+
// A run with no annotations at all offers no filter to clear, whatever the URL says.
|
|
410
|
+
filtered: Boolean((severity || selectedJob || selection?.annotation) && ((annotationSummary?.total ?? 0) > 0 || hasSynthesizedJobAnnotations)),
|
|
411
|
+
filteredJobName: selectedJob?.displayName,
|
|
412
|
+
filteredSeverity: severity,
|
|
413
|
+
onClearFilters: onClearAnnotationFilters,
|
|
414
|
+
selectedAnnotationId: selection?.annotation
|
|
415
|
+
}, `${run.id}:${run.runAttempt.attempt}:${severity ?? 'all'}:${selectedJob?.id ?? 'all'}`)
|
|
376
416
|
})
|
|
377
417
|
]
|
|
378
|
-
})
|
|
379
|
-
/*#__PURE__*/ _jsx(RunAnnotationList, {
|
|
380
|
-
query: annotations.query,
|
|
381
|
-
entries: entries,
|
|
382
|
-
derivedAnnotations: derivedAnnotations,
|
|
383
|
-
workspaceSlug: workspaceSlug,
|
|
384
|
-
projectSlug: projectSlug,
|
|
385
|
-
workflowRunId: run.id,
|
|
386
|
-
runAttempt: run.runAttempt.attempt,
|
|
387
|
-
// A run with no annotations at all offers no filter to clear, whatever the URL says.
|
|
388
|
-
filtered: Boolean((severity || selectedJob || selection?.annotation) && ((annotationSummary?.total ?? 0) > 0 || hasSynthesizedJobAnnotations)),
|
|
389
|
-
filteredJobName: selectedJob?.displayName,
|
|
390
|
-
filteredSeverity: severity,
|
|
391
|
-
onClearFilters: onClearAnnotationFilters,
|
|
392
|
-
selectedAnnotationId: selection?.annotation
|
|
393
|
-
}, `${run.id}:${run.runAttempt.attempt}:${severity ?? 'all'}:${selectedJob?.id ?? 'all'}`)
|
|
418
|
+
})
|
|
394
419
|
]
|
|
395
420
|
})
|
|
396
421
|
});
|
|
@@ -470,7 +495,7 @@ function AnnotationJobFilter({ jobs, selectedJobId, onSelect }) {
|
|
|
470
495
|
function RunWorkspaceNavSkeleton() {
|
|
471
496
|
return /*#__PURE__*/ _jsx("aside", {
|
|
472
497
|
"aria-label": "Loading run navigation",
|
|
473
|
-
className: "hidden w-240 shrink-0
|
|
498
|
+
className: "hidden w-240 shrink-0 p-panel-compact min-[768px]:block",
|
|
474
499
|
children: /*#__PURE__*/ _jsxs("div", {
|
|
475
500
|
className: "flex flex-col gap-group",
|
|
476
501
|
children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/workflow-run-view/workflow-run-view.tsx"],"sourcesContent":["import {ApiError} from '@shipfox/client-api';\nimport {QueryLoadError} from '@shipfox/client-ui';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {RelativeTimeProvider} from '@shipfox/react-ui/relative-time';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@shipfox/react-ui/select';\nimport {toast} from '@shipfox/react-ui/toast';\nimport {Text} from '@shipfox/react-ui/typography';\nimport {useNavigate} from '@tanstack/react-router';\nimport {type ReactNode, useEffect, useMemo} from 'react';\nimport {buildRunAnnotationList, type RunAnnotationSummary} from '#core/run-annotation.js';\nimport {\n type EvaluationTraceEntry,\n isWorkflowRunTerminal,\n type Job,\n type WorkflowRunRerunMode,\n} from '#core/workflow-run.js';\nimport {withoutWorkflowRunSelectionSearch} from '#core/workflow-run-url-state.js';\nimport {useRunAnnotationsQuery} from '#hooks/api/run-annotations.js';\nimport {\n useCancelWorkflowRunMutation,\n useRerunWorkflowRunMutation,\n useWorkflowRunAttemptQuery,\n} from '#hooks/api/workflow-runs.js';\nimport {\n type WorkflowJobSearch,\n type WorkflowRunsSearch,\n type WorkflowRunTab,\n workflowJobSearchParams,\n workflowRunSearchParams,\n} from '#routes/inputs.js';\nimport {JobGraph} from '../job-graph/index.js';\nimport type {JobGraphSelectionSource} from '../job-graph/types.js';\nimport {WorkflowRunSummary} from '../workflow-run-summary/index.js';\nimport {\n type DerivedRunAnnotation,\n RunAnnotationList,\n RunAnnotationSummaryLine,\n} from '../workflow-run-tabs/index.js';\nimport {WorkflowSourceContent} from '../workflow-source-panel/index.js';\nimport {RunWorkspaceNav} from './run-workspace-nav.js';\nimport {resolveWorkflowRunSelection} from './workflow-run-selection.js';\nimport {\n WorkflowRunContentSkeleton,\n WorkflowRunNotFound,\n WorkflowRunSkeleton,\n WorkflowRunStaleError,\n} from './workflow-run-states.js';\n\ntype RunWorkspaceSection = Exclude<WorkflowRunTab, 'jobs'>;\n\nexport interface WorkflowRunViewProps {\n projectId: string;\n workspaceSlug?: string | undefined;\n projectSlug?: string | undefined;\n workflowRunId?: string | undefined;\n runAttempt?: number | undefined;\n selection?: WorkflowRunsSearch | undefined;\n tab?: WorkflowRunTab | undefined;\n activeJobId?: string | undefined;\n jobSearch?: WorkflowJobSearch | undefined;\n jobContent?: ReactNode | undefined;\n}\n\n/**\n * The persistent run workspace. Run-level sections and dedicated job routes share the same\n * header and job index, while the all-jobs Summary always opens on the dependency graph.\n */\nexport function WorkflowRunView({\n projectId,\n workspaceSlug,\n projectSlug,\n workflowRunId,\n runAttempt,\n selection,\n tab,\n activeJobId,\n jobSearch,\n jobContent,\n}: WorkflowRunViewProps) {\n const runQuery = useWorkflowRunAttemptQuery({\n workflowRunId,\n runAttempt: selection?.runAttempt ?? runAttempt,\n });\n const rerunMutation = useRerunWorkflowRunMutation(projectId);\n // Annotations are read on their own cadence rather than hydrated into the run, so the two\n // modules stay decoupled. The key is shared, so the job page's count chip costs no extra fetch.\n //\n // Polling is scoped to the surface that renders bodies. The read has no counts-only mode, so\n // every poll transfers whole Markdown bodies; doing that every four seconds behind Summary,\n // Source, and the job log spends megabytes to keep one rail number warm. Off that surface the\n // counts still refresh on navigation and on window focus.\n const annotationsQuery = useRunAnnotationsQuery({\n workflowRunId,\n runAttempt: runQuery.data?.runAttempt.attempt,\n live:\n runWorkspaceSection(tab) === 'annotations' &&\n !activeJobId &&\n Boolean(runQuery.data) &&\n !isWorkflowRunTerminal(runQuery.data?.runAttempt.status ?? 'pending'),\n });\n\n return (\n <RelativeTimeProvider>\n <div className=\"flex min-h-0 min-w-0 flex-1 overflow-hidden\">\n <RunViewContent\n workspaceSlug={workspaceSlug}\n projectSlug={projectSlug}\n query={runQuery}\n annotations={annotationsQuery}\n rerunMutation={rerunMutation}\n runAttempt={runAttempt}\n selection={selection}\n tab={tab}\n activeJobId={activeJobId}\n jobSearch={jobSearch}\n jobContent={jobContent}\n />\n </div>\n </RelativeTimeProvider>\n );\n}\n\nfunction RunViewContent({\n workspaceSlug,\n projectSlug,\n query,\n annotations,\n rerunMutation,\n runAttempt,\n selection,\n tab,\n activeJobId,\n jobSearch,\n jobContent,\n}: {\n workspaceSlug: string | undefined;\n projectSlug: string | undefined;\n query: ReturnType<typeof useWorkflowRunAttemptQuery>;\n annotations: ReturnType<typeof useRunAnnotationsQuery>;\n rerunMutation: ReturnType<typeof useRerunWorkflowRunMutation>;\n runAttempt: number | undefined;\n selection: WorkflowRunsSearch | undefined;\n tab: WorkflowRunTab | undefined;\n activeJobId: string | undefined;\n jobSearch: WorkflowJobSearch | undefined;\n jobContent: ReactNode | undefined;\n}) {\n const navigate = useNavigate();\n const runData = query.data;\n const annotationSummary = annotations.summary;\n const activeSection = runWorkspaceSection(tab);\n const cancelMutation = useCancelWorkflowRunMutation(runData);\n const sourceSnapshot = runData?.sourceSnapshot ?? null;\n const resolvedSelection =\n runData && selection ? resolveWorkflowRunSelection({run: runData, selection}) : undefined;\n const highlightedLineRange = resolvedSelection?.step?.sourceLocation ?? null;\n\n useEffect(() => {\n const hasLegacyJobSelection = Boolean(\n selection?.jobId ||\n selection?.jobExecutionId ||\n selection?.stepId ||\n selection?.stepAttemptId,\n );\n if (\n activeJobId ||\n activeSection !== 'summary' ||\n !hasLegacyJobSelection ||\n !resolvedSelection?.job ||\n !runData ||\n !workspaceSlug ||\n !projectSlug\n ) {\n return;\n }\n\n void navigate({\n to: '/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId/jobs/$jobId',\n params: {\n workspaceSlug,\n projectSlug,\n workflowRunId: runData.id,\n jobId: resolvedSelection.job.id,\n },\n search: workflowJobSearchParams({\n jobExecutionId: selection?.jobExecutionId,\n stepId: selection?.stepId,\n stepAttemptId: selection?.stepAttemptId,\n runAttempt: selection?.runAttempt,\n }) as never,\n replace: true,\n });\n }, [\n activeJobId,\n activeSection,\n navigate,\n projectSlug,\n resolvedSelection?.job,\n runData,\n selection,\n workspaceSlug,\n ]);\n\n async function rerun(mode: WorkflowRunRerunMode) {\n if (!runData || !workspaceSlug || !projectSlug) {\n toast.error('Could not start re-run from this route.');\n return;\n }\n try {\n const run = await rerunMutation.mutateAsync({workflowRunId: runData.id, mode});\n toast.success('Re-run started');\n await navigate({\n to: '/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId',\n params: {workspaceSlug, projectSlug, workflowRunId: run.id},\n search: ((previous: Record<string, unknown>) =>\n withoutWorkflowRunSelectionSearch(previous)) as never,\n });\n } catch (error) {\n toast.error(error instanceof ApiError ? error.message : 'Could not start re-run');\n }\n }\n\n function selectGraphJob(jobId: string | undefined, source: JobGraphSelectionSource = 'pointer') {\n if (source !== 'pointer' || !jobId || !runData || !workspaceSlug || !projectSlug) return;\n\n void navigate({\n to: '/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId/jobs/$jobId',\n params: {workspaceSlug, projectSlug, workflowRunId: runData.id, jobId},\n search: workflowJobSearchParams({\n runAttempt: selection?.runAttempt ?? runAttempt ?? runData.runAttempt.attempt,\n }) as never,\n });\n }\n\n function selectAnnotationJob(jobId: string | undefined) {\n if (!runData || !workspaceSlug || !projectSlug) return;\n const nextSearch: WorkflowRunsSearch = {...selection, tab: 'annotations'};\n if (jobId) nextSearch.jobId = jobId;\n else delete nextSearch.jobId;\n delete nextSearch.jobExecutionId;\n delete nextSearch.stepId;\n delete nextSearch.stepAttemptId;\n\n void navigate({\n to: '/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId',\n params: {workspaceSlug, projectSlug, workflowRunId: runData.id},\n search: workflowRunSearchParams(nextSearch, nextSearch) as never,\n });\n }\n\n function clearAnnotationFilters() {\n if (!runData || !workspaceSlug || !projectSlug) return;\n const nextSearch: WorkflowRunsSearch = {...selection, tab: 'annotations'};\n delete nextSearch.jobId;\n delete nextSearch.jobExecutionId;\n delete nextSearch.stepId;\n delete nextSearch.stepAttemptId;\n delete nextSearch.severity;\n delete nextSearch.annotation;\n\n void navigate({\n to: '/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId',\n params: {workspaceSlug, projectSlug, workflowRunId: runData.id},\n search: workflowRunSearchParams(nextSearch, nextSearch) as never,\n replace: true,\n });\n }\n\n function cancelRun() {\n cancelMutation.mutate(undefined, {\n onError: (error) => toast.error(cancelErrorMessage(error)),\n });\n }\n\n const fatalError = query.isError && runData === undefined;\n const loadingOrError = fatalError ? (\n query.error instanceof ApiError && query.error.status === 404 ? (\n <WorkflowRunNotFound />\n ) : (\n <QueryLoadError query={query} subject=\"workflow run\" icon=\"pulseLine\" />\n )\n ) : query.isPending || runData === undefined ? (\n <WorkflowRunContentSkeleton />\n ) : null;\n\n return (\n <div className=\"flex min-h-0 min-w-0 flex-1 flex-col\">\n {runData ? (\n <WorkflowRunSummary\n workspaceSlug={workspaceSlug}\n projectSlug={projectSlug}\n run={runData}\n cancelling={cancelMutation.isPending}\n onCancel={cancelRun}\n rerunPending={rerunMutation.isPending}\n onRerun={(mode) => void rerun(mode)}\n latestAttempt={runData.latestAttempt}\n />\n ) : (\n <WorkflowRunSkeleton />\n )}\n {runData && query.isError ? <WorkflowRunStaleError query={query} /> : null}\n\n <div\n data-run-workspace-layout\n className=\"flex min-h-0 min-w-0 flex-1 flex-col border-t border-border-neutral-base min-[768px]:flex-row\"\n >\n {runData && workspaceSlug && projectSlug ? (\n <RunWorkspaceNav\n workspaceSlug={workspaceSlug}\n projectSlug={projectSlug}\n run={runData}\n activeSection={activeSection}\n currentJobId={activeJobId}\n jobSearch={jobSearch}\n annotationSummary={annotationSummary}\n />\n ) : (\n <RunWorkspaceNavSkeleton />\n )}\n\n <div\n data-run-workspace-content\n className=\"flex min-h-0 min-w-0 flex-1 flex-col bg-background-neutral-base\"\n >\n {runData && jobContent ? (\n jobContent\n ) : runData ? (\n <RunSectionContent\n section={activeSection}\n run={runData}\n annotations={annotations}\n annotationSummary={annotationSummary}\n workspaceSlug={workspaceSlug}\n projectSlug={projectSlug}\n selection={selection}\n selectedJobId={selection?.jobId}\n onSelectGraphJob={selectGraphJob}\n onSelectAnnotationJob={selectAnnotationJob}\n onClearAnnotationFilters={clearAnnotationFilters}\n sourceSnapshot={sourceSnapshot}\n highlightedLineRange={highlightedLineRange}\n />\n ) : (\n <div className=\"min-h-0 flex-1 overflow-auto p-panel\">{loadingOrError}</div>\n )}\n </div>\n </div>\n </div>\n );\n}\n\nfunction RunSectionContent({\n section,\n run,\n annotations,\n annotationSummary,\n workspaceSlug,\n projectSlug,\n selection,\n selectedJobId,\n onSelectGraphJob,\n onSelectAnnotationJob,\n onClearAnnotationFilters,\n sourceSnapshot,\n highlightedLineRange,\n}: {\n section: RunWorkspaceSection;\n run: NonNullable<ReturnType<typeof useWorkflowRunAttemptQuery>['data']>;\n annotations: ReturnType<typeof useRunAnnotationsQuery>;\n annotationSummary: RunAnnotationSummary | undefined;\n workspaceSlug: string | undefined;\n projectSlug: string | undefined;\n selection: WorkflowRunsSearch | undefined;\n selectedJobId: string | undefined;\n onSelectGraphJob: (jobId: string | undefined, source?: JobGraphSelectionSource) => void;\n onSelectAnnotationJob: (jobId: string | undefined) => void;\n onClearAnnotationFilters: () => void;\n sourceSnapshot: NonNullable<\n ReturnType<typeof useWorkflowRunAttemptQuery>['data']\n >['sourceSnapshot'];\n highlightedLineRange: NonNullable<\n ReturnType<typeof useWorkflowRunAttemptQuery>['data']\n >['jobs'][number]['jobExecutions'][number]['steps'][number]['sourceLocation'];\n}) {\n if (section === 'summary') {\n return (\n <section\n aria-label=\"All jobs summary\"\n className=\"min-h-0 flex-1 overflow-auto pb-panel pt-[16px]\"\n >\n <div className=\"mx-auto flex w-full max-w-[1120px] flex-col gap-group px-frame\">\n <Text as=\"h2\" className=\"sr-only\">\n All jobs summary\n </Text>\n <JobGraph\n run={run}\n selectedJobId={selectedJobId}\n onSelectedJobChange={onSelectGraphJob}\n className=\"min-h-160 overflow-hidden\"\n />\n </div>\n </section>\n );\n }\n\n if (section === 'annotations') {\n return (\n <RunAnnotationsSection\n run={run}\n annotations={annotations}\n annotationSummary={annotationSummary}\n workspaceSlug={workspaceSlug}\n projectSlug={projectSlug}\n selection={selection}\n selectedJobId={selectedJobId}\n onSelectAnnotationJob={onSelectAnnotationJob}\n onClearAnnotationFilters={onClearAnnotationFilters}\n />\n );\n }\n\n return (\n <section\n aria-label=\"Workflow source\"\n className=\"min-h-0 flex-1 overflow-auto pb-panel pt-[16px]\"\n >\n <div className=\"mx-auto flex min-h-full w-full max-w-[1120px] flex-col px-frame\">\n <Text as=\"h2\" className=\"sr-only\">\n Workflow source\n </Text>\n {sourceSnapshot ? (\n <WorkflowSourceContent\n source={sourceSnapshot}\n highlightedLineRange={highlightedLineRange}\n scrollHighlightedIntoView\n />\n ) : (\n <EmptyState\n className=\"min-h-160 w-full\"\n icon=\"fileDamageLine\"\n title=\"Source snapshot unavailable\"\n description={\n run.isTemporary\n ? 'Temporary runs do not capture workflow source.'\n : 'This run was created before workflow source snapshots were captured.'\n }\n />\n )}\n </div>\n </section>\n );\n}\n\nfunction RunAnnotationsSection({\n run,\n annotations,\n annotationSummary,\n workspaceSlug,\n projectSlug,\n selection,\n selectedJobId,\n onSelectAnnotationJob,\n onClearAnnotationFilters,\n}: {\n run: NonNullable<ReturnType<typeof useWorkflowRunAttemptQuery>['data']>;\n annotations: ReturnType<typeof useRunAnnotationsQuery>;\n annotationSummary: RunAnnotationSummary | undefined;\n workspaceSlug: string | undefined;\n projectSlug: string | undefined;\n selection: WorkflowRunsSearch | undefined;\n selectedJobId: string | undefined;\n onSelectAnnotationJob: (jobId: string | undefined) => void;\n onClearAnnotationFilters: () => void;\n}) {\n const selectedJob = run.jobs.find((job) => job.id === selectedJobId);\n const severity = selection?.severity;\n const records = annotations.annotations;\n\n const entries = useMemo(\n () =>\n records\n ? buildRunAnnotationList({\n annotations: records,\n jobs: run.jobs,\n severity,\n jobId: selectedJob?.id,\n })\n : undefined,\n [records, run.jobs, selectedJob?.id, severity],\n );\n const derivedAnnotations = useMemo<readonly DerivedRunAnnotation[] | undefined>(() => {\n if (!records) return undefined;\n const jobsWithAnnotations = new Set(records.map((annotation) => annotation.jobId));\n\n return run.jobs\n .filter((job) => {\n const style = job.status === 'failed' ? 'error' : 'warning';\n return (\n (!selectedJob || selectedJob.id === job.id) &&\n !jobsWithAnnotations.has(job.id) &&\n (job.status === 'failed' || job.status === 'skipped') &&\n job.jobExecutions.length === 0 &&\n matchesDerivedAnnotationFilters(style, selection)\n );\n })\n .map((job) => ({\n id: `derived-${job.id}`,\n style: job.status === 'failed' ? 'error' : 'warning',\n body: derivedJobAnnotation(job),\n }));\n }, [records, run.jobs, selectedJob, selection]);\n const hasSynthesizedJobAnnotations = run.jobs.some(\n (job) =>\n (job.status === 'failed' || job.status === 'skipped') && job.jobExecutions.length === 0,\n );\n\n return (\n <section\n aria-label=\"Run annotations\"\n className=\"min-h-0 flex-1 overflow-auto pb-panel pt-[16px]\"\n >\n <div className=\"mx-auto flex w-full max-w-[1120px] flex-col gap-group px-frame\">\n <Text as=\"h2\" className=\"sr-only\">\n Annotations\n </Text>\n <div className=\"flex flex-wrap items-center justify-between gap-inline\">\n <RunAnnotationSummaryLine\n summary={annotationSummary}\n workspaceSlug={workspaceSlug}\n projectSlug={projectSlug}\n workflowRunId={run.id}\n search={selection}\n />\n <AnnotationJobFilter\n jobs={run.jobs}\n selectedJobId={selectedJob?.id}\n onSelect={onSelectAnnotationJob}\n />\n </div>\n <RunAnnotationList\n // Remounting on a filter or run-attempt change resets the render window, so the next\n // list never inherits a \"show more\" position from different data.\n key={`${run.id}:${run.runAttempt.attempt}:${severity ?? 'all'}:${selectedJob?.id ?? 'all'}`}\n query={annotations.query}\n entries={entries}\n derivedAnnotations={derivedAnnotations}\n workspaceSlug={workspaceSlug}\n projectSlug={projectSlug}\n workflowRunId={run.id}\n runAttempt={run.runAttempt.attempt}\n // A run with no annotations at all offers no filter to clear, whatever the URL says.\n filtered={Boolean(\n (severity || selectedJob || selection?.annotation) &&\n ((annotationSummary?.total ?? 0) > 0 || hasSynthesizedJobAnnotations),\n )}\n filteredJobName={selectedJob?.displayName}\n filteredSeverity={severity}\n onClearFilters={onClearAnnotationFilters}\n selectedAnnotationId={selection?.annotation}\n />\n </div>\n </section>\n );\n}\n\nfunction matchesDerivedAnnotationFilters(\n style: 'warning' | 'error',\n selection: WorkflowRunsSearch | undefined,\n): boolean {\n if (selection?.severity && style !== selection.severity) return false;\n // A selected annotation is a deep-link to a real annotation record. Synthetic diagnostics\n // have no id or context, so they must not remain visible behind that selection.\n return !selection?.annotation;\n}\n\nfunction derivedJobAnnotation(job: Job): string {\n const reason = job.statusReason ? `Reason: \\`${job.statusReason}\\`` : null;\n const traceSummary = formatConditionEvaluation(job.evaluationTrace);\n const details = [reason, traceSummary].filter(Boolean).join('\\n');\n\n if (job.status === 'skipped') {\n return [\n `**${job.displayName}** was skipped before an execution was created.`,\n '',\n 'Review its dependencies or condition before re-running.',\n details,\n ]\n .filter(Boolean)\n .join('\\n');\n }\n return [\n `**${job.displayName}** failed before an execution was created.`,\n '',\n 'Check runner availability and workflow configuration before re-running.',\n details,\n ]\n .filter(Boolean)\n .join('\\n');\n}\n\nfunction formatConditionEvaluation(\n trace: readonly EvaluationTraceEntry[] | null | undefined,\n): string | null {\n if (!trace?.length) return null;\n\n return [\n 'Condition evaluation:',\n ...trace.map((entry) => {\n if ('dropped' in entry) {\n return `- ${entry.dropped} additional evaluation${entry.dropped === 1 ? '' : 's'} not recorded`;\n }\n const value =\n entry.value === undefined || entry.value === '' ? '(empty)' : `\\`${entry.value}\\``;\n return `- \\`${entry.field}\\` evaluated \\`${entry.expression}\\` to ${value}${entry.degraded ? ' (degraded)' : ''}`;\n }),\n ].join('\\n');\n}\n\nconst ALL_ANNOTATION_JOBS = 'all-jobs';\n\nfunction AnnotationJobFilter({\n jobs,\n selectedJobId,\n onSelect,\n}: {\n jobs: Job[];\n selectedJobId: string | undefined;\n onSelect: (jobId: string | undefined) => void;\n}) {\n const sortedJobs = [...jobs].sort(\n (left, right) => left.position - right.position || left.id.localeCompare(right.id),\n );\n\n return (\n <Select\n value={selectedJobId ?? ALL_ANNOTATION_JOBS}\n onValueChange={(value) => onSelect(value === ALL_ANNOTATION_JOBS ? undefined : value)}\n >\n <SelectTrigger\n size=\"small\"\n aria-label=\"Filter annotations by job\"\n className=\"w-full min-[480px]:w-240\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent align=\"end\">\n <SelectItem value={ALL_ANNOTATION_JOBS}>All jobs</SelectItem>\n {sortedJobs.map((job) => (\n <SelectItem key={job.id} value={job.id}>\n {job.displayName}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n}\n\nfunction RunWorkspaceNavSkeleton() {\n return (\n <aside\n aria-label=\"Loading run navigation\"\n className=\"hidden w-240 shrink-0 border-r border-border-neutral-base bg-background-neutral-background p-panel-compact min-[768px]:block\"\n >\n <div className=\"flex flex-col gap-group\">\n <div className=\"h-32 rounded-4 bg-background-components-subtle\" />\n <div className=\"flex flex-col gap-inline\">\n <div className=\"h-16 w-64 rounded-4 bg-background-components-subtle\" />\n <div className=\"h-32 rounded-4 bg-background-components-subtle\" />\n <div className=\"h-32 rounded-4 bg-background-components-subtle\" />\n </div>\n </div>\n </aside>\n );\n}\n\nfunction runWorkspaceSection(tab: WorkflowRunTab | undefined): RunWorkspaceSection {\n return tab === 'annotations' || tab === 'source' ? tab : 'summary';\n}\n\nfunction cancelErrorMessage(error: unknown): string {\n if (error instanceof ApiError && error.code === 'run-already-finished') {\n return 'This workflow run has already finished.';\n }\n return 'Could not cancel workflow run.';\n}\n"],"names":["ApiError","QueryLoadError","EmptyState","RelativeTimeProvider","Select","SelectContent","SelectItem","SelectTrigger","SelectValue","toast","Text","useNavigate","useEffect","useMemo","buildRunAnnotationList","isWorkflowRunTerminal","withoutWorkflowRunSelectionSearch","useRunAnnotationsQuery","useCancelWorkflowRunMutation","useRerunWorkflowRunMutation","useWorkflowRunAttemptQuery","workflowJobSearchParams","workflowRunSearchParams","JobGraph","WorkflowRunSummary","RunAnnotationList","RunAnnotationSummaryLine","WorkflowSourceContent","RunWorkspaceNav","resolveWorkflowRunSelection","WorkflowRunContentSkeleton","WorkflowRunNotFound","WorkflowRunSkeleton","WorkflowRunStaleError","WorkflowRunView","projectId","workspaceSlug","projectSlug","workflowRunId","runAttempt","selection","tab","activeJobId","jobSearch","jobContent","runQuery","rerunMutation","annotationsQuery","data","attempt","live","runWorkspaceSection","Boolean","status","div","className","RunViewContent","query","annotations","navigate","runData","annotationSummary","summary","activeSection","cancelMutation","sourceSnapshot","resolvedSelection","run","undefined","highlightedLineRange","step","sourceLocation","hasLegacyJobSelection","jobId","jobExecutionId","stepId","stepAttemptId","job","to","params","id","search","replace","rerun","mode","error","mutateAsync","success","previous","message","selectGraphJob","source","selectAnnotationJob","nextSearch","clearAnnotationFilters","severity","annotation","cancelRun","mutate","onError","cancelErrorMessage","fatalError","isError","loadingOrError","subject","icon","isPending","cancelling","onCancel","rerunPending","onRerun","latestAttempt","data-run-workspace-layout","currentJobId","RunWorkspaceNavSkeleton","data-run-workspace-content","RunSectionContent","section","selectedJobId","onSelectGraphJob","onSelectAnnotationJob","onClearAnnotationFilters","aria-label","as","onSelectedJobChange","RunAnnotationsSection","scrollHighlightedIntoView","title","description","isTemporary","selectedJob","jobs","find","records","entries","derivedAnnotations","jobsWithAnnotations","Set","map","filter","style","has","jobExecutions","length","matchesDerivedAnnotationFilters","body","derivedJobAnnotation","hasSynthesizedJobAnnotations","some","AnnotationJobFilter","onSelect","filtered","total","filteredJobName","displayName","filteredSeverity","onClearFilters","selectedAnnotationId","reason","statusReason","traceSummary","formatConditionEvaluation","evaluationTrace","details","join","trace","entry","dropped","value","field","expression","degraded","ALL_ANNOTATION_JOBS","sortedJobs","sort","left","right","position","localeCompare","onValueChange","size","align","aside","code"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-run-view/workflow-run-view.tsx"],"sourcesContent":["import {ApiError} from '@shipfox/client-api';\nimport {QueryLoadError} from '@shipfox/client-ui';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {Panel, PanelBody, PanelHeader} from '@shipfox/react-ui/panel';\nimport {RelativeTimeProvider} from '@shipfox/react-ui/relative-time';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@shipfox/react-ui/select';\nimport {toast} from '@shipfox/react-ui/toast';\nimport {Text} from '@shipfox/react-ui/typography';\nimport {useNavigate} from '@tanstack/react-router';\nimport {type ReactNode, useEffect, useMemo} from 'react';\nimport {buildRunAnnotationList, type RunAnnotationSummary} from '#core/run-annotation.js';\nimport {\n type EvaluationTraceEntry,\n isWorkflowRunTerminal,\n type Job,\n type WorkflowRunRerunMode,\n} from '#core/workflow-run.js';\nimport {withoutWorkflowRunSelectionSearch} from '#core/workflow-run-url-state.js';\nimport {useRunAnnotationsQuery} from '#hooks/api/run-annotations.js';\nimport {\n useCancelWorkflowRunMutation,\n useRerunWorkflowRunMutation,\n useWorkflowRunAttemptQuery,\n} from '#hooks/api/workflow-runs.js';\nimport {\n type WorkflowJobSearch,\n type WorkflowRunsSearch,\n type WorkflowRunTab,\n workflowJobSearchParams,\n workflowRunSearchParams,\n} from '#routes/inputs.js';\nimport {JobGraph} from '../job-graph/index.js';\nimport type {JobGraphSelectionSource} from '../job-graph/types.js';\nimport {WorkflowRunSummary} from '../workflow-run-summary/index.js';\nimport {\n type DerivedRunAnnotation,\n RunAnnotationList,\n RunAnnotationSummaryLine,\n} from '../workflow-run-tabs/index.js';\nimport {WorkflowSourceContent} from '../workflow-source-panel/index.js';\nimport {RunWorkspaceNav} from './run-workspace-nav.js';\nimport {resolveWorkflowRunSelection} from './workflow-run-selection.js';\nimport {\n WorkflowRunContentSkeleton,\n WorkflowRunNotFound,\n WorkflowRunSkeleton,\n WorkflowRunStaleError,\n} from './workflow-run-states.js';\n\ntype RunWorkspaceSection = Exclude<WorkflowRunTab, 'jobs'>;\n\nexport interface WorkflowRunViewProps {\n projectId: string;\n workspaceSlug?: string | undefined;\n projectSlug?: string | undefined;\n workflowRunId?: string | undefined;\n runAttempt?: number | undefined;\n selection?: WorkflowRunsSearch | undefined;\n tab?: WorkflowRunTab | undefined;\n activeJobId?: string | undefined;\n jobSearch?: WorkflowJobSearch | undefined;\n jobContent?: ReactNode | undefined;\n}\n\n/**\n * The persistent run workspace. Run-level sections and dedicated job routes share the same\n * header and job index, while the all-jobs Summary always opens on the dependency graph.\n */\nexport function WorkflowRunView({\n projectId,\n workspaceSlug,\n projectSlug,\n workflowRunId,\n runAttempt,\n selection,\n tab,\n activeJobId,\n jobSearch,\n jobContent,\n}: WorkflowRunViewProps) {\n const runQuery = useWorkflowRunAttemptQuery({\n workflowRunId,\n runAttempt: selection?.runAttempt ?? runAttempt,\n });\n const rerunMutation = useRerunWorkflowRunMutation(projectId);\n // Annotations are read on their own cadence rather than hydrated into the run, so the two\n // modules stay decoupled. The key is shared, so the job page's count chip costs no extra fetch.\n //\n // Polling is scoped to the surface that renders bodies. The read has no counts-only mode, so\n // every poll transfers whole Markdown bodies; doing that every four seconds behind Summary,\n // Source, and the job log spends megabytes to keep one rail number warm. Off that surface the\n // counts still refresh on navigation and on window focus.\n const annotationsQuery = useRunAnnotationsQuery({\n workflowRunId,\n runAttempt: runQuery.data?.runAttempt.attempt,\n live:\n runWorkspaceSection(tab) === 'annotations' &&\n !activeJobId &&\n Boolean(runQuery.data) &&\n !isWorkflowRunTerminal(runQuery.data?.runAttempt.status ?? 'pending'),\n });\n\n return (\n <RelativeTimeProvider>\n <div className=\"flex min-h-0 min-w-0 flex-1 overflow-hidden\">\n <RunViewContent\n workspaceSlug={workspaceSlug}\n projectSlug={projectSlug}\n query={runQuery}\n annotations={annotationsQuery}\n rerunMutation={rerunMutation}\n runAttempt={runAttempt}\n selection={selection}\n tab={tab}\n activeJobId={activeJobId}\n jobSearch={jobSearch}\n jobContent={jobContent}\n />\n </div>\n </RelativeTimeProvider>\n );\n}\n\nfunction RunViewContent({\n workspaceSlug,\n projectSlug,\n query,\n annotations,\n rerunMutation,\n runAttempt,\n selection,\n tab,\n activeJobId,\n jobSearch,\n jobContent,\n}: {\n workspaceSlug: string | undefined;\n projectSlug: string | undefined;\n query: ReturnType<typeof useWorkflowRunAttemptQuery>;\n annotations: ReturnType<typeof useRunAnnotationsQuery>;\n rerunMutation: ReturnType<typeof useRerunWorkflowRunMutation>;\n runAttempt: number | undefined;\n selection: WorkflowRunsSearch | undefined;\n tab: WorkflowRunTab | undefined;\n activeJobId: string | undefined;\n jobSearch: WorkflowJobSearch | undefined;\n jobContent: ReactNode | undefined;\n}) {\n const navigate = useNavigate();\n const runData = query.data;\n const annotationSummary = annotations.summary;\n const activeSection = runWorkspaceSection(tab);\n const cancelMutation = useCancelWorkflowRunMutation(runData);\n const sourceSnapshot = runData?.sourceSnapshot ?? null;\n const resolvedSelection =\n runData && selection ? resolveWorkflowRunSelection({run: runData, selection}) : undefined;\n const highlightedLineRange = resolvedSelection?.step?.sourceLocation ?? null;\n\n useEffect(() => {\n const hasLegacyJobSelection = Boolean(\n selection?.jobId ||\n selection?.jobExecutionId ||\n selection?.stepId ||\n selection?.stepAttemptId,\n );\n if (\n activeJobId ||\n activeSection !== 'summary' ||\n !hasLegacyJobSelection ||\n !resolvedSelection?.job ||\n !runData ||\n !workspaceSlug ||\n !projectSlug\n ) {\n return;\n }\n\n void navigate({\n to: '/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId/jobs/$jobId',\n params: {\n workspaceSlug,\n projectSlug,\n workflowRunId: runData.id,\n jobId: resolvedSelection.job.id,\n },\n search: workflowJobSearchParams({\n jobExecutionId: selection?.jobExecutionId,\n stepId: selection?.stepId,\n stepAttemptId: selection?.stepAttemptId,\n runAttempt: selection?.runAttempt,\n }) as never,\n replace: true,\n });\n }, [\n activeJobId,\n activeSection,\n navigate,\n projectSlug,\n resolvedSelection?.job,\n runData,\n selection,\n workspaceSlug,\n ]);\n\n async function rerun(mode: WorkflowRunRerunMode) {\n if (!runData || !workspaceSlug || !projectSlug) {\n toast.error('Could not start re-run from this route.');\n return;\n }\n try {\n const run = await rerunMutation.mutateAsync({workflowRunId: runData.id, mode});\n toast.success('Re-run started');\n await navigate({\n to: '/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId',\n params: {workspaceSlug, projectSlug, workflowRunId: run.id},\n search: ((previous: Record<string, unknown>) =>\n withoutWorkflowRunSelectionSearch(previous)) as never,\n });\n } catch (error) {\n toast.error(error instanceof ApiError ? error.message : 'Could not start re-run');\n }\n }\n\n function selectGraphJob(jobId: string | undefined, source: JobGraphSelectionSource = 'pointer') {\n if (source !== 'pointer' || !jobId || !runData || !workspaceSlug || !projectSlug) return;\n\n void navigate({\n to: '/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId/jobs/$jobId',\n params: {workspaceSlug, projectSlug, workflowRunId: runData.id, jobId},\n search: workflowJobSearchParams({\n runAttempt: selection?.runAttempt ?? runAttempt ?? runData.runAttempt.attempt,\n }) as never,\n });\n }\n\n function selectAnnotationJob(jobId: string | undefined) {\n if (!runData || !workspaceSlug || !projectSlug) return;\n const nextSearch: WorkflowRunsSearch = {...selection, tab: 'annotations'};\n if (jobId) nextSearch.jobId = jobId;\n else delete nextSearch.jobId;\n delete nextSearch.jobExecutionId;\n delete nextSearch.stepId;\n delete nextSearch.stepAttemptId;\n\n void navigate({\n to: '/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId',\n params: {workspaceSlug, projectSlug, workflowRunId: runData.id},\n search: workflowRunSearchParams(nextSearch, nextSearch) as never,\n });\n }\n\n function clearAnnotationFilters() {\n if (!runData || !workspaceSlug || !projectSlug) return;\n const nextSearch: WorkflowRunsSearch = {...selection, tab: 'annotations'};\n delete nextSearch.jobId;\n delete nextSearch.jobExecutionId;\n delete nextSearch.stepId;\n delete nextSearch.stepAttemptId;\n delete nextSearch.severity;\n delete nextSearch.annotation;\n\n void navigate({\n to: '/w/$workspaceSlug/p/$projectSlug/runs/$workflowRunId',\n params: {workspaceSlug, projectSlug, workflowRunId: runData.id},\n search: workflowRunSearchParams(nextSearch, nextSearch) as never,\n replace: true,\n });\n }\n\n function cancelRun() {\n cancelMutation.mutate(undefined, {\n onError: (error) => toast.error(cancelErrorMessage(error)),\n });\n }\n\n const fatalError = query.isError && runData === undefined;\n const loadingOrError = fatalError ? (\n query.error instanceof ApiError && query.error.status === 404 ? (\n <WorkflowRunNotFound />\n ) : (\n <QueryLoadError query={query} subject=\"workflow run\" icon=\"pulseLine\" />\n )\n ) : query.isPending || runData === undefined ? (\n <WorkflowRunContentSkeleton />\n ) : null;\n\n return (\n <div className=\"flex min-h-0 min-w-0 flex-1 flex-col\">\n {runData ? (\n <WorkflowRunSummary\n workspaceSlug={workspaceSlug}\n projectSlug={projectSlug}\n run={runData}\n cancelling={cancelMutation.isPending}\n onCancel={cancelRun}\n rerunPending={rerunMutation.isPending}\n onRerun={(mode) => void rerun(mode)}\n latestAttempt={runData.latestAttempt}\n />\n ) : (\n <WorkflowRunSkeleton />\n )}\n {runData && query.isError ? <WorkflowRunStaleError query={query} /> : null}\n\n <div\n data-run-workspace-layout\n className=\"flex min-h-0 min-w-0 flex-1 flex-col border-t border-border-neutral-base\"\n >\n <div\n data-run-workspace-frame\n className=\"flex min-h-0 min-w-0 w-full flex-1 flex-col min-[768px]:flex-row\"\n >\n {runData && workspaceSlug && projectSlug ? (\n <RunWorkspaceNav\n workspaceSlug={workspaceSlug}\n projectSlug={projectSlug}\n run={runData}\n activeSection={activeSection}\n currentJobId={activeJobId}\n jobSearch={jobSearch}\n annotationSummary={annotationSummary}\n />\n ) : (\n <RunWorkspaceNavSkeleton />\n )}\n\n <div data-run-workspace-content className=\"flex min-h-0 min-w-0 flex-1 flex-col\">\n {runData && jobContent ? (\n jobContent\n ) : runData ? (\n <RunSectionContent\n section={activeSection}\n run={runData}\n annotations={annotations}\n annotationSummary={annotationSummary}\n workspaceSlug={workspaceSlug}\n projectSlug={projectSlug}\n selection={selection}\n selectedJobId={selection?.jobId}\n onSelectGraphJob={selectGraphJob}\n onSelectAnnotationJob={selectAnnotationJob}\n onClearAnnotationFilters={clearAnnotationFilters}\n sourceSnapshot={sourceSnapshot}\n highlightedLineRange={highlightedLineRange}\n />\n ) : (\n <div className=\"min-h-0 flex-1 overflow-auto p-panel\">{loadingOrError}</div>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction RunSectionContent({\n section,\n run,\n annotations,\n annotationSummary,\n workspaceSlug,\n projectSlug,\n selection,\n selectedJobId,\n onSelectGraphJob,\n onSelectAnnotationJob,\n onClearAnnotationFilters,\n sourceSnapshot,\n highlightedLineRange,\n}: {\n section: RunWorkspaceSection;\n run: NonNullable<ReturnType<typeof useWorkflowRunAttemptQuery>['data']>;\n annotations: ReturnType<typeof useRunAnnotationsQuery>;\n annotationSummary: RunAnnotationSummary | undefined;\n workspaceSlug: string | undefined;\n projectSlug: string | undefined;\n selection: WorkflowRunsSearch | undefined;\n selectedJobId: string | undefined;\n onSelectGraphJob: (jobId: string | undefined, source?: JobGraphSelectionSource) => void;\n onSelectAnnotationJob: (jobId: string | undefined) => void;\n onClearAnnotationFilters: () => void;\n sourceSnapshot: NonNullable<\n ReturnType<typeof useWorkflowRunAttemptQuery>['data']\n >['sourceSnapshot'];\n highlightedLineRange: NonNullable<\n ReturnType<typeof useWorkflowRunAttemptQuery>['data']\n >['jobs'][number]['jobExecutions'][number]['steps'][number]['sourceLocation'];\n}) {\n if (section === 'summary') {\n return (\n <section\n aria-label=\"All jobs summary\"\n className=\"min-h-0 flex-1 overflow-auto pb-panel pt-[16px]\"\n >\n <div className=\"flex w-full flex-col gap-group\">\n <Text as=\"h2\" className=\"sr-only\">\n All jobs summary\n </Text>\n <Panel className=\"min-h-160\">\n <PanelBody className=\"min-h-160 bg-background-components-base p-0\">\n <JobGraph\n run={run}\n selectedJobId={selectedJobId}\n onSelectedJobChange={onSelectGraphJob}\n className=\"min-h-160 overflow-hidden\"\n />\n </PanelBody>\n </Panel>\n </div>\n </section>\n );\n }\n\n if (section === 'annotations') {\n return (\n <RunAnnotationsSection\n run={run}\n annotations={annotations}\n annotationSummary={annotationSummary}\n workspaceSlug={workspaceSlug}\n projectSlug={projectSlug}\n selection={selection}\n selectedJobId={selectedJobId}\n onSelectAnnotationJob={onSelectAnnotationJob}\n onClearAnnotationFilters={onClearAnnotationFilters}\n />\n );\n }\n\n return (\n <section\n aria-label=\"Workflow source\"\n className=\"min-h-0 flex-1 overflow-auto pb-panel pt-[16px]\"\n >\n <div className=\"flex min-h-full w-full flex-col\">\n <Text as=\"h2\" className=\"sr-only\">\n Workflow source\n </Text>\n <Panel className=\"min-h-160 flex-1\">\n <PanelBody className=\"min-h-160 flex-1 p-0\">\n {sourceSnapshot ? (\n <WorkflowSourceContent\n source={sourceSnapshot}\n highlightedLineRange={highlightedLineRange}\n scrollHighlightedIntoView\n />\n ) : (\n <EmptyState\n variant=\"panel\"\n className=\"min-h-160\"\n icon=\"fileDamageLine\"\n title=\"Source snapshot unavailable\"\n description={\n run.isTemporary\n ? 'Temporary runs do not capture workflow source.'\n : 'This run was created before workflow source snapshots were captured.'\n }\n />\n )}\n </PanelBody>\n </Panel>\n </div>\n </section>\n );\n}\n\nfunction RunAnnotationsSection({\n run,\n annotations,\n annotationSummary,\n workspaceSlug,\n projectSlug,\n selection,\n selectedJobId,\n onSelectAnnotationJob,\n onClearAnnotationFilters,\n}: {\n run: NonNullable<ReturnType<typeof useWorkflowRunAttemptQuery>['data']>;\n annotations: ReturnType<typeof useRunAnnotationsQuery>;\n annotationSummary: RunAnnotationSummary | undefined;\n workspaceSlug: string | undefined;\n projectSlug: string | undefined;\n selection: WorkflowRunsSearch | undefined;\n selectedJobId: string | undefined;\n onSelectAnnotationJob: (jobId: string | undefined) => void;\n onClearAnnotationFilters: () => void;\n}) {\n const selectedJob = run.jobs.find((job) => job.id === selectedJobId);\n const severity = selection?.severity;\n const records = annotations.annotations;\n\n const entries = useMemo(\n () =>\n records\n ? buildRunAnnotationList({\n annotations: records,\n jobs: run.jobs,\n severity,\n jobId: selectedJob?.id,\n })\n : undefined,\n [records, run.jobs, selectedJob?.id, severity],\n );\n const derivedAnnotations = useMemo<readonly DerivedRunAnnotation[] | undefined>(() => {\n if (!records) return undefined;\n const jobsWithAnnotations = new Set(records.map((annotation) => annotation.jobId));\n\n return run.jobs\n .filter((job) => {\n const style = job.status === 'failed' ? 'error' : 'warning';\n return (\n (!selectedJob || selectedJob.id === job.id) &&\n !jobsWithAnnotations.has(job.id) &&\n (job.status === 'failed' || job.status === 'skipped') &&\n job.jobExecutions.length === 0 &&\n matchesDerivedAnnotationFilters(style, selection)\n );\n })\n .map((job) => ({\n id: `derived-${job.id}`,\n style: job.status === 'failed' ? 'error' : 'warning',\n body: derivedJobAnnotation(job),\n }));\n }, [records, run.jobs, selectedJob, selection]);\n const hasSynthesizedJobAnnotations = run.jobs.some(\n (job) =>\n (job.status === 'failed' || job.status === 'skipped') && job.jobExecutions.length === 0,\n );\n\n return (\n <section\n aria-label=\"Run annotations\"\n className=\"min-h-0 flex-1 overflow-auto pb-panel pt-[16px]\"\n >\n <div className=\"flex w-full flex-col\">\n <Text as=\"h2\" className=\"sr-only\">\n Annotations\n </Text>\n <Panel>\n <PanelHeader className=\"flex-wrap\">\n <RunAnnotationSummaryLine\n summary={annotationSummary}\n workspaceSlug={workspaceSlug}\n projectSlug={projectSlug}\n workflowRunId={run.id}\n search={selection}\n />\n <AnnotationJobFilter\n jobs={run.jobs}\n selectedJobId={selectedJob?.id}\n onSelect={onSelectAnnotationJob}\n />\n </PanelHeader>\n <PanelBody className=\"gap-group p-panel\">\n <RunAnnotationList\n // Remounting on a filter or run-attempt change resets the render window, so the next\n // list never inherits a \"show more\" position from different data.\n key={`${run.id}:${run.runAttempt.attempt}:${severity ?? 'all'}:${selectedJob?.id ?? 'all'}`}\n query={annotations.query}\n entries={entries}\n derivedAnnotations={derivedAnnotations}\n workspaceSlug={workspaceSlug}\n projectSlug={projectSlug}\n workflowRunId={run.id}\n runAttempt={run.runAttempt.attempt}\n // A run with no annotations at all offers no filter to clear, whatever the URL says.\n filtered={Boolean(\n (severity || selectedJob || selection?.annotation) &&\n ((annotationSummary?.total ?? 0) > 0 || hasSynthesizedJobAnnotations),\n )}\n filteredJobName={selectedJob?.displayName}\n filteredSeverity={severity}\n onClearFilters={onClearAnnotationFilters}\n selectedAnnotationId={selection?.annotation}\n />\n </PanelBody>\n </Panel>\n </div>\n </section>\n );\n}\n\nfunction matchesDerivedAnnotationFilters(\n style: 'warning' | 'error',\n selection: WorkflowRunsSearch | undefined,\n): boolean {\n if (selection?.severity && style !== selection.severity) return false;\n // A selected annotation is a deep-link to a real annotation record. Synthetic diagnostics\n // have no id or context, so they must not remain visible behind that selection.\n return !selection?.annotation;\n}\n\nfunction derivedJobAnnotation(job: Job): string {\n const reason = job.statusReason ? `Reason: \\`${job.statusReason}\\`` : null;\n const traceSummary = formatConditionEvaluation(job.evaluationTrace);\n const details = [reason, traceSummary].filter(Boolean).join('\\n');\n\n if (job.status === 'skipped') {\n return [\n `**${job.displayName}** was skipped before an execution was created.`,\n '',\n 'Review its dependencies or condition before re-running.',\n details,\n ]\n .filter(Boolean)\n .join('\\n');\n }\n return [\n `**${job.displayName}** failed before an execution was created.`,\n '',\n 'Check runner availability and workflow configuration before re-running.',\n details,\n ]\n .filter(Boolean)\n .join('\\n');\n}\n\nfunction formatConditionEvaluation(\n trace: readonly EvaluationTraceEntry[] | null | undefined,\n): string | null {\n if (!trace?.length) return null;\n\n return [\n 'Condition evaluation:',\n ...trace.map((entry) => {\n if ('dropped' in entry) {\n return `- ${entry.dropped} additional evaluation${entry.dropped === 1 ? '' : 's'} not recorded`;\n }\n const value =\n entry.value === undefined || entry.value === '' ? '(empty)' : `\\`${entry.value}\\``;\n return `- \\`${entry.field}\\` evaluated \\`${entry.expression}\\` to ${value}${entry.degraded ? ' (degraded)' : ''}`;\n }),\n ].join('\\n');\n}\n\nconst ALL_ANNOTATION_JOBS = 'all-jobs';\n\nfunction AnnotationJobFilter({\n jobs,\n selectedJobId,\n onSelect,\n}: {\n jobs: Job[];\n selectedJobId: string | undefined;\n onSelect: (jobId: string | undefined) => void;\n}) {\n const sortedJobs = [...jobs].sort(\n (left, right) => left.position - right.position || left.id.localeCompare(right.id),\n );\n\n return (\n <Select\n value={selectedJobId ?? ALL_ANNOTATION_JOBS}\n onValueChange={(value) => onSelect(value === ALL_ANNOTATION_JOBS ? undefined : value)}\n >\n <SelectTrigger\n size=\"small\"\n aria-label=\"Filter annotations by job\"\n className=\"w-full min-[480px]:w-240\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent align=\"end\">\n <SelectItem value={ALL_ANNOTATION_JOBS}>All jobs</SelectItem>\n {sortedJobs.map((job) => (\n <SelectItem key={job.id} value={job.id}>\n {job.displayName}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n}\n\nfunction RunWorkspaceNavSkeleton() {\n return (\n <aside\n aria-label=\"Loading run navigation\"\n className=\"hidden w-240 shrink-0 p-panel-compact min-[768px]:block\"\n >\n <div className=\"flex flex-col gap-group\">\n <div className=\"h-32 rounded-4 bg-background-components-subtle\" />\n <div className=\"flex flex-col gap-inline\">\n <div className=\"h-16 w-64 rounded-4 bg-background-components-subtle\" />\n <div className=\"h-32 rounded-4 bg-background-components-subtle\" />\n <div className=\"h-32 rounded-4 bg-background-components-subtle\" />\n </div>\n </div>\n </aside>\n );\n}\n\nfunction runWorkspaceSection(tab: WorkflowRunTab | undefined): RunWorkspaceSection {\n return tab === 'annotations' || tab === 'source' ? tab : 'summary';\n}\n\nfunction cancelErrorMessage(error: unknown): string {\n if (error instanceof ApiError && error.code === 'run-already-finished') {\n return 'This workflow run has already finished.';\n }\n return 'Could not cancel workflow run.';\n}\n"],"names":["ApiError","QueryLoadError","EmptyState","Panel","PanelBody","PanelHeader","RelativeTimeProvider","Select","SelectContent","SelectItem","SelectTrigger","SelectValue","toast","Text","useNavigate","useEffect","useMemo","buildRunAnnotationList","isWorkflowRunTerminal","withoutWorkflowRunSelectionSearch","useRunAnnotationsQuery","useCancelWorkflowRunMutation","useRerunWorkflowRunMutation","useWorkflowRunAttemptQuery","workflowJobSearchParams","workflowRunSearchParams","JobGraph","WorkflowRunSummary","RunAnnotationList","RunAnnotationSummaryLine","WorkflowSourceContent","RunWorkspaceNav","resolveWorkflowRunSelection","WorkflowRunContentSkeleton","WorkflowRunNotFound","WorkflowRunSkeleton","WorkflowRunStaleError","WorkflowRunView","projectId","workspaceSlug","projectSlug","workflowRunId","runAttempt","selection","tab","activeJobId","jobSearch","jobContent","runQuery","rerunMutation","annotationsQuery","data","attempt","live","runWorkspaceSection","Boolean","status","div","className","RunViewContent","query","annotations","navigate","runData","annotationSummary","summary","activeSection","cancelMutation","sourceSnapshot","resolvedSelection","run","undefined","highlightedLineRange","step","sourceLocation","hasLegacyJobSelection","jobId","jobExecutionId","stepId","stepAttemptId","job","to","params","id","search","replace","rerun","mode","error","mutateAsync","success","previous","message","selectGraphJob","source","selectAnnotationJob","nextSearch","clearAnnotationFilters","severity","annotation","cancelRun","mutate","onError","cancelErrorMessage","fatalError","isError","loadingOrError","subject","icon","isPending","cancelling","onCancel","rerunPending","onRerun","latestAttempt","data-run-workspace-layout","data-run-workspace-frame","currentJobId","RunWorkspaceNavSkeleton","data-run-workspace-content","RunSectionContent","section","selectedJobId","onSelectGraphJob","onSelectAnnotationJob","onClearAnnotationFilters","aria-label","as","onSelectedJobChange","RunAnnotationsSection","scrollHighlightedIntoView","variant","title","description","isTemporary","selectedJob","jobs","find","records","entries","derivedAnnotations","jobsWithAnnotations","Set","map","filter","style","has","jobExecutions","length","matchesDerivedAnnotationFilters","body","derivedJobAnnotation","hasSynthesizedJobAnnotations","some","AnnotationJobFilter","onSelect","filtered","total","filteredJobName","displayName","filteredSeverity","onClearFilters","selectedAnnotationId","reason","statusReason","traceSummary","formatConditionEvaluation","evaluationTrace","details","join","trace","entry","dropped","value","field","expression","degraded","ALL_ANNOTATION_JOBS","sortedJobs","sort","left","right","position","localeCompare","onValueChange","size","align","aside","code"],"mappings":"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"}
|
|
@@ -35,7 +35,7 @@ export function WorkflowSourceContent({ source, highlightedLineRange, scrollHigh
|
|
|
35
35
|
className: "flex min-h-0 flex-1 overflow-auto scrollbar",
|
|
36
36
|
children: (item)=>/*#__PURE__*/ _jsx(CodeBlockItem, {
|
|
37
37
|
value: item.filename,
|
|
38
|
-
className: cn('min-h-full px-0 pb-0', '[&>div]:rounded-none [&>div]:border-0 [&>div]:bg-background-contrast-base
|
|
38
|
+
className: cn('min-h-full px-0 pb-0', '[&>div]:rounded-none [&>div]:border-0 [&>div]:bg-background-contrast-base', '[&_code]:!text-sm [&_code]:!text-foreground-contrast-primary [&_.line]:!text-sm [&_.line]:before:!text-sm [&_.line]:before:!text-foreground-contrast-secondary'),
|
|
39
39
|
children: /*#__PURE__*/ _jsx(CodeBlockContent, {
|
|
40
40
|
language: "yaml",
|
|
41
41
|
themes: WORKFLOW_SOURCE_CODE_THEMES,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/workflow-source-panel/workflow-source-content.tsx"],"sourcesContent":["import {\n CodeBlock,\n CodeBlockBody,\n CodeBlockContent,\n CodeBlockCopyButton,\n CodeBlockFilename,\n CodeBlockFiles,\n CodeBlockHeader,\n type CodeBlockHighlightedLineRange,\n CodeBlockItem,\n} from '@shipfox/react-ui/code-block';\nimport {cn} from '@shipfox/react-ui/utils';\nimport type {ReactNode} from 'react';\nimport type {WorkflowSourceSnapshot} from '#core/workflow-run.js';\n\nconst WORKFLOW_SOURCE_FILENAME = 'workflow.yaml';\nconst WORKFLOW_SOURCE_CODE_THEMES = {\n light: 'vitesse-dark',\n dark: 'vitesse-dark',\n};\n\nexport interface WorkflowSourceContentProps {\n source: WorkflowSourceSnapshot;\n highlightedLineRange?: CodeBlockHighlightedLineRange | null | undefined;\n scrollHighlightedIntoView?: boolean | undefined;\n headerAction?: ReactNode;\n className?: string | undefined;\n}\n\nexport function WorkflowSourceContent({\n source,\n highlightedLineRange,\n scrollHighlightedIntoView,\n headerAction,\n className,\n}: WorkflowSourceContentProps) {\n const data = [\n {\n language: 'yaml',\n filename: WORKFLOW_SOURCE_FILENAME,\n code: source.content,\n },\n ];\n\n return (\n <CodeBlock\n data={data}\n className={cn(\n 'flex size-full flex-col rounded-none bg-background-contrast-base shadow-none',\n className,\n )}\n >\n <CodeBlockHeader className=\"shrink-0 border-b border-border-contrast-base bg-background-contrast-base\">\n <CodeBlockFiles>\n {(item) => <CodeBlockFilename value={item.filename}>{item.filename}</CodeBlockFilename>}\n </CodeBlockFiles>\n <CodeBlockCopyButton />\n {headerAction}\n </CodeBlockHeader>\n <CodeBlockBody className=\"flex min-h-0 flex-1 overflow-auto scrollbar\">\n {(item) => (\n <CodeBlockItem\n value={item.filename}\n className={cn(\n 'min-h-full px-0 pb-0',\n '[&>div]:rounded-none [&>div]:border-0 [&>div]:bg-background-contrast-base
|
|
1
|
+
{"version":3,"sources":["../../../src/components/workflow-source-panel/workflow-source-content.tsx"],"sourcesContent":["import {\n CodeBlock,\n CodeBlockBody,\n CodeBlockContent,\n CodeBlockCopyButton,\n CodeBlockFilename,\n CodeBlockFiles,\n CodeBlockHeader,\n type CodeBlockHighlightedLineRange,\n CodeBlockItem,\n} from '@shipfox/react-ui/code-block';\nimport {cn} from '@shipfox/react-ui/utils';\nimport type {ReactNode} from 'react';\nimport type {WorkflowSourceSnapshot} from '#core/workflow-run.js';\n\nconst WORKFLOW_SOURCE_FILENAME = 'workflow.yaml';\nconst WORKFLOW_SOURCE_CODE_THEMES = {\n light: 'vitesse-dark',\n dark: 'vitesse-dark',\n};\n\nexport interface WorkflowSourceContentProps {\n source: WorkflowSourceSnapshot;\n highlightedLineRange?: CodeBlockHighlightedLineRange | null | undefined;\n scrollHighlightedIntoView?: boolean | undefined;\n headerAction?: ReactNode;\n className?: string | undefined;\n}\n\nexport function WorkflowSourceContent({\n source,\n highlightedLineRange,\n scrollHighlightedIntoView,\n headerAction,\n className,\n}: WorkflowSourceContentProps) {\n const data = [\n {\n language: 'yaml',\n filename: WORKFLOW_SOURCE_FILENAME,\n code: source.content,\n },\n ];\n\n return (\n <CodeBlock\n data={data}\n className={cn(\n 'flex size-full flex-col rounded-none bg-background-contrast-base shadow-none',\n className,\n )}\n >\n <CodeBlockHeader className=\"shrink-0 border-b border-border-contrast-base bg-background-contrast-base\">\n <CodeBlockFiles>\n {(item) => <CodeBlockFilename value={item.filename}>{item.filename}</CodeBlockFilename>}\n </CodeBlockFiles>\n <CodeBlockCopyButton />\n {headerAction}\n </CodeBlockHeader>\n <CodeBlockBody className=\"flex min-h-0 flex-1 overflow-auto scrollbar\">\n {(item) => (\n <CodeBlockItem\n value={item.filename}\n className={cn(\n 'min-h-full px-0 pb-0',\n '[&>div]:rounded-none [&>div]:border-0 [&>div]:bg-background-contrast-base',\n '[&_code]:!text-sm [&_code]:!text-foreground-contrast-primary [&_.line]:!text-sm [&_.line]:before:!text-sm [&_.line]:before:!text-foreground-contrast-secondary',\n )}\n >\n <CodeBlockContent\n language=\"yaml\"\n themes={WORKFLOW_SOURCE_CODE_THEMES}\n syntaxHighlighting\n highlightedLineRange={highlightedLineRange}\n scrollHighlightedIntoView={scrollHighlightedIntoView}\n >\n {item.code}\n </CodeBlockContent>\n </CodeBlockItem>\n )}\n </CodeBlockBody>\n </CodeBlock>\n );\n}\n"],"names":["CodeBlock","CodeBlockBody","CodeBlockContent","CodeBlockCopyButton","CodeBlockFilename","CodeBlockFiles","CodeBlockHeader","CodeBlockItem","cn","WORKFLOW_SOURCE_FILENAME","WORKFLOW_SOURCE_CODE_THEMES","light","dark","WorkflowSourceContent","source","highlightedLineRange","scrollHighlightedIntoView","headerAction","className","data","language","filename","code","content","item","value","themes","syntaxHighlighting"],"mappings":";AAAA,SACEA,SAAS,EACTC,aAAa,EACbC,gBAAgB,EAChBC,mBAAmB,EACnBC,iBAAiB,EACjBC,cAAc,EACdC,eAAe,EAEfC,aAAa,QACR,+BAA+B;AACtC,SAAQC,EAAE,QAAO,0BAA0B;AAI3C,MAAMC,2BAA2B;AACjC,MAAMC,8BAA8B;IAClCC,OAAO;IACPC,MAAM;AACR;AAUA,OAAO,SAASC,sBAAsB,EACpCC,MAAM,EACNC,oBAAoB,EACpBC,yBAAyB,EACzBC,YAAY,EACZC,SAAS,EACkB;IAC3B,MAAMC,OAAO;QACX;YACEC,UAAU;YACVC,UAAUZ;YACVa,MAAMR,OAAOS,OAAO;QACtB;KACD;IAED,qBACE,MAACvB;QACCmB,MAAMA;QACND,WAAWV,GACT,gFACAU;;0BAGF,MAACZ;gBAAgBY,WAAU;;kCACzB,KAACb;kCACE,CAACmB,qBAAS,KAACpB;gCAAkBqB,OAAOD,KAAKH,QAAQ;0CAAGG,KAAKH,QAAQ;;;kCAEpE,KAAClB;oBACAc;;;0BAEH,KAAChB;gBAAciB,WAAU;0BACtB,CAACM,qBACA,KAACjB;wBACCkB,OAAOD,KAAKH,QAAQ;wBACpBH,WAAWV,GACT,wBACA,6EACA;kCAGF,cAAA,KAACN;4BACCkB,UAAS;4BACTM,QAAQhB;4BACRiB,kBAAkB;4BAClBZ,sBAAsBA;4BACtBC,2BAA2BA;sCAE1BQ,KAAKF,IAAI;;;;;;AAOxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-workflows-page.d.ts","sourceRoot":"","sources":["../../src/pages/project-workflows-page.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"project-workflows-page.d.ts","sourceRoot":"","sources":["../../src/pages/project-workflows-page.tsx"],"names":[],"mappings":"AAsCA,wBAAgB,oBAAoB,CAAC,EAAC,SAAS,EAAC,EAAE;IAAC,SAAS,EAAE,MAAM,CAAA;CAAC,+BAMpE"}
|