mirror of
https://github.com/datahub-project/datahub.git
synced 2025-11-03 04:10:43 +00:00
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:
parent
a14617b6a4
commit
efc6ac3753
@ -35,7 +35,7 @@ describe('filterSchemaRows', () => {
|
|||||||
expect(expandedRowsFromFilter).toMatchObject(new Set());
|
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 = {
|
const editableSchemaMetadata = {
|
||||||
editableSchemaFieldInfo: [
|
editableSchemaFieldInfo: [
|
||||||
{ fieldPath: 'customer', globalTags: { tags: [{ tag: sampleTag }] }, glossaryTerms: null },
|
{ fieldPath: 'customer', globalTags: { tags: [{ tag: sampleTag }] }, glossaryTerms: null },
|
||||||
@ -53,7 +53,7 @@ describe('filterSchemaRows', () => {
|
|||||||
expect(expandedRowsFromFilter).toMatchObject(new Set());
|
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 = {
|
const editableSchemaMetadata = {
|
||||||
editableSchemaFieldInfo: [
|
editableSchemaFieldInfo: [
|
||||||
{ fieldPath: 'shipment', globalTags: null, glossaryTerms: { terms: [{ term: glossaryTerm1 }] } },
|
{ fieldPath: 'shipment', globalTags: null, glossaryTerms: { terms: [{ term: glossaryTerm1 }] } },
|
||||||
@ -119,4 +119,42 @@ describe('filterSchemaRows', () => {
|
|||||||
]);
|
]);
|
||||||
expect(expandedRowsFromFilter).toMatchObject(new Set(['customer', 'customer.child1']));
|
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());
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,37 +1,35 @@
|
|||||||
import { EntityType, SchemaField } from '../../../../../../../types.generated';
|
import { EntityType, SchemaField } from '../../../../../../../types.generated';
|
||||||
import EntityRegistry from '../../../../../EntityRegistry';
|
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
|
// returns list of fieldPaths for fields that have Terms or Tags matching the filterText
|
||||||
function getFilteredFieldPathsByMetadata(editableSchemaMetadata: any, entityRegistry, filterText) {
|
function getFilteredFieldPathsByMetadata(editableSchemaMetadata: any, entityRegistry, filterText) {
|
||||||
return (
|
return (
|
||||||
editableSchemaMetadata?.editableSchemaFieldInfo
|
editableSchemaMetadata?.editableSchemaFieldInfo
|
||||||
.filter((fieldInfo) => {
|
.filter((fieldInfo) => matchesTagsOrTerms(fieldInfo, filterText, entityRegistry))
|
||||||
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),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.map((fieldInfo) => fieldInfo.fieldPath) || []
|
.map((fieldInfo) => fieldInfo.fieldPath) || []
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function shouldInclude(
|
function matchesEditableTagsOrTerms(field: SchemaField, filteredFieldPathsByEditableMetadata: any) {
|
||||||
fieldName: string,
|
return filteredFieldPathsByEditableMetadata.includes(field.fieldPath);
|
||||||
fullFieldPath: string,
|
}
|
||||||
filterText: string,
|
|
||||||
filteredFieldPathsByMetadata: any,
|
function matchesFieldName(fieldName: string, filterText: string) {
|
||||||
) {
|
return fieldName.toLocaleLowerCase().includes(filterText);
|
||||||
return fieldName.toLocaleLowerCase().includes(filterText) || filteredFieldPathsByMetadata.includes(fullFieldPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function filterSchemaRows(
|
export function filterSchemaRows(
|
||||||
@ -44,7 +42,7 @@ export function filterSchemaRows(
|
|||||||
if (!filterText) return { filteredRows: rows, expandedRowsFromFilter: new Set() };
|
if (!filterText) return { filteredRows: rows, expandedRowsFromFilter: new Set() };
|
||||||
const formattedFilterText = filterText.toLocaleLowerCase();
|
const formattedFilterText = filterText.toLocaleLowerCase();
|
||||||
|
|
||||||
const filteredFieldPathsByMetadata = getFilteredFieldPathsByMetadata(
|
const filteredFieldPathsByEditableMetadata = getFilteredFieldPathsByMetadata(
|
||||||
editableSchemaMetadata,
|
editableSchemaMetadata,
|
||||||
entityRegistry,
|
entityRegistry,
|
||||||
formattedFilterText,
|
formattedFilterText,
|
||||||
@ -53,12 +51,20 @@ export function filterSchemaRows(
|
|||||||
const expandedRowsFromFilter = new Set();
|
const expandedRowsFromFilter = new Set();
|
||||||
|
|
||||||
rows.forEach((row) => {
|
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);
|
finalFieldPaths.add(row.fieldPath);
|
||||||
}
|
}
|
||||||
const splitFieldPath = row.fieldPath.split('.');
|
const splitFieldPath = row.fieldPath.split('.');
|
||||||
const fieldName = splitFieldPath.slice(-1)[0];
|
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
|
// if we match specifically on this field (not just its parent), add and expand all parents
|
||||||
splitFieldPath.reduce((previous, current) => {
|
splitFieldPath.reduce((previous, current) => {
|
||||||
finalFieldPaths.add(previous);
|
finalFieldPaths.add(previous);
|
||||||
|
|||||||
@ -210,7 +210,13 @@ export default function TagTermGroup({
|
|||||||
>
|
>
|
||||||
<Tag closable={false} style={{ cursor: 'pointer' }}>
|
<Tag closable={false} style={{ cursor: 'pointer' }}>
|
||||||
<BookOutlined style={{ marginRight: '3%' }} />
|
<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>
|
</Tag>
|
||||||
</TermLink>
|
</TermLink>
|
||||||
</HoverEntityTooltip>
|
</HoverEntityTooltip>
|
||||||
@ -231,7 +237,11 @@ export default function TagTermGroup({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<BookOutlined style={{ marginRight: '3%' }} />
|
<BookOutlined style={{ marginRight: '3%' }} />
|
||||||
<Highlight matchStyle={highlightMatchStyle} search={highlightText}>
|
<Highlight
|
||||||
|
style={{ marginLeft: 0 }}
|
||||||
|
matchStyle={highlightMatchStyle}
|
||||||
|
search={highlightText}
|
||||||
|
>
|
||||||
{entityRegistry.getDisplayName(EntityType.GlossaryTerm, term.term)}
|
{entityRegistry.getDisplayName(EntityType.GlossaryTerm, term.term)}
|
||||||
</Highlight>
|
</Highlight>
|
||||||
</Tag>
|
</Tag>
|
||||||
@ -258,7 +268,11 @@ export default function TagTermGroup({
|
|||||||
$color={tag?.tag?.properties?.colorHex}
|
$color={tag?.tag?.properties?.colorHex}
|
||||||
closable={false}
|
closable={false}
|
||||||
>
|
>
|
||||||
<Highlight matchStyle={highlightMatchStyle} search={highlightText}>
|
<Highlight
|
||||||
|
style={{ marginLeft: 0 }}
|
||||||
|
matchStyle={highlightMatchStyle}
|
||||||
|
search={highlightText}
|
||||||
|
>
|
||||||
{displayName}
|
{displayName}
|
||||||
</Highlight>
|
</Highlight>
|
||||||
</StyledTag>
|
</StyledTag>
|
||||||
@ -286,7 +300,11 @@ export default function TagTermGroup({
|
|||||||
removeTag(tag);
|
removeTag(tag);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Highlight matchStyle={highlightMatchStyle} search={highlightText}>
|
<Highlight
|
||||||
|
style={{ marginLeft: 0 }}
|
||||||
|
matchStyle={highlightMatchStyle}
|
||||||
|
search={highlightText}
|
||||||
|
>
|
||||||
{displayName}
|
{displayName}
|
||||||
</Highlight>
|
</Highlight>
|
||||||
</StyledTag>
|
</StyledTag>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user