fix(grid): append infinite scroll result segments
This commit is contained in:
1 parent
678033c82e
commit
c153e93d54
9 files changed
+303
-30
No files matched your search
@@ -2269,6 +2269,8 @@ const isInfiniteScrollPaginating = ref(false);
|
||||
let lastInfiniteScrollPage = 0;
|
||||
let infiniteScrollCheckScheduled = false;
|
||||
let infiniteScrollAllLoaded = false;
|
||||
let infiniteScrollRequestedOffset: number | undefined;
|
||||
let infiniteScrollRequestedLimit: number | undefined;
|
||||
// Tracks whether the current loading cycle was triggered by a refresh/rollback
|
||||
// (as opposed to a normal paginate). Used to decide whether to auto-redirect
|
||||
// when the current page no longer exists after data was deleted.
|
||||
@@ -2313,9 +2315,19 @@ watch(
|
||||
if (prevLoading && !loading && infiniteScrollLoading.value) {
|
||||
infiniteScrollLoading.value = false;
|
||||
isInfiniteScrollPaginating.value = false;
|
||||
// Detect if the backend returned no new data for this page
|
||||
const expectedRows = currentPage.value * pageSize.value;
|
||||
if (props.result.rows.length < expectedRows) {
|
||||
const requestedOffset = infiniteScrollRequestedOffset;
|
||||
const requestedLimit = infiniteScrollRequestedLimit;
|
||||
infiniteScrollRequestedOffset = undefined;
|
||||
infiniteScrollRequestedLimit = undefined;
|
||||
if (requestedOffset === undefined || props.result.appended_from_row_count !== requestedOffset) {
|
||||
// Failed/stale append requests preserve the old result. Roll back the
|
||||
// optimistic page marker so a later scroll can retry the same segment.
|
||||
currentPage.value = Math.max(1, currentPage.value - 1);
|
||||
lastInfiniteScrollPage = Math.max(0, currentPage.value - 1);
|
||||
return;
|
||||
}
|
||||
const appendedRows = props.result.rows.length - requestedOffset;
|
||||
if (props.result.rows.length >= infiniteScrollMaxRows.value || appendedRows < (requestedLimit ?? pageSize.value)) {
|
||||
infiniteScrollAllLoaded = true;
|
||||
}
|
||||
}
|
||||
@@ -2489,21 +2501,21 @@ function nextPage() {
|
||||
|
||||
function infiniteScrollNextPage() {
|
||||
if (infiniteScrollLoading.value || props.loading) return;
|
||||
const nextOffset = props.result.rows.length;
|
||||
const remainingRows = infiniteScrollMaxRows.value - nextOffset;
|
||||
if (remainingRows <= 0) return;
|
||||
const nextLimit = Math.min(pageSize.value, remainingRows);
|
||||
const nextPageNum = currentPage.value + 1;
|
||||
const cumulativeLimit = nextPageNum * pageSize.value;
|
||||
if (cumulativeLimit > infiniteScrollMaxRows.value) return;
|
||||
// Stop if we already know all data is loaded
|
||||
if (infiniteScrollAllLoaded) return;
|
||||
// Skip if we already have this many rows loaded (e.g. cached data)
|
||||
if (props.result.rows.length >= cumulativeLimit) {
|
||||
currentPage.value = nextPageNum;
|
||||
return;
|
||||
}
|
||||
infiniteScrollLoading.value = true;
|
||||
isInfiniteScrollPaginating.value = true;
|
||||
infiniteScrollRequestedOffset = nextOffset;
|
||||
infiniteScrollRequestedLimit = nextLimit;
|
||||
currentPage.value = nextPageNum;
|
||||
// Load cumulative data (all rows up to current page) to append instead of replace
|
||||
emit("paginate", 0, cumulativeLimit, currentWhereInput(), currentOrderBy());
|
||||
// Fetch only the missing segment. Re-reading offset 0 grows transfer and replaces
|
||||
// row identities, which would invalidate pending edits while the user scrolls.
|
||||
emit("paginate", nextOffset, nextLimit, currentWhereInput(), currentOrderBy());
|
||||
}
|
||||
function checkInfiniteScroll(scroller: HTMLElement) {
|
||||
if (!infiniteScrollEnabled.value || infiniteScrollLoading.value || props.loading) return;
|
||||
@@ -2969,6 +2981,8 @@ function resetInfiniteScrollState() {
|
||||
currentPage.value = 1;
|
||||
lastInfiniteScrollPage = 0;
|
||||
infiniteScrollAllLoaded = false;
|
||||
infiniteScrollRequestedOffset = undefined;
|
||||
infiniteScrollRequestedLimit = undefined;
|
||||
isInfiniteScrollPaginating.value = false;
|
||||
infiniteScrollLoading.value = false;
|
||||
infiniteScrollPositions = new WeakMap();
|
||||
|
||||
Reference in new issue
Block a user