Skip to content

Instantly share code, notes, and snippets.

@landbryo
Last active February 13, 2023 14:03
Show Gist options
  • Save landbryo/01a9eaea330e030d5904553b15ac0263 to your computer and use it in GitHub Desktop.
Save landbryo/01a9eaea330e030d5904553b15ac0263 to your computer and use it in GitHub Desktop.
Add additional authors UI.
/**
* WordPress dependencies
*/
import { PluginPostStatusInfo } from '@wordpress/edit-post';
import { useEffect, useMemo, useState } from '@wordpress/element';
import { useDispatch, useSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { SelectControl } from '@wordpress/components';
import { decodeEntities } from '@wordpress/html-entities';
import { store as coreStore } from '@wordpress/core-data';
const PostAddAuthor = () => {
const [ inputList, setInputList ] = useState( [] );
const { editPost } = useDispatch( 'core/editor' );
// Get author ids from meta.
let authorIds = useSelect( ( select ) => {
const { getEditedPostAttribute } = select( 'core/editor' );
return getEditedPostAttribute( 'meta' ).forage_authors || [];
}, [] );
// Get array of user objects.
const authors = useSelect( ( select ) => {
const AUTHORS_QUERY = {
who: 'authors',
per_page: 100,
_fields: 'id,name',
context: 'view',
};
const { getUsers } = select( coreStore );
const query = { ...AUTHORS_QUERY };
return getUsers( query );
}, [] );
/**
* Handle author selection.
*
* @param {number} authorId The selected Author.
* @param {number} index The author ID index for the previous value.
*/
const onChangeAuthor = ( authorId, index ) => {
if ( ! authorId ) {
return;
}
const ids = authorIds;
// Make sure the authorId is a number.
authorId = Number( authorId );
// Don't add duplicate authors.
if ( ids.includes( authorId ) ) {
onAddAuthor();
return;
}
ids[ Number( index ) ] = authorId;
editPost( {
meta: {
forage_authors: ids,
forage_authors_updated: Math.floor( Date.now() / 1000 ),
},
} );
authorIds = ids;
};
/**
* Handle removing the additionally added author.
*
* @param {number} authorId The selected Author.
* @param {number} index The author ID index for the previous value.
*/
const removeAuthor = ( authorId, index ) => {
const ids = authorIds.filter(
( item, itemIndex ) => item !== authorId && index !== itemIndex
);
editPost( {
meta: {
forage_authors: ids,
forage_authors_updated: Math.floor( Date.now() / 1000 ),
},
} );
authorIds = ids;
};
/**
* Handle adding another author selector.
*/
const onAddAuthor = () => {
setInputList(
inputList.concat(
<AddAuthor
key={ inputList.length }
index={ inputList.length }
options={ authorOptions }
onChangeAuthor={ onChangeAuthor }
removeAuthor={ removeAuthor }
/>
)
);
};
/**
* Populate author options from fetched authors.
*
* @type {*[]}
*/
const authorOptions = useMemo( () => {
const fetchedAuthors = [
{
value: 0,
label: __( 'Select', 'forage-core' ),
},
];
( authors ?? [] ).forEach( ( author ) => {
if ( author ) {
fetchedAuthors.push( {
value: author.id,
label: decodeEntities( author.name ),
} );
}
} );
return fetchedAuthors;
}, [ authors ] );
/**
* Add existing authors to input list.
*/
useEffect( () => {
const inputs = [];
authorIds.forEach( ( authorId, index ) => {
inputs.push(
<AddAuthor
key={ index }
index={ index }
authorId={ authorId }
options={ authorOptions }
onChangeAuthor={ onChangeAuthor }
removeAuthor={ removeAuthor }
/>
);
} );
setInputList( inputs );
}, [ authors, authorIds ] );
return (
<PluginPostStatusInfo className="forage-additional">
<button className="forage-additional__add" onClick={ onAddAuthor }>
{ __( 'Add Author', 'forage-core' ) } +
</button>
{ inputList }
</PluginPostStatusInfo>
);
};
const AddAuthor = ( {
index,
authorId,
options,
onChangeAuthor,
removeAuthor,
} ) => {
return (
<div className="forage-additional__author">
<SelectControl
label={ __( 'Additional Author', 'forage-core' ) }
options={ options }
value={ authorId }
onChange={ ( newId ) => {
onChangeAuthor( newId, index );
} }
/>
<button
className="clear-button"
onClick={ () => {
removeAuthor( authorId, index );
} }
>
&times;
</button>
</div>
);
};
export default PostAddAuthor;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment