#14127 Timestamp statistical measurements is not being computed and UI Time Filter get reset to default (Last 3 Days) (#14797)

Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
This commit is contained in:
Shailesh Parmar 2024-01-21 12:02:34 +05:30 committed by GitHub
parent eb1550205a
commit 62d1ef7c7d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 126 additions and 87 deletions

View File

@ -14,8 +14,9 @@
import { CloseCircleOutlined } from '@ant-design/icons'; import { CloseCircleOutlined } from '@ant-design/icons';
import { Button, DatePicker, Dropdown, MenuProps, Space } from 'antd'; import { Button, DatePicker, Dropdown, MenuProps, Space } from 'antd';
import { RangePickerProps } from 'antd/lib/date-picker'; import { RangePickerProps } from 'antd/lib/date-picker';
import { isUndefined } from 'lodash'; import { isUndefined, pick } from 'lodash';
import { DateFilterType, DateRangeObject } from 'Models'; import { DateFilterType, DateRangeObject } from 'Models';
import moment from 'moment';
import { MenuInfo } from 'rc-menu/lib/interface'; import { MenuInfo } from 'rc-menu/lib/interface';
import React, { useMemo, useState } from 'react'; import React, { useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -35,42 +36,39 @@ import {
import './date-picker-menu.less'; import './date-picker-menu.less';
interface DatePickerMenuProps { interface DatePickerMenuProps {
defaultDateRange?: Partial<DateRangeObject>;
showSelectedCustomRange?: boolean; showSelectedCustomRange?: boolean;
handleDateRangeChange: (value: DateRangeObject, days?: number) => void; handleDateRangeChange: (value: DateRangeObject, days?: number) => void;
options?: DateFilterType; options?: DateFilterType;
defaultValue?: string;
allowCustomRange?: boolean; allowCustomRange?: boolean;
handleSelectedTimeRange?: (value: string) => void; handleSelectedTimeRange?: (value: string) => void;
} }
function DatePickerMenu({ const DatePickerMenu = ({
defaultDateRange,
showSelectedCustomRange, showSelectedCustomRange,
handleDateRangeChange, handleDateRangeChange,
handleSelectedTimeRange, handleSelectedTimeRange,
options, options,
defaultValue,
allowCustomRange = true, allowCustomRange = true,
}: DatePickerMenuProps) { }: DatePickerMenuProps) => {
const { menuOptions, defaultOptions } = useMemo(() => { const { menuOptions, defaultOptions } = useMemo(() => {
let defaultOptions = DEFAULT_SELECTED_RANGE; const defaultOptions = pick(DEFAULT_SELECTED_RANGE, ['title', 'key']);
if (defaultValue) { if (defaultDateRange && defaultDateRange.key) {
if (options && !isUndefined(options[defaultValue]?.title)) { defaultOptions.key = defaultDateRange.key;
defaultOptions = { if (defaultDateRange.key === 'customRange' && defaultDateRange.title) {
title: options[defaultValue].title, defaultOptions.title = defaultDateRange.title;
key: defaultValue,
days: options[defaultValue].days,
};
} else if ( } else if (
!isUndefined( options &&
PROFILER_FILTER_RANGE[defaultValue as keyof DateFilterType]?.title !isUndefined(options[defaultDateRange.key]?.title)
)
) { ) {
defaultOptions = { defaultOptions.title = options[defaultDateRange.key].title;
title: PROFILER_FILTER_RANGE[defaultValue].title, } else if (
key: defaultValue, !isUndefined(PROFILER_FILTER_RANGE[defaultDateRange.key]?.title)
days: PROFILER_FILTER_RANGE[defaultValue].days, ) {
}; defaultOptions.title =
PROFILER_FILTER_RANGE[defaultDateRange.key].title;
} }
} }
@ -112,7 +110,15 @@ function DatePickerMenu({
setSelectedTimeRange(selectedRangeLabel); setSelectedTimeRange(selectedRangeLabel);
setSelectedTimeRangeKey('customRange'); setSelectedTimeRangeKey('customRange');
setIsMenuOpen(false); setIsMenuOpen(false);
handleDateRangeChange({ startTs, endTs }, daysCount); handleDateRangeChange(
{
startTs,
endTs,
key: 'customRange',
title: selectedRangeLabel,
},
daysCount
);
handleSelectedTimeRange?.(selectedRangeLabel); handleSelectedTimeRange?.(selectedRangeLabel);
} }
}; };
@ -132,7 +138,10 @@ function DatePickerMenu({
setSelectedTimeRangeKey(key); setSelectedTimeRangeKey(key);
setIsMenuOpen(false); setIsMenuOpen(false);
handleDateRangeChange({ startTs, endTs }, selectedNumberOfDays); handleDateRangeChange(
{ startTs, endTs, key, title: filterRange.title },
selectedNumberOfDays
);
handleSelectedTimeRange?.(menuOptions[key].title); handleSelectedTimeRange?.(menuOptions[key].title);
}; };
@ -143,30 +152,33 @@ function DatePickerMenu({
key, key,
}) })
); );
{
allowCustomRange && allowCustomRange &&
items.push({ items.push({
label: t('label.custom-range'), label: t('label.custom-range'),
key: 'customRange', key: 'customRange',
children: [ children: [
{ {
label: ( label: (
<DatePicker.RangePicker <DatePicker.RangePicker
bordered={false} bordered={false}
clearIcon={<CloseCircleOutlined />} clearIcon={<CloseCircleOutlined />}
format={(value) => value.utc().format('YYYY-MM-DD')} defaultValue={[
open={isMenuOpen} moment(defaultDateRange?.startTs),
placement="bottomRight" moment(defaultDateRange?.endTs),
suffixIcon={null} ]}
onChange={handleCustomDateChange} format={(value) => value.utc().format('YYYY-MM-DD')}
/> open={isMenuOpen}
), placement="bottomRight"
key: 'datePicker', suffixIcon={null}
}, onChange={handleCustomDateChange}
], />
popupClassName: 'date-picker-sub-menu-popup', ),
}); key: 'datePicker',
} },
],
popupClassName: 'date-picker-sub-menu-popup',
});
return items; return items;
}; };
@ -174,27 +186,25 @@ function DatePickerMenu({
const items: MenuProps['items'] = getMenuItems(); const items: MenuProps['items'] = getMenuItems();
return ( return (
<> <Dropdown
<Dropdown destroyPopupOnHide
destroyPopupOnHide menu={{
menu={{ items,
items, triggerSubMenuAction: 'click',
triggerSubMenuAction: 'click', onClick: handleOptionClick,
onClick: handleOptionClick, selectedKeys: [selectedTimeRangeKey],
selectedKeys: [selectedTimeRangeKey], }}
}} open={isMenuOpen}
open={isMenuOpen} trigger={['click']}
trigger={['click']} onOpenChange={(value) => setIsMenuOpen(value)}>
onOpenChange={(value) => setIsMenuOpen(value)}> <Button>
<Button> <Space align="center" size={8}>
<Space align="center" size={8}> {selectedTimeRange}
{selectedTimeRange} <DropdownIcon className="align-middle" height={14} width={14} />
<DropdownIcon className="align-middle" height={14} width={14} /> </Space>
</Space> </Button>
</Button> </Dropdown>
</Dropdown>
</>
); );
} };
export default DatePickerMenu; export default DatePickerMenu;

View File

@ -20,6 +20,7 @@ import {
isEqual, isEqual,
isUndefined, isUndefined,
omitBy, omitBy,
pick,
round, round,
uniqueId, uniqueId,
} from 'lodash'; } from 'lodash';
@ -254,7 +255,7 @@ const TestSummary: React.FC<TestSummaryProps> = ({
try { try {
const { data: chartData } = await getListTestCaseResults( const { data: chartData } = await getListTestCaseResults(
data.fullyQualifiedName || '', data.fullyQualifiedName || '',
dateRangeObj pick(dateRangeObj, ['startTs', 'endTs'])
); );
setResults(chartData); setResults(chartData);
@ -476,7 +477,7 @@ const TestSummary: React.FC<TestSummaryProps> = ({
<Col> <Col>
<DatePickerMenu <DatePickerMenu
showSelectedCustomRange showSelectedCustomRange
defaultValue={defaultRange.key} defaultDateRange={pick(defaultRange, ['key', 'title'])}
handleDateRangeChange={handleDateRangeChange} handleDateRangeChange={handleDateRangeChange}
handleSelectedTimeRange={handleSelectedTimeRange} handleSelectedTimeRange={handleSelectedTimeRange}
/> />

View File

@ -38,7 +38,6 @@ import { TableProfilerTab } from '../../../components/ProfilerDashboard/profiler
import { NO_DATA_PLACEHOLDER } from '../../../constants/constants'; import { NO_DATA_PLACEHOLDER } from '../../../constants/constants';
import { PAGE_HEADERS } from '../../../constants/PageHeaders.constant'; import { PAGE_HEADERS } from '../../../constants/PageHeaders.constant';
import { import {
DEFAULT_RANGE_DATA,
DEFAULT_TEST_VALUE, DEFAULT_TEST_VALUE,
INITIAL_TEST_RESULT_SUMMARY, INITIAL_TEST_RESULT_SUMMARY,
} from '../../../constants/profiler.constant'; } from '../../../constants/profiler.constant';
@ -88,6 +87,8 @@ const ColumnProfileTable = () => {
isProfilingEnabled, isProfilingEnabled,
tableProfiler, tableProfiler,
splitTestCases, splitTestCases,
dateRangeObject,
onDateRangeChange,
} = useTableProfiler(); } = useTableProfiler();
const isLoading = isTestsLoading || isProfilerDataLoading; const isLoading = isTestsLoading || isProfilerDataLoading;
const columnTests = splitTestCases.column ?? []; const columnTests = splitTestCases.column ?? [];
@ -96,8 +97,6 @@ const ColumnProfileTable = () => {
const [data, setData] = useState<ModifiedColumn[]>(columns); const [data, setData] = useState<ModifiedColumn[]>(columns);
const [columnTestSummary, setColumnTestSummary] = const [columnTestSummary, setColumnTestSummary] =
useState<columnTestResultType>(); useState<columnTestResultType>();
const [dateRangeObject, setDateRangeObject] =
useState<DateRangeObject>(DEFAULT_RANGE_DATA);
const { activeColumnFqn, activeTab } = useMemo(() => { const { activeColumnFqn, activeTab } = useMemo(() => {
const param = location.search; const param = location.search;
@ -337,7 +336,7 @@ const ColumnProfileTable = () => {
const handleDateRangeChange = (value: DateRangeObject) => { const handleDateRangeChange = (value: DateRangeObject) => {
if (!isEqual(value, dateRangeObject)) { if (!isEqual(value, dateRangeObject)) {
setDateRangeObject(value); onDateRangeChange(value);
} }
}; };
@ -393,6 +392,7 @@ const ColumnProfileTable = () => {
{!isEmpty(activeColumnFqn) && ( {!isEmpty(activeColumnFqn) && (
<DatePickerMenu <DatePickerMenu
showSelectedCustomRange showSelectedCustomRange
defaultDateRange={dateRangeObject}
handleDateRangeChange={handleDateRangeChange} handleDateRangeChange={handleDateRangeChange}
/> />
)} )}

View File

@ -12,7 +12,7 @@
*/ */
import { Card, Col, Row, Typography } from 'antd'; import { Card, Col, Row, Typography } from 'antd';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import { first, isString, last } from 'lodash'; import { first, isString, last, pick } from 'lodash';
import { DateRangeObject } from 'Models'; import { DateRangeObject } from 'Models';
import React, { FC, useEffect, useMemo, useState } from 'react'; import React, { FC, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -77,12 +77,12 @@ const SingleColumnProfile: FC<SingleColumnProfileProps> = ({
fqn: string, fqn: string,
dateRangeObject?: DateRangeObject dateRangeObject?: DateRangeObject
) => { ) => {
const dateRange = dateRangeObject
? pick(dateRangeObject, ['startTs', 'endTs'])
: DEFAULT_RANGE_DATA;
try { try {
setIsLoading(true); setIsLoading(true);
const { data } = await getColumnProfilerList( const { data } = await getColumnProfilerList(fqn, dateRange);
fqn,
dateRangeObject ?? DEFAULT_RANGE_DATA
);
setColumnProfilerData(data); setColumnProfilerData(data);
} catch (error) { } catch (error) {
showErrorToast(error as AxiosError); showErrorToast(error as AxiosError);

View File

@ -53,6 +53,17 @@ jest.mock('../../common/SummaryCard/SummaryCard.component', () => {
SummaryCard: jest.fn().mockImplementation(() => <div>SummaryCard</div>), SummaryCard: jest.fn().mockImplementation(() => <div>SummaryCard</div>),
}; };
}); });
jest.mock('../TableProfilerProvider', () => ({
useTableProfiler: jest.fn().mockReturnValue({
dateRangeObject: DEFAULT_RANGE_DATA,
isProfilerDataLoading: false,
permissions: {
EditAll: true,
EditDataProfile: true,
},
isTableDeleted: false,
}),
}));
describe('TableProfilerChart component test', () => { describe('TableProfilerChart component test', () => {
it('Component should render', async () => { it('Component should render', async () => {

View File

@ -24,7 +24,7 @@ import {
} from 'antd'; } from 'antd';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import classNames from 'classnames'; import classNames from 'classnames';
import { isEqual } from 'lodash'; import { isEqual, pick } from 'lodash';
import { DateRangeObject } from 'Models'; import { DateRangeObject } from 'Models';
import React, { useEffect, useMemo, useState } from 'react'; import React, { useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -32,7 +32,6 @@ import { useHistory } from 'react-router-dom';
import { ReactComponent as SettingIcon } from '../../../assets/svg/ic-settings-primery.svg'; import { ReactComponent as SettingIcon } from '../../../assets/svg/ic-settings-primery.svg';
import { PAGE_HEADERS } from '../../../constants/PageHeaders.constant'; import { PAGE_HEADERS } from '../../../constants/PageHeaders.constant';
import { import {
DEFAULT_RANGE_DATA,
INITIAL_OPERATION_METRIC_VALUE, INITIAL_OPERATION_METRIC_VALUE,
INITIAL_ROW_METRIC_VALUE, INITIAL_ROW_METRIC_VALUE,
} from '../../../constants/profiler.constant'; } from '../../../constants/profiler.constant';
@ -80,6 +79,8 @@ const TableProfilerChart = ({
onSettingButtonClick, onSettingButtonClick,
isProfilingEnabled, isProfilingEnabled,
customMetric: tableCustomMetric, customMetric: tableCustomMetric,
dateRangeObject,
onDateRangeChange,
} = useTableProfiler(); } = useTableProfiler();
const { fqn: datasetFQN } = useFqn(); const { fqn: datasetFQN } = useFqn();
@ -91,8 +92,6 @@ const TableProfilerChart = ({
); );
const editDataProfile = permissions?.EditAll || permissions?.EditDataProfile; const editDataProfile = permissions?.EditAll || permissions?.EditDataProfile;
const [dateRangeObject, setDateRangeObject] =
useState<DateRangeObject>(DEFAULT_RANGE_DATA);
const [rowCountMetrics, setRowCountMetrics] = useState<MetricChartType>( const [rowCountMetrics, setRowCountMetrics] = useState<MetricChartType>(
INITIAL_ROW_METRIC_VALUE INITIAL_ROW_METRIC_VALUE
); );
@ -135,7 +134,7 @@ const TableProfilerChart = ({
const handleDateRangeChange = (value: DateRangeObject) => { const handleDateRangeChange = (value: DateRangeObject) => {
if (!isEqual(value, dateRangeObject)) { if (!isEqual(value, dateRangeObject)) {
setDateRangeObject(value); onDateRangeChange(value);
} }
}; };
@ -172,9 +171,10 @@ const TableProfilerChart = ({
fqn: string, fqn: string,
dateRangeObj: DateRangeObject dateRangeObj: DateRangeObject
) => { ) => {
const dateRange = pick(dateRangeObj, ['startTs', 'endTs']);
setIsLoading(true); setIsLoading(true);
await fetchTableProfiler(fqn, dateRangeObj); await fetchTableProfiler(fqn, dateRange);
await fetchSystemProfiler(fqn, dateRangeObj); await fetchSystemProfiler(fqn, dateRange);
setIsLoading(false); setIsLoading(false);
}; };
@ -199,6 +199,7 @@ const TableProfilerChart = ({
<Space align="center" className="w-full justify-end"> <Space align="center" className="w-full justify-end">
<DatePickerMenu <DatePickerMenu
showSelectedCustomRange showSelectedCustomRange
defaultDateRange={dateRangeObject}
handleDateRangeChange={handleDateRangeChange} handleDateRangeChange={handleDateRangeChange}
/> />

View File

@ -11,6 +11,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { DateRangeObject } from 'Models';
import { ReactNode } from 'react'; import { ReactNode } from 'react';
import { SystemProfile } from '../../generated/api/data/createTableProfile'; import { SystemProfile } from '../../generated/api/data/createTableProfile';
import { import {
@ -50,6 +51,8 @@ export interface TableProfilerContextInterface {
onCustomMetricUpdate: (table: Table) => void; onCustomMetricUpdate: (table: Table) => void;
isProfilingEnabled: boolean; isProfilingEnabled: boolean;
splitTestCases: SplitTestCasesType; splitTestCases: SplitTestCasesType;
dateRangeObject: DateRangeObject;
onDateRangeChange: (dateRange: DateRangeObject) => void;
} }
export type SplitTestCasesType = { export type SplitTestCasesType = {

View File

@ -13,6 +13,7 @@
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import { isEmpty, isUndefined } from 'lodash'; import { isEmpty, isUndefined } from 'lodash';
import { DateTime } from 'luxon'; import { DateTime } from 'luxon';
import { DateRangeObject } from 'Models';
import Qs from 'qs'; import Qs from 'qs';
import React, { import React, {
createContext, createContext,
@ -26,6 +27,7 @@ import { useTranslation } from 'react-i18next';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { API_RES_MAX_SIZE } from '../../constants/constants'; import { API_RES_MAX_SIZE } from '../../constants/constants';
import { mockDatasetData } from '../../constants/mockTourData.constants'; import { mockDatasetData } from '../../constants/mockTourData.constants';
import { DEFAULT_RANGE_DATA } from '../../constants/profiler.constant';
import { Table } from '../../generated/entity/data/table'; import { Table } from '../../generated/entity/data/table';
import { ProfileSampleType } from '../../generated/metadataIngestion/databaseServiceProfilerPipeline'; import { ProfileSampleType } from '../../generated/metadataIngestion/databaseServiceProfilerPipeline';
import { TestCase } from '../../generated/tests/testCase'; import { TestCase } from '../../generated/tests/testCase';
@ -74,6 +76,8 @@ export const TableProfilerProvider = ({
column: [], column: [],
table: [], table: [],
}); });
const [dateRangeObject, setDateRangeObject] =
useState<DateRangeObject>(DEFAULT_RANGE_DATA);
const { const {
activeTab = isTourOpen activeTab = isTourOpen
@ -150,6 +154,10 @@ export const TableProfilerProvider = ({
]; ];
}, [tableProfiler]); }, [tableProfiler]);
const handleDateRangeChange = (data: DateRangeObject) => {
setDateRangeObject(data);
};
const splitTableAndColumnTest = (data: TestCase[]) => { const splitTableAndColumnTest = (data: TestCase[]) => {
const columnTestsCase: TestCase[] = []; const columnTestsCase: TestCase[] = [];
const tableTests: TestCase[] = []; const tableTests: TestCase[] = [];
@ -279,6 +287,8 @@ export const TableProfilerProvider = ({
splitTestCases, splitTestCases,
customMetric, customMetric,
onCustomMetricUpdate: handleUpdateCustomMetrics, onCustomMetricUpdate: handleUpdateCustomMetrics,
onDateRangeChange: handleDateRangeChange,
dateRangeObject,
}; };
}, [ }, [
isTestsLoading, isTestsLoading,
@ -291,6 +301,7 @@ export const TableProfilerProvider = ({
onTestCaseUpdate, onTestCaseUpdate,
splitTestCases, splitTestCases,
customMetric, customMetric,
dateRangeObject,
]); ]);
return ( return (

View File

@ -279,5 +279,7 @@ declare module 'Models' {
export interface DateRangeObject { export interface DateRangeObject {
startTs: number; startTs: number;
endTs: number; endTs: number;
key?: string;
title?: string;
} }
} }

View File

@ -237,7 +237,7 @@ const IncidentManagerPage = () => {
}; };
if (!isEqual(value, dateRangeObject)) { if (!isEqual(value, dateRangeObject)) {
setFilters((pre) => ({ ...pre, ...value })); setFilters((pre) => ({ ...pre, ...dateRangeObject }));
} }
}; };