Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: Improve UndoManager API #3639

Open
2 tasks
anatoli-dp opened this issue Jul 23, 2021 · 9 comments
Open
2 tasks

[Feature]: Improve UndoManager API #3639

anatoli-dp opened this issue Jul 23, 2021 · 9 comments

Comments

@anatoli-dp
Copy link

anatoli-dp commented Jul 23, 2021

One thing i think would add great functionality is a more detailed history stack. U can get the undo stack and build a sort of history report from it of all the edits one has made but it is a little unclear as to what each edit was (at least to me so if I am missing something please let me know). Maybe like a formulaic description that is like component [component name] added/deleted/edited at [location on page or component added to], or component [component] text edited, . . . (please excuse the general description as even i have no clue how i would phrase it) just some quick description that can give a brief overview of what that particular undo/redo history was for each item on the stack. I am aware of only the id of each history item atm, so if this is currently possible I am just unaware of how i should go about extracting this information to create a history sidebar outside of just the id so please give me a clue as what to look for

Is there an alternative at the latest version?

  • Yes (describe the alternative)
  • [ x] No

Is this related to an issue?

  • Yes (Give a link to the issue)
  • [ x] No
@artf
Copy link
Member

artf commented Aug 2, 2021

Hi @anatoli-dp the ability to view the undo history would be actually super cool and I was already thinking about how to extend the UndoManager module in order to allow this kind of functionality via a plugin (eg. you can render the UI with your framework of choice).
The UndoManager stack is updated, with a new UndoAction object (containing infos about the action), on any change of listened models/collections (components, css rules, etc.). One thing worth noting is that one change can generate multiple UndoActions:

// This will generate one UndoAction for a new component 
// and another one for a new CSS Rule
editor.addComponents(`
  <div class="test">Hi</div>
  <style>.test{color: red}</style>
`);

Here is an example of how you could retrieve an array of grouped UndoActions (the private method I made during the last refactoring).

One thing to understand is how to identify each group of UndoActions with the proper description/label (as you have described).

@anatoli-dp
Copy link
Author

yeah im aware of how to access the stack i just dont know how to intepret it to give a more meaningful description to the end user

@artf
Copy link
Member

artf commented Aug 3, 2021

i just dont know how to intepret it to give a more meaningful description to the end user

Each UndoAction (each instance of the stack) tells you the action type (eg. add, remove, reset, change) and details about the updated model (eg. Component, CssRule, etc.). You can try to read those data but I was thinking more about how to make each operation easily recognizable.

@Agobin
Copy link

Agobin commented Aug 29, 2021

Just an idea.

If there was a way to add a data-label attribute to trait controls when they are defined to describe the action they perform. And when this trait element performs an action, the label can be used to describe that change.

Before the trait element applies the change, we get the location of the undomanager's pointer (that is the index of the model it is currently pointing to). After the trait element applies the change, we update the magic fusion index attribute of all the models created when that change was performed to have the same magic fusion index (the magic fusion of the last model could be used).

Now we can store a list of changes that has the description of the change and the magic fusion index of the models that resulted from the change. With this list, we can display a history of changes and easily navigate the stack to switch between states.

To switch between states, since we know the magic fusion index of the state, depending on the location of the stack pointer, we could perform a series of undo(true) or redo(true) to move the stack pointer until we reach a model whose magic fusion index is the magic fusion index of the target state.

Special cases:
For editor functions like addComponents, setStyle we could add an option for the user to add a description and use the same concept as mentioned above.

For RTE edits, we could use the rte:enable and rte:disable events to track the models created during the edit, since the description is text change, we could use the type of component to complete the description.

My two cents, maybe it could be worth exploring.

@artf
Copy link
Member

artf commented Sep 2, 2021

Thanks @Agobin I've been actually thinking the same, adding an extra option for each meaningful top APIs, eg:

editor.addComponents(`
  <div class="test">Hi</div>
  <style>.test{color: red}</style>
`, { undoLabel: 'add-components' });

then a new API method (eg. getGroupedStack) on UndoManager which returns a similar array of UndoActionGroup:

{
    [
        index: 1, // Magix index to use to jump on this state
        labels: ['add-components'], // probably we might have multiple labels
        actions: [{}, {}, ...], // all grouped UndoActions which contain more details for each change
    ],
    // ...
    [
        index: 5,
        labels: ['custom-label-1', 'custom-label-2'],
        actions: [{}, {}],
    ],
}

And probably an easier way to select the current undo index undoManager.setIndex(UndoActionGroup.index) to switch the state.

I'd really appreciate a PR if anybody wants to try.

@artf artf changed the title FEAT: Detailed History Report FEAT: Detailed History Report (Improve UndoManager API) Oct 30, 2021
@artf
Copy link
Member

artf commented Oct 30, 2021

Other features to add in UndoManager:

  • Ability to clear the history at a specific index
  • Register new Models/Collections to track, eg.
    const obj = um.addModel({ prop1: 'value1', prop2: 'value2' });
    obj.set({ prop2: 'value2' }); // Change tracked

@mihir-khandekar
Copy link

Hi @artf, is there any update on these changes?
#3639 (comment)

@vizardkill
Copy link

up

@artf artf changed the title FEAT: Detailed History Report (Improve UndoManager API) [Feature]: Improve UndoManager API Aug 10, 2023
@artf artf added feature and removed help wanted labels Aug 10, 2023
@artf artf added this to Roadmap Aug 10, 2023
@artf artf moved this to 📋 Accepted in Roadmap Aug 10, 2023
@jogibear9988
Copy link

I created this in my Designer via a API to open a UNDO group: https://github.com/node-projects/web-component-designer/blob/656ef532088731eb4fa7998b612ca3f273d27f9f/packages/web-component-designer/src/elements/services/undoService/IUndoService.ts#L6
This group you hand over a description, and all undo items are then put into this group (also nested groups are possible) until I call commit on the group.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 📋 Accepted
Development

No branches or pull requests

6 participants