Skip to content

Commit

Permalink
extract and inject references for by value visualization panels corre…
Browse files Browse the repository at this point in the history
…ctly (#126499)
  • Loading branch information
flash1293 authored Mar 1, 2022
1 parent f82a575 commit 7bea08f
Show file tree
Hide file tree
Showing 2 changed files with 296 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { EmbeddableStateWithType } from 'src/plugins/embeddable/common';
import { VisualizeEmbeddableFactory, VisualizeInput } from '.';
import { VisualizeEmbeddableFactoryDeps } from './visualize_embeddable_factory';

describe('visualize_embeddable_factory', () => {
const factory = new VisualizeEmbeddableFactory({} as VisualizeEmbeddableFactoryDeps);
test('extract saved search references for search source state and not store them in state', () => {
const { state, references } = factory.extract({
savedVis: {
type: 'area',
params: {},
uiState: {},
data: {
aggs: [
{
id: '1',
enabled: true,
type: 'count',
params: {},
schema: 'metric',
},
],
searchSource: {
query: {
query: '',
language: 'kuery',
},
filter: [],
},
savedSearchId: '123',
},
},
enhancements: {},
type: 'visualization',
} as unknown as EmbeddableStateWithType);
expect(references).toEqual([
{
type: 'search',
name: 'search_0',
id: '123',
},
]);
expect((state as unknown as VisualizeInput).savedVis?.data.savedSearchId).toBeUndefined();
});

test('extract data view references for search source state and not store them in state', () => {
const { state, references } = factory.extract({
savedVis: {
type: 'area',
params: {},
uiState: {},
data: {
aggs: [
{
id: '1',
enabled: true,
type: 'count',
params: {},
schema: 'metric',
},
],
searchSource: {
query: {
query: '',
language: 'kuery',
},
index: '123',
filter: [],
},
},
},
enhancements: {},
type: 'visualization',
} as unknown as EmbeddableStateWithType);
expect(references).toEqual([
{
type: 'index-pattern',
name: (
(state as unknown as VisualizeInput).savedVis?.data.searchSource as {
indexRefName: string;
}
).indexRefName,
id: '123',
},
]);
expect((state as unknown as VisualizeInput).savedVis?.data.searchSource.index).toBeUndefined();
});

test('inject data view references into search source state', () => {
const embeddedState = factory.inject(
{
savedVis: {
type: 'area',
params: {},
uiState: {},
data: {
aggs: [
{
id: '1',
enabled: true,
type: 'count',
params: {},
schema: 'metric',
},
],
searchSource: {
query: {
query: '',
language: 'kuery',
},
indexRefName: 'x',
filter: [],
},
},
},
enhancements: {},
type: 'visualization',
} as unknown as EmbeddableStateWithType,
[{ name: 'x', id: '123', type: 'index-pattern' }]
) as VisualizeInput;
expect(embeddedState.savedVis!.data.searchSource.index).toBe('123');
expect(
(embeddedState.savedVis!.data.searchSource as { indexRefName: string }).indexRefName
).toBe(undefined);
});

test('inject data view reference into search source state even if it is in injected state already', () => {
const embeddedState = factory.inject(
{
savedVis: {
type: 'area',
params: {},
uiState: {},
data: {
aggs: [
{
id: '1',
enabled: true,
type: 'count',
params: {},
schema: 'metric',
},
],
searchSource: {
query: {
query: '',
language: 'kuery',
},
index: '456',
filter: [],
},
},
},
enhancements: {},
type: 'visualization',
} as unknown as EmbeddableStateWithType,
[{ name: 'kibanaSavedObjectMeta.searchSourceJSON.index', id: '123', type: 'index-pattern' }]
) as VisualizeInput;
expect(embeddedState.savedVis!.data.searchSource.index).toBe('123');
expect(
(embeddedState.savedVis!.data.searchSource as { indexRefName: string }).indexRefName
).toBe(undefined);
});

test('inject search reference into search source state', () => {
const embeddedState = factory.inject(
{
savedVis: {
type: 'area',
params: {},
uiState: {},
data: {
aggs: [
{
id: '1',
enabled: true,
type: 'count',
params: {},
schema: 'metric',
},
],
searchSource: {
query: {
query: '',
language: 'kuery',
},
filter: [],
},
},
},
enhancements: {},
type: 'visualization',
} as unknown as EmbeddableStateWithType,
[{ name: 'search_0', id: '123', type: 'search' }]
);
expect((embeddedState as VisualizeInput).savedVis!.data.savedSearchId).toBe('123');
});

test('inject search reference into search source state even if it is injected already', () => {
const embeddedState = factory.inject(
{
savedVis: {
type: 'area',
params: {},
uiState: {},
data: {
aggs: [
{
id: '1',
enabled: true,
type: 'count',
params: {},
schema: 'metric',
},
],
searchSource: {
query: {
query: '',
language: 'kuery',
},
filter: [],
},
savedSearchId: '789',
},
},
enhancements: {},
type: 'visualization',
} as unknown as EmbeddableStateWithType,
[{ name: 'search_0', id: '123', type: 'search' }]
);
expect((embeddedState as VisualizeInput).savedVis!.data.savedSearchId).toBe('123');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ import { first } from 'rxjs/operators';
import type { SavedObjectMetaData, OnSaveProps } from 'src/plugins/saved_objects/public';
import type { EmbeddableStateWithType } from 'src/plugins/embeddable/common';

import { extractSearchSourceReferences } from '../../../data/public';
import {
injectSearchSourceReferences,
extractSearchSourceReferences,
SerializedSearchSourceFields,
} from '../../../data/public';
import type { SavedObjectAttributes, SavedObjectReference } from '../../../../core/public';

import {
Expand Down Expand Up @@ -288,7 +292,7 @@ export class VisualizeEmbeddableFactory
}

public inject(_state: EmbeddableStateWithType, references: SavedObjectReference[]) {
const state = _state as unknown as VisualizeInput;
let state = _state as unknown as VisualizeInput;

const { type, params } = state.savedVis ?? {};

Expand All @@ -297,21 +301,40 @@ export class VisualizeEmbeddableFactory
injectTimeSeriesReferences(type, params, references);
}

return _state;
if (state.savedVis?.data.searchSource) {
let extractedSearchSource = state.savedVis?.data
.searchSource as SerializedSearchSourceFields & {
indexRefName: string;
};
if (!('indexRefName' in state.savedVis.data.searchSource)) {
// due to a bug in 8.0, some visualizations were saved with an injected state - re-extract in that case and inject the upstream references because they might have changed
extractedSearchSource = extractSearchSourceReferences(
extractedSearchSource
)[0] as SerializedSearchSourceFields & {
indexRefName: string;
};
}
const injectedSearchSource = injectSearchSourceReferences(extractedSearchSource, references);
state = {
...state,
savedVis: {
...state.savedVis,
data: {
...state.savedVis.data,
searchSource: injectedSearchSource,
savedSearchId: references.find((r) => r.name === 'search_0')?.id,
},
},
};
}

return state as EmbeddableStateWithType;
}

public extract(_state: EmbeddableStateWithType) {
const state = _state as unknown as VisualizeInput;
let state = _state as unknown as VisualizeInput;
const references = [];

if (state.savedVis?.data.searchSource) {
const [, searchSourceReferences] = extractSearchSourceReferences(
state.savedVis.data.searchSource
);

references.push(...searchSourceReferences);
}

if (state.savedVis?.data.savedSearchId) {
references.push({
name: 'search_0',
Expand All @@ -320,13 +343,32 @@ export class VisualizeEmbeddableFactory
});
}

if (state.savedVis?.data.searchSource) {
const [extractedSearchSource, searchSourceReferences] = extractSearchSourceReferences(
state.savedVis.data.searchSource
);

references.push(...searchSourceReferences);
state = {
...state,
savedVis: {
...state.savedVis,
data: {
...state.savedVis.data,
searchSource: extractedSearchSource,
savedSearchId: undefined,
},
},
};
}

const { type, params } = state.savedVis ?? {};

if (type && params) {
extractControlsReferences(type, params, references, `control_${state.id}`);
extractTimeSeriesReferences(type, params, references, `metrics_${state.id}`);
}

return { state: _state, references };
return { state: state as EmbeddableStateWithType, references };
}
}

0 comments on commit 7bea08f

Please sign in to comment.