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 98c72fd19b6..799287a5cc8 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 @@ -116,7 +116,7 @@ const EditTestCaseModal: React.FC = ({ ...testCase, parameterValues, description, - name: value.name, + displayName: value.displayName, }; const jsonPatch = compare(testCase, updatedTestCase); @@ -124,10 +124,10 @@ const EditTestCaseModal: React.FC = ({ try { setIsLoadingOnSave(true); const updateRes = await updateTestCaseById( - testCase.id || '', + testCase.id ?? '', jsonPatch ); - onUpdate && onUpdate(updateRes); + onUpdate?.(updateRes); showSuccessToast( t('server.update-entity-success', { entity: t('label.test-case') }) ); @@ -216,17 +216,17 @@ const EditTestCaseModal: React.FC = ({ layout="vertical" name="tableTestForm" onFinish={handleFormSubmit}> - + {isColumn && ( - + )} = ({ ]}> + + + = ({ {GenerateParamsField()} - + = ({ }; const createIngestionPipeline = async (repeatFrequency: string) => { - const updatedName = replaceSpaceWith_(testSuite.name); + const tableName = replaceAllSpacialCharWith_( + getNameFromFQN( + testSuite.executableEntityReference?.fullyQualifiedName ?? '' + ) + ); + const updatedName = getIngestionName(tableName, PipelineType.TestSuite); const ingestionPayload: CreateIngestionPipeline = { airflowConfig: { @@ -121,10 +128,10 @@ const TestSuiteIngestion: React.FC = ({ ? undefined : repeatFrequency, }, - name: `${updatedName}_${PipelineType.TestSuite}`, + name: updatedName, pipelineType: PipelineType.TestSuite, service: { - id: testSuite.id || '', + id: testSuite.id ?? '', type: camelCase(PipelineType.TestSuite), }, sourceConfig: { diff --git a/openmetadata-ui/src/main/resources/ui/src/components/AddDataQualityTest/components/TestCaseForm.tsx b/openmetadata-ui/src/main/resources/ui/src/components/AddDataQualityTest/components/TestCaseForm.tsx index 866be6875c6..c426b35b41a 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/AddDataQualityTest/components/TestCaseForm.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/AddDataQualityTest/components/TestCaseForm.tsx @@ -138,16 +138,18 @@ const TestCaseForm: React.FC = ({ : value, }) ); + const name = + value.testName?.trim() || + `${columnName ? columnName : table.name}_${snakeCase( + selectedTestType + )}_${cryptoRandomString({ + length: 4, + type: 'alphanumeric', + })}`; return { - name: - value.testName?.trim() || - `${columnName ? columnName : table.name}_${snakeCase( - selectedTestType - )}_${cryptoRandomString({ - length: 4, - type: 'alphanumeric', - })}`, + name, + displayName: name, entityLink: generateEntityLink( isColumnFqn ? `${decodedEntityFQN}.${columnName}` : decodedEntityFQN, isColumnFqn diff --git a/openmetadata-ui/src/main/resources/ui/src/components/AddTestCaseModal/AddTestCaseModal.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/AddTestCaseList/AddTestCaseList.component.tsx similarity index 52% rename from openmetadata-ui/src/main/resources/ui/src/components/AddTestCaseModal/AddTestCaseModal.component.tsx rename to openmetadata-ui/src/main/resources/ui/src/components/AddTestCaseList/AddTestCaseList.component.tsx index 4b1edd4ad14..291c2a4a2ca 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/AddTestCaseModal/AddTestCaseModal.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/AddTestCaseList/AddTestCaseList.component.tsx @@ -10,11 +10,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { Checkbox, Col, List, Modal, Row, Space, Typography } from 'antd'; -import { AxiosError } from 'axios'; +import { Button, Checkbox, Col, List, Row, Space, Typography } from 'antd'; import Searchbar from 'components/common/searchbar/Searchbar'; import Loader from 'components/Loader/Loader'; -import { getTableTabPath, PAGE_SIZE_MEDIUM } from 'constants/constants'; +import { getTableTabPath, PAGE_SIZE } from 'constants/constants'; import { SearchIndex } from 'enums/search.enum'; import { TestCase } from 'generated/tests/testCase'; import { @@ -26,13 +25,11 @@ import React, { UIEventHandler, useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Link } from 'react-router-dom'; import { searchQuery } from 'rest/searchAPI'; -import { addTestCaseToLogicalTestSuite } from 'rest/testAPI'; import { getNameFromFQN } from 'utils/CommonUtils'; import { getEntityName } from 'utils/EntityUtils'; import { getDecodedFqn } from 'utils/StringsUtils'; import { getEntityFqnFromEntityLink } from 'utils/TableUtils'; -import { showErrorToast } from 'utils/ToastUtils'; -import { AddTestCaseModalProps } from './AddTestCaseModal.interface'; +import { AddTestCaseModalProps } from './AddTestCaseList.interface'; // Todo: need to help from backend guys for ES query // export const getQueryFilterToExcludeTest = (testCase: EntityReference[]) => ({ @@ -47,12 +44,12 @@ import { AddTestCaseModalProps } from './AddTestCaseModal.interface'; // }, // }); -export const AddTestCaseModal = ({ - open, +export const AddTestCaseList = ({ onCancel, existingTest, - testSuiteId, onSubmit, + cancelText, + submitText, }: AddTestCaseModalProps) => { const { t } = useTranslation(); const [searchTerm, setSearchTerm] = useState(''); @@ -74,7 +71,7 @@ export const AddTestCaseModal = ({ setIsLoading(true); const res = await searchQuery({ pageNumber: page, - pageSize: PAGE_SIZE_MEDIUM, + pageSize: PAGE_SIZE, searchIndex: SearchIndex.TEST_CASE, query: searchText, // queryFilter: getQueryFilterToExcludeTest(existingTest), @@ -100,17 +97,8 @@ export const AddTestCaseModal = ({ const testCaseIds = [...(selectedItems?.values() ?? [])].map( (test) => test.id ?? '' ); - - try { - await addTestCaseToLogicalTestSuite({ testCaseIds, testSuiteId }); - - onSubmit(); - onCancel(); - } catch (error) { - showErrorToast(error as AxiosError); - } finally { - setIsLoading(false); - } + onSubmit(testCaseIds); + setIsLoading(false); }; const onScroll: UIEventHandler = useCallback( @@ -126,7 +114,7 @@ export const AddTestCaseModal = ({ }); } }, - [searchTerm, totalCount, items] + [searchTerm, totalCount, items, isLoading] ); const handleCardClick = (details: TestCase) => { @@ -160,99 +148,92 @@ export const AddTestCaseModal = ({ } }; useEffect(() => { - if (open) { - fetchTestCases({ searchText: searchTerm }); - } - }, [open, searchTerm]); + fetchTestCases({ searchText: searchTerm }); + }, [searchTerm]); return ( - - - - - - - }}> - - {({ _source: test }) => { - const tableFqn = getEntityFqnFromEntityLink(test.entityLink); - const tableName = getNameFromFQN(tableFqn); - const isColumn = test.entityLink.includes('::columns::'); + + + + + + }}> + + {({ _source: test }) => { + const tableFqn = getEntityFqnFromEntityLink(test.entityLink); + const tableName = getNameFromFQN(tableFqn); + const isColumn = test.entityLink.includes('::columns::'); - return ( - handleCardClick(test)}> - - - {getEntityName(test)} - + return ( + handleCardClick(test)}> + + + {getEntityName(test)} + - - - - {getEntityName(test.testDefinition)} - - - e.stopPropagation()}> - {tableName} - - - {isColumn && ( - - {`${t( - 'label.column' - )}:`} - - {getNameFromFQN( - getDecodedFqn( - getEntityFqnFromEntityLink( - test.entityLink, - isColumn - ), - true - ) - ) ?? '--'} - - - )} + - ); - }} - - - - - + + {getEntityName(test.testDefinition)} + + + e.stopPropagation()}> + {tableName} + + + {isColumn && ( + + {`${t( + 'label.column' + )}:`} + + {getNameFromFQN( + getDecodedFqn( + getEntityFqnFromEntityLink( + test.entityLink, + isColumn + ), + true + ) + ) ?? '--'} + + + )} + + ); + }} + + + + + + + + ); }; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/AddTestCaseModal/AddTestCaseModal.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/AddTestCaseList/AddTestCaseList.interface.ts similarity index 82% rename from openmetadata-ui/src/main/resources/ui/src/components/AddTestCaseModal/AddTestCaseModal.interface.ts rename to openmetadata-ui/src/main/resources/ui/src/components/AddTestCaseList/AddTestCaseList.interface.ts index 6684649dbd7..840c76aed1c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/AddTestCaseModal/AddTestCaseModal.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/components/AddTestCaseList/AddTestCaseList.interface.ts @@ -13,9 +13,9 @@ import { EntityReference } from 'generated/tests/testCase'; export interface AddTestCaseModalProps { - open: boolean; - onCancel: () => void; - onSubmit: () => void; - existingTest: EntityReference[]; - testSuiteId: string; + onCancel?: () => void; + onSubmit: (testCaseIds: string[]) => void; + existingTest?: EntityReference[]; + cancelText?: string; + submitText?: string; } 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 70ff9728a3b..19f868b3538 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 @@ -13,6 +13,7 @@ import { Col, Row } from 'antd'; import { AxiosError } from 'axios'; import { SummaryCard } from 'components/common/SummaryCard/SummaryCard.component'; +import { usePermissionProvider } from 'components/PermissionProvider/PermissionProvider'; import { TestSummary } from 'generated/tests/testSuite'; import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; @@ -23,6 +24,8 @@ import { SummaryPanelProps } from './SummaryPanel.interface'; export const SummaryPanel = ({ testSuiteId }: SummaryPanelProps) => { const { t } = useTranslation(); + const { permissions } = usePermissionProvider(); + const { testCase: testCasePermission } = permissions; const [summary, setSummary] = useState(); const [isLoading, setIsLoading] = useState(true); @@ -40,8 +43,10 @@ export const SummaryPanel = ({ testSuiteId }: SummaryPanelProps) => { }; useEffect(() => { - fetchTestSummary(); - }, [testSuiteId]); + if (testCasePermission?.ViewAll || testCasePermission?.ViewBasic) { + fetchTestSummary(); + } + }, [testSuiteId, testCasePermission]); return ( 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 5b65302dcec..3c8a3016338 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 @@ -13,6 +13,7 @@ import { Col, Row } from 'antd'; import { AxiosError } from 'axios'; import Searchbar from 'components/common/searchbar/Searchbar'; +import { usePermissionProvider } from 'components/PermissionProvider/PermissionProvider'; import DataQualityTab from 'components/ProfilerDashboard/component/DataQualityTab'; import { INITIAL_PAGING_VALUE, PAGE_SIZE } from 'constants/constants'; import { SearchIndex } from 'enums/search.enum'; @@ -29,7 +30,11 @@ import QueryString from 'qs'; import React, { useEffect, useMemo, useState } from 'react'; import { useHistory, useLocation, useParams } from 'react-router-dom'; import { searchQuery } from 'rest/searchAPI'; -import { getListTestCase, ListTestCaseParams } from 'rest/testAPI'; +import { + getListTestCase, + getTestCaseById, + ListTestCaseParams, +} from 'rest/testAPI'; import { showErrorToast } from 'utils/ToastUtils'; import { DataQualitySearchParams } from '../DataQuality.interface'; import { SummaryPanel } from '../SummaryPannel/SummaryPanel.component'; @@ -38,6 +43,8 @@ export const TestCases = () => { const history = useHistory(); const location = useLocation(); const { tab } = useParams<{ tab: DataQualityPageTabs }>(); + const { permissions } = usePermissionProvider(); + const { testCase: testCasePermission } = permissions; const params = useMemo(() => { const search = location.search; @@ -115,16 +122,31 @@ export const TestCases = () => { pageSize: PAGE_SIZE, searchIndex: SearchIndex.TEST_CASE, query: searchValue, + fetchSource: false, }); - const hits = ( + const promise = ( response.hits.hits as SearchHitBody< SearchIndex.TEST_CASE, TestCaseSearchSource >[] - ).map((value) => value._source); + ).map((value) => + getTestCaseById(value._id ?? '', { + fields: 'testDefinition,testCaseResult,testSuite', + }) + ); + + const value = await Promise.allSettled(promise); + + const testSuites = value.reduce((prev, curr) => { + if (curr.status === 'fulfilled') { + return [...prev, curr.value.data]; + } + + return prev; + }, [] as TestCase[]); setTestCase({ - data: hits, + data: testSuites, paging: { total: response.hits.total.value ?? 0 }, }); } catch (error) { @@ -151,14 +173,16 @@ export const TestCases = () => { }; useEffect(() => { - if (tab === DataQualityPageTabs.TEST_CASES) { - if (searchValue) { - searchTestCases(); - } else { - fetchTestCases(); + if (testCasePermission?.ViewAll || testCasePermission?.ViewBasic) { + if (tab === DataQualityPageTabs.TEST_CASES) { + if (searchValue) { + searchTestCases(); + } else { + fetchTestCases(); + } } } - }, [tab, searchValue]); + }, [tab, searchValue, testCasePermission]); return ( 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 f3eb11f81b6..135efa2a58d 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 @@ -17,6 +17,7 @@ import FilterTablePlaceHolder from 'components/common/error-with-placeholder/Fil import NextPrevious from 'components/common/next-previous/NextPrevious'; import { OwnerLabel } from 'components/common/OwnerLabel/OwnerLabel.component'; import Searchbar from 'components/common/searchbar/Searchbar'; +import { usePermissionProvider } from 'components/PermissionProvider/PermissionProvider'; import { TableProfilerTab } from 'components/ProfilerDashboard/profilerDashboard.interface'; import ProfilerProgressWidget from 'components/TableProfiler/Component/ProfilerProgressWidget'; import { @@ -55,6 +56,8 @@ export const TestSuites = () => { useParams<{ tab: DataQualityPageTabs }>(); const history = useHistory(); const location = useLocation(); + const { permissions } = usePermissionProvider(); + const { testSuite: testSuitePermission } = permissions; const [testSuites, setTestSuites] = useState>({ data: [], @@ -177,8 +180,10 @@ export const TestSuites = () => { }; useEffect(() => { - fetchTestSuites(); - }, [tab]); + if (testSuitePermission?.ViewAll || testSuitePermission?.ViewBasic) { + fetchTestSuites(); + } + }, [tab, testSuitePermission]); return ( @@ -192,13 +197,14 @@ export const TestSuites = () => { /> - {tab === DataQualityPageTabs.TEST_SUITES && ( - - - - )} + {tab === DataQualityPageTabs.TEST_SUITES && + testSuitePermission?.Create && ( + + + + )} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/TestSummary.tsx b/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/TestSummary.tsx index 17de64741ff..8c128f70e95 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/TestSummary.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/ProfilerDashboard/component/TestSummary.tsx @@ -11,8 +11,9 @@ * limitations under the License. */ -import { Button, Col, Row, Typography } from 'antd'; +import { Button, Col, Row, Space, Typography } from 'antd'; import { AxiosError } from 'axios'; +import RichTextEditorPreviewer from 'components/common/rich-text-editor/RichTextEditorPreviewer'; import DatePickerMenu from 'components/DatePickerMenu/DatePickerMenu.component'; import { GREEN_3, @@ -97,13 +98,13 @@ const TestSummary: React.FC = ({ const values = result.testResultValue?.reduce((acc, curr) => { return { ...acc, - [curr.name || 'value']: round(parseFloat(curr.value ?? ''), 2) || 0, + [curr.name ?? 'value']: round(parseFloat(curr.value ?? ''), 2) || 0, }; }, {}); chartData.push({ name: getFormattedDateFromSeconds(result.timestamp as number), - status: result.testCaseStatus || '', + status: result.testCaseStatus ?? '', ...values, }); }); @@ -111,9 +112,9 @@ const TestSummary: React.FC = ({ setChartData({ information: currentData[0]?.testResultValue?.map((info, i) => ({ - label: info.name || '', + label: info.name ?? '', color: COLORS[i], - })) || [], + })) ?? [], data: chartData, }); }; @@ -251,13 +252,16 @@ const TestSummary: React.FC = ({ if (isSqlQuery) { return ( - - + + {`${param.name}:`} - + = ({ )} - {showParameters && ( - + + {showParameters && ( {`${t('label.parameter')}:`} - - {!isEmpty(parameterValuesWithoutSqlExpression) ? ( {parameterValuesWithoutSqlExpression?.map(showParamsData)} ) : ( - + {t('label.no-parameter-available')} )} - - )} - - {!isUndefined(parameterValuesWithSqlExpression) - ? parameterValuesWithSqlExpression.map(showParamsData) - : null} + )} + {!isUndefined(parameterValuesWithSqlExpression) ? ( + {parameterValuesWithSqlExpression.map(showParamsData)} + ) : null} + {data.description && ( + + + + {`${t('label.description')}:`} + + + + + )} + ); 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 3e8e310fefd..391b7780b44 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 @@ -118,6 +118,7 @@ const AddTestSuiteForm: React.FC = ({ form.setFieldsValue({ description: value })} /> diff --git a/openmetadata-ui/src/main/resources/ui/src/components/TestSuite/TestSuiteStepper/TestSuiteStepper.tsx b/openmetadata-ui/src/main/resources/ui/src/components/TestSuite/TestSuiteStepper/TestSuiteStepper.tsx index 94ae53543bf..59511245f5b 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/TestSuite/TestSuiteStepper/TestSuiteStepper.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/TestSuite/TestSuiteStepper/TestSuiteStepper.tsx @@ -11,34 +11,28 @@ * limitations under the License. */ -import { Button, Col, Form, Row, Select, Space, Typography } from 'antd'; +import { Col, Row, Space, Typography } from 'antd'; import { AxiosError } from 'axios'; import RightPanel from 'components/AddDataQualityTest/components/RightPanel'; import { getRightPanelForAddTestSuitePage } from 'components/AddDataQualityTest/rightPanelData'; +import { AddTestCaseList } from 'components/AddTestCaseList/AddTestCaseList.component'; import ResizablePanels from 'components/common/ResizablePanels/ResizablePanels'; import SuccessScreen from 'components/common/success-screen/SuccessScreen'; import TitleBreadcrumb from 'components/common/title-breadcrumb/title-breadcrumb.component'; import IngestionStepper from 'components/IngestionStepper/IngestionStepper.component'; import { HTTP_STATUS_CODE } from 'constants/auth.constants'; -import { PAGE_SIZE_LARGE } from 'constants/constants'; import { STEPS_FOR_ADD_TEST_SUITE, TEST_SUITE_STEPPER_BREADCRUMB, } from 'constants/TestSuite.constant'; import { FormSubmitType } from 'enums/form.enum'; import { OwnerType } from 'enums/user.enum'; -import { TestCase } from 'generated/tests/testCase'; import { TestSuite } from 'generated/tests/testSuite'; -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useHistory } from 'react-router-dom'; -import { - addTestCaseToLogicalTestSuite, - createTestSuites, - getListTestCase, -} from 'rest/testAPI'; +import { addTestCaseToLogicalTestSuite, createTestSuites } from 'rest/testAPI'; import { getCurrentUserId } from 'utils/CommonUtils'; -import { getEntityName } from 'utils/EntityUtils'; import { getTestSuitePath } from 'utils/RouterUtils'; import { showErrorToast } from 'utils/ToastUtils'; import AddTestSuiteForm from '../AddTestSuiteForm/AddTestSuiteForm'; @@ -48,11 +42,9 @@ const TestSuiteStepper = () => { const history = useHistory(); const [activeServiceStep, setActiveServiceStep] = useState(1); const [testSuiteResponse, setTestSuiteResponse] = useState(); - const [testCases, setTestCases] = useState([]); - const [selectedTestCase, setSelectedTestCase] = useState([]); const handleViewTestSuiteClick = () => { - history.push(getTestSuitePath(testSuiteResponse?.fullyQualifiedName || '')); + history.push(getTestSuitePath(testSuiteResponse?.fullyQualifiedName ?? '')); }; const handleTestSuitNextClick = (data: TestSuite) => { @@ -60,7 +52,7 @@ const TestSuiteStepper = () => { setActiveServiceStep(2); }; - const onSubmit = async (data: { testCase: string[] }) => { + const onSubmit = async (data: string[]) => { try { const owner = { id: getCurrentUserId(), @@ -74,7 +66,7 @@ const TestSuiteStepper = () => { }); setTestSuiteResponse(response); await addTestCaseToLogicalTestSuite({ - testCaseIds: data.testCase, + testCaseIds: data, testSuiteId: response.id ?? '', }); setActiveServiceStep(3); @@ -100,61 +92,15 @@ const TestSuiteStepper = () => { } }; - const fetchTestCases = async () => { - try { - const response = await getListTestCase({ limit: PAGE_SIZE_LARGE }); - setTestCases(response.data); - } catch (error) { - setTestCases([]); - } - }; - - useEffect(() => { - fetchTestCases(); - }, []); - - const selectTestCase = useMemo(() => { - return ( -
setSelectedTestCase(testCase)}> - - - - - - - - - -
- ); - }, [testCases, selectedTestCase, testSuiteResponse]); - const RenderSelectedTab = useCallback(() => { if (activeServiceStep === 2) { - return selectTestCase; + return ( + setActiveServiceStep(1)} + onSubmit={onSubmit} + /> + ); } else if (activeServiceStep === 3) { return ( { fetchTestCases(); }; + const handleAddTestCaseSubmit = async (testCaseIds: string[]) => { + try { + await addTestCaseToLogicalTestSuite({ + testCaseIds, + testSuiteId: testSuite?.id ?? '', + }); + setIsTestCaseModalOpen(false); + fetchTestCases(); + } catch (error) { + showErrorToast(error as AxiosError); + } + }; + const fetchTestSuiteByName = async () => { try { const response = await getTestSuiteByName(testSuiteFQN, { @@ -309,11 +323,16 @@ const TestSuiteDetailsPage = () => { titleLinks={slashedBreadCrumb} /> - + {(testSuitePermissions.EditAll || + testSuitePermissions.EditTests) && ( + + )} { /> - setIsTestCaseModalOpen(false)} - onSubmit={afterSubmitAction} - /> + title={t('label.add-entity', { + entity: t('label.test-case-plural'), + })} + width={750}> + setIsTestCaseModalOpen(false)} + onSubmit={handleAddTestCaseSubmit} + /> +
diff --git a/openmetadata-ui/src/main/resources/ui/src/rest/testAPI.ts b/openmetadata-ui/src/main/resources/ui/src/rest/testAPI.ts index 45330c1b53f..650507cdfc6 100644 --- a/openmetadata-ui/src/main/resources/ui/src/rest/testAPI.ts +++ b/openmetadata-ui/src/main/resources/ui/src/rest/testAPI.ts @@ -113,6 +113,16 @@ export const getTestCaseByFqn = async ( return response; }; +export const getTestCaseById = async ( + id: string, + params?: Pick +) => { + const response = await APIClient.get(`${testCaseUrl}/${id}`, { + params, + }); + + return response; +}; export const createTestCase = async (data: CreateTestCase) => { const response = await APIClient.post<