Skip to content

Commit eaa6553

Browse files
authored
Use saved object references for dashboard drilldowns (#82602)
1 parent 58ad7ec commit eaa6553

58 files changed

Lines changed: 1122 additions & 301 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddablesetup.getattributeservice.md

Lines changed: 0 additions & 11 deletions
This file was deleted.

docs/development/plugins/embeddable/server/kibana-plugin-plugins-embeddable-server.embeddablesetup.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@
77
<b>Signature:</b>
88

99
```typescript
10-
export interface EmbeddableSetup
10+
export interface EmbeddableSetup extends PersistableStateService<EmbeddableStateWithType>
1111
```
1212
1313
## Properties
1414
1515
| Property | Type | Description |
1616
| --- | --- | --- |
17-
| [getAttributeService](./kibana-plugin-plugins-embeddable-server.embeddablesetup.getattributeservice.md) | <code>any</code> | |
1817
| [registerEmbeddableFactory](./kibana-plugin-plugins-embeddable-server.embeddablesetup.registerembeddablefactory.md) | <code>(factory: EmbeddableRegistryDefinition) =&gt; void</code> | |
1918
| [registerEnhancement](./kibana-plugin-plugins-embeddable-server.embeddablesetup.registerenhancement.md) | <code>(enhancement: EnhancementRegistryDefinition) =&gt; void</code> | |
2019
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
import {
21+
ExtractDeps,
22+
extractPanelsReferences,
23+
InjectDeps,
24+
injectPanelsReferences,
25+
} from './embeddable_references';
26+
import { createEmbeddablePersistableStateServiceMock } from '../../../embeddable/common/mocks';
27+
import { SavedDashboardPanel } from '../types';
28+
import { EmbeddableStateWithType } from '../../../embeddable/common';
29+
30+
const embeddablePersistableStateService = createEmbeddablePersistableStateServiceMock();
31+
const deps: InjectDeps & ExtractDeps = {
32+
embeddablePersistableStateService,
33+
};
34+
35+
test('inject/extract panel references', () => {
36+
embeddablePersistableStateService.extract.mockImplementationOnce((state) => {
37+
const { HARDCODED_ID, ...restOfState } = (state as unknown) as Record<string, unknown>;
38+
return {
39+
state: restOfState as EmbeddableStateWithType,
40+
references: [{ id: HARDCODED_ID as string, name: 'refName', type: 'type' }],
41+
};
42+
});
43+
44+
embeddablePersistableStateService.inject.mockImplementationOnce((state, references) => {
45+
const ref = references.find((r) => r.name === 'refName');
46+
return {
47+
...state,
48+
HARDCODED_ID: ref!.id,
49+
};
50+
});
51+
52+
const savedDashboardPanel: SavedDashboardPanel = {
53+
type: 'search',
54+
embeddableConfig: {
55+
HARDCODED_ID: 'IMPORTANT_HARDCODED_ID',
56+
},
57+
id: 'savedObjectId',
58+
panelIndex: '123',
59+
gridData: {
60+
x: 0,
61+
y: 0,
62+
h: 15,
63+
w: 15,
64+
i: '123',
65+
},
66+
version: '7.0.0',
67+
};
68+
69+
const [{ panel: extractedPanel, references }] = extractPanelsReferences(
70+
[savedDashboardPanel],
71+
deps
72+
);
73+
expect(extractedPanel.embeddableConfig).toEqual({});
74+
expect(references).toMatchInlineSnapshot(`
75+
Array [
76+
Object {
77+
"id": "IMPORTANT_HARDCODED_ID",
78+
"name": "refName",
79+
"type": "type",
80+
},
81+
]
82+
`);
83+
84+
const [injectedPanel] = injectPanelsReferences([extractedPanel], references, deps);
85+
86+
expect(injectedPanel).toEqual(savedDashboardPanel);
87+
});
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
import { omit } from 'lodash';
21+
import {
22+
convertSavedDashboardPanelToPanelState,
23+
convertPanelStateToSavedDashboardPanel,
24+
} from './embeddable_saved_object_converters';
25+
import { SavedDashboardPanel } from '../types';
26+
import { SavedObjectReference } from '../../../../core/types';
27+
import { EmbeddablePersistableStateService } from '../../../embeddable/common/types';
28+
29+
export interface InjectDeps {
30+
embeddablePersistableStateService: EmbeddablePersistableStateService;
31+
}
32+
33+
export function injectPanelsReferences(
34+
panels: SavedDashboardPanel[],
35+
references: SavedObjectReference[],
36+
deps: InjectDeps
37+
): SavedDashboardPanel[] {
38+
const result: SavedDashboardPanel[] = [];
39+
for (const panel of panels) {
40+
const embeddableState = convertSavedDashboardPanelToPanelState(panel);
41+
embeddableState.explicitInput = omit(
42+
deps.embeddablePersistableStateService.inject(
43+
{ ...embeddableState.explicitInput, type: panel.type },
44+
references
45+
),
46+
'type'
47+
);
48+
result.push(convertPanelStateToSavedDashboardPanel(embeddableState, panel.version));
49+
}
50+
return result;
51+
}
52+
53+
export interface ExtractDeps {
54+
embeddablePersistableStateService: EmbeddablePersistableStateService;
55+
}
56+
57+
export function extractPanelsReferences(
58+
panels: SavedDashboardPanel[],
59+
deps: ExtractDeps
60+
): Array<{ panel: SavedDashboardPanel; references: SavedObjectReference[] }> {
61+
const result: Array<{ panel: SavedDashboardPanel; references: SavedObjectReference[] }> = [];
62+
63+
for (const panel of panels) {
64+
const embeddable = convertSavedDashboardPanelToPanelState(panel);
65+
const {
66+
state: embeddableInputWithExtractedReferences,
67+
references,
68+
} = deps.embeddablePersistableStateService.extract({
69+
...embeddable.explicitInput,
70+
type: embeddable.type,
71+
});
72+
embeddable.explicitInput = omit(embeddableInputWithExtractedReferences, 'type');
73+
74+
const newPanel = convertPanelStateToSavedDashboardPanel(embeddable, panel.version);
75+
result.push({
76+
panel: newPanel,
77+
references,
78+
});
79+
}
80+
81+
return result;
82+
}

src/plugins/dashboard/public/application/lib/embeddable_saved_object_converters.test.ts renamed to src/plugins/dashboard/common/embeddable/embeddable_saved_object_converters.test.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ import {
2121
convertSavedDashboardPanelToPanelState,
2222
convertPanelStateToSavedDashboardPanel,
2323
} from './embeddable_saved_object_converters';
24-
import { SavedDashboardPanel } from '../../types';
25-
import { DashboardPanelState } from '../embeddable';
26-
import { EmbeddableInput } from '../../../../embeddable/public';
24+
import { SavedDashboardPanel, DashboardPanelState } from '../types';
25+
import { EmbeddableInput } from '../../../embeddable/common/types';
2726

2827
test('convertSavedDashboardPanelToPanelState', () => {
2928
const savedDashboardPanel: SavedDashboardPanel = {
@@ -135,3 +134,24 @@ test('convertPanelStateToSavedDashboardPanel will not add an undefined id when n
135134
const converted = convertPanelStateToSavedDashboardPanel(dashboardPanel, '8.0.0');
136135
expect(converted.hasOwnProperty('id')).toBe(false);
137136
});
137+
138+
test('convertPanelStateToSavedDashboardPanel will not leave title as part of embeddable config', () => {
139+
const dashboardPanel: DashboardPanelState = {
140+
gridData: {
141+
x: 0,
142+
y: 0,
143+
h: 15,
144+
w: 15,
145+
i: '123',
146+
},
147+
explicitInput: {
148+
id: '123',
149+
title: 'title',
150+
} as EmbeddableInput,
151+
type: 'search',
152+
};
153+
154+
const converted = convertPanelStateToSavedDashboardPanel(dashboardPanel, '8.0.0');
155+
expect(converted.embeddableConfig.hasOwnProperty('title')).toBe(false);
156+
expect(converted.title).toBe('title');
157+
});

src/plugins/dashboard/public/application/lib/embeddable_saved_object_converters.ts renamed to src/plugins/dashboard/common/embeddable/embeddable_saved_object_converters.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@
1717
* under the License.
1818
*/
1919
import { omit } from 'lodash';
20-
import { SavedDashboardPanel } from '../../types';
21-
import { DashboardPanelState } from '../embeddable';
22-
import { SavedObjectEmbeddableInput } from '../../embeddable_plugin';
20+
import { DashboardPanelState, SavedDashboardPanel } from '../types';
21+
import { SavedObjectEmbeddableInput } from '../../../embeddable/common/';
2322

2423
export function convertSavedDashboardPanelToPanelState(
2524
savedDashboardPanel: SavedDashboardPanel
@@ -49,7 +48,7 @@ export function convertPanelStateToSavedDashboardPanel(
4948
type: panelState.type,
5049
gridData: panelState.gridData,
5150
panelIndex: panelState.explicitInput.id,
52-
embeddableConfig: omit(panelState.explicitInput, ['id', 'savedObjectId']),
51+
embeddableConfig: omit(panelState.explicitInput, ['id', 'savedObjectId', 'title']),
5352
...(customTitle && { title: customTitle }),
5453
...(savedObjectId !== undefined && { id: savedObjectId }),
5554
};

0 commit comments

Comments
 (0)