diff --git a/code/frontend/src/app/features/seeker-stats/searches-tab/searches-tab.component.html b/code/frontend/src/app/features/seeker-stats/searches-tab/searches-tab.component.html
index 16e3b8c5..33a6d91a 100644
--- a/code/frontend/src/app/features/seeker-stats/searches-tab/searches-tab.component.html
+++ b/code/frontend/src/app/features/seeker-stats/searches-tab/searches-tab.component.html
@@ -77,9 +77,9 @@
- {{ inst.cycleStartedAt ? formatCycleDuration(inst.cycleStartedAt) : '—' }}
+ {{ cycleDuration(inst) }}
-
+
Cycle Duration
diff --git a/code/frontend/src/app/features/seeker-stats/searches-tab/searches-tab.component.spec.ts b/code/frontend/src/app/features/seeker-stats/searches-tab/searches-tab.component.spec.ts
index 474dd52a..2944148c 100644
--- a/code/frontend/src/app/features/seeker-stats/searches-tab/searches-tab.component.spec.ts
+++ b/code/frontend/src/app/features/seeker-stats/searches-tab/searches-tab.component.spec.ts
@@ -403,15 +403,19 @@ describe('SearchesTabComponent', () => {
expect(component.searchReasonSeverity('Whatever')).toBe('default');
});
- it('formats the cycle duration down to the largest non-zero unit', () => {
+ it('measures a running cycle until now and a completed cycle until its completion', () => {
const { component } = setup();
vi.useFakeTimers();
vi.setSystemTime(new Date('2026-07-31T12:00:00Z'));
- expect(component.formatCycleDuration('2026-07-29T09:00:00Z')).toBe('2d 3h');
- expect(component.formatCycleDuration('2026-07-31T07:00:00Z')).toBe('5h');
- expect(component.formatCycleDuration('2026-07-31T11:30:00Z')).toBe('30m');
+ expect(component.cycleDuration(instance({ cycleStartedAt: '2026-07-29T09:00:00Z' }))).toBe('2d 3h');
+ expect(component.cycleDuration(instance({ cycleStartedAt: '2026-07-31T11:30:00Z' }))).toBe('30m');
+ expect(component.cycleDuration(instance({
+ cycleStartedAt: '2026-07-29T09:00:00Z',
+ cycleCompletedAt: '2026-07-29T09:20:00Z',
+ }))).toBe('20m');
+ expect(component.cycleDuration(instance({ cycleStartedAt: null }))).toBe('—');
});
it('toasts the error message when loading search stats fails', () => {
diff --git a/code/frontend/src/app/features/seeker-stats/searches-tab/searches-tab.component.ts b/code/frontend/src/app/features/seeker-stats/searches-tab/searches-tab.component.ts
index dd76e763..6ffa0614 100644
--- a/code/frontend/src/app/features/seeker-stats/searches-tab/searches-tab.component.ts
+++ b/code/frontend/src/app/features/seeker-stats/searches-tab/searches-tab.component.ts
@@ -316,7 +316,16 @@ export class SearchesTabComponent {
readonly searchReasonSeverity = searchReasonSeverity;
readonly cycleProgress = cycleProgress;
readonly instanceHealthWarning = instanceHealthWarning;
- readonly formatCycleDuration = formatCycleDuration;
+
+ cycleDuration(inst: InstanceSearchStat): string {
+ const { cycleStartedAt, cycleCompletedAt } = inst;
+ if (!cycleStartedAt) {
+ return '—';
+ }
+ return cycleCompletedAt
+ ? formatDurationBetween(cycleStartedAt, cycleCompletedAt)
+ : formatCycleDuration(cycleStartedAt);
+ }
lastCycleDuration(inst: InstanceSearchStat): string {
const { lastCycleStartedAt, lastCycleCompletedAt } = inst;