-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Navigation screen: Atomic save using customizer API endpoint #22603
Navigation screen: Atomic save using customizer API endpoint #22603
Conversation
Size Change: -18.3 kB (1%) Total Size: 1.11 MB
ℹ️ View Unchanged
|
createErrorNotice( __( 'There was an error.' ), { | ||
type: 'snackbar', | ||
} ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should implement a more sophisticated error handling in a follow-up PR
|
||
export default function useNavigationBlocks( menuId ) { | ||
const [ deletedMenuItemsIds, setDeletedMenuItemsIds ] = useState( [] ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a hack to work around re-appearing menu items. I'd like to get rid of it and only rely on the data layer in a follow-up PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merging the delete part will make it work.
promiseQueueRef.current.enqueue( () => | ||
createDraftMenuItem( clientId ).then( | ||
async ( menuItem ) => { | ||
menuItemsRef.current[ clientId ] = menuItem; | ||
processedBlocksIds.current.splice( | ||
processedBlocksIds.current.indexOf( clientId ) | ||
); | ||
} | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should handle failures here - let's discuss in a follow-up PR.
createSuccessNotice( __( 'Navigation saved.' ), { | ||
type: 'snackbar', | ||
} ); | ||
receiveEntityRecords( 'root', 'menuItem', [], query, true ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This re-requests menu items related to current menu. Ideally we won't need to do it - let's discuss in a follow-up PR.
|
||
export default function useNavigationBlocks( menuId ) { | ||
const [ deletedMenuItemsIds, setDeletedMenuItemsIds ] = useState( [] ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merging the delete part will make it work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed, didn't test yet. Pretty much going on! Will comment more once I also test.
packages/edit-navigation/src/components/menu-editor/use-navigation-blocks.js
Show resolved
Hide resolved
packages/edit-navigation/src/components/menu-editor/use-navigation-blocks.js
Outdated
Show resolved
Hide resolved
useEffect( | ||
function() { | ||
for ( const clientId of getAllClientIds( debouncedBlocks ) ) { | ||
// Already has a related menu item |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does "related" mean here?
packages/edit-navigation/src/components/menu-editor/use-navigation-blocks.js
Outdated
Show resolved
Hide resolved
); | ||
setDeletedMenuItemsIds( [ | ||
...deletedMenuItemsIds, | ||
difference( allMenuItemsIds, savedMenuItemIds ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 21557 I fixed an issue where we delete all the nested items because of a bad difference
.
packages/edit-navigation/src/components/menu-editor/use-navigation-blocks.js
Outdated
Show resolved
Hide resolved
packages/edit-navigation/src/components/menu-editor/use-navigation-blocks.js
Show resolved
Hide resolved
packages/edit-navigation/src/components/menu-editor/use-navigation-blocks.js
Outdated
Show resolved
Hide resolved
With this kind of manual |
@draganescu while out of scope for this PR, this is a pretty good question! Would you open an issue to discuss that more? |
@adamziel here is how it works for me, can you reproduce this behavior (Firefox) I used to have this problem when I attempted to save a state version of menu items in my deleteEntity explorations. |
@draganescu ah thank you for reporting. I just took another pass on it and turns out |
fa7be78
to
1ff5329
Compare
…g it duplicates {n} results where n is the amount of the deleted items. The underlying state is intact and we should address the root cause in a separate PR.
1ff5329
to
b6315f4
Compare
The data layer PR is now merged and I removed the workarounds in this one - it looks good in my testing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my testing this works as expected now. It is considered a stop gap solution to both the entities in Gutenberg and the REST API not supporting batch and bulk operations applied to multiple entities.
Description
This PR enables saving the entire navigation using a single HTTP request.
The current behavior is sending one request per change at the moment. If you e.g. add 20 menu items, update 17 and remove 10, it will result in 47 http requests. This is pretty fragile and would easily break under a number of scenarios - validation errors, network failures, accidentally closing the browser, and so on.
This PR proposes the following implementation:
The previous approach also proposed a new batch endpoint for handling these requests - ultimately we agreed on implementing this on the core level instead of adding a custom endpoint: #22148
How has this been tested?
Types of changes
New feature (non-breaking change which adds functionality)
Checklist: