diff --git a/openmetadata-ui/src/main/resources/ui/src/components/AddDataQualityTest/AddDataQualityTest.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/AddDataQualityTest/AddDataQualityTest.interface.ts index db6461a43ca..c6d19c94b8c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/AddDataQualityTest/AddDataQualityTest.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/AddDataQualityTest/AddDataQualityTest.interface.ts @@ -70,5 +70,5 @@ export interface EditTestCaseModalProps { visible: boolean; testCase: TestCase; onCancel: () => void; - onUpdate?: () => void; + onUpdate?: (testCase: TestCase) => void; } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/AddDataQualityTest/EditTestCaseModal.tsx b/openmetadata-ui/src/main/resources/ui/src/components/AddDataQualityTest/EditTestCaseModal.tsx index ada5aff1895..98c72fd19b6 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/AddDataQualityTest/EditTestCaseModal.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/AddDataQualityTest/EditTestCaseModal.tsx @@ -112,14 +112,22 @@ const EditTestCaseModal: React.FC = ({ const handleFormSubmit: FormProps['onFinish'] = async (value) => { const { parameterValues, description } = createTestCaseObj(value); - const updatedTestCase = { ...testCase, parameterValues, description }; + const updatedTestCase = { + ...testCase, + parameterValues, + description, + name: value.name, + }; const jsonPatch = compare(testCase, updatedTestCase); if (jsonPatch.length) { try { setIsLoadingOnSave(true); - await updateTestCaseById(testCase.id || '', jsonPatch); - onUpdate && onUpdate(); + const updateRes = await updateTestCaseById( + testCase.id || '', + jsonPatch + ); + onUpdate && onUpdate(updateRes); showSuccessToast( t('server.update-entity-success', { entity: t('label.test-case') }) ); 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 1a89236b68c..70ff9728a3b 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 @@ -19,8 +19,9 @@ import { useTranslation } from 'react-i18next'; import { getTestCaseExecutionSummary } from 'rest/testAPI'; import {} from 'utils/CommonUtils'; import { showErrorToast } from 'utils/ToastUtils'; +import { SummaryPanelProps } from './SummaryPanel.interface'; -export const SummaryPanel = () => { +export const SummaryPanel = ({ testSuiteId }: SummaryPanelProps) => { const { t } = useTranslation(); const [summary, setSummary] = useState(); @@ -29,7 +30,7 @@ export const SummaryPanel = () => { const fetchTestSummary = async () => { setIsLoading(true); try { - const response = await getTestCaseExecutionSummary(); + const response = await getTestCaseExecutionSummary(testSuiteId); setSummary(response); } catch (error) { showErrorToast(error as AxiosError); @@ -40,7 +41,7 @@ export const SummaryPanel = () => { useEffect(() => { fetchTestSummary(); - }, []); + }, [testSuiteId]); return ( diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCases/test-cases.style.less b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/SummaryPannel/SummaryPanel.interface.ts similarity index 51% rename from openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCases/test-cases.style.less rename to openmetadata-ui/src/main/resources/ui/src/components/DataQuality/SummaryPannel/SummaryPanel.interface.ts index 27539a5efb2..83e14e1673b 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCases/test-cases.style.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/SummaryPannel/SummaryPanel.interface.ts @@ -10,31 +10,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -@import url('../../../styles/variables.less'); - -.test-case-table-container { - .resolution { - width: max-content; - &.ack { - background-color: @blue-1; - border: 1px solid @blue-2; - .ant-typography { - color: @blue-2; - } - } - &.new { - background-color: @purple-1; - border: 1px solid @purple-2; - .ant-typography { - color: @purple-2; - } - } - &.resolved { - background-color: @green-4; - border: 1px solid @green-5; - .ant-typography { - color: @green-5; - } - } - } +export interface SummaryPanelProps { + testSuiteId?: string; } diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCaseStatusModal/TestCaseStatusModal.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCaseStatusModal/TestCaseStatusModal.component.tsx index b40b8e5fe98..2b52f836a3f 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCaseStatusModal/TestCaseStatusModal.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestCaseStatusModal/TestCaseStatusModal.component.tsx @@ -22,7 +22,7 @@ import { import { startCase } from 'lodash'; import React, { useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { getCurrentUTCDateTimeStamp } from 'utils/TimeUtils'; +import { getCurrentUTCDateTimeMillis } from 'utils/TimeUtils'; import { TestCaseStatusModalProps } from './TestCaseStatusModal.interface'; export const TestCaseStatusModal = ({ @@ -36,17 +36,12 @@ export const TestCaseStatusModal = ({ const markdownRef = useRef(); const [isLoading, setIsLoading] = useState(false); - const [description, setDescription] = useState( - data?.testCaseFailureComment - ); - const statusType = Form.useWatch('testCaseFailureStatusType', form); const handleFormSubmit = (data: TestCaseFailureStatus) => { const updatedData: TestCaseFailureStatus = { ...data, - testCaseFailureComment: description, - updatedAt: getCurrentUTCDateTimeStamp(), + updatedAt: getCurrentUTCDateTimeMillis(), updatedBy: AppState.getCurrentUserDetails()?.fullyQualifiedName, }; onSubmit(updatedData).finally(() => { @@ -115,15 +110,27 @@ export const TestCaseStatusModal = ({ ))} - + setDescription(value)} + onTextChange={(value) => + form.setFieldValue('testCaseFailureComment', value) + } /> 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 11ccee0bdff..5b65302dcec 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 @@ -33,7 +33,6 @@ import { getListTestCase, ListTestCaseParams } from 'rest/testAPI'; import { showErrorToast } from 'utils/ToastUtils'; import { DataQualitySearchParams } from '../DataQuality.interface'; import { SummaryPanel } from '../SummaryPannel/SummaryPanel.component'; -import './test-cases.style.less'; export const TestCases = () => { const history = useHistory(); @@ -68,6 +67,18 @@ export const TestCases = () => { }); }; + const handleTestCaseUpdate = (data?: TestCase) => { + if (data) { + setTestCase((prev) => { + const updatedTestCase = prev.data.map((test) => + test.id === data.id ? { ...test, ...data } : test + ); + + return { ...prev, data: updatedTestCase }; + }); + } + }; + const fetchTestCases = async (params?: ListTestCaseParams) => { setIsLoading(true); try { @@ -172,6 +183,7 @@ export const TestCases = () => { }} testCases={testCase.data} onTestCaseResultUpdate={handleStatusSubmit} + onTestUpdate={handleTestCaseUpdate} /> diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestSuites/TestSuites.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestSuites/TestSuites.component.tsx index 99571afd93f..f3eb11f81b6 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestSuites/TestSuites.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestSuites/TestSuites.component.tsx @@ -83,20 +83,25 @@ export const TestSuites = () => { dataIndex: 'name', key: 'name', render: (_, record) => { - const path = - tab === DataQualityPageTabs.TABLES - ? { - pathname: getTableTabPath( - record.executableEntityReference?.fullyQualifiedName ?? '', - EntityTabs.PROFILER - ), - search: QueryString.stringify({ - activeTab: TableProfilerTab.DATA_QUALITY, - }), - } - : getTestSuitePath(record.fullyQualifiedName ?? record.name); - - return {getEntityName(record)}; + return record.executable ? ( + + {getEntityName(record.executableEntityReference)} + + ) : ( + + {getEntityName(record)} + + ); }, }, { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/DataQualityTab.style.less b/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/DataQualityTab.style.less index 02864697e60..c8f73efb8dc 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/DataQualityTab.style.less +++ b/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/DataQualityTab.style.less @@ -10,7 +10,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +@import (reference) url('../../../styles/variables.less'); .test-case-summary-table { // Removed padding for expanded rows to prevent unnecessary scrolling behavior for the expanded row content .ant-table.ant-table-small .ant-table-tbody > tr.ant-table-expanded-row > td { @@ -18,3 +18,29 @@ padding-right: 0px; } } +.test-case-table-container { + .resolution { + width: max-content; + &.ack { + background-color: @blue-1; + border: 1px solid @blue-2; + .ant-typography { + color: @blue-2; + } + } + &.new { + background-color: @purple-1; + border: 1px solid @purple-2; + .ant-typography { + color: @purple-2; + } + } + &.resolved { + background-color: @green-4; + border: 1px solid @green-3; + .ant-typography { + color: @green-3; + } + } + } +} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/DataQualityTab.tsx b/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/DataQualityTab.tsx index d4a0425b355..121e5ddd29b 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/DataQualityTab.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/DataQualityTab.tsx @@ -35,6 +35,7 @@ import { ResourceEntity } from 'components/PermissionProvider/PermissionProvider import { TestCaseStatus } from 'generated/configuration/testResultNotificationConfiguration'; import { Operation } from 'generated/entity/policies/policy'; import { isUndefined, sortBy } from 'lodash'; +import QueryString from 'qs'; import { putTestCaseResult, removeTestCaseFromTestSuite } from 'rest/testAPI'; import { checkPermission } from 'utils/PermissionsUtils'; import { showErrorToast } from 'utils/ToastUtils'; @@ -51,11 +52,15 @@ import { getEntityFqnFromEntityLink, getTableExpandableConfig, } from '../../../utils/TableUtils'; -import { getFormattedDateFromSeconds } from '../../../utils/TimeUtils'; +import { + getFormattedDateFromMilliSeconds, + getFormattedDateFromSeconds, +} from '../../../utils/TimeUtils'; import DeleteWidgetModal from '../../common/DeleteWidget/DeleteWidgetModal'; import Loader from '../../Loader/Loader'; import { DataQualityTabProps, + TableProfilerTab, TestCaseAction, } from '../profilerDashboard.interface'; import './DataQualityTab.style.less'; @@ -191,7 +196,12 @@ const DataQualityTab: React.FC = ({ return ( e.stopPropagation()}> {name} @@ -242,12 +252,33 @@ const DataQualityTab: React.FC = ({ width: 100, render: (value: TestCaseResult) => { const label = value?.testCaseFailureStatus?.testCaseFailureStatusType; + const failureStatus = value?.testCaseFailureStatus; return label ? ( - + +
+ +
+
) : ( '--' ); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/profilerDashboard.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/profilerDashboard.interface.ts index 708b616bb72..366ac903d1d 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/profilerDashboard.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/profilerDashboard.interface.ts @@ -100,7 +100,7 @@ export interface ProfilerSummaryCardProps { export interface DataQualityTabProps { testCases: TestCase[]; - onTestUpdate?: () => void; + onTestUpdate?: (testCase?: TestCase) => void; showTableColumn?: boolean; isLoading?: boolean; onTestCaseResultUpdate?: (data: TestCase) => void; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/TableProfiler/QualityTab/QualityTab.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/TableProfiler/QualityTab/QualityTab.component.tsx index 20bd8f8a22d..cfbe77b07bf 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/TableProfiler/QualityTab/QualityTab.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/TableProfiler/QualityTab/QualityTab.component.tsx @@ -57,7 +57,7 @@ export const QualityTab = ({ return ( - + diff --git a/openmetadata-ui/src/main/resources/ui/src/components/TestSuite/AddTestSuiteForm/AddTestSuiteForm.tsx b/openmetadata-ui/src/main/resources/ui/src/components/TestSuite/AddTestSuiteForm/AddTestSuiteForm.tsx index 62fc00696f8..3e8e310fefd 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/TestSuite/AddTestSuiteForm/AddTestSuiteForm.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/TestSuite/AddTestSuiteForm/AddTestSuiteForm.tsx @@ -15,13 +15,14 @@ import { Button, Form, Input, Space } from 'antd'; import RichTextEditor from 'components/common/rich-text-editor/RichTextEditor'; import Loader from 'components/Loader/Loader'; import { ENTITY_NAME_REGEX } from 'constants/regex.constants'; +import { DataQualityPageTabs } from 'pages/DataQuality/DataQualityPage.interface'; import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useHistory } from 'react-router-dom'; import { getListTestSuites } from 'rest/testAPI'; +import { getDataQualityPagePath } from 'utils/RouterUtils'; import { PAGE_SIZE_MEDIUM, - ROUTES, VALIDATION_MESSAGES, } from '../../../constants/constants'; import { TestSuite } from '../../../generated/tests/testSuite'; @@ -52,6 +53,10 @@ const AddTestSuiteForm: React.FC = ({ } }; + const handleCancelClick = () => { + history.push(getDataQualityPagePath(DataQualityPageTabs.TEST_SUITES)); + }; + useEffect(() => { fetchTestSuites(); }, []); @@ -120,9 +125,7 @@ const AddTestSuiteForm: React.FC = ({ -