diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/CustomNode.utils.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/CustomNode.utils.tsx index 9d545e452bb..c39be3bf440 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/CustomNode.utils.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/CustomNode.utils.tsx @@ -137,8 +137,7 @@ export const getColumnContent = (
- -
- {getColumnDataTypeIcon({ - dataType: column.dataType, - width: '14px', - })} -
+ + + {column.dataType && ( +
+ {getColumnDataTypeIcon({ + dataType: column.dataType, + width: '14px', + })} +
+ )} @@ -169,16 +168,18 @@ export const getColumnContent = ( - - {column.constraint} - + {column.constraint && ( + + {column.constraint} + + )} {showDataObservabilitySummary && ( - + ({ + useLineageProvider: jest.fn().mockImplementation(() => mockLineageProvider), +})); + +jest.mock('../../../../rest/testAPI', () => ({ + getTestCaseExecutionSummary: jest.fn(), +})); + +jest.mock('../../../../utils/EntityLink', () => ({ + EntityLink: jest.fn(), +})); + +jest.mock('../../../../utils/SearchClassBase', () => ({ + getEntityIcon: jest.fn().mockReturnValue('entityIcon'), +})); + +jest.mock('../CustomNode.utils', () => ({ + getColumnContent: jest + .fn() + .mockImplementation((column) =>

{column.name}

), +})); + +jest.mock('../TestSuiteSummaryWidget/TestSuiteSummaryWidget.component', () => + jest.fn().mockReturnValue(

TestSuiteSummaryWidget

) +); + +describe('NodeChildren Component', () => { + it('should show show more button when there are columns without lineage', () => { + render(); + + const showMoreButton = screen.getByTestId('show-more-columns-btn'); + + expect(showMoreButton).toBeInTheDocument(); + }); + + it('should hide show more button when all columns are shown after clicking show more button', () => { + render(); + + const showMoreButton = screen.getByTestId('show-more-columns-btn'); + fireEvent.click(showMoreButton); + + expect( + screen.queryByTestId('show-more-columns-btn') + ).not.toBeInTheDocument(); + }); + + it('should hide show more button when all columns are shown', () => { + (useLineageProvider as jest.Mock).mockImplementation(() => ({ + ...mockLineageProvider, + columnsHavingLineage: ['test.fqn.column1', 'test.fqn.column2'], + })); + + render(); + + expect( + screen.queryByTestId('show-more-columns-btn') + ).not.toBeInTheDocument(); + }); + + it('should show all columns when searching', () => { + render(); + + const searchInput = screen.getByPlaceholderText('label.search-entity'); + act(() => { + fireEvent.change(searchInput, { target: { value: 'column' } }); + }); + + expect(screen.getByText('column1')).toBeInTheDocument(); + expect(screen.getByText('column2')).toBeInTheDocument(); + }); + + it('should hide show more button when searching', () => { + render(); + + const searchInput = screen.getByPlaceholderText('label.search-entity'); + fireEvent.change(searchInput, { target: { value: 'column' } }); + + expect( + screen.queryByTestId('show-more-columns-btn') + ).not.toBeInTheDocument(); + }); + + it('should filter columns based on search input', () => { + render(); + + const searchInput = screen.getByPlaceholderText('label.search-entity'); + fireEvent.change(searchInput, { target: { value: 'column1' } }); + + expect(screen.getByText('column1')).toBeInTheDocument(); + expect(screen.queryByText('column2')).not.toBeInTheDocument(); + }); +}); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/NodeChildren/NodeChildren.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/NodeChildren/NodeChildren.component.tsx index 682d1485467..b1c94bd288f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/NodeChildren/NodeChildren.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Entity/EntityLineage/NodeChildren/NodeChildren.component.tsx @@ -115,6 +115,7 @@ const NodeChildren = ({ node, isConnectable }: NodeChildrenProps) => { getEntityName(column).toLowerCase().includes(value.toLowerCase()) ); setFilteredColumns(filtered); + setShowAllColumns(true); } }, [children] @@ -151,7 +152,7 @@ const NodeChildren = ({ node, isConnectable }: NodeChildrenProps) => { try { const response = await getTestCaseExecutionSummary(testSuite.id); setSummary(response); - } catch (error) { + } catch { setSummary(undefined); } finally { setIsLoading(false); @@ -286,7 +287,9 @@ const NodeChildren = ({ node, isConnectable }: NodeChildrenProps) => { // Pre-render column data outside of the return statement const renderedColumns = useMemo(() => { - return filteredColumns.map((column) => renderColumnsData(column as Column)); + return filteredColumns + .map((column) => renderColumnsData(column as Column)) + .filter(Boolean); }, [filteredColumns, renderColumnsData]); // Memoize the expand/collapse icon to prevent unnecessary re-renders @@ -303,6 +306,15 @@ const NodeChildren = ({ node, isConnectable }: NodeChildrenProps) => { return searchClassBase.getEntityIcon(node.entityType ?? ''); }, [node.entityType]); + const shouldShowMoreButton = useMemo(() => { + return ( + !showAllColumns && + !isEmpty(children) && + renderedColumns.length !== children.length && + !searchValue + ); + }, [showAllColumns, children, renderedColumns, searchValue]); + // Memoize the expand/collapse click handler const handleExpandCollapseClick = useCallback((e: React.MouseEvent) => { e.stopPropagation(); @@ -346,18 +358,21 @@ const NodeChildren = ({ node, isConnectable }: NodeChildrenProps) => { />
-
-
- {renderedColumns} -
-
+ {!isEmpty(renderedColumns) && ( +
+
+ {renderedColumns} +
+
+ )} - {!showAllColumns && ( + {shouldShowMoreButton && (