Skip to content

Commit

Permalink
PostPreviewButton: rewrite to functional, avoid state transitions in …
Browse files Browse the repository at this point in the history
…lifecycles (#44971)

* PostPreviewButton: rewrite to functional, avoid state transitions in lifecycles

* PreviewOptions: close dropdown after opening external preview

* Move metaboxes save into a hook in savePost

* Make isSavingPost true during entire save, not only when saving the entity

* Remove forceIsSaving and forcePreviewLink props: isSavingPost returns complete info

* Fix unit tests for isEditedPostAutosaveable and isSavingPost

* Fix PostPreviewButton unit tests

* Rename the action to editor.__unstableSavePost

* Remove the 'disabled when saving metaboxes' e2e test
  • Loading branch information
jsnajdr committed Jul 10, 2023
1 parent cb29d3c commit 55fbdd9
Show file tree
Hide file tree
Showing 19 changed files with 328 additions and 519 deletions.
35 changes: 18 additions & 17 deletions packages/block-editor/src/components/preview-options/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,24 @@ const MyPreviewOptions = () => (
className="edit-post-post-preview-dropdown"
deviceType={ deviceType }
setDeviceType={ setPreviewDeviceType }
>
<MenuGroup>
<div className="edit-post-header-preview__grouping-external">
<PostPreviewButton
className={ 'edit-post-header-preview__button-external' }
role="menuitem"
forceIsAutosaveable={ hasActiveMetaboxes }
forcePreviewLink={ isSaving ? null : undefined }
textContent={
<>
{ __( 'Preview in new tab' ) }
<Icon icon={ external } />
</>
}
/>
</div>
</MenuGroup>
> { ( { onClose } ) => (
<MenuGroup>
<div className="edit-post-header-preview__grouping-external">
<PostPreviewButton
className="edit-post-header-preview__button-external"
role="menuitem"
forceIsAutosaveable={ hasActiveMetaboxes }
textContent={
<>
{ __( 'Preview in new tab' ) }
<Icon icon={ external } />
</>
}
onPreview={ onClose }
/>
</div>
</MenuGroup>
) }
</PreviewOptions>
);
```
Expand Down
4 changes: 2 additions & 2 deletions packages/block-editor/src/components/preview-options/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default function PreviewOptions( {
icon={ deviceIcons[ deviceType.toLowerCase() ] }
label={ label || __( 'Preview' ) }
>
{ () => (
{ ( renderProps ) => (
<>
<MenuGroup>
<MenuItem
Expand All @@ -79,7 +79,7 @@ export default function PreviewOptions( {
{ __( 'Mobile' ) }
</MenuItem>
</MenuGroup>
{ children }
{ children( renderProps ) }
</>
) }
</DropdownMenu>
Expand Down
15 changes: 0 additions & 15 deletions packages/e2e-tests/specs/editor/various/publish-button.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,4 @@ describe( 'PostPublishButton', () => {
await page.$( '.editor-post-publish-button[aria-disabled="true"]' )
).not.toBeNull();
} );

it( 'should be disabled when metabox is being saved', async () => {
await canvas().type( '.editor-post-title__input', 'E2E Test Post' ); // Make it saveable.
expect(
await page.$( '.editor-post-publish-button[aria-disabled="true"]' )
).toBeNull();

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();
} );
} );
74 changes: 35 additions & 39 deletions packages/edit-post/src/components/device-preview/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,22 @@ import { store as coreStore } from '@wordpress/core-data';
import { store as editPostStore } from '../../store';

export default function DevicePreview() {
const {
hasActiveMetaboxes,
isPostSaveable,
isSaving,
isViewable,
deviceType,
} = useSelect( ( select ) => {
const { getEditedPostAttribute } = select( editorStore );
const { getPostType } = select( coreStore );
const postType = getPostType( getEditedPostAttribute( 'type' ) );
const { hasActiveMetaboxes, isPostSaveable, isViewable, deviceType } =
useSelect( ( select ) => {
const { getEditedPostAttribute } = select( editorStore );
const { getPostType } = select( coreStore );
const postType = getPostType( getEditedPostAttribute( 'type' ) );

return {
hasActiveMetaboxes: select( editPostStore ).hasMetaBoxes(),
isSaving: select( editPostStore ).isSavingMetaBoxes(),
isPostSaveable: select( editorStore ).isEditedPostSaveable(),
isViewable: postType?.viewable ?? false,
deviceType:
select( editPostStore ).__experimentalGetPreviewDeviceType(),
};
}, [] );
return {
hasActiveMetaboxes: select( editPostStore ).hasMetaBoxes(),
isPostSaveable: select( editorStore ).isEditedPostSaveable(),
isViewable: postType?.viewable ?? false,
deviceType:
select(
editPostStore
).__experimentalGetPreviewDeviceType(),
};
}, [] );
const { __experimentalSetPreviewDeviceType: setPreviewDeviceType } =
useDispatch( editPostStore );

Expand All @@ -46,26 +42,26 @@ export default function DevicePreview() {
setDeviceType={ setPreviewDeviceType }
label={ __( 'Preview' ) }
>
{ isViewable && (
<MenuGroup>
<div className="edit-post-header-preview__grouping-external">
<PostPreviewButton
className={
'edit-post-header-preview__button-external'
}
role="menuitem"
forceIsAutosaveable={ hasActiveMetaboxes }
forcePreviewLink={ isSaving ? null : undefined }
textContent={
<>
{ __( 'Preview in new tab' ) }
<Icon icon={ external } />
</>
}
/>
</div>
</MenuGroup>
) }
{ ( { onClose } ) =>
isViewable && (
<MenuGroup>
<div className="edit-post-header-preview__grouping-external">
<PostPreviewButton
className="edit-post-header-preview__button-external"
role="menuitem"
forceIsAutosaveable={ hasActiveMetaboxes }
textContent={
<>
{ __( 'Preview in new tab' ) }
<Icon icon={ external } />
</>
}
onPreview={ onClose }
/>
</div>
</MenuGroup>
)
}
</PreviewOptions>
);
}
34 changes: 12 additions & 22 deletions packages/edit-post/src/components/header/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,17 @@ const slideX = {

function Header( { setEntitiesSavedStatesCallback } ) {
const isLargeViewport = useViewportMatch( 'large' );
const {
hasActiveMetaboxes,
isPublishSidebarOpened,
isSaving,
showIconLabels,
} = useSelect(
( select ) => ( {
hasActiveMetaboxes: select( editPostStore ).hasMetaBoxes(),
isPublishSidebarOpened:
select( editPostStore ).isPublishSidebarOpened(),
isSaving: select( editPostStore ).isSavingMetaBoxes(),
showIconLabels:
select( editPostStore ).isFeatureActive( 'showIconLabels' ),
} ),
[]
);
const { hasActiveMetaboxes, isPublishSidebarOpened, showIconLabels } =
useSelect(
( select ) => ( {
hasActiveMetaboxes: select( editPostStore ).hasMetaBoxes(),
isPublishSidebarOpened:
select( editPostStore ).isPublishSidebarOpened(),
showIconLabels:
select( editPostStore ).isFeatureActive( 'showIconLabels' ),
} ),
[]
);

return (
<div className="edit-post-header">
Expand Down Expand Up @@ -82,19 +77,14 @@ function Header( { setEntitiesSavedStatesCallback } ) {
// when the publish sidebar has been closed.
<PostSavedState
forceIsDirty={ hasActiveMetaboxes }
forceIsSaving={ isSaving }
showIconLabels={ showIconLabels }
/>
) }
<DevicePreview />
<PostPreviewButton
forceIsAutosaveable={ hasActiveMetaboxes }
forcePreviewLink={ isSaving ? null : undefined }
/>
<PostPreviewButton forceIsAutosaveable={ hasActiveMetaboxes } />
<ViewLink />
<PostPublishButtonOrToggle
forceIsDirty={ hasActiveMetaboxes }
forceIsSaving={ isSaving }
setEntitiesSavedStatesCallback={
setEntitiesSavedStatesCallback
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { store as editPostStore } from '../../store';

export function PostPublishButtonOrToggle( {
forceIsDirty,
forceIsSaving,
hasPublishAction,
isBeingScheduled,
isPending,
Expand Down Expand Up @@ -67,7 +66,6 @@ export function PostPublishButtonOrToggle( {
return (
<PostPublishButton
forceIsDirty={ forceIsDirty }
forceIsSaving={ forceIsSaving }
isOpen={ isPublishSidebarOpened }
isToggle={ component === IS_TOGGLE }
onToggle={ togglePublishSidebar }
Expand Down
12 changes: 5 additions & 7 deletions packages/edit-post/src/components/layout/actions-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,17 @@ export default function ActionsPanel( {
const {
publishSidebarOpened,
hasActiveMetaboxes,
isSavingMetaBoxes,
hasNonPostEntityChanges,
} = useSelect( ( select ) => {
return {
} = useSelect(
( select ) => ( {
publishSidebarOpened:
select( editPostStore ).isPublishSidebarOpened(),
hasActiveMetaboxes: select( editPostStore ).hasMetaBoxes(),
isSavingMetaBoxes: select( editPostStore ).isSavingMetaBoxes(),
hasNonPostEntityChanges:
select( editorStore ).hasNonPostEntityChanges(),
};
}, [] );
} ),
[]
);

const openEntitiesSavedStates = useCallback(
() => setEntitiesSavedStatesCallback( true ),
Expand All @@ -57,7 +56,6 @@ export default function ActionsPanel( {
<PostPublishPanel
onClose={ closePublishSidebar }
forceIsDirty={ hasActiveMetaboxes }
forceIsSaving={ isSavingMetaBoxes }
PrePublishExtension={ PluginPrePublishPanel.Slot }
PostPublishExtension={ PluginPostPublishPanel.Slot }
/>
Expand Down
45 changes: 18 additions & 27 deletions packages/edit-post/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { store as coreStore } from '@wordpress/core-data';
import { store as blockEditorStore } from '@wordpress/block-editor';
import { store as editorStore } from '@wordpress/editor';
import deprecated from '@wordpress/deprecated';
import { addFilter } from '@wordpress/hooks';

/**
* Internal dependencies
Expand Down Expand Up @@ -567,33 +568,23 @@ export const initializeMetaBoxes =

metaBoxesInitialized = true;

let wasSavingPost = registry.select( editorStore ).isSavingPost();
let wasAutosavingPost = registry
.select( editorStore )
.isAutosavingPost();

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

// Save metaboxes on save completion, except for autosaves.
const shouldTriggerMetaboxesSave =
wasSavingPost &&
! wasAutosavingPost &&
! isSavingPost &&
select.hasMetaBoxes();

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

if ( shouldTriggerMetaboxesSave ) {
await dispatch.requestMetaBoxUpdates();
}
} );
// Save metaboxes on save completion, except for autosaves.
addFilter(
'editor.__unstableSavePost',
'core/edit-post/save-metaboxes',
( previous, options ) =>
previous.then( () => {
if ( options.isAutosave ) {
return;
}

if ( ! select.hasMetaBoxes() ) {
return;
}

return dispatch.requestMetaBoxUpdates();
} )
);

dispatch( {
type: 'META_BOXES_INITIALIZED',
Expand Down
33 changes: 18 additions & 15 deletions packages/edit-site/src/components/header-edit-mode/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,21 +323,24 @@ export default function HeaderEditMode() {
setDeviceType={ setPreviewDeviceType }
label={ __( 'View' ) }
>
<MenuGroup>
<MenuItem
href={ homeUrl }
target="_blank"
icon={ external }
>
{ __( 'View site' ) }
<VisuallyHidden as="span">
{
/* translators: accessibility text */
__( '(opens in a new tab)' )
}
</VisuallyHidden>
</MenuItem>
</MenuGroup>
{ ( { onClose } ) => (
<MenuGroup>
<MenuItem
href={ homeUrl }
target="_blank"
icon={ external }
onClick={ onClose }
>
{ __( 'View site' ) }
<VisuallyHidden as="span">
{
/* translators: accessibility text */
__( '(opens in a new tab)' )
}
</VisuallyHidden>
</MenuItem>
</MenuGroup>
) }
</PreviewOptions>
</div>
) }
Expand Down

1 comment on commit 55fbdd9

@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 55fbdd9.
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/5507451025
📝 Reported issues:

Please sign in to comment.