-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Reuse and unify post and page actions, accross the different use cases. #59849
Changes from all commits
9b24862
431b77b
ae011ed
5340396
d92a6b1
fe078b0
1464197
32a9320
6116b91
3248418
2f87575
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,126 @@ | ||||||||||
/** | ||||||||||
* WordPress dependencies | ||||||||||
*/ | ||||||||||
import { | ||||||||||
PanelBody, | ||||||||||
__experimentalText as Text, | ||||||||||
__experimentalVStack as VStack, | ||||||||||
} from '@wordpress/components'; | ||||||||||
import { | ||||||||||
store as editorStore, | ||||||||||
privateApis as editorPrivateApis, | ||||||||||
} from '@wordpress/editor'; | ||||||||||
import { decodeEntities } from '@wordpress/html-entities'; | ||||||||||
import { useSelect } from '@wordpress/data'; | ||||||||||
import { useMemo } from '@wordpress/element'; | ||||||||||
import { page as pageIcon } from '@wordpress/icons'; | ||||||||||
import { __, sprintf } from '@wordpress/i18n'; | ||||||||||
import { humanTimeDiff } from '@wordpress/date'; | ||||||||||
import { addQueryArgs } from '@wordpress/url'; | ||||||||||
|
||||||||||
/** | ||||||||||
* Internal dependencies | ||||||||||
*/ | ||||||||||
import { unlock } from '../../../lock-unlock'; | ||||||||||
|
||||||||||
const { | ||||||||||
PostActions: EditorPostActions, | ||||||||||
postManagementActions, | ||||||||||
PostSidebarCard, | ||||||||||
} = unlock( editorPrivateApis ); | ||||||||||
|
||||||||||
const { | ||||||||||
trashPostAction, | ||||||||||
usePermanentlyDeletePostAction, | ||||||||||
useRestorePostAction, | ||||||||||
postRevisionsAction, | ||||||||||
} = postManagementActions; | ||||||||||
|
||||||||||
function PostActions( { postType, postId } ) { | ||||||||||
const permanentlyDeletePostAction = usePermanentlyDeletePostAction(); | ||||||||||
const restorePostAction = useRestorePostAction(); | ||||||||||
|
||||||||||
const actions = useMemo( () => { | ||||||||||
const TrashPostModal = trashPostAction.RenderModal; | ||||||||||
const customizedTrashPostAction = { | ||||||||||
...trashPostAction, | ||||||||||
RenderModal: ( props ) => { | ||||||||||
return ( | ||||||||||
<TrashPostModal | ||||||||||
{ ...props } | ||||||||||
onPerform={ () => { | ||||||||||
if ( props.onPerform ) { | ||||||||||
props.onPerform(); | ||||||||||
} | ||||||||||
Comment on lines
+52
to
+54
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just for fun:
Suggested change
|
||||||||||
window.location.href = addQueryArgs( 'edit.php', { | ||||||||||
post_type: postType, | ||||||||||
} ); | ||||||||||
} } | ||||||||||
/> | ||||||||||
); | ||||||||||
}, | ||||||||||
}; | ||||||||||
const customizedPermanentlyDeletePostAction = { | ||||||||||
...permanentlyDeletePostAction, | ||||||||||
callback: async ( posts, onPerform ) => { | ||||||||||
await permanentlyDeletePostAction.callback( posts, () => { | ||||||||||
if ( onPerform ) { | ||||||||||
onPerform(); | ||||||||||
} | ||||||||||
window.location.href = addQueryArgs( 'edit.php', { | ||||||||||
post_type: postType, | ||||||||||
} ); | ||||||||||
} ); | ||||||||||
}, | ||||||||||
}; | ||||||||||
return [ | ||||||||||
customizedTrashPostAction, | ||||||||||
customizedPermanentlyDeletePostAction, | ||||||||||
restorePostAction, | ||||||||||
postRevisionsAction, | ||||||||||
]; | ||||||||||
}, [ permanentlyDeletePostAction, restorePostAction, postType ] ); | ||||||||||
|
||||||||||
return ( | ||||||||||
<EditorPostActions | ||||||||||
postType={ postType } | ||||||||||
postId={ postId } | ||||||||||
actions={ actions } | ||||||||||
/> | ||||||||||
); | ||||||||||
} | ||||||||||
|
||||||||||
export default function PostInitialSidebar() { | ||||||||||
const { postType, postId, modified, title } = useSelect( ( select ) => { | ||||||||||
const { getCurrentPostType, getCurrentPostId, getEditedPostAttribute } = | ||||||||||
select( editorStore ); | ||||||||||
return { | ||||||||||
postType: getCurrentPostType(), | ||||||||||
postId: getCurrentPostId(), | ||||||||||
title: getEditedPostAttribute( 'title' ), | ||||||||||
modified: getEditedPostAttribute( 'modified' ), | ||||||||||
}; | ||||||||||
} ); | ||||||||||
return ( | ||||||||||
<PanelBody> | ||||||||||
<PostSidebarCard | ||||||||||
title={ decodeEntities( title ) } | ||||||||||
icon={ pageIcon } | ||||||||||
actions={ | ||||||||||
<PostActions postType={ postType } postId={ postId } /> | ||||||||||
} | ||||||||||
description={ | ||||||||||
<VStack> | ||||||||||
<Text> | ||||||||||
{ sprintf( | ||||||||||
// translators: %s: Human-readable time difference, e.g. "2 days ago". | ||||||||||
__( 'Last edited %s' ), | ||||||||||
humanTimeDiff( modified ) | ||||||||||
) } | ||||||||||
</Text> | ||||||||||
</VStack> | ||||||||||
} | ||||||||||
/> | ||||||||||
</PanelBody> | ||||||||||
); | ||||||||||
} |
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ import { dateI18n, getDate, getSettings } from '@wordpress/date'; | |
import { privateApis as routerPrivateApis } from '@wordpress/router'; | ||
import { useSelect, useDispatch } from '@wordpress/data'; | ||
import { DataViews } from '@wordpress/dataviews'; | ||
import { privateApis as editorPrivateApis } from '@wordpress/editor'; | ||
|
||
/** | ||
* Internal dependencies | ||
|
@@ -34,17 +35,19 @@ import { | |
OPERATOR_IS_NONE, | ||
} from '../../utils/constants'; | ||
|
||
import { | ||
import AddNewPageModal from '../add-new-page'; | ||
import Media from '../media'; | ||
import { unlock } from '../../lock-unlock'; | ||
|
||
const { postManagementActions } = unlock( editorPrivateApis ); | ||
const { | ||
trashPostAction, | ||
usePermanentlyDeletePostAction, | ||
useRestorePostAction, | ||
postRevisionsAction, | ||
viewPostAction, | ||
useEditPostAction, | ||
} from '../actions'; | ||
import AddNewPageModal from '../add-new-page'; | ||
import Media from '../media'; | ||
import { unlock } from '../../lock-unlock'; | ||
postRevisionsAction, | ||
} = postManagementActions; | ||
|
||
const { useLocation, useHistory } = unlock( routerPrivateApis ); | ||
|
||
|
@@ -352,13 +355,24 @@ export default function PagePages() { | |
const permanentlyDeletePostAction = usePermanentlyDeletePostAction(); | ||
const restorePostAction = useRestorePostAction(); | ||
const editPostAction = useEditPostAction(); | ||
const customizedEditPostAction = { | ||
...editPostAction, | ||
callback: ( posts ) => { | ||
const post = posts[ 0 ]; | ||
history.push( { | ||
postId: post.id, | ||
postType: post.type, | ||
canvas: 'edit', | ||
} ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe we have some "commands" that either navigate using the url or use history depending on whether we detect that we're in the site editor. Can't we do the same thing within the shared action and avoid overriding it entirely? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The action itself does not determine whether navigation is necessary or not. For instance, on data views (such as the posts list), the action is used as it is, without requiring any navigation. It is the specific location where the action is utilized that determines whether performing an action has a side effect, such as navigation. The commands always navigate to the site editor, even if the post was in the post editor:
When we are in the post editor and a post is deleted we want to go back to the "old post" list "edit.php?post_type=page" at least for now. We may also need to go to "edit.php?post_type=post" or to "edit.php?post_type=custom_post_type" so we don't want to go to the site editor every time like in commands. We could have in the editor something like
Where usePostActions(true) is used on post editor, site editor details and site editor inspector. When it is true we would have some logic to check if we are in the site editor isSiteEditor(). If yes we navigate in a way if not we navigate in another way. But that approach seems wrong to me it is editor package that is implementing the specific logic of post-edit, and site-edit while to me it seems it should be the other way around. |
||
}, | ||
}; | ||
const actions = useMemo( | ||
() => [ | ||
viewPostAction, | ||
trashPostAction, | ||
restorePostAction, | ||
permanentlyDeletePostAction, | ||
editPostAction, | ||
customizedEditPostAction, | ||
postRevisionsAction, | ||
], | ||
[ permanentlyDeletePostAction, restorePostAction, editPostAction ] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is specific about edit-post that is forcing us to override the default "editor" PostActions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When we execute an action, it may require us to navigate to a different page. For example, when we delete a post while editing it, we need to navigate to a completely different page using "window.location.href". This is a unique requirement on the edit-post. We are not replacing the action, but rather, we are adding specific callbacks to the onPerform function when needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But it's almost always the same kind of override. So rather than all of this complex code, some simple
onNavigateToList
/onNavigateToPost
props or something like that could work.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would work. Thank you for the suggestion @youknowriad 👍 Another possibility is a a generic usePostActions( onPerform ) with a global onPerform( actionId, items) that receives the actionId and the items where the action was executed. And then the usage would be very simple:
Let me know which API would you prefer a onNavigateToList and a onNavigateToPost or a global onPerform.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the generic
onPerform
is slightly better.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
onPerform
is not very obvious. MaybeonNavigateAfterAction
?onAfterAction
?onActionPerformed
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good points. The onPerform may be used for other things besides navigation e.g: close a menu after the action is performed etc. And we already had onPerform for actions before:
gutenberg/packages/edit-site/src/components/actions/index.js
Lines 150 to 153 in 9c0a5ac
But not all of the actions had it.
I think I will go for onActionPerformed, it more clear on what it does and what is expected when compared with just onPerform.