Handle crash when other user deletes a row that is either the source or target of cell selection

This commit is contained in:
Andrew Kingston 2024-06-24 15:25:00 +01:00
parent 5c6cb0a73a
commit e0c38d7fbe
No known key found for this signature in database
2 changed files with 22 additions and 27 deletions

View File

@ -638,14 +638,6 @@ export const createActions = context => {
get(fetch)?.nextPage() get(fetch)?.nextPage()
} }
// Checks if we have a row with a certain ID
const hasRow = id => {
if (id === NewRowID) {
return true
}
return get(rowLookupMap)[id] != null
}
// Cleans a row by removing any internal grid metadata from it. // Cleans a row by removing any internal grid metadata from it.
// Call this before passing a row to any sort of external flow. // Call this before passing a row to any sort of external flow.
const cleanRow = row => { const cleanRow = row => {
@ -667,7 +659,6 @@ export const createActions = context => {
updateValue, updateValue,
applyRowChanges, applyRowChanges,
deleteRows, deleteRows,
hasRow,
loadNextPage, loadNextPage,
refreshRow, refreshRow,
replaceRow, replaceRow,

View File

@ -117,8 +117,11 @@ export const deriveStores = context => {
} }
// Row indices // Row indices
const sourceRowIndex = $rowLookupMap[sourceInfo.rowId].__idx const sourceRowIndex = $rowLookupMap[sourceInfo.rowId]?.__idx
const targetRowIndex = $rowLookupMap[targetInfo.rowId].__idx const targetRowIndex = $rowLookupMap[targetInfo.rowId]?.__idx
if (sourceRowIndex == null || targetRowIndex == null) {
return []
}
const lowerRowIndex = Math.min(sourceRowIndex, targetRowIndex) const lowerRowIndex = Math.min(sourceRowIndex, targetRowIndex)
const upperRowIndex = Math.max(sourceRowIndex, targetRowIndex) const upperRowIndex = Math.max(sourceRowIndex, targetRowIndex)
@ -305,7 +308,7 @@ export const initialise = context => {
focusedRowId, focusedRowId,
previousFocusedRowId, previousFocusedRowId,
previousFocusedCellId, previousFocusedCellId,
rows, rowLookupMap,
focusedCellId, focusedCellId,
selectedRows, selectedRows,
hoveredRowId, hoveredRowId,
@ -320,18 +323,17 @@ export const initialise = context => {
} = context } = context
// Ensure we clear invalid rows from state if they disappear // Ensure we clear invalid rows from state if they disappear
rows.subscribe(async () => { rowLookupMap.subscribe(async $rowLookupMap => {
// We tick here to ensure other derived stores have properly updated. // We tick here to ensure other derived stores have properly updated.
// We depend on the row lookup map which is a derived store, // We depend on the row lookup map which is a derived store,
await tick() await tick()
const $focusedCellId = get(focusedCellId) const $focusedRowId = get(focusedRowId)
const $selectedRows = get(selectedRows) const $selectedRows = get(selectedRows)
const $hoveredRowId = get(hoveredRowId) const $hoveredRowId = get(hoveredRowId)
const hasRow = rows.actions.hasRow const hasRow = id => $rowLookupMap[id] != null
// Check selected cell // Check focused cell
const selectedRowId = parseCellID($focusedCellId).rowId if ($focusedRowId && !hasRow($focusedRowId)) {
if (selectedRowId && !hasRow(selectedRowId)) {
focusedCellId.set(null) focusedCellId.set(null)
} }
@ -341,17 +343,19 @@ export const initialise = context => {
} }
// Check selected rows // Check selected rows
let newSelectedRows = { ...$selectedRows }
let selectedRowsNeedsUpdate = false
const selectedIds = Object.keys($selectedRows) const selectedIds = Object.keys($selectedRows)
for (let i = 0; i < selectedIds.length; i++) { if (selectedIds.length) {
if (!hasRow(selectedIds[i])) { let newSelectedRows = { ...$selectedRows }
delete newSelectedRows[selectedIds[i]] let selectedRowsNeedsUpdate = false
selectedRowsNeedsUpdate = true for (let i = 0; i < selectedIds.length; i++) {
if (!hasRow(selectedIds[i])) {
delete newSelectedRows[selectedIds[i]]
selectedRowsNeedsUpdate = true
}
}
if (selectedRowsNeedsUpdate) {
selectedRows.set(newSelectedRows)
} }
}
if (selectedRowsNeedsUpdate) {
selectedRows.set(newSelectedRows)
} }
}) })