Ensure all derived stores have default values
This commit is contained in:
parent
38a3ef0c34
commit
d7666272e0
|
@ -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 => {
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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 = {}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
|
|
|
@ -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]
|
||||
|
|
Loading…
Reference in New Issue