diff --git a/packages/block-library/src/query/edit/query-toolbar.js b/packages/block-library/src/query/edit/query-toolbar.js index 2453c7ca7112d6..7bd16afb99ad0d 100644 --- a/packages/block-library/src/query/edit/query-toolbar.js +++ b/packages/block-library/src/query/edit/query-toolbar.js @@ -15,7 +15,7 @@ import { postList } from '@wordpress/icons'; /** * Internal dependencies */ -import { getTaxonomyInfo } from '../utils'; +import { getTermsInfo } from '../utils'; export default function QueryToolbar( { query, setQuery } ) { const { categories, tags } = useSelect( ( select ) => { @@ -23,10 +23,22 @@ export default function QueryToolbar( { query, setQuery } ) { const _categories = getEntityRecords( 'taxonomy', 'category' ); const _tags = getEntityRecords( 'taxonomy', 'post_tag' ); return { - categories: getTaxonomyInfo( _categories ), - tags: getTaxonomyInfo( _tags ), + categories: getTermsInfo( _categories ), + tags: getTermsInfo( _tags ), }; }, [] ); + + // Handles categories and tags changes. + const onTermsChange = ( terms, queryProperty ) => ( newTermNames ) => { + const termIds = newTermNames.map( + ( name ) => terms.mapByName[ name ]?.id + ); + if ( termIds.includes( undefined ) ) return; + setQuery( { [ queryProperty ]: termIds } ); + }; + const onCategoriesChange = onTermsChange( categories, 'categoryIds' ); + const onTagsChange = onTermsChange( tags, 'tagIds' ); + return ( name - ) } - onChange={ ( newCategoryNames ) => { - const categoryIds = newCategoryNames.map( - ( categoryName ) => - categories.mapByName[ categoryName ] - ?.id - ); - if ( categoryIds.includes( undefined ) ) - return; - setQuery( { categoryIds } ); - } } + suggestions={ categories.names } + onChange={ onCategoriesChange } /> ) } { tags?.terms && ( @@ -101,17 +102,8 @@ export default function QueryToolbar( { query, setQuery } ) { value: tags.mapById[ tagId ].name, } ) ) } - suggestions={ tags.terms.map( - ( { name } ) => name - ) } - onChange={ ( newTagNames ) => { - const tagIds = newTagNames.map( - ( tagName ) => - tags.mapByName[ tagName ]?.id - ); - if ( tagIds.includes( undefined ) ) return; - setQuery( { tagIds } ); - } } + suggestions={ tags.names } + onChange={ onTagsChange } /> ) } diff --git a/packages/block-library/src/query/test/fixtures/index.js b/packages/block-library/src/query/test/fixtures/index.js new file mode 100644 index 00000000000000..c285343bf3db6e --- /dev/null +++ b/packages/block-library/src/query/test/fixtures/index.js @@ -0,0 +1,21 @@ +export const terms = [ + { + count: 2, + id: 4, + meta: [], + name: 'nba', + parent: 0, + slug: 'nba', + taxonomy: 'category', + }, + { + count: 0, + id: 11, + link: 'http://localhost:8888/?tag=featured', + name: 'featured', + slug: 'featured', + taxonomy: 'post_tag', + }, +]; + +export default { terms }; diff --git a/packages/block-library/src/query/test/utils.js b/packages/block-library/src/query/test/utils.js new file mode 100644 index 00000000000000..c7acb4b6110bae --- /dev/null +++ b/packages/block-library/src/query/test/utils.js @@ -0,0 +1,30 @@ +/** + * Internal dependencies + */ +import { terms } from './fixtures'; +import { getTermsInfo } from '../utils'; + +describe( 'Query block utils', () => { + describe( 'getTermsInfo', () => { + it( 'should return an empty object when no terms provided', () => { + expect( getTermsInfo() ).toEqual( { terms: undefined } ); + } ); + it( 'should return proper terms info object', () => { + expect( getTermsInfo( terms ) ).toEqual( + expect.objectContaining( { + mapById: expect.objectContaining( { + '4': expect.objectContaining( { name: 'nba' } ), + '11': expect.objectContaining( { + name: 'featured', + } ), + } ), + mapByName: expect.objectContaining( { + nba: expect.objectContaining( { id: 4 } ), + featured: expect.objectContaining( { id: 11 } ), + } ), + names: expect.arrayContaining( [ 'nba', 'featured' ] ), + } ) + ); + } ); + } ); +} ); diff --git a/packages/block-library/src/query/utils.js b/packages/block-library/src/query/utils.js index a006225196cbc1..d865ecea8ec41c 100644 --- a/packages/block-library/src/query/utils.js +++ b/packages/block-library/src/query/utils.js @@ -1,17 +1,14 @@ // TODO jsdoc and tests -export const getTaxonomyInfo = ( terms ) => ( { +export const getTermsInfo = ( terms ) => ( { terms, ...terms?.reduce( - ( acc, term ) => ( { - mapById: { - ...acc.mapById, - [ term.id ]: term, - }, - mapByName: { - ...acc.mapByName, - [ term.name ]: term, - }, - } ), - { mapById: {}, mapByName: {} } + ( accumulator, term ) => { + const { mapById, mapByName, names } = accumulator; + mapById[ term.id ] = term; + mapByName[ term.name ] = term; + names.push( term.name ); + return accumulator; + }, + { mapById: {}, mapByName: {}, names: [] } ), } );