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

Add the ability to create a new page in the Site Editor #50565

Merged
merged 23 commits into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
21 changes: 0 additions & 21 deletions docs/reference-guides/data/data-core-edit-site.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,18 +131,6 @@ _Returns_

- `Object`: Settings.

### isCreatePageModalOpened

Returns the current opened/closed state of the create page modal.

_Parameters_

- _state_ `Object`: Global application state.

_Returns_

- `boolean`: True if the create page modal should be open; false if closed.

### isFeatureActive

> **Deprecated**
Expand Down Expand Up @@ -268,15 +256,6 @@ _Returns_

> **Deprecated**

### setIsCreatePageModalOpened

Sets whether the create new page modal is open

_Parameters_

- _isOpen_ `boolean`: If true, opens the create new page modal. If false, closes it. It does not toggle the state, but sets it directly.
- _options_ `Object`: Options for the create new page modal.

### setIsInserterOpened

Opens or closes the inserter.
Expand Down
52 changes: 5 additions & 47 deletions packages/edit-site/src/components/add-new-page/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,43 +14,21 @@ import {
TextControl,
} from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import { useDispatch, useSelect } from '@wordpress/data';
import { useDispatch } from '@wordpress/data';
import { useState } from '@wordpress/element';
import { store as coreStore } from '@wordpress/core-data';
import { store as noticesStore } from '@wordpress/notices';
import { privateApis as routerPrivateApis } from '@wordpress/router';

/**
* Internal dependencies
*/
import { store as editSiteStore } from '../../store';
import { unlock } from '../../private-apis';

const DEFAULT_TITLE = __( 'Untitled page' );

const { useHistory } = unlock( routerPrivateApis );

export default function AddNewPageModal() {
export default function AddNewPageModal( { onSave, onCancel } ) {
const [ isCreatingPage, setIsCreatingPage ] = useState( false );
const [ title, setTitle ] = useState( DEFAULT_TITLE );

const history = useHistory();
const { saveEntityRecord } = useDispatch( coreStore );
const { createErrorNotice, createSuccessNotice } =
useDispatch( noticesStore );

const { isCreatePageModalOpen } = useSelect( ( select ) => {
const { isCreatePageModalOpened } = unlock( select( editSiteStore ) );

return {
isCreatePageModalOpen: isCreatePageModalOpened(),
};
}, [] );

const { setIsCreatePageModalOpened } = useDispatch( editSiteStore );

const { setPage } = unlock( useDispatch( editSiteStore ) );

async function createPage( event ) {
event.preventDefault();

Expand All @@ -70,21 +48,7 @@ export default function AddNewPageModal() {
{ throwOnError: true }
);

if ( isCreatePageModalOpen.options?.redirectAfterSave ) {
// Set template before navigating away to avoid initial stale value.
setPage( {
context: { postType: 'page', postId: newPage.id },
} );
// Navigate to the created template editor.
history.push( {
postId: newPage.id,
postType: newPage.type,
canvas: 'edit',
} );
}

// Close the modal when complete
setIsCreatePageModalOpened( false, { redirectAfterSave: false } );
onSave( newPage );

Copy link
Contributor

Choose a reason for hiding this comment

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

After the page is created, where should focus get placed? Right now it's being dropped at the hidden Back button in the closed sidebar. I agree with @carolinan that the current mode of being moved to the site editor template for this page is an odd experience. I'd be fine with it if the sidebar stayed open, in which case, handling the focus here isn't an issue since it's being placed in a sensible spot.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the current mode of being moved to the site editor template for this page is an odd experience

This will make more sense once the content editing PR is merged. There is also some follow up work around improving the add page experience, including selecting starter patterns.

createSuccessNotice(
sprintf(
Expand All @@ -110,14 +74,8 @@ export default function AddNewPageModal() {
}
}

const handleClose = () => {
setIsCreatePageModalOpened( false );
};

if ( ! isCreatePageModalOpen.isOpen ) return null;

return (
<Modal title="Draft a new page" onRequestClose={ handleClose }>
<Modal title="Draft a new page" onRequestClose={ onCancel }>
<form onSubmit={ createPage }>
<VStack spacing={ 3 }>
<TextControl
SaxonF marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -127,7 +85,7 @@ export default function AddNewPageModal() {
value={ title }
SaxonF marked this conversation as resolved.
Show resolved Hide resolved
/>
<HStack spacing={ 2 } justify="end">
<Button variant="tertiary" onClick={ handleClose }>
<Button variant="tertiary" onClick={ onCancel }>
{ __( 'Cancel' ) }
</Button>
<Button
Expand Down
2 changes: 0 additions & 2 deletions packages/edit-site/src/components/layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import { unlock } from '../../private-apis';
import SavePanel from '../save-panel';
import KeyboardShortcutsRegister from '../keyboard-shortcuts/register';
import KeyboardShortcutsGlobal from '../keyboard-shortcuts/global';
import AddNewPageModal from '../add-new-page';

const { useCommands } = unlock( coreCmmandsPrivateApis );

Expand Down Expand Up @@ -133,7 +132,6 @@ export default function Layout() {
return (
<>
{ window?.__experimentalEnableCommandCenter && <CommandMenu /> }
<AddNewPageModal />
<KeyboardShortcutsRegister />
<KeyboardShortcutsGlobal />
{ fullResizer }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import {
__experimentalItemGroup as ItemGroup,
__experimentalItem as Item,
} from '@wordpress/components';
import { useState } from '@wordpress/elements';
import { __ } from '@wordpress/i18n';
import { useEntityRecords } from '@wordpress/core-data';
import { decodeEntities } from '@wordpress/html-entities';
import { plus } from '@wordpress/icons';
import { useDispatch } from '@wordpress/data';
import { privateApis as routerPrivateApis } from '@wordpress/router';

/**
* Internal dependencies
Expand All @@ -20,6 +22,10 @@ import { useLink } from '../routes/link';
import SidebarNavigationItem from '../sidebar-navigation-item';
import SidebarNavigationSubtitle from '../sidebar-navigation-subtitle';
import SidebarButton from '../sidebar-button';
import AddNewPageModal from '../add-new-page';
import { unlock } from '../../private-apis';

const { useHistory } = unlock( routerPrivateApis );

const PageItem = ( { postId, ...props } ) => {
const linkInfo = useLink( {
Expand All @@ -35,65 +41,85 @@ export default function SidebarNavigationScreenPages() {
'page'
);

const { setIsCreatePageModalOpened } = useDispatch( editSiteStore );
const [ showAddPage, setShowAddPage ] = useState( false );

const history = useHistory();
const { setPage } = unlock( useDispatch( editSiteStore ) );

const handleNewPage = ( { type, id } ) => {
setPage( {
context: { postType: type, postId: id },
} );
SaxonF marked this conversation as resolved.
Show resolved Hide resolved
// Navigate to the created template editor.
history.push( {
SaxonF marked this conversation as resolved.
Show resolved Hide resolved
postId: id,
postType: type,
canvas: 'edit',
} );
setShowAddPage( false );
};

return (
<SidebarNavigationScreen
title={ __( 'Pages' ) }
description={ __( 'Browse and edit pages on your site.' ) }
actions={
<SidebarButton
icon={ plus }
label={ __( 'Draft a new page' ) }
onClick={ () =>
setIsCreatePageModalOpened( true, {
redirectAfterSave: true,
} )
}
<>
{ showAddPage && (
<AddNewPageModal
onSave={ handleNewPage }
onCancel={ () => setShowAddPage( false ) }
SaxonF marked this conversation as resolved.
Show resolved Hide resolved
/>
}
content={
<>
{ isLoading && (
<ItemGroup>
<Item>{ __( 'Loading pages' ) }</Item>
</ItemGroup>
) }
{ ! isLoading && (
<>
<SidebarNavigationSubtitle>
{ __( 'Recent' ) }
</SidebarNavigationSubtitle>
) }
<SidebarNavigationScreen
title={ __( 'Pages' ) }
description={ __( 'Browse and edit pages on your site.' ) }
actions={
<SidebarButton
icon={ plus }
label={ __( 'Draft a new page' ) }
onClick={ () => setShowAddPage( true ) }
/>
}
content={
<>
{ isLoading && (
<ItemGroup>
{ ! pages?.length && (
<Item>{ __( 'No page found' ) }</Item>
) }
{ pages?.map( ( page ) => (
<PageItem
postId={ page.id }
key={ page.id }
withChevron
>
{ decodeEntities(
page.title?.rendered
) ?? __( '(no title)' ) }
</PageItem>
) ) }
<SidebarNavigationItem
className="edit-site-sidebar-navigation-screen-pages__see-all"
href="edit.php?post_type=page"
onClick={ () => {
document.location =
'edit.php?post_type=page';
} }
>
{ __( 'Manage all pages' ) }
</SidebarNavigationItem>
<Item>{ __( 'Loading pages' ) }</Item>
</ItemGroup>
</>
) }
</>
}
/>
) }
{ ! isLoading && (
<>
<SidebarNavigationSubtitle>
{ __( 'Recent' ) }
</SidebarNavigationSubtitle>
<ItemGroup>
{ ! pages?.length && (
<Item>{ __( 'No page found' ) }</Item>
) }
{ pages?.map( ( page ) => (
<PageItem
postId={ page.id }
key={ page.id }
withChevron
>
{ decodeEntities(
page.title?.rendered
) ?? __( '(no title)' ) }
Copy link
Contributor

Choose a reason for hiding this comment

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

If the page title is an empty string this will return an empty string rather than (no title).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@scruffian I think this is something we can address in this issue as its more directly related to the pages list

</PageItem>
) ) }
<SidebarNavigationItem
className="edit-site-sidebar-navigation-screen-pages__see-all"
href="edit.php?post_type=page"
onClick={ () => {
document.location =
SaxonF marked this conversation as resolved.
Show resolved Hide resolved
'edit.php?post_type=page';
} }
>
{ __( 'Manage all pages' ) }
</SidebarNavigationItem>
</ItemGroup>
</>
) }
</>
}
/>
</>
);
}
15 changes: 0 additions & 15 deletions packages/edit-site/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -354,21 +354,6 @@ export function setIsSaveViewOpened( isOpen ) {
};
}

/**
* Sets whether the create new page modal is open
*
* @param {boolean} isOpen If true, opens the create new page modal. If false, closes it.
* It does not toggle the state, but sets it directly.
* @param {Object} options Options for the create new page modal.
*/
export function setIsCreatePageModalOpened( isOpen, options ) {
return {
type: 'SET_IS_CREATE_PAGE_MODAL_OPENED',
isOpen,
options,
};
}

/**
* Reverts a template to its original theme-provided file.
*
Expand Down
19 changes: 0 additions & 19 deletions packages/edit-site/src/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,32 +157,13 @@ function editorCanvasContainerView( state = undefined, action ) {
return state;
}

/**
* Reducer used to track the create new page modal which can be opened in and out of editor
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*/
function createPageModal( state = false, action ) {
switch ( action.type ) {
case 'SET_IS_CREATE_PAGE_MODAL_OPENED':
return {
isOpen: action.isOpen,
options: action.options,
};
}

return state;
}

export default combineReducers( {
deviceType,
settings,
editedPost,
blockInserterPanel,
listViewPanel,
saveViewPanel,
createPageModal,
canvasMode,
editorCanvasContainerView,
} );
11 changes: 0 additions & 11 deletions packages/edit-site/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -289,17 +289,6 @@ export function getEditorMode( state ) {
return __unstableGetPreference( state, 'editorMode' );
}

/**
* Returns the current opened/closed state of the create page modal.
*
* @param {Object} state Global application state.
*
* @return {boolean} True if the create page modal should be open; false if closed.
*/
export function isCreatePageModalOpened( state ) {
return state.createPageModal;
}

/**
* @deprecated
*/
Expand Down