mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 18:51:07 -04:00
[ES|QL][Controls] Listen to ?_tstart and ?_tend named params (#225054)
## Summary Passes the timeRange into the `getESQLResults` in order the queries witj `_tstart` and `_tend` to work properly <img width="1280" alt="image" src="https://github.com/user-attachments/assets/4f03b0c7-6d3c-40e2-8775-b2d9b2f22c02" /> ### Checklist - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
This commit is contained in:
parent
f9d2c33852
commit
a07c4608e4
7 changed files with 75 additions and 8 deletions
|
@ -102,7 +102,11 @@ export class EsqlPlugin implements Plugin<{}, EsqlPluginStart> {
|
|||
const { CreateESQLControlAction } = await import(
|
||||
'./triggers/esql_controls/esql_control_action'
|
||||
);
|
||||
const createESQLControlAction = new CreateESQLControlAction(core, data.search.search);
|
||||
const createESQLControlAction = new CreateESQLControlAction(
|
||||
core,
|
||||
data.search.search,
|
||||
data.query.timefilter.timefilter
|
||||
);
|
||||
return createESQLControlAction;
|
||||
});
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
import React, { useCallback, useMemo, useState, useEffect } from 'react';
|
||||
import { EuiFlyoutBody } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import type { TimeRange } from '@kbn/es-query';
|
||||
import { ESQLVariableType, type ESQLControlVariable, type ESQLControlState } from '@kbn/esql-types';
|
||||
import { getValuesFromQueryField } from '@kbn/esql-utils';
|
||||
import { EsqlControlType, VariableNamePrefix } from '@kbn/esql-types';
|
||||
|
@ -35,6 +36,7 @@ interface ESQLControlsFlyoutProps {
|
|||
initialVariableType: ESQLVariableType;
|
||||
queryString: string;
|
||||
esqlVariables: ESQLControlVariable[];
|
||||
timeRange?: TimeRange;
|
||||
onSaveControl?: (controlState: ESQLControlState, updatedQuery: string) => Promise<void>;
|
||||
onCancelControl?: () => void;
|
||||
cursorPosition?: monaco.Position;
|
||||
|
@ -47,6 +49,7 @@ export function ESQLControlsFlyout({
|
|||
initialVariableType,
|
||||
queryString,
|
||||
esqlVariables,
|
||||
timeRange,
|
||||
onSaveControl,
|
||||
onCancelControl,
|
||||
cursorPosition,
|
||||
|
@ -185,6 +188,7 @@ export function ESQLControlsFlyout({
|
|||
setControlState={setControlState}
|
||||
search={search}
|
||||
valuesRetrieval={valuesField}
|
||||
timeRange={timeRange}
|
||||
/>
|
||||
) : (
|
||||
<IdentifierControlForm
|
||||
|
|
|
@ -8,12 +8,13 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render, within, fireEvent } from '@testing-library/react';
|
||||
import { render, within, fireEvent, waitFor } from '@testing-library/react';
|
||||
import { dataPluginMock } from '@kbn/data-plugin/public/mocks';
|
||||
import { IUiSettingsClient } from '@kbn/core/public';
|
||||
import { monaco } from '@kbn/monaco';
|
||||
import { coreMock } from '@kbn/core/server/mocks';
|
||||
import { ESQLVariableType, EsqlControlType, ESQLControlState } from '@kbn/esql-types';
|
||||
import { getESQLResults } from '@kbn/esql-utils';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
|
||||
import { ESQLControlsFlyout } from '.';
|
||||
|
@ -294,6 +295,33 @@ describe('ValueControlForm', () => {
|
|||
const identifiersOptionsDropdown = await findByTestId('esqlIdentifiersOptions');
|
||||
expect(identifiersOptionsDropdown).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should call getESQLResults with the provided timeRange when query is submitted', async () => {
|
||||
const mockTimeRange = { from: '2023-01-01', to: '2023-01-02' };
|
||||
|
||||
render(
|
||||
<IntlProvider locale="en">
|
||||
<ESQLControlsFlyout
|
||||
initialVariableType={ESQLVariableType.VALUES}
|
||||
queryString="FROM foo | WHERE field =="
|
||||
onSaveControl={jest.fn()}
|
||||
closeFlyout={jest.fn()}
|
||||
onCancelControl={jest.fn()}
|
||||
search={searchMock}
|
||||
esqlVariables={[]}
|
||||
timeRange={mockTimeRange}
|
||||
/>
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getESQLResults).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
timeRange: mockTimeRange,
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -20,6 +20,7 @@ import {
|
|||
EuiPanel,
|
||||
} from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import type { TimeRange } from '@kbn/es-query';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import type { ISearchGeneric } from '@kbn/search-types';
|
||||
import {
|
||||
|
@ -46,12 +47,15 @@ interface ValueControlFormProps {
|
|||
setControlState: (state: ESQLControlState) => void;
|
||||
initialState?: ESQLControlState;
|
||||
valuesRetrieval?: string;
|
||||
timeRange?: TimeRange;
|
||||
}
|
||||
|
||||
const SUGGESTED_INTERVAL_VALUES = ['5 minutes', '1 hour', '1 day', '1 week', '1 month'];
|
||||
const INITIAL_EMPTY_STATE_QUERY = `/** Example
|
||||
To get the agent field values use:
|
||||
FROM logs-* | STATS BY agent
|
||||
FROM logs-*
|
||||
| WHERE @timestamp <=?_tend and @timestamp >?_tstart
|
||||
| STATS BY agent
|
||||
*/`;
|
||||
|
||||
export function ValueControlForm({
|
||||
|
@ -63,6 +67,7 @@ export function ValueControlForm({
|
|||
search,
|
||||
setControlState,
|
||||
valuesRetrieval,
|
||||
timeRange,
|
||||
}: ValueControlFormProps) {
|
||||
const isMounted = useMountedState();
|
||||
|
||||
|
@ -157,6 +162,7 @@ export function ValueControlForm({
|
|||
signal: undefined,
|
||||
filter: undefined,
|
||||
dropNullColumns: true,
|
||||
timeRange,
|
||||
}).then((results) => {
|
||||
if (!isMounted()) {
|
||||
return;
|
||||
|
@ -185,7 +191,7 @@ export function ValueControlForm({
|
|||
setEsqlQueryErrors([e]);
|
||||
}
|
||||
},
|
||||
[isMounted, search]
|
||||
[isMounted, search, timeRange]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -16,6 +16,7 @@ import { CreateESQLControlAction } from './esql_control_action';
|
|||
describe('update ES|QL query action', () => {
|
||||
const dataMock = dataPluginMock.createStartContract();
|
||||
const searchMock = dataMock.search.search;
|
||||
const timefilterMock = dataMock.query.timefilter.timefilter;
|
||||
const core = coreMock.createStart();
|
||||
const coreStart = {
|
||||
...core,
|
||||
|
@ -28,7 +29,11 @@ describe('update ES|QL query action', () => {
|
|||
} as CoreStart;
|
||||
describe('compatibility check', () => {
|
||||
it('is compatible if queryString is given', async () => {
|
||||
const createControlAction = new CreateESQLControlAction(coreStart, searchMock);
|
||||
const createControlAction = new CreateESQLControlAction(
|
||||
coreStart,
|
||||
searchMock,
|
||||
timefilterMock
|
||||
);
|
||||
const isCompatible = await createControlAction.isCompatible({
|
||||
queryString: 'FROM index',
|
||||
variableType: ESQLVariableType.FIELDS,
|
||||
|
@ -48,7 +53,11 @@ describe('update ES|QL query action', () => {
|
|||
},
|
||||
},
|
||||
} as CoreStart;
|
||||
const createControlAction = new CreateESQLControlAction(coreStartESQLDidabled, searchMock);
|
||||
const createControlAction = new CreateESQLControlAction(
|
||||
coreStartESQLDidabled,
|
||||
searchMock,
|
||||
timefilterMock
|
||||
);
|
||||
const isCompatible = await createControlAction.isCompatible({
|
||||
queryString: '',
|
||||
variableType: ESQLVariableType.FIELDS,
|
||||
|
@ -59,7 +68,11 @@ describe('update ES|QL query action', () => {
|
|||
});
|
||||
|
||||
it('is incompatible if variableType is invalid', async () => {
|
||||
const createControlAction = new CreateESQLControlAction(coreStart, searchMock);
|
||||
const createControlAction = new CreateESQLControlAction(
|
||||
coreStart,
|
||||
searchMock,
|
||||
timefilterMock
|
||||
);
|
||||
const isCompatible = await createControlAction.isCompatible({
|
||||
queryString: 'FROM index',
|
||||
variableType: 'INVALID_TYPE' as ESQLVariableType,
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import type { Action } from '@kbn/ui-actions-plugin/public';
|
||||
import type { CoreStart } from '@kbn/core/public';
|
||||
import type { TimefilterContract } from '@kbn/data-plugin/public';
|
||||
import type { ISearchGeneric } from '@kbn/search-types';
|
||||
import type { ESQLVariableType, ESQLControlState } from '@kbn/esql-types';
|
||||
import type { ESQLControlVariable } from '@kbn/esql-types';
|
||||
|
@ -32,7 +33,11 @@ export class CreateESQLControlAction implements Action<Context> {
|
|||
public id = ACTION_CREATE_ESQL_CONTROL;
|
||||
public order = 50;
|
||||
|
||||
constructor(protected readonly core: CoreStart, protected readonly search: ISearchGeneric) {}
|
||||
constructor(
|
||||
protected readonly core: CoreStart,
|
||||
protected readonly search: ISearchGeneric,
|
||||
protected readonly timefilter: TimefilterContract
|
||||
) {}
|
||||
|
||||
public getDisplayName(): string {
|
||||
return i18n.translate('esql.createESQLControlLabel', {
|
||||
|
@ -61,6 +66,7 @@ export class CreateESQLControlAction implements Action<Context> {
|
|||
queryString,
|
||||
core: this.core,
|
||||
search: this.search,
|
||||
timefilter: this.timefilter,
|
||||
variableType,
|
||||
esqlVariables,
|
||||
onSaveControl,
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
import React, { lazy, Suspense, Fragment } from 'react';
|
||||
import { IncompatibleActionError } from '@kbn/ui-actions-plugin/public';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import type { TimefilterContract } from '@kbn/data-plugin/public';
|
||||
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
|
||||
import type { CoreStart } from '@kbn/core/public';
|
||||
import type { ISearchGeneric } from '@kbn/search-types';
|
||||
|
@ -22,6 +23,7 @@ interface Context {
|
|||
queryString: string;
|
||||
core: CoreStart;
|
||||
search: ISearchGeneric;
|
||||
timefilter: TimefilterContract;
|
||||
variableType: ESQLVariableType;
|
||||
esqlVariables: ESQLControlVariable[];
|
||||
onSaveControl?: (controlState: ESQLControlState, updatedQuery: string) => Promise<void>;
|
||||
|
@ -44,6 +46,7 @@ export async function executeAction({
|
|||
queryString,
|
||||
core,
|
||||
search,
|
||||
timefilter,
|
||||
variableType,
|
||||
esqlVariables,
|
||||
onSaveControl,
|
||||
|
@ -62,6 +65,8 @@ export async function executeAction({
|
|||
};
|
||||
});
|
||||
|
||||
const timeRange = timefilter.getTime();
|
||||
|
||||
const deps = await untilPluginStartServicesReady();
|
||||
const handle = core.overlays.openFlyout(
|
||||
toMountPoint(
|
||||
|
@ -85,6 +90,7 @@ export async function executeAction({
|
|||
cursorPosition={cursorPosition}
|
||||
initialState={initialState}
|
||||
esqlVariables={esqlVariables}
|
||||
timeRange={timeRange}
|
||||
/>
|
||||
</Suspense>
|
||||
</KibanaContextProvider>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue