Skip to content

Commit

Permalink
[Backport 2.x] feat: enable data grid in Chatbot (opensearch-project#…
Browse files Browse the repository at this point in the history
…1341) (opensearch-project#1383)

Signed-off-by: SuZhou-Joe <[email protected]>
  • Loading branch information
SuZhou-Joe authored Jan 25, 2024
1 parent d4d8dbc commit b3430d1
Show file tree
Hide file tree
Showing 9 changed files with 412 additions and 172 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
EuiDescriptionListDescription,
EuiDescriptionListTitle,
EuiPanel,
EuiDataGridProps,
} from '@elastic/eui';
import moment from 'moment';
import React, { Fragment, MutableRefObject, useEffect, useRef, useState } from 'react';
Expand All @@ -27,11 +28,10 @@ import { useFetchEvents } from '../../hooks';
import { redoQuery } from '../../utils/utils';
import { FlyoutButton } from './docViewRow';

interface DataGridProps {
export interface DataGridProps {
http: HttpSetup;
pplService: PPLService;
rows: any[];
rowsAll: any[];
explorerFields: IExplorerFields;
timeStampField: string;
rawQuery: string;
Expand All @@ -40,8 +40,12 @@ interface DataGridProps {
startTime: string;
endTime: string;
storedSelectedColumns: IField[];
formatGridColumn?: (columns: EuiDataGridColumn[]) => EuiDataGridColumn[];
OuiDataGridProps?: Partial<EuiDataGridProps>;
}

const defaultFormatGrid = (columns: EuiDataGridColumn[]) => columns;

export function DataGrid(props: DataGridProps) {
const {
http,
Expand All @@ -54,6 +58,8 @@ export function DataGrid(props: DataGridProps) {
requestParams,
startTime,
endTime,
formatGridColumn = defaultFormatGrid,
OuiDataGridProps,
} = props;
const { fetchEvents } = useFetchEvents({
pplService,
Expand Down Expand Up @@ -120,7 +126,7 @@ export function DataGrid(props: DataGridProps) {
});
}
});
return columns;
return formatGridColumn(columns);
};

// used for which columns are visible and their order
Expand Down Expand Up @@ -258,6 +264,7 @@ export function DataGrid(props: DataGridProps) {
showStyleSelector: false,
}}
rowHeightsOptions={rowHeightsOptions()}
{...OuiDataGridProps}
/>
</div>
</EuiPanel>
Expand Down
7 changes: 4 additions & 3 deletions public/components/event_analytics/utils/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -422,10 +422,11 @@ export const redoQuery = (
const start = datemath.parse(startTime)?.utc().format(DATE_PICKER_FORMAT);
const end = datemath.parse(endTime, { roundUp: true })?.utc().format(DATE_PICKER_FORMAT);
const tokens = rawQuery.replaceAll(PPL_NEWLINE_REGEX, '').match(PPL_INDEX_INSERT_POINT_REGEX);
const timeRange = timeStampField
? `| where ${timeStampField} >= '${start}' and ${timeStampField} <= '${end}'`
: '';

finalQuery = `${tokens![1]}=${
tokens![2]
} | where ${timeStampField} >= '${start}' and ${timeStampField} <= '${end}'`;
finalQuery = `${tokens![1]}=${tokens![2]} ${timeRange}`;

finalQuery += tokens![3];

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<DataGridContainer /> should render empty when rawQuery is not provided 1`] = `<div />`;

exports[`<DataGridContainer /> should render when all props are provided 1`] = `
<div>
<div
style="overflow-x: hidden;"
>
<div
data-test-subj="test"
>
{
"http": {},
"pplService": {},
"rows": [
{
"timestamp": "now",
"count": 1
}
],
"explorerFields": {
"selectedFields": [],
"unselectedFields": [],
"availableFields": [],
"queriedFields": []
},
"timeStampField": "timestamp",
"totalHits": 1,
"requestParams": {
"tabId": "OBSERVABILITY_DEFAULT_TAB"
},
"startTime": "",
"endTime": "now",
"storedSelectedColumns": [],
"OuiDataGridProps": {
"gridStyle": {
"fontSize": "s",
"cellPadding": "s"
},
"minSizeForControls": 300,
"rowHeightsOptions": {
"defaultHeight": 80
}
},
"rawQuery": "source=foo",
"columns": [
{
"id": "timestamp",
"isSortable": true,
"display": "Time",
"schema": "datetime",
"initialWidth": 50
},
{
"id": "_source",
"isSortable": false,
"display": "Source",
"schema": "_source"
}
]
}
</div>
</div>
</div>
`;

exports[`<DataGridContainer /> should switch props when in full screen mode 1`] = `
<div>
<div
style="overflow-x: hidden;"
>
<div
data-test-subj="test"
>
{
"http": {},
"pplService": {},
"rows": [
{
"timestamp": "now",
"count": 1
}
],
"explorerFields": {
"selectedFields": [],
"unselectedFields": [],
"availableFields": [],
"queriedFields": []
},
"timeStampField": "timestamp",
"totalHits": 1,
"requestParams": {
"tabId": "OBSERVABILITY_DEFAULT_TAB"
},
"startTime": "",
"endTime": "now",
"storedSelectedColumns": [],
"OuiDataGridProps": {
"gridStyle": {},
"minSizeForControls": 300,
"rowHeightsOptions": {}
},
"rawQuery": "source=foo",
"columns": [
{
"id": "timestamp",
"isSortable": true,
"display": "Time",
"schema": "datetime",
"initialWidth": 200
},
{
"id": "_source",
"isSortable": false,
"display": "Source",
"schema": "_source"
}
]
}
</div>
</div>
</div>
`;
122 changes: 122 additions & 0 deletions public/dependencies/components/data_grid_container.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { render, waitFor } from '@testing-library/react';
import { Provider } from 'react-redux';
import { DataGridContainer } from './data_grid_container';
import { RenderProps } from '../../types';
import { store } from '../../framework/redux/store';
import { DataGridProps } from '../../components/event_analytics/explorer/events_views/data_grid';
import {
DEFAULT_SOURCE_COLUMN as mock_DEFAULT_SOURCE_COLUMN,
DEFAULT_TIMESTAMP_COLUMN as mock_DEFAULT_TIMESTAMP_COLUMN,
} from '../../../common/constants/explorer';

jest.mock('../../components/event_analytics/utils/utils', () => ({
redoQuery: (...args: any[]) => {
args[7]([
{
timestamp: 'now',
count: 1,
},
]);
},
}));

jest.mock('../../../common/utils', () => ({
getPPLService: () => ({}),
getOSDHttp: () => ({}),
}));

jest.mock('../../components/event_analytics/explorer/events_views/data_grid', () => ({
DataGrid: (props: DataGridProps) => {
const columnsResult = props.formatGridColumn?.([
mock_DEFAULT_TIMESTAMP_COLUMN,
mock_DEFAULT_SOURCE_COLUMN,
]);
return (
<div data-test-subj="test">
{JSON.stringify({ ...props, columns: columnsResult }, null, 2)}
</div>
);
},
}));

describe('<DataGridContainer />', () => {
it('should render when all props are provided', async () => {
const { container, findByTestId } = render(
<Provider store={store}>
<DataGridContainer
rawQuery="source=foo"
renderProps={{
props: {
message: {
type: 'output',
contentType: 'ppl_data_grid',
content: 'source=foo',
},
},
chatContext: {
flyoutFullScreen: false,
} as RenderProps['chatContext'],
}}
/>
</Provider>
);
await findByTestId('test');
expect(container).toMatchSnapshot();
});

it('should render empty when rawQuery is not provided', async () => {
const { container, queryByTestId } = render(
<Provider store={store}>
<DataGridContainer
rawQuery=""
renderProps={{
props: {
message: {
type: 'output',
contentType: 'ppl_data_grid',
content: 'source=foo',
},
},
chatContext: {
flyoutFullScreen: false,
} as RenderProps['chatContext'],
}}
/>
</Provider>
);
await waitFor(() => {
expect(queryByTestId('test')).toBeNull();
});
expect(container).toMatchSnapshot();
});

it('should switch props when in full screen mode', async () => {
const { container, findByTestId } = render(
<Provider store={store}>
<DataGridContainer
rawQuery="source=foo"
renderProps={{
props: {
message: {
type: 'output',
contentType: 'ppl_data_grid',
content: 'source=foo',
},
},
chatContext: {
flyoutFullScreen: true,
} as RenderProps['chatContext'],
}}
/>
</Provider>
);
await findByTestId('test');
expect(container).toMatchSnapshot();
});
});
Loading

0 comments on commit b3430d1

Please sign in to comment.