Skip to content

Commit 57a53db

Browse files
Revert "Revert "[Canvas] By-Value Embeddables (#113827)" (#116527)" (#117613)
* Revert "Revert "[Canvas] By-Value Embeddables (#113827)" (#116527)" This reverts commit 9e6e845. * Fix ts error Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
1 parent 7455bde commit 57a53db

File tree

60 files changed

+1329
-127
lines changed

Some content is hidden

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

60 files changed

+1329
-127
lines changed

src/plugins/dashboard/public/application/top_nav/editor_menu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ export const EditorMenu = ({ dashboardContainer, createNewVisType }: Props) => {
231231
<SolutionToolbarPopover
232232
ownFocus
233233
label={i18n.translate('dashboard.solutionToolbar.editorMenuButtonLabel', {
234-
defaultMessage: 'All types',
234+
defaultMessage: 'Select type',
235235
})}
236236
iconType="arrowDown"
237237
iconSide="right"

src/plugins/kibana_usage_collection/server/collectors/management/schema.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,10 @@ export const stackManagementSchema: MakeSchemaFrom<UsageStats> = {
444444
type: 'boolean',
445445
_meta: { description: 'Non-default value of setting.' },
446446
},
447+
'labs:canvas:byValueEmbeddable': {
448+
type: 'boolean',
449+
_meta: { description: 'Non-default value of setting.' },
450+
},
447451
'labs:canvas:useDataService': {
448452
type: 'boolean',
449453
_meta: { description: 'Non-default value of setting.' },

src/plugins/kibana_usage_collection/server/collectors/management/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ export interface UsageStats {
122122
'banners:textColor': string;
123123
'banners:backgroundColor': string;
124124
'labs:canvas:enable_ui': boolean;
125+
'labs:canvas:byValueEmbeddable': boolean;
125126
'labs:canvas:useDataService': boolean;
126127
'labs:presentation:timeToPresent': boolean;
127128
'labs:dashboard:enable_ui': boolean;

src/plugins/presentation_util/common/labs.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import { i18n } from '@kbn/i18n';
1111
export const LABS_PROJECT_PREFIX = 'labs:';
1212
export const DEFER_BELOW_FOLD = `${LABS_PROJECT_PREFIX}dashboard:deferBelowFold` as const;
1313
export const DASHBOARD_CONTROLS = `${LABS_PROJECT_PREFIX}dashboard:dashboardControls` as const;
14-
export const projectIDs = [DEFER_BELOW_FOLD, DASHBOARD_CONTROLS] as const;
14+
export const BY_VALUE_EMBEDDABLE = `${LABS_PROJECT_PREFIX}canvas:byValueEmbeddable` as const;
15+
16+
export const projectIDs = [DEFER_BELOW_FOLD, DASHBOARD_CONTROLS, BY_VALUE_EMBEDDABLE] as const;
1517
export const environmentNames = ['kibana', 'browser', 'session'] as const;
1618
export const solutionNames = ['canvas', 'dashboard', 'presentation'] as const;
1719

@@ -48,6 +50,19 @@ export const projects: { [ID in ProjectID]: ProjectConfig & { id: ID } } = {
4850
}),
4951
solutions: ['dashboard'],
5052
},
53+
[BY_VALUE_EMBEDDABLE]: {
54+
id: BY_VALUE_EMBEDDABLE,
55+
isActive: true,
56+
isDisplayed: true,
57+
environments: ['kibana', 'browser', 'session'],
58+
name: i18n.translate('presentationUtil.labs.enableByValueEmbeddableName', {
59+
defaultMessage: 'By-Value Embeddables',
60+
}),
61+
description: i18n.translate('presentationUtil.labs.enableByValueEmbeddableDescription', {
62+
defaultMessage: 'Enables support for by-value embeddables in Canvas',
63+
}),
64+
solutions: ['canvas'],
65+
},
5166
};
5267

5368
export type ProjectID = typeof projectIDs[number];
Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
11
.quickButtonGroup {
2-
.quickButtonGroup__button {
3-
background-color: $euiColorEmptyShade;
4-
// sass-lint:disable-block no-important
5-
border-width: $euiBorderWidthThin !important;
6-
border-style: solid !important;
7-
border-color: $euiBorderColor !important;
2+
.euiButtonGroup__buttons {
3+
border-radius: $euiBorderRadius;
4+
5+
.quickButtonGroup__button {
6+
background-color: $euiColorEmptyShade;
7+
// sass-lint:disable-block no-important
8+
border-width: $euiBorderWidthThin !important;
9+
border-style: solid !important;
10+
border-color: $euiBorderColor !important;
11+
}
12+
13+
.quickButtonGroup__button:first-of-type {
14+
// sass-lint:disable-block no-important
15+
border-top-left-radius: $euiBorderRadius !important;
16+
border-bottom-left-radius: $euiBorderRadius !important;
17+
}
18+
19+
.quickButtonGroup__button:last-of-type {
20+
// sass-lint:disable-block no-important
21+
border-top-right-radius: $euiBorderRadius !important;
22+
border-bottom-right-radius: $euiBorderRadius !important;
23+
}
824
}
925
}

src/plugins/telemetry/schema/oss_plugins.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7683,6 +7683,12 @@
76837683
"description": "Non-default value of setting."
76847684
}
76857685
},
7686+
"labs:canvas:byValueEmbeddable": {
7687+
"type": "boolean",
7688+
"_meta": {
7689+
"description": "Non-default value of setting."
7690+
}
7691+
},
76867692
"labs:canvas:useDataService": {
76877693
"type": "boolean",
76887694
"_meta": {

x-pack/plugins/canvas/canvas_plugin_src/expression_types/embeddable.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77

88
import { ExpressionTypeDefinition } from '../../../../../src/plugins/expressions';
9-
import { EmbeddableInput } from '../../../../../src/plugins/embeddable/common/';
9+
import { EmbeddableInput } from '../../types';
1010
import { EmbeddableTypes } from './embeddable_types';
1111

1212
export const EmbeddableExpressionType = 'embeddable';

x-pack/plugins/canvas/canvas_plugin_src/functions/browser/index.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,11 @@
66
*/
77

88
import { functions as commonFunctions } from '../common';
9-
import { functions as externalFunctions } from '../external';
109
import { location } from './location';
1110
import { markdown } from './markdown';
1211
import { urlparam } from './urlparam';
1312
import { escount } from './escount';
1413
import { esdocs } from './esdocs';
1514
import { essql } from './essql';
1615

17-
export const functions = [
18-
location,
19-
markdown,
20-
urlparam,
21-
escount,
22-
esdocs,
23-
essql,
24-
...commonFunctions,
25-
...externalFunctions,
26-
];
16+
export const functions = [location, markdown, urlparam, escount, esdocs, essql, ...commonFunctions];
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
import { embeddableFunctionFactory } from './embeddable';
9+
import { getQueryFilters } from '../../../common/lib/build_embeddable_filters';
10+
import { ExpressionValueFilter } from '../../../types';
11+
import { encode } from '../../../common/lib/embeddable_dataurl';
12+
import { InitializeArguments } from '.';
13+
14+
const filterContext: ExpressionValueFilter = {
15+
type: 'filter',
16+
and: [
17+
{
18+
type: 'filter',
19+
and: [],
20+
value: 'filter-value',
21+
column: 'filter-column',
22+
filterType: 'exactly',
23+
},
24+
{
25+
type: 'filter',
26+
and: [],
27+
column: 'time-column',
28+
filterType: 'time',
29+
from: '2019-06-04T04:00:00.000Z',
30+
to: '2019-06-05T04:00:00.000Z',
31+
},
32+
],
33+
};
34+
35+
describe('embeddable', () => {
36+
const fn = embeddableFunctionFactory({} as InitializeArguments)().fn;
37+
const config = {
38+
id: 'some-id',
39+
timerange: { from: '15m', to: 'now' },
40+
title: 'test embeddable',
41+
};
42+
43+
const args = {
44+
config: encode(config),
45+
type: 'visualization',
46+
};
47+
48+
it('accepts null context', () => {
49+
const expression = fn(null, args, {} as any);
50+
51+
expect(expression.input.filters).toEqual([]);
52+
});
53+
54+
it('accepts filter context', () => {
55+
const expression = fn(filterContext, args, {} as any);
56+
const embeddableFilters = getQueryFilters(filterContext.and);
57+
58+
expect(expression.input.filters).toEqual(embeddableFilters);
59+
});
60+
});
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common';
9+
import { ExpressionValueFilter, EmbeddableInput } from '../../../types';
10+
import { EmbeddableExpressionType, EmbeddableExpression } from '../../expression_types';
11+
import { getFunctionHelp } from '../../../i18n';
12+
import { SavedObjectReference } from '../../../../../../src/core/types';
13+
import { getQueryFilters } from '../../../common/lib/build_embeddable_filters';
14+
import { decode, encode } from '../../../common/lib/embeddable_dataurl';
15+
import { InitializeArguments } from '.';
16+
17+
export interface Arguments {
18+
config: string;
19+
type: string;
20+
}
21+
22+
const defaultTimeRange = {
23+
from: 'now-15m',
24+
to: 'now',
25+
};
26+
27+
const baseEmbeddableInput = {
28+
timeRange: defaultTimeRange,
29+
disableTriggers: true,
30+
renderMode: 'noInteractivity',
31+
};
32+
33+
type Return = EmbeddableExpression<EmbeddableInput>;
34+
35+
type EmbeddableFunction = ExpressionFunctionDefinition<
36+
'embeddable',
37+
ExpressionValueFilter | null,
38+
Arguments,
39+
Return
40+
>;
41+
42+
export function embeddableFunctionFactory({
43+
embeddablePersistableStateService,
44+
}: InitializeArguments): () => EmbeddableFunction {
45+
return function embeddable(): EmbeddableFunction {
46+
const { help, args: argHelp } = getFunctionHelp().embeddable;
47+
48+
return {
49+
name: 'embeddable',
50+
help,
51+
args: {
52+
config: {
53+
aliases: ['_'],
54+
types: ['string'],
55+
required: true,
56+
help: argHelp.config,
57+
},
58+
type: {
59+
types: ['string'],
60+
required: true,
61+
help: argHelp.type,
62+
},
63+
},
64+
context: {
65+
types: ['filter'],
66+
},
67+
type: EmbeddableExpressionType,
68+
fn: (input, args) => {
69+
const filters = input ? input.and : [];
70+
71+
const embeddableInput = decode(args.config) as EmbeddableInput;
72+
73+
return {
74+
type: EmbeddableExpressionType,
75+
input: {
76+
...baseEmbeddableInput,
77+
...embeddableInput,
78+
filters: getQueryFilters(filters),
79+
},
80+
generatedAt: Date.now(),
81+
embeddableType: args.type,
82+
};
83+
},
84+
85+
extract(state) {
86+
const input = decode(state.config[0] as string);
87+
88+
// extracts references for by-reference embeddables
89+
if (input.savedObjectId) {
90+
const refName = 'embeddable.savedObjectId';
91+
92+
const references: SavedObjectReference[] = [
93+
{
94+
name: refName,
95+
type: state.type[0] as string,
96+
id: input.savedObjectId as string,
97+
},
98+
];
99+
100+
return {
101+
state,
102+
references,
103+
};
104+
}
105+
106+
// extracts references for by-value embeddables
107+
const { state: extractedState, references: extractedReferences } =
108+
embeddablePersistableStateService.extract({
109+
...input,
110+
type: state.type[0],
111+
});
112+
113+
const { type, ...extractedInput } = extractedState;
114+
115+
return {
116+
state: { ...state, config: [encode(extractedInput)], type: [type] },
117+
references: extractedReferences,
118+
};
119+
},
120+
121+
inject(state, references) {
122+
const input = decode(state.config[0] as string);
123+
const savedObjectReference = references.find(
124+
(ref) => ref.name === 'embeddable.savedObjectId'
125+
);
126+
127+
// injects saved object id for by-references embeddable
128+
if (savedObjectReference) {
129+
input.savedObjectId = savedObjectReference.id;
130+
state.config[0] = encode(input);
131+
state.type[0] = savedObjectReference.type;
132+
} else {
133+
// injects references for by-value embeddables
134+
const { type, ...injectedInput } = embeddablePersistableStateService.inject(
135+
{ ...input, type: state.type[0] },
136+
references
137+
);
138+
state.config[0] = encode(injectedInput);
139+
state.type[0] = type;
140+
}
141+
return state;
142+
},
143+
};
144+
};
145+
}

0 commit comments

Comments
 (0)