From 6cc101675f8f8b1cea89b5aed7acbd046e093c8d Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Sat, 15 May 2021 18:56:08 +0300 Subject: [PATCH] [Block Library - Query]: Allow term addition from user case-insensitive input (#31301) * [Block Library - Query]: Allow term addition from user case-insensitive input * fix typo --- .../query/edit/query-inspector-controls.js | 37 ++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/packages/block-library/src/query/edit/query-inspector-controls.js b/packages/block-library/src/query/edit/query-inspector-controls.js index 71e9f38017ee3..dff59bf40868e 100644 --- a/packages/block-library/src/query/edit/query-inspector-controls.js +++ b/packages/block-library/src/query/edit/query-inspector-controls.js @@ -56,6 +56,28 @@ const CreateNewPostLink = ( { type } ) => { ); }; +// Helper function to get the term id based on user input in terms `FormTokenField`. +const getTermIdByTermValue = ( termsMappedByName, termValue ) => { + // First we check for exact match by `term.id` or case sensitive `term.name` match. + const termId = termValue?.id || termsMappedByName[ termValue ]?.id; + if ( termId ) return termId; + /** + * Here we make an extra check for entered terms in a non case sensitive way, + * to match user expectations, due to `FormTokenField` behaviour that shows + * suggestions which are case insensitive. + * + * Although WP tries to discourage users to add terms with the same name (case insensitive), + * it's still possible if you manually change the name, as long as the terms have different slugs. + * In this edge case we always apply the first match from the terms list. + */ + const termValueLower = termValue.toLocaleLowerCase(); + for ( const term in termsMappedByName ) { + if ( term.toLocaleLowerCase() === termValueLower ) { + return termsMappedByName[ term ].id; + } + } +}; + export default function QueryInspectorControls( { attributes: { query, layout }, setQuery, @@ -114,11 +136,16 @@ export default function QueryInspectorControls( { }; // Handles categories and tags changes. const onTermsChange = ( terms, queryProperty ) => ( newTermValues ) => { - const termIds = newTermValues.reduce( ( accumulator, termValue ) => { - const termId = termValue?.id || terms.mapByName[ termValue ]?.id; - if ( termId ) accumulator.push( termId ); - return accumulator; - }, [] ); + const termIds = Array.from( + newTermValues.reduce( ( accumulator, termValue ) => { + const termId = getTermIdByTermValue( + terms.mapByName, + termValue + ); + if ( termId ) accumulator.add( termId ); + return accumulator; + }, new Set() ) + ); setQuery( { [ queryProperty ]: termIds } ); }; const onCategoriesChange = onTermsChange( categories, 'categoryIds' );