diff --git a/.changeset/large-trainers-float.md b/.changeset/large-trainers-float.md new file mode 100644 index 0000000000..b5d1d9be1d --- /dev/null +++ b/.changeset/large-trainers-float.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-react': patch +--- + +Properly handle free-text entity filtering in the case of empty tag arrays diff --git a/plugins/catalog-react/src/filters.ts b/plugins/catalog-react/src/filters.ts index a828015f0e..056b3b92c1 100644 --- a/plugins/catalog-react/src/filters.ts +++ b/plugins/catalog-react/src/filters.ts @@ -84,20 +84,32 @@ export class EntityTextFilter implements EntityFilter { constructor(readonly value: string) {} filterEntity(entity: Entity): boolean { - const upperCaseValue = this.value.toLocaleUpperCase('en-US'); + const words = this.toUpperArray(this.value.split(/\s/)); + const exactMatch = this.toUpperArray([entity.metadata.tags]); + const partialMatch = this.toUpperArray([ + entity.metadata.name, + entity.metadata.title, + ]); - return ( - entity.metadata.name - .toLocaleUpperCase('en-US') - .includes(upperCaseValue) || - `${entity.metadata.title}` - .toLocaleUpperCase('en-US') - .includes(upperCaseValue) || - entity.metadata.tags - ?.join('') - .toLocaleUpperCase('en-US') - .indexOf(upperCaseValue) !== -1 - ); + for (const word of words) { + if ( + exactMatch.every(m => m !== word) && + partialMatch.every(m => !m.includes(word)) + ) { + return false; + } + } + + return true; + } + + private toUpperArray( + value: Array, + ): Array { + return value + .flat() + .filter((m): m is string => Boolean(m)) + .map(m => m.toLocaleUpperCase('en-US')); } }