From 2c06bcf32719183c2a85a231763fdbc41224f6ea Mon Sep 17 00:00:00 2001 From: Shailesh Parmar Date: Wed, 22 Jan 2025 18:53:43 +0530 Subject: [PATCH] Fix: Implement Data Quality Dashboards (Incident Manager + Data Quality) (#19231) * Fix: Implement Data Quality Dashboards (Incident Manager + Data Quality) * added icon for test case status * added filters in the api * added filters for dq * added filter of table/column * added test coverage * address the comments --- .../DataQuality/DataQuality.interface.ts | 5 + .../SummaryPannel/SummaryPanel.component.tsx | 64 +++++++- .../SummaryPannel/SummaryPanel.interface.ts | 1 + .../SummaryPannel/SummaryPanel.test.tsx | 8 + .../TestCases/TestCases.component.tsx | 5 +- .../TestSuiteList/TestSuites.component.tsx | 1 + .../SummaryCard/SummaryCard.component.tsx | 22 ++- .../SummaryCard/SummaryCard.interface.ts | 7 + .../common/SummaryCard/SummaryCard.test.tsx | 27 ++++ .../SummaryCard/summary-card.style.less | 18 +++ .../DataQuality/DataQualityPage.interface.ts | 8 +- .../DataQuality/DataQualityProvider.test.tsx | 80 +++++++++- .../pages/DataQuality/DataQualityProvider.tsx | 71 +++++++- .../src/rest/dataQualityDashboardAPI.test.ts | 151 ++++++++++++------ .../ui/src/rest/dataQualityDashboardAPI.ts | 90 +---------- .../src/utils/DataQuality/DataQualityUtils.ts | 112 ++++++++++++- 16 files changed, 510 insertions(+), 160 deletions(-) diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/DataQuality.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/DataQuality.interface.ts index 9ccff47fccf..bdf77229350 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/DataQuality.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/DataQuality.interface.ts @@ -46,6 +46,11 @@ export type TestCaseSearchParams = { dataQualityDimension?: string; }; +export type DataQualityPageParams = TestCaseSearchParams & { + owner?: string; + tags?: string[]; +}; + export interface IncidentTypeAreaChartWidgetProps { title: string; incidentStatusType: TestCaseResolutionStatusTypes; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/SummaryPannel/SummaryPanel.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/SummaryPannel/SummaryPanel.component.tsx index c8091098a7e..67bcef2682e 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/SummaryPannel/SummaryPanel.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/SummaryPannel/SummaryPanel.component.tsx @@ -11,56 +11,110 @@ * limitations under the License. */ import { Col, Row } from 'antd'; -import React, { FC } from 'react'; +import React, { FC, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; +import { ReactComponent as TestCaseAbortedIcon } from '../../../assets/svg/aborted-status.svg'; +import { ReactComponent as TestCaseIcon } from '../../../assets/svg/all-activity-v2.svg'; +import { ReactComponent as TestCaseFailedIcon } from '../../../assets/svg/failed-status.svg'; +import { ReactComponent as DataAssetsCoverageIcon } from '../../../assets/svg/ic-data-assets-coverage.svg'; +import { ReactComponent as HealthCheckIcon } from '../../../assets/svg/ic-green-heart-border.svg'; +import { ReactComponent as TestCaseSuccessIcon } from '../../../assets/svg/success-colored.svg'; import { SummaryCard } from '../../../components/common/SummaryCard/SummaryCard.component'; +import { PRIMARY_COLOR } from '../../../constants/Color.constants'; import { SummaryPanelProps } from './SummaryPanel.interface'; export const SummaryPanel: FC = ({ testSummary: summary, isLoading = false, + showAdditionalSummary = false, }: SummaryPanelProps) => { const { t } = useTranslation(); + const spanValue = useMemo( + () => (showAdditionalSummary ? 8 : 6), + [showAdditionalSummary] + ); return ( - + + } total={summary?.total ?? 0} value={summary?.total ?? 0} /> - + } total={summary?.total ?? 0} type="success" value={summary?.success ?? 0} /> - + } total={summary?.total ?? 0} type="aborted" value={summary?.aborted ?? 0} /> - + } total={summary?.total ?? 0} type="failed" value={summary?.failed ?? 0} /> + {showAdditionalSummary && ( + <> + + } + total={summary?.totalDQEntities ?? 0} + type="success" + value={summary?.healthy ?? 0} + /> + + + } + total={summary?.totalEntityCount ?? 0} + type="acknowledged" + value={summary?.totalDQEntities ?? 0} + /> + + + )} ); }; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/SummaryPannel/SummaryPanel.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/SummaryPannel/SummaryPanel.interface.ts index 4a1d6d158f6..2c2414e7a8f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/SummaryPannel/SummaryPanel.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/SummaryPannel/SummaryPanel.interface.ts @@ -15,4 +15,5 @@ import { TestSummary } from '../../../generated/tests/testSuite'; export interface SummaryPanelProps { testSummary: TestSummary; isLoading?: boolean; + showAdditionalSummary?: boolean; } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/SummaryPannel/SummaryPanel.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/SummaryPannel/SummaryPanel.test.tsx index 91228de6ded..7ed582ac4b7 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/SummaryPannel/SummaryPanel.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/SummaryPannel/SummaryPanel.test.tsx @@ -55,6 +55,14 @@ describe('SummaryPanel component', () => { expect(summaryCards).toHaveLength(4); }); + it('Show additional summary card if showAdditionalSummary is true', async () => { + render(); + + const summaryCards = await screen.findAllByText('SummaryCard.component'); + + expect(summaryCards).toHaveLength(6); + }); + it('should not call getTestCaseExecutionSummary API, if testSummary data is provided', async () => { const mockGetTestCaseExecutionSummary = getTestCaseExecutionSummary as jest.Mock; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCases/TestCases.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCases/TestCases.component.tsx index ea92c5a0871..460a08e84d7 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCases/TestCases.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCases/TestCases.component.tsx @@ -111,8 +111,8 @@ export const TestCases = () => { return params as TestCaseSearchParams; }, [location.search]); - const { searchValue = '' } = params; + const { searchValue = '' } = params; const [testCase, setTestCase] = useState([]); const [isLoading, setIsLoading] = useState(true); const [selectedFilter, setSelectedFilter] = useState([ @@ -416,7 +416,6 @@ export const TestCases = () => { key: filter, label: startCase(name), value: filter, - onClick: handleMenuClick, })); }, []); @@ -497,6 +496,7 @@ export const TestCases = () => { menu={{ items: filterMenu, selectedKeys: selectedFilter, + onClick: handleMenuClick, }} trigger={['click']}>