1
0
Fork 0
mirror of synced 2024-09-08 05:31:47 +12:00

Ensure all derived stores have default values

This commit is contained in:
Andrew Kingston 2023-03-11 19:20:38 +00:00
parent 38a3ef0c34
commit d7666272e0
9 changed files with 153 additions and 110 deletions

View file

@ -9,24 +9,32 @@ export const createColumnsStores = context => {
// Derive an enriched version of columns with left offsets and indexes
// automatically calculated
const enrichedColumns = derived(columns, $columns => {
let offset = 0
return $columns.map(column => {
const enriched = {
...column,
left: offset,
}
if (column.visible) {
offset += column.width
}
return enriched
})
})
const enrichedColumns = derived(
columns,
$columns => {
let offset = 0
return $columns.map(column => {
const enriched = {
...column,
left: offset,
}
if (column.visible) {
offset += column.width
}
return enriched
})
},
[]
)
// Derived list of columns which have not been explicitly hidden
const visibleColumns = derived(enrichedColumns, $columns => {
return $columns.filter(col => col.visible)
})
const visibleColumns = derived(
enrichedColumns,
$columns => {
return $columns.filter(col => col.visible)
},
[]
)
// Merge new schema fields with existing schema in order to preserve widths
schema.subscribe($schema => {

View file

@ -11,7 +11,11 @@ export const createReorderStores = context => {
sheetLeft: 0,
}
const reorder = writable(reorderInitialState)
const isReordering = derived(reorder, $reorder => !!$reorder.sourceColumn)
const isReordering = derived(
reorder,
$reorder => !!$reorder.sourceColumn,
false
)
// Callback when dragging on a colum header and starting reordering
const startReordering = (column, e) => {

View file

@ -14,7 +14,7 @@ export const createResizeStores = context => {
left: 0,
}
const resize = writable(initialState)
const isResizing = derived(resize, $resize => $resize.column != null)
const isResizing = derived(resize, $resize => $resize.column != null, false)
// Starts resizing a certain column
const startResizing = (column, e) => {

View file

@ -18,21 +18,29 @@ export const createRowsStore = context => {
const sort = writable(initialSortState)
// Enrich rows with an index property
const enrichedRows = derived(rows, $rows => {
return $rows.map((row, idx) => ({
...row,
__idx: idx,
}))
})
const enrichedRows = derived(
rows,
$rows => {
return $rows.map((row, idx) => ({
...row,
__idx: idx,
}))
},
[]
)
// Generate a lookup map to quick find a row by ID
const rowLookupMap = derived(enrichedRows, $rows => {
let map = {}
for (let row of $rows) {
map[row._id] = row.__idx
}
return map
})
const rowLookupMap = derived(
enrichedRows,
$rows => {
let map = {}
for (let row of $rows) {
map[row._id] = row.__idx
}
return map
},
{}
)
// Local cache of row IDs to speed up checking if a row exists
let rowCacheMap = {}

View file

@ -9,8 +9,8 @@ export const createScrollStores = context => {
})
// Memoize store primitives
const scrollTop = derived(scroll, $scroll => $scroll.top)
const scrollLeft = derived(scroll, $scroll => $scroll.left)
const scrollTop = derived(scroll, $scroll => $scroll.top, 0)
const scrollLeft = derived(scroll, $scroll => $scroll.left, 0)
// Derive vertical limits
const height = derived(bounds, $bounds => $bounds.height, 0)
@ -80,6 +80,23 @@ export const createScrollStores = context => {
}
})
// Fetch next page when fewer than 50 scrollable rows remaining
const scrollableRows = derived(
[scrollTop, maxScrollTop],
([$scrollTop, $maxScrollTop]) => {
if (!$maxScrollTop) {
return 100
}
return ($maxScrollTop - $scrollTop) / cellHeight
},
100
)
scrollableRows.subscribe(count => {
if (count < 25) {
rows.actions.loadNextPage()
}
})
return {
scroll,
contentHeight,

View file

@ -14,7 +14,8 @@ export const createUIStores = context => {
const rowId = $selectedCellId?.split("-")[0]
const index = $rowLookupMap[rowId]
return $rows[index]
}
},
null
)
// Ensure we clear invalid rows from state if they disappear

View file

@ -5,50 +5,70 @@ export const createUserStores = () => {
const userId = writable(null)
// Enrich users with unique colours
const enrichedUsers = derived([users, userId], ([$users, $userId]) => {
return (
$users
.slice()
// Place current user first
.sort((a, b) => {
if (a.id === $userId) {
return -1
} else if (b.id === $userId) {
return 1
} else {
return 0
}
})
// Enrich users with colors
.map((user, idx) => {
// Generate random colour hue
let hue = 1
for (let i = 0; i < user.email.length && i < 5; i++) {
hue *= user.email.charCodeAt(i)
}
hue = hue % 360
const color =
idx === 0
? "var(--spectrum-global-color-blue-400)"
: `hsl(${hue}, 50%, 40%)`
// Generate friendly label
let label = user.email
if (user.firstName) {
label = user.firstName
if (user.lastName) {
label += ` ${user.lastName}`
const enrichedUsers = derived(
[users, userId],
([$users, $userId]) => {
return (
$users
.slice()
// Place current user first
.sort((a, b) => {
if (a.id === $userId) {
return -1
} else if (b.id === $userId) {
return 1
} else {
return 0
}
}
})
// Enrich users with colors
.map((user, idx) => {
// Generate random colour hue
let hue = 1
for (let i = 0; i < user.email.length && i < 5; i++) {
hue *= user.email.charCodeAt(i)
}
hue = hue % 360
const color =
idx === 0
? "var(--spectrum-global-color-blue-400)"
: `hsl(${hue}, 50%, 40%)`
return {
...user,
color,
label,
}
})
)
})
// Generate friendly label
let label = user.email
if (user.firstName) {
label = user.firstName
if (user.lastName) {
label += ` ${user.lastName}`
}
}
return {
...user,
color,
label,
}
})
)
},
[]
)
// Generate a lookup map of cell ID to the user that has it selected, to make
// lookups inside sheet cells extremely fast
const selectedCellMap = derived(
[enrichedUsers, userId],
([$enrichedUsers, $userId]) => {
let map = {}
$enrichedUsers.forEach(user => {
if (user.selectedCellId && user.id !== $userId) {
map[user.selectedCellId] = user
}
})
return map
},
{}
)
const updateUser = user => {
const $users = get(users)
@ -69,21 +89,6 @@ export const createUserStores = () => {
})
}
// Generate a lookup map of cell ID to the user that has it selected, to make
// lookups inside sheet cells extremely fast
const selectedCellMap = derived(
[enrichedUsers, userId],
([$enrichedUsers, $userId]) => {
let map = {}
$enrichedUsers.forEach(user => {
if (user.selectedCellId && user.id !== $userId) {
map[user.selectedCellId] = user
}
})
return map
}
)
return {
users: {
...enrichedUsers,

View file

@ -6,23 +6,32 @@ export const createViewportStores = context => {
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)
const width = derived(bounds, $bounds => $bounds.width, 0)
const height = derived(bounds, $bounds => $bounds.height, 0)
// 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 renderedRowCount = derived(height, $height => {
return Math.ceil($height / cellHeight)
})
const firstRowIdx = derived(
scrollTop,
$scrollTop => {
return Math.floor($scrollTop / cellHeight)
},
0
)
const renderedRowCount = derived(
height,
$height => {
return Math.ceil($height / cellHeight)
},
0
)
const renderedRows = derived(
[rows, firstRowIdx, renderedRowCount],
([$rows, $firstRowIdx, $visibleRowCount]) => {
return $rows.slice($firstRowIdx, $firstRowIdx + $visibleRowCount)
}
},
[]
)
// Derive visible columns
@ -65,15 +74,5 @@ export const createViewportStores = context => {
[]
)
// Fetch next page when approaching end of data
renderedRows.subscribe($renderedRows => {
const lastVisible = $renderedRows[$renderedRows.length - 1]
const $rows = get(rows)
const lastRow = $rows[$rows.length - 1]
if (lastVisible && lastRow && lastVisible._id === lastRow._id) {
rows.actions.loadNextPage()
}
})
return { renderedRows, renderedColumns }
}

View file

@ -419,6 +419,7 @@ export default class DataFetch {
if (state.loading || !this.options.paginate || !state.hasNextPage) {
return
}
console.log("NEXT PAGE")
// Fetch next page
const nextCursor = state.cursors[state.pageNumber + 1]