diff --git a/packages/frontend-core/src/components/sheet/HeaderRow.svelte b/packages/frontend-core/src/components/sheet/HeaderRow.svelte
index 71fd1237cc..01a50d07f2 100644
--- a/packages/frontend-core/src/components/sheet/HeaderRow.svelte
+++ b/packages/frontend-core/src/components/sheet/HeaderRow.svelte
@@ -38,13 +38,5 @@
diff --git a/packages/frontend-core/src/components/sheet/NewRow.svelte b/packages/frontend-core/src/components/sheet/NewRow.svelte
index 764c207228..63985febf0 100644
--- a/packages/frontend-core/src/components/sheet/NewRow.svelte
+++ b/packages/frontend-core/src/components/sheet/NewRow.svelte
@@ -29,8 +29,6 @@
diff --git a/packages/frontend-core/src/components/sheet/stores/rows.js b/packages/frontend-core/src/components/sheet/stores/rows.js
index 840798f1e2..0c4785ddba 100644
--- a/packages/frontend-core/src/components/sheet/stores/rows.js
+++ b/packages/frontend-core/src/components/sheet/stores/rows.js
@@ -4,7 +4,7 @@ import { fetchData } from "../../../fetch/fetchData"
import { notifications } from "@budibase/bbui"
export const createRowsStore = context => {
- const { tableId, filter, API } = context
+ const { tableId, filter, API, scroll } = context
// Flag for whether this is the first time loading our fetch
let loaded = false
@@ -61,12 +61,17 @@ export const createRowsStore = context => {
loaded = true
rowCacheMap = {}
rows.set([])
+
+ // Enrich primary display into schema
let newSchema = $$fetch.schema
const primaryDisplay = $$fetch.definition?.primaryDisplay
if (primaryDisplay && newSchema[primaryDisplay]) {
newSchema[primaryDisplay].primaryDisplay = true
}
schema.set(newSchema)
+
+ // Reset scroll state for fresh dataset
+ scroll.set({ left: 0, top: 0 })
}
// Process new rows
diff --git a/packages/frontend-core/src/components/sheet/stores/viewport.js b/packages/frontend-core/src/components/sheet/stores/viewport.js
index 56987006a7..ef95965ff7 100644
--- a/packages/frontend-core/src/components/sheet/stores/viewport.js
+++ b/packages/frontend-core/src/components/sheet/stores/viewport.js
@@ -1,64 +1,53 @@
-import { writable, derived, get } from "svelte/store"
+import { derived, get } from "svelte/store"
export const createViewportStores = context => {
const { cellHeight, columns, rows, scroll, bounds } = context
-
- // Use local variables to avoid needing to invoke 2 svelte getters each time
- // scroll state changes, but also use stores to allow use of derived stores
- let scrollTop = 0
- let scrollLeft = 0
- const scrollTopStore = writable(0)
- const scrollLeftStore = writable(0)
+ const scrollTop = derived(scroll, $scroll => $scroll.top, 0)
+ const scrollLeft = derived(scroll, $scroll => $scroll.left, 0)
// Derive height and width as primitives to avoid wasted computation
const width = derived(bounds, $bounds => $bounds.width)
const height = derived(bounds, $bounds => $bounds.height)
- // Debounce scroll updates so we can slow down visible row computation
- scroll.subscribe(({ left, top }) => {
- scrollTop = top
- scrollTopStore.set(top)
- scrollLeft = left
- scrollLeftStore.set(left)
- })
-
// Derive visible rows
+ // Split into multiple stores containing primitives to optimise invalidation
+ // as mich as possible
+ const firstRowIdx = derived(scrollTop, $scrollTop => {
+ return Math.floor($scrollTop / cellHeight)
+ })
+ const visibleRowCount = derived(height, $height => {
+ return Math.ceil($height / cellHeight)
+ })
const visibleRows = derived(
- [rows, scrollTopStore, height],
- ([$rows, $scrollTop, $height]) => {
- const maxRows = Math.ceil($height / cellHeight) + 1
- const firstRow = Math.max(0, Math.floor($scrollTop / cellHeight))
- return $rows.slice(firstRow, firstRow + maxRows)
+ [rows, firstRowIdx, visibleRowCount],
+ ([$rows, $firstRowIdx, $visibleRowCount]) => {
+ return $rows.slice($firstRowIdx, $firstRowIdx + $visibleRowCount)
}
)
// Derive visible columns
const visibleColumns = derived(
- [columns, scrollLeftStore, width],
+ [columns, scrollLeft, width],
([$columns, $scrollLeft, $width]) => {
if (!$columns.length) {
return []
}
let startColIdx = 0
let rightEdge = $columns[0].width
- while (rightEdge < $scrollLeft) {
+ while (rightEdge < $scrollLeft && startColIdx < $columns.length - 1) {
startColIdx++
rightEdge += $columns[startColIdx].width
}
let endColIdx = startColIdx + 1
let leftEdge = rightEdge
- while (leftEdge < $width + $scrollLeft) {
- leftEdge += $columns[endColIdx]?.width
+ while (leftEdge < $width + $scrollLeft && endColIdx < $columns.length) {
+ leftEdge += $columns[endColIdx].width
endColIdx++
}
- return $columns.slice(Math.max(0, startColIdx - 1), endColIdx + 1)
+ return $columns.slice(startColIdx, endColIdx)
}
)
- // visibleColumns.subscribe(state => {
- // console.log(state)
- // })
-
// Fetch next page when approaching end of data
visibleRows.subscribe($visibleRows => {
const lastVisible = $visibleRows[$visibleRows.length - 1]