Skip to content

Commit

Permalink
(timechart) use date range based on buckets for query assist
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuali925 committed May 1, 2024
1 parent 407f059 commit 55a4cb1
Show file tree
Hide file tree
Showing 17 changed files with 331 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import PPLService from '../../../../services/requests/ppl';
import { useFetchEvents } from '../../hooks';
import { redoQuery } from '../../utils/utils';
import { FlyoutButton } from './docViewRow';
import { HitsCounter } from '../hits_counter/hits_counter';
import { HitsCounter } from '../timechart/hits_counter';

export interface DataGridProps {
http: HttpSetup;
Expand Down
41 changes: 19 additions & 22 deletions public/components/event_analytics/explorer/explorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
EuiText,
} from '@elastic/eui';
import { FormattedMessage } from '@osd/i18n/react';
import { createBrowserHistory } from 'history';
import _, { isEmpty, isEqual, reduce } from 'lodash';
import React, {
ReactElement,
Expand All @@ -32,7 +33,6 @@ import React, {
useState,
} from 'react';
import { batch, useDispatch, useSelector } from 'react-redux';
import { createBrowserHistory } from 'history';
import { LogExplorerRouterContext } from '..';
import {
DEFAULT_DATA_SOURCE_TYPE,
Expand Down Expand Up @@ -127,13 +127,11 @@ import { formatError, getContentTabTitle } from '../utils/utils';
import { DataSourceSelection } from './datasources/datasources_selection';
import { DirectQueryRunning } from './direct_query_running';
import { DataGrid } from './events_views/data_grid';
import { HitsCounter } from './hits_counter/hits_counter';
import { LogPatterns } from './log_patterns/log_patterns';
import { NoResults } from './no_results';
import { ObservabilitySideBar } from './sidebar/observability_sidebar';
import { TimechartHeader } from './timechart_header';
import { getTimeRangeFromCountDistribution, HitsCounter, Timechart } from './timechart';
import { ExplorerVisualizations } from './visualizations';
import { CountDistribution } from './visualizations/count_distribution';
import { DirectQueryVisualization } from './visualizations/direct_query_vis';

export const Explorer = ({
Expand Down Expand Up @@ -527,6 +525,19 @@ export const Explorer = ({
handleQuerySearch();
};

/**
* If query assist is enabled, the time range is fixed to
* QUERY_ASSIST_START_TIME and QUERY_ASSIST_END_TIME and not useful. Return
* the time range based on aggregation buckets instead.
*
* @returns startTime and endTime
*/
const getTimeChartRange = (): { startTime?: string; endTime?: string } => {
if (!coreRefs.queryAssistEnabled) return { startTime, endTime };
const { startTime: start, endTime: end } = getTimeRangeFromCountDistribution(countDistribution);
return { startTime: start ?? startTime, endTime: end ?? endTime };
};

const totalHits: number = useMemo(() => {
if (isLiveTailOn && countDistribution?.data) {
const hits = reduce(
Expand Down Expand Up @@ -558,13 +569,9 @@ export const Explorer = ({
<EuiPanel hasBorder={false} hasShadow={false} paddingSize="s" color="transparent">
{countDistribution?.data && !isLiveTailOnRef.current && (
<EuiPanel>
<HitsCounter
hits={_.sum(countDistribution.data?.['count()'])}
showResetButton={false}
onResetQuery={() => {}}
/>
<TimechartHeader
options={timeIntervalOptions}
<Timechart
countDistribution={countDistribution}
timeIntervalOptions={timeIntervalOptions}
onChangeInterval={(selectedIntrv) => {
const intervalOptionsIndex = timeIntervalOptions.findIndex(
(item) => item.value === selectedIntrv
Expand All @@ -580,20 +587,10 @@ export const Explorer = ({
selectedIntervalRef.current = timeIntervalOptions[intervalOptionsIndex];
getPatterns(intrv, getErrorHandler('Error fetching patterns'));
}}
stateInterval={
countDistribution.selectedInterval || selectedIntervalRef.current?.value
}
startTime={startTime}
endTime={endTime}
/>
<EuiSpacer size="s" />
<CountDistribution
countDistribution={countDistribution}
selectedInterval={
countDistribution.selectedInterval || selectedIntervalRef.current?.value
}
startTime={startTime}
endTime={endTime}
{...getTimeChartRange()}
/>
</EuiPanel>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<Timechart /> spec should match snapshot 1`] = `
<div>
<div
class="euiFlexGroup euiFlexGroup--gutterSmall euiFlexGroup--alignItemsCenter euiFlexGroup--justifyContentCenter euiFlexGroup--directionRow dscResultCount"
>
<div
class="euiFlexItem euiFlexItem--flexGrowZero"
>
<div
class="euiText euiText--medium"
>
<strong
data-test-subj="discoverQueryHits"
>
194
</strong>
hits
</div>
</div>
</div>
<div
class="euiFlexGroup euiFlexGroup--gutterSmall euiFlexGroup--alignItemsCenter euiFlexGroup--justifyContentCenter euiFlexGroup--directionRow euiFlexGroup--responsive"
>
<div
class="euiFlexItem euiFlexItem--flexGrowZero"
>
<span
class="euiToolTipAnchor"
>
<div
class="euiText euiText--small"
data-test-subj="discoverIntervalDateRange"
>
Jan 1, 2024 @ 00:00:00.000 - Jan 1, 2024 @ 00:00:00.000
</div>
</span>
</div>
<div
class="euiFlexItem euiFlexItem--flexGrowZero"
>
<div
class="euiFormControlLayout euiFormControlLayout--compressed"
>
<div
class="euiFormControlLayout__childrenWrapper"
>
<select
aria-label="Time interval"
class="euiSelect euiSelect--compressed"
data-test-subj="eventAnalytics__EventIntervalSelect"
id="dscResultsIntervalSelector"
>
<option
value="m"
>
Minute
</option>
<option
value="h"
>
Hour
</option>
<option
value="d"
>
Day
</option>
<option
value="w"
>
Week
</option>
<option
value="M"
>
Month
</option>
<option
value="y"
>
Year
</option>
</select>
<div
class="euiFormControlLayoutIcons euiFormControlLayoutIcons--right"
>
<span
class="euiFormControlLayoutCustomIcon"
>
<svg
aria-hidden="true"
class="euiIcon euiIcon--small euiFormControlLayoutCustomIcon__icon"
focusable="false"
height="16"
role="img"
viewBox="0 0 16 16"
width="16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M13.069 5.157 8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0Z"
fill-rule="non-zero"
/>
</svg>
</span>
</div>
</div>
</div>
</div>
</div>
<div
class="euiSpacer euiSpacer--s"
/>
<div
id="explorerPlotComponent"
style="width: 100%; height: 100%;"
/>
</div>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { fireEvent, render } from '@testing-library/react';
import React, { ComponentProps } from 'react';
import { Timechart } from '../timechart';

const renderTimechart = (overrideProps: Partial<ComponentProps<typeof Timechart>> = {}) => {
const props: jest.Mocked<ComponentProps<typeof Timechart>> = Object.assign<
ComponentProps<typeof Timechart>,
Partial<ComponentProps<typeof Timechart>>
>(
{
countDistribution: {
selectedInterval: 'y',
data: { 'count()': [194], 'span(timestamp,1y)': ['2024-01-01 00:00:00'] },
metadata: {
fields: [
{ name: 'count()', type: 'integer' },
{ name: 'span(timestamp,1y)', type: 'timestamp' },
],
},
size: 1,
status: 200,
jsonData: [{ 'count()': 194, 'span(timestamp,1y)': '2024-01-01 00:00:00' }],
},
timeIntervalOptions: [
{ text: 'Minute', value: 'm' },
{ text: 'Hour', value: 'h' },
{ text: 'Day', value: 'd' },
{ text: 'Week', value: 'w' },
{ text: 'Month', value: 'M' },
{ text: 'Year', value: 'y' },
],
onChangeInterval: jest.fn(),
selectedInterval: 'y',
startTime: '2024-01-01 00:00:00',
endTime: '2024-01-01 00:00:00',
},
overrideProps
);
const component = render(<Timechart {...props} />);
return { component, props };
};

describe('<Timechart /> spec', () => {
it('should change to week', () => {
const { component, props } = renderTimechart();
fireEvent.change(component.getByTestId('eventAnalytics__EventIntervalSelect'), {
target: { value: 'w' },
});
expect(props.onChangeInterval).toBeCalledWith('w');
});

it('should match snapshot', () => {
const { component } = renderTimechart();
expect(component.container).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { getTimeRangeFromCountDistribution } from '../utils';

describe('getTimeRangeFromCountDistribution', () => {
it('gets from first and last element of span', () => {
const results = getTimeRangeFromCountDistribution({
data: {
'count()': [194],
'span(timestamp,1d)': ['2024-01-01 00:00:00', '2024-01-02 00:00:00', '2024-01-03 00:00:00'],
},
metadata: {
fields: [
{ name: 'count()', type: 'integer' },
{ name: 'span(timestamp,1d)', type: 'timestamp' },
],
},
});

expect(results).toMatchInlineSnapshot(`
Object {
"endTime": "2024-01-03 00:00:00",
"startTime": "2024-01-01 00:00:00",
}
`);
});

it('handles empty inputs and returns undefined', () => {
const results = getTimeRangeFromCountDistribution({
data: {
'count()': [194],
'span(timestamp,1d)': [],
},
metadata: {
fields: [
{ name: 'count()', type: 'integer' },
{ name: 'span(timestamp,1d)', type: 'timestamp' },
],
},
});

expect(results).toMatchInlineSnapshot(`
Object {
"endTime": undefined,
"startTime": undefined,
}
`);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import React from 'react';
import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
import { FormattedMessage, I18nProvider } from '@osd/i18n/react';
import { i18n } from '@osd/i18n';
import { formatNumWithCommas } from '../../../common/helpers';
import { formatNumWithCommas } from '../../../../common/helpers';

export interface HitsCounterProps {
/**
Expand Down
8 changes: 8 additions & 0 deletions public/components/event_analytics/explorer/timechart/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

export { HitsCounter } from './hits_counter/hits_counter';
export { Timechart } from './timechart';
export { getTimeRangeFromCountDistribution } from './utils';
Loading

0 comments on commit 55a4cb1

Please sign in to comment.