Skip to content

Commit

Permalink
Update bulk header with actions (WordPress#67743)
Browse files Browse the repository at this point in the history
* Update PostCardPanel for multiple posts

* Fix rename missed during rebase

* Add inline comment

* Stick with single postId prop

Co-authored-by: louwie17 <[email protected]>
Co-authored-by: youknowriad <[email protected]>
  • Loading branch information
3 people authored and yogeshbhutkar committed Dec 18, 2024
1 parent f48f4f5 commit 1ba9c30
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 151 deletions.
88 changes: 0 additions & 88 deletions packages/edit-site/src/components/post-edit/header.js

This file was deleted.

5 changes: 2 additions & 3 deletions packages/edit-site/src/components/post-edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -159,7 +158,7 @@ function PostEditForm( { postType, postId } ) {

return (
<VStack spacing={ 4 }>
<PostEditHeader postType={ postType } postId={ postId } />
<PostCardPanel postType={ postType } postId={ ids } />
<DataForm
data={ ids.length === 1 ? record : multiEdits }
fields={ fieldsWithDependency }
Expand Down
10 changes: 0 additions & 10 deletions packages/edit-site/src/components/post-edit/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,3 @@
padding-top: $grid-unit-20;
}
}

.edit-site-post-edit-header {
.edit-site-post-edit-header__description {
color: $gray-700;
}

.edit-site-post-edit-header__title {
@include heading-medium();
}
}
61 changes: 40 additions & 21 deletions packages/editor/src/components/post-actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,38 +20,57 @@ import { usePostActions } from './actions';

const { Menu, kebabCase } = unlock( componentsPrivateApis );

export default function PostActions( { postType, postId, onActionPerformed } ) {
const [ activeModalAction, setActiveModalAction ] = useState( null );
const { item, permissions } = useSelect(
function useEditedEntityRecordsWithPermissions( postType, postIds ) {
const { items, permissions } = useSelect(
( select ) => {
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 (
<>
Expand All @@ -70,14 +89,14 @@ export default function PostActions( { postType, postId, onActionPerformed } ) {
>
<ActionsDropdownMenuGroup
actions={ actions }
item={ itemWithPermissions }
items={ itemsWithPermissions }
setActiveModalAction={ setActiveModalAction }
/>
</Menu>
{ !! activeModalAction && (
<ActionModal
action={ activeModalAction }
items={ [ item ] }
items={ itemsWithPermissions }
closeModal={ () => setActiveModalAction( null ) }
/>
) }
Expand Down Expand Up @@ -119,7 +138,7 @@ export function ActionModal( { action, items, closeModal } ) {
);
}

function ActionsDropdownMenuGroup( { actions, item, setActiveModalAction } ) {
function ActionsDropdownMenuGroup( { actions, items, setActiveModalAction } ) {
const registry = useRegistry();
return (
<Menu.Group>
Expand All @@ -133,9 +152,9 @@ function ActionsDropdownMenuGroup( { actions, item, setActiveModalAction } ) {
setActiveModalAction( action );
return;
}
action.callback( [ item ], { registry } );
action.callback( items, { registry } );
} }
items={ [ item ] }
items={ items }
/>
);
} ) }
Expand Down
90 changes: 64 additions & 26 deletions packages/editor/src/components/post-card-panel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand All @@ -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 (
<div className="editor-post-card-panel">
<VStack spacing={ 1 } className="editor-post-card-panel">
<HStack
spacing={ 2 }
className="editor-post-card-panel__header"
Expand All @@ -80,8 +109,8 @@ export default function PostCardPanel( {
className="editor-post-card-panel__title"
as="h2"
>
{ title ? decodeEntities( title ) : __( 'No title' ) }
{ pageTypeBadge && (
{ title }
{ pageTypeBadge && postIds.length === 1 && (
<span className="editor-post-card-panel__title-badge">
{ pageTypeBadge }
</span>
Expand All @@ -93,6 +122,15 @@ export default function PostCardPanel( {
onActionPerformed={ onActionPerformed }
/>
</HStack>
</div>
{ postIds.length > 1 && (
<Text className="editor-post-card-panel__description">
{ sprintf(
// translators: %s: Name of the plural post type e.g: "Posts".
__( 'Changes will be applied to all selected %s.' ),
labels?.name.toLowerCase()
) }
</Text>
) }
</VStack>
);
}
4 changes: 4 additions & 0 deletions packages/editor/src/components/post-card-panel/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading

0 comments on commit 1ba9c30

Please sign in to comment.