diff --git a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestSuite/TestSuiteList/TestSuites.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestSuite/TestSuiteList/TestSuites.component.tsx index 8966f7595f3..76d815f7970 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestSuite/TestSuiteList/TestSuites.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/DataQuality/TestSuite/TestSuiteList/TestSuites.component.tsx @@ -173,6 +173,7 @@ export const TestSuites = () => { { title: `${t('label.success')} %`, dataIndex: 'summary', + width: 200, key: 'success', render: (value: TestSuite['summary']) => { const percent = diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/DataQualityTab/DataQualityTab.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/DataQualityTab/DataQualityTab.tsx index beb098d0e13..4312875c066 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/DataQualityTab/DataQualityTab.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/DataQualityTab/DataQualityTab.tsx @@ -41,7 +41,7 @@ import { removeTestCaseFromTestSuite } from '../../../../rest/testAPI'; import { getNameFromFQN, Transi18next } from '../../../../utils/CommonUtils'; import { formatDate, - formatDateTime, + formatDateTimeLong, } from '../../../../utils/date-time/DateTimeUtils'; import { getColumnNameFromEntityLink, @@ -254,7 +254,7 @@ const DataQualityTab: React.FC = ({ width: 150, sorter: true, render: (result: TestCaseResult) => - result?.timestamp ? formatDateTime(result.timestamp) : '--', + result?.timestamp ? formatDateTimeLong(result.timestamp) : '--', }, { title: t('label.incident'), diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/ProfilerDetailsCard/ProfilerDetailsCard.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/ProfilerDetailsCard/ProfilerDetailsCard.test.tsx index a2b5b026c6c..f02ee55e8d3 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/ProfilerDetailsCard/ProfilerDetailsCard.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/ProfilerDetailsCard/ProfilerDetailsCard.test.tsx @@ -13,31 +13,42 @@ import { queryByAttribute, render, screen } from '@testing-library/react'; import React from 'react'; -import { MOCK_CHART_COLLECTION_DATA } from '../../../../mocks/TestSuite.mock'; import { ProfilerDetailsCardProps } from '../ProfilerDashboard/profilerDashboard.interface'; import ProfilerDetailsCard from './ProfilerDetailsCard'; +// Mock utility functions +jest.mock('../../../../utils/ChartUtils', () => ({ + axisTickFormatter: jest.fn(), + tooltipFormatter: jest.fn(), + updateActiveChartFilter: jest.fn(), +})); + +jest.mock('../../../../utils/date-time/DateTimeUtils', () => ({ + formatDateTimeLong: jest.fn(), +})); + +// Existing mocks +jest.mock('../ProfilerLatestValue/ProfilerLatestValue', () => + jest.fn(() =>
ProfilerLatestValue
) +); + +jest.mock('../../../common/ErrorWithPlaceholder/ErrorPlaceHolder', () => + jest.fn(() =>
ErrorPlaceHolder
) +); + +jest.mock('../../../../utils/DataInsightUtils', () => ({ + CustomTooltip: jest.fn(() =>
CustomTooltip
), +})); + +// Improve mock data to be minimal const mockProps: ProfilerDetailsCardProps = { - chartCollection: MOCK_CHART_COLLECTION_DATA, + chartCollection: { + data: [{ name: 'test', value: 1 }], + information: [{ dataKey: 'value', title: 'Test', color: '#000' }], + }, name: 'rowCount', }; -jest.mock('../ProfilerLatestValue/ProfilerLatestValue', () => { - return jest.fn().mockImplementation(() => { - return
ProfilerLatestValue
; - }); -}); -jest.mock('../../../common/ErrorWithPlaceholder/ErrorPlaceHolder', () => { - return jest.fn().mockImplementation(() => { - return
ErrorPlaceHolder
; - }); -}); -jest.mock('../../../../utils/DataInsightUtils', () => { - return jest.fn().mockImplementation(() => { - return
CustomTooltip
; - }); -}); - describe('ProfilerDetailsCard Test', () => { it('Component should render', async () => { const { container } = render(); diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/ProfilerDetailsCard/ProfilerDetailsCard.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/ProfilerDetailsCard/ProfilerDetailsCard.tsx index d6c0d28db47..7229818b0f7 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/ProfilerDetailsCard/ProfilerDetailsCard.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/ProfilerDetailsCard/ProfilerDetailsCard.tsx @@ -31,7 +31,7 @@ import { updateActiveChartFilter, } from '../../../../utils/ChartUtils'; import { CustomTooltip } from '../../../../utils/DataInsightUtils'; -import { formatDateTime } from '../../../../utils/date-time/DateTimeUtils'; +import { formatDateTimeLong } from '../../../../utils/date-time/DateTimeUtils'; import ErrorPlaceHolder from '../../../common/ErrorWithPlaceholder/ErrorPlaceHolder'; import { ProfilerDetailsCardProps } from '../ProfilerDashboard/profilerDashboard.interface'; import ProfilerLatestValue from '../ProfilerLatestValue/ProfilerLatestValue'; @@ -98,7 +98,7 @@ const ProfilerDetailsCard: React.FC = ({ tooltipFormatter(value, tickFormatter) diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/CustomMetricGraphs/CustomMetricGraphs.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/CustomMetricGraphs/CustomMetricGraphs.component.tsx index 05410904ad6..84a543db927 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/CustomMetricGraphs/CustomMetricGraphs.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TableProfiler/CustomMetricGraphs/CustomMetricGraphs.component.tsx @@ -52,7 +52,7 @@ import { CustomTooltip, getRandomHexColor, } from '../../../../../utils/DataInsightUtils'; -import { formatDateTime } from '../../../../../utils/date-time/DateTimeUtils'; +import { formatDateTimeLong } from '../../../../../utils/date-time/DateTimeUtils'; import { showErrorToast, showSuccessToast, @@ -268,7 +268,7 @@ const CustomMetricGraphs = ({ tooltipFormatter(value) diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TestSummaryCustomTooltip/TestSummaryCustomTooltip.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TestSummaryCustomTooltip/TestSummaryCustomTooltip.component.tsx index 2f77b7678f8..b2f11226822 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TestSummaryCustomTooltip/TestSummaryCustomTooltip.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TestSummaryCustomTooltip/TestSummaryCustomTooltip.component.tsx @@ -20,7 +20,7 @@ import { TABLE_FRESHNESS_KEY } from '../../../../constants/TestSuite.constant'; import { Thread } from '../../../../generated/entity/feed/thread'; import { convertMillisecondsToHumanReadableFormat, - formatDateTime, + formatDateTimeLong, } from '../../../../utils/date-time/DateTimeUtils'; import { getTaskDetailPath } from '../../../../utils/TasksUtils'; import { OwnerLabel } from '../../../common/OwnerLabel/OwnerLabel.component'; @@ -95,7 +95,7 @@ const TestSummaryCustomTooltip = ( - {formatDateTime(payload[0].payload.name)} + {formatDateTimeLong(payload[0].payload.name)} }>
    diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TestSummaryCustomTooltip/TestSummaryCustomTooltip.test.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TestSummaryCustomTooltip/TestSummaryCustomTooltip.test.tsx index 68f4fe010ae..acd00b5411c 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TestSummaryCustomTooltip/TestSummaryCustomTooltip.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Database/Profiler/TestSummaryCustomTooltip/TestSummaryCustomTooltip.test.tsx @@ -39,7 +39,9 @@ const mockProps = { ], }; jest.mock('../../../../utils/date-time/DateTimeUtils', () => ({ - formatDateTime: jest.fn().mockReturnValue('Jan 3, 2024, 6:45 PM'), + formatDateTimeLong: jest + .fn() + .mockReturnValue('Jan 3, 2024, 6:45 PM (UTC+05:30)'), })); jest.mock('../../../../utils/TasksUtils', () => ({ diff --git a/openmetadata-ui/src/main/resources/ui/src/components/IncidentManager/IncidentManager.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/IncidentManager/IncidentManager.component.tsx index 524444654b6..f0daf6d00a9 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/IncidentManager/IncidentManager.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/IncidentManager/IncidentManager.component.tsx @@ -57,7 +57,7 @@ import { getPartialNameFromTableFQN, } from '../../utils/CommonUtils'; import { - formatDateTime, + formatDateTimeLong, getCurrentMillis, getEpochMillisForPastDays, } from '../../utils/date-time/DateTimeUtils'; @@ -468,8 +468,8 @@ const IncidentManager = ({ title: t('label.execution-time'), dataIndex: 'timestamp', key: 'timestamp', - width: 150, - render: (value: number) => (value ? formatDateTime(value) : '--'), + width: 200, + render: (value: number) => (value ? formatDateTimeLong(value) : '--'), }, { title: t('label.status'), @@ -500,7 +500,7 @@ const IncidentManager = ({ title: t('label.severity'), dataIndex: 'severity', key: 'severity', - width: 150, + width: 100, render: (value: Severities, record: TestCaseResolutionStatus) => { if (isPermissionLoading) { return ; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/Ingestion/IngestionRecentRun/IngestionRecentRuns.component.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/Ingestion/IngestionRecentRun/IngestionRecentRuns.component.tsx index 241b6dffd0c..c19e90627f7 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/Ingestion/IngestionRecentRun/IngestionRecentRuns.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/Ingestion/IngestionRecentRun/IngestionRecentRuns.component.tsx @@ -20,7 +20,7 @@ import { NO_DATA_PLACEHOLDER } from '../../../../../constants/constants'; import { PipelineStatus } from '../../../../../generated/entity/services/ingestionPipelines/ingestionPipeline'; import { getRunHistoryForPipeline } from '../../../../../rest/ingestionPipelineAPI'; import { - formatDateTime, + formatDateTimeLong, getCurrentMillis, getEpochMillisForPastDays, } from '../../../../../utils/date-time/DateTimeUtils'; @@ -128,18 +128,19 @@ export const IngestionRecentRuns = ({ {r.timestamp && (

    {`${t('label.execution-date')}:`}{' '} - {formatDateTime(r.timestamp)} + {formatDateTimeLong(r.timestamp)}

    )} {r.startDate && (

    {t('label.start-entity', { entity: t('label.date') })}:{' '} - {formatDateTime(r.startDate)} + {formatDateTimeLong(r.startDate)}

    )} {r.endDate && (

    - {`${t('label.end-date')}:`} {formatDateTime(r.endDate)} + {`${t('label.end-date')}:`}{' '} + {formatDateTimeLong(r.endDate)}

    )} diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Visualisations/Chart/CustomBarChart.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Visualisations/Chart/CustomBarChart.tsx index 158a46fbb4e..12d09acb0b6 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Visualisations/Chart/CustomBarChart.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Visualisations/Chart/CustomBarChart.tsx @@ -31,7 +31,7 @@ import { updateActiveChartFilter, } from '../../../utils/ChartUtils'; import { CustomTooltip } from '../../../utils/DataInsightUtils'; -import { formatDateTime } from '../../../utils/date-time/DateTimeUtils'; +import { formatDateTimeLong } from '../../../utils/date-time/DateTimeUtils'; import ErrorPlaceHolder from '../../common/ErrorWithPlaceholder/ErrorPlaceHolder'; import { CustomBarChartProps } from './Chart.interface'; @@ -81,7 +81,7 @@ const CustomBarChart = ({ tooltipFormatter(value, tickFormatter)} /> diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Visualisations/Chart/OperationDateBarChart.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Visualisations/Chart/OperationDateBarChart.tsx index da3d27d2be1..5008de345bf 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Visualisations/Chart/OperationDateBarChart.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Visualisations/Chart/OperationDateBarChart.tsx @@ -30,7 +30,7 @@ import { updateActiveChartFilter, } from '../../../utils/ChartUtils'; import { CustomTooltip } from '../../../utils/DataInsightUtils'; -import { formatDateTime } from '../../../utils/date-time/DateTimeUtils'; +import { formatDateTimeLong } from '../../../utils/date-time/DateTimeUtils'; import ErrorPlaceHolder from '../../common/ErrorWithPlaceholder/ErrorPlaceHolder'; import { CustomBarChartProps } from './Chart.interface'; @@ -74,7 +74,7 @@ const OperationDateBarChart = ({ content={ tooltipFormatter(value)} /> diff --git a/openmetadata-ui/src/main/resources/ui/src/interface/data-insight.interface.ts b/openmetadata-ui/src/main/resources/ui/src/interface/data-insight.interface.ts index 9998d8e394e..d6d7ef6b775 100644 --- a/openmetadata-ui/src/main/resources/ui/src/interface/data-insight.interface.ts +++ b/openmetadata-ui/src/main/resources/ui/src/interface/data-insight.interface.ts @@ -41,7 +41,7 @@ export interface ChartFilter { export interface DataInsightChartTooltipProps extends TooltipProps { isPercentage?: boolean; isTier?: boolean; - dateTimeFormatter?: (date?: number) => string; + dateTimeFormatter?: (date?: number, format?: string) => string; valueFormatter?: (value: number | string, key?: string) => string | number; timeStampKey?: string; transformLabel?: boolean; diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/BotsUtils.ts b/openmetadata-ui/src/main/resources/ui/src/utils/BotsUtils.ts index 5a4676428fc..b83dd14fe55 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/BotsUtils.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/BotsUtils.ts @@ -12,7 +12,10 @@ */ import { JWTTokenExpiry } from '../generated/entity/teams/user'; -import { formatDateTimeLong } from './date-time/DateTimeUtils'; +import { + DATE_TIME_WEEKDAY_WITH_ORDINAL, + formatDateTimeLong, +} from './date-time/DateTimeUtils'; export const getJWTTokenExpiryOptions = () => { return Object.keys(JWTTokenExpiry).map((expiry) => { @@ -38,7 +41,7 @@ export const getTokenExpiry = (expiry: number) => { const isTokenExpired = currentTimeStamp >= expiry; return { - tokenExpiryDate: formatDateTimeLong(expiry), + tokenExpiryDate: formatDateTimeLong(expiry, DATE_TIME_WEEKDAY_WITH_ORDINAL), isTokenExpired, }; }; diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/date-time/DateTimeUtils.test.ts b/openmetadata-ui/src/main/resources/ui/src/utils/date-time/DateTimeUtils.test.ts index 2a694342137..2c09be2c546 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/date-time/DateTimeUtils.test.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/date-time/DateTimeUtils.test.ts @@ -50,7 +50,9 @@ describe('DateTimeUtils tests', () => { }); it(`formatDateShort should formate date and time both`, () => { - expect(formatDateTimeLong(0)).toBe(`Thu 1th January, 1970, 12:00 AM`); + expect(formatDateTimeLong(0)).toBe( + `January 01, 1970, 12:00 AM (UTC+00:00)` + ); }); it(`formatTimeDurationFromSeconds should formate date and time both`, () => { diff --git a/openmetadata-ui/src/main/resources/ui/src/utils/date-time/DateTimeUtils.ts b/openmetadata-ui/src/main/resources/ui/src/utils/date-time/DateTimeUtils.ts index 991badc7c21..28d44e95bee 100644 --- a/openmetadata-ui/src/main/resources/ui/src/utils/date-time/DateTimeUtils.ts +++ b/openmetadata-ui/src/main/resources/ui/src/utils/date-time/DateTimeUtils.ts @@ -14,7 +14,8 @@ import { capitalize, isNil, toInteger, toNumber } from 'lodash'; import { DateTime, Duration } from 'luxon'; export const DATE_TIME_12_HOUR_FORMAT = 'MMM dd, yyyy, hh:mm a'; // e.g. Jan 01, 12:00 AM - +export const DATE_TIME_WITH_OFFSET_FORMAT = "MMMM dd, yyyy, h:mm a '(UTC'ZZ')'"; // e.g. Jan 01, 12:00 AM (UTC+05:30) +export const DATE_TIME_WEEKDAY_WITH_ORDINAL = "ccc d'th' MMMM, yyyy, hh:mm a"; // e.g. Mon 1st January, 2025, 12:00 AM /** * @param date EPOCH millis * @returns Formatted date for valid input. Format: MMM DD, YYYY, HH:MM AM/PM @@ -49,10 +50,15 @@ export const formatDate = (date?: number, supportUTC = false) => { * @param date EPOCH millis * @returns Formatted date for valid input. Format: MMM DD, YYYY */ -export const formatDateTimeLong = (timestamp: number, format?: string) => - DateTime.fromMillis(toNumber(timestamp), { locale: 'en-US' }).toFormat( - format || "ccc d'th' MMMM, yyyy, hh:mm a" +export const formatDateTimeLong = (timestamp?: number, format?: string) => { + if (isNil(timestamp)) { + return ''; + } + + return DateTime.fromMillis(toNumber(timestamp), { locale: 'en-US' }).toFormat( + format || DATE_TIME_WITH_OFFSET_FORMAT ); +}; /** *