Skip to content

Commit

Permalink
Move the mapping back to state
Browse files Browse the repository at this point in the history
  • Loading branch information
adamziel committed Jun 17, 2020
1 parent dba1798 commit 59b5c0a
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 53 deletions.
51 changes: 34 additions & 17 deletions packages/edit-navigation/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,25 @@ import { __ } from '@wordpress/i18n';
* Internal dependencies
*/
import {
getNavigationPost,
getPendingActions,
isProcessingPost,
getMenuItemToClientIdMapping,
resolveMenuItems,
dispatch,
apiFetch,
} from './controls';
import { menuItemsQuery, KIND, POST_TYPE } from './utils';
import { menuItemsQuery } from './utils';

// Hits POST /wp/v2/menu-items once for every Link block that doesn't have an
// associated menu item. (IDK what a good name for this is.)
export const createMissingMenuItems = serializeProcessing( function* ( post ) {
const menuId = post.meta.menuId;
const mapping = post.meta.menuItemIdToClientId;

const mapping = yield {
type: 'GET_MENU_ITEM_TO_CLIENT_ID_MAPPING',
postId: post.id,
};
const clientIdToMenuId = invert( mapping );

const stack = [ post.blocks[ 0 ] ];
Expand Down Expand Up @@ -57,23 +63,29 @@ export const createMissingMenuItems = serializeProcessing( function* ( post ) {
stack.push( ...block.innerBlocks );
}

yield dispatch( 'core', 'editEntityRecord', KIND, POST_TYPE, post.id, {
meta: {
...post.meta,
menuItemIdToClientId: mapping,
},
} );
yield {
type: 'SET_MENU_ITEM_TO_CLIENT_ID_MAPPING',
postId: post.id,
mapping,
};
} );

export const saveNavigationPost = serializeProcessing( function* ( post ) {
const menuId = post.meta.menuId;
const menuItemsByClientId = mapMenuItemsByClientId(
yield resolveMenuItems( menuId ),
post.meta.menuItemIdToClientId
yield getMenuItemToClientIdMapping( post.id )
);

try {
yield* batchSave( menuId, menuItemsByClientId, post.blocks[ 0 ] );
const response = yield* batchSave(
menuId,
menuItemsByClientId,
post.blocks[ 0 ]
);
if ( ! response.success ) {
throw new Error();
}
yield dispatch(
'core/notices',
'createSuccessNotice',
Expand Down Expand Up @@ -131,7 +143,7 @@ function* batchSave( menuId, menuItemsByClientId, navigationBlock ) {
)
);

yield apiFetch( {
return yield apiFetch( {
url: '/wp-admin/admin-ajax.php',
method: 'POST',
body,
Expand Down Expand Up @@ -193,37 +205,42 @@ function computeCustomizedAttribute( blocks, menuId, menuItemsByClientId ) {

function serializeProcessing( callback ) {
return function* ( post ) {
const isProcessing = yield isProcessingPost( post.id );
const postId = post.id;
const isProcessing = yield isProcessingPost( postId );

if ( isProcessing ) {
yield {
type: 'ENQUEUE_AFTER_PROCESSING',
id: post.id,
postId,
action: callback,
};
return { status: 'pending' };
}

yield {
type: 'START_PROCESSING_POST',
id: post.id,
postId,
};

try {
yield* callback( post );
} finally {
yield {
type: 'FINISH_PROCESSING_POST',
id: post.id,
postId,
action: callback,
};

const pendingActions = yield getPendingActions( post.id );
const pendingActions = yield getPendingActions( postId );
if ( pendingActions.length ) {
const serializedCallback = serializeProcessing(
pendingActions[ 0 ]
);
yield* serializedCallback( post );

// re-fetch the post as running the callback() likely updated it
yield* serializedCallback(
yield getNavigationPost( post.meta.menuId )
);
}
}
};
Expand Down
45 changes: 31 additions & 14 deletions packages/edit-navigation/src/store/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,21 @@ export function apiFetch( request ) {
export function getPendingActions( postId ) {
return {
type: 'GET_PENDING_ACTIONS',
id: postId,
postId,
};
}

export function isProcessingPost( postId ) {
return {
type: 'IS_PROCESSING_POST',
id: postId,
postId,
};
}

export function getMenuItemToClientIdMapping( postId ) {
return {
type: 'GET_MENU_ITEM_TO_CLIENT_ID_MAPPING',
postId,
};
}

Expand Down Expand Up @@ -109,19 +116,26 @@ const controls = {
}
),

GET_PENDING_ACTIONS: createRegistryControl( ( registry ) => ( { id } ) => {
const state = registry.stores[
'core/edit-navigation'
].store.getState();
return state.processingQueue[ id ]?.pendingActions || [];
} ),
GET_PENDING_ACTIONS: createRegistryControl(
( registry ) => ( { postId } ) => {
return (
getState( registry ).processingQueue[ postId ]
?.pendingActions || []
);
}
),

IS_PROCESSING_POST: createRegistryControl(
( registry ) => ( { postId } ) => {
return getState( registry ).processingQueue[ postId ]?.inProgress;
}
),

IS_PROCESSING_POST: createRegistryControl( ( registry ) => ( { id } ) => {
const state = registry.stores[
'core/edit-navigation'
].store.getState();
return state.processingQueue[ id ]?.inProgress;
} ),
GET_MENU_ITEM_TO_CLIENT_ID_MAPPING: createRegistryControl(
( registry ) => ( { postId } ) => {
return getState( registry ).mapping[ postId ] || {};
}
),

DISPATCH: createRegistryControl(
( registry ) => ( { registryName, actionName, args } ) => {
Expand All @@ -138,4 +152,7 @@ const controls = {
),
};

const getState = ( registry ) =>
registry.stores[ 'core/edit-navigation' ].store.getState();

export default controls;
27 changes: 18 additions & 9 deletions packages/edit-navigation/src/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,37 @@
*/
import { combineReducers } from '@wordpress/data';

function processingQueue( state, { type, id, ...rest } ) {
function mapping( state, { type, postId, ...rest } ) {
if ( type === 'SET_MENU_ITEM_TO_CLIENT_ID_MAPPING' ) {
state[ postId ] = rest.mapping;
}

return state || {};
}

function processingQueue( state, { type, postId, ...rest } ) {
switch ( type ) {
case 'START_PROCESSING_POST':
state[ id ] = {
...state[ id ],
state[ postId ] = {
...state[ postId ],
inProgress: true,
};
break;
case 'FINISH_PROCESSING_POST':
state[ id ] = {
...state[ id ],
state[ postId ] = {
...state[ postId ],
inProgress: false,
pendingActions:
state[ id ]?.pendingActions?.filter(
state[ postId ]?.pendingActions?.filter(
( item ) => item !== rest.action
) || [],
};
break;
case 'ENQUEUE_AFTER_PROCESSING':
const pendingActions = state[ id ]?.pendingActions || [];
const pendingActions = state[ postId ]?.pendingActions || [];
if ( ! pendingActions.includes( rest.action ) ) {
state[ id ] = {
...state[ id ],
state[ postId ] = {
...state[ postId ],
pendingActions: [ ...pendingActions, rest.action ],
};
}
Expand All @@ -36,5 +44,6 @@ function processingQueue( state, { type, id, ...rest } ) {
}

export default combineReducers( {
mapping,
processingQueue,
} );
25 changes: 14 additions & 11 deletions packages/edit-navigation/src/store/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,22 @@ import { KIND, POST_TYPE, buildNavigationPostId } from './utils';

export function* getNavigationPost( menuId ) {
// Ensure an empty post to start with
yield persistPost(
createStubPost( menuId, [], {
isResolving: true,
} )
);
const stubPost = createStubPost( menuId, null, {
isResolving: true,
} );
yield persistPost( stubPost );

// Now let's create a proper one hydrated with actual menu items
const menuItems = yield resolveMenuItems( menuId );
yield persistPost( createStubPost( menuId, menuItems ) );
const [ navigationBlock, menuItemIdToClientId ] = createNavigationBlock(
menuItems
);
yield {
type: 'SET_MENU_ITEM_TO_CLIENT_ID_MAPPING',
postId: stubPost.id,
mapping: menuItemIdToClientId,
};
yield persistPost( createStubPost( menuId, navigationBlock ) );
}

const persistPost = ( post ) =>
Expand All @@ -38,10 +45,7 @@ const persistPost = ( post ) =>
false
);

const createStubPost = ( menuId, menuItems, meta ) => {
const [ navigationBlock, menuItemIdToClientId ] = createNavigationBlock(
menuItems
);
const createStubPost = ( menuId, navigationBlock, meta ) => {
const id = buildNavigationPostId( menuId );
return {
id,
Expand All @@ -52,7 +56,6 @@ const createStubPost = ( menuId, menuItems, meta ) => {
meta: {
...meta,
menuId,
menuItemIdToClientId,
},
};
};
Expand Down
4 changes: 2 additions & 2 deletions packages/edit-navigation/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export const isResolvingNavigationPost = ( state, menuId ) => {
};

export const getMenuItemForClientId = createRegistrySelector(
( select ) => ( state, post, clientId ) => {
const mapping = invert( post.meta.menuItemIdToClientId );
( select ) => ( state, postId, clientId ) => {
const mapping = invert( state.mapping[ postId ] );
return select( 'core' ).getMenuItem( mapping[ clientId ] );
}
);

0 comments on commit 59b5c0a

Please sign in to comment.