cypress: added cypress for incident manager (#14824)

* cypress: added cypress for incident manager

* fixed failing cypress
This commit is contained in:
Shailesh Parmar 2024-01-24 09:57:28 +05:30 committed by GitHub
parent 9f5a70bd71
commit 569c668117
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 306 additions and 197 deletions

View File

@ -96,7 +96,7 @@ const createCustomMetric = ({
cy.get('[data-testid="custom-metric"]').click();
// validate redirection and cancel button
cy.get('[data-testid="heading"]').should('be.visible');
cy.get('[data-testid="heading"]').first().should('be.visible');
cy.get(
`[data-testid=${
isColumnMetric
@ -108,6 +108,7 @@ const createCustomMetric = ({
verifyResponseStatusCode('@getCustomMetric', 200);
cy.url().should('include', 'profiler');
cy.get('[data-testid="heading"]')
.first()
.invoke('text')
.should('equal', isColumnMetric ? 'Column Profile' : 'Table Profile');
@ -133,6 +134,7 @@ const createCustomMetric = ({
// verify the created custom metric
cy.url().should('include', 'profiler');
cy.get('[data-testid="heading"]')
.first()
.invoke('text')
.should('equal', isColumnMetric ? 'Column Profile' : 'Table Profile');
cy.get(`[data-testid="${metric.name}-custom-metrics"]`)

View File

@ -11,18 +11,30 @@
* limitations under the License.
*/
import {
descriptionBox,
interceptURL,
scheduleIngestion,
verifyResponseStatusCode,
visitEntityDetailsPage,
} from '../../common/common';
import { createEntityTableViaREST } from '../../common/Utils/Entity';
import { DATA_ASSETS, NEW_TABLE_TEST_CASE } from '../../constants/constants';
import { SidebarItem } from '../../constants/Entity.interface';
import {
createEntityTableViaREST,
deleteEntityViaREST,
} from '../../common/Utils/Entity';
import { DATA_ASSETS, uuid } from '../../constants/constants';
import { EntityType, SidebarItem } from '../../constants/Entity.interface';
import { DATABASE_SERVICE } from '../../constants/EntityConstant';
const TABLE_NAME = DATABASE_SERVICE.entity.name;
const testSuite = {
name: `${DATABASE_SERVICE.entity.databaseSchema}.${DATABASE_SERVICE.entity.name}.testSuite`,
executableEntityReference: `${DATABASE_SERVICE.entity.databaseSchema}.${DATABASE_SERVICE.entity.name}`,
};
const testCases = [
`cy_first_table_column_count_to_be_between_${uuid()}`,
`cy_second_table_column_count_to_be_between_${uuid()}`,
`cy_third_table_column_count_to_be_between_${uuid()}`,
];
const goToProfilerTab = () => {
interceptURL(
'GET',
@ -47,8 +59,9 @@ const acknowledgeTask = (testCase) => {
.click();
cy.get(`[data-testid="${testCase}"]`)
.find('.last-run-box.failed')
.scrollIntoView()
.should('be.visible');
cy.get('.ant-table-row-level-0').should('contain', 'New');
cy.get(`[data-testid="${testCase}-status"]`).should('contain', 'New');
cy.get(`[data-testid="${testCase}"]`).contains(testCase).click();
cy.get('[data-testid="edit-resolution-icon"]').click();
cy.get('[data-testid="test-case-resolution-status-type"]').click();
@ -63,9 +76,72 @@ const acknowledgeTask = (testCase) => {
cy.get(`[data-testid="${testCase}-status"]`).should('contain', 'Ack');
};
const triggerTestCasePipeline = () => {
interceptURL('GET', `/api/v1/tables/*/systemProfile?*`, 'systemProfile');
interceptURL('GET', `/api/v1/tables/*/tableProfile?*`, 'tableProfile');
goToProfilerTab();
interceptURL(
'GET',
`api/v1/tables/name/${DATABASE_SERVICE.service.name}.*.${TABLE_NAME}?include=all`,
'addTableTestPage'
);
verifyResponseStatusCode('@systemProfile', 200);
verifyResponseStatusCode('@tableProfile', 200);
interceptURL('GET', '/api/v1/dataQuality/testCases?fields=*', 'testCase');
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.click();
verifyResponseStatusCode('@testCase', 200);
interceptURL(
'GET',
'/api/v1/services/ingestionPipelines/*/pipelineStatus?startTs=*&endTs=*',
'getPipelineStatus'
);
interceptURL(
'POST',
'/api/v1/services/ingestionPipelines/trigger/*',
'triggerPipeline'
);
cy.get('[id*="tab-pipeline"]').click();
verifyResponseStatusCode('@getPipelineStatus', 200);
cy.get('[data-testid="run"]').click();
cy.wait('@triggerPipeline');
};
const assignIncident = (testCaseName) => {
cy.sidebarClick(SidebarItem.INCIDENT_MANAGER);
cy.get(`[data-testid="test-case-${testCaseName}"]`).should('be.visible');
cy.get(`[data-testid="${testCaseName}-status"]`)
.find(`[data-testid="edit-resolution-icon"]`)
.click();
cy.get(`[data-testid="test-case-resolution-status-type"]`).click();
cy.get(`[title="Assigned"]`).click();
cy.get('#testCaseResolutionStatusDetails_assignee').should('be.visible');
interceptURL(
'GET',
'/api/v1/search/suggest?q=Aaron%20Johnson&index=user_search_index',
'searchAssignee'
);
cy.get('#testCaseResolutionStatusDetails_assignee').type('Aaron Johnson');
verifyResponseStatusCode('@searchAssignee', 200);
cy.get('[data-testid="aaron_johnson0"]').click();
interceptURL(
'POST',
'/api/v1/dataQuality/testCases/testCaseIncidentStatus',
'updateTestCaseIncidentStatus'
);
cy.get('#update-status-button').click();
verifyResponseStatusCode('@updateTestCaseIncidentStatus', 200);
cy.get(
`[data-testid="${testCaseName}-status"] [data-testid="badge-container"]`
).should('contain', 'Assigned');
};
describe('Incident Manager', () => {
before(() => {
cy.login();
cy.getAllLocalStorage().then((data) => {
const token = Object.values(data)[0].oidcIdToken;
@ -74,109 +150,90 @@ describe('Incident Manager', () => {
...DATABASE_SERVICE,
tables: [DATABASE_SERVICE.entity],
});
// create testSuite
cy.request({
method: 'POST',
url: `/api/v1/dataQuality/testSuites/executable`,
headers: { Authorization: `Bearer ${token}` },
body: testSuite,
}).then((testSuiteResponse) => {
// creating test case
testCases.forEach((testCase) => {
cy.request({
method: 'POST',
url: `/api/v1/dataQuality/testCases`,
headers: { Authorization: `Bearer ${token}` },
body: {
name: testCase,
entityLink: `<#E::table::${testSuite.executableEntityReference}>`,
parameterValues: [
{ name: 'minColValue', value: 12 },
{ name: 'maxColValue', value: 24 },
],
testDefinition: 'tableColumnCountToBeBetween',
testSuite: testSuite.name,
},
});
});
cy.request({
method: 'POST',
url: `/api/v1/services/ingestionPipelines`,
headers: { Authorization: `Bearer ${token}` },
body: {
airflowConfig: {},
name: `${testSuite.executableEntityReference}_test_suite`,
pipelineType: 'TestSuite',
service: {
id: testSuiteResponse.body.id,
type: 'testSuite',
},
sourceConfig: {
config: {
type: 'TestSuite',
entityFullyQualifiedName: testSuite.executableEntityReference,
},
},
},
}).then((response) =>
cy.request({
method: 'POST',
url: `/api/v1/services/ingestionPipelines/deploy/${response.body.id}`,
headers: { Authorization: `Bearer ${token}` },
})
);
});
});
triggerTestCasePipeline();
});
after(() => {
cy.login();
cy.getAllLocalStorage().then((data) => {
const token = Object.values(data)[0].oidcIdToken;
deleteEntityViaREST({
token,
endPoint: EntityType.DatabaseService,
entityName: DATABASE_SERVICE.service.name,
});
});
});
describe('Basic Scenario', () => {
const testCaseName = testCases[0];
beforeEach(() => {
cy.login();
interceptURL('GET', `/api/v1/tables/*/systemProfile?*`, 'systemProfile');
interceptURL('GET', `/api/v1/tables/*/tableProfile?*`, 'tableProfile');
});
it('Add table test case', () => {
const term = TABLE_NAME;
goToProfilerTab();
interceptURL(
'GET',
`api/v1/tables/name/${DATABASE_SERVICE.service.name}.*.${term}?include=all`,
'addTableTestPage'
);
verifyResponseStatusCode('@systemProfile', 200);
verifyResponseStatusCode('@tableProfile', 200);
interceptURL('GET', '/api/v1/dataQuality/testCases?fields=*', 'testCase');
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.click();
verifyResponseStatusCode('@testCase', 200);
cy.get('[data-testid="profiler-add-table-test-btn"]').click();
cy.get('[data-testid="table"]').click();
// creating new test case
cy.get('#tableTestForm_testTypeId').scrollIntoView().click();
cy.contains(NEW_TABLE_TEST_CASE.label).should('be.visible').click();
cy.get('#tableTestForm_testName').type(NEW_TABLE_TEST_CASE.name);
cy.get('#tableTestForm_params_columnName').type(
NEW_TABLE_TEST_CASE.field
);
cy.get(descriptionBox).scrollIntoView();
cy.get(descriptionBox).type(NEW_TABLE_TEST_CASE.description);
cy.get('[data-testid="submit-test"]').scrollIntoView().click();
cy.get('[data-testid="success-line"]')
.scrollIntoView()
.should('be.visible');
cy.get('[data-testid="add-ingestion-button"]').click();
scheduleIngestion(false);
cy.get('[data-testid="success-line"]')
.scrollIntoView()
.should('be.visible');
cy.get('[data-testid="view-service-button"]').click({ force: true });
verifyResponseStatusCode('@getEntityDetails', 200);
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.click();
verifyResponseStatusCode('@testCase', 200);
cy.contains(NEW_TABLE_TEST_CASE.name).should('be.visible');
interceptURL(
'GET',
'/api/v1/services/ingestionPipelines/*/pipelineStatus?startTs=*&endTs=*',
'getPipelineStatus'
);
cy.get('[id*="tab-pipeline"]').click();
verifyResponseStatusCode('@getPipelineStatus', 200);
cy.get('[data-testid="run"]').click();
});
it("Acknowledge table test case's failure", () => {
acknowledgeTask(NEW_TABLE_TEST_CASE.name);
acknowledgeTask(testCaseName);
});
it('Assign incident to user', () => {
cy.sidebarClick(SidebarItem.INCIDENT_MANAGER);
cy.get(`[data-testid="test-case-${NEW_TABLE_TEST_CASE.name}"]`).should(
'be.visible'
);
cy.get(`[data-testid="${NEW_TABLE_TEST_CASE.name}-status"]`)
.find(`[data-testid="edit-resolution-icon"]`)
.click();
cy.get(`[data-testid="test-case-resolution-status-type"]`).click();
cy.get(`[title="Assigned"]`).click();
cy.get('#testCaseResolutionStatusDetails_assignee').should('be.visible');
interceptURL(
'GET',
'/api/v1/search/suggest?q=Aaron%20Johnson&index=user_search_index',
'searchAssignee'
);
cy.get('#testCaseResolutionStatusDetails_assignee').type('Aaron Johnson');
verifyResponseStatusCode('@searchAssignee', 200);
cy.get('[data-testid="aaron_johnson0"]').click();
interceptURL(
'POST',
'/api/v1/dataQuality/testCases/testCaseIncidentStatus',
'updateTestCaseIncidentStatus'
);
cy.get('#update-status-button').click();
verifyResponseStatusCode('@updateTestCaseIncidentStatus', 200);
cy.get(
`[data-testid="${NEW_TABLE_TEST_CASE.name}-status"] [data-testid="badge-container"]`
).should('contain', 'Assigned');
assignIncident(testCaseName);
});
it('Re-assign incident to user', () => {
@ -186,10 +243,8 @@ describe('Incident Manager', () => {
'getTestCase'
);
interceptURL('GET', '/api/v1/feed?entityLink=*&type=Task', 'getTaskFeed');
cy.sidebarClick(SidebarItem.INCIDENT_MANAGER);
cy.get(`[data-testid="test-case-${NEW_TABLE_TEST_CASE.name}"]`).click();
cy.get(`[data-testid="test-case-${testCaseName}"]`).click();
verifyResponseStatusCode('@getTestCase', 200);
cy.get('[data-testid="incident"]').click();
verifyResponseStatusCode('@getTaskFeed', 200);
@ -226,7 +281,7 @@ describe('Incident Manager', () => {
);
interceptURL('GET', '/api/v1/feed?entityLink=*&type=Task', 'getTaskFeed');
cy.sidebarClick(SidebarItem.INCIDENT_MANAGER);
cy.get(`[data-testid="test-case-${NEW_TABLE_TEST_CASE.name}"]`).click();
cy.get(`[data-testid="test-case-${testCaseName}"]`).click();
verifyResponseStatusCode('@getTestCase', 200);
cy.get('[data-testid="incident"]').click();
verifyResponseStatusCode('@getTaskFeed', 200);
@ -246,68 +301,11 @@ describe('Incident Manager', () => {
});
});
describe('Resolving task from the Incident List Page', () => {
const testName = `${NEW_TABLE_TEST_CASE.name}_new_name`;
describe('Resolving incident & re-run pipeline', () => {
const testName = testCases[1];
beforeEach(() => {
cy.login();
interceptURL('GET', `/api/v1/tables/*/systemProfile?*`, 'systemProfile');
interceptURL('GET', `/api/v1/tables/*/tableProfile?*`, 'tableProfile');
});
it('Add table test case', () => {
const term = TABLE_NAME;
goToProfilerTab();
interceptURL(
'GET',
`api/v1/tables/name/${DATABASE_SERVICE.service.name}.*.${term}?include=all`,
'addTableTestPage'
);
verifyResponseStatusCode('@systemProfile', 200);
verifyResponseStatusCode('@tableProfile', 200);
interceptURL('GET', '/api/v1/dataQuality/testCases?fields=*', 'testCase');
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.click();
verifyResponseStatusCode('@testCase', 200);
cy.get('[data-testid="profiler-add-table-test-btn"]').click();
cy.get('[data-testid="table"]').click();
// creating new test case
cy.get('#tableTestForm_testTypeId').scrollIntoView().click();
cy.contains(NEW_TABLE_TEST_CASE.label).should('be.visible').click();
cy.get('#tableTestForm_testName').type(testName);
cy.get('#tableTestForm_params_columnName').type(
NEW_TABLE_TEST_CASE.field
);
cy.get(descriptionBox).scrollIntoView();
cy.get(descriptionBox).type(NEW_TABLE_TEST_CASE.description);
cy.get('[data-testid="submit-test"]').scrollIntoView().click();
cy.get('[data-testid="success-line"]')
.scrollIntoView()
.should('be.visible');
cy.get('[data-testid="view-service-button"]').click({ force: true });
verifyResponseStatusCode('@getEntityDetails', 200);
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.click();
verifyResponseStatusCode('@testCase', 200);
cy.contains(testName).should('be.visible');
interceptURL(
'GET',
'/api/v1/services/ingestionPipelines/*/pipelineStatus?startTs=*&endTs=*',
'getPipelineStatus'
);
cy.get('[id*="tab-pipeline"]').click();
verifyResponseStatusCode('@getPipelineStatus', 200);
cy.get('[data-testid="run"]').click();
});
it("Acknowledge table test case's failure", () => {
@ -328,8 +326,9 @@ describe('Incident Manager', () => {
verifyResponseStatusCode('@testCaseList', 200);
cy.get(`[data-testid="${testName}"]`)
.find('.last-run-box.failed')
.scrollIntoView()
.should('be.visible');
cy.get('.ant-table-row-level-0').should('contain', 'New');
cy.get('.ant-table-row-level-0').should('contain', 'Ack');
interceptURL(
'GET',
'/api/v1/dataQuality/testCases/testCaseIncidentStatus?latest=true&startTs=*&endTs=*&limit=*',
@ -378,6 +377,7 @@ describe('Incident Manager', () => {
verifyResponseStatusCode('@testCaseList', 200);
cy.get(`[data-testid="${testName}"]`)
.find('.last-run-box.failed')
.scrollIntoView()
.should('be.visible');
cy.get(`[data-testid="${testName}"]`).contains(testName).click();
@ -391,5 +391,84 @@ describe('Incident Manager', () => {
'Resolved the Task.'
);
});
it('Re-run pipeline', () => {
triggerTestCasePipeline();
});
it('Verify open and closed task', () => {
acknowledgeTask(testName);
interceptURL(
'GET',
'/api/v1/dataQuality/testCases/name/*?fields=*',
'getTestCase'
);
interceptURL('GET', '/api/v1/feed?entityLink=*&type=Task', 'getTaskFeed');
cy.reload();
verifyResponseStatusCode('@getTestCase', 200);
cy.get('[data-testid="incident"]').click();
verifyResponseStatusCode('@getTaskFeed', 200);
cy.get('[data-testid="open-task"]')
.invoke('text')
.then((text) => {
expect(text.trim()).equal('1 Open');
});
cy.get('[data-testid="closed-task"]')
.invoke('text')
.then((text) => {
expect(text.trim()).equal('1 Closed');
});
});
});
describe('Rerunning pipeline for an open incident', () => {
const testName = testCases[2];
beforeEach(() => {
cy.login();
});
it('Ack incident and verify open task', () => {
acknowledgeTask(testName);
interceptURL(
'GET',
'/api/v1/dataQuality/testCases/name/*?fields=*',
'getTestCase'
);
interceptURL('GET', '/api/v1/feed?entityLink=*&type=Task', 'getTaskFeed');
cy.reload();
verifyResponseStatusCode('@getTestCase', 200);
cy.get('[data-testid="incident"]').click();
verifyResponseStatusCode('@getTaskFeed', 200);
cy.get('[data-testid="open-task"]')
.invoke('text')
.then((text) => {
expect(text.trim()).equal('1 Open');
});
});
it('Assign incident to user', () => {
assignIncident(testName);
});
it('Re-run pipeline', () => {
triggerTestCasePipeline();
});
it("Verify incident's status on DQ page", () => {
goToProfilerTab();
cy.get('[data-testid="profiler-tab-left-panel"]')
.contains('Data Quality')
.click();
cy.get(`[data-testid="${testName}"]`)
.find('.last-run-box.failed')
.scrollIntoView()
.should('be.visible');
cy.get(`[data-testid="${testName}-status"]`).should(
'contain',
'Assigned'
);
});
});
});

View File

@ -247,10 +247,15 @@ const DataQualityTab: React.FC<DataQualityTabProps> = ({
: ''
}`
}>
<AppBadge
className={classNames('resolution', label.toLocaleLowerCase())}
label={label}
/>
<span data-testid={`${record.name}-status`}>
<AppBadge
className={classNames(
'resolution',
label.toLocaleLowerCase()
)}
label={label}
/>
</span>
</Tooltip>
) : (
'--'

View File

@ -37,6 +37,7 @@ import {
import { ReactComponent as IconDropdown } from '../../../assets/svg/menu.svg';
import { GRAPH_BACKGROUND_COLOR } from '../../../constants/constants';
import { TOTAL_ENTITY_CHART_COLOR } from '../../../constants/DataInsight.constants';
import { PAGE_HEADERS } from '../../../constants/PageHeaders.constant';
import { EntityType } from '../../../enums/entity.enum';
import { CustomMetric } from '../../../generated/entity/data/table';
import {
@ -49,6 +50,7 @@ import { showErrorToast, showSuccessToast } from '../../../utils/ToastUtils';
import DeleteWidgetModal from '../../common/DeleteWidget/DeleteWidgetModal';
import ErrorPlaceHolder from '../../common/ErrorWithPlaceholder/ErrorPlaceHolder';
import CustomMetricForm from '../../CustomMetricForm/CustomMetricForm.component';
import PageHeader from '../../PageHeader/PageHeader.component';
import ProfilerLatestValue from '../../ProfilerDashboard/component/ProfilerLatestValue';
import { useTableProfiler } from '../TableProfilerProvider';
import './custom-metric-graphs.style.less';
@ -169,6 +171,11 @@ const CustomMetricGraphs = ({
return (
<Row data-testid="custom-metric-graph-container" gutter={[16, 16]}>
{!isEmpty(customMetricsGraphData) && (
<Col span={24}>
<PageHeader data={PAGE_HEADERS.CUSTOM_METRICS} />
</Col>
)}
{toPairs(customMetricsGraphData).map(([key, metric], i) => {
const color = TOTAL_ENTITY_CHART_COLOR[i] ?? getRandomHexColor();
@ -196,18 +203,14 @@ const CustomMetricGraphs = ({
) : null
}
loading={isLoading}
title={
<Typography.Title level={5}>
{t('label.custom-metric')}
</Typography.Title>
}>
title={<Typography.Title level={5}>{key}</Typography.Title>}>
<Row gutter={[16, 16]}>
<Col span={4}>
<ProfilerLatestValue
information={[
{
latestValue: last(metric)?.[key] ?? '--',
title: key,
title: '',
dataKey: key,
color,
},

View File

@ -11,6 +11,7 @@
* limitations under the License.
*/
import { Col, Menu, MenuProps, Row, Space } from 'antd';
import { ItemType } from 'antd/lib/menu/hooks/useItems';
import Qs from 'qs';
import React, { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
@ -54,7 +55,7 @@ const TableProfiler = (props: TableProfilerProps) => {
};
}, [props.permissions]);
const tabOptions = useMemo(
const tabOptions: ItemType[] = useMemo(
() => [
{
label: t('label.table-entity-text', {

View File

@ -12,7 +12,7 @@
*/
import { Col, Row, Space, Steps, Typography } from 'antd';
import { isEmpty, isUndefined, last, toLower } from 'lodash';
import React, { useMemo } from 'react';
import React, { ReactNode, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { NO_DATA_PLACEHOLDER } from '../../../constants/constants';
import { TEST_CASE_STATUS } from '../../../constants/TestSuite.constant';
@ -45,27 +45,41 @@ const TaskTabIncidentManagerHeader = ({ thread }: { thread: Thread }) => {
}
return updatedData.map((status) => {
const assigneeDetail =
TestCaseResolutionStatusTypes.Assigned ===
status.testCaseResolutionStatusType &&
status.testCaseResolutionStatusDetails?.assignee ? (
<Typography.Text className="text-grey-muted text-xss">
{`To ${getEntityName(
status.testCaseResolutionStatusDetails?.assignee
)} on `}
</Typography.Text>
) : null;
let details: ReactNode = null;
const resolvedDetail =
TestCaseResolutionStatusTypes.Resolved ===
status.testCaseResolutionStatusType &&
status.testCaseResolutionStatusDetails?.resolvedBy ? (
<Typography.Text className="text-grey-muted text-xss">
{`By ${getEntityName(
status.testCaseResolutionStatusDetails.resolvedBy
)} on `}
</Typography.Text>
) : null;
switch (status.testCaseResolutionStatusType) {
case TestCaseResolutionStatusTypes.ACK:
details = status.updatedBy ? (
<Typography.Text className="text-grey-muted text-xss">
{`By ${getEntityName(status.updatedBy)} on `}
</Typography.Text>
) : null;
break;
case TestCaseResolutionStatusTypes.Assigned:
details = status.testCaseResolutionStatusDetails?.assignee ? (
<Typography.Text className="text-grey-muted text-xss">
{`To ${getEntityName(
status.testCaseResolutionStatusDetails?.assignee
)} on `}
</Typography.Text>
) : null;
break;
case TestCaseResolutionStatusTypes.Resolved:
details = status.testCaseResolutionStatusDetails?.resolvedBy ? (
<Typography.Text className="text-grey-muted text-xss">
{`By ${getEntityName(
status.testCaseResolutionStatusDetails.resolvedBy
)} on `}
</Typography.Text>
) : null;
break;
default:
break;
}
return {
className: toLower(status.testCaseResolutionStatusType),
@ -75,8 +89,7 @@ const TaskTabIncidentManagerHeader = ({ thread }: { thread: Thread }) => {
{status.testCaseResolutionStatusType}
</Typography.Paragraph>
<Typography.Paragraph className="m-b-0">
{assigneeDetail}
{resolvedDetail}
{details}
{status.updatedAt && (
<Typography.Text className="text-grey-muted text-xss">
{formatDateTime(status.updatedAt)}

View File

@ -123,7 +123,8 @@ const DeleteWidgetModal = ({
const isDeleteTextPresent = useMemo(() => {
return (
deleteConfirmationText.toLowerCase() === DELETE_CONFIRMATION_TEXT.toLowerCase() &&
deleteConfirmationText.toLowerCase() ===
DELETE_CONFIRMATION_TEXT.toLowerCase() &&
(deletionType === DeleteType.SOFT_DELETE ||
deletionType === DeleteType.HARD_DELETE)
);

View File

@ -174,4 +174,9 @@ export const PAGE_HEADERS = {
header: i18n.t('label.incident-manager'),
subHeader: i18n.t('message.page-sub-header-for-data-quality'),
},
CUSTOM_METRICS: {
header: i18n.t('label.custom-metric'),
// Todo: need to update message once @harshach provides the message
subHeader: '',
},
};