mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-01 21:23:10 +00:00
ui: worked on DQ feedback part 3 (#12149)
* ui: worked on DQ feedback part 3 * updated name of test suite ingestion name - Added description field in test case expand view - Added functionality to update displayname of test case * added testCase in re-indexing * integrated permission in DQ
This commit is contained in:
parent
0010a4fe2a
commit
fecb65c513
@ -116,7 +116,7 @@ const EditTestCaseModal: React.FC<EditTestCaseModalProps> = ({
|
|||||||
...testCase,
|
...testCase,
|
||||||
parameterValues,
|
parameterValues,
|
||||||
description,
|
description,
|
||||||
name: value.name,
|
displayName: value.displayName,
|
||||||
};
|
};
|
||||||
const jsonPatch = compare(testCase, updatedTestCase);
|
const jsonPatch = compare(testCase, updatedTestCase);
|
||||||
|
|
||||||
@ -124,10 +124,10 @@ const EditTestCaseModal: React.FC<EditTestCaseModalProps> = ({
|
|||||||
try {
|
try {
|
||||||
setIsLoadingOnSave(true);
|
setIsLoadingOnSave(true);
|
||||||
const updateRes = await updateTestCaseById(
|
const updateRes = await updateTestCaseById(
|
||||||
testCase.id || '',
|
testCase.id ?? '',
|
||||||
jsonPatch
|
jsonPatch
|
||||||
);
|
);
|
||||||
onUpdate && onUpdate(updateRes);
|
onUpdate?.(updateRes);
|
||||||
showSuccessToast(
|
showSuccessToast(
|
||||||
t('server.update-entity-success', { entity: t('label.test-case') })
|
t('server.update-entity-success', { entity: t('label.test-case') })
|
||||||
);
|
);
|
||||||
@ -216,17 +216,17 @@ const EditTestCaseModal: React.FC<EditTestCaseModalProps> = ({
|
|||||||
layout="vertical"
|
layout="vertical"
|
||||||
name="tableTestForm"
|
name="tableTestForm"
|
||||||
onFinish={handleFormSubmit}>
|
onFinish={handleFormSubmit}>
|
||||||
<Form.Item required label={`${t('label.table')}:`} name="table">
|
<Form.Item required label={`${t('label.table')}`} name="table">
|
||||||
<Input disabled />
|
<Input disabled />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
{isColumn && (
|
{isColumn && (
|
||||||
<Form.Item required label={`${t('label.column')}:`} name="column">
|
<Form.Item required label={`${t('label.column')}`} name="column">
|
||||||
<Input disabled />
|
<Input disabled />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)}
|
)}
|
||||||
<Form.Item
|
<Form.Item
|
||||||
required
|
required
|
||||||
label={`${t('label.name')}:`}
|
label={`${t('label.name')}`}
|
||||||
name="name"
|
name="name"
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
@ -236,6 +236,9 @@ const EditTestCaseModal: React.FC<EditTestCaseModalProps> = ({
|
|||||||
]}>
|
]}>
|
||||||
<Input disabled placeholder={t('message.enter-test-case-name')} />
|
<Input disabled placeholder={t('message.enter-test-case-name')} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item label={t('label.display-name')} name="displayName">
|
||||||
|
<Input placeholder={t('message.enter-test-case-name')} />
|
||||||
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
required
|
required
|
||||||
label={`${t('label.test-entity', {
|
label={`${t('label.test-entity', {
|
||||||
@ -247,7 +250,7 @@ const EditTestCaseModal: React.FC<EditTestCaseModalProps> = ({
|
|||||||
|
|
||||||
{GenerateParamsField()}
|
{GenerateParamsField()}
|
||||||
|
|
||||||
<Form.Item label={`${t('label.description')}:`} name="description">
|
<Form.Item label={`${t('label.description')}`} name="description">
|
||||||
<RichTextEditor
|
<RichTextEditor
|
||||||
height="200px"
|
height="200px"
|
||||||
initialValue={testCase?.description || ''}
|
initialValue={testCase?.description || ''}
|
||||||
|
@ -22,6 +22,7 @@ import {
|
|||||||
deployIngestionPipelineById,
|
deployIngestionPipelineById,
|
||||||
updateIngestionPipeline as putIngestionPipeline,
|
updateIngestionPipeline as putIngestionPipeline,
|
||||||
} from 'rest/ingestionPipelineAPI';
|
} from 'rest/ingestionPipelineAPI';
|
||||||
|
import { getIngestionName } from 'utils/ServiceUtils';
|
||||||
import {
|
import {
|
||||||
DEPLOYED_PROGRESS_VAL,
|
DEPLOYED_PROGRESS_VAL,
|
||||||
INGESTION_PROGRESS_END_VAL,
|
INGESTION_PROGRESS_END_VAL,
|
||||||
@ -36,7 +37,8 @@ import {
|
|||||||
import { IngestionPipeline } from '../../generated/entity/services/ingestionPipelines/ingestionPipeline';
|
import { IngestionPipeline } from '../../generated/entity/services/ingestionPipelines/ingestionPipeline';
|
||||||
import {
|
import {
|
||||||
getIngestionFrequency,
|
getIngestionFrequency,
|
||||||
replaceSpaceWith_,
|
getNameFromFQN,
|
||||||
|
replaceAllSpacialCharWith_,
|
||||||
Transi18next,
|
Transi18next,
|
||||||
} from '../../utils/CommonUtils';
|
} from '../../utils/CommonUtils';
|
||||||
import { showErrorToast } from '../../utils/ToastUtils';
|
import { showErrorToast } from '../../utils/ToastUtils';
|
||||||
@ -113,7 +115,12 @@ const TestSuiteIngestion: React.FC<TestSuiteIngestionProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const createIngestionPipeline = async (repeatFrequency: string) => {
|
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 = {
|
const ingestionPayload: CreateIngestionPipeline = {
|
||||||
airflowConfig: {
|
airflowConfig: {
|
||||||
@ -121,10 +128,10 @@ const TestSuiteIngestion: React.FC<TestSuiteIngestionProps> = ({
|
|||||||
? undefined
|
? undefined
|
||||||
: repeatFrequency,
|
: repeatFrequency,
|
||||||
},
|
},
|
||||||
name: `${updatedName}_${PipelineType.TestSuite}`,
|
name: updatedName,
|
||||||
pipelineType: PipelineType.TestSuite,
|
pipelineType: PipelineType.TestSuite,
|
||||||
service: {
|
service: {
|
||||||
id: testSuite.id || '',
|
id: testSuite.id ?? '',
|
||||||
type: camelCase(PipelineType.TestSuite),
|
type: camelCase(PipelineType.TestSuite),
|
||||||
},
|
},
|
||||||
sourceConfig: {
|
sourceConfig: {
|
||||||
|
@ -138,16 +138,18 @@ const TestCaseForm: React.FC<TestCaseFormProps> = ({
|
|||||||
: value,
|
: value,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
const name =
|
||||||
|
value.testName?.trim() ||
|
||||||
|
`${columnName ? columnName : table.name}_${snakeCase(
|
||||||
|
selectedTestType
|
||||||
|
)}_${cryptoRandomString({
|
||||||
|
length: 4,
|
||||||
|
type: 'alphanumeric',
|
||||||
|
})}`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name:
|
name,
|
||||||
value.testName?.trim() ||
|
displayName: name,
|
||||||
`${columnName ? columnName : table.name}_${snakeCase(
|
|
||||||
selectedTestType
|
|
||||||
)}_${cryptoRandomString({
|
|
||||||
length: 4,
|
|
||||||
type: 'alphanumeric',
|
|
||||||
})}`,
|
|
||||||
entityLink: generateEntityLink(
|
entityLink: generateEntityLink(
|
||||||
isColumnFqn ? `${decodedEntityFQN}.${columnName}` : decodedEntityFQN,
|
isColumnFqn ? `${decodedEntityFQN}.${columnName}` : decodedEntityFQN,
|
||||||
isColumnFqn
|
isColumnFqn
|
||||||
|
@ -10,11 +10,10 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { Checkbox, Col, List, Modal, Row, Space, Typography } from 'antd';
|
import { Button, Checkbox, Col, List, Row, Space, Typography } from 'antd';
|
||||||
import { AxiosError } from 'axios';
|
|
||||||
import Searchbar from 'components/common/searchbar/Searchbar';
|
import Searchbar from 'components/common/searchbar/Searchbar';
|
||||||
import Loader from 'components/Loader/Loader';
|
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 { SearchIndex } from 'enums/search.enum';
|
||||||
import { TestCase } from 'generated/tests/testCase';
|
import { TestCase } from 'generated/tests/testCase';
|
||||||
import {
|
import {
|
||||||
@ -26,13 +25,11 @@ import React, { UIEventHandler, useCallback, useEffect, useState } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { searchQuery } from 'rest/searchAPI';
|
import { searchQuery } from 'rest/searchAPI';
|
||||||
import { addTestCaseToLogicalTestSuite } from 'rest/testAPI';
|
|
||||||
import { getNameFromFQN } from 'utils/CommonUtils';
|
import { getNameFromFQN } from 'utils/CommonUtils';
|
||||||
import { getEntityName } from 'utils/EntityUtils';
|
import { getEntityName } from 'utils/EntityUtils';
|
||||||
import { getDecodedFqn } from 'utils/StringsUtils';
|
import { getDecodedFqn } from 'utils/StringsUtils';
|
||||||
import { getEntityFqnFromEntityLink } from 'utils/TableUtils';
|
import { getEntityFqnFromEntityLink } from 'utils/TableUtils';
|
||||||
import { showErrorToast } from 'utils/ToastUtils';
|
import { AddTestCaseModalProps } from './AddTestCaseList.interface';
|
||||||
import { AddTestCaseModalProps } from './AddTestCaseModal.interface';
|
|
||||||
|
|
||||||
// Todo: need to help from backend guys for ES query
|
// Todo: need to help from backend guys for ES query
|
||||||
// export const getQueryFilterToExcludeTest = (testCase: EntityReference[]) => ({
|
// export const getQueryFilterToExcludeTest = (testCase: EntityReference[]) => ({
|
||||||
@ -47,12 +44,12 @@ import { AddTestCaseModalProps } from './AddTestCaseModal.interface';
|
|||||||
// },
|
// },
|
||||||
// });
|
// });
|
||||||
|
|
||||||
export const AddTestCaseModal = ({
|
export const AddTestCaseList = ({
|
||||||
open,
|
|
||||||
onCancel,
|
onCancel,
|
||||||
existingTest,
|
existingTest,
|
||||||
testSuiteId,
|
|
||||||
onSubmit,
|
onSubmit,
|
||||||
|
cancelText,
|
||||||
|
submitText,
|
||||||
}: AddTestCaseModalProps) => {
|
}: AddTestCaseModalProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [searchTerm, setSearchTerm] = useState<string>('');
|
const [searchTerm, setSearchTerm] = useState<string>('');
|
||||||
@ -74,7 +71,7 @@ export const AddTestCaseModal = ({
|
|||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
const res = await searchQuery({
|
const res = await searchQuery({
|
||||||
pageNumber: page,
|
pageNumber: page,
|
||||||
pageSize: PAGE_SIZE_MEDIUM,
|
pageSize: PAGE_SIZE,
|
||||||
searchIndex: SearchIndex.TEST_CASE,
|
searchIndex: SearchIndex.TEST_CASE,
|
||||||
query: searchText,
|
query: searchText,
|
||||||
// queryFilter: getQueryFilterToExcludeTest(existingTest),
|
// queryFilter: getQueryFilterToExcludeTest(existingTest),
|
||||||
@ -100,17 +97,8 @@ export const AddTestCaseModal = ({
|
|||||||
const testCaseIds = [...(selectedItems?.values() ?? [])].map(
|
const testCaseIds = [...(selectedItems?.values() ?? [])].map(
|
||||||
(test) => test.id ?? ''
|
(test) => test.id ?? ''
|
||||||
);
|
);
|
||||||
|
onSubmit(testCaseIds);
|
||||||
try {
|
setIsLoading(false);
|
||||||
await addTestCaseToLogicalTestSuite({ testCaseIds, testSuiteId });
|
|
||||||
|
|
||||||
onSubmit();
|
|
||||||
onCancel();
|
|
||||||
} catch (error) {
|
|
||||||
showErrorToast(error as AxiosError);
|
|
||||||
} finally {
|
|
||||||
setIsLoading(false);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onScroll: UIEventHandler<HTMLElement> = useCallback(
|
const onScroll: UIEventHandler<HTMLElement> = useCallback(
|
||||||
@ -126,7 +114,7 @@ export const AddTestCaseModal = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[searchTerm, totalCount, items]
|
[searchTerm, totalCount, items, isLoading]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleCardClick = (details: TestCase) => {
|
const handleCardClick = (details: TestCase) => {
|
||||||
@ -160,99 +148,92 @@ export const AddTestCaseModal = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open) {
|
fetchTestCases({ searchText: searchTerm });
|
||||||
fetchTestCases({ searchText: searchTerm });
|
}, [searchTerm]);
|
||||||
}
|
|
||||||
}, [open, searchTerm]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Row gutter={[0, 16]}>
|
||||||
centered
|
<Col span={24}>
|
||||||
destroyOnClose
|
<Searchbar
|
||||||
closable={false}
|
removeMargin
|
||||||
okButtonProps={{
|
showClearSearch
|
||||||
loading: isLoading,
|
showLoadingStatus
|
||||||
}}
|
placeholder={t('label.search-entity', {
|
||||||
open={open}
|
entity: t('label.test-case-plural'),
|
||||||
title={t('label.add-entity', { entity: t('label.test-case-plural') })}
|
})}
|
||||||
width={750}
|
searchValue={searchTerm}
|
||||||
onCancel={onCancel}
|
onSearch={handleSearch}
|
||||||
onOk={handleSubmit}>
|
/>
|
||||||
<Row gutter={[0, 16]}>
|
</Col>
|
||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
<Searchbar
|
<List loading={{ spinning: false, indicator: <Loader /> }}>
|
||||||
removeMargin
|
<VirtualList
|
||||||
showClearSearch
|
data={items}
|
||||||
showLoadingStatus
|
height={500}
|
||||||
placeholder={t('label.search-entity', {
|
itemKey="id"
|
||||||
entity: t('label.test-case-plural'),
|
onScroll={onScroll}>
|
||||||
})}
|
{({ _source: test }) => {
|
||||||
searchValue={searchTerm}
|
const tableFqn = getEntityFqnFromEntityLink(test.entityLink);
|
||||||
onSearch={handleSearch}
|
const tableName = getNameFromFQN(tableFqn);
|
||||||
/>
|
const isColumn = test.entityLink.includes('::columns::');
|
||||||
</Col>
|
|
||||||
<Col span={24}>
|
|
||||||
<List loading={{ spinning: false, indicator: <Loader /> }}>
|
|
||||||
<VirtualList
|
|
||||||
data={items}
|
|
||||||
height={500}
|
|
||||||
itemKey="id"
|
|
||||||
onScroll={onScroll}>
|
|
||||||
{({ _source: test }) => {
|
|
||||||
const tableFqn = getEntityFqnFromEntityLink(test.entityLink);
|
|
||||||
const tableName = getNameFromFQN(tableFqn);
|
|
||||||
const isColumn = test.entityLink.includes('::columns::');
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Space
|
<Space
|
||||||
className="m-b-md border rounded-4 p-sm cursor-pointer"
|
className="m-b-md border rounded-4 p-sm cursor-pointer"
|
||||||
direction="vertical"
|
direction="vertical"
|
||||||
onClick={() => handleCardClick(test)}>
|
onClick={() => handleCardClick(test)}>
|
||||||
<Space className="justify-between w-full">
|
<Space className="justify-between w-full">
|
||||||
<Typography.Paragraph
|
<Typography.Paragraph
|
||||||
className="m-0 font-medium text-base"
|
className="m-0 font-medium text-base"
|
||||||
data-testid={test.name}>
|
data-testid={test.name}>
|
||||||
{getEntityName(test)}
|
{getEntityName(test)}
|
||||||
</Typography.Paragraph>
|
</Typography.Paragraph>
|
||||||
|
|
||||||
<Checkbox checked={selectedItems?.has(test.id ?? '')} />
|
<Checkbox checked={selectedItems?.has(test.id ?? '')} />
|
||||||
</Space>
|
|
||||||
<Typography.Paragraph className="m-0">
|
|
||||||
{getEntityName(test.testDefinition)}
|
|
||||||
</Typography.Paragraph>
|
|
||||||
<Typography.Paragraph className="m-0">
|
|
||||||
<Link
|
|
||||||
data-testid="table-link"
|
|
||||||
to={getTableTabPath(tableFqn, 'profiler')}
|
|
||||||
onClick={(e) => e.stopPropagation()}>
|
|
||||||
{tableName}
|
|
||||||
</Link>
|
|
||||||
</Typography.Paragraph>
|
|
||||||
{isColumn && (
|
|
||||||
<Space>
|
|
||||||
<Typography.Text className="font-medium text-xs">{`${t(
|
|
||||||
'label.column'
|
|
||||||
)}:`}</Typography.Text>
|
|
||||||
<Typography.Text className="text-grey-muted text-xs">
|
|
||||||
{getNameFromFQN(
|
|
||||||
getDecodedFqn(
|
|
||||||
getEntityFqnFromEntityLink(
|
|
||||||
test.entityLink,
|
|
||||||
isColumn
|
|
||||||
),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
) ?? '--'}
|
|
||||||
</Typography.Text>
|
|
||||||
</Space>
|
|
||||||
)}
|
|
||||||
</Space>
|
</Space>
|
||||||
);
|
<Typography.Paragraph className="m-0">
|
||||||
}}
|
{getEntityName(test.testDefinition)}
|
||||||
</VirtualList>
|
</Typography.Paragraph>
|
||||||
</List>
|
<Typography.Paragraph className="m-0">
|
||||||
</Col>
|
<Link
|
||||||
</Row>
|
data-testid="table-link"
|
||||||
</Modal>
|
to={getTableTabPath(tableFqn, 'profiler')}
|
||||||
|
onClick={(e) => e.stopPropagation()}>
|
||||||
|
{tableName}
|
||||||
|
</Link>
|
||||||
|
</Typography.Paragraph>
|
||||||
|
{isColumn && (
|
||||||
|
<Space>
|
||||||
|
<Typography.Text className="font-medium text-xs">{`${t(
|
||||||
|
'label.column'
|
||||||
|
)}:`}</Typography.Text>
|
||||||
|
<Typography.Text className="text-grey-muted text-xs">
|
||||||
|
{getNameFromFQN(
|
||||||
|
getDecodedFqn(
|
||||||
|
getEntityFqnFromEntityLink(
|
||||||
|
test.entityLink,
|
||||||
|
isColumn
|
||||||
|
),
|
||||||
|
true
|
||||||
|
)
|
||||||
|
) ?? '--'}
|
||||||
|
</Typography.Text>
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</VirtualList>
|
||||||
|
</List>
|
||||||
|
</Col>
|
||||||
|
<Col className="d-flex justify-end items-center p-y-xss" span={24}>
|
||||||
|
<Button type="link" onClick={onCancel}>
|
||||||
|
{cancelText ?? t('label.cancel')}
|
||||||
|
</Button>
|
||||||
|
<Button loading={isLoading} type="primary" onClick={handleSubmit}>
|
||||||
|
{submitText ?? t('label.submit')}
|
||||||
|
</Button>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
);
|
);
|
||||||
};
|
};
|
@ -13,9 +13,9 @@
|
|||||||
import { EntityReference } from 'generated/tests/testCase';
|
import { EntityReference } from 'generated/tests/testCase';
|
||||||
|
|
||||||
export interface AddTestCaseModalProps {
|
export interface AddTestCaseModalProps {
|
||||||
open: boolean;
|
onCancel?: () => void;
|
||||||
onCancel: () => void;
|
onSubmit: (testCaseIds: string[]) => void;
|
||||||
onSubmit: () => void;
|
existingTest?: EntityReference[];
|
||||||
existingTest: EntityReference[];
|
cancelText?: string;
|
||||||
testSuiteId: string;
|
submitText?: string;
|
||||||
}
|
}
|
@ -13,6 +13,7 @@
|
|||||||
import { Col, Row } from 'antd';
|
import { Col, Row } from 'antd';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import { SummaryCard } from 'components/common/SummaryCard/SummaryCard.component';
|
import { SummaryCard } from 'components/common/SummaryCard/SummaryCard.component';
|
||||||
|
import { usePermissionProvider } from 'components/PermissionProvider/PermissionProvider';
|
||||||
import { TestSummary } from 'generated/tests/testSuite';
|
import { TestSummary } from 'generated/tests/testSuite';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -23,6 +24,8 @@ import { SummaryPanelProps } from './SummaryPanel.interface';
|
|||||||
|
|
||||||
export const SummaryPanel = ({ testSuiteId }: SummaryPanelProps) => {
|
export const SummaryPanel = ({ testSuiteId }: SummaryPanelProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const { permissions } = usePermissionProvider();
|
||||||
|
const { testCase: testCasePermission } = permissions;
|
||||||
|
|
||||||
const [summary, setSummary] = useState<TestSummary>();
|
const [summary, setSummary] = useState<TestSummary>();
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
@ -40,8 +43,10 @@ export const SummaryPanel = ({ testSuiteId }: SummaryPanelProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchTestSummary();
|
if (testCasePermission?.ViewAll || testCasePermission?.ViewBasic) {
|
||||||
}, [testSuiteId]);
|
fetchTestSummary();
|
||||||
|
}
|
||||||
|
}, [testSuiteId, testCasePermission]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row wrap gutter={[16, 16]}>
|
<Row wrap gutter={[16, 16]}>
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
import { Col, Row } from 'antd';
|
import { Col, Row } from 'antd';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import Searchbar from 'components/common/searchbar/Searchbar';
|
import Searchbar from 'components/common/searchbar/Searchbar';
|
||||||
|
import { usePermissionProvider } from 'components/PermissionProvider/PermissionProvider';
|
||||||
import DataQualityTab from 'components/ProfilerDashboard/component/DataQualityTab';
|
import DataQualityTab from 'components/ProfilerDashboard/component/DataQualityTab';
|
||||||
import { INITIAL_PAGING_VALUE, PAGE_SIZE } from 'constants/constants';
|
import { INITIAL_PAGING_VALUE, PAGE_SIZE } from 'constants/constants';
|
||||||
import { SearchIndex } from 'enums/search.enum';
|
import { SearchIndex } from 'enums/search.enum';
|
||||||
@ -29,7 +30,11 @@ import QueryString from 'qs';
|
|||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import { useHistory, useLocation, useParams } from 'react-router-dom';
|
import { useHistory, useLocation, useParams } from 'react-router-dom';
|
||||||
import { searchQuery } from 'rest/searchAPI';
|
import { searchQuery } from 'rest/searchAPI';
|
||||||
import { getListTestCase, ListTestCaseParams } from 'rest/testAPI';
|
import {
|
||||||
|
getListTestCase,
|
||||||
|
getTestCaseById,
|
||||||
|
ListTestCaseParams,
|
||||||
|
} from 'rest/testAPI';
|
||||||
import { showErrorToast } from 'utils/ToastUtils';
|
import { showErrorToast } from 'utils/ToastUtils';
|
||||||
import { DataQualitySearchParams } from '../DataQuality.interface';
|
import { DataQualitySearchParams } from '../DataQuality.interface';
|
||||||
import { SummaryPanel } from '../SummaryPannel/SummaryPanel.component';
|
import { SummaryPanel } from '../SummaryPannel/SummaryPanel.component';
|
||||||
@ -38,6 +43,8 @@ export const TestCases = () => {
|
|||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const { tab } = useParams<{ tab: DataQualityPageTabs }>();
|
const { tab } = useParams<{ tab: DataQualityPageTabs }>();
|
||||||
|
const { permissions } = usePermissionProvider();
|
||||||
|
const { testCase: testCasePermission } = permissions;
|
||||||
|
|
||||||
const params = useMemo(() => {
|
const params = useMemo(() => {
|
||||||
const search = location.search;
|
const search = location.search;
|
||||||
@ -115,16 +122,31 @@ export const TestCases = () => {
|
|||||||
pageSize: PAGE_SIZE,
|
pageSize: PAGE_SIZE,
|
||||||
searchIndex: SearchIndex.TEST_CASE,
|
searchIndex: SearchIndex.TEST_CASE,
|
||||||
query: searchValue,
|
query: searchValue,
|
||||||
|
fetchSource: false,
|
||||||
});
|
});
|
||||||
const hits = (
|
const promise = (
|
||||||
response.hits.hits as SearchHitBody<
|
response.hits.hits as SearchHitBody<
|
||||||
SearchIndex.TEST_CASE,
|
SearchIndex.TEST_CASE,
|
||||||
TestCaseSearchSource
|
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({
|
setTestCase({
|
||||||
data: hits,
|
data: testSuites,
|
||||||
paging: { total: response.hits.total.value ?? 0 },
|
paging: { total: response.hits.total.value ?? 0 },
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -151,14 +173,16 @@ export const TestCases = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (tab === DataQualityPageTabs.TEST_CASES) {
|
if (testCasePermission?.ViewAll || testCasePermission?.ViewBasic) {
|
||||||
if (searchValue) {
|
if (tab === DataQualityPageTabs.TEST_CASES) {
|
||||||
searchTestCases();
|
if (searchValue) {
|
||||||
} else {
|
searchTestCases();
|
||||||
fetchTestCases();
|
} else {
|
||||||
|
fetchTestCases();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [tab, searchValue]);
|
}, [tab, searchValue, testCasePermission]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row className="p-x-lg p-t-md" gutter={[16, 16]}>
|
<Row className="p-x-lg p-t-md" gutter={[16, 16]}>
|
||||||
|
@ -17,6 +17,7 @@ import FilterTablePlaceHolder from 'components/common/error-with-placeholder/Fil
|
|||||||
import NextPrevious from 'components/common/next-previous/NextPrevious';
|
import NextPrevious from 'components/common/next-previous/NextPrevious';
|
||||||
import { OwnerLabel } from 'components/common/OwnerLabel/OwnerLabel.component';
|
import { OwnerLabel } from 'components/common/OwnerLabel/OwnerLabel.component';
|
||||||
import Searchbar from 'components/common/searchbar/Searchbar';
|
import Searchbar from 'components/common/searchbar/Searchbar';
|
||||||
|
import { usePermissionProvider } from 'components/PermissionProvider/PermissionProvider';
|
||||||
import { TableProfilerTab } from 'components/ProfilerDashboard/profilerDashboard.interface';
|
import { TableProfilerTab } from 'components/ProfilerDashboard/profilerDashboard.interface';
|
||||||
import ProfilerProgressWidget from 'components/TableProfiler/Component/ProfilerProgressWidget';
|
import ProfilerProgressWidget from 'components/TableProfiler/Component/ProfilerProgressWidget';
|
||||||
import {
|
import {
|
||||||
@ -55,6 +56,8 @@ export const TestSuites = () => {
|
|||||||
useParams<{ tab: DataQualityPageTabs }>();
|
useParams<{ tab: DataQualityPageTabs }>();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
const { permissions } = usePermissionProvider();
|
||||||
|
const { testSuite: testSuitePermission } = permissions;
|
||||||
|
|
||||||
const [testSuites, setTestSuites] = useState<PagingResponse<TestSuite[]>>({
|
const [testSuites, setTestSuites] = useState<PagingResponse<TestSuite[]>>({
|
||||||
data: [],
|
data: [],
|
||||||
@ -177,8 +180,10 @@ export const TestSuites = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchTestSuites();
|
if (testSuitePermission?.ViewAll || testSuitePermission?.ViewBasic) {
|
||||||
}, [tab]);
|
fetchTestSuites();
|
||||||
|
}
|
||||||
|
}, [tab, testSuitePermission]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row className="p-x-lg p-t-md" gutter={[16, 16]}>
|
<Row className="p-x-lg p-t-md" gutter={[16, 16]}>
|
||||||
@ -192,13 +197,14 @@ export const TestSuites = () => {
|
|||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
{tab === DataQualityPageTabs.TEST_SUITES && (
|
{tab === DataQualityPageTabs.TEST_SUITES &&
|
||||||
<Link to={ROUTES.ADD_TEST_SUITES}>
|
testSuitePermission?.Create && (
|
||||||
<Button type="primary">
|
<Link to={ROUTES.ADD_TEST_SUITES}>
|
||||||
{t('label.add-entity', { entity: t('label.test-suite') })}
|
<Button type="primary">
|
||||||
</Button>
|
{t('label.add-entity', { entity: t('label.test-suite') })}
|
||||||
</Link>
|
</Button>
|
||||||
)}
|
</Link>
|
||||||
|
)}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -11,8 +11,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Button, Col, Row, Typography } from 'antd';
|
import { Button, Col, Row, Space, Typography } from 'antd';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
|
import RichTextEditorPreviewer from 'components/common/rich-text-editor/RichTextEditorPreviewer';
|
||||||
import DatePickerMenu from 'components/DatePickerMenu/DatePickerMenu.component';
|
import DatePickerMenu from 'components/DatePickerMenu/DatePickerMenu.component';
|
||||||
import {
|
import {
|
||||||
GREEN_3,
|
GREEN_3,
|
||||||
@ -97,13 +98,13 @@ const TestSummary: React.FC<TestSummaryProps> = ({
|
|||||||
const values = result.testResultValue?.reduce((acc, curr) => {
|
const values = result.testResultValue?.reduce((acc, curr) => {
|
||||||
return {
|
return {
|
||||||
...acc,
|
...acc,
|
||||||
[curr.name || 'value']: round(parseFloat(curr.value ?? ''), 2) || 0,
|
[curr.name ?? 'value']: round(parseFloat(curr.value ?? ''), 2) || 0,
|
||||||
};
|
};
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
chartData.push({
|
chartData.push({
|
||||||
name: getFormattedDateFromSeconds(result.timestamp as number),
|
name: getFormattedDateFromSeconds(result.timestamp as number),
|
||||||
status: result.testCaseStatus || '',
|
status: result.testCaseStatus ?? '',
|
||||||
...values,
|
...values,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -111,9 +112,9 @@ const TestSummary: React.FC<TestSummaryProps> = ({
|
|||||||
setChartData({
|
setChartData({
|
||||||
information:
|
information:
|
||||||
currentData[0]?.testResultValue?.map((info, i) => ({
|
currentData[0]?.testResultValue?.map((info, i) => ({
|
||||||
label: info.name || '',
|
label: info.name ?? '',
|
||||||
color: COLORS[i],
|
color: COLORS[i],
|
||||||
})) || [],
|
})) ?? [],
|
||||||
data: chartData,
|
data: chartData,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -251,13 +252,16 @@ const TestSummary: React.FC<TestSummaryProps> = ({
|
|||||||
|
|
||||||
if (isSqlQuery) {
|
if (isSqlQuery) {
|
||||||
return (
|
return (
|
||||||
<Row className="sql-expression-container" gutter={8} key={param.name}>
|
<Row
|
||||||
<Col span={showExpandIcon ? 2 : 3}>
|
className="sql-expression-container"
|
||||||
|
gutter={[8, 8]}
|
||||||
|
key={param.name}>
|
||||||
|
<Col span={24}>
|
||||||
<Typography.Text className="text-grey-muted">
|
<Typography.Text className="text-grey-muted">
|
||||||
{`${param.name}:`}
|
{`${param.name}:`}
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={showExpandIcon ? 22 : 21}>
|
<Col span={24}>
|
||||||
<SchemaEditor
|
<SchemaEditor
|
||||||
editorClass="table-query-editor"
|
editorClass="table-query-editor"
|
||||||
mode={{ name: CSMode.SQL }}
|
mode={{ name: CSMode.SQL }}
|
||||||
@ -344,30 +348,37 @@ const TestSummary: React.FC<TestSummaryProps> = ({
|
|||||||
)}
|
)}
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
{showParameters && (
|
<Row align="top" data-testid="params-container" gutter={[16, 16]}>
|
||||||
<Row align="top" data-testid="params-container" gutter={16}>
|
{showParameters && (
|
||||||
<Col>
|
<Col>
|
||||||
<Typography.Text className="text-grey-muted">
|
<Typography.Text className="text-grey-muted">
|
||||||
{`${t('label.parameter')}:`}
|
{`${t('label.parameter')}:`}
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
</Col>
|
|
||||||
<Col>
|
|
||||||
{!isEmpty(parameterValuesWithoutSqlExpression) ? (
|
{!isEmpty(parameterValuesWithoutSqlExpression) ? (
|
||||||
<Row className="parameter-value-container" gutter={[4, 4]}>
|
<Row className="parameter-value-container" gutter={[4, 4]}>
|
||||||
{parameterValuesWithoutSqlExpression?.map(showParamsData)}
|
{parameterValuesWithoutSqlExpression?.map(showParamsData)}
|
||||||
</Row>
|
</Row>
|
||||||
) : (
|
) : (
|
||||||
<Typography.Text type="secondary">
|
<Typography.Text className="m-l-xs" type="secondary">
|
||||||
{t('label.no-parameter-available')}
|
{t('label.no-parameter-available')}
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
)}
|
)}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
)}
|
||||||
)}
|
{!isUndefined(parameterValuesWithSqlExpression) ? (
|
||||||
|
<Col>{parameterValuesWithSqlExpression.map(showParamsData)}</Col>
|
||||||
{!isUndefined(parameterValuesWithSqlExpression)
|
) : null}
|
||||||
? parameterValuesWithSqlExpression.map(showParamsData)
|
{data.description && (
|
||||||
: null}
|
<Col>
|
||||||
|
<Space direction="vertical" size={4}>
|
||||||
|
<Typography.Text className="text-grey-muted">
|
||||||
|
{`${t('label.description')}:`}
|
||||||
|
</Typography.Text>
|
||||||
|
<RichTextEditorPreviewer markdown={data.description} />
|
||||||
|
</Space>
|
||||||
|
</Col>
|
||||||
|
)}
|
||||||
|
</Row>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
|
@ -118,6 +118,7 @@ const AddTestSuiteForm: React.FC<AddTestSuiteFormProps> = ({
|
|||||||
<Form.Item label={t('label.description')} name="description">
|
<Form.Item label={t('label.description')} name="description">
|
||||||
<RichTextEditor
|
<RichTextEditor
|
||||||
data-testid="test-suite-description"
|
data-testid="test-suite-description"
|
||||||
|
height="200px"
|
||||||
initialValue={testSuite?.description ?? ''}
|
initialValue={testSuite?.description ?? ''}
|
||||||
onTextChange={(value) => form.setFieldsValue({ description: value })}
|
onTextChange={(value) => form.setFieldsValue({ description: value })}
|
||||||
/>
|
/>
|
||||||
|
@ -11,34 +11,28 @@
|
|||||||
* limitations under the License.
|
* 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 { AxiosError } from 'axios';
|
||||||
import RightPanel from 'components/AddDataQualityTest/components/RightPanel';
|
import RightPanel from 'components/AddDataQualityTest/components/RightPanel';
|
||||||
import { getRightPanelForAddTestSuitePage } from 'components/AddDataQualityTest/rightPanelData';
|
import { getRightPanelForAddTestSuitePage } from 'components/AddDataQualityTest/rightPanelData';
|
||||||
|
import { AddTestCaseList } from 'components/AddTestCaseList/AddTestCaseList.component';
|
||||||
import ResizablePanels from 'components/common/ResizablePanels/ResizablePanels';
|
import ResizablePanels from 'components/common/ResizablePanels/ResizablePanels';
|
||||||
import SuccessScreen from 'components/common/success-screen/SuccessScreen';
|
import SuccessScreen from 'components/common/success-screen/SuccessScreen';
|
||||||
import TitleBreadcrumb from 'components/common/title-breadcrumb/title-breadcrumb.component';
|
import TitleBreadcrumb from 'components/common/title-breadcrumb/title-breadcrumb.component';
|
||||||
import IngestionStepper from 'components/IngestionStepper/IngestionStepper.component';
|
import IngestionStepper from 'components/IngestionStepper/IngestionStepper.component';
|
||||||
import { HTTP_STATUS_CODE } from 'constants/auth.constants';
|
import { HTTP_STATUS_CODE } from 'constants/auth.constants';
|
||||||
import { PAGE_SIZE_LARGE } from 'constants/constants';
|
|
||||||
import {
|
import {
|
||||||
STEPS_FOR_ADD_TEST_SUITE,
|
STEPS_FOR_ADD_TEST_SUITE,
|
||||||
TEST_SUITE_STEPPER_BREADCRUMB,
|
TEST_SUITE_STEPPER_BREADCRUMB,
|
||||||
} from 'constants/TestSuite.constant';
|
} from 'constants/TestSuite.constant';
|
||||||
import { FormSubmitType } from 'enums/form.enum';
|
import { FormSubmitType } from 'enums/form.enum';
|
||||||
import { OwnerType } from 'enums/user.enum';
|
import { OwnerType } from 'enums/user.enum';
|
||||||
import { TestCase } from 'generated/tests/testCase';
|
|
||||||
import { TestSuite } from 'generated/tests/testSuite';
|
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 { useTranslation } from 'react-i18next';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import {
|
import { addTestCaseToLogicalTestSuite, createTestSuites } from 'rest/testAPI';
|
||||||
addTestCaseToLogicalTestSuite,
|
|
||||||
createTestSuites,
|
|
||||||
getListTestCase,
|
|
||||||
} from 'rest/testAPI';
|
|
||||||
import { getCurrentUserId } from 'utils/CommonUtils';
|
import { getCurrentUserId } from 'utils/CommonUtils';
|
||||||
import { getEntityName } from 'utils/EntityUtils';
|
|
||||||
import { getTestSuitePath } from 'utils/RouterUtils';
|
import { getTestSuitePath } from 'utils/RouterUtils';
|
||||||
import { showErrorToast } from 'utils/ToastUtils';
|
import { showErrorToast } from 'utils/ToastUtils';
|
||||||
import AddTestSuiteForm from '../AddTestSuiteForm/AddTestSuiteForm';
|
import AddTestSuiteForm from '../AddTestSuiteForm/AddTestSuiteForm';
|
||||||
@ -48,11 +42,9 @@ const TestSuiteStepper = () => {
|
|||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const [activeServiceStep, setActiveServiceStep] = useState(1);
|
const [activeServiceStep, setActiveServiceStep] = useState(1);
|
||||||
const [testSuiteResponse, setTestSuiteResponse] = useState<TestSuite>();
|
const [testSuiteResponse, setTestSuiteResponse] = useState<TestSuite>();
|
||||||
const [testCases, setTestCases] = useState<TestCase[]>([]);
|
|
||||||
const [selectedTestCase, setSelectedTestCase] = useState<string[]>([]);
|
|
||||||
|
|
||||||
const handleViewTestSuiteClick = () => {
|
const handleViewTestSuiteClick = () => {
|
||||||
history.push(getTestSuitePath(testSuiteResponse?.fullyQualifiedName || ''));
|
history.push(getTestSuitePath(testSuiteResponse?.fullyQualifiedName ?? ''));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTestSuitNextClick = (data: TestSuite) => {
|
const handleTestSuitNextClick = (data: TestSuite) => {
|
||||||
@ -60,7 +52,7 @@ const TestSuiteStepper = () => {
|
|||||||
setActiveServiceStep(2);
|
setActiveServiceStep(2);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit = async (data: { testCase: string[] }) => {
|
const onSubmit = async (data: string[]) => {
|
||||||
try {
|
try {
|
||||||
const owner = {
|
const owner = {
|
||||||
id: getCurrentUserId(),
|
id: getCurrentUserId(),
|
||||||
@ -74,7 +66,7 @@ const TestSuiteStepper = () => {
|
|||||||
});
|
});
|
||||||
setTestSuiteResponse(response);
|
setTestSuiteResponse(response);
|
||||||
await addTestCaseToLogicalTestSuite({
|
await addTestCaseToLogicalTestSuite({
|
||||||
testCaseIds: data.testCase,
|
testCaseIds: data,
|
||||||
testSuiteId: response.id ?? '',
|
testSuiteId: response.id ?? '',
|
||||||
});
|
});
|
||||||
setActiveServiceStep(3);
|
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 (
|
|
||||||
<Form
|
|
||||||
data-testid="test-case-form"
|
|
||||||
initialValues={{ testCase: selectedTestCase }}
|
|
||||||
layout="vertical"
|
|
||||||
name="selectTestCase"
|
|
||||||
onFinish={onSubmit}
|
|
||||||
onValuesChange={({ testCase }) => setSelectedTestCase(testCase)}>
|
|
||||||
<Form.Item label={t('label.test-case-plural')} name="testCase">
|
|
||||||
<Select
|
|
||||||
mode="multiple"
|
|
||||||
placeholder={t('label.please-select-entity', {
|
|
||||||
entity: t('label.test-case-plural'),
|
|
||||||
})}>
|
|
||||||
{testCases.map((test) => (
|
|
||||||
<Select.Option key={test.id}>{getEntityName(test)}</Select.Option>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item noStyle>
|
|
||||||
<Space className="w-full justify-end" size={16}>
|
|
||||||
<Button
|
|
||||||
data-testid="back-button"
|
|
||||||
onClick={() => setActiveServiceStep(1)}>
|
|
||||||
{t('label.back')}
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
data-testid="submit-button"
|
|
||||||
htmlType="submit"
|
|
||||||
type="primary">
|
|
||||||
{t('label.submit')}
|
|
||||||
</Button>
|
|
||||||
</Space>
|
|
||||||
</Form.Item>
|
|
||||||
</Form>
|
|
||||||
);
|
|
||||||
}, [testCases, selectedTestCase, testSuiteResponse]);
|
|
||||||
|
|
||||||
const RenderSelectedTab = useCallback(() => {
|
const RenderSelectedTab = useCallback(() => {
|
||||||
if (activeServiceStep === 2) {
|
if (activeServiceStep === 2) {
|
||||||
return selectTestCase;
|
return (
|
||||||
|
<AddTestCaseList
|
||||||
|
cancelText={t('label.back')}
|
||||||
|
onCancel={() => setActiveServiceStep(1)}
|
||||||
|
onSubmit={onSubmit}
|
||||||
|
/>
|
||||||
|
);
|
||||||
} else if (activeServiceStep === 3) {
|
} else if (activeServiceStep === 3) {
|
||||||
return (
|
return (
|
||||||
<SuccessScreen
|
<SuccessScreen
|
||||||
|
@ -72,6 +72,10 @@ export const ELASTIC_SEARCH_INDEX_ENTITIES = [
|
|||||||
value: 'query',
|
value: 'query',
|
||||||
label: t('label.query'),
|
label: t('label.query'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
value: 'testCase',
|
||||||
|
label: t('label.test-case'),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const ELASTIC_SEARCH_INITIAL_VALUES = {
|
export const ELASTIC_SEARCH_INITIAL_VALUES = {
|
||||||
|
@ -11,9 +11,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Button, Col, Row, Space } from 'antd';
|
import { Button, Col, Modal, Row, Space } from 'antd';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import { AddTestCaseModal } from 'components/AddTestCaseModal/AddTestCaseModal.component';
|
import { AddTestCaseList } from 'components/AddTestCaseList/AddTestCaseList.component';
|
||||||
import { useAuthContext } from 'components/authentication/auth-provider/AuthProvider';
|
import { useAuthContext } from 'components/authentication/auth-provider/AuthProvider';
|
||||||
import Description from 'components/common/description/Description';
|
import Description from 'components/common/description/Description';
|
||||||
import ManageButton from 'components/common/entityPageInfo/ManageButton/ManageButton';
|
import ManageButton from 'components/common/entityPageInfo/ManageButton/ManageButton';
|
||||||
@ -38,6 +38,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useHistory, useParams } from 'react-router-dom';
|
import { useHistory, useParams } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
|
addTestCaseToLogicalTestSuite,
|
||||||
getListTestCase,
|
getListTestCase,
|
||||||
getTestSuiteByName,
|
getTestSuiteByName,
|
||||||
ListTestCaseParams,
|
ListTestCaseParams,
|
||||||
@ -154,6 +155,19 @@ const TestSuiteDetailsPage = () => {
|
|||||||
fetchTestCases();
|
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 () => {
|
const fetchTestSuiteByName = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await getTestSuiteByName(testSuiteFQN, {
|
const response = await getTestSuiteByName(testSuiteFQN, {
|
||||||
@ -309,11 +323,16 @@ const TestSuiteDetailsPage = () => {
|
|||||||
titleLinks={slashedBreadCrumb}
|
titleLinks={slashedBreadCrumb}
|
||||||
/>
|
/>
|
||||||
<Space>
|
<Space>
|
||||||
<Button
|
{(testSuitePermissions.EditAll ||
|
||||||
type="primary"
|
testSuitePermissions.EditTests) && (
|
||||||
onClick={() => setIsTestCaseModalOpen(true)}>
|
<Button
|
||||||
{t('label.add-entity', { entity: t('label.test-case-plural') })}
|
type="primary"
|
||||||
</Button>
|
onClick={() => setIsTestCaseModalOpen(true)}>
|
||||||
|
{t('label.add-entity', {
|
||||||
|
entity: t('label.test-case-plural'),
|
||||||
|
})}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
<ManageButton
|
<ManageButton
|
||||||
isRecursiveDelete
|
isRecursiveDelete
|
||||||
afterDeleteAction={afterDeleteAction}
|
afterDeleteAction={afterDeleteAction}
|
||||||
@ -366,13 +385,22 @@ const TestSuiteDetailsPage = () => {
|
|||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
<AddTestCaseModal
|
<Modal
|
||||||
existingTest={testSuite?.tests ?? []}
|
centered
|
||||||
|
destroyOnClose
|
||||||
|
closable={false}
|
||||||
|
footer={null}
|
||||||
open={isTestCaseModalOpen}
|
open={isTestCaseModalOpen}
|
||||||
testSuiteId={testSuite?.id ?? ''}
|
title={t('label.add-entity', {
|
||||||
onCancel={() => setIsTestCaseModalOpen(false)}
|
entity: t('label.test-case-plural'),
|
||||||
onSubmit={afterSubmitAction}
|
})}
|
||||||
/>
|
width={750}>
|
||||||
|
<AddTestCaseList
|
||||||
|
existingTest={testSuite?.tests ?? []}
|
||||||
|
onCancel={() => setIsTestCaseModalOpen(false)}
|
||||||
|
onSubmit={handleAddTestCaseSubmit}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</PageLayoutV1>
|
</PageLayoutV1>
|
||||||
|
@ -113,6 +113,16 @@ export const getTestCaseByFqn = async (
|
|||||||
|
|
||||||
return response;
|
return response;
|
||||||
};
|
};
|
||||||
|
export const getTestCaseById = async (
|
||||||
|
id: string,
|
||||||
|
params?: Pick<ListParams, 'fields' | 'include'>
|
||||||
|
) => {
|
||||||
|
const response = await APIClient.get<TestCase>(`${testCaseUrl}/${id}`, {
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
||||||
export const createTestCase = async (data: CreateTestCase) => {
|
export const createTestCase = async (data: CreateTestCase) => {
|
||||||
const response = await APIClient.post<
|
const response = await APIClient.post<
|
||||||
|
Loading…
x
Reference in New Issue
Block a user