Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions web/src/lib/__tests__/pipelineRunSelection.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { describe, expect, it } from "vitest";

import { selectRunIdToLoad } from "../pipelineRunSelection";

describe("selectRunIdToLoad", () => {
it("keeps the user's selected run across polls", () => {
expect(selectRunIdToLoad("older-run", ["newest-run", "older-run"])).toBe("older-run");
});

it("auto-selects the newest run when no run is selected", () => {
expect(selectRunIdToLoad(null, ["newest-run", "older-run"])).toBe("newest-run");
});

it("selects the newest run when the previous selection belongs to another pipeline", () => {
expect(selectRunIdToLoad("other-pipeline-run", ["newest-run", "older-run"])).toBe("newest-run");
});

it("clears the selection when there are no runs", () => {
expect(selectRunIdToLoad("older-run", [])).toBeNull();
});
});
8 changes: 8 additions & 0 deletions web/src/lib/pipelineRunSelection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function selectRunIdToLoad(
selectedRunId: string | null,
runIds: readonly string[]
): string | null {
if (runIds.length === 0) return null;
if (selectedRunId && runIds.includes(selectedRunId)) return selectedRunId;
return runIds[0] ?? null;
}
17 changes: 13 additions & 4 deletions web/src/pages/Pipelines.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useMemo, useState } from "react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import {
api,
type PipelineData,
Expand All @@ -8,6 +8,7 @@ import {
type PipelineStepData,
} from "../lib/api";
import { useTranslation } from "react-i18next";
import { selectRunIdToLoad } from "../lib/pipelineRunSelection";

interface StepDraft {
id: string;
Expand Down Expand Up @@ -438,6 +439,7 @@ export function Pipelines() {
const [saving, setSaving] = useState(false);
const [running, setRunning] = useState(false);
const [error, setError] = useState<string | null>(null);
const selectedRunIdRef = useRef<string | null>(null);

const selected = useMemo(
() => pipelines.find((pipeline) => pipeline.id === selectedId) ?? pipelines[0] ?? null,
Expand All @@ -462,7 +464,9 @@ export function Pipelines() {
const loadRunDetail = useCallback(async (pipelineId: string, runId: string) => {
try {
const res = await api.pipelineRunDetail(pipelineId, runId);
setSelectedRun(res.data ?? null);
const detail = res.data ?? null;
selectedRunIdRef.current = detail?.run.id ?? null;
setSelectedRun(detail);
} catch (err) {
setError(err instanceof Error ? err.message : String(err));
}
Expand All @@ -475,9 +479,14 @@ export function Pipelines() {
const res = await api.pipelineRunsList(pipelineId);
const next = res.data ?? [];
setRuns(next);
if (next[0]) {
await loadRunDetail(pipelineId, next[0].id);
const runId = selectRunIdToLoad(
selectedRunIdRef.current,
next.map((run) => run.id)
);
if (runId) {
await loadRunDetail(pipelineId, runId);
} else {
selectedRunIdRef.current = null;
setSelectedRun(null);
}
} catch (err) {
Expand Down
Loading