Skip to content

Commit a07c460

Browse files
authored
[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
1 parent f9d2c33 commit a07c460

File tree

7 files changed

+75
-8
lines changed

7 files changed

+75
-8
lines changed

src/platform/plugins/shared/esql/public/plugin.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,11 @@ export class EsqlPlugin implements Plugin<{}, EsqlPluginStart> {
102102
const { CreateESQLControlAction } = await import(
103103
'./triggers/esql_controls/esql_control_action'
104104
);
105-
const createESQLControlAction = new CreateESQLControlAction(core, data.search.search);
105+
const createESQLControlAction = new CreateESQLControlAction(
106+
core,
107+
data.search.search,
108+
data.query.timefilter.timefilter
109+
);
106110
return createESQLControlAction;
107111
});
108112

src/platform/plugins/shared/esql/public/triggers/esql_controls/control_flyout/index.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import React, { useCallback, useMemo, useState, useEffect } from 'react';
1111
import { EuiFlyoutBody } from '@elastic/eui';
1212
import { css } from '@emotion/react';
13+
import type { TimeRange } from '@kbn/es-query';
1314
import { ESQLVariableType, type ESQLControlVariable, type ESQLControlState } from '@kbn/esql-types';
1415
import { getValuesFromQueryField } from '@kbn/esql-utils';
1516
import { EsqlControlType, VariableNamePrefix } from '@kbn/esql-types';
@@ -35,6 +36,7 @@ interface ESQLControlsFlyoutProps {
3536
initialVariableType: ESQLVariableType;
3637
queryString: string;
3738
esqlVariables: ESQLControlVariable[];
39+
timeRange?: TimeRange;
3840
onSaveControl?: (controlState: ESQLControlState, updatedQuery: string) => Promise<void>;
3941
onCancelControl?: () => void;
4042
cursorPosition?: monaco.Position;
@@ -47,6 +49,7 @@ export function ESQLControlsFlyout({
4749
initialVariableType,
4850
queryString,
4951
esqlVariables,
52+
timeRange,
5053
onSaveControl,
5154
onCancelControl,
5255
cursorPosition,
@@ -185,6 +188,7 @@ export function ESQLControlsFlyout({
185188
setControlState={setControlState}
186189
search={search}
187190
valuesRetrieval={valuesField}
191+
timeRange={timeRange}
188192
/>
189193
) : (
190194
<IdentifierControlForm

src/platform/plugins/shared/esql/public/triggers/esql_controls/control_flyout/value_control_form.test.tsx

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88
*/
99

1010
import React from 'react';
11-
import { render, within, fireEvent } from '@testing-library/react';
11+
import { render, within, fireEvent, waitFor } from '@testing-library/react';
1212
import { dataPluginMock } from '@kbn/data-plugin/public/mocks';
1313
import { IUiSettingsClient } from '@kbn/core/public';
1414
import { monaco } from '@kbn/monaco';
1515
import { coreMock } from '@kbn/core/server/mocks';
1616
import { ESQLVariableType, EsqlControlType, ESQLControlState } from '@kbn/esql-types';
17+
import { getESQLResults } from '@kbn/esql-utils';
1718
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
1819
import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
1920
import { ESQLControlsFlyout } from '.';
@@ -294,6 +295,33 @@ describe('ValueControlForm', () => {
294295
const identifiersOptionsDropdown = await findByTestId('esqlIdentifiersOptions');
295296
expect(identifiersOptionsDropdown).toBeInTheDocument();
296297
});
298+
299+
it('should call getESQLResults with the provided timeRange when query is submitted', async () => {
300+
const mockTimeRange = { from: '2023-01-01', to: '2023-01-02' };
301+
302+
render(
303+
<IntlProvider locale="en">
304+
<ESQLControlsFlyout
305+
initialVariableType={ESQLVariableType.VALUES}
306+
queryString="FROM foo | WHERE field =="
307+
onSaveControl={jest.fn()}
308+
closeFlyout={jest.fn()}
309+
onCancelControl={jest.fn()}
310+
search={searchMock}
311+
esqlVariables={[]}
312+
timeRange={mockTimeRange}
313+
/>
314+
</IntlProvider>
315+
);
316+
317+
await waitFor(() => {
318+
expect(getESQLResults).toHaveBeenCalledWith(
319+
expect.objectContaining({
320+
timeRange: mockTimeRange,
321+
})
322+
);
323+
});
324+
});
297325
});
298326
});
299327
});

src/platform/plugins/shared/esql/public/triggers/esql_controls/control_flyout/value_control_form.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
EuiPanel,
2121
} from '@elastic/eui';
2222
import { css } from '@emotion/react';
23+
import type { TimeRange } from '@kbn/es-query';
2324
import { FormattedMessage } from '@kbn/i18n-react';
2425
import type { ISearchGeneric } from '@kbn/search-types';
2526
import {
@@ -46,12 +47,15 @@ interface ValueControlFormProps {
4647
setControlState: (state: ESQLControlState) => void;
4748
initialState?: ESQLControlState;
4849
valuesRetrieval?: string;
50+
timeRange?: TimeRange;
4951
}
5052

5153
const SUGGESTED_INTERVAL_VALUES = ['5 minutes', '1 hour', '1 day', '1 week', '1 month'];
5254
const INITIAL_EMPTY_STATE_QUERY = `/** Example
5355
To get the agent field values use:
54-
FROM logs-* | STATS BY agent
56+
FROM logs-*
57+
| WHERE @timestamp <=?_tend and @timestamp >?_tstart
58+
| STATS BY agent
5559
*/`;
5660

5761
export function ValueControlForm({
@@ -63,6 +67,7 @@ export function ValueControlForm({
6367
search,
6468
setControlState,
6569
valuesRetrieval,
70+
timeRange,
6671
}: ValueControlFormProps) {
6772
const isMounted = useMountedState();
6873

@@ -157,6 +162,7 @@ export function ValueControlForm({
157162
signal: undefined,
158163
filter: undefined,
159164
dropNullColumns: true,
165+
timeRange,
160166
}).then((results) => {
161167
if (!isMounted()) {
162168
return;
@@ -185,7 +191,7 @@ export function ValueControlForm({
185191
setEsqlQueryErrors([e]);
186192
}
187193
},
188-
[isMounted, search]
194+
[isMounted, search, timeRange]
189195
);
190196

191197
useEffect(() => {

src/platform/plugins/shared/esql/public/triggers/esql_controls/esql_control_action.test.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { CreateESQLControlAction } from './esql_control_action';
1616
describe('update ES|QL query action', () => {
1717
const dataMock = dataPluginMock.createStartContract();
1818
const searchMock = dataMock.search.search;
19+
const timefilterMock = dataMock.query.timefilter.timefilter;
1920
const core = coreMock.createStart();
2021
const coreStart = {
2122
...core,
@@ -28,7 +29,11 @@ describe('update ES|QL query action', () => {
2829
} as CoreStart;
2930
describe('compatibility check', () => {
3031
it('is compatible if queryString is given', async () => {
31-
const createControlAction = new CreateESQLControlAction(coreStart, searchMock);
32+
const createControlAction = new CreateESQLControlAction(
33+
coreStart,
34+
searchMock,
35+
timefilterMock
36+
);
3237
const isCompatible = await createControlAction.isCompatible({
3338
queryString: 'FROM index',
3439
variableType: ESQLVariableType.FIELDS,
@@ -48,7 +53,11 @@ describe('update ES|QL query action', () => {
4853
},
4954
},
5055
} as CoreStart;
51-
const createControlAction = new CreateESQLControlAction(coreStartESQLDidabled, searchMock);
56+
const createControlAction = new CreateESQLControlAction(
57+
coreStartESQLDidabled,
58+
searchMock,
59+
timefilterMock
60+
);
5261
const isCompatible = await createControlAction.isCompatible({
5362
queryString: '',
5463
variableType: ESQLVariableType.FIELDS,
@@ -59,7 +68,11 @@ describe('update ES|QL query action', () => {
5968
});
6069

6170
it('is incompatible if variableType is invalid', async () => {
62-
const createControlAction = new CreateESQLControlAction(coreStart, searchMock);
71+
const createControlAction = new CreateESQLControlAction(
72+
coreStart,
73+
searchMock,
74+
timefilterMock
75+
);
6376
const isCompatible = await createControlAction.isCompatible({
6477
queryString: 'FROM index',
6578
variableType: 'INVALID_TYPE' as ESQLVariableType,

src/platform/plugins/shared/esql/public/triggers/esql_controls/esql_control_action.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import { i18n } from '@kbn/i18n';
1111
import type { Action } from '@kbn/ui-actions-plugin/public';
1212
import type { CoreStart } from '@kbn/core/public';
13+
import type { TimefilterContract } from '@kbn/data-plugin/public';
1314
import type { ISearchGeneric } from '@kbn/search-types';
1415
import type { ESQLVariableType, ESQLControlState } from '@kbn/esql-types';
1516
import type { ESQLControlVariable } from '@kbn/esql-types';
@@ -32,7 +33,11 @@ export class CreateESQLControlAction implements Action<Context> {
3233
public id = ACTION_CREATE_ESQL_CONTROL;
3334
public order = 50;
3435

35-
constructor(protected readonly core: CoreStart, protected readonly search: ISearchGeneric) {}
36+
constructor(
37+
protected readonly core: CoreStart,
38+
protected readonly search: ISearchGeneric,
39+
protected readonly timefilter: TimefilterContract
40+
) {}
3641

3742
public getDisplayName(): string {
3843
return i18n.translate('esql.createESQLControlLabel', {
@@ -61,6 +66,7 @@ export class CreateESQLControlAction implements Action<Context> {
6166
queryString,
6267
core: this.core,
6368
search: this.search,
69+
timefilter: this.timefilter,
6470
variableType,
6571
esqlVariables,
6672
onSaveControl,

src/platform/plugins/shared/esql/public/triggers/esql_controls/esql_control_helpers.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import React, { lazy, Suspense, Fragment } from 'react';
1010
import { IncompatibleActionError } from '@kbn/ui-actions-plugin/public';
1111
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
12+
import type { TimefilterContract } from '@kbn/data-plugin/public';
1213
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
1314
import type { CoreStart } from '@kbn/core/public';
1415
import type { ISearchGeneric } from '@kbn/search-types';
@@ -22,6 +23,7 @@ interface Context {
2223
queryString: string;
2324
core: CoreStart;
2425
search: ISearchGeneric;
26+
timefilter: TimefilterContract;
2527
variableType: ESQLVariableType;
2628
esqlVariables: ESQLControlVariable[];
2729
onSaveControl?: (controlState: ESQLControlState, updatedQuery: string) => Promise<void>;
@@ -44,6 +46,7 @@ export async function executeAction({
4446
queryString,
4547
core,
4648
search,
49+
timefilter,
4750
variableType,
4851
esqlVariables,
4952
onSaveControl,
@@ -62,6 +65,8 @@ export async function executeAction({
6265
};
6366
});
6467

68+
const timeRange = timefilter.getTime();
69+
6570
const deps = await untilPluginStartServicesReady();
6671
const handle = core.overlays.openFlyout(
6772
toMountPoint(
@@ -85,6 +90,7 @@ export async function executeAction({
8590
cursorPosition={cursorPosition}
8691
initialState={initialState}
8792
esqlVariables={esqlVariables}
93+
timeRange={timeRange}
8894
/>
8995
</Suspense>
9096
</KibanaContextProvider>

0 commit comments

Comments
 (0)