Moving A Cell
If a user cut-pastes a cell, they are intending to move it. So the Cell ID (block ID) needs to be included in the HTML content in the clipboard.
If the cell is moved to another row, but the column is the same, this will result in a MoveBlock operation. If the content has changed, it will also have a ReplaceBlock op.
Empty Cells do not need blocks (or IDs)
If a user deletes a cell, or if they cut without pasting anywhere, this results in a deleted block.
Workflow Psuedocode
Load the document state, with the HMBlockNode hierarchy
Convert HMBlockNode to BlockNoteTree(EditorState), with the full table structure - New Code
User edits the table - draft saved as BlockNoteTree(EditorState)
On publish, convert BlockNoteTree(EditorState) back to HMBlockNode - New Code
Evaluate for operations - Code is unchanged
Publish operations into a change blob
Edge Case 1 - Concurrent Cell Insertion
Two users concurrently attempt to insert the same cell location. They can both succeed, resulting in two conflicting cells in the HMBlockNode hierarchy
We need a tie breaker, ideally last write wins.
The block hierarchy can have a revisionTime field for each block. The highest revision for the two conflicting cells will win.
Edge Case 2 - Orphan Cells
Concurrently add a row and delete a column. Final state has orphan cell which can be ignored
Edge Case 3 - Excessive Move Operations of Cells
We will have unnecessary move operations for cells. Because the cells will be ordered in column-order when converting from EditorState to HMBlockNode
Its not that big of a deal
Dealing with Row and Column Headers
No text fields on column and row blocks. Add isHeader attribute to column and row types, but only allow it to be true if it's the first in the table. Moving the header row/column will set its' isHeader to false and set the new first row/column as a header.
Should we allow multi column and multi row headers?
Do you like what you are reading? Subscribe to receive updates.
Unsubscribe anytime