Skip to content

Commit 8170888

Browse files
authored
fix: "Showing 1-0 of 0" in TUI, cache unfiltered total count through search reset (#196)
## Description <!-- Provide a brief description of your changes --> **Note:** PR titles should follow [Conventional Commits](https://www.conventionalcommits.org/) format (e.g., `feat(devbox): add support for custom env vars` or `fix(snapshot): resolve pagination issue`) as they are used for automatic release notes generation. ## Type of Change <!-- Mark the relevant option with an 'x' --> - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] Documentation update - [ ] Code refactoring - [ ] Performance improvement - [ ] Test updates ## Related Issues <!-- Link to related issues using #issue-number --> Closes # ## Changes Made <!-- Describe the changes in detail --> ## Testing <!-- Describe how you tested your changes --> - [ ] I have tested locally - [ ] I have added/updated tests - [ ] All existing tests pass ## Checklist - [ ] My code follows the code style of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have updated the documentation accordingly - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published ## Screenshots (if applicable) <!-- Add screenshots to help explain your changes --> ## Additional Notes <!-- Any additional information that reviewers should know -->
1 parent 5462e68 commit 8170888

6 files changed

Lines changed: 90 additions & 48 deletions

File tree

src/components/ResourcePicker.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -461,13 +461,17 @@ export function ResourcePicker<T>({
461461
)}
462462
</>
463463
)}
464-
<Text color={colors.textDim} dimColor>
465-
{" "}
466-
{" "}
467-
</Text>
468-
<Text color={colors.textDim} dimColor>
469-
Showing {startIndex + 1}-{endIndex} of {totalCount}
470-
</Text>
464+
{endIndex > startIndex && (
465+
<>
466+
<Text color={colors.textDim} dimColor>
467+
{" "}
468+
{" "}
469+
</Text>
470+
<Text color={colors.textDim} dimColor>
471+
Showing {startIndex + 1}-{endIndex} of {totalCount}
472+
</Text>
473+
</>
474+
)}
471475
</Box>
472476

473477
{/* Help Bar */}

src/hooks/useCursorPagination.ts

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ export function useCursorPagination<T>(
111111
// Abort controller for cancelling in-flight count requests
112112
const countAbortRef = React.useRef<AbortController | null>(null);
113113

114+
// Cache the unfiltered (initial deps) total count to avoid re-fetching on filter clear
115+
const initialDepsKeyRef = React.useRef<string>(JSON.stringify(deps));
116+
const baseTotalCountRef = React.useRef<number | null>(null);
117+
const depsKeyRef = React.useRef<string>(JSON.stringify(deps));
118+
114119
// Cursor history: cursorHistory[N] = last item ID of page N
115120
// Used to determine startingAt for page N+1
116121
const cursorHistoryRef = React.useRef<(string | undefined)[]>([]);
@@ -206,8 +211,13 @@ export function useCursorPagination<T>(
206211
// Cancel the background count request if still pending.
207212
if (!result.hasMore && !hasCachedTotalCountRef.current) {
208213
countAbortRef.current?.abort();
209-
setTotalCount(page * pageSizeRef.current + result.items.length);
214+
const computedTotal =
215+
page * pageSizeRef.current + result.items.length;
216+
setTotalCount(computedTotal);
210217
hasCachedTotalCountRef.current = true;
218+
if (depsKeyRef.current === initialDepsKeyRef.current) {
219+
baseTotalCountRef.current = computedTotal;
220+
}
211221
}
212222
} catch (err) {
213223
if (!isMountedRef.current) return;
@@ -226,6 +236,7 @@ export function useCursorPagination<T>(
226236
// Reset when deps change (e.g., filters, search)
227237
const depsKey = JSON.stringify(deps);
228238
React.useEffect(() => {
239+
depsKeyRef.current = depsKey;
229240
// Clear cursor history when deps change
230241
cursorHistoryRef.current = [];
231242
hasCachedTotalCountRef.current = false;
@@ -243,18 +254,29 @@ export function useCursorPagination<T>(
243254
// Data fetch
244255
fetchPageData(0, true);
245256

246-
// Background count fetch — fires immediately alongside data
247-
fetchPageRef
248-
.current({ limit: 0, startingAt: undefined, includeTotalCount: true })
249-
.then((result) => {
250-
if (cancelled || countAbort.signal.aborted || !isMountedRef.current)
251-
return;
252-
if (result.totalCount !== undefined) {
253-
setTotalCount(result.totalCount);
254-
hasCachedTotalCountRef.current = true;
255-
}
256-
})
257-
.catch(() => {}); // count failure is non-critical
257+
// If returning to unfiltered state and we have a cached base count, reuse it
258+
const isUnfiltered = depsKey === initialDepsKeyRef.current;
259+
if (isUnfiltered && baseTotalCountRef.current !== null) {
260+
setTotalCount(baseTotalCountRef.current);
261+
hasCachedTotalCountRef.current = true;
262+
} else {
263+
// Background count fetch — fires immediately alongside data
264+
fetchPageRef
265+
.current({ limit: 0, startingAt: undefined, includeTotalCount: true })
266+
.then((result) => {
267+
if (cancelled || countAbort.signal.aborted || !isMountedRef.current)
268+
return;
269+
if (result.totalCount !== undefined) {
270+
setTotalCount(result.totalCount);
271+
hasCachedTotalCountRef.current = true;
272+
// Cache the unfiltered total count
273+
if (isUnfiltered) {
274+
baseTotalCountRef.current = result.totalCount;
275+
}
276+
}
277+
})
278+
.catch(() => {}); // count failure is non-critical
279+
}
258280

259281
return () => {
260282
cancelled = true;

src/screens/BenchmarkJobListScreen.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -635,13 +635,17 @@ export function BenchmarkJobListScreen() {
635635
)}
636636
</>
637637
)}
638-
<Text color={colors.textDim} dimColor>
639-
{" "}
640-
{" "}
641-
</Text>
642-
<Text color={colors.textDim} dimColor>
643-
Showing {startIndex + 1}-{endIndex} of {totalCount}
644-
</Text>
638+
{endIndex > startIndex && (
639+
<>
640+
<Text color={colors.textDim} dimColor>
641+
{" "}
642+
{" "}
643+
</Text>
644+
<Text color={colors.textDim} dimColor>
645+
Showing {startIndex + 1}-{endIndex} of {totalCount}
646+
</Text>
647+
</>
648+
)}
645649
</Box>
646650
)}
647651

src/screens/BenchmarkListScreen.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -376,13 +376,17 @@ export function BenchmarkListScreen() {
376376
)}
377377
</>
378378
)}
379-
<Text color={colors.textDim} dimColor>
380-
{" "}
381-
{" "}
382-
</Text>
383-
<Text color={colors.textDim} dimColor>
384-
Showing {startIndex + 1}-{endIndex} of {totalCount}
385-
</Text>
379+
{endIndex > startIndex && (
380+
<>
381+
<Text color={colors.textDim} dimColor>
382+
{" "}
383+
{" "}
384+
</Text>
385+
<Text color={colors.textDim} dimColor>
386+
Showing {startIndex + 1}-{endIndex} of {totalCount}
387+
</Text>
388+
</>
389+
)}
386390
</Box>
387391
)}
388392

src/screens/BenchmarkRunListScreen.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -377,13 +377,17 @@ export function BenchmarkRunListScreen() {
377377
)}
378378
</>
379379
)}
380-
<Text color={colors.textDim} dimColor>
381-
{" "}
382-
{" "}
383-
</Text>
384-
<Text color={colors.textDim} dimColor>
385-
Showing {startIndex + 1}-{endIndex} of {totalCount}
386-
</Text>
380+
{endIndex > startIndex && (
381+
<>
382+
<Text color={colors.textDim} dimColor>
383+
{" "}
384+
{" "}
385+
</Text>
386+
<Text color={colors.textDim} dimColor>
387+
Showing {startIndex + 1}-{endIndex} of {totalCount}
388+
</Text>
389+
</>
390+
)}
387391
</Box>
388392
)}
389393

src/screens/ScenarioRunListScreen.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -365,13 +365,17 @@ export function ScenarioRunListScreen({
365365
)}
366366
</>
367367
)}
368-
<Text color={colors.textDim} dimColor>
369-
{" "}
370-
{" "}
371-
</Text>
372-
<Text color={colors.textDim} dimColor>
373-
Showing {startIndex + 1}-{endIndex} of {totalCount}
374-
</Text>
368+
{endIndex > startIndex && (
369+
<>
370+
<Text color={colors.textDim} dimColor>
371+
{" "}
372+
{" "}
373+
</Text>
374+
<Text color={colors.textDim} dimColor>
375+
Showing {startIndex + 1}-{endIndex} of {totalCount}
376+
</Text>
377+
</>
378+
)}
375379
{benchmarkRunId && (
376380
<>
377381
<Text color={colors.textDim} dimColor>

0 commit comments

Comments
 (0)