From db83f863a05bf6ff7e3bae17d925c264b026d504 Mon Sep 17 00:00:00 2001 From: Clint Andrew Hall Date: Thu, 5 Sep 2019 16:45:23 -0500 Subject: [PATCH] Types + Extract Integration Util (#44433) * Types + Extract Integration Util * Missed a file * Compensate for the TS/JS import confusion by eslint --- .../canvas/__tests__/fixtures/workpads.ts | 10 +++ .../workpad_page/integration_utils.js | 55 +-------------- .../workpad_page/positioning_utils.ts | 68 +++++++++++++++++++ .../workpad_page/workpad_static_page/index.js | 2 +- .../static_workpad_page.js | 2 +- .../canvas/public/state/reducers/pages.js | 2 +- x-pack/legacy/plugins/canvas/types/canvas.ts | 22 ++++-- .../legacy/plugins/canvas/types/elements.ts | 4 ++ 8 files changed, 104 insertions(+), 61 deletions(-) create mode 100644 x-pack/legacy/plugins/canvas/public/components/workpad_page/positioning_utils.ts diff --git a/x-pack/legacy/plugins/canvas/__tests__/fixtures/workpads.ts b/x-pack/legacy/plugins/canvas/__tests__/fixtures/workpads.ts index 0251095c9e75e..d7ebbd87c97e6 100644 --- a/x-pack/legacy/plugins/canvas/__tests__/fixtures/workpads.ts +++ b/x-pack/legacy/plugins/canvas/__tests__/fixtures/workpads.ts @@ -6,6 +6,16 @@ import { CanvasWorkpad, CanvasElement, CanvasPage } from '../../types'; const BaseWorkpad: CanvasWorkpad = { + '@created': '2019-02-08T18:35:23.029Z', + '@timestamp': '2019-02-08T18:35:23.029Z', + assets: { + 'asset-ada763f1-295e-4188-8e08-b5bed9e006a1': { + id: 'asset-ada763f1-295e-4188-8e08-b5bed9e006a1', + '@created': '2018-01-17T19:13:09.185Z', + type: 'dataurl', + value: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciLz4=', + }, + }, name: 'base workpad', id: 'base-workpad', width: 0, diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_page/integration_utils.js b/x-pack/legacy/plugins/canvas/public/components/workpad_page/integration_utils.js index 5866faa08bdfe..51a897d3c6d9a 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_page/integration_utils.js +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_page/integration_utils.js @@ -8,61 +8,12 @@ import { shallowEqual } from 'recompose'; import { getNodes, getSelectedPage } from '../../state/selectors/workpad'; import { addElement, removeElements, setMultiplePositions } from '../../state/actions/elements'; import { selectToplevelNodes } from '../../state/actions/transient'; -import { matrixToAngle, multiply, rotateZ, translate } from '../../lib/aeroelastic/matrix'; +import { matrixToAngle } from '../../lib/aeroelastic/matrix'; import { arrayToMap, flatten, identity } from '../../lib/aeroelastic/functional'; import { getLocalTransformMatrix } from '../../lib/aeroelastic/layout_functions'; +import { isGroupId, elementToShape } from './positioning_utils'; -export const isGroupId = id => id.startsWith('group'); - -const headerData = id => - isGroupId(id) - ? { id, type: 'group', subtype: 'persistentGroup' } - : { id, type: 'rectangleElement', subtype: '' }; - -const transformData = ({ top, left, width, height, angle }, z) => - multiply( - translate(left + width / 2, top + height / 2, z), // painter's algo: latest item (highest z) goes to top - rotateZ((-angle / 180) * Math.PI) // minus angle as transform:matrix3d uses a left-handed coordinate system - ); - -const simplePosition = ({ id, position, filter }, z) => ({ - ...headerData(id), - width: position.width, - height: position.height, - transformMatrix: transformData(position, z), - filter, -}); - -export const simplePositioning = ({ elements }) => ({ elements: elements.map(simplePosition) }); - -/** - * elementToShape - * - * converts a `kibana-canvas` element to an `aeroelastic` shape. - * - * Shape: the layout algorithms need to deal with objects through their geometric properties, excluding other aspects, - * such as what's inside the element, eg. image or scatter plot. This representation is, at its core, a transform matrix - * that establishes a new local coordinate system https://drafts.csswg.org/css-transforms/#local-coordinate-system plus a - * size descriptor. There are two versions of the transform matrix: - * - `transformMatrix` is analogous to the SVG https://drafts.csswg.org/css-transforms/#current-transformation-matrix - * - `localTransformMatrix` is analogous to the SVG https://drafts.csswg.org/css-transforms/#transformation-matrix - * - * Element: it also needs to represent the geometry, primarily because of the need to persist it in `redux` and on the - * server, and to accept such data from the server. The redux and server representations will need to change as more general - * projections such as 3D are added. The element also needs to maintain its content, such as an image or a plot. - * - * While all elements on the current page also exist as shapes, there are shapes that are not elements: annotations. - * For example, `rotation_handle`, `border_resize_handle` and `border_connection` are modeled as shapes by the layout - * library, simply for generality. - */ - -export const elementToShape = ({ id, position }, z) => ({ - ...headerData(id), - parent: (position && position.parent) || null, - transformMatrix: transformData(position, z), - a: position.width / 2, // we currently specify half-width, half-height as it leads to - b: position.height / 2, // more regular math (like ellipsis radii rather than diameters) -}); +export * from './positioning_utils'; const shapeToElement = shape => ({ left: shape.transformMatrix[12] - shape.a, diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_page/positioning_utils.ts b/x-pack/legacy/plugins/canvas/public/components/workpad_page/positioning_utils.ts new file mode 100644 index 0000000000000..f4d399065df83 --- /dev/null +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_page/positioning_utils.ts @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { PositionedElement, ElementPosition } from '../../../types'; +import { multiply, rotateZ, translate } from '../../lib/aeroelastic/matrix'; + +export const isGroupId = (id: string) => id.startsWith('group'); + +const headerData = (id: string) => + isGroupId(id) + ? { id, type: 'group', subtype: 'persistentGroup' } + : { id, type: 'rectangleElement', subtype: '' }; + +const transformData = ({ top, left, width, height, angle }: ElementPosition, z: number) => + multiply( + translate(left + width / 2, top + height / 2, z), // painter's algo: latest item (highest z) goes to top + rotateZ((-angle / 180) * Math.PI) // minus angle as transform:matrix3d uses a left-handed coordinate system + ); + +/** + * elementToShape + * + * converts a `kibana-canvas` element to an `aeroelastic` shape. + * + * Shape: the layout algorithms need to deal with objects through their geometric properties, excluding other aspects, + * such as what's inside the element, eg. image or scatter plot. This representation is, at its core, a transform matrix + * that establishes a new local coordinate system https://drafts.csswg.org/css-transforms/#local-coordinate-system plus a + * size descriptor. There are two versions of the transform matrix: + * - `transformMatrix` is analogous to the SVG https://drafts.csswg.org/css-transforms/#current-transformation-matrix + * - `localTransformMatrix` is analogous to the SVG https://drafts.csswg.org/css-transforms/#transformation-matrix + * + * Element: it also needs to represent the geometry, primarily because of the need to persist it in `redux` and on the + * server, and to accept such data from the server. The redux and server representations will need to change as more general + * projections such as 3D are added. The element also needs to maintain its content, such as an image or a plot. + * + * While all elements on the current page also exist as shapes, there are shapes that are not elements: annotations. + * For example, `rotation_handle`, `border_resize_handle` and `border_connection` are modeled as shapes by the layout + * library, simply for generality. + */ + +export const elementToShape = ( + { id, position }: { id: string; position: ElementPosition }, + z: number +) => ({ + ...headerData(id), + parent: (position && position.parent) || null, + transformMatrix: transformData(position, z), + a: position.width / 2, // we currently specify half-width, half-height as it leads to + b: position.height / 2, // more regular math (like ellipsis radii rather than diameters) +}); + +const simplePosition = ( + { id, position, filter }: { id: string; position: ElementPosition; filter: string }, + z: number +) => ({ + ...headerData(id), + width: position.width, + height: position.height, + transformMatrix: transformData(position, z), + filter, +}); + +export const simplePositioning = ({ elements }: { elements: PositionedElement[] }) => ({ + elements: elements.map(simplePosition), +}); diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_static_page/index.js b/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_static_page/index.js index f539436e97e89..6bd7af7cc89ef 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_static_page/index.js +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_static_page/index.js @@ -5,7 +5,7 @@ */ import { withProps } from 'recompose'; -import { simplePositioning } from '../integration_utils'; +import { simplePositioning } from '../positioning_utils'; import { StaticWorkpadPage } from './static_workpad_page'; export const StaticPage = () => withProps(simplePositioning)(StaticWorkpadPage); diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_static_page/static_workpad_page.js b/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_static_page/static_workpad_page.js index 94e16fd97bb8b..9e8962755e00b 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_static_page/static_workpad_page.js +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_page/workpad_static_page/static_workpad_page.js @@ -7,7 +7,7 @@ import React, { PureComponent } from 'react'; import { ElementWrapper } from '../../element_wrapper'; import { staticWorkpadPagePropTypes } from '../prop_types'; -import { isGroupId } from '../integration_utils'; +import { isGroupId } from '../positioning_utils'; export class StaticWorkpadPage extends PureComponent { static propTypes = staticWorkpadPagePropTypes; diff --git a/x-pack/legacy/plugins/canvas/public/state/reducers/pages.js b/x-pack/legacy/plugins/canvas/public/state/reducers/pages.js index 224d0a3c03795..50a28475ef5bc 100644 --- a/x-pack/legacy/plugins/canvas/public/state/reducers/pages.js +++ b/x-pack/legacy/plugins/canvas/public/state/reducers/pages.js @@ -12,7 +12,7 @@ import { routerProvider } from '../../lib/router_provider'; import { getDefaultPage } from '../defaults'; import * as actions from '../actions/pages'; import { getSelectedPageIndex } from '../selectors/workpad'; -import { isGroupId } from '../../components/workpad_page/integration_utils'; +import { isGroupId } from '../../components/workpad_page/positioning_utils'; const { set, del, insert } = immutable; diff --git a/x-pack/legacy/plugins/canvas/types/canvas.ts b/x-pack/legacy/plugins/canvas/types/canvas.ts index 97f8917d50725..0843e5e99dc4e 100644 --- a/x-pack/legacy/plugins/canvas/types/canvas.ts +++ b/x-pack/legacy/plugins/canvas/types/canvas.ts @@ -6,6 +6,13 @@ import { ElementPosition } from './elements'; +export interface CanvasAsset { + '@created': string; + id: string; + type: 'dataurl'; + value: string; +} + export interface CanvasElement { id: string; position: ElementPosition; @@ -25,13 +32,16 @@ export interface CanvasPage { } export interface CanvasWorkpad { - name: string; - id: string; - width: number; - height: number; + '@created': string; + '@timestamp': string; + assets: { [id: string]: CanvasAsset }; + colors: string[]; css: string; + height: number; + id: string; + isWriteable: boolean; + name: string; page: number; pages: CanvasPage[]; - colors: string[]; - isWriteable: boolean; + width: number; } diff --git a/x-pack/legacy/plugins/canvas/types/elements.ts b/x-pack/legacy/plugins/canvas/types/elements.ts index 48047c327a6e9..ce9db8202072f 100644 --- a/x-pack/legacy/plugins/canvas/types/elements.ts +++ b/x-pack/legacy/plugins/canvas/types/elements.ts @@ -95,4 +95,8 @@ export interface PositionedElement { * AST of the Canvas expression for the element */ ast: ExpressionAST; + /** + * Applied filter + */ + filter: string; }