diff --git a/edit-post/components/header/index.js b/edit-post/components/header/index.js
index 9fcafc7b32582..8c74fda38e9ce 100644
--- a/edit-post/components/header/index.js
+++ b/edit-post/components/header/index.js
@@ -7,6 +7,7 @@ import {
PostPreviewButton,
PostSavedState,
PostPublishPanelToggle,
+ PostPublishButton,
} from '@wordpress/editor';
import { withDispatch, withSelect } from '@wordpress/data';
import { compose } from '@wordpress/compose';
@@ -26,6 +27,7 @@ function Header( {
openGeneralSidebar,
closeGeneralSidebar,
isPublishSidebarOpened,
+ isPublishSidebarEnabled,
togglePublishSidebar,
hasActiveMetaboxes,
isSaving,
@@ -48,12 +50,19 @@ function Header( {
forceIsSaving={ isSaving }
/>
-
+ { isPublishSidebarEnabled ? (
+
+ ) : (
+
+ ) }
( {
isEditorSidebarOpened: select( 'core/edit-post' ).isEditorSidebarOpened(),
isPublishSidebarOpened: select( 'core/edit-post' ).isPublishSidebarOpened(),
+ isPublishSidebarEnabled: select( 'core/editor' ).isPublishSidebarEnabled(),
hasActiveMetaboxes: select( 'core/edit-post' ).hasMetaBoxes(),
isSaving: select( 'core/edit-post' ).isSavingMetaBoxes(),
hasBlockSelection: !! select( 'core/editor' ).getBlockSelectionStart(),
diff --git a/edit-post/components/header/more-menu/index.js b/edit-post/components/header/more-menu/index.js
index 17ea090a1b710..60f4a9225b52d 100644
--- a/edit-post/components/header/more-menu/index.js
+++ b/edit-post/components/header/more-menu/index.js
@@ -14,6 +14,7 @@ import PluginMoreMenuGroup from '../plugins-more-menu-group';
import TipsToggle from '../tips-toggle';
import KeyboardShortcutsHelpMenuItem from '../keyboard-shortcuts-help-menu-item';
import WritingMenu from '../writing-menu';
+import PublishSidebarToggle from '../publish-sidebar-toggle';
const MoreMenu = () => (
(
{ __( 'Manage All Reusable Blocks' ) }
+
diff --git a/edit-post/components/header/publish-sidebar-toggle/index.js b/edit-post/components/header/publish-sidebar-toggle/index.js
new file mode 100644
index 0000000000000..b3949ec866b95
--- /dev/null
+++ b/edit-post/components/header/publish-sidebar-toggle/index.js
@@ -0,0 +1,38 @@
+/**
+ * WordPress Dependencies
+ */
+import { __ } from '@wordpress/i18n';
+import { MenuItem } from '@wordpress/components';
+import { compose } from '@wordpress/compose';
+import { withSelect, withDispatch } from '@wordpress/data';
+
+const PublishSidebarToggle = function( { onToggle, isEnabled } ) {
+ return (
+
+ );
+};
+
+export default compose( [
+ withSelect( ( select ) => ( {
+ isEnabled: select( 'core/editor' ).isPublishSidebarEnabled(),
+ } ) ),
+ withDispatch( ( dispatch, ownProps ) => ( {
+ onToggle() {
+ const { disablePublishSidebar, enablePublishSidebar } = dispatch( 'core/editor' );
+ if ( ownProps.isEnabled ) {
+ disablePublishSidebar();
+ } else {
+ enablePublishSidebar();
+ }
+ ownProps.onToggle();
+ },
+ } ) ),
+] )( PublishSidebarToggle );
diff --git a/packages/editor/src/components/post-publish-panel/index.js b/packages/editor/src/components/post-publish-panel/index.js
index 93a21c18b84c4..f4b7248d8a715 100644
--- a/packages/editor/src/components/post-publish-panel/index.js
+++ b/packages/editor/src/components/post-publish-panel/index.js
@@ -8,8 +8,8 @@ import { get } from 'lodash';
*/
import { __ } from '@wordpress/i18n';
import { Component } from '@wordpress/element';
-import { IconButton, Spinner } from '@wordpress/components';
-import { withSelect } from '@wordpress/data';
+import { IconButton, Spinner, CheckboxControl } from '@wordpress/components';
+import { withSelect, withDispatch } from '@wordpress/data';
import { compose } from '@wordpress/compose';
/**
@@ -62,7 +62,7 @@ class PostPublishPanel extends Component {
}
render() {
- const { isScheduled, onClose, forceIsDirty, forceIsSaving, PrePublishExtension, PostPublishExtension, ...additionalProps } = this.props;
+ const { isScheduled, isPublishSidebarEnabled, onClose, onTogglePublishSidebar, forceIsDirty, forceIsSaving, PrePublishExtension, PostPublishExtension, ...additionalProps } = this.props;
const { loading, submitted } = this.state;
return (
@@ -97,6 +97,13 @@ class PostPublishPanel extends Component {
) }
+
+
+
);
}
@@ -112,6 +119,7 @@ export default compose( [
isSavingPost,
isEditedPostDirty,
} = select( 'core/editor' );
+ const { isPublishSidebarEnabled } = select( 'core/editor' );
return {
postType: getCurrentPostType(),
hasPublishAction: get( getCurrentPost(), [ '_links', 'wp:action-publish' ], false ),
@@ -119,6 +127,19 @@ export default compose( [
isScheduled: isCurrentPostScheduled(),
isSaving: isSavingPost(),
isDirty: isEditedPostDirty(),
+ isPublishSidebarEnabled: isPublishSidebarEnabled(),
+ };
+ } ),
+ withDispatch( ( dispatch, { isPublishSidebarEnabled } ) => {
+ const { disablePublishSidebar, enablePublishSidebar } = dispatch( 'core/editor' );
+ return {
+ onTogglePublishSidebar: ( ) => {
+ if ( isPublishSidebarEnabled ) {
+ disablePublishSidebar();
+ } else {
+ enablePublishSidebar();
+ }
+ },
};
} ),
] )( PostPublishPanel );
diff --git a/packages/editor/src/components/post-publish-panel/style.scss b/packages/editor/src/components/post-publish-panel/style.scss
index 0a2b539bca965..137fc6876793f 100644
--- a/packages/editor/src/components/post-publish-panel/style.scss
+++ b/packages/editor/src/components/post-publish-panel/style.scss
@@ -30,6 +30,12 @@
flex-grow: 1;
}
+.editor-post-publish-panel__footer {
+ padding: 16px;
+ position: absolute;
+ bottom: 0;
+}
+
.components-button.editor-post-publish-panel__toggle.is-primary {
display: inline-flex;
align-items: center;
diff --git a/packages/editor/src/store/actions.js b/packages/editor/src/store/actions.js
index d9d4e3186b73c..4d81471a6fa4f 100644
--- a/packages/editor/src/store/actions.js
+++ b/packages/editor/src/store/actions.js
@@ -763,3 +763,25 @@ export function unregisterToken( name ) {
name,
};
}
+
+/**
+ * Returns an action object used in signalling that the user has enabled the publish sidebar.
+ *
+ * @return {Object} Action object
+ */
+export function enablePublishSidebar() {
+ return {
+ type: 'ENABLE_PUBLISH_SIDEBAR',
+ };
+}
+
+/**
+ * Returns an action object used in signalling that the user has disabled the publish sidebar.
+ *
+ * @return {Object} Action object
+ */
+export function disablePublishSidebar() {
+ return {
+ type: 'DISABLE_PUBLISH_SIDEBAR',
+ };
+}
diff --git a/packages/editor/src/store/defaults.js b/packages/editor/src/store/defaults.js
index bc4be6692059b..1118028ccd2d9 100644
--- a/packages/editor/src/store/defaults.js
+++ b/packages/editor/src/store/defaults.js
@@ -5,6 +5,7 @@ import { __ } from '@wordpress/i18n';
export const PREFERENCES_DEFAULTS = {
insertUsage: {},
+ isPublishSidebarEnabled: true,
};
/**
diff --git a/packages/editor/src/store/reducer.js b/packages/editor/src/store/reducer.js
index 09d58a57be956..fbca6f70ad976 100644
--- a/packages/editor/src/store/reducer.js
+++ b/packages/editor/src/store/reducer.js
@@ -773,9 +773,6 @@ export function settings( state = EDITOR_SETTINGS_DEFAULTS, action ) {
* Reducer returning the user preferences.
*
* @param {Object} state Current state.
- * @param {string} state.mode Current editor mode, either "visual" or "text".
- * @param {boolean} state.isSidebarOpened Whether the sidebar is opened or closed.
- * @param {Object} state.panels The state of the different sidebar panels.
* @param {Object} action Dispatched action.
*
* @return {string} Updated state.
@@ -810,6 +807,18 @@ export function preferences( state = PREFERENCES_DEFAULTS, action ) {
...state,
insertUsage: omitBy( state.insertUsage, ( { insert } ) => insert.ref === action.id ),
};
+
+ case 'ENABLE_PUBLISH_SIDEBAR':
+ return {
+ ...state,
+ isPublishSidebarEnabled: true,
+ };
+
+ case 'DISABLE_PUBLISH_SIDEBAR':
+ return {
+ ...state,
+ isPublishSidebarEnabled: false,
+ };
}
return state;
diff --git a/packages/editor/src/store/selectors.js b/packages/editor/src/store/selectors.js
index 81bc282d774e6..10068aadf3609 100644
--- a/packages/editor/src/store/selectors.js
+++ b/packages/editor/src/store/selectors.js
@@ -27,6 +27,11 @@ import { serialize, getBlockType, getBlockTypes, hasBlockSupport, hasChildBlocks
import { moment } from '@wordpress/date';
import { removep } from '@wordpress/autop';
+/**
+ * Dependencies
+ */
+import { PREFERENCES_DEFAULTS } from './defaults';
+
/***
* Module constants
*/
@@ -1879,3 +1884,18 @@ export function getTokenSettings( state, name ) {
export function canUserUseUnfilteredHTML( state ) {
return has( getCurrentPost( state ), [ '_links', 'wp:action-unfiltered_html' ] );
}
+
+/**
+ * Returns whether the pre-publish panel should be shown
+ * or skipped when the user clicks the "publish" button.
+ *
+ * @param {Object} state Global application state.
+ *
+ * @return {boolean} Whether the pre-publish panel should be shown or not.
+ */
+export function isPublishSidebarEnabled( state ) {
+ if ( state.preferences.hasOwnProperty( 'isPublishSidebarEnabled' ) ) {
+ return state.preferences.isPublishSidebarEnabled;
+ }
+ return PREFERENCES_DEFAULTS.isPublishSidebarEnabled;
+}
diff --git a/packages/editor/src/store/test/reducer.js b/packages/editor/src/store/test/reducer.js
index 9445b32a11e7c..9913daf213ec2 100644
--- a/packages/editor/src/store/test/reducer.js
+++ b/packages/editor/src/store/test/reducer.js
@@ -1580,9 +1580,28 @@ describe( 'state', () => {
expect( state ).toEqual( {
insertUsage: {},
+ isPublishSidebarEnabled: true,
} );
} );
+ it( 'should disable the publish sidebar', () => {
+ const original = deepFreeze( preferences( undefined, { } ) );
+ const state = preferences( original, {
+ type: 'DISABLE_PUBLISH_SIDEBAR',
+ } );
+
+ expect( state.isPublishSidebarEnabled ).toBe( false );
+ } );
+
+ it( 'should enable the publish sidebar', () => {
+ const original = deepFreeze( preferences( { isPublishSidebarEnabled: false }, { } ) );
+ const state = preferences( original, {
+ type: 'ENABLE_PUBLISH_SIDEBAR',
+ } );
+
+ expect( state.isPublishSidebarEnabled ).toBe( true );
+ } );
+
it( 'should record recently used blocks', () => {
const state = preferences( deepFreeze( { insertUsage: {} } ), {
type: 'INSERT_BLOCKS',
diff --git a/packages/editor/src/store/test/selectors.js b/packages/editor/src/store/test/selectors.js
index 60bde150d492a..9b88a450c763c 100644
--- a/packages/editor/src/store/test/selectors.js
+++ b/packages/editor/src/store/test/selectors.js
@@ -13,6 +13,7 @@ import { moment } from '@wordpress/date';
* Internal dependencies
*/
import * as selectors from '../selectors';
+import { PREFERENCES_DEFAULTS } from '../defaults';
const {
canUserUseUnfilteredHTML,
@@ -82,6 +83,7 @@ const {
getReusableBlocks,
getStateBeforeOptimisticTransaction,
isPublishingPost,
+ isPublishSidebarEnabled,
canInsertBlockType,
getInserterItems,
isValidTemplate,
@@ -3387,6 +3389,33 @@ describe( 'selectors', () => {
} );
} );
+ describe( 'isPublishSidebarEnabled', () => {
+ it( 'should return the value on state if it is thruthy', () => {
+ const state = {
+ preferences: {
+ isPublishSidebarEnabled: true,
+ },
+ };
+ expect( isPublishSidebarEnabled( state ) ).toBe( state.preferences.isPublishSidebarEnabled );
+ } );
+
+ it( 'should return the value on state if it is falsy', () => {
+ const state = {
+ preferences: {
+ isPublishSidebarEnabled: false,
+ },
+ };
+ expect( isPublishSidebarEnabled( state ) ).toBe( state.preferences.isPublishSidebarEnabled );
+ } );
+
+ it( 'should return the default value if there is no isPublishSidebarEnabled key on state', () => {
+ const state = {
+ preferences: { },
+ };
+ expect( isPublishSidebarEnabled( state ) ).toBe( PREFERENCES_DEFAULTS.isPublishSidebarEnabled );
+ } );
+ } );
+
describe( 'isFetchingReusableBlock', () => {
it( 'should return false when the block is not being fetched', () => {
const state = {
diff --git a/test/e2e/specs/publishing.test.js b/test/e2e/specs/publishing.test.js
index 0eed46e1e4c1b..31265b35ece7a 100644
--- a/test/e2e/specs/publishing.test.js
+++ b/test/e2e/specs/publishing.test.js
@@ -4,48 +4,76 @@
import {
newPost,
publishPost,
+ publishPostWithoutPrePublishChecks,
+ enablePrePublishChecks,
+ disablePrePublishChecks,
+ arePrePublishChecksEnabled,
} from '../support/utils';
describe( 'Publishing', () => {
- describe( 'a post', () => {
- beforeEach( async () => {
- await newPost();
- } );
+ [ 'post', 'page' ].forEach( ( postType ) => {
+ let werePrePublishChecksEnabled;
+ describe( `a ${ postType }`, () => {
+ beforeEach( async () => {
+ await newPost( postType );
+ werePrePublishChecksEnabled = await arePrePublishChecksEnabled();
+ if ( ! werePrePublishChecksEnabled ) {
+ await enablePrePublishChecks();
+ }
+ } );
+
+ afterEach( async () => {
+ if ( ! werePrePublishChecksEnabled ) {
+ await disablePrePublishChecks();
+ }
+ } );
- it( 'should publish a post and close the panel once we start editing again', async () => {
- await page.type( '.editor-post-title__input', 'E2E Test Post' );
+ it( `should publish the ${ postType } and close the panel once we start editing again.`, async () => {
+ await page.type( '.editor-post-title__input', 'E2E Test Post' );
- await publishPost();
+ await publishPost();
- // The post-publishing panel is visible.
- expect( await page.$( '.editor-post-publish-panel' ) ).not.toBeNull();
+ // The post-publishing panel is visible.
+ expect( await page.$( '.editor-post-publish-panel' ) ).not.toBeNull();
- // Start editing again.
- await page.type( '.editor-post-title__input', ' (Updated)' );
+ // Start editing again.
+ await page.type( '.editor-post-title__input', ' (Updated)' );
- // The post-publishing panel is not visible anymore.
- expect( await page.$( '.editor-post-publish-panel' ) ).toBeNull();
+ // The post-publishing panel is not visible anymore.
+ expect( await page.$( '.editor-post-publish-panel' ) ).toBeNull();
+ } );
} );
} );
- describe( 'a page', () => {
- beforeEach( async () => {
- await newPost( 'page' );
- } );
+ [ 'post', 'page' ].forEach( ( postType ) => {
+ let werePrePublishChecksEnabled;
+ describe( `a ${ postType } with pre-publish checks disabled`, () => {
+ beforeEach( async () => {
+ await newPost( postType );
+ werePrePublishChecksEnabled = await arePrePublishChecksEnabled();
+ if ( werePrePublishChecksEnabled ) {
+ await disablePrePublishChecks();
+ }
+ } );
- it( 'should publish a page and close the panel once we start editing again', async () => {
- await page.type( '.editor-post-title__input', 'E2E Test Page' );
+ afterEach( async () => {
+ if ( werePrePublishChecksEnabled ) {
+ await enablePrePublishChecks();
+ }
+ } );
- await publishPost();
+ it( `should publish the ${ postType } without opening the post-publish sidebar.`, async () => {
+ await page.type( '.editor-post-title__input', 'E2E Test Post' );
- // The post-publishing panel is visible.
- expect( await page.$( '.editor-post-publish-panel' ) ).not.toBeNull();
+ // The "Publish" button should be shown instead of the "Publish..." toggle
+ expect( await page.$( '.editor-post-publish-panel__toggle' ) ).toBeNull();
+ expect( await page.$( '.editor-post-publish-button' ) ).not.toBeNull();
- // Start editing the page again.
- await page.type( '.editor-post-title__input', ' (Updated)' );
+ await publishPostWithoutPrePublishChecks();
- // The post-publishing panel is not visible anymore.
- expect( await page.$( '.editor-post-publish-panel' ) ).toBeNull();
+ // The post-publishing panel should have been not shown.
+ expect( await page.$( '.editor-post-publish-panel' ) ).toBeNull();
+ } );
} );
} );
} );
diff --git a/test/e2e/support/utils.js b/test/e2e/support/utils.js
index ea162ed86df7f..15a4d7bcf4768 100644
--- a/test/e2e/support/utils.js
+++ b/test/e2e/support/utils.js
@@ -136,6 +136,28 @@ export async function newPost( { postType, enableTips = false } = {} ) {
}
}
+export async function togglePrePublishChecks( ) {
+ await page.click( '.edit-post-more-menu' );
+ await page.waitForSelector( '.components-popover__content' );
+ await page.click( '.edit-post__pre-publish-checks' );
+}
+
+export async function arePrePublishChecksEnabled( ) {
+ return page.evaluate( () => window.wp.data.select( 'core/editor' ).isPublishSidebarEnabled() );
+}
+
+export async function enablePrePublishChecks( ) {
+ if ( ! await arePrePublishChecksEnabled( ) ) {
+ await togglePrePublishChecks();
+ }
+}
+
+export async function disablePrePublishChecks( ) {
+ if ( await arePrePublishChecksEnabled( ) ) {
+ await togglePrePublishChecks();
+ }
+}
+
export async function setViewport( type ) {
const allowedDimensions = {
large: { width: 960, height: 700 },
@@ -294,6 +316,17 @@ export async function publishPost() {
return page.waitForSelector( '.components-notice.is-success' );
}
+/**
+ * Publishes the post without the pre-publish checks,
+ * resolving once the request is complete (once a notice is displayed).
+ *
+ * @return {Promise} Promise resolving when publish is complete.
+ */
+export async function publishPostWithoutPrePublishChecks() {
+ await page.click( '.editor-post-publish-button' );
+ return page.waitForSelector( '.components-notice.is-success' );
+}
+
/**
* Saves the post as a draft, resolving once the request is complete (once the
* "Saved" indicator is displayed).