-
-
- {filterMenu}
-
+
+
+
+
+
+
+ {filterMenu}
+
-
-
-
- )}
+
+
+
)
}>
- {activeViewTab === LINEAGE_TAB_VIEW.DIAGRAM_VIEW ? (
+ {
)}
- ) : (
-
- )}
+ }
);
};
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Lineage/LineageTable/LineageTable.component.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Lineage/LineageTable/LineageTable.component.test.tsx
deleted file mode 100644
index cd9ea0d8c81..00000000000
--- a/openmetadata-ui/src/main/resources/ui/src/components/Lineage/LineageTable/LineageTable.component.test.tsx
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright 2023 Collate.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { render, screen, waitFor } from '@testing-library/react';
-import { act } from 'react';
-import { readString } from 'react-papaparse';
-import { ExportTypes } from '../../../constants/Export.constants';
-import { LINEAGE_TABLE_COLUMN_LOCALIZATION_KEYS } from '../../../constants/Lineage.constants';
-import { useLineageProvider } from '../../../context/LineageProvider/LineageProvider';
-import { useFqn } from '../../../hooks/useFqn';
-import { getLineageTableConfig } from '../../../utils/EntityLineageUtils';
-import { useEntityExportModalProvider } from '../../Entity/EntityExportModalProvider/EntityExportModalProvider.component';
-import LineageTable from './LineageTable.component';
-
-// Mock the dependencies
-jest.mock('../../../context/LineageProvider/LineageProvider');
-jest.mock('../../../hooks/useFqn');
-jest.mock('../../../utils/EntityLineageUtils');
-jest.mock(
- '../../Entity/EntityExportModalProvider/EntityExportModalProvider.component'
-);
-jest.mock('react-papaparse', () => ({
- readString: jest.fn(),
-}));
-
-const mockUseLineageProvider = useLineageProvider as jest.MockedFunction<
- typeof useLineageProvider
->;
-const mockUseFqn = useFqn as jest.MockedFunction;
-const mockUseEntityExportModalProvider =
- useEntityExportModalProvider as jest.MockedFunction<
- typeof useEntityExportModalProvider
- >;
-const mockGetLineageColumnsAndDataSourceFromCSV =
- getLineageTableConfig as jest.MockedFunction;
-const mockReadString = readString as jest.MockedFunction;
-
-describe('LineageTable Component', () => {
- const mockFqn = 'test.fqn';
- const mockExportLineageData = jest.fn();
- const mockTriggerExportForBulkEdit = jest.fn();
- const mockClearCSVExportData = jest.fn();
-
- const mockTableConfig = {
- columns: [
- {
- title: 'Name',
- dataIndex: 'name',
- key: 'name',
- width: 200,
- ellipsis: { showTitle: false },
- render: jest.fn(),
- },
- {
- title: 'Type',
- dataIndex: 'type',
- key: 'type',
- width: 200,
- ellipsis: { showTitle: false },
- render: jest.fn(),
- },
- ],
- dataSource: [
- { name: 'Test Entity 1', type: 'Table', key: '0' },
- { name: 'Test Entity 2', type: 'Dashboard', key: '1' },
- ],
- };
-
- beforeEach(() => {
- jest.clearAllMocks();
-
- // Setup default mocks
- mockUseFqn.mockReturnValue({ fqn: mockFqn } as any);
- mockUseLineageProvider.mockReturnValue({
- exportLineageData: mockExportLineageData,
- } as any);
- mockUseEntityExportModalProvider.mockReturnValue({
- triggerExportForBulkEdit: mockTriggerExportForBulkEdit,
- csvExportData: undefined,
- clearCSVExportData: mockClearCSVExportData,
- } as any);
- mockGetLineageColumnsAndDataSourceFromCSV.mockReturnValue(mockTableConfig);
- });
-
- it('should render the component', async () => {
- // Mock CSV data to trigger table rendering
- const mockCSVData = 'Name,Type\nTest Entity 1,Table';
- const mockParsedData = {
- data: [
- ['Name', 'Type'],
- ['Test Entity 1', 'Table'],
- ],
- };
-
- mockReadString.mockImplementation((_: string, options: any) => {
- if (options.complete) {
- options.complete(mockParsedData);
- }
- });
-
- mockUseEntityExportModalProvider.mockReturnValue({
- triggerExportForBulkEdit: mockTriggerExportForBulkEdit,
- csvExportData: mockCSVData,
- clearCSVExportData: mockClearCSVExportData,
- } as any);
-
- await act(async () => {
- render();
- });
-
- await waitFor(() => {
- expect(screen.getByTestId('lineage-table')).toBeInTheDocument();
- });
- });
-
- it('should trigger export for bulk edit on mount', () => {
- render();
-
- expect(mockTriggerExportForBulkEdit).toHaveBeenCalledWith({
- name: mockFqn,
- onExport: mockExportLineageData,
- exportTypes: [ExportTypes.CSV],
- hideExportModal: true,
- });
- });
-
- it('should clear CSV export data on unmount', () => {
- const { unmount } = render();
-
- unmount();
-
- expect(mockClearCSVExportData).toHaveBeenCalled();
- });
-
- it('should render table with empty data initially', async () => {
- // Mock empty CSV data to trigger table rendering with empty state
- const mockCSVData = 'Name,Type';
- const mockParsedData = {
- data: [['Name', 'Type']],
- };
-
- mockReadString.mockImplementation((_: string, options: any) => {
- if (options.complete) {
- options.complete(mockParsedData);
- }
- });
-
- mockUseEntityExportModalProvider.mockReturnValue({
- triggerExportForBulkEdit: mockTriggerExportForBulkEdit,
- csvExportData: mockCSVData,
- clearCSVExportData: mockClearCSVExportData,
- } as any);
-
- render();
-
- await waitFor(() => {
- expect(screen.getByTestId('lineage-table')).toBeInTheDocument();
- });
- });
-
- it('should handle CSV data processing when csvExportData is available', async () => {
- const mockCSVData =
- 'Name,Type\nTest Entity 1,Table\nTest Entity 2,Dashboard';
- const mockParsedData = {
- data: [
- ['Name', 'Type'],
- ['Test Entity 1', 'Table'],
- ['Test Entity 2', 'Dashboard'],
- ],
- };
-
- mockReadString.mockImplementation((_: string, options: any) => {
- if (options.complete) {
- options.complete(mockParsedData);
- }
- });
-
- mockUseEntityExportModalProvider.mockReturnValue({
- triggerExportForBulkEdit: mockTriggerExportForBulkEdit,
- csvExportData: mockCSVData,
- clearCSVExportData: mockClearCSVExportData,
- } as any);
-
- render();
-
- await waitFor(() => {
- expect(mockReadString).toHaveBeenCalledWith(mockCSVData, {
- worker: true,
- skipEmptyLines: true,
- complete: expect.any(Function),
- });
- });
-
- expect(mockGetLineageColumnsAndDataSourceFromCSV).toHaveBeenCalledWith(
- mockParsedData.data
- );
- });
-
- it('should not process CSV data when csvExportData is not available', () => {
- render();
-
- expect(mockReadString).not.toHaveBeenCalled();
- });
-
- it('should update table config when CSV data is processed', async () => {
- const mockCSVData = 'Name,Type\nTest Entity 1,Table';
- const mockParsedData = {
- data: [
- ['Name', 'Type'],
- ['Test Entity 1', 'Table'],
- ],
- };
-
- mockReadString.mockImplementation((_: string, options: any) => {
- if (options.complete) {
- options.complete(mockParsedData);
- }
- });
-
- mockUseEntityExportModalProvider.mockReturnValue({
- triggerExportForBulkEdit: mockTriggerExportForBulkEdit,
- csvExportData: mockCSVData,
- clearCSVExportData: mockClearCSVExportData,
- } as any);
-
- render();
-
- await waitFor(() => {
- expect(mockGetLineageColumnsAndDataSourceFromCSV).toHaveBeenCalledWith(
- mockParsedData.data
- );
- });
- });
-
- it('should handle multiple CSV data updates', async () => {
- const mockCSVData1 = 'Name,Type\nTest Entity 1,Table';
- const mockCSVData2 = 'Name,Type\nTest Entity 2,Dashboard';
- const mockParsedData1 = {
- data: [
- ['Name', 'Type'],
- ['Test Entity 1', 'Table'],
- ],
- };
- const mockParsedData2 = {
- data: [
- ['Name', 'Type'],
- ['Test Entity 2', 'Dashboard'],
- ],
- };
-
- mockReadString.mockImplementation((data: string, options: any) => {
- if (data === mockCSVData1 && options.complete) {
- options.complete(mockParsedData1);
- } else if (data === mockCSVData2 && options.complete) {
- options.complete(mockParsedData2);
- }
- });
-
- const { rerender } = render();
-
- mockUseEntityExportModalProvider.mockReturnValue({
- triggerExportForBulkEdit: mockTriggerExportForBulkEdit,
- csvExportData: mockCSVData1,
- clearCSVExportData: mockClearCSVExportData,
- } as any);
-
- rerender();
-
- await waitFor(() => {
- expect(mockGetLineageColumnsAndDataSourceFromCSV).toHaveBeenCalledWith(
- mockParsedData1.data
- );
- });
-
- mockUseEntityExportModalProvider.mockReturnValue({
- triggerExportForBulkEdit: mockTriggerExportForBulkEdit,
- csvExportData: mockCSVData2,
- clearCSVExportData: mockClearCSVExportData,
- } as any);
-
- rerender();
-
- await waitFor(() => {
- expect(mockGetLineageColumnsAndDataSourceFromCSV).toHaveBeenCalledWith(
- mockParsedData2.data
- );
- });
- });
-});
-
-describe('LINEAGE_TABLE_COLUMN_LOCALIZATION_KEYS', () => {
- it('should contain all required column keys', () => {
- const expectedKeys = [
- 'fromEntityFQN',
- 'fromServiceName',
- 'fromServiceType',
- 'fromOwners',
- 'fromDomain',
- 'toEntityFQN',
- 'toServiceName',
- 'toServiceType',
- 'toOwners',
- 'toDomain',
- 'fromChildEntityFQN',
- 'toChildEntityFQN',
- 'pipelineName',
- 'pipelineDisplayName',
- 'pipelineType',
- 'pipelineDescription',
- 'pipelineOwners',
- 'pipelineDomain',
- 'pipelineServiceName',
- 'pipelineServiceType',
- ];
-
- expectedKeys.forEach((key) => {
- expect(LINEAGE_TABLE_COLUMN_LOCALIZATION_KEYS).toHaveProperty(key);
- expect(LINEAGE_TABLE_COLUMN_LOCALIZATION_KEYS[key]).toMatch(/^label\./);
- });
- });
-
- it('should have proper localization key format', () => {
- Object.values(LINEAGE_TABLE_COLUMN_LOCALIZATION_KEYS).forEach((value) => {
- expect(value).toMatch(/^label\.[a-z-]+$/);
- });
- });
-});
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Lineage/LineageTable/LineageTable.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Lineage/LineageTable/LineageTable.component.tsx
deleted file mode 100644
index 007dc6f9fcf..00000000000
--- a/openmetadata-ui/src/main/resources/ui/src/components/Lineage/LineageTable/LineageTable.component.tsx
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2025 Collate.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { ColumnsType } from 'antd/lib/table';
-import { isEmpty } from 'lodash';
-import { useCallback, useEffect, useState } from 'react';
-import { readString } from 'react-papaparse';
-import { ExportTypes } from '../../../constants/Export.constants';
-import { TABLE_SCROLL_VALUE } from '../../../constants/Table.constants';
-import { useLineageProvider } from '../../../context/LineageProvider/LineageProvider';
-import { useFqn } from '../../../hooks/useFqn';
-import { getLineageTableConfig } from '../../../utils/EntityLineageUtils';
-import ErrorPlaceHolder from '../../common/ErrorWithPlaceholder/ErrorPlaceHolder';
-import Loader from '../../common/Loader/Loader';
-import Table from '../../common/Table/Table';
-import { useEntityExportModalProvider } from '../../Entity/EntityExportModalProvider/EntityExportModalProvider.component';
-import './lineage-table.less';
-
-const LineageTable = () => {
- const { fqn } = useFqn();
- const { exportLineageData } = useLineageProvider();
- const { triggerExportForBulkEdit, csvExportData, clearCSVExportData } =
- useEntityExportModalProvider();
- const [tableConfig, setTableConfig] = useState<{
- isLoading: boolean;
- columns: ColumnsType;
- dataSource: Record[];
- }>({
- isLoading: true,
- columns: [],
- dataSource: [],
- });
-
- const onCSVReadComplete = useCallback((results: { data: string[][] }) => {
- const { columns, dataSource } = getLineageTableConfig(
- results.data as string[][]
- );
-
- setTableConfig({
- isLoading: false,
- columns,
- dataSource,
- });
- }, []);
-
- useEffect(() => {
- setTableConfig({
- isLoading: true,
- columns: [],
- dataSource: [],
- });
-
- triggerExportForBulkEdit({
- name: fqn,
- onExport: exportLineageData,
- exportTypes: [ExportTypes.CSV],
- hideExportModal: true,
- });
- }, []);
-
- useEffect(() => {
- if (csvExportData) {
- readString(csvExportData, {
- worker: true,
- skipEmptyLines: true,
- complete: onCSVReadComplete,
- });
- }
- }, [csvExportData]);
-
- useEffect(() => {
- // clear the csvExportData data from the state
- return () => {
- clearCSVExportData();
- };
- }, []);
-
- if (tableConfig.isLoading) {
- return ;
- }
-
- if (isEmpty(tableConfig.columns)) {
- return ;
- }
-
- return (
-
- );
-};
-
-export default LineageTable;
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Lineage/LineageTable/lineage-table.less b/openmetadata-ui/src/main/resources/ui/src/components/Lineage/LineageTable/lineage-table.less
deleted file mode 100644
index 5e693c772a8..00000000000
--- a/openmetadata-ui/src/main/resources/ui/src/components/Lineage/LineageTable/lineage-table.less
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright 2025 Collate.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-.header-icon {
- width: 20px;
- height: 20px;
-}
diff --git a/openmetadata-ui/src/main/resources/ui/src/components/LineageTable/LineageTable.tsx b/openmetadata-ui/src/main/resources/ui/src/components/LineageTable/LineageTable.tsx
index ccd30a04cac..7350b2a2560 100644
--- a/openmetadata-ui/src/main/resources/ui/src/components/LineageTable/LineageTable.tsx
+++ b/openmetadata-ui/src/main/resources/ui/src/components/LineageTable/LineageTable.tsx
@@ -11,7 +11,6 @@
* limitations under the License.
*/
import { SettingOutlined } from '@ant-design/icons';
-import { ListItemIcon, ListItemText } from '@mui/material';
import Button from '@mui/material/Button';
import Chip from '@mui/material/Chip';
import MenuItem from '@mui/material/MenuItem';
@@ -384,8 +383,8 @@ const LineageTable = () => {
handlePageChange(currentPage);
setImpactOnEl(null);
}}>
- {option.icon}
- {option.label}
+ {option.icon}
+ {option.label}
))}
@@ -555,6 +554,7 @@ const LineageTable = () => {
}
sx={{
+ fontWeight: 500,
'& .MuiButton-endIcon': {
svg: {
height: 12,
@@ -604,8 +604,11 @@ const LineageTable = () => {
/>