Skip to content

Commit 473b6aa

Browse files
authored
[Canvas] Expression shape (elastic#103219)
* expression_reveal_image skeleton. * expression_functions added. * expression_renderers added. * Backup of daily work. * Fixed errors. * Added legacy support. Added button for legacy. * Added storybook. * Removed revealImage from canvas. * Types fixed. * Fixed test suite error. * Fixed eslint error. * Moved UI and elements, related to expressionRevealImage from canvas. * Fixed unused translations errors. * Moved type of element to types. * Fixed types and added service for representing elements, ui and supported renderers to canvas. * Added expression registration to canvas. * Fixed * Fixed mutiple call of the function. * Removed support of a legacy lib for revealImage chart. * Removed legacy presentation_utils plugin import. * Removed useless translations and tried to fix error. * One more fix. * Small imports fix. * Fixed translations. * Made fixes based on nits. * Removed useless params. * fix. * Fixed errors, related to jest and __mocks__. * Removed useless type definition. * Replaced RendererHandlers with IInterpreterRendererHandlers. * fixed supported_shareable. * Moved elements back to canvas. * Moved views to canvas, removed expression service and imported renderer to canvas. * Fixed translations. * Moved libs to presentation utils. * Fixed types and removed function_wrapper.ts * Fixed types of test helpers. * Fixed imports. * One more fix. * Fixed public API. * Moved css to component. * Fixed spaces at element. * Removed unused plugin. * Basic setup of error plugin. * Removed not used `function` files at `error` expression. * Moved related components from canvas. * Changed imports of components. * Removed useless translations and fixed .i18nrc.json * More fixes of i18nrc. * Fixed async functions. Written current code, based on storybookjs/storybook#7745 * Fixed one test with Expression input. After changing the way of rendering in stories, all elements are mounting and componentDidMount is involved. The previous snapshot was without mounted `monaco` editor. * generated plugin and copied code from expression_reveal_image * fixed double import after merge. * Changed all names from reveal_image to shape. * moved shape to plugin and added all necessary configs * Fixed translations, fixed all imports and debug of svg. * `function` moved to `server`. * One shape is rewritten to `React` and rendering is written with passing necessary props. * changed default width and heigth. * Added `ShapeHOC`. * Shapes changed. * small refactor. * Removed useless import. * one more refactor. * Refactor + fix errors + updated limits. * Changed ShapePreview from pure js to react and removed `dangerouslySetInnerHTML` * Fixed types of viewbox. * Changed types source for Shape components. * small refactor. * Fixed imports. * Removed `shape` from `canvas` * Updated docs. * Basic setup of error plugin. * Removed not used `function` files at `error` expression. * Changed imports of components. * Fixed errors, related to shape and autosuggestions. * Fixed i18n for shape. * Moved function from public to common and registered at server. * Fixed types error. * Fixed snapshots and shape mocks. * Moved some libs from `presentations_util` to `expression_shape` * Shape refactored. * Shape picker fixed. * Moved `Popover` back to `canvas` * Removed `Popover` export from presentation_utils components. * Moved error_component and debug_component from presentation_util to expression_error. * Removed `.i18nrc.json`. * Removed `.i18nrc.json`. * Removed useless scss. * Fixed color of `error`. * added fixes of rebase. * More fixes of rebase error . * Removed useless .i18nrc.json file. * More fixes. * More fixes of rebase. * One more fix. * More fixes. * Fixed limits and translations. * Added. * Fixed i18nrc. * Fixed error.. * Moved shapes to async chunks. * One more fix. * Some fixes. * Trying to fix the typecheck error. * Added temp of drawer. * Moved shapes to the async chunk in a less complex way. * Made `ShapeDrawer` reusable among different `expressions`. * Changed type of `shapes` from `any` and `Shape` to `string`. * Made changes, based on nits. * Removed not necessary changes. * Moved all reusable libs to `expression_shapes`. * Reduced the size of the bundle. * Hope, fixed type check errors. * Removed getDefaultShapeData. * Removed `getViewBox` from bundle.
1 parent 8460035 commit 473b6aa

File tree

100 files changed

+1852
-490
lines changed

Some content is hidden

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

100 files changed

+1852
-490
lines changed

.eslintrc.js

+1
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ module.exports = {
446446
'!(src|x-pack)/plugins/**/(public|server)/mocks/index.{js,mjs,ts}',
447447
'!(src|x-pack)/plugins/**/(public|server)/(index|mocks).{js,mjs,ts,tsx}',
448448
'!(src|x-pack)/plugins/**/__stories__/index.{js,mjs,ts,tsx}',
449+
'!(src|x-pack)/plugins/**/__fixtures__/index.{js,mjs,ts,tsx}',
449450
],
450451
allowSameFolder: true,
451452
errorMessage: 'Plugins may only import from top-level public and server modules.',

.i18nrc.json

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"expressions": "src/plugins/expressions",
1919
"expressionError": "src/plugins/expression_error",
2020
"expressionRevealImage": "src/plugins/expression_reveal_image",
21+
"expressionShape": "src/plugins/expression_shape",
2122
"inputControl": "src/plugins/input_control_vis",
2223
"inspector": "src/plugins/inspector",
2324
"inspectorViews": "src/legacy/core_plugins/inspector_views",

docs/developer/plugin-list.asciidoc

+4
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ want to incorporate their own functions, types, and renderers into the service
9999
for use in their own application.
100100
101101
102+
|{kib-repo}blob/{branch}/src/plugins/expression_shape/README.md[expressionShape]
103+
|Expression Shape plugin adds a shape function to the expression plugin and an associated renderer. The renderer will display the given shape with selected decorations.
104+
105+
102106
|{kib-repo}blob/{branch}/src/plugins/home/README.md[home]
103107
|Moves the legacy ui/registry/feature_catalogue module for registering "features" that should be shown in the home page's feature catalogue to a service within a "home" plugin. The feature catalogue refered to here should not be confused with the "feature" plugin for registering features used to derive UI capabilities for feature controls.
104108

packages/kbn-optimizer/limits.yml

+1
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,4 @@ pageLoadAssetSize:
114114
cases: 144442
115115
expressionError: 22127
116116
userSetup: 18532
117+
expressionShape: 30033

src/dev/storybook/aliases.ts

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const storybookAliases = {
1919
embeddable: 'src/plugins/embeddable/.storybook',
2020
expression_error: 'src/plugins/expression_error/.storybook',
2121
expression_reveal_image: 'src/plugins/expression_reveal_image/.storybook',
22+
expression_shape: 'src/plugins/expression_shape/.storybook',
2223
infra: 'x-pack/plugins/infra/.storybook',
2324
security_solution: 'x-pack/plugins/security_solution/.storybook',
2425
ui_actions_enhanced: 'x-pack/plugins/ui_actions_enhanced/.storybook',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
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 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
// eslint-disable-next-line import/no-commonjs
10+
module.exports = require('@kbn/storybook').defaultConfig;
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# expressionShape
2+
3+
Expression Shape plugin adds a `shape` function to the expression plugin and an associated renderer. The renderer will display the given shape with selected decorations.
4+
5+
---
6+
7+
## Development
8+
9+
See the [kibana contributing guide](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md) for instructions setting up your development environment.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
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 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
import { shapeFunction } from '../common/expression_functions';
10+
import { ExpressionFunction } from '../../../../src/plugins/expressions';
11+
12+
export const functionSpecs = [shapeFunction].map((fn) => new ExpressionFunction(fn()));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
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 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
export * from './function_specs';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
export const PLUGIN_ID = 'expressionShape';
10+
export const PLUGIN_NAME = 'expressionShape';
11+
export const SVG = 'SVG';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
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 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
export { shapeFunction } from './shape_function';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
import { i18n } from '@kbn/i18n';
10+
import { ExpressionShapeFunction, Shape } from '../types';
11+
import { SVG } from '../constants';
12+
import { getAvailableShapes } from '../lib';
13+
14+
export const strings = {
15+
help: i18n.translate('expressionShape.functions.shapeHelpText', {
16+
defaultMessage: 'Creates a shape.',
17+
}),
18+
args: {
19+
shape: i18n.translate('expressionShape.functions.shape.args.shapeHelpText', {
20+
defaultMessage: 'Pick a shape.',
21+
}),
22+
border: i18n.translate('expressionShape.functions.shape.args.borderHelpText', {
23+
defaultMessage: 'An {SVG} color for the border outlining the shape.',
24+
values: {
25+
SVG,
26+
},
27+
}),
28+
borderWidth: i18n.translate('expressionShape.functions.shape.args.borderWidthHelpText', {
29+
defaultMessage: 'The thickness of the border.',
30+
}),
31+
fill: i18n.translate('expressionShape.functions.shape.args.fillHelpText', {
32+
defaultMessage: 'An {SVG} color to fill the shape.',
33+
values: {
34+
SVG,
35+
},
36+
}),
37+
maintainAspect: i18n.translate('expressionShape.functions.shape.args.maintainAspectHelpText', {
38+
defaultMessage: `Maintain the shape's original aspect ratio?`,
39+
}),
40+
},
41+
};
42+
43+
export const errors = {
44+
invalidShape: (shape: string) =>
45+
new Error(
46+
i18n.translate('expressionShape.functions.shape.invalidShapeErrorMessage', {
47+
defaultMessage: "Invalid value: '{shape}'. Such a shape doesn't exist.",
48+
values: {
49+
shape,
50+
},
51+
})
52+
),
53+
};
54+
55+
export const shapeFunction: ExpressionShapeFunction = () => {
56+
const { help, args: argHelp } = strings;
57+
58+
return {
59+
name: 'shape',
60+
aliases: [],
61+
inputTypes: ['null'],
62+
help,
63+
args: {
64+
shape: {
65+
types: ['string'],
66+
help: argHelp.shape,
67+
aliases: ['_'],
68+
default: 'square',
69+
options: Object.values(Shape),
70+
},
71+
border: {
72+
types: ['string'],
73+
aliases: ['stroke'],
74+
help: argHelp.border,
75+
},
76+
borderWidth: {
77+
types: ['number'],
78+
aliases: ['strokeWidth'],
79+
help: argHelp.borderWidth,
80+
default: 0,
81+
},
82+
fill: {
83+
types: ['string'],
84+
help: argHelp.fill,
85+
default: 'black',
86+
},
87+
maintainAspect: {
88+
types: ['boolean'],
89+
help: argHelp.maintainAspect,
90+
default: false,
91+
options: [true, false],
92+
},
93+
},
94+
fn: (input, args) => {
95+
const avaliableShapes = getAvailableShapes();
96+
if (!avaliableShapes.includes(args.shape)) {
97+
throw errors.invalidShape(args.shape);
98+
}
99+
100+
return {
101+
type: 'shape',
102+
...args,
103+
};
104+
},
105+
};
106+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
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 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
export * from './constants';
10+
export * from './types';
11+
12+
export { getAvailableShapes } from './lib/available_shapes';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
import { Shape } from '../types';
10+
11+
export const getAvailableShapes = () => Object.values(Shape);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
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 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
export * from './view_box';
10+
export * from './available_shapes';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
9+
import { ParentNodeParams, ViewBoxParams } from '../types';
10+
11+
export function viewBoxToString(viewBox?: ViewBoxParams): undefined | string {
12+
if (!viewBox) return;
13+
return `${viewBox?.minX} ${viewBox?.minY} ${viewBox?.width} ${viewBox?.height}`;
14+
}
15+
16+
function getMinxAndWidth(viewBoxParams: ViewBoxParams, { borderOffset, width }: ParentNodeParams) {
17+
let { minX, width: shapeWidth } = viewBoxParams;
18+
if (width) {
19+
const xOffset = (shapeWidth / width) * borderOffset;
20+
minX -= xOffset;
21+
shapeWidth += xOffset * 2;
22+
} else {
23+
shapeWidth = 0;
24+
}
25+
26+
return [minX, shapeWidth];
27+
}
28+
29+
function getMinyAndHeight(
30+
viewBoxParams: ViewBoxParams,
31+
{ borderOffset, height }: ParentNodeParams
32+
) {
33+
let { minY, height: shapeHeight } = viewBoxParams;
34+
if (height) {
35+
const yOffset = (shapeHeight / height) * borderOffset;
36+
minY -= yOffset;
37+
shapeHeight += yOffset * 2;
38+
} else {
39+
shapeHeight = 0;
40+
}
41+
42+
return [minY, shapeHeight];
43+
}
44+
45+
export function getViewBox(
46+
viewBoxParams: ViewBoxParams,
47+
parentNodeParams: ParentNodeParams
48+
): ViewBoxParams {
49+
const [minX, width] = getMinxAndWidth(viewBoxParams, parentNodeParams);
50+
const [minY, height] = getMinyAndHeight(viewBoxParams, parentNodeParams);
51+
return { minX, minY, width, height };
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
import { ExpressionFunctionDefinition } from 'src/plugins/expressions';
9+
10+
export enum Shape {
11+
ARROW = 'arrow',
12+
ARROW_MULTI = 'arrowMulti',
13+
BOOKMARK = 'bookmark',
14+
CIRCLE = 'circle',
15+
CROSS = 'cross',
16+
HEXAGON = 'hexagon',
17+
KITE = 'kite',
18+
PENTAGON = 'pentagon',
19+
RHOMBUS = 'rhombus',
20+
SEMICIRCLE = 'semicircle',
21+
SPEECH_BUBBLE = 'speechBubble',
22+
SQUARE = 'square',
23+
STAR = 'star',
24+
TAG = 'tag',
25+
TRIANGLE = 'triangle',
26+
TRIANGLE_RIGHT = 'triangleRight',
27+
}
28+
29+
interface Arguments {
30+
border: string;
31+
borderWidth: number;
32+
shape: Shape;
33+
fill: string;
34+
maintainAspect: boolean;
35+
}
36+
37+
export interface Output extends Arguments {
38+
type: 'shape';
39+
}
40+
41+
export type ExpressionShapeFunction = () => ExpressionFunctionDefinition<
42+
'shape',
43+
number | null,
44+
Arguments,
45+
Output
46+
>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
import { Shape } from './expression_functions';
9+
10+
export type OriginString = 'bottom' | 'left' | 'top' | 'right';
11+
export interface ShapeRendererConfig {
12+
border: string;
13+
borderWidth: number;
14+
shape: Shape;
15+
fill: string;
16+
maintainAspect: boolean;
17+
}
18+
19+
export interface NodeDimensions {
20+
width: number;
21+
height: number;
22+
}
23+
24+
export interface ParentNodeParams {
25+
borderOffset: number;
26+
width: number;
27+
height: number;
28+
}
29+
30+
export interface ViewBoxParams {
31+
minX: number;
32+
minY: number;
33+
width: number;
34+
height: number;
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
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 and the Server Side Public License, v 1; you may not use this file except
5+
* in compliance with, at your election, the Elastic License 2.0 or the Server
6+
* Side Public License, v 1.
7+
*/
8+
export * from './expression_functions';
9+
export * from './expression_renderers';

0 commit comments

Comments
 (0)