Skip to content

Commit

Permalink
Refactor the user autocompleter to avoid apiFetch and rely on the dat…
Browse files Browse the repository at this point in the history
…a module (#33028)
  • Loading branch information
youknowriad authored Jul 7, 2021
1 parent 0c9900f commit b9203ca
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 67 deletions.
61 changes: 28 additions & 33 deletions packages/editor/src/components/autocompleters/test/user.js
Original file line number Diff line number Diff line change
@@ -1,54 +1,49 @@
/**
* Internal dependencies
*/
import userCompleter from '../user';
import { getUserLabel } from '../user';

describe( 'user', () => {
describe( 'getOptionLabel', () => {
describe( 'getUserLabel', () => {
it( 'should return user details fragment', () => {
const user = {
name: 'Smithers Jones',
slug: 'userSlug',
avatar_urls: { 24: 'http://my.avatar' },
};
const userLabel = userCompleter.getOptionLabel( user );
expect( userLabel[ 0 ] ).toEqual(
<img
key="avatar"
className="editor-autocompleters__user-avatar"
alt=""
src="http://my.avatar"
/>
);
expect( userLabel[ 1 ] ).toEqual(
<span key="name" className="editor-autocompleters__user-name">
Smithers Jones
</span>
);
expect( userLabel[ 2 ] ).toEqual(
<span key="slug" className="editor-autocompleters__user-slug">
userSlug
</span>
const userLabel = getUserLabel( user );
expect( userLabel ).toEqual(
<>
<img
className="editor-autocompleters__user-avatar"
alt=""
src="http://my.avatar"
/>
<span className="editor-autocompleters__user-name">
Smithers Jones
</span>
<span className="editor-autocompleters__user-slug">
userSlug
</span>
</>
);
} );
it( 'should return user details fragment without default avatar dashicon if avatar_urls array not set', () => {
const user = {
name: 'Smithers Jones',
slug: 'userSlug',
};
const userLabel = userCompleter.getOptionLabel( user );
expect( userLabel[ 0 ] ).toEqual(
<span className="editor-autocompleters__no-avatar"></span>
);
expect( userLabel[ 1 ] ).toEqual(
<span key="name" className="editor-autocompleters__user-name">
Smithers Jones
</span>
);
expect( userLabel[ 2 ] ).toEqual(
<span key="slug" className="editor-autocompleters__user-slug">
userSlug
</span>
const userLabel = getUserLabel( user );
expect( userLabel ).toEqual(
<>
<span className="editor-autocompleters__no-avatar"></span>
<span className="editor-autocompleters__user-name">
Smithers Jones
</span>
<span className="editor-autocompleters__user-slug">
userSlug
</span>
</>
);
} );
} );
Expand Down
89 changes: 55 additions & 34 deletions packages/editor/src/components/autocompleters/user.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,37 @@
/**
* WordPress dependencies
*/
import apiFetch from '@wordpress/api-fetch';
import { useMemo } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';

/** @typedef {import('@wordpress/components').WPCompleter} WPCompleter */

export function getUserLabel( user ) {
const avatar =
user.avatar_urls && user.avatar_urls[ 24 ] ? (
<img
className="editor-autocompleters__user-avatar"
alt=""
src={ user.avatar_urls[ 24 ] }
/>
) : (
<span className="editor-autocompleters__no-avatar"></span>
);

return (
<>
{ avatar }
<span className="editor-autocompleters__user-name">
{ user.name }
</span>
<span className="editor-autocompleters__user-slug">
{ user.slug }
</span>
</>
);
}

/**
* A user mentions completer.
*
Expand All @@ -14,40 +41,34 @@ export default {
name: 'users',
className: 'editor-autocompleters__user',
triggerPrefix: '@',
options( search ) {
let payload = '';
if ( search ) {
payload = '?search=' + encodeURIComponent( search );
}
return apiFetch( { path: '/wp/v2/users' + payload } );
},
isDebounced: true,
getOptionKeywords( user ) {
return [ user.slug, user.name ];
},
getOptionLabel( user ) {
const avatar =
user.avatar_urls && user.avatar_urls[ 24 ] ? (
<img
key="avatar"
className="editor-autocompleters__user-avatar"
alt=""
src={ user.avatar_urls[ 24 ] }
/>
) : (
<span className="editor-autocompleters__no-avatar"></span>
);

return [
avatar,
<span key="name" className="editor-autocompleters__user-name">
{ user.name }
</span>,
<span key="slug" className="editor-autocompleters__user-slug">
{ user.slug }
</span>,
];

useItems( filterValue ) {
const users = useSelect(
( select ) => {
const { getUsers } = select( coreStore );
return getUsers( {
context: 'view',
search: encodeURIComponent( filterValue ),
} );
},
[ filterValue ]
);

const options = useMemo(
() =>
users
? users.map( ( user ) => ( {
key: `user-${ user.slug }`,
value: user,
label: getUserLabel( user ),
} ) )
: [],
[ users ]
);

return [ options ];
},

getOptionCompletion( user ) {
return `@${ user.slug }`;
},
Expand Down

0 comments on commit b9203ca

Please sign in to comment.