Skip to content

Commit

Permalink
[Canvas] Expression error (#103048) (#105724)
Browse files Browse the repository at this point in the history
* Basic setup of error plugin.

* Removed not used `function` files at `error` expression.

* Moved related components from canvas.

* Changed imports of components.

* Fixed renderer and storybook.

* Fixed types errors.

* Added limits.

* Removed useless translations and fixed .i18nrc.json

* added `done` handler call.

* Added more fixes fo i18nc.

* Added docs.

* 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.

* Fixed storybook error.

* More fixes.

* removed unused translations.

* Removed handlers and changed the way of handling `resize` and calling `done`.

* Fixed i18n error.

* Fixed storybook.

* Replaced Popover with EuiPopover.

* Moved `Popover` back to `canvas`

* Removed `Popover` export from presentation_utils components.

* Moved error_component and debug_component from presentation_util to expression_error.

* Fixed translations and imports.

* Moved `debug renderer` to `expression_error` plugin.

* Fixed error.

* Fixed lazy exports.

* Fixed imports

* Fixed storybook snapshot.

* Removed `.i18nrc.json`.

* Fixed color of `error`.

* Exported concrete elements from popover.

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
# Conflicts:
#	packages/kbn-optimizer/limits.yml
#	src/plugins/expression_error/public/components/debug/debug.tsx
  • Loading branch information
Kuznietsov authored Jul 15, 2021
1 parent 125eee0 commit d54d0b5
Show file tree
Hide file tree
Showing 59 changed files with 538 additions and 218 deletions.
1 change: 1 addition & 0 deletions .i18nrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"esUi": "src/plugins/es_ui_shared",
"devTools": "src/plugins/dev_tools",
"expressions": "src/plugins/expressions",
"expressionError": "src/plugins/expression_error",
"expressionRevealImage": "src/plugins/expression_reveal_image",
"inputControl": "src/plugins/input_control_vis",
"inspector": "src/plugins/inspector",
Expand Down
4 changes: 4 additions & 0 deletions docs/developer/plugin-list.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ This API doesn't support angular, for registering angular dev tools, bootstrap a
|WARNING: Missing README.
|{kib-repo}blob/{branch}/src/plugins/expression_error/README.md[expressionError]
|Expression Error plugin adds an error renderer to the expression plugin. The renderer will display the error image.
|{kib-repo}blob/{branch}/src/plugins/expression_reveal_image/README.md[expressionRevealImage]
|Expression Reveal Image plugin adds a revealImage function to the expression plugin and an associated renderer. The renderer will display the given percentage of a given image.
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,4 @@ pageLoadAssetSize:
visTypePie: 35583
expressionRevealImage: 25675
cases: 144442
expressionError: 22127
1 change: 1 addition & 0 deletions src/dev/storybook/aliases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const storybookAliases = {
dashboard_enhanced: 'x-pack/plugins/dashboard_enhanced/.storybook',
data_enhanced: 'x-pack/plugins/data_enhanced/.storybook',
embeddable: 'src/plugins/embeddable/.storybook',
expression_error: 'src/plugins/expression_error/.storybook',
expression_reveal_image: 'src/plugins/expression_reveal_image/.storybook',
infra: 'x-pack/plugins/infra/.storybook',
security_solution: 'x-pack/plugins/security_solution/.storybook',
Expand Down
10 changes: 10 additions & 0 deletions src/plugins/expression_error/.storybook/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* 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.
*/

// eslint-disable-next-line import/no-commonjs
module.exports = require('@kbn/storybook').defaultConfig;
9 changes: 9 additions & 0 deletions src/plugins/expression_error/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# expressionRevealImage

Expression Error plugin adds an `error` renderer to the expression plugin. The renderer will display the error image.

---

## Development

See the [kibana contributing guide](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md) for instructions setting up your development environment.
11 changes: 11 additions & 0 deletions src/plugins/expression_error/common/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* 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.
*/
export const PLUGIN_ID = 'expressionError';
export const PLUGIN_NAME = 'expressionError';

export const JSON = 'JSON';
9 changes: 9 additions & 0 deletions src/plugins/expression_error/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export * from './constants';
18 changes: 18 additions & 0 deletions src/plugins/expression_error/common/types/expression_renderers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* 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.
*/

export type OriginString = 'bottom' | 'left' | 'top' | 'right';

export interface ErrorRendererConfig {
error: Error;
}

export interface NodeDimensions {
width: number;
height: number;
}
9 changes: 9 additions & 0 deletions src/plugins/expression_error/common/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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.
*/

export * from './expression_renderers';
13 changes: 13 additions & 0 deletions src/plugins/expression_error/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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.
*/

module.exports = {
preset: '@kbn/test',
rootDir: '../../..',
roots: ['<rootDir>/src/plugins/expression_error'],
};
10 changes: 10 additions & 0 deletions src/plugins/expression_error/kibana.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"id": "expressionError",
"version": "1.0.0",
"kibanaVersion": "kibana",
"server": false,
"ui": true,
"requiredPlugins": ["expressions", "presentationUtil"],
"optionalPlugins": [],
"requiredBundles": []
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
* 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 React from 'react';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
* 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.
*/

export const largePayload = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
* 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 React from 'react';
import PropTypes from 'prop-types';
import { EuiCode } from '@elastic/eui';
import './debug.scss';

const LimitRows = (key: string, value: any) => {
if (key === 'rows') {
Expand All @@ -16,14 +17,10 @@ const LimitRows = (key: string, value: any) => {
return value;
};

export const Debug = ({ payload }: any) => (
export const Debug = ({ payload }: { payload: unknown }) => (
<EuiCode className="canvasDebug">
<pre className="canvasDebug__content" data-test-subj="canvasDebug__content">
{JSON.stringify(payload, LimitRows, 2)}
</pre>
</EuiCode>
);

Debug.propTypes = {
payload: PropTypes.object.isRequired,
};
10 changes: 10 additions & 0 deletions src/plugins/expression_error/public/components/debug/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* 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.
*/

// eslint-disable-next-line import/no-default-export
export { Debug as default } from './debug';
52 changes: 52 additions & 0 deletions src/plugins/expression_error/public/components/debug_component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* 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 React, { useState, useEffect, useCallback } from 'react';
import { useResizeObserver } from '@elastic/eui';
import { IInterpreterRenderHandlers } from '../../../expressions';
import { withSuspense } from '../../../presentation_util/public';
import { NodeDimensions } from '../../common/types';
import { LazyDebugComponent } from '.';

const Debug = withSuspense(LazyDebugComponent);

interface DebugComponentProps {
onLoaded: IInterpreterRenderHandlers['done'];
parentNode: HTMLElement;
payload: any;
}

function DebugComponent({ onLoaded, parentNode, payload }: DebugComponentProps) {
const parentNodeDimensions = useResizeObserver(parentNode);
const [dimensions, setDimensions] = useState<NodeDimensions>({
width: parentNode.offsetWidth,
height: parentNode.offsetHeight,
});

const updateDebugView = useCallback(() => {
setDimensions({
width: parentNode.offsetWidth,
height: parentNode.offsetHeight,
});
onLoaded();
}, [parentNode, onLoaded]);

useEffect(() => {
updateDebugView();
}, [parentNodeDimensions, updateDebugView]);

return (
<div style={dimensions}>
<Debug payload={payload} />
</div>
);
}

// default export required for React.Lazy
// eslint-disable-next-line import/no-default-export
export { DebugComponent as default };
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
* 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 React, { FC } from 'react';
import PropTypes from 'prop-types';
import { EuiCallOut } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { get } from 'lodash';

import { ShowDebugging } from './show_debugging';

const strings = {
getDescription: () =>
i18n.translate('xpack.canvas.errorComponent.description', {
i18n.translate('expressionError.errorComponent.description', {
defaultMessage: 'Expression failed with the message:',
}),
getTitle: () =>
i18n.translate('xpack.canvas.errorComponent.title', {
i18n.translate('expressionError.errorComponent.title', {
defaultMessage: 'Whoops! Expression failed',
}),
};

export interface Props {
payload: {
error: Error;
Expand All @@ -46,7 +46,3 @@ export const Error: FC<Props> = ({ payload }) => {
</EuiCallOut>
);
};

Error.propTypes = {
payload: PropTypes.object.isRequired,
};
10 changes: 10 additions & 0 deletions src/plugins/expression_error/public/components/error/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* 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.
*/

// eslint-disable-next-line import/no-default-export
export { Error as default } from './error';
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
* 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 React, { FC, useState } from 'react';
import PropTypes from 'prop-types';
import { EuiButtonEmpty } from '@elastic/eui';
import { Debug } from '../debug';
import Debug from '../debug';
import { Props } from './error';

export const ShowDebugging: FC<Props> = ({ payload }) => {
Expand All @@ -30,7 +30,3 @@ export const ShowDebugging: FC<Props> = ({ payload }) => {
</div>
);
};

ShowDebugging.propTypes = {
payload: PropTypes.object.isRequired,
};
67 changes: 67 additions & 0 deletions src/plugins/expression_error/public/components/error_component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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 React, { useState, useEffect, useCallback } from 'react';
import { EuiIcon, useResizeObserver, EuiPopover } from '@elastic/eui';
import { IInterpreterRenderHandlers } from '../../../expressions';
import { withSuspense } from '../../../presentation_util/public';
import { ErrorRendererConfig } from '../../common/types';
import { LazyErrorComponent } from '.';

const Error = withSuspense(LazyErrorComponent);

interface ErrorComponentProps extends ErrorRendererConfig {
onLoaded: IInterpreterRenderHandlers['done'];
parentNode: HTMLElement;
}

function ErrorComponent({ onLoaded, parentNode, error }: ErrorComponentProps) {
const getButtonSize = (node: HTMLElement) => Math.min(node.clientHeight, node.clientWidth);
const parentNodeDimensions = useResizeObserver(parentNode);

const [buttonSize, setButtonSize] = useState<number>(getButtonSize(parentNode));
const [isPopoverOpen, setPopoverOpen] = useState<boolean>(false);

const handlePopoverClick = () => setPopoverOpen(!isPopoverOpen);
const closePopover = () => setPopoverOpen(false);

const updateErrorView = useCallback(() => {
setButtonSize(getButtonSize(parentNode));
onLoaded();
}, [parentNode, onLoaded]);

useEffect(() => {
updateErrorView();
}, [parentNodeDimensions, updateErrorView]);

return (
<div className="canvasRenderError">
<EuiPopover
closePopover={closePopover}
button={
<EuiIcon
className="canvasRenderError__icon"
onClick={handlePopoverClick}
style={{
height: buttonSize,
width: buttonSize,
}}
type="alert"
/>
}
isOpen={isPopoverOpen}
>
<Error payload={{ error }} />
</EuiPopover>
</div>
);
}

// default export required for React.Lazy
// eslint-disable-next-line import/no-default-export
export { ErrorComponent as default };
Loading

0 comments on commit d54d0b5

Please sign in to comment.