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

Edit Post: Refactor effects to action generators #27069

Merged
merged 9 commits into from
Nov 26, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -372,10 +372,6 @@ _Returns_

Returns an action object used to request meta box update.

_Returns_

- `Object`: Action object.

<a name="setAvailableMetaBoxesPerLocation" href="#setAvailableMetaBoxesPerLocation">#</a> **setAvailableMetaBoxesPerLocation**

Returns an action object used in signaling
Expand All @@ -385,10 +381,6 @@ _Parameters_

- _metaBoxesPerLocation_ `Object`: Meta boxes per location.

_Returns_

- `Object`: Action object.

<a name="setIsInserterOpened" href="#setIsInserterOpened">#</a> **setIsInserterOpened**

Returns an action object used to open/close the inserter.
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ describe( 'PostPublishButton', () => {
await page.$( '.editor-post-publish-button[aria-disabled="true"]' )
).toBeNull();

await page.evaluate( () =>
window.wp.data.dispatch( 'core/edit-post' ).requestMetaBoxUpdates()
);
await page.evaluate( () => {
window.wp.data.dispatch( 'core/edit-post' ).requestMetaBoxUpdates();
return true;
} );
expect(
await page.$( '.editor-post-publish-button[aria-disabled="true"]' )
).not.toBeNull();
Expand Down
2 changes: 1 addition & 1 deletion packages/edit-post/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@wordpress/compose": "file:../compose",
"@wordpress/core-data": "file:../core-data",
"@wordpress/data": "file:../data",
"@wordpress/data-controls": "file:../data-controls",
"@wordpress/editor": "file:../editor",
"@wordpress/element": "file:../element",
"@wordpress/hooks": "file:../hooks",
Expand All @@ -52,7 +53,6 @@
"classnames": "^2.2.5",
"lodash": "^4.17.19",
"memize": "^1.1.0",
"refx": "^3.0.0",
"rememo": "^3.0.0"
},
"publishConfig": {
Expand Down
145 changes: 135 additions & 10 deletions packages/edit-post/src/store/actions.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
/**
* External dependencies
*/
import { castArray } from 'lodash';
import { castArray, reduce } from 'lodash';

/**
* WordPress dependencies
*/
import { controls } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { apiFetch } from '@wordpress/data-controls';
import { controls, dispatch, select, subscribe } from '@wordpress/data';
import { speak } from '@wordpress/a11y';

/**
* Internal dependencies
*/
import { getMetaBoxContainer } from '../utils/meta-boxes';

/**
* Returns an action object used in signalling that the user opened an editor sidebar.
Expand Down Expand Up @@ -153,11 +161,22 @@ export function toggleFeature( feature ) {
};
}

export function switchEditorMode( mode ) {
return {
export function* switchEditorMode( mode ) {
yield {
type: 'SWITCH_MODE',
mode,
};

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

const message =
mode === 'visual'
? __( 'Visual editor selected' )
: __( 'Code editor selected' );
speak( message, 'assertive' );
}

/**
Expand Down Expand Up @@ -234,30 +253,136 @@ export function showBlockTypes( blockNames ) {
};
}

let saveMetaboxUnsubscribe;

/**
* Returns an action object used in signaling
* what Meta boxes are available in which location.
*
* @param {Object} metaBoxesPerLocation Meta boxes per location.
*
* @return {Object} Action object.
* @yield {Object} Action object.
*/
export function setAvailableMetaBoxesPerLocation( metaBoxesPerLocation ) {
return {
export function* setAvailableMetaBoxesPerLocation( metaBoxesPerLocation ) {
yield {
type: 'SET_META_BOXES_PER_LOCATIONS',
metaBoxesPerLocation,
};

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

let wasSavingPost = yield controls.select( 'core/editor', 'isSavingPost' );
let wasAutosavingPost = yield controls.select(
'core/editor',
'isAutosavingPost'
);

// Meta boxes are initialized once at page load. It is not necessary to
// account for updates on each state change.
//
// See: https://github.com/WordPress/WordPress/blob/5.1.1/wp-admin/includes/post.php#L2307-L2309
const hasActiveMetaBoxes = yield controls.select(
'core/edit-post',
'hasMetaBoxes'
);

// First remove any existing subscription in order to prevent multiple saves
if ( !! saveMetaboxUnsubscribe ) {
Copy link
Contributor

@adamziel adamziel Nov 23, 2020

Choose a reason for hiding this comment

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

For this to work you'd need to declare let saveMetaboxUnsubscribe outside of this function, right now this will always be false since the variable is undefined at this point. I think this doesn't throw an error only because const is transpiled to var.

Copy link
Contributor

@adamziel adamziel Nov 23, 2020

Choose a reason for hiding this comment

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

BTW this won't work with multiple registries. However, effects.js wouldn't as well so I don't think it's a blocker - just something to take note of for later.

Copy link
Contributor

Choose a reason for hiding this comment

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

I updated that in 2e12440

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, @adamziel, that makes sense 👍

saveMetaboxUnsubscribe();
}

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

// Save metaboxes on save completion, except for autosaves that are not a post preview.
const shouldTriggerMetaboxesSave =
hasActiveMetaBoxes &&
wasSavingPost &&
! isSavingPost &&
! wasAutosavingPost;

// Save current state for next inspection.
wasSavingPost = isSavingPost;
wasAutosavingPost = isAutosavingPost;

if ( shouldTriggerMetaboxesSave ) {
dispatch( 'core/edit-post' ).requestMetaBoxUpdates();
}
} );
}

/**
* Returns an action object used to request meta box update.
*
* @return {Object} Action object.
* @yield {Object} Action object.
*/
export function requestMetaBoxUpdates() {
return {
export function* requestMetaBoxUpdates() {
yield {
type: 'REQUEST_META_BOX_UPDATES',
};

// Saves the wp_editor fields
if ( window.tinyMCE ) {
window.tinyMCE.triggerSave();
}

// 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( 'core/editor', 'getCurrentPost' );
const additionalData = [
post.comment_status ? [ 'comment_status', post.comment_status ] : false,
post.ping_status ? [ 'ping_status', post.ping_status ] : false,
post.sticky ? [ 'sticky', post.sticky ] : false,
post.author ? [ 'post_author', post.author ] : false,
].filter( Boolean );

// We gather all the metaboxes locations data and the base form data
const baseFormData = new window.FormData(
document.querySelector( '.metabox-base-form' )
);
const activeMetaBoxLocations = yield controls.select(
'core/edit-post',
'getActiveMetaBoxLocations'
);
const formDataToMerge = [
baseFormData,
...activeMetaBoxLocations.map(
( location ) =>
new window.FormData( getMetaBoxContainer( location ) )
),
];

// Merge all form data objects into a single one.
const formData = reduce(
formDataToMerge,
( memo, currentFormData ) => {
for ( const [ key, value ] of currentFormData ) {
memo.append( key, value );
}
return memo;
},
new window.FormData()
);
additionalData.forEach( ( [ key, value ] ) =>
formData.append( key, value )
);

// Save the metaboxes
yield apiFetch( {
url: window._wpMetaBoxUrl,
method: 'POST',
body: formData,
parse: false,
} );
yield controls.dispatch( 'core/edit-post', 'metaBoxUpdatesSuccess' );
}

/**
Expand Down
Loading