fix(ui) Filter search through schemas based on non-editable tags and terms as well (#5942)

* filter based on non-editable tags and terms as well

* update function name for consistency

Co-authored-by: Chris Collins <chriscollins@Chriss-MBP-2.lan>
Co-authored-by: Chris Collins <chriscollins@Chriss-MBP-2-18.lan>
This commit is contained in:
Chris Collins 2022-09-16 17:57:17 -04:00 committed by GitHub
parent a14617b6a4
commit efc6ac3753
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 32 deletions

View File

@ -35,7 +35,7 @@ describe('filterSchemaRows', () => {
expect(expandedRowsFromFilter).toMatchObject(new Set());
});
it('should properly filter schema rows based on tags', () => {
it('should properly filter schema rows based on editable tags', () => {
const editableSchemaMetadata = {
editableSchemaFieldInfo: [
{ fieldPath: 'customer', globalTags: { tags: [{ tag: sampleTag }] }, glossaryTerms: null },
@ -53,7 +53,7 @@ describe('filterSchemaRows', () => {
expect(expandedRowsFromFilter).toMatchObject(new Set());
});
it('should properly filter schema rows based on glossary terms', () => {
it('should properly filter schema rows based on editable glossary terms', () => {
const editableSchemaMetadata = {
editableSchemaFieldInfo: [
{ fieldPath: 'shipment', globalTags: null, glossaryTerms: { terms: [{ term: glossaryTerm1 }] } },
@ -119,4 +119,42 @@ describe('filterSchemaRows', () => {
]);
expect(expandedRowsFromFilter).toMatchObject(new Set(['customer', 'customer.child1']));
});
it('should properly filter schema rows based on non-editable tags', () => {
const rowsWithTags = [
{ fieldPath: 'customer' },
{ fieldPath: 'testing', globalTags: { tags: [{ tag: sampleTag }] } },
{ fieldPath: 'shipment' },
] as SchemaField[];
const editableSchemaMetadata = { editableSchemaFieldInfo: [] };
const filterText = sampleTag.properties.name;
const { filteredRows, expandedRowsFromFilter } = filterSchemaRows(
rowsWithTags,
editableSchemaMetadata,
filterText,
testEntityRegistry,
);
expect(filteredRows).toMatchObject([{ fieldPath: 'testing' }]);
expect(expandedRowsFromFilter).toMatchObject(new Set());
});
it('should properly filter schema rows based on non-editable glossary terms', () => {
const rowsWithTerms = [
{ fieldPath: 'customer' },
{ fieldPath: 'testing' },
{ fieldPath: 'shipment', glossaryTerms: { terms: [{ term: glossaryTerm1 }] } },
] as SchemaField[];
const editableSchemaMetadata = { editableSchemaFieldInfo: [] };
const filterText = glossaryTerm1.properties?.name as string;
const { filteredRows, expandedRowsFromFilter } = filterSchemaRows(
rowsWithTerms,
editableSchemaMetadata,
filterText,
testEntityRegistry,
);
expect(filteredRows).toMatchObject([{ fieldPath: 'shipment' }]);
expect(expandedRowsFromFilter).toMatchObject(new Set());
});
});

View File

@ -1,37 +1,35 @@
import { EntityType, SchemaField } from '../../../../../../../types.generated';
import EntityRegistry from '../../../../../EntityRegistry';
function matchesTagsOrTerms(field: SchemaField, filterText: string, entityRegistry: EntityRegistry) {
return (
field.globalTags?.tags?.find((tagAssociation) =>
entityRegistry.getDisplayName(EntityType.Tag, tagAssociation.tag).toLocaleLowerCase().includes(filterText),
) ||
field.glossaryTerms?.terms?.find((termAssociation) =>
entityRegistry
.getDisplayName(EntityType.GlossaryTerm, termAssociation.term)
.toLocaleLowerCase()
.includes(filterText),
)
);
}
// returns list of fieldPaths for fields that have Terms or Tags matching the filterText
function getFilteredFieldPathsByMetadata(editableSchemaMetadata: any, entityRegistry, filterText) {
return (
editableSchemaMetadata?.editableSchemaFieldInfo
.filter((fieldInfo) => {
return (
fieldInfo.globalTags?.tags.find((tagAssociation) =>
entityRegistry
.getDisplayName(EntityType.Tag, tagAssociation.tag)
.toLocaleLowerCase()
.includes(filterText),
) ||
fieldInfo.glossaryTerms?.terms.find((termAssociation) =>
entityRegistry
.getDisplayName(EntityType.GlossaryTerm, termAssociation.term)
.toLocaleLowerCase()
.includes(filterText),
)
);
})
.filter((fieldInfo) => matchesTagsOrTerms(fieldInfo, filterText, entityRegistry))
.map((fieldInfo) => fieldInfo.fieldPath) || []
);
}
function shouldInclude(
fieldName: string,
fullFieldPath: string,
filterText: string,
filteredFieldPathsByMetadata: any,
) {
return fieldName.toLocaleLowerCase().includes(filterText) || filteredFieldPathsByMetadata.includes(fullFieldPath);
function matchesEditableTagsOrTerms(field: SchemaField, filteredFieldPathsByEditableMetadata: any) {
return filteredFieldPathsByEditableMetadata.includes(field.fieldPath);
}
function matchesFieldName(fieldName: string, filterText: string) {
return fieldName.toLocaleLowerCase().includes(filterText);
}
export function filterSchemaRows(
@ -44,7 +42,7 @@ export function filterSchemaRows(
if (!filterText) return { filteredRows: rows, expandedRowsFromFilter: new Set() };
const formattedFilterText = filterText.toLocaleLowerCase();
const filteredFieldPathsByMetadata = getFilteredFieldPathsByMetadata(
const filteredFieldPathsByEditableMetadata = getFilteredFieldPathsByMetadata(
editableSchemaMetadata,
entityRegistry,
formattedFilterText,
@ -53,12 +51,20 @@ export function filterSchemaRows(
const expandedRowsFromFilter = new Set();
rows.forEach((row) => {
if (shouldInclude(row.fieldPath, row.fieldPath, formattedFilterText, filteredFieldPathsByMetadata)) {
if (
matchesFieldName(row.fieldPath, formattedFilterText) ||
matchesEditableTagsOrTerms(row, filteredFieldPathsByEditableMetadata) ||
matchesTagsOrTerms(row, formattedFilterText, entityRegistry) // non-editable tags and terms
) {
finalFieldPaths.add(row.fieldPath);
}
const splitFieldPath = row.fieldPath.split('.');
const fieldName = splitFieldPath.slice(-1)[0];
if (shouldInclude(fieldName, row.fieldPath, formattedFilterText, filteredFieldPathsByMetadata)) {
if (
matchesFieldName(fieldName, formattedFilterText) ||
matchesEditableTagsOrTerms(row, filteredFieldPathsByEditableMetadata) ||
matchesTagsOrTerms(row, formattedFilterText, entityRegistry)
) {
// if we match specifically on this field (not just its parent), add and expand all parents
splitFieldPath.reduce((previous, current) => {
finalFieldPaths.add(previous);

View File

@ -210,7 +210,13 @@ export default function TagTermGroup({
>
<Tag closable={false} style={{ cursor: 'pointer' }}>
<BookOutlined style={{ marginRight: '3%' }} />
{entityRegistry.getDisplayName(EntityType.GlossaryTerm, term.term)}
<Highlight
style={{ marginLeft: 0 }}
matchStyle={highlightMatchStyle}
search={highlightText}
>
{entityRegistry.getDisplayName(EntityType.GlossaryTerm, term.term)}
</Highlight>
</Tag>
</TermLink>
</HoverEntityTooltip>
@ -231,7 +237,11 @@ export default function TagTermGroup({
}}
>
<BookOutlined style={{ marginRight: '3%' }} />
<Highlight matchStyle={highlightMatchStyle} search={highlightText}>
<Highlight
style={{ marginLeft: 0 }}
matchStyle={highlightMatchStyle}
search={highlightText}
>
{entityRegistry.getDisplayName(EntityType.GlossaryTerm, term.term)}
</Highlight>
</Tag>
@ -258,7 +268,11 @@ export default function TagTermGroup({
$color={tag?.tag?.properties?.colorHex}
closable={false}
>
<Highlight matchStyle={highlightMatchStyle} search={highlightText}>
<Highlight
style={{ marginLeft: 0 }}
matchStyle={highlightMatchStyle}
search={highlightText}
>
{displayName}
</Highlight>
</StyledTag>
@ -286,7 +300,11 @@ export default function TagTermGroup({
removeTag(tag);
}}
>
<Highlight matchStyle={highlightMatchStyle} search={highlightText}>
<Highlight
style={{ marginLeft: 0 }}
matchStyle={highlightMatchStyle}
search={highlightText}
>
{displayName}
</Highlight>
</StyledTag>