Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move Metrics Explorer date span, range into redux metrics-slice #1105

Merged
merged 1 commit into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions public/components/metrics/helpers/__tests__/utils.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,26 +34,6 @@ import _ from 'lodash';
describe('Utils helper functions', () => {
configure({ adapter: new Adapter() });

it('validates onTimeChange function', () => {
const setRecentlyUsedRanges = jest.fn((x) => x);
const setStart = jest.fn();
const setEnd = jest.fn();
const recentlyUsedRanges: DurationRange[] = [];
onTimeChange(
'2022-01-30T18:44:40.577Z',
'2022-02-25T19:18:33.075Z',
recentlyUsedRanges,
setRecentlyUsedRanges,
setStart,
setEnd
);
expect(setRecentlyUsedRanges).toHaveBeenCalledWith([
{ start: '2022-01-30T18:44:40.577Z', end: '2022-02-25T19:18:33.075Z' },
]);
expect(setStart).toHaveBeenCalledWith('2022-01-30T18:44:40.577Z');
expect(setEnd).toHaveBeenCalledWith('2022-02-25T19:18:33.075Z');
});

it('validates getNewVizDimensions function', () => {
expect(getNewVizDimensions([])).toMatchObject({
x: 0,
Expand Down
36 changes: 9 additions & 27 deletions public/components/metrics/helpers/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,6 @@ import { VisualizationType } from '../../../../common/types/custom_panels';
import { DEFAULT_METRIC_HEIGHT, DEFAULT_METRIC_WIDTH } from '../../../../common/constants/metrics';
import { updateQuerySpanInterval } from '../../custom_panels/helpers/utils';

export const onTimeChange = (
start: ShortDate,
end: ShortDate,
recentlyUsedRanges: DurationRange[],
setRecentlyUsedRanges: React.Dispatch<React.SetStateAction<DurationRange[]>>,
setStart: React.Dispatch<React.SetStateAction<string>>,
setEnd: React.Dispatch<React.SetStateAction<string>>
) => {
const recentlyUsedRange = recentlyUsedRanges.filter((recentlyUsedRange) => {
const isDuplicate = recentlyUsedRange.start === start && recentlyUsedRange.end === end;
return !isDuplicate;
});
recentlyUsedRange.unshift({ start, end });
setStart(start);
setEnd(end);
setRecentlyUsedRanges(recentlyUsedRange.slice(0, 9));
};

// PPL Service requestor
export const pplServiceRequestor = (pplService: PPLService, finalQuery: string) => {
return pplService.fetch({ query: finalQuery, format: VISUALIZATION }).catch((error: Error) => {
Expand All @@ -58,21 +40,21 @@ export const getVisualizations = (http: CoreStart['http']) => {
});
};

interface boxType {
interface BoxType {
x1: number;
y1: number;
x2: number;
y2: number;
}

const calculatOverlapArea = (bb1: boxType, bb2: boxType) => {
const x_left = Math.max(bb1.x1, bb2.x1);
const y_top = Math.max(bb1.y1, bb2.y1);
const x_right = Math.min(bb1.x2, bb2.x2);
const y_bottom = Math.min(bb1.y2, bb2.y2);
const calculatOverlapArea = (bb1: BoxType, bb2: BoxType) => {
const xLeft = Math.max(bb1.x1, bb2.x1);
const yTop = Math.max(bb1.y1, bb2.y1);
const xRight = Math.min(bb1.x2, bb2.x2);
const yBottom = Math.min(bb1.y2, bb2.y2);

if (x_right < x_left || y_bottom < y_top) return 0;
return (x_right - x_left) * (y_bottom - y_top);
if (xRight < xLeft || yBottom < yTop) return 0;
return (xRight - xLeft) * (yBottom - yTop);
};

const getTotalOverlapArea = (panelVisualizations: MetricType[]) => {
Expand Down Expand Up @@ -149,7 +131,7 @@ export const mergeLayoutAndMetrics = (

for (let i = 0; i < newVisualizationList.length; i++) {
for (let j = 0; j < layout.length; j++) {
if (newVisualizationList[i].id == layout[j].i) {
if (newVisualizationList[i].id === layout[j].i) {
newPanelVisualizations.push({
...newVisualizationList[i],
x: layout[j].x,
Expand Down
44 changes: 0 additions & 44 deletions public/components/metrics/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@ import {
OnTimeChangeProps,
ShortDate,
} from '@elastic/eui';
import { DurationRange } from '@elastic/eui/src/components/date_picker/types';
import React, { ReactChild, useEffect, useState } from 'react';
import { HashRouter, Route, RouteComponentProps } from 'react-router-dom';
import { StaticContext } from 'react-router-dom';
import { useSelector } from 'react-redux';
import { ChromeBreadcrumb, Toast } from '../../../../../src/core/public';
import { onTimeChange } from './helpers/utils';
import { Sidebar } from './sidebar/sidebar';
import { EmptyMetricsView } from './view/empty_view';
import PPLService from '../../services/requests/ppl';
Expand All @@ -44,19 +42,10 @@ export const Home = ({ chrome, parentBreadcrumb }: MetricsProps) => {
const selectedMetrics = useSelector(selectedMetricsSelector);
const metricsLayout = useSelector(metricsLayoutSelector);

// Date picker constants
const [recentlyUsedRanges, setRecentlyUsedRanges] = useState<DurationRange[]>([]);
const [startTime, setStartTime] = useState<ShortDate>('now-1d');
const [endTime, setEndTime] = useState<ShortDate>('now');

// Top panel
const [IsTopPanelDisabled, setIsTopPanelDisabled] = useState(false);
const [editMode, setEditMode] = useState(false);
const [onRefresh, setOnRefresh] = useState(false);
const [editActionType, setEditActionType] = useState('');
const [resolutionValue, setResolutionValue] = useState(resolutionOptions[2].value);
const [spanValue, setSpanValue] = useState(1);
const resolutionSelectId = htmlIdGenerator('resolutionSelect')();
const [toasts, setToasts] = useState<Toast[]>([]);
const [toastRightSide, setToastRightSide] = useState<boolean>(true);

Expand All @@ -69,26 +58,6 @@ export const Home = ({ chrome, parentBreadcrumb }: MetricsProps) => {
setToasts([...toasts, { id: new Date().toISOString(), title, text, color } as Toast]);
};

const onRefreshFilters = () => {
if (spanValue < 1) {
setToast('Please add a valid span interval', 'danger');
return;
}
setOnRefresh(!onRefresh);
};

const onDatePickerChange = (props: OnTimeChangeProps) => {
onTimeChange(
props.start,
props.end,
recentlyUsedRanges,
setRecentlyUsedRanges,
setStartTime,
setEndTime
);
onRefreshFilters();
};

const onEditClick = (savedVisualizationId: string) => {
window.location.assign(`${observabilityLogsID}#/explorer/${savedVisualizationId}`);
};
Expand Down Expand Up @@ -135,20 +104,11 @@ export const Home = ({ chrome, parentBreadcrumb }: MetricsProps) => {
<EuiPageBody component="div">
<TopMenu
IsTopPanelDisabled={IsTopPanelDisabled}
startTime={startTime}
endTime={endTime}
onDatePickerChange={onDatePickerChange}
recentlyUsedRanges={recentlyUsedRanges}
editMode={editMode}
setEditMode={setEditMode}
setEditActionType={setEditActionType}
panelVisualizations={panelVisualizations}
setPanelVisualizations={setPanelVisualizations}
resolutionValue={resolutionValue}
setResolutionValue={setResolutionValue}
spanValue={spanValue}
setSpanValue={setSpanValue}
resolutionSelectId={resolutionSelectId}
setToast={setToast}
/>
<div className="dscAppContainer">
Expand All @@ -168,13 +128,9 @@ export const Home = ({ chrome, parentBreadcrumb }: MetricsProps) => {
panelVisualizations={panelVisualizations}
setPanelVisualizations={setPanelVisualizations}
editMode={editMode}
startTime={startTime}
endTime={endTime}
moveToEvents={onEditClick}
onRefresh={onRefresh}
editActionType={editActionType}
setEditActionType={setEditActionType}
spanParam={spanValue + resolutionValue}
/>
) : (
<EmptyMetricsView />
Expand Down
48 changes: 43 additions & 5 deletions public/components/metrics/redux/slices/metrics_slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ const initialState = {
dataSources: [OBSERVABILITY_CUSTOM_METRIC],
dataSourceTitles: ['Observability Custom Metrics'],
dataSourceIcons: coloredIconsFrom([OBSERVABILITY_CUSTOM_METRIC]),
dateSpanFilter: {
start: 'now-1d',
end: 'now',
span: 1,
resolution: 'h',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this set anywhere before as the default?

recentlyUsedRanges: [],
},
refresh: 0, // set to new Date() to trigger
};

export const loadMetrics = () => async (dispatch) => {
Expand Down Expand Up @@ -168,20 +176,30 @@ export const metricSlice = createSlice({
setDataSourceIcons: (state, { payload }) => {
state.dataSourceIcons = payload;
},
setDateSpan: (state, { payload }) => {
state.dateSpanFilter = { ...state.dateSpanFilter, ...payload };
},
setRefresh: (state) => {
state.refresh = Date.now();
},
},
});

export const {
setMetrics,
deSelectMetric,
selectMetric,
updateMetricsLayout,
setSearch,
setDataSources,
setDataSourceTitles,
setDataSourceIcons,
setDataSourceTitles,
setDataSources,
setMetrics,
setRefresh,
setSearch,
updateMetricsLayout,
} = metricSlice.actions;

/** private actions */
const { setDateSpan } = metricSlice.actions;

export const availableMetricsSelector = (state) =>
state.metrics.metrics
.filter((metric) => !state.metrics.selected.includes(metric.id))
Expand All @@ -190,6 +208,22 @@ export const availableMetricsSelector = (state) =>
state.metrics.search === '' || metric.name.match(new RegExp(state.metrics.search, 'i'))
);

export const updateStartEndDate = ({ start, end }) => (dispatch, getState) => {
const currentDateSpanFilter = getState().metrics.dateSpanFilter;
const recentlyUsedRange = currentDateSpanFilter.recentlyUsedRanges.filter((r) => {
const isDuplicate = r.start === start && r.end === end;
return !isDuplicate;
});
recentlyUsedRange.unshift({ start, end });

dispatch(setDateSpan({ start, end, recentlyUsedRanges: recentlyUsedRange.slice(0, 9) }));
dispatch(setRefresh());
};

export const updateDateSpan = (props: { span?: string; resolution?: string }) => (dispatch) => {
dispatch(setDateSpan(props)); // specifically use props variable to partial update
};

export const selectedMetricsSelector = (state) =>
state.metrics.selected.map((id) => state.metrics.metrics.find((metric) => metric.id === id));

Expand All @@ -201,4 +235,8 @@ export const metricsLayoutSelector = (state) => state.metrics.metricsLayout;

export const dataSourcesSelector = (state) => state.metrics.dataSources;

export const dateSpanFilterSelector = (state) => state.metrics.dateSpanFilter;

export const refreshSelector = (state) => state.metrics.refresh;

export const metricsReducers = metricSlice.reducer;
Loading
Loading