Skip to content

Commit

Permalink
Post Editor: Update publish flow (#60456)
Browse files Browse the repository at this point in the history
Co-authored-by: ntsekouras <[email protected]>
Co-authored-by: jameskoster <[email protected]>
Co-authored-by: youknowriad <[email protected]>
Co-authored-by: oandregal <[email protected]>
Co-authored-by: mirka <[email protected]>
  • Loading branch information
6 people authored Apr 17, 2024
1 parent 671b9ed commit 50f5c74
Show file tree
Hide file tree
Showing 31 changed files with 655 additions and 277 deletions.
18 changes: 14 additions & 4 deletions packages/e2e-test-utils-playwright/src/editor/publish-post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,21 @@ import type { Editor } from './index';
* @param this
*/
export async function publishPost( this: Editor ) {
await this.page.click( 'role=button[name="Publish"i]' );
const entitiesSaveButton = this.page.locator(
'role=region[name="Editor publish"i] >> role=button[name="Save"i]'
);
// If we have changes in other entities, the label is `Save` instead of `Publish`.
const saveButton = this.page
.getByRole( 'region', { name: 'Editor top bar' } )
.getByRole( 'button', { name: 'Save', exact: true } );
const publishButton = this.page
.getByRole( 'region', { name: 'Editor top bar' } )
.getByRole( 'button', { name: 'Publish' } );
const buttonToClick = ( await saveButton.isVisible() )
? saveButton
: publishButton;
await buttonToClick.click();

const entitiesSaveButton = this.page
.getByRole( 'region', { name: 'Editor publish' } )
.getByRole( 'button', { name: 'Save', exact: true } );
const isEntitiesSavePanelVisible = await entitiesSaveButton.isVisible();

// Save any entities.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export function PostPublishButtonOrToggle( {
isScheduled,
togglePublishSidebar,
setEntitiesSavedStatesCallback,
postStatusHasChanged,
postStatus,
} ) {
const IS_TOGGLE = 'toggle';
const IS_BUTTON = 'button';
Expand All @@ -29,6 +31,7 @@ export function PostPublishButtonOrToggle( {
* for a particular role (see https://wordpress.org/documentation/article/post-status/):
*
* - is published
* - post status has changed explicitely to something different than 'future' or 'publish'
* - is scheduled to be published
* - is pending and can't be published (but only for viewports >= medium).
* Originally, we considered showing a button for pending posts that couldn't be published
Expand All @@ -46,13 +49,13 @@ export function PostPublishButtonOrToggle( {
*/
if (
isPublished ||
( postStatusHasChanged &&
! [ 'future', 'publish' ].includes( postStatus ) ) ||
( isScheduled && isBeingScheduled ) ||
( isPending && ! hasPublishAction && ! isSmallerThanMediumViewport )
) {
component = IS_BUTTON;
} else if ( isSmallerThanMediumViewport ) {
component = IS_TOGGLE;
} else if ( isPublishSidebarEnabled ) {
} else if ( isSmallerThanMediumViewport || isPublishSidebarEnabled ) {
component = IS_TOGGLE;
} else {
component = IS_BUTTON;
Expand Down Expand Up @@ -82,6 +85,8 @@ export default compose(
select( editorStore ).isPublishSidebarEnabled(),
isPublishSidebarOpened: select( editorStore ).isPublishSidebarOpened(),
isScheduled: select( editorStore ).isCurrentPostScheduled(),
postStatus: select( editorStore ).getEditedPostAttribute( 'status' ),
postStatusHasChanged: select( editorStore ).getPostEdits()?.status,
} ) ),
withDispatch( ( dispatch ) => {
const { togglePublishSidebar } = dispatch( editorStore );
Expand Down
14 changes: 13 additions & 1 deletion packages/edit-post/src/components/header/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,23 @@
*/
import { render, screen } from '@testing-library/react';

/**
* WordPress dependencies
*/
import { useViewportMatch } from '@wordpress/compose';

/**
* Internal dependencies
*/
import { PostPublishButtonOrToggle } from '../post-publish-button-or-toggle';

jest.mock( '@wordpress/compose/src/hooks/use-viewport-match' );

describe( 'PostPublishButtonOrToggle should render a', () => {
afterEach( () => {
useViewportMatch.mockRestore();
} );

it( 'button when the post is published (1)', () => {
render( <PostPublishButtonOrToggle isPublished /> );
expect(
Expand All @@ -33,7 +44,8 @@ describe( 'PostPublishButtonOrToggle should render a', () => {
).toBeVisible();
} );

it( 'toggle when post is not (1), (2), (3), the viewport is >= medium, and the publish sidebar is enabled', () => {
it( 'toggle when post is not (1), (2), (3), the viewport is <= medium, and the publish sidebar is enabled', () => {
useViewportMatch.mockReturnValue( true );
render( <PostPublishButtonOrToggle isPublishSidebarEnabled /> );
expect(
screen.getByRole( 'button', { name: 'Publish' } )
Expand Down
13 changes: 5 additions & 8 deletions packages/edit-post/src/components/sidebar/post-status/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,25 @@ import { useDispatch, useSelect } from '@wordpress/data';
import {
PostAuthorPanel,
PostSchedulePanel,
PostSwitchToDraftButton,
PostSyncStatus,
PostURLPanel,
PostTemplatePanel,
PostFeaturedImagePanel,
store as editorStore,
privateApis as editorPrivateApis,
} from '@wordpress/editor';

/**
* Internal dependencies
*/
import PostVisibility from '../post-visibility';
import PostTrash from '../post-trash';
import PostSticky from '../post-sticky';
import PostSlug from '../post-slug';
import PostFormat from '../post-format';
import PostPendingStatus from '../post-pending-status';
import PluginPostStatusInfo from '../plugin-post-status-info';
import { unlock } from '../../../lock-unlock';

const { PostStatus: PostStatusPanel } = unlock( editorPrivateApis );

/**
* Module Constants
Expand Down Expand Up @@ -61,14 +62,13 @@ export default function PostStatus() {
<PluginPostStatusInfo.Slot>
{ ( fills ) => (
<>
<PostStatusPanel />
<PostFeaturedImagePanel withPanelBody={ false } />
<PostVisibility />
<PostSchedulePanel />
<PostTemplatePanel />
<PostURLPanel />
<PostSyncStatus />
<PostSticky />
<PostPendingStatus />
<PostFormat />
<PostSlug />
<PostAuthorPanel />
Expand All @@ -77,10 +77,7 @@ export default function PostStatus() {
style={ {
marginTop: '16px',
} }
spacing={ 4 }
wrap
>
<PostSwitchToDraftButton />
<PostTrash />
</HStack>
</>
Expand Down
59 changes: 23 additions & 36 deletions packages/editor/src/components/post-publish-button/index.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import { Button } from '@wordpress/components';
import { Component, createRef } from '@wordpress/element';
import { withSelect, withDispatch } from '@wordpress/data';
import { compose } from '@wordpress/compose';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
Expand Down Expand Up @@ -112,13 +106,14 @@ export class PostPublishButton extends Component {
isSaving,
isAutoSaving,
isToggle,
onSave,
onStatusChange,
savePostStatus,
onSubmit = noop,
onToggle,
visibility,
hasNonPostEntityChanges,
isSavingNonPostEntityChanges,
postStatus,
postStatusHasChanged,
} = this.props;

const isButtonDisabled =
Expand All @@ -135,26 +130,30 @@ export class PostPublishButton extends Component {
( ! isPublishable && ! forceIsDirty ) ) &&
( ! hasNonPostEntityChanges || isSavingNonPostEntityChanges );

let publishStatus;
if ( ! hasPublishAction ) {
// If the new status has not changed explicitely, we derive it from
// other factors, like having a publish action, etc.. We need to preserve
// this because it affects when to show the pre and post publish panels.
// If it has changed though explicitely, we need to respect that.
let publishStatus = 'publish';
if ( postStatusHasChanged ) {
publishStatus = postStatus;
} else if ( ! hasPublishAction ) {
publishStatus = 'pending';
} else if ( visibility === 'private' ) {
publishStatus = 'private';
} else if ( isBeingScheduled ) {
publishStatus = 'future';
} else {
publishStatus = 'publish';
}

const onClickButton = () => {
if ( isButtonDisabled ) {
return;
}
onSubmit();
onStatusChange( publishStatus );
onSave();
savePostStatus( publishStatus );
};

// Callback to open the publish panel.
const onClickToggle = () => {
if ( isToggleDisabled ) {
return;
Expand All @@ -179,33 +178,16 @@ export class PostPublishButton extends Component {
size: 'compact',
onClick: this.createOnClick( onClickToggle ),
};

const toggleChildren = isBeingScheduled
? __( 'Schedule…' )
: __( 'Publish' );
const buttonChildren = (
<PublishButtonLabel
hasNonPostEntityChanges={ hasNonPostEntityChanges }
/>
);

const componentProps = isToggle ? toggleProps : buttonProps;
const componentChildren = isToggle ? toggleChildren : buttonChildren;
return (
<>
<Button
ref={ this.buttonNode }
{ ...componentProps }
className={ classnames(
componentProps.className,
'editor-post-publish-button__button',
{
'has-changes-dot': hasNonPostEntityChanges,
}
) }
className={ `${ componentProps.className } editor-post-publish-button__button` }
size="compact"
>
{ componentChildren }
<PublishButtonLabel />
</Button>
</>
);
Expand All @@ -228,6 +210,8 @@ export default compose( [
getCurrentPostId,
hasNonPostEntityChanges,
isSavingNonPostEntityChanges,
getEditedPostAttribute,
getPostEdits,
} = select( editorStore );
return {
isSaving: isSavingPost(),
Expand All @@ -242,16 +226,19 @@ export default compose( [
getCurrentPost()._links?.[ 'wp:action-publish' ] ?? false,
postType: getCurrentPostType(),
postId: getCurrentPostId(),
postStatus: getEditedPostAttribute( 'status' ),
postStatusHasChanged: getPostEdits()?.status,
hasNonPostEntityChanges: hasNonPostEntityChanges(),
isSavingNonPostEntityChanges: isSavingNonPostEntityChanges(),
};
} ),
withDispatch( ( dispatch ) => {
const { editPost, savePost } = dispatch( editorStore );
return {
onStatusChange: ( status ) =>
editPost( { status }, { undoIgnore: true } ),
onSave: savePost,
savePostStatus: ( status ) => {
editPost( { status }, { undoIgnore: true } );
savePost();
},
};
} ),
] )( PostPublishButton );
Loading

1 comment on commit 50f5c74

@github-actions
Copy link

Choose a reason for hiding this comment

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

Flaky tests detected in 50f5c74.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/8719839926
📝 Reported issues:

Please sign in to comment.