mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-11-02 19:48:17 +00:00
#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:
parent
eb1550205a
commit
62d1ef7c7d
@ -14,8 +14,9 @@
|
||||
import { CloseCircleOutlined } from '@ant-design/icons';
|
||||
import { Button, DatePicker, Dropdown, MenuProps, Space } from 'antd';
|
||||
import { RangePickerProps } from 'antd/lib/date-picker';
|
||||
import { isUndefined } from 'lodash';
|
||||
import { isUndefined, pick } from 'lodash';
|
||||
import { DateFilterType, DateRangeObject } from 'Models';
|
||||
import moment from 'moment';
|
||||
import { MenuInfo } from 'rc-menu/lib/interface';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -35,42 +36,39 @@ import {
|
||||
import './date-picker-menu.less';
|
||||
|
||||
interface DatePickerMenuProps {
|
||||
defaultDateRange?: Partial<DateRangeObject>;
|
||||
showSelectedCustomRange?: boolean;
|
||||
handleDateRangeChange: (value: DateRangeObject, days?: number) => void;
|
||||
options?: DateFilterType;
|
||||
defaultValue?: string;
|
||||
allowCustomRange?: boolean;
|
||||
handleSelectedTimeRange?: (value: string) => void;
|
||||
}
|
||||
|
||||
function DatePickerMenu({
|
||||
const DatePickerMenu = ({
|
||||
defaultDateRange,
|
||||
showSelectedCustomRange,
|
||||
handleDateRangeChange,
|
||||
handleSelectedTimeRange,
|
||||
options,
|
||||
defaultValue,
|
||||
allowCustomRange = true,
|
||||
}: DatePickerMenuProps) {
|
||||
}: DatePickerMenuProps) => {
|
||||
const { menuOptions, defaultOptions } = useMemo(() => {
|
||||
let defaultOptions = DEFAULT_SELECTED_RANGE;
|
||||
const defaultOptions = pick(DEFAULT_SELECTED_RANGE, ['title', 'key']);
|
||||
|
||||
if (defaultValue) {
|
||||
if (options && !isUndefined(options[defaultValue]?.title)) {
|
||||
defaultOptions = {
|
||||
title: options[defaultValue].title,
|
||||
key: defaultValue,
|
||||
days: options[defaultValue].days,
|
||||
};
|
||||
if (defaultDateRange && defaultDateRange.key) {
|
||||
defaultOptions.key = defaultDateRange.key;
|
||||
if (defaultDateRange.key === 'customRange' && defaultDateRange.title) {
|
||||
defaultOptions.title = defaultDateRange.title;
|
||||
} else if (
|
||||
!isUndefined(
|
||||
PROFILER_FILTER_RANGE[defaultValue as keyof DateFilterType]?.title
|
||||
)
|
||||
options &&
|
||||
!isUndefined(options[defaultDateRange.key]?.title)
|
||||
) {
|
||||
defaultOptions = {
|
||||
title: PROFILER_FILTER_RANGE[defaultValue].title,
|
||||
key: defaultValue,
|
||||
days: PROFILER_FILTER_RANGE[defaultValue].days,
|
||||
};
|
||||
defaultOptions.title = options[defaultDateRange.key].title;
|
||||
} else if (
|
||||
!isUndefined(PROFILER_FILTER_RANGE[defaultDateRange.key]?.title)
|
||||
) {
|
||||
defaultOptions.title =
|
||||
PROFILER_FILTER_RANGE[defaultDateRange.key].title;
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,7 +110,15 @@ function DatePickerMenu({
|
||||
setSelectedTimeRange(selectedRangeLabel);
|
||||
setSelectedTimeRangeKey('customRange');
|
||||
setIsMenuOpen(false);
|
||||
handleDateRangeChange({ startTs, endTs }, daysCount);
|
||||
handleDateRangeChange(
|
||||
{
|
||||
startTs,
|
||||
endTs,
|
||||
key: 'customRange',
|
||||
title: selectedRangeLabel,
|
||||
},
|
||||
daysCount
|
||||
);
|
||||
handleSelectedTimeRange?.(selectedRangeLabel);
|
||||
}
|
||||
};
|
||||
@ -132,7 +138,10 @@ function DatePickerMenu({
|
||||
setSelectedTimeRangeKey(key);
|
||||
setIsMenuOpen(false);
|
||||
|
||||
handleDateRangeChange({ startTs, endTs }, selectedNumberOfDays);
|
||||
handleDateRangeChange(
|
||||
{ startTs, endTs, key, title: filterRange.title },
|
||||
selectedNumberOfDays
|
||||
);
|
||||
handleSelectedTimeRange?.(menuOptions[key].title);
|
||||
};
|
||||
|
||||
@ -143,30 +152,33 @@ function DatePickerMenu({
|
||||
key,
|
||||
})
|
||||
);
|
||||
{
|
||||
allowCustomRange &&
|
||||
items.push({
|
||||
label: t('label.custom-range'),
|
||||
key: 'customRange',
|
||||
children: [
|
||||
{
|
||||
label: (
|
||||
<DatePicker.RangePicker
|
||||
bordered={false}
|
||||
clearIcon={<CloseCircleOutlined />}
|
||||
format={(value) => value.utc().format('YYYY-MM-DD')}
|
||||
open={isMenuOpen}
|
||||
placement="bottomRight"
|
||||
suffixIcon={null}
|
||||
onChange={handleCustomDateChange}
|
||||
/>
|
||||
),
|
||||
key: 'datePicker',
|
||||
},
|
||||
],
|
||||
popupClassName: 'date-picker-sub-menu-popup',
|
||||
});
|
||||
}
|
||||
|
||||
allowCustomRange &&
|
||||
items.push({
|
||||
label: t('label.custom-range'),
|
||||
key: 'customRange',
|
||||
children: [
|
||||
{
|
||||
label: (
|
||||
<DatePicker.RangePicker
|
||||
bordered={false}
|
||||
clearIcon={<CloseCircleOutlined />}
|
||||
defaultValue={[
|
||||
moment(defaultDateRange?.startTs),
|
||||
moment(defaultDateRange?.endTs),
|
||||
]}
|
||||
format={(value) => value.utc().format('YYYY-MM-DD')}
|
||||
open={isMenuOpen}
|
||||
placement="bottomRight"
|
||||
suffixIcon={null}
|
||||
onChange={handleCustomDateChange}
|
||||
/>
|
||||
),
|
||||
key: 'datePicker',
|
||||
},
|
||||
],
|
||||
popupClassName: 'date-picker-sub-menu-popup',
|
||||
});
|
||||
|
||||
return items;
|
||||
};
|
||||
@ -174,27 +186,25 @@ function DatePickerMenu({
|
||||
const items: MenuProps['items'] = getMenuItems();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Dropdown
|
||||
destroyPopupOnHide
|
||||
menu={{
|
||||
items,
|
||||
triggerSubMenuAction: 'click',
|
||||
onClick: handleOptionClick,
|
||||
selectedKeys: [selectedTimeRangeKey],
|
||||
}}
|
||||
open={isMenuOpen}
|
||||
trigger={['click']}
|
||||
onOpenChange={(value) => setIsMenuOpen(value)}>
|
||||
<Button>
|
||||
<Space align="center" size={8}>
|
||||
{selectedTimeRange}
|
||||
<DropdownIcon className="align-middle" height={14} width={14} />
|
||||
</Space>
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</>
|
||||
<Dropdown
|
||||
destroyPopupOnHide
|
||||
menu={{
|
||||
items,
|
||||
triggerSubMenuAction: 'click',
|
||||
onClick: handleOptionClick,
|
||||
selectedKeys: [selectedTimeRangeKey],
|
||||
}}
|
||||
open={isMenuOpen}
|
||||
trigger={['click']}
|
||||
onOpenChange={(value) => setIsMenuOpen(value)}>
|
||||
<Button>
|
||||
<Space align="center" size={8}>
|
||||
{selectedTimeRange}
|
||||
<DropdownIcon className="align-middle" height={14} width={14} />
|
||||
</Space>
|
||||
</Button>
|
||||
</Dropdown>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default DatePickerMenu;
|
||||
|
||||
@ -20,6 +20,7 @@ import {
|
||||
isEqual,
|
||||
isUndefined,
|
||||
omitBy,
|
||||
pick,
|
||||
round,
|
||||
uniqueId,
|
||||
} from 'lodash';
|
||||
@ -254,7 +255,7 @@ const TestSummary: React.FC<TestSummaryProps> = ({
|
||||
try {
|
||||
const { data: chartData } = await getListTestCaseResults(
|
||||
data.fullyQualifiedName || '',
|
||||
dateRangeObj
|
||||
pick(dateRangeObj, ['startTs', 'endTs'])
|
||||
);
|
||||
|
||||
setResults(chartData);
|
||||
@ -476,7 +477,7 @@ const TestSummary: React.FC<TestSummaryProps> = ({
|
||||
<Col>
|
||||
<DatePickerMenu
|
||||
showSelectedCustomRange
|
||||
defaultValue={defaultRange.key}
|
||||
defaultDateRange={pick(defaultRange, ['key', 'title'])}
|
||||
handleDateRangeChange={handleDateRangeChange}
|
||||
handleSelectedTimeRange={handleSelectedTimeRange}
|
||||
/>
|
||||
|
||||
@ -38,7 +38,6 @@ import { TableProfilerTab } from '../../../components/ProfilerDashboard/profiler
|
||||
import { NO_DATA_PLACEHOLDER } from '../../../constants/constants';
|
||||
import { PAGE_HEADERS } from '../../../constants/PageHeaders.constant';
|
||||
import {
|
||||
DEFAULT_RANGE_DATA,
|
||||
DEFAULT_TEST_VALUE,
|
||||
INITIAL_TEST_RESULT_SUMMARY,
|
||||
} from '../../../constants/profiler.constant';
|
||||
@ -88,6 +87,8 @@ const ColumnProfileTable = () => {
|
||||
isProfilingEnabled,
|
||||
tableProfiler,
|
||||
splitTestCases,
|
||||
dateRangeObject,
|
||||
onDateRangeChange,
|
||||
} = useTableProfiler();
|
||||
const isLoading = isTestsLoading || isProfilerDataLoading;
|
||||
const columnTests = splitTestCases.column ?? [];
|
||||
@ -96,8 +97,6 @@ const ColumnProfileTable = () => {
|
||||
const [data, setData] = useState<ModifiedColumn[]>(columns);
|
||||
const [columnTestSummary, setColumnTestSummary] =
|
||||
useState<columnTestResultType>();
|
||||
const [dateRangeObject, setDateRangeObject] =
|
||||
useState<DateRangeObject>(DEFAULT_RANGE_DATA);
|
||||
|
||||
const { activeColumnFqn, activeTab } = useMemo(() => {
|
||||
const param = location.search;
|
||||
@ -337,7 +336,7 @@ const ColumnProfileTable = () => {
|
||||
|
||||
const handleDateRangeChange = (value: DateRangeObject) => {
|
||||
if (!isEqual(value, dateRangeObject)) {
|
||||
setDateRangeObject(value);
|
||||
onDateRangeChange(value);
|
||||
}
|
||||
};
|
||||
|
||||
@ -393,6 +392,7 @@ const ColumnProfileTable = () => {
|
||||
{!isEmpty(activeColumnFqn) && (
|
||||
<DatePickerMenu
|
||||
showSelectedCustomRange
|
||||
defaultDateRange={dateRangeObject}
|
||||
handleDateRangeChange={handleDateRangeChange}
|
||||
/>
|
||||
)}
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
*/
|
||||
import { Card, Col, Row, Typography } from 'antd';
|
||||
import { AxiosError } from 'axios';
|
||||
import { first, isString, last } from 'lodash';
|
||||
import { first, isString, last, pick } from 'lodash';
|
||||
import { DateRangeObject } from 'Models';
|
||||
import React, { FC, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@ -77,12 +77,12 @@ const SingleColumnProfile: FC<SingleColumnProfileProps> = ({
|
||||
fqn: string,
|
||||
dateRangeObject?: DateRangeObject
|
||||
) => {
|
||||
const dateRange = dateRangeObject
|
||||
? pick(dateRangeObject, ['startTs', 'endTs'])
|
||||
: DEFAULT_RANGE_DATA;
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const { data } = await getColumnProfilerList(
|
||||
fqn,
|
||||
dateRangeObject ?? DEFAULT_RANGE_DATA
|
||||
);
|
||||
const { data } = await getColumnProfilerList(fqn, dateRange);
|
||||
setColumnProfilerData(data);
|
||||
} catch (error) {
|
||||
showErrorToast(error as AxiosError);
|
||||
|
||||
@ -53,6 +53,17 @@ jest.mock('../../common/SummaryCard/SummaryCard.component', () => {
|
||||
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', () => {
|
||||
it('Component should render', async () => {
|
||||
|
||||
@ -24,7 +24,7 @@ import {
|
||||
} from 'antd';
|
||||
import { AxiosError } from 'axios';
|
||||
import classNames from 'classnames';
|
||||
import { isEqual } from 'lodash';
|
||||
import { isEqual, pick } from 'lodash';
|
||||
import { DateRangeObject } from 'Models';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
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 { PAGE_HEADERS } from '../../../constants/PageHeaders.constant';
|
||||
import {
|
||||
DEFAULT_RANGE_DATA,
|
||||
INITIAL_OPERATION_METRIC_VALUE,
|
||||
INITIAL_ROW_METRIC_VALUE,
|
||||
} from '../../../constants/profiler.constant';
|
||||
@ -80,6 +79,8 @@ const TableProfilerChart = ({
|
||||
onSettingButtonClick,
|
||||
isProfilingEnabled,
|
||||
customMetric: tableCustomMetric,
|
||||
dateRangeObject,
|
||||
onDateRangeChange,
|
||||
} = useTableProfiler();
|
||||
|
||||
const { fqn: datasetFQN } = useFqn();
|
||||
@ -91,8 +92,6 @@ const TableProfilerChart = ({
|
||||
);
|
||||
|
||||
const editDataProfile = permissions?.EditAll || permissions?.EditDataProfile;
|
||||
const [dateRangeObject, setDateRangeObject] =
|
||||
useState<DateRangeObject>(DEFAULT_RANGE_DATA);
|
||||
const [rowCountMetrics, setRowCountMetrics] = useState<MetricChartType>(
|
||||
INITIAL_ROW_METRIC_VALUE
|
||||
);
|
||||
@ -135,7 +134,7 @@ const TableProfilerChart = ({
|
||||
|
||||
const handleDateRangeChange = (value: DateRangeObject) => {
|
||||
if (!isEqual(value, dateRangeObject)) {
|
||||
setDateRangeObject(value);
|
||||
onDateRangeChange(value);
|
||||
}
|
||||
};
|
||||
|
||||
@ -172,9 +171,10 @@ const TableProfilerChart = ({
|
||||
fqn: string,
|
||||
dateRangeObj: DateRangeObject
|
||||
) => {
|
||||
const dateRange = pick(dateRangeObj, ['startTs', 'endTs']);
|
||||
setIsLoading(true);
|
||||
await fetchTableProfiler(fqn, dateRangeObj);
|
||||
await fetchSystemProfiler(fqn, dateRangeObj);
|
||||
await fetchTableProfiler(fqn, dateRange);
|
||||
await fetchSystemProfiler(fqn, dateRange);
|
||||
setIsLoading(false);
|
||||
};
|
||||
|
||||
@ -199,6 +199,7 @@ const TableProfilerChart = ({
|
||||
<Space align="center" className="w-full justify-end">
|
||||
<DatePickerMenu
|
||||
showSelectedCustomRange
|
||||
defaultDateRange={dateRangeObject}
|
||||
handleDateRangeChange={handleDateRangeChange}
|
||||
/>
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DateRangeObject } from 'Models';
|
||||
import { ReactNode } from 'react';
|
||||
import { SystemProfile } from '../../generated/api/data/createTableProfile';
|
||||
import {
|
||||
@ -50,6 +51,8 @@ export interface TableProfilerContextInterface {
|
||||
onCustomMetricUpdate: (table: Table) => void;
|
||||
isProfilingEnabled: boolean;
|
||||
splitTestCases: SplitTestCasesType;
|
||||
dateRangeObject: DateRangeObject;
|
||||
onDateRangeChange: (dateRange: DateRangeObject) => void;
|
||||
}
|
||||
|
||||
export type SplitTestCasesType = {
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
import { AxiosError } from 'axios';
|
||||
import { isEmpty, isUndefined } from 'lodash';
|
||||
import { DateTime } from 'luxon';
|
||||
import { DateRangeObject } from 'Models';
|
||||
import Qs from 'qs';
|
||||
import React, {
|
||||
createContext,
|
||||
@ -26,6 +27,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { API_RES_MAX_SIZE } from '../../constants/constants';
|
||||
import { mockDatasetData } from '../../constants/mockTourData.constants';
|
||||
import { DEFAULT_RANGE_DATA } from '../../constants/profiler.constant';
|
||||
import { Table } from '../../generated/entity/data/table';
|
||||
import { ProfileSampleType } from '../../generated/metadataIngestion/databaseServiceProfilerPipeline';
|
||||
import { TestCase } from '../../generated/tests/testCase';
|
||||
@ -74,6 +76,8 @@ export const TableProfilerProvider = ({
|
||||
column: [],
|
||||
table: [],
|
||||
});
|
||||
const [dateRangeObject, setDateRangeObject] =
|
||||
useState<DateRangeObject>(DEFAULT_RANGE_DATA);
|
||||
|
||||
const {
|
||||
activeTab = isTourOpen
|
||||
@ -150,6 +154,10 @@ export const TableProfilerProvider = ({
|
||||
];
|
||||
}, [tableProfiler]);
|
||||
|
||||
const handleDateRangeChange = (data: DateRangeObject) => {
|
||||
setDateRangeObject(data);
|
||||
};
|
||||
|
||||
const splitTableAndColumnTest = (data: TestCase[]) => {
|
||||
const columnTestsCase: TestCase[] = [];
|
||||
const tableTests: TestCase[] = [];
|
||||
@ -279,6 +287,8 @@ export const TableProfilerProvider = ({
|
||||
splitTestCases,
|
||||
customMetric,
|
||||
onCustomMetricUpdate: handleUpdateCustomMetrics,
|
||||
onDateRangeChange: handleDateRangeChange,
|
||||
dateRangeObject,
|
||||
};
|
||||
}, [
|
||||
isTestsLoading,
|
||||
@ -291,6 +301,7 @@ export const TableProfilerProvider = ({
|
||||
onTestCaseUpdate,
|
||||
splitTestCases,
|
||||
customMetric,
|
||||
dateRangeObject,
|
||||
]);
|
||||
|
||||
return (
|
||||
|
||||
@ -279,5 +279,7 @@ declare module 'Models' {
|
||||
export interface DateRangeObject {
|
||||
startTs: number;
|
||||
endTs: number;
|
||||
key?: string;
|
||||
title?: string;
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,7 +237,7 @@ const IncidentManagerPage = () => {
|
||||
};
|
||||
|
||||
if (!isEqual(value, dateRangeObject)) {
|
||||
setFilters((pre) => ({ ...pre, ...value }));
|
||||
setFilters((pre) => ({ ...pre, ...dateRangeObject }));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user