Skip to content

Commit

Permalink
Post fields: move author from edit-site to fields package (#66939)
Browse files Browse the repository at this point in the history
Co-authored-by: oandregal <[email protected]>
Co-authored-by: youknowriad <[email protected]>
Co-authored-by: sirreal <[email protected]>
  • Loading branch information
4 people authored Nov 14, 2024
1 parent 7d21c9b commit cd5ead1
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 61 deletions.
2 changes: 2 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

65 changes: 4 additions & 61 deletions packages/edit-site/src/components/post-fields/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
/**
* External dependencies
*/
import clsx from 'clsx';

/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import {
featuredImageField,
slugField,
Expand All @@ -16,50 +10,10 @@ import {
commentStatusField,
titleField,
dateField,
authorField,
} from '@wordpress/fields';
import { useMemo, useState } from '@wordpress/element';
import { commentAuthorAvatar as authorIcon } from '@wordpress/icons';
import { __experimentalHStack as HStack, Icon } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { useEntityRecords, store as coreStore } from '@wordpress/core-data';

function PostAuthorField( { item } ) {
const { text, imageUrl } = useSelect(
( select ) => {
const { getUser } = select( coreStore );
const user = getUser( item.author );
return {
imageUrl: user?.avatar_urls?.[ 48 ],
text: user?.name,
};
},
[ item ]
);
const [ isImageLoaded, setIsImageLoaded ] = useState( false );
return (
<HStack alignment="left" spacing={ 0 }>
{ !! imageUrl && (
<div
className={ clsx( 'page-templates-author-field__avatar', {
'is-loaded': isImageLoaded,
} ) }
>
<img
onLoad={ () => setIsImageLoaded( true ) }
alt={ __( 'Author avatar' ) }
src={ imageUrl }
/>
</div>
) }
{ ! imageUrl && (
<div className="page-templates-author-field__icon">
<Icon icon={ authorIcon } />
</div>
) }
<span className="page-templates-author-field__name">{ text }</span>
</HStack>
);
}
import { useMemo } from '@wordpress/element';
import { useEntityRecords } from '@wordpress/core-data';

function usePostFields() {
const { records: authors, isResolving: isLoadingAuthors } =
Expand All @@ -70,23 +24,12 @@ function usePostFields() {
featuredImageField,
titleField,
{
label: __( 'Author' ),
id: 'author',
type: 'integer',
...authorField,
elements:
authors?.map( ( { id, name } ) => ( {
value: id,
label: name,
} ) ) || [],
render: PostAuthorField,
sort: ( a, b, direction ) => {
const nameA = a._embedded?.author?.[ 0 ]?.name || '';
const nameB = b._embedded?.author?.[ 0 ]?.name || '';

return direction === 'asc'
? nameA.localeCompare( nameB )
: nameB.localeCompare( nameA );
},
},
statusField,
dateField,
Expand Down
4 changes: 4 additions & 0 deletions packages/fields/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ npm install @wordpress/fields --save

<!-- START TOKEN(Autogenerated API docs) -->

### authorField

Author field for BasePost.

### commentStatusField

Comment status field for BasePost.
Expand Down
1 change: 1 addition & 0 deletions packages/fields/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"@wordpress/warning": "*",
"change-case": "4.1.2",
"client-zip": "^2.4.5",
"clsx": "2.1.1",
"remove-accents": "^0.5.0"
},
"peerDependencies": {
Expand Down
63 changes: 63 additions & 0 deletions packages/fields/src/fields/author/author-view.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* External dependencies
*/
import clsx from 'clsx';

/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import { commentAuthorAvatar as authorIcon } from '@wordpress/icons';
import { __experimentalHStack as HStack, Icon } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
import type { User } from '@wordpress/core-data';

/**
* Internal dependencies
*/
import type { BasePostWithEmbeddedAuthor } from '../../types';

function AuthorView( { item }: { item: BasePostWithEmbeddedAuthor } ) {
const { text, imageUrl } = useSelect(
( select ) => {
const { getEntityRecord } = select( coreStore );
let user: User | undefined;
if ( !! item.author ) {
user = getEntityRecord( 'root', 'user', item.author );
}
return {
imageUrl: user?.avatar_urls?.[ 48 ],
text: user?.name,
};
},
[ item ]
);
const [ isImageLoaded, setIsImageLoaded ] = useState( false );
return (
<HStack alignment="left" spacing={ 0 }>
{ !! imageUrl && (
<div
className={ clsx( 'page-templates-author-field__avatar', {
'is-loaded': isImageLoaded,
} ) }
>
<img
onLoad={ () => setIsImageLoaded( true ) }
alt={ __( 'Author avatar' ) }
src={ imageUrl }
/>
</div>
) }
{ ! imageUrl && (
<div className="page-templates-author-field__icon">
<Icon icon={ authorIcon } />
</div>
) }
<span className="page-templates-author-field__name">{ text }</span>
</HStack>
);
}

export default AuthorView;
32 changes: 32 additions & 0 deletions packages/fields/src/fields/author/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* WordPress dependencies
*/
import type { Field } from '@wordpress/dataviews';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import type { BasePostWithEmbeddedAuthor } from '../../types';
import AuthorView from './author-view';

const authorField: Field< BasePostWithEmbeddedAuthor > = {
label: __( 'Author' ),
id: 'author',
type: 'integer',
elements: [],
render: AuthorView,
sort: ( a, b, direction ) => {
const nameA = a._embedded?.author?.[ 0 ]?.name || '';
const nameB = b._embedded?.author?.[ 0 ]?.name || '';

return direction === 'asc'
? nameA.localeCompare( nameB )
: nameB.localeCompare( nameA );
},
};

/**
* Author field for BasePost.
*/
export default authorField;
1 change: 1 addition & 0 deletions packages/fields/src/fields/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export { default as passwordField } from './password';
export { default as statusField } from './status';
export { default as commentStatusField } from './comment-status';
export { default as dateField } from './date';
export { default as authorField } from './author';
14 changes: 14 additions & 0 deletions packages/fields/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ interface Links {
[ key: string ]: { href: string }[] | undefined;
}

interface Author {
name: string;
avatar_urls: Record< string, string >;
}

interface EmbeddedAuthor {
author: Author[];
}

export interface BasePost extends CommonPost {
comment_status?: 'open' | 'closed';
excerpt?: string | { raw: string; rendered: string };
Expand All @@ -39,6 +48,11 @@ export interface BasePost extends CommonPost {
permalink_template?: string;
date?: string;
modified?: string;
author?: number;
}

export interface BasePostWithEmbeddedAuthor extends BasePost {
_embedded: EmbeddedAuthor;
}

export interface Template extends CommonPost {
Expand Down

0 comments on commit cd5ead1

Please sign in to comment.