diff --git a/packages/edit-site/src/components/post-edit/header.js b/packages/edit-site/src/components/post-edit/header.js deleted file mode 100644 index 305589d0cc22bf..00000000000000 --- a/packages/edit-site/src/components/post-edit/header.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * WordPress dependencies - */ -import { - __experimentalHStack as HStack, - __experimentalVStack as VStack, - Icon, - __experimentalText as Text, -} from '@wordpress/components'; -import { useMemo } from '@wordpress/element'; -import { - privateApis as editorPrivateApis, - store as editorStore, -} from '@wordpress/editor'; -import { store as coreStore } from '@wordpress/core-data'; -import { useSelect } from '@wordpress/data'; -import { sprintf, __ } from '@wordpress/i18n'; - -/** - * Internal dependencies - */ -import { unlock } from '../../lock-unlock'; - -const { PostCardPanel } = unlock( editorPrivateApis ); - -export default function PostEditHeader( { postType, postId } ) { - const ids = useMemo( () => postId.split( ',' ), [ postId ] ); - const { icon, labels } = useSelect( - ( select ) => { - const { getEditedEntityRecord, getPostType } = select( coreStore ); - const { getPostIcon } = unlock( select( editorStore ) ); - const _record = getEditedEntityRecord( - 'postType', - postType, - ids[ 0 ] - ); - - return { - icon: getPostIcon( postType, { - area: _record?.area, - } ), - labels: getPostType( postType )?.labels, - }; - }, - [ ids, postType ] - ); - - if ( ids.length === 1 ) { - return ( - - ); - } - - return ( - - - - - { labels?.name && - sprintf( - // translators: %i number of selected items %s: Name of the plural post type e.g: "Posts". - __( '%i %s' ), - ids.length, - labels?.name - ) } - - - - { sprintf( - // translators: %s: Name of the plural post type e.g: "Posts". - __( 'Changes will be applied to all selected %s.' ), - labels?.name.toLowerCase() - ) } - - - ); -} diff --git a/packages/edit-site/src/components/post-edit/index.js b/packages/edit-site/src/components/post-edit/index.js index b3954e4ddbdeaf..d32666bcf3aa1b 100644 --- a/packages/edit-site/src/components/post-edit/index.js +++ b/packages/edit-site/src/components/post-edit/index.js @@ -18,12 +18,11 @@ import { privateApis as editorPrivateApis } from '@wordpress/editor'; * Internal dependencies */ import Page from '../page'; -import PostEditHeader from '../post-edit/header'; import { unlock } from '../../lock-unlock'; import usePatternSettings from '../page-patterns/use-pattern-settings'; import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor'; -const { usePostFields } = unlock( editorPrivateApis ); +const { usePostFields, PostCardPanel } = unlock( editorPrivateApis ); const fieldsWithBulkEditSupport = [ 'title', @@ -159,7 +158,7 @@ function PostEditForm( { postType, postId } ) { return ( - + { const { getEditedEntityRecord, getEntityRecordPermissions } = unlock( select( coreStore ) ); return { - item: getEditedEntityRecord( 'postType', postType, postId ), - permissions: getEntityRecordPermissions( - 'postType', - postType, - postId + items: postIds.map( ( postId ) => + getEditedEntityRecord( 'postType', postType, postId ) + ), + permissions: postIds.map( ( postId ) => + getEntityRecordPermissions( 'postType', postType, postId ) ), }; }, - [ postId, postType ] + [ postIds, postType ] ); - const itemWithPermissions = useMemo( () => { - return { + + return useMemo( () => { + return items.map( ( item, index ) => ( { ...item, - permissions, - }; - }, [ item, permissions ] ); + permissions: permissions[ index ], + } ) ); + }, [ items, permissions ] ); +} + +export default function PostActions( { postType, postId, onActionPerformed } ) { + const [ activeModalAction, setActiveModalAction ] = useState( null ); + const _postIds = useMemo( () => { + if ( Array.isArray( postId ) ) { + return postId; + } + return postId ? [ postId ] : []; + }, [ postId ] ); + + const itemsWithPermissions = useEditedEntityRecordsWithPermissions( + postType, + _postIds + ); const allActions = usePostActions( { postType, onActionPerformed } ); const actions = useMemo( () => { return allActions.filter( ( action ) => { return ( - ! action.isEligible || action.isEligible( itemWithPermissions ) + ( ! action.isEligible || + itemsWithPermissions.some( ( itemWithPermissions ) => + action.isEligible( itemWithPermissions ) + ) ) && + ( itemsWithPermissions.length < 2 || action.supportsBulk ) ); } ); - }, [ allActions, itemWithPermissions ] ); + }, [ allActions, itemsWithPermissions ] ); return ( <> @@ -70,14 +89,14 @@ export default function PostActions( { postType, postId, onActionPerformed } ) { > { !! activeModalAction && ( setActiveModalAction( null ) } /> ) } @@ -119,7 +138,7 @@ export function ActionModal( { action, items, closeModal } ) { ); } -function ActionsDropdownMenuGroup( { actions, item, setActiveModalAction } ) { +function ActionsDropdownMenuGroup( { actions, items, setActiveModalAction } ) { const registry = useRegistry(); return ( @@ -133,9 +152,9 @@ function ActionsDropdownMenuGroup( { actions, item, setActiveModalAction } ) { setActiveModalAction( action ); return; } - action.callback( [ item ], { registry } ); + action.callback( items, { registry } ); } } - items={ [ item ] } + items={ items } /> ); } ) } diff --git a/packages/editor/src/components/post-card-panel/index.js b/packages/editor/src/components/post-card-panel/index.js index e347d3c79fc521..7849f014ab49c8 100644 --- a/packages/editor/src/components/post-card-panel/index.js +++ b/packages/editor/src/components/post-card-panel/index.js @@ -4,11 +4,13 @@ import { Icon, __experimentalHStack as HStack, + __experimentalVStack as VStack, __experimentalText as Text, } from '@wordpress/components'; import { store as coreStore } from '@wordpress/core-data'; import { useSelect } from '@wordpress/data'; -import { __ } from '@wordpress/i18n'; +import { useMemo } from '@wordpress/element'; +import { __, sprintf } from '@wordpress/i18n'; import { decodeEntities } from '@wordpress/html-entities'; /** @@ -24,50 +26,77 @@ import PostActions from '../post-actions'; import usePageTypeBadge from '../../utils/pageTypeBadge'; import { getTemplateInfo } from '../../utils/get-template-info'; +/** + * Renders a title of the post type and the available quick actions available within a 3-dot dropdown. + * + * @param {Object} props - Component props. + * @param {string} [props.postType] - The post type string. + * @param {string|string[]} [props.postId] - The post id or list of post ids. + * @param {Function} [props.onActionPerformed] - A callback function for when a quick action is performed. + * @return {React.ReactNode} The rendered component. + */ export default function PostCardPanel( { postType, postId, onActionPerformed, } ) { - const { title, icon } = useSelect( + const postIds = useMemo( + () => ( Array.isArray( postId ) ? postId : [ postId ] ), + [ postId ] + ); + const { postTitle, icon, labels } = useSelect( ( select ) => { - const { getEditedEntityRecord } = select( coreStore ); + const { getEditedEntityRecord, getEntityRecord, getPostType } = + select( coreStore ); + const { getPostIcon } = unlock( select( editorStore ) ); + let _title = ''; const _record = getEditedEntityRecord( 'postType', postType, - postId + postIds[ 0 ] ); + if ( postIds.length === 1 ) { + const { default_template_types: templateTypes = [] } = + getEntityRecord( 'root', '__unstableBase' ) ?? {}; - const { default_template_types: templateTypes = [] } = - select( coreStore ).getEntityRecord( - 'root', - '__unstableBase' - ) ?? {}; - - const _templateInfo = [ - TEMPLATE_POST_TYPE, - TEMPLATE_PART_POST_TYPE, - ].includes( postType ) - ? getTemplateInfo( { - template: _record, - templateTypes, - } ) - : {}; + const _templateInfo = [ + TEMPLATE_POST_TYPE, + TEMPLATE_PART_POST_TYPE, + ].includes( postType ) + ? getTemplateInfo( { + template: _record, + templateTypes, + } ) + : {}; + _title = _templateInfo?.title || _record?.title; + } return { - title: _templateInfo?.title || _record?.title, - icon: unlock( select( editorStore ) ).getPostIcon( postType, { + postTitle: _title, + icon: getPostIcon( postType, { area: _record?.area, } ), + labels: getPostType( postType )?.labels, }; }, - [ postId, postType ] + [ postIds, postType ] ); const pageTypeBadge = usePageTypeBadge( postId ); + let title = __( 'No title' ); + if ( labels?.name && postIds.length > 1 ) { + title = sprintf( + // translators: %i number of selected items %s: Name of the plural post type e.g: "Posts". + __( '%i %s' ), + postId.length, + labels?.name + ); + } else if ( postTitle ) { + title = decodeEntities( postTitle ); + } return ( -
+ - { title ? decodeEntities( title ) : __( 'No title' ) } - { pageTypeBadge && ( + { title } + { pageTypeBadge && postIds.length === 1 && ( { pageTypeBadge } @@ -93,6 +122,15 @@ export default function PostCardPanel( { onActionPerformed={ onActionPerformed } /> -
+ { postIds.length > 1 && ( + + { sprintf( + // translators: %s: Name of the plural post type e.g: "Posts". + __( 'Changes will be applied to all selected %s.' ), + labels?.name.toLowerCase() + ) } + + ) } +
); } diff --git a/packages/editor/src/components/post-card-panel/style.scss b/packages/editor/src/components/post-card-panel/style.scss index d9ecfc58304e85..c3638b313a8285 100644 --- a/packages/editor/src/components/post-card-panel/style.scss +++ b/packages/editor/src/components/post-card-panel/style.scss @@ -33,6 +33,10 @@ &.has-description &__header { margin-bottom: $grid-unit-10; } + + .editor-post-card-panel__description { + color: $gray-700; + } } .editor-post-card-panel__title-badge { diff --git a/packages/editor/src/utils/pageTypeBadge.js b/packages/editor/src/utils/pageTypeBadge.js index bc787b12284222..3dc7d4750be739 100644 --- a/packages/editor/src/utils/pageTypeBadge.js +++ b/packages/editor/src/utils/pageTypeBadge.js @@ -8,7 +8,7 @@ import { store as coreStore } from '@wordpress/core-data'; /** * Custom hook to get the page type badge for the current post on edit site view. * - * @param {number} postId postId of the current post being edited. + * @param {number|string} postId postId of the current post being edited. */ export default function usePageTypeBadge( postId ) { const { isFrontPage, isPostsPage } = useSelect( ( select ) => { @@ -20,9 +20,11 @@ export default function usePageTypeBadge( postId ) { ? getEditedEntityRecord( 'root', 'site' ) : undefined; + const _postId = parseInt( postId, 10 ); + return { - isFrontPage: siteSettings?.page_on_front === postId, - isPostsPage: siteSettings?.page_for_posts === postId, + isFrontPage: siteSettings?.page_on_front === _postId, + isPostsPage: siteSettings?.page_for_posts === _postId, }; } );