Skip to content

Commit 77dacfd

Browse files
committed
changes
1 parent 1751f9a commit 77dacfd

3 files changed

Lines changed: 37 additions & 13 deletions

File tree

trackio/frontend/src/App.svelte

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,13 @@
147147
148148
if (JSON.stringify(runs) !== JSON.stringify(newRuns)) {
149149
const prevSelected = selectedRuns;
150+
const prevOrdered = runs.map(runKey);
150151
runs = newRuns;
151-
selectedRuns = reconcileSelectedRuns(prevSelected, newRuns.map(runKey));
152+
selectedRuns = reconcileSelectedRuns(
153+
prevSelected,
154+
newRuns.map(runKey),
155+
prevOrdered,
156+
);
152157
}
153158
} catch (e) {
154159
console.error("Failed to load runs:", e);

trackio/frontend/src/lib/selection.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,24 @@ export function latestOnlySelection(filteredRunIds) {
33
return [filteredRunIds[0]];
44
}
55

6-
export function reconcileSelectedRuns(prevSelected, newOrderedIds) {
6+
export function reconcileSelectedRuns(prevSelected, newOrderedIds, prevOrderedIds) {
77
const prev = prevSelected ?? [];
88
const ordered = newOrderedIds ?? [];
9+
const prevOrdered = prevOrderedIds ?? [];
910
const newIdSet = new Set(ordered);
1011
const kept = prev.filter((r) => newIdSet.has(r));
1112

1213
if (prev.length === 0 || kept.length === 0) {
1314
return [...ordered];
1415
}
1516

17+
const allPrevSelected =
18+
prevOrdered.length > 0 && prev.length === prevOrdered.length;
19+
if (allPrevSelected) {
20+
const keptSet = new Set(kept);
21+
const additions = ordered.filter((r) => !keptSet.has(r));
22+
return [...kept, ...additions];
23+
}
24+
1625
return kept;
1726
}

trackio/frontend/src/lib/selection.test.js

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,37 @@ describe("reconcileSelectedRuns", () => {
2222
expect(reconcileSelectedRuns([], ["a", "b", "c"])).toEqual(["a", "b", "c"]);
2323
});
2424

25-
test("keeps the previously selected run without auto-selecting new runs", () => {
26-
expect(reconcileSelectedRuns(["a"], ["a", "b", "c"])).toEqual(["a"]);
25+
test("keeps a partial selection without auto-selecting new runs", () => {
26+
expect(reconcileSelectedRuns(["a"], ["a", "b", "c"], ["a", "b"])).toEqual(["a"]);
27+
});
28+
29+
test("auto-selects new runs when all previous runs were selected", () => {
30+
expect(
31+
reconcileSelectedRuns(["a", "b"], ["a", "b", "c"], ["a", "b"]),
32+
).toEqual(["a", "b", "c"]);
2733
});
2834

2935
test("preserves the chosen runs when the run list is unchanged on refresh", () => {
3036
const prev = ["b"];
3137
const next = ["a", "b", "c"];
32-
expect(reconcileSelectedRuns(prev, next)).toEqual(["b"]);
33-
expect(reconcileSelectedRuns(["b", "a", "c"], next)).toEqual(["b", "a", "c"]);
38+
expect(reconcileSelectedRuns(prev, next, next)).toEqual(["b"]);
39+
expect(reconcileSelectedRuns(["b", "a", "c"], next, next)).toEqual([
40+
"b",
41+
"a",
42+
"c",
43+
]);
3444
});
3545

3646
test("drops runs that no longer exist on the server", () => {
37-
expect(reconcileSelectedRuns(["a", "b", "c"], ["a", "c"])).toEqual(["a", "c"]);
47+
expect(
48+
reconcileSelectedRuns(["a", "b", "c"], ["a", "c"], ["a", "b", "c"]),
49+
).toEqual(["a", "c"]);
3850
});
3951

4052
test("falls back to all runs when none of the previously selected runs exist anymore", () => {
41-
expect(reconcileSelectedRuns(["a"], ["b"])).toEqual(["b"]);
42-
expect(reconcileSelectedRuns(["x", "y"], ["a", "b", "c"])).toEqual([
43-
"a",
44-
"b",
45-
"c",
46-
]);
53+
expect(reconcileSelectedRuns(["a"], ["b"], ["a"])).toEqual(["b"]);
54+
expect(
55+
reconcileSelectedRuns(["x", "y"], ["a", "b", "c"], ["x", "y"]),
56+
).toEqual(["a", "b", "c"]);
4757
});
4858
});

0 commit comments

Comments
 (0)