Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[7.x] [Canvas] Expression error (#103048) #105724

Merged
merged 1 commit into from
Jul 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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