diff --git a/studio/frontend/src/features/recipe-studio/components/executions/executions-view.tsx b/studio/frontend/src/features/recipe-studio/components/executions/executions-view.tsx index c10b1d5f5d..eb15ac0da2 100644 --- a/studio/frontend/src/features/recipe-studio/components/executions/executions-view.tsx +++ b/studio/frontend/src/features/recipe-studio/components/executions/executions-view.tsx @@ -33,16 +33,13 @@ import type { RecipeExecutionRecord, RecipeExecutionStatus, } from "../../execution-types"; +import { isExecutionInProgress } from "../../executions/execution-helpers"; type ExecutionsViewProps = { executions: RecipeExecutionRecord[]; selectedExecutionId: string | null; currentSignature: string; - previewLoading: boolean; - fullLoading: boolean; onSelectExecution: (id: string) => void; - onRunPreview: () => void; - onRunFull: () => void; onCancelExecution: (id: string) => void; onLoadDatasetPage: (id: string, page: number) => void; }; @@ -126,15 +123,6 @@ function parseAnalysisColumns(analysis: RecipeExecutionAnalysis | null): Analysi .filter((item): item is AnalysisColumnStat => item !== null); } -function isInProgress(status: RecipeExecutionStatus): boolean { - return ( - status === "running" || - status === "active" || - status === "pending" || - status === "cancelling" - ); -} - function statusTone(status: RecipeExecutionStatus): string { if (status === "completed") { return "bg-emerald-100 text-emerald-700"; @@ -142,7 +130,7 @@ function statusTone(status: RecipeExecutionStatus): string { if (status === "error" || status === "cancelled") { return "bg-red-100 text-red-700"; } - if (isInProgress(status)) { + if (isExecutionInProgress(status)) { return "bg-amber-100 text-amber-700"; } return "bg-muted text-muted-foreground"; @@ -155,7 +143,7 @@ function statusRightBorder(status: RecipeExecutionStatus): string { if (status === "error" || status === "cancelled") { return "border-r-red-500"; } - if (isInProgress(status)) { + if (isExecutionInProgress(status)) { return "border-r-amber-500"; } return "border-r-border"; @@ -221,11 +209,7 @@ export function ExecutionsView({ executions, selectedExecutionId, currentSignature, - previewLoading, - fullLoading, onSelectExecution, - onRunPreview, - onRunFull, onCancelExecution, onLoadDatasetPage, }: ExecutionsViewProps): ReactElement { @@ -349,7 +333,7 @@ export function ExecutionsView({ }, [selectedExecution?.analysis?.side_effect_column_names]); const canCancel = Boolean( - selectedExecution?.jobId && isInProgress(selectedExecution.status), + selectedExecution?.jobId && isExecutionInProgress(selectedExecution.status), ); const datasetPage = selectedExecution?.datasetPage ?? 1; const datasetPageSize = selectedExecution?.datasetPageSize ?? 20; @@ -429,7 +413,7 @@ export function ExecutionsView({ const showSummaryCards = selectedExecution?.status === "completed"; const showProgressPanel = selectedExecution?.status === "completed" || - (selectedExecution ? isInProgress(selectedExecution.status) : false); + (selectedExecution ? isExecutionInProgress(selectedExecution.status) : false); const progressComplete = selectedExecution?.status === "completed"; const progressPercent = selectedExecution?.progress?.percent ?? (progressComplete ? 100 : 0); const terminalLines = selectedExecution?.log_lines ?? []; @@ -455,25 +439,6 @@ export function ExecutionsView({

Executions

-
- - -
{executions.length === 0 ? ( @@ -632,7 +597,7 @@ export function ExecutionsView({ )} {(selectedExecution.status === "completed" || - isInProgress(selectedExecution.status)) && ( + isExecutionInProgress(selectedExecution.status)) && (
@@ -815,7 +780,7 @@ export function ExecutionsView({ > {terminalLines.length === 0 ? (

- {isInProgress(selectedExecution.status) + {isExecutionInProgress(selectedExecution.status) ? "Waiting for logs..." : "No logs captured."}

@@ -911,7 +876,7 @@ export function ExecutionsView({ size="sm" variant="outline" disabled={ - isInProgress(selectedExecution.status) || datasetPage <= 1 + isExecutionInProgress(selectedExecution.status) || datasetPage <= 1 } onClick={() => onLoadDatasetPage(selectedExecution.id, datasetPage - 1)} @@ -923,7 +888,7 @@ export function ExecutionsView({ size="sm" variant="outline" disabled={ - isInProgress(selectedExecution.status) || + isExecutionInProgress(selectedExecution.status) || datasetPage >= totalPages } onClick={() => diff --git a/studio/frontend/src/features/recipe-studio/components/recipe-studio-header.tsx b/studio/frontend/src/features/recipe-studio/components/recipe-studio-header.tsx index b5ff7ec82b..afd7c35fab 100644 --- a/studio/frontend/src/features/recipe-studio/components/recipe-studio-header.tsx +++ b/studio/frontend/src/features/recipe-studio/components/recipe-studio-header.tsx @@ -16,6 +16,7 @@ type StatusTone = "success" | "error"; type RecipeStudioHeaderProps = { activeView: RecipeStudioView; previewLoading: boolean; + fullLoading: boolean; saveLoading: boolean; saveTone: StatusTone; savedAtLabel: string; @@ -23,6 +24,7 @@ type RecipeStudioHeaderProps = { onWorkflowNameChange: (value: string) => void; onViewChange: (view: RecipeStudioView) => void; onPreview: () => void; + onRunFull: () => void; onSaveRecipe: () => void; }; @@ -34,6 +36,7 @@ const STATUS_MESSAGE_CLASS: Record = { export function RecipeStudioHeader({ activeView, previewLoading, + fullLoading, saveLoading, saveTone, savedAtLabel, @@ -41,6 +44,7 @@ export function RecipeStudioHeader({ onWorkflowNameChange, onViewChange, onPreview, + onRunFull, onSaveRecipe, }: RecipeStudioHeaderProps): ReactElement { const [editingWorkflowName, setEditingWorkflowName] = useState(false); @@ -116,6 +120,10 @@ export function RecipeStudioHeader({ {previewLoading ? "Previewing..." : "Preview"} +