Skip to content

Commit 3052b89

Browse files
committed
fix: Improve infinite scroll virtualization and item count handling in table widget
1 parent 23c5200 commit 3052b89

File tree

4 files changed

+31
-29
lines changed

4 files changed

+31
-29
lines changed

app/client/src/widgets/TableWidgetV2/component/TableBody/InifiniteScrollBody/index.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ interface InfiniteScrollBodyProps {
1515
innerElementType?: ReactElementType;
1616
isLoading: boolean;
1717
totalRecordsCount?: number;
18-
itemCount: number;
1918
loadMoreFromEvaluations: () => void;
2019
pageSize: number;
2120
}
@@ -51,9 +50,9 @@ const InfiniteScrollBody = React.forwardRef(
5150
height={props.height}
5251
infiniteLoaderListRef={infiniteLoaderRef}
5352
innerElementType={props.innerElementType}
53+
itemCount={itemCount}
5454
onItemsRendered={onItemsRendered}
5555
outerRef={ref}
56-
pageSize={props.pageSize}
5756
rows={cachedRows}
5857
tableSizes={props.tableSizes}
5958
/>

app/client/src/widgets/TableWidgetV2/component/TableBody/InifiniteScrollBody/useInfiniteVirtualization.tsx

+26-23
Original file line numberDiff line numberDiff line change
@@ -27,42 +27,41 @@ export const useInfiniteVirtualization = ({
2727
rows,
2828
totalRecordsCount,
2929
}: UseInfiniteVirtualizationProps): UseInfiniteVirtualizationReturn => {
30-
// Keep track of which pages are loaded
3130
const [loadedPages, setLoadedPages] = useState<LoadedRowsCache>({});
32-
33-
// Keep track of the last loaded page for appending new data
3431
const lastLoadedPageRef = useRef<number>(0);
32+
const hasMoreDataRef = useRef<boolean>(true); // Track if more data is available
3533

36-
// Calculate max possible pages based on total records
3734
const maxPages = useMemo(() => {
3835
if (!totalRecordsCount) return Infinity;
3936

4037
return Math.ceil(totalRecordsCount / pageSize);
4138
}, [totalRecordsCount, pageSize]);
4239

43-
// Effect to handle new data
4440
useEffect(() => {
4541
if (rows.length > 0) {
46-
// Since we know we get pageSize number of rows each time (except possibly last page)
47-
// we can calculate the current page index
4842
const currentPageIndex = lastLoadedPageRef.current;
4943

50-
// Store the current page of rows in cache
5144
setLoadedPages((prev) => ({
5245
...prev,
5346
[currentPageIndex]: rows,
5447
}));
5548

56-
// Increment the last loaded page counter for next load
57-
lastLoadedPageRef.current = currentPageIndex + 1;
49+
// Only increment if we got a full page or some data
50+
if (rows.length === pageSize) {
51+
lastLoadedPageRef.current = currentPageIndex + 1;
52+
} else if (rows.length < pageSize && rows.length > 0) {
53+
// If we got less than a full page, assume this is the last page
54+
hasMoreDataRef.current = false;
55+
}
56+
} else if (rows.length === 0 && lastLoadedPageRef.current > 0) {
57+
// If no rows are returned and we've loaded at least one page, assume end of data
58+
hasMoreDataRef.current = false;
5859
}
5960
}, [rows, pageSize]);
6061

61-
// Memoize the combined rows from cache
6262
const cachedRows = useMemo(() => {
6363
const allRows: ReactTableRowType<Record<string, unknown>>[] = [];
6464

65-
// Add all rows from cache in order
6665
Object.keys(loadedPages)
6766
.map(Number)
6867
.sort((a, b) => a - b)
@@ -77,25 +76,29 @@ export const useInfiniteVirtualization = ({
7776
(index: number) => {
7877
const pageIndex = Math.floor(index / pageSize);
7978

80-
// Consider items loaded if we've reached max pages or if the page is already loaded
81-
return pageIndex >= maxPages || pageIndex < lastLoadedPageRef.current;
79+
return (
80+
pageIndex >= maxPages ||
81+
pageIndex < lastLoadedPageRef.current ||
82+
!hasMoreDataRef.current
83+
);
8284
},
8385
[pageSize, maxPages],
8486
);
8587

86-
// const itemCount = useMemo(() => {
87-
// return totalRecordsCount || cachedRows.length;
88-
// }, [totalRecordsCount, cachedRows.length]);
88+
const itemCount = useMemo(() => {
89+
// If we know there's no more data, cap itemCount at cachedRows.length
90+
if (!hasMoreDataRef.current) {
91+
return cachedRows.length;
92+
}
93+
94+
return totalRecordsCount || cachedRows.length;
95+
}, [totalRecordsCount, cachedRows.length]);
8996

9097
const loadMoreItems = useCallback(
9198
async (startIndex: number, stopIndex: number) => {
92-
if (!isLoading) {
99+
if (!isLoading && hasMoreDataRef.current) {
93100
const targetPage = Math.floor(stopIndex / pageSize);
94101

95-
// Only load if:
96-
// 1. We haven't loaded this page yet
97-
// 2. We haven't reached the max number of pages
98-
// 3. We're not currently loading
99102
if (targetPage >= lastLoadedPageRef.current && targetPage < maxPages) {
100103
loadMore();
101104
}
@@ -108,7 +111,7 @@ export const useInfiniteVirtualization = ({
108111

109112
return {
110113
isItemLoaded,
111-
itemCount: totalRecordsCount || Infinity,
114+
itemCount,
112115
loadMoreItems,
113116
cachedRows,
114117
};

app/client/src/widgets/TableWidgetV2/component/TableBody/VirtualList.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,20 @@ interface BaseVirtualListProps {
3232
height: number;
3333
tableSizes: TableSizes;
3434
rows: ReactTableRowType<Record<string, unknown>>[];
35-
pageSize: number;
3635
innerElementType?: ReactElementType;
3736
outerRef?: React.Ref<SimpleBar>;
3837
onItemsRendered?: (props: ListOnItemsRenderedProps) => void;
3938
infiniteLoaderListRef?: React.Ref<FixedSizeList>;
39+
itemCount: number;
4040
}
4141

4242
const BaseVirtualList = React.memo(function BaseVirtualList({
4343
height,
4444
infiniteLoaderListRef,
4545
innerElementType,
46+
itemCount,
4647
onItemsRendered,
4748
outerRef,
48-
pageSize,
4949
rows,
5050
tableSizes,
5151
}: BaseVirtualListProps) {
@@ -58,7 +58,7 @@ const BaseVirtualList = React.memo(function BaseVirtualList({
5858
2 * tableSizes.VERTICAL_PADDING
5959
}
6060
innerElementType={innerElementType}
61-
itemCount={Math.max(rows.length, pageSize)}
61+
itemCount={itemCount}
6262
itemData={rows}
6363
itemSize={tableSizes.ROW_HEIGHT}
6464
onItemsRendered={onItemsRendered}

app/client/src/widgets/TableWidgetV2/widget/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1960,7 +1960,7 @@ class TableWidgetV2 extends BaseWidget<TableWidgetProps, WidgetState> {
19601960
originalIndex = rowIndex === 0 ? -1 : row[ORIGINAL_INDEX_KEY] ?? rowIndex;
19611961
} else {
19621962
row = filteredTableData[rowIndex];
1963-
originalIndex = row[ORIGINAL_INDEX_KEY] ?? rowIndex;
1963+
originalIndex = row ? row[ORIGINAL_INDEX_KEY] ?? rowIndex : rowIndex;
19641964
}
19651965

19661966
const isNewRow = this.props.isAddRowInProgress && rowIndex === 0;

0 commit comments

Comments
 (0)