[]
        
(Showing Draft Content)

Undo

In collaborative scenarios, undo and redo operations are also supported. This document will provide a detailed introduction.

Undo Stack Storage

Since all modifications in collaboration need to be synchronized with other clients and server, the results of undo must also be synchronized. This means that undo results are stored in the form of Ops. Therefore, the undo stack stores Ops, and behaviors that cannot be represented by Ops (e.g., selection states) cannot be undone.

Undo Content

In collaboration, each user can make modifications and receive modifications from others. The undo action should only undo the user’s own operations, not those of others.

Undo Conflicts

Since undo only affects the user’s own operations, if operations from other clients are received before the user’s operation is undone, the user’s undo may need to be transformed with the operations from other clients.

For example:

  • Alice changes the value of cell (1,1) from "old" to "new", i.e., sheet.setValue(1,1,'new');

  • Bob inserts a row at position 0, i.e., sheet.addRows(0,1);

  • Alice performs undo, modifying the value of cell (2,1) instead of (1,1), i.e., sheet.setValue(2,1, 'old');

  • Alice performs redo, also modifying (2,1) instead of (1,1), i.e., sheet.setValue(2,1,'new');

From this example, it’s clear that undo and redo may differ from the initial execution. Undo and redo execute the results transformed with operations from other clients.

Usage

Collaborative undo is a feature specific to collaboration. In non-collaborative scenarios, undo remains the non-collaborative undo method!

The usage of undo hasn’t changed; it still needs to be executed via commands, though there are some differences. We’ll use the following command as an example.

Here’s a normal command for changing color:


undo


The code in the Command is divided into two parts.

In non-collaborative scenarios:

  • do: Executes code segment 1

  • undo: Executes code segment 2

  • redo: Executes code segment 1

In collaborative scenarios, since undo/redo execute Ops, the command code is not executed, so:

  • do: Executes code segment 1

  • undo: Executes other code

  • redo: Executes other code

Although the execution logic of the command changes, collaborative undo is compatible with commands. Users can support collaborative undo with a command written as above without needing modifications.

API

Since undo and redo do not execute the logic within the command, events previously triggered in the command during undo and redo will not be triggered. To provide users with appropriate timing to handle their scenarios (e.g., updating their own UI), four new events have been added to provide timing for collaborative undo:

interface IChangeSet {
  ops: IOpComponent[];
}
workbook.bind(GC.Spread.Sheets.Events.CollaborationStartUndo, (sender, args: { changeSet: IChangeSet  }) => {
    const changeSet = args.changeSet;
    console.log('undo changeSet is:' changeSet);
});
workbook.bind(GC.Spread.Sheets.Events.CollaborationEndUndo, (sender, args: { changeSet: IChangeSet  }) => {
    const changeSet = args.changeSet;
    console.log('undo changeSet is:' changeSet);
});
workbook.bind(GC.Spread.Sheets.Events.CollaborationStartRedo, (sender, args: { changeSet: IChangeSet  }) => {
    const changeSet = args.changeSet;
    console.log('redo changeSet is:' changeSet);
});
workbook.bind(GC.Spread.Sheets.Events.CollaborationEndRedo, (sender, args: { changeSet: IChangeSet  }) => {
    const changeSet = args.changeSet;
    console.log('redo changeSet is:' changeSet);
});