[Lens][Inspector] Enable inspector to display multiple requests for multiple layers (#105224) (#105605)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: Marco Liberati <dej611@users.noreply.github.com>
This commit is contained in:
Kibana Machine 2021-07-14 11:58:49 -04:00 committed by GitHub
parent 0d470f8b94
commit 72a082eba4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 74 additions and 10 deletions

View file

@ -39,5 +39,5 @@ export declare class Execution<Input = unknown, Output = unknown, InspectorAdapt
| [invokeChain(chainArr, input)](./kibana-plugin-plugins-expressions-public.execution.invokechain.md) | | |
| [invokeFunction(fn, input, args)](./kibana-plugin-plugins-expressions-public.execution.invokefunction.md) | | |
| [resolveArgs(fnDef, input, argAsts)](./kibana-plugin-plugins-expressions-public.execution.resolveargs.md) | | |
| [start(input)](./kibana-plugin-plugins-expressions-public.execution.start.md) | | Call this method to start execution.<!-- -->N.B. <code>input</code> is initialized to <code>null</code> rather than <code>undefined</code> for legacy reasons, because in legacy interpreter it was set to <code>null</code> by default. |
| [start(input, isSubExpression)](./kibana-plugin-plugins-expressions-public.execution.start.md) | | Call this method to start execution.<!-- -->N.B. <code>input</code> is initialized to <code>null</code> rather than <code>undefined</code> for legacy reasons, because in legacy interpreter it was set to <code>null</code> by default. |

View file

@ -11,7 +11,7 @@ N.B. `input` is initialized to `null` rather than `undefined` for legacy reasons
<b>Signature:</b>
```typescript
start(input?: Input): Observable<ExecutionResult<Output | ExpressionValueError>>;
start(input?: Input, isSubExpression?: boolean): Observable<ExecutionResult<Output | ExpressionValueError>>;
```
## Parameters
@ -19,6 +19,7 @@ start(input?: Input): Observable<ExecutionResult<Output | ExpressionValueError>>
| Parameter | Type | Description |
| --- | --- | --- |
| input | <code>Input</code> | |
| isSubExpression | <code>boolean</code> | |
<b>Returns:</b>

View file

@ -39,5 +39,5 @@ export declare class Execution<Input = unknown, Output = unknown, InspectorAdapt
| [invokeChain(chainArr, input)](./kibana-plugin-plugins-expressions-server.execution.invokechain.md) | | |
| [invokeFunction(fn, input, args)](./kibana-plugin-plugins-expressions-server.execution.invokefunction.md) | | |
| [resolveArgs(fnDef, input, argAsts)](./kibana-plugin-plugins-expressions-server.execution.resolveargs.md) | | |
| [start(input)](./kibana-plugin-plugins-expressions-server.execution.start.md) | | Call this method to start execution.<!-- -->N.B. <code>input</code> is initialized to <code>null</code> rather than <code>undefined</code> for legacy reasons, because in legacy interpreter it was set to <code>null</code> by default. |
| [start(input, isSubExpression)](./kibana-plugin-plugins-expressions-server.execution.start.md) | | Call this method to start execution.<!-- -->N.B. <code>input</code> is initialized to <code>null</code> rather than <code>undefined</code> for legacy reasons, because in legacy interpreter it was set to <code>null</code> by default. |

View file

@ -11,7 +11,7 @@ N.B. `input` is initialized to `null` rather than `undefined` for legacy reasons
<b>Signature:</b>
```typescript
start(input?: Input): Observable<ExecutionResult<Output | ExpressionValueError>>;
start(input?: Input, isSubExpression?: boolean): Observable<ExecutionResult<Output | ExpressionValueError>>;
```
## Parameters
@ -19,6 +19,7 @@ start(input?: Input): Observable<ExecutionResult<Output | ExpressionValueError>>
| Parameter | Type | Description |
| --- | --- | --- |
| input | <code>Input</code> | |
| isSubExpression | <code>boolean</code> | |
<b>Returns:</b>

View file

@ -100,8 +100,6 @@ export const handleRequest = async ({
requestSearchSource.setField('filter', filters);
requestSearchSource.setField('query', query);
inspectorAdapters.requests?.reset();
const { rawResponse: response } = await requestSearchSource
.fetch$({
abortSignal,

View file

@ -339,6 +339,14 @@ describe('Execution', () => {
});
expect(execution.inspectorAdapters).toBe(inspectorAdapters);
});
test('it should reset the request adapter only on startup', async () => {
const inspectorAdapters = { requests: { reset: jest.fn() } };
await run('add val={add 5 | access "value"}', {
inspectorAdapters,
});
expect(inspectorAdapters.requests.reset).toHaveBeenCalledTimes(1);
});
});
describe('expression abortion', () => {

View file

@ -280,13 +280,18 @@ export class Execution<
* because in legacy interpreter it was set to `null` by default.
*/
public start(
input: Input = null as any
input: Input = null as any,
isSubExpression?: boolean
): Observable<ExecutionResult<Output | ExpressionValueError>> {
if (this.hasStarted) throw new Error('Execution already started.');
this.hasStarted = true;
this.input = input;
this.state.transitions.start();
if (!isSubExpression) {
this.context.inspectorAdapters.requests?.reset();
}
if (isObservable<Input>(input)) {
input.subscribe(this.input$);
} else if (isPromise(input)) {
@ -534,7 +539,7 @@ export class Execution<
);
this.childExecutions.push(execution);
return execution.start(input);
return execution.start(input, true);
case 'string':
case 'number':
case 'null':

View file

@ -120,7 +120,7 @@ export class Execution<Input = unknown, Output = unknown, InspectorAdapters exte
// (undocumented)
resolveArgs(fnDef: ExpressionFunction, input: unknown, argAsts: any): Observable<any>;
readonly result: Observable<ExecutionResult<Output | ExpressionValueError>>;
start(input?: Input): Observable<ExecutionResult<Output | ExpressionValueError>>;
start(input?: Input, isSubExpression?: boolean): Observable<ExecutionResult<Output | ExpressionValueError>>;
// Warning: (ae-forgotten-export) The symbol "ExecutionResult" needs to be exported by the entry point index.d.ts
readonly state: ExecutionContainer<ExecutionResult<Output | ExpressionValueError>>;
}

View file

@ -118,7 +118,7 @@ export class Execution<Input = unknown, Output = unknown, InspectorAdapters exte
// (undocumented)
resolveArgs(fnDef: ExpressionFunction, input: unknown, argAsts: any): Observable<any>;
readonly result: Observable<ExecutionResult<Output | ExpressionValueError>>;
start(input?: Input): Observable<ExecutionResult<Output | ExpressionValueError>>;
start(input?: Input, isSubExpression?: boolean): Observable<ExecutionResult<Output | ExpressionValueError>>;
// Warning: (ae-forgotten-export) The symbol "ExecutionResult" needs to be exported by the entry point index.d.ts
readonly state: ExecutionContainer<ExecutionResult<Output | ExpressionValueError>>;
}

View file

@ -27,6 +27,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const filterBar = getService('filterBar');
const security = getService('security');
const panelActions = getService('dashboardPanelActions');
const inspector = getService('inspector');
async function clickInChart(x: number, y: number) {
const el = await elasticChart.getCanvas();
@ -158,6 +159,56 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await testSubjects.existOrFail(ACTION_TEST_SUBJ);
});
it('should show all data from all layers in the inspector', async () => {
await PageObjects.common.navigateToApp('dashboard');
await PageObjects.dashboard.clickNewDashboard();
await dashboardAddPanel.clickCreateNewLink();
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.lens.goToTimeRange();
await PageObjects.lens.configureDimension({
dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension',
operation: 'date_histogram',
field: '@timestamp',
});
await PageObjects.lens.configureDimension({
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
operation: 'average',
field: 'bytes',
});
await PageObjects.lens.createLayer();
expect(await PageObjects.lens.hasChartSwitchWarning('line')).to.eql(false);
await PageObjects.lens.switchToVisualization('line');
await PageObjects.lens.configureDimension(
{
dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension',
operation: 'date_histogram',
field: '@timestamp',
},
1
);
await PageObjects.lens.configureDimension(
{
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
operation: 'median',
field: 'bytes',
},
1
);
await PageObjects.lens.saveAndReturn();
await panelActions.openContextMenu();
await panelActions.clickContextMenuMoreItem();
await testSubjects.click('embeddablePanelAction-openInspector');
await inspector.openInspectorRequestsView();
const requests = await inspector.getRequestNames();
expect(requests.split(',').length).to.be(2);
});
it('unlink lens panel from embeddable library', async () => {
await PageObjects.common.navigateToApp('dashboard');
await PageObjects.dashboard.clickNewDashboard();