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

Data: Allow passing store definitions to controls #34170

Merged
merged 1 commit into from
Aug 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/block-directory/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export function* installBlockType( block ) {

yield loadAssets( assets );
const registeredBlocks = yield controls.select(
blocksStore.name,
blocksStore,
'getBlockTypes'
);
if ( ! registeredBlocks.some( ( i ) => i.name === block.name ) ) {
Expand Down
8 changes: 4 additions & 4 deletions packages/block-directory/src/store/test/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ describe( 'actions', () => {
expect( generator.next( [ block ] ).value ).toMatchObject( {
type: '@@data/DISPATCH',
actionName: 'createInfoNotice',
storeKey: noticesStore,
storeKey: noticesStore.name,
} );

expect( generator.next().value ).toEqual( {
Expand Down Expand Up @@ -161,7 +161,7 @@ describe( 'actions', () => {
expect( generator.next( [ inactiveBlock ] ).value ).toMatchObject( {
type: '@@data/DISPATCH',
actionName: 'createInfoNotice',
storeKey: noticesStore,
storeKey: noticesStore.name,
} );

expect( generator.next().value ).toEqual( {
Expand Down Expand Up @@ -211,7 +211,7 @@ describe( 'actions', () => {
expect( generator.next().value ).toMatchObject( {
type: '@@data/DISPATCH',
actionName: 'createErrorNotice',
storeKey: noticesStore,
storeKey: noticesStore.name,
} );

expect( generator.next().value ).toEqual( {
Expand Down Expand Up @@ -300,7 +300,7 @@ describe( 'actions', () => {
expect( generator.throw( apiError ).value ).toMatchObject( {
type: '@@data/DISPATCH',
actionName: 'createErrorNotice',
storeKey: noticesStore,
storeKey: noticesStore.name,
} );

expect( generator.next() ).toEqual( {
Expand Down
1 change: 1 addition & 0 deletions packages/data/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- Added a `batch` registry method to batch dispatch calls for performance reasons.
- Add a new migration for the persistence plugin to migrate edit-widgets preferences to the interface package. As part of this change deprecated migrations for the persistence plugin have been removed ([#33774](https://github.com/WordPress/gutenberg/pull/33774)).
- Update data controls to accept a data store definition as their first param in addition to a string-based store name value ([#34170](https://github.com/WordPress/gutenberg/pull/34170)).

## 6.0.0 (2021-07-29)

Expand Down
58 changes: 43 additions & 15 deletions packages/data/src/controls.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
/**
* External dependencies
*/
import { isObject } from 'lodash';

/**
* Internal dependencies
*/
import { createRegistryControl } from './factory';

/** @typedef {import('./types').WPDataStore} WPDataStore */

const SELECT = '@@data/SELECT';
const RESOLVE_SELECT = '@@data/RESOLVE_SELECT';
const DISPATCH = '@@data/DISPATCH';
Expand All @@ -13,9 +20,9 @@ const DISPATCH = '@@data/DISPATCH';
* Note: This control synchronously returns the current selector value, triggering the
* resolution, but not waiting for it.
*
* @param {string} storeKey The key for the store the selector belongs to.
* @param {string} selectorName The name of the selector.
* @param {Array} args Arguments for the selector.
* @param {string|WPDataStore} storeNameOrDefinition Unique namespace identifier for the store
* @param {string} selectorName The name of the selector.
* @param {Array} args Arguments for the selector.
*
* @example
* ```js
Expand All @@ -30,8 +37,15 @@ const DISPATCH = '@@data/DISPATCH';
*
* @return {Object} The control descriptor.
*/
function select( storeKey, selectorName, ...args ) {
return { type: SELECT, storeKey, selectorName, args };
function select( storeNameOrDefinition, selectorName, ...args ) {
return {
type: SELECT,
storeKey: isObject( storeNameOrDefinition )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potentially this check could be moved to the implementation of the control itself. Actually, I wonder if it's needed at all since this should just call registry.select which handles both already right? (same for the others)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are probably correct. There are some levels of indirection here so I would have to do a second pass of refactorings. I will merge this PR and open another one. I suspect that some unit tests will have to be revised so they work with storeKey as an object. I also wasn't sure if I can update storeKey key.

? storeNameOrDefinition.name
: storeNameOrDefinition,
selectorName,
args,
};
}

/**
Expand All @@ -41,9 +55,9 @@ function select( storeKey, selectorName, ...args ) {
* selectors that may have a resolver. In such case, it will return a `Promise` that resolves
* after the selector finishes resolving, with the final result value.
*
* @param {string} storeKey The key for the store the selector belongs to
* @param {string} selectorName The name of the selector
* @param {Array} args Arguments for the selector.
* @param {string|WPDataStore} storeNameOrDefinition Unique namespace identifier for the store
* @param {string} selectorName The name of the selector
* @param {Array} args Arguments for the selector.
*
* @example
* ```js
Expand All @@ -58,16 +72,23 @@ function select( storeKey, selectorName, ...args ) {
*
* @return {Object} The control descriptor.
*/
function resolveSelect( storeKey, selectorName, ...args ) {
return { type: RESOLVE_SELECT, storeKey, selectorName, args };
function resolveSelect( storeNameOrDefinition, selectorName, ...args ) {
return {
type: RESOLVE_SELECT,
storeKey: isObject( storeNameOrDefinition )
? storeNameOrDefinition.name
: storeNameOrDefinition,
selectorName,
args,
};
}

/**
* Dispatches a control action for triggering a registry dispatch.
*
* @param {string} storeKey The key for the store the action belongs to
* @param {string} actionName The name of the action to dispatch
* @param {Array} args Arguments for the dispatch action.
* @param {string|WPDataStore} storeNameOrDefinition Unique namespace identifier for the store
* @param {string} actionName The name of the action to dispatch
* @param {Array} args Arguments for the dispatch action.
*
* @example
* ```js
Expand All @@ -82,8 +103,15 @@ function resolveSelect( storeKey, selectorName, ...args ) {
*
* @return {Object} The control descriptor.
*/
function dispatch( storeKey, actionName, ...args ) {
return { type: DISPATCH, storeKey, actionName, args };
function dispatch( storeNameOrDefinition, actionName, ...args ) {
return {
type: DISPATCH,
storeKey: isObject( storeNameOrDefinition )
? storeNameOrDefinition.name
: storeNameOrDefinition,
actionName,
args,
};
}

export const controls = { select, resolveSelect, dispatch };
Expand Down
8 changes: 3 additions & 5 deletions packages/edit-navigation/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const getNavigationPostForMenu = createRegistrySelector(
if ( ! hasResolvedNavigationPost( state, menuId ) ) {
return null;
}
return select( coreStore.name ).getEditedEntityRecord(
return select( coreStore ).getEditedEntityRecord(
NAVIGATION_POST_KIND,
NAVIGATION_POST_POST_TYPE,
buildNavigationPostId( menuId )
Expand All @@ -60,9 +60,7 @@ export const getNavigationPostForMenu = createRegistrySelector(
*/
export const hasResolvedNavigationPost = createRegistrySelector(
( select ) => ( state, menuId ) => {
return select(
coreStore.name
).hasFinishedResolution( 'getEntityRecord', [
return select( coreStore ).hasFinishedResolution( 'getEntityRecord', [
NAVIGATION_POST_KIND,
NAVIGATION_POST_POST_TYPE,
buildNavigationPostId( menuId ),
Expand All @@ -80,6 +78,6 @@ export const hasResolvedNavigationPost = createRegistrySelector(
export const getMenuItemForClientId = createRegistrySelector(
( select ) => ( state, postId, clientId ) => {
const mapping = invert( state.mapping[ postId ] );
return select( coreStore.name ).getMenuItem( mapping[ clientId ] );
return select( coreStore ).getMenuItem( mapping[ clientId ] );
}
);
13 changes: 9 additions & 4 deletions packages/edit-navigation/src/store/test/selectors.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* WordPress dependencies
*/
import { store as coreDataStore } from '@wordpress/core-data';

/**
* Internal dependencies
*/
Expand Down Expand Up @@ -33,7 +38,7 @@ describe( 'getNavigationPostForMenu', () => {

expect( getNavigationPostForMenu( 'state', menuId ) ).toBe( 'record' );

expect( registry.select ).toHaveBeenCalledWith( 'core' );
expect( registry.select ).toHaveBeenCalledWith( coreDataStore );
expect( getEditedEntityRecord ).toHaveBeenCalledWith(
NAVIGATION_POST_KIND,
NAVIGATION_POST_POST_TYPE,
Expand Down Expand Up @@ -62,7 +67,7 @@ describe( 'getNavigationPostForMenu', () => {

expect( getNavigationPostForMenu( 'state', menuId ) ).toBe( null );

expect( registry.select ).toHaveBeenCalledWith( 'core' );
expect( registry.select ).toHaveBeenCalledWith( coreDataStore );
expect( getEditedEntityRecord ).not.toHaveBeenCalled();

getNavigationPostForMenu.registry = defaultRegistry;
Expand All @@ -86,7 +91,7 @@ describe( 'hasResolvedNavigationPost', () => {

expect( hasResolvedNavigationPost( 'state', menuId ) ).toBe( true );

expect( registry.select ).toHaveBeenCalledWith( 'core' );
expect( registry.select ).toHaveBeenCalledWith( coreDataStore );
expect( hasFinishedResolution ).toHaveBeenCalledWith(
'getEntityRecord',
[
Expand Down Expand Up @@ -125,7 +130,7 @@ describe( 'getMenuItemForClientId', () => {
'menuItem'
);

expect( registry.select ).toHaveBeenCalledWith( 'core' );
expect( registry.select ).toHaveBeenCalledWith( coreDataStore );
expect( getMenuItem ).toHaveBeenCalledWith( '123' );

getMenuItemForClientId.registry = defaultRegistry;
Expand Down
42 changes: 18 additions & 24 deletions packages/edit-post/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { store as editPostStore } from '.';
*/
export function* openGeneralSidebar( name ) {
yield controls.dispatch(
interfaceStore.name,
interfaceStore,
'enableComplementaryArea',
editPostStore.name,
name
Expand All @@ -44,7 +44,7 @@ export function* openGeneralSidebar( name ) {
*/
export function* closeGeneralSidebar() {
yield controls.dispatch(
interfaceStore.name,
interfaceStore,
'disableComplementaryArea',
editPostStore.name
);
Expand Down Expand Up @@ -174,7 +174,7 @@ export function* switchEditorMode( mode ) {

// Unselect blocks when we switch to the code editor.
if ( mode !== 'visual' ) {
yield controls.dispatch( blockEditorStore.name, 'clearSelectedBlock' );
yield controls.dispatch( blockEditorStore, 'clearSelectedBlock' );
}

const message =
Expand All @@ -191,14 +191,14 @@ export function* switchEditorMode( mode ) {
*/
export function* togglePinnedPluginItem( pluginName ) {
const isPinned = yield controls.select(
interfaceStore.name,
interfaceStore,
'isItemPinned',
'core/edit-post',
pluginName
);

yield controls.dispatch(
interfaceStore.name,
interfaceStore,
isPinned ? 'unpinItem' : 'pinItem',
'core/edit-post',
pluginName
Expand Down Expand Up @@ -281,20 +281,14 @@ export function* setAvailableMetaBoxesPerLocation( metaBoxesPerLocation ) {
metaBoxesPerLocation,
};

const postType = yield controls.select(
editorStore.name,
'getCurrentPostType'
);
const postType = yield controls.select( editorStore, 'getCurrentPostType' );
if ( window.postboxes.page !== postType ) {
window.postboxes.add_postbox_toggles( postType );
}

let wasSavingPost = yield controls.select(
editorStore.name,
'isSavingPost'
);
let wasSavingPost = yield controls.select( editorStore, 'isSavingPost' );
let wasAutosavingPost = yield controls.select(
editorStore.name,
editorStore,
'isAutosavingPost'
);

Expand All @@ -303,7 +297,7 @@ export function* setAvailableMetaBoxesPerLocation( metaBoxesPerLocation ) {
//
// See: https://github.com/WordPress/WordPress/blob/5.1.1/wp-admin/includes/post.php#L2307-L2309
const hasActiveMetaBoxes = yield controls.select(
editPostStore.name,
editPostStore,
'hasMetaBoxes'
);

Expand All @@ -314,8 +308,8 @@ export function* setAvailableMetaBoxesPerLocation( metaBoxesPerLocation ) {

// Save metaboxes when performing a full save on the post.
saveMetaboxUnsubscribe = subscribe( () => {
const isSavingPost = select( editorStore.name ).isSavingPost();
const isAutosavingPost = select( editorStore.name ).isAutosavingPost();
const isSavingPost = select( editorStore ).isSavingPost();
const isAutosavingPost = select( editorStore ).isAutosavingPost();

// Save metaboxes on save completion, except for autosaves that are not a post preview.
const shouldTriggerMetaboxesSave =
Expand All @@ -329,7 +323,7 @@ export function* setAvailableMetaBoxesPerLocation( metaBoxesPerLocation ) {
wasAutosavingPost = isAutosavingPost;

if ( shouldTriggerMetaboxesSave ) {
dispatch( editPostStore.name ).requestMetaBoxUpdates();
dispatch( editPostStore ).requestMetaBoxUpdates();
}
} );
}
Expand All @@ -351,7 +345,7 @@ export function* requestMetaBoxUpdates() {

// Additional data needed for backward compatibility.
// If we do not provide this data, the post will be overridden with the default values.
const post = yield controls.select( editorStore.name, 'getCurrentPost' );
const post = yield controls.select( editorStore, 'getCurrentPost' );
const additionalData = [
post.comment_status ? [ 'comment_status', post.comment_status ] : false,
post.ping_status ? [ 'ping_status', post.ping_status ] : false,
Expand All @@ -364,7 +358,7 @@ export function* requestMetaBoxUpdates() {
document.querySelector( '.metabox-base-form' )
);
const activeMetaBoxLocations = yield controls.select(
editPostStore.name,
editPostStore,
'getActiveMetaBoxLocations'
);
const formDataToMerge = [
Expand Down Expand Up @@ -398,9 +392,9 @@ export function* requestMetaBoxUpdates() {
body: formData,
parse: false,
} );
yield controls.dispatch( editPostStore.name, 'metaBoxUpdatesSuccess' );
yield controls.dispatch( editPostStore, 'metaBoxUpdatesSuccess' );
} catch {
yield controls.dispatch( editPostStore.name, 'metaBoxUpdatesFailure' );
yield controls.dispatch( editPostStore, 'metaBoxUpdatesFailure' );
}
}

Expand Down Expand Up @@ -494,7 +488,7 @@ export function* __unstableSwitchToTemplateMode( newTemplate = false ) {
yield setIsEditingTemplate( true );

const isWelcomeGuideActive = yield controls.select(
editPostStore.name,
editPostStore,
'isFeatureActive',
'welcomeGuideTemplate'
);
Expand Down Expand Up @@ -524,7 +518,7 @@ export function* __unstableCreateTemplate( template ) {
'wp_template',
template
);
const post = yield controls.select( editorStore.name, 'getCurrentPost' );
const post = yield controls.select( editorStore, 'getCurrentPost' );

yield controls.dispatch(
coreStore,
Expand Down
Loading