Core Data: Add support for entity edits and undo history.#16867
Conversation
5b5494e to
9f0b52c
Compare
f5f95d7 to
90b72e2
Compare
There was a problem hiding this comment.
What does "offset" mean in that context?
There was a problem hiding this comment.
This is already available in the reducer, why duplicate it in the action? (I guess to ease access to this value in a sub reducer), can't we leverage a higher-order reducer to add it to the action instead?
There was a problem hiding this comment.
can't we leverage a higher-order reducer to add it to the action instead
Good idea, I'll do that.
There was a problem hiding this comment.
Isn't this behavior already done in the reducer? at least it feels like a better place for it.
There was a problem hiding this comment.
I needed access to the entity, I guess I can also use a higher order reducer for this.
There was a problem hiding this comment.
should we consider returning early if there's no edits?
There was a problem hiding this comment.
Why do we use _ ? To denote that it's transient? Isn't it redundant?
There was a problem hiding this comment.
Separate from this PR: we should document the entity config somewhere
There was a problem hiding this comment.
Also, I know that some properties of the post object are not handled/merged separately (edits and persisted) and they're merged with a deep merge. Thinking of meta for instance (see the editor selectors..), I was thinking we probably need something here to "mark" these properties?
There was a problem hiding this comment.
Why do we use _ ? To denote that it's transient? Isn't it redundant?
Yeah, it was in my head from the other PR, I'll remove it.
Also, I know that some properties of the post object are not handled/merged separately (edits and persisted) and they're merged with a deep merge. Thinking of meta for instance (see the editor selectors..), I was thinking we probably need something here to "mark" these properties?
What if we just deeply merge edits if they are objects?
There was a problem hiding this comment.
What if we just deeply merge edits if they are objects?
We discussed this a long time for the PR that introduced the behavior and I think there's a valid reason (object values that we don't want to merge recursively). I'll have to look for the original PR to find the details
There was a problem hiding this comment.
Mmmm, there will also be properties that should be merged to different depths. I think meta only merges shallowly.
What do you think of an editsMergeDepths object, which for now would have meta: 1.
youknowriad
left a comment
There was a problem hiding this comment.
Do you think we should separate the core-data changes from the editor changes. I feel we can land the core-data changes separately (as they have value even without using them in the editor package). (Essentially to ease reviews/iterations)
Yeah, definitely, I just wanted to test things together, I probably shouldn't have pushed, but I am about to reduce the scope here again and implement your suggestions. |
90b72e2 to
ca5109f
Compare
| // so that the property is not considered dirty. | ||
| edits: Object.keys( edits ).reduce( ( acc, key ) => { | ||
| const value = mergedEdits[ key ] ? | ||
| merge( record[ key ], edits[ key ] ) : |
There was a problem hiding this comment.
This works a bit differently than what we currently have in the editor package. I think we only store in the edits reducer the modified sub properties and do the merge in the selectors. This might be simpler though.
There was a problem hiding this comment.
Yeah, we need this for undos to work in this context.
youknowriad
left a comment
There was a problem hiding this comment.
LGTM 👍 Great work. The undo comments are mostly thoughts for future possible enhancements maybe.
| * @return {number} The current undo offset. | ||
| */ | ||
| export function getCurrentUndoOffset( state ) { | ||
| return state.undo.offset; |
There was a problem hiding this comment.
While I understand the purpose now, I do wonder whether this should be exposed or not, as it seems like just an implementation detail. Any particular reason for having this selector?
There was a problem hiding this comment.
To not repeat it in the following two, but yeah, it could be private for now. Although I do potentially see people using it to show how many redos are available or something like that.
There was a problem hiding this comment.
it's different than the offset though. Let's make it private for now.
There was a problem hiding this comment.
It's the negation of the offset, yeah kind of confusing. I'll make it private in the autosaves PR.
| UNDO_INITIAL_STATE.offset = 0; | ||
| export function undo( state = UNDO_INITIAL_STATE, action ) { | ||
| switch ( action.type ) { | ||
| case 'EDIT_ENTITY_RECORD': |
There was a problem hiding this comment.
Something to think about for later maybe: This could be made more generic. Instead of checking the action type, we could rely on the presence of undo property in the meta key in order to support any random action.
There was a problem hiding this comment.
Yeah, that would be nice. We can add that if it's needed.
| // Transient edits don't create an undo level, but are | ||
| // reachable in the next meaningful edit to which they | ||
| // are merged. They are defined in the entity's config. | ||
| if ( ! Object.keys( action.edits ).some( ( key ) => ! action.transientEdits[ key ] ) ) { |
There was a problem hiding this comment.
Kind of related to the previews comment, but we could decide to only set the meta undo key if there are non-transient edits.
There was a problem hiding this comment.
But we still need transient edits to always go through this so that they are applied/unapplied.
|
Thanks for expediting these reviews. I'll merge and move on to autosaves now 😄 🚀 |
* Core Data: Add support for entity edits and undo history. * Core Data: Update docs.
* Core Data: Add support for entity edits and undo history. * Core Data: Update docs.
Based on #16761
Description
This PR follows a similar approach to adding edit and history support as #16761, but simplifies a lot of the logic by not relying on hacking property descriptors to let properties opt out of history tracking and change detection. Instead, it lets entity configs define which properties should opt out.
It also has a different take on the store structure which makes it play nicer with the current code and thus minimizes required changes.
The approach to undo/redo has also changed slightly, because it wasn't handling certain scenarios like undo => edit => redo.
How has this been tested?
The editor store refactor from #16761 was cherry picked on top and everything worked as expected.
Types of Changes
New Feature: Add edit, undo/redo history, and change detection support to core data entities.
Checklist: