mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
* Lazy load metrics vis * Use common chart spinner * Simplify markdown renderer * Update tests * Update types for metric vis * Fix tests * Fix merge conflict Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
ca86c890b2
commit
4c3068cc7c
20 changed files with 132 additions and 199 deletions
|
@ -4,5 +4,5 @@
|
|||
"ui": true,
|
||||
"server": true,
|
||||
"requiredPlugins": ["expressions", "visualizations"],
|
||||
"requiredBundles": ["kibanaUtils", "kibanaReact", "charts", "visualizations", "expressions", "visDefaultEditor"]
|
||||
"requiredBundles": ["kibanaReact", "charts", "visualizations", "expressions", "visDefaultEditor"]
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ Object {
|
|||
"as": "markdown_vis",
|
||||
"type": "render",
|
||||
"value": Object {
|
||||
"visConfig": Object {
|
||||
"visParams": Object {
|
||||
"fontSize": 12,
|
||||
"markdown": "## hello _markdown_",
|
||||
"openLinksInNewTab": true,
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
// Prefix all styles with "mkd" to avoid conflicts.
|
||||
// Examples
|
||||
// mkdChart
|
||||
// mkdChart__legend
|
||||
// mkdChart__legend--small
|
||||
// mkdChart__legend-isLoading
|
||||
|
||||
@import './markdown_vis';
|
|
@ -21,16 +21,16 @@ import { i18n } from '@kbn/i18n';
|
|||
import { ExpressionFunctionDefinition, Render } from '../../expressions/public';
|
||||
import { Arguments, MarkdownVisParams } from './types';
|
||||
|
||||
interface RenderValue {
|
||||
export interface MarkdownVisRenderValue {
|
||||
visType: 'markdown';
|
||||
visConfig: MarkdownVisParams;
|
||||
visParams: MarkdownVisParams;
|
||||
}
|
||||
|
||||
export type MarkdownVisExpressionFunctionDefinition = ExpressionFunctionDefinition<
|
||||
'markdownVis',
|
||||
unknown,
|
||||
Arguments,
|
||||
Render<RenderValue>
|
||||
Render<MarkdownVisRenderValue>
|
||||
>;
|
||||
|
||||
export const createMarkdownVisFn = (): MarkdownVisExpressionFunctionDefinition => ({
|
||||
|
@ -70,7 +70,7 @@ export const createMarkdownVisFn = (): MarkdownVisExpressionFunctionDefinition =
|
|||
as: 'markdown_vis',
|
||||
value: {
|
||||
visType: 'markdown',
|
||||
visConfig: {
|
||||
visParams: {
|
||||
markdown: args.markdown,
|
||||
openLinksInNewTab: args.openLinksInNewTab,
|
||||
fontSize: parseInt(args.font.spec.fontSize || '12', 10),
|
||||
|
|
|
@ -17,41 +17,29 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { lazy } from 'react';
|
||||
import { render, unmountComponentAtNode } from 'react-dom';
|
||||
import { VisualizationContainer } from '../../visualizations/public';
|
||||
import { ExpressionRenderDefinition } from '../../expressions/common/expression_renderers';
|
||||
import { MarkdownVisWrapper } from './markdown_vis_controller';
|
||||
import { StartServicesGetter } from '../../kibana_utils/public';
|
||||
import { MarkdownVisRenderValue } from './markdown_fn';
|
||||
|
||||
export const getMarkdownRenderer = (start: StartServicesGetter) => {
|
||||
const markdownVisRenderer: () => ExpressionRenderDefinition = () => ({
|
||||
name: 'markdown_vis',
|
||||
displayName: 'markdown visualization',
|
||||
reuseDomNode: true,
|
||||
render: async (domNode: HTMLElement, config: any, handlers: any) => {
|
||||
const { visConfig } = config;
|
||||
// @ts-ignore
|
||||
const MarkdownVisComponent = lazy(() => import('./markdown_vis_controller'));
|
||||
|
||||
const I18nContext = await start().core.i18n.Context;
|
||||
export const markdownVisRenderer: ExpressionRenderDefinition<MarkdownVisRenderValue> = {
|
||||
name: 'markdown_vis',
|
||||
displayName: 'markdown visualization',
|
||||
reuseDomNode: true,
|
||||
render: async (domNode, { visParams }, handlers) => {
|
||||
handlers.onDestroy(() => {
|
||||
unmountComponentAtNode(domNode);
|
||||
});
|
||||
|
||||
handlers.onDestroy(() => {
|
||||
unmountComponentAtNode(domNode);
|
||||
});
|
||||
|
||||
render(
|
||||
<I18nContext>
|
||||
<VisualizationContainer className="markdownVis">
|
||||
<MarkdownVisWrapper
|
||||
visParams={visConfig}
|
||||
renderComplete={handlers.done}
|
||||
fireEvent={handlers.event}
|
||||
/>
|
||||
</VisualizationContainer>
|
||||
</I18nContext>,
|
||||
domNode
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
return markdownVisRenderer;
|
||||
render(
|
||||
<VisualizationContainer className="markdownVis">
|
||||
<MarkdownVisComponent {...visParams} renderComplete={handlers.done} />
|
||||
</VisualizationContainer>,
|
||||
domNode
|
||||
);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
// Prefix all styles with "mkd" to avoid conflicts.
|
||||
// Examples
|
||||
// mkdChart
|
||||
// mkdChart__legend
|
||||
// mkdChart__legend--small
|
||||
// mkdChart__legend-isLoading
|
||||
|
||||
.mkdVis {
|
||||
padding: $euiSizeS;
|
||||
width: 100%;
|
|
@ -20,7 +20,7 @@
|
|||
import React from 'react';
|
||||
import { wait } from '@testing-library/dom';
|
||||
import { render, cleanup } from '@testing-library/react/pure';
|
||||
import { MarkdownVisWrapper } from './markdown_vis_controller';
|
||||
import MarkdownVisComponent from './markdown_vis_controller';
|
||||
|
||||
afterEach(cleanup);
|
||||
|
||||
|
@ -36,7 +36,7 @@ describe('markdown vis controller', () => {
|
|||
};
|
||||
|
||||
const { getByTestId, getByText } = render(
|
||||
<MarkdownVisWrapper visParams={vis.params} renderComplete={jest.fn()} fireEvent={jest.fn()} />
|
||||
<MarkdownVisComponent {...vis.params} renderComplete={jest.fn()} />
|
||||
);
|
||||
|
||||
await wait(() => getByTestId('markdownBody'));
|
||||
|
@ -60,7 +60,7 @@ describe('markdown vis controller', () => {
|
|||
};
|
||||
|
||||
const { getByTestId, getByText } = render(
|
||||
<MarkdownVisWrapper visParams={vis.params} renderComplete={jest.fn()} fireEvent={jest.fn()} />
|
||||
<MarkdownVisComponent {...vis.params} renderComplete={jest.fn()} />
|
||||
);
|
||||
|
||||
await wait(() => getByTestId('markdownBody'));
|
||||
|
@ -82,7 +82,7 @@ describe('markdown vis controller', () => {
|
|||
};
|
||||
|
||||
const { getByTestId, getByText, rerender } = render(
|
||||
<MarkdownVisWrapper visParams={vis.params} renderComplete={jest.fn()} fireEvent={jest.fn()} />
|
||||
<MarkdownVisComponent {...vis.params} renderComplete={jest.fn()} />
|
||||
);
|
||||
|
||||
await wait(() => getByTestId('markdownBody'));
|
||||
|
@ -90,9 +90,7 @@ describe('markdown vis controller', () => {
|
|||
expect(getByText(/initial/i)).toBeInTheDocument();
|
||||
|
||||
vis.params.markdown = 'Updated';
|
||||
rerender(
|
||||
<MarkdownVisWrapper visParams={vis.params} renderComplete={jest.fn()} fireEvent={jest.fn()} />
|
||||
);
|
||||
rerender(<MarkdownVisComponent {...vis.params} renderComplete={jest.fn()} />);
|
||||
|
||||
expect(getByText(/Updated/i)).toBeInTheDocument();
|
||||
});
|
||||
|
@ -114,11 +112,7 @@ describe('markdown vis controller', () => {
|
|||
|
||||
it('should be called on initial rendering', async () => {
|
||||
const { getByTestId } = render(
|
||||
<MarkdownVisWrapper
|
||||
visParams={vis.params}
|
||||
renderComplete={renderComplete}
|
||||
fireEvent={jest.fn()}
|
||||
/>
|
||||
<MarkdownVisComponent {...vis.params} renderComplete={renderComplete} />
|
||||
);
|
||||
|
||||
await wait(() => getByTestId('markdownBody'));
|
||||
|
@ -128,11 +122,7 @@ describe('markdown vis controller', () => {
|
|||
|
||||
it('should be called on successive render when params change', async () => {
|
||||
const { getByTestId, rerender } = render(
|
||||
<MarkdownVisWrapper
|
||||
visParams={vis.params}
|
||||
renderComplete={renderComplete}
|
||||
fireEvent={jest.fn()}
|
||||
/>
|
||||
<MarkdownVisComponent {...vis.params} renderComplete={renderComplete} />
|
||||
);
|
||||
|
||||
await wait(() => getByTestId('markdownBody'));
|
||||
|
@ -142,24 +132,14 @@ describe('markdown vis controller', () => {
|
|||
renderComplete.mockClear();
|
||||
vis.params.markdown = 'changed';
|
||||
|
||||
rerender(
|
||||
<MarkdownVisWrapper
|
||||
visParams={vis.params}
|
||||
renderComplete={renderComplete}
|
||||
fireEvent={jest.fn()}
|
||||
/>
|
||||
);
|
||||
rerender(<MarkdownVisComponent {...vis.params} renderComplete={renderComplete} />);
|
||||
|
||||
expect(renderComplete).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should be called on successive render even without data change', async () => {
|
||||
const { getByTestId, rerender } = render(
|
||||
<MarkdownVisWrapper
|
||||
visParams={vis.params}
|
||||
renderComplete={renderComplete}
|
||||
fireEvent={jest.fn()}
|
||||
/>
|
||||
<MarkdownVisComponent {...vis.params} renderComplete={renderComplete} />
|
||||
);
|
||||
|
||||
await wait(() => getByTestId('markdownBody'));
|
||||
|
@ -168,13 +148,7 @@ describe('markdown vis controller', () => {
|
|||
|
||||
renderComplete.mockClear();
|
||||
|
||||
rerender(
|
||||
<MarkdownVisWrapper
|
||||
visParams={vis.params}
|
||||
renderComplete={renderComplete}
|
||||
fireEvent={jest.fn()}
|
||||
/>
|
||||
);
|
||||
rerender(<MarkdownVisComponent {...vis.params} renderComplete={renderComplete} />);
|
||||
|
||||
expect(renderComplete).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
|
|
@ -17,83 +17,35 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { Markdown } from '../../kibana_react/public';
|
||||
import { MarkdownVisParams } from './types';
|
||||
|
||||
import './markdown_vis.scss';
|
||||
|
||||
interface MarkdownVisComponentProps extends MarkdownVisParams {
|
||||
renderComplete: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* The MarkdownVisComponent renders markdown to HTML and presents it.
|
||||
*/
|
||||
class MarkdownVisComponent extends React.Component<MarkdownVisComponentProps> {
|
||||
/**
|
||||
* Will be called after the first render when the component is present in the DOM.
|
||||
*
|
||||
* We call renderComplete here, to signal, that we are done with rendering.
|
||||
*/
|
||||
componentDidMount() {
|
||||
this.props.renderComplete();
|
||||
}
|
||||
const MarkdownVisComponent = ({
|
||||
fontSize,
|
||||
markdown,
|
||||
openLinksInNewTab,
|
||||
renderComplete,
|
||||
}: MarkdownVisComponentProps) => {
|
||||
useEffect(renderComplete); // renderComplete will be called after each render to signal, that we are done with rendering.
|
||||
|
||||
/**
|
||||
* Will be called after the component has been updated and the changes has been
|
||||
* flushed into the DOM.
|
||||
*
|
||||
* We will use this to signal that we are done rendering by calling the
|
||||
* renderComplete property.
|
||||
*/
|
||||
componentDidUpdate() {
|
||||
this.props.renderComplete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the actual HTML.
|
||||
* Note: if only fontSize parameter has changed, this method will be called
|
||||
* and return the appropriate JSX, but React will detect, that only the
|
||||
* style argument has been updated, and thus only set this attribute to the DOM.
|
||||
*/
|
||||
render() {
|
||||
return (
|
||||
<div className="mkdVis" style={{ fontSize: `${this.props.fontSize}pt` }}>
|
||||
<Markdown
|
||||
data-test-subj="markdownBody"
|
||||
markdown={this.props.markdown}
|
||||
openLinksInNewTab={this.props.openLinksInNewTab}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a wrapper component, that is actually used as the visualization.
|
||||
* The sole purpose of this component is to extract all required parameters from
|
||||
* the properties and pass them down as separate properties to the actual component.
|
||||
* That way the actual (MarkdownVisComponent) will properly trigger it's prop update
|
||||
* callback (componentWillReceiveProps) if one of these params change. It wouldn't
|
||||
* trigger otherwise (e.g. it doesn't for this wrapper), since it only triggers
|
||||
* if the reference to the prop changes (in this case the reference to vis).
|
||||
*
|
||||
* The way React works, this wrapper nearly brings no overhead, but allows us
|
||||
* to use proper lifecycle methods in the actual component.
|
||||
*/
|
||||
|
||||
export interface MarkdownVisWrapperProps {
|
||||
visParams: MarkdownVisParams;
|
||||
fireEvent: (event: any) => void;
|
||||
renderComplete: () => void;
|
||||
}
|
||||
|
||||
export function MarkdownVisWrapper(props: MarkdownVisWrapperProps) {
|
||||
return (
|
||||
<MarkdownVisComponent
|
||||
fontSize={props.visParams.fontSize}
|
||||
markdown={props.visParams.markdown}
|
||||
openLinksInNewTab={props.visParams.openLinksInNewTab}
|
||||
renderComplete={props.renderComplete}
|
||||
/>
|
||||
<div className="mkdVis" style={{ fontSize: `${fontSize}pt` }}>
|
||||
<Markdown
|
||||
data-test-subj="markdownBody"
|
||||
markdown={markdown}
|
||||
openLinksInNewTab={openLinksInNewTab}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// default export required for React.Lazy
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export { MarkdownVisComponent as default };
|
||||
|
|
|
@ -24,10 +24,7 @@ import { VisualizationsSetup } from '../../visualizations/public';
|
|||
import { markdownVisDefinition } from './markdown_vis';
|
||||
import { createMarkdownVisFn } from './markdown_fn';
|
||||
import { ConfigSchema } from '../config';
|
||||
|
||||
import './index.scss';
|
||||
import { getMarkdownRenderer } from './markdown_renderer';
|
||||
import { createStartServicesGetter } from '../../kibana_utils/public';
|
||||
import { markdownVisRenderer } from './markdown_renderer';
|
||||
|
||||
/** @internal */
|
||||
export interface MarkdownPluginSetupDependencies {
|
||||
|
@ -44,9 +41,8 @@ export class MarkdownPlugin implements Plugin<void, void> {
|
|||
}
|
||||
|
||||
public setup(core: CoreSetup, { expressions, visualizations }: MarkdownPluginSetupDependencies) {
|
||||
const start = createStartServicesGetter(core.getStartServices);
|
||||
visualizations.createBaseVisualization(markdownVisDefinition);
|
||||
expressions.registerRenderer(getMarkdownRenderer(start));
|
||||
expressions.registerRenderer(markdownVisRenderer);
|
||||
expressions.registerFunction(createMarkdownVisFn);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
// Prefix all styles with "mtr" to avoid conflicts.
|
||||
// Examples
|
||||
// mtrChart
|
||||
// mtrChart__legend
|
||||
// mtrChart__legend--small
|
||||
// mtrChart__legend-isLoading
|
||||
|
||||
.mtrVis {
|
||||
width: 100%;
|
||||
display: flex;
|
|
@ -20,7 +20,7 @@
|
|||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { MetricVisComponent, MetricVisComponentProps } from './metric_vis_component';
|
||||
import MetricVisComponent, { MetricVisComponentProps } from './metric_vis_component';
|
||||
|
||||
jest.mock('../services', () => ({
|
||||
getFormatService: () => ({
|
||||
|
|
|
@ -30,14 +30,16 @@ import { getFormatService } from '../services';
|
|||
import { SchemaConfig } from '../../../visualizations/public';
|
||||
import { Range } from '../../../expressions/public';
|
||||
|
||||
import './metric_vis.scss';
|
||||
|
||||
export interface MetricVisComponentProps {
|
||||
visParams: VisParams;
|
||||
visParams: Pick<VisParams, 'metric' | 'dimensions'>;
|
||||
visData: Input;
|
||||
fireEvent: (event: any) => void;
|
||||
renderComplete: () => void;
|
||||
}
|
||||
|
||||
export class MetricVisComponent extends Component<MetricVisComponentProps> {
|
||||
class MetricVisComponent extends Component<MetricVisComponentProps> {
|
||||
private getLabels() {
|
||||
const config = this.props.visParams.metric;
|
||||
const isPercentageMode = config.percentageMode;
|
||||
|
@ -209,3 +211,7 @@ export class MetricVisComponent extends Component<MetricVisComponentProps> {
|
|||
return metricsHtml;
|
||||
}
|
||||
}
|
||||
|
||||
// default export required for React.Lazy
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export { MetricVisComponent as default };
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
// Prefix all styles with "mtr" to avoid conflicts.
|
||||
// Examples
|
||||
// mtrChart
|
||||
// mtrChart__legend
|
||||
// mtrChart__legend--small
|
||||
// mtrChart__legend-isLoading
|
||||
|
||||
@import 'metric_vis';
|
|
@ -16,7 +16,6 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import './index.scss';
|
||||
import { PluginInitializerContext } from 'kibana/public';
|
||||
import { MetricVisPlugin as Plugin } from './plugin';
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ interface Arguments {
|
|||
bucket: any; // these aren't typed yet
|
||||
}
|
||||
|
||||
interface RenderValue {
|
||||
export interface MetricVisRenderValue {
|
||||
visType: typeof visType;
|
||||
visData: Input;
|
||||
visConfig: Pick<VisParams, 'metric' | 'dimensions'>;
|
||||
|
@ -57,7 +57,7 @@ export type MetricVisExpressionFunctionDefinition = ExpressionFunctionDefinition
|
|||
'metricVis',
|
||||
Input,
|
||||
Arguments,
|
||||
Render<RenderValue>
|
||||
Render<MetricVisRenderValue>
|
||||
>;
|
||||
|
||||
export const createMetricVisFn = (): MetricVisExpressionFunctionDefinition => ({
|
||||
|
|
|
@ -17,37 +17,33 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { lazy } from 'react';
|
||||
import { render, unmountComponentAtNode } from 'react-dom';
|
||||
import { MetricVisComponent } from './components/metric_vis_component';
|
||||
import { getI18n } from './services';
|
||||
|
||||
import { VisualizationContainer } from '../../visualizations/public';
|
||||
import { ExpressionRenderDefinition } from '../../expressions/common/expression_renderers';
|
||||
import { MetricVisRenderValue } from './metric_vis_fn';
|
||||
// @ts-ignore
|
||||
const MetricVisComponent = lazy(() => import('./components/metric_vis_component'));
|
||||
|
||||
export const metricVisRenderer: () => ExpressionRenderDefinition = () => ({
|
||||
export const metricVisRenderer: () => ExpressionRenderDefinition<MetricVisRenderValue> = () => ({
|
||||
name: 'metric_vis',
|
||||
displayName: 'metric visualization',
|
||||
reuseDomNode: true,
|
||||
render: async (domNode: HTMLElement, config: any, handlers: any) => {
|
||||
const { visData, visConfig } = config;
|
||||
|
||||
const I18nContext = getI18n().Context;
|
||||
|
||||
render: async (domNode, { visData, visConfig }, handlers) => {
|
||||
handlers.onDestroy(() => {
|
||||
unmountComponentAtNode(domNode);
|
||||
});
|
||||
|
||||
render(
|
||||
<I18nContext>
|
||||
<VisualizationContainer className="mtrVis">
|
||||
<MetricVisComponent
|
||||
visData={visData}
|
||||
visParams={visConfig}
|
||||
renderComplete={handlers.done}
|
||||
fireEvent={handlers.event}
|
||||
/>
|
||||
</VisualizationContainer>
|
||||
</I18nContext>,
|
||||
<VisualizationContainer className="mtrVis" showNoResult={!visData.rows?.length}>
|
||||
<MetricVisComponent
|
||||
visData={visData}
|
||||
visParams={visConfig}
|
||||
renderComplete={handlers.done}
|
||||
fireEvent={handlers.event}
|
||||
/>
|
||||
</VisualizationContainer>,
|
||||
domNode
|
||||
);
|
||||
},
|
||||
|
|
|
@ -25,7 +25,7 @@ import { createMetricVisFn } from './metric_vis_fn';
|
|||
import { createMetricVisTypeDefinition } from './metric_vis_type';
|
||||
import { ChartsPluginSetup } from '../../charts/public';
|
||||
import { DataPublicPluginStart } from '../../data/public';
|
||||
import { setFormatService, setI18n } from './services';
|
||||
import { setFormatService } from './services';
|
||||
import { ConfigSchema } from '../config';
|
||||
import { metricVisRenderer } from './metric_vis_renderer';
|
||||
|
||||
|
@ -59,7 +59,6 @@ export class MetricVisPlugin implements Plugin<void, void> {
|
|||
}
|
||||
|
||||
public start(core: CoreStart, { data }: MetricVisPluginStartDependencies) {
|
||||
setI18n(core.i18n);
|
||||
setFormatService(data.fieldFormats);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,12 +17,9 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { I18nStart } from 'kibana/public';
|
||||
import { createGetterSetter } from '../../kibana_utils/common';
|
||||
import { DataPublicPluginStart } from '../../data/public';
|
||||
|
||||
export const [getFormatService, setFormatService] = createGetterSetter<
|
||||
DataPublicPluginStart['fieldFormats']
|
||||
>('metric data.fieldFormats');
|
||||
|
||||
export const [getI18n, setI18n] = createGetterSetter<I18nStart>('I18n');
|
||||
|
|
|
@ -70,3 +70,10 @@
|
|||
flex-direction: column;
|
||||
}
|
||||
|
||||
.visChart__spinner {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,14 +17,35 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import React, { ReactNode } from 'react';
|
||||
import React, { ReactNode, Suspense } from 'react';
|
||||
import { EuiLoadingChart } from '@elastic/eui';
|
||||
import classNames from 'classnames';
|
||||
import { VisualizationNoResults } from './visualization_noresults';
|
||||
|
||||
interface VisualizationContainerProps {
|
||||
className?: string;
|
||||
children: ReactNode;
|
||||
showNoResult?: boolean;
|
||||
}
|
||||
|
||||
export const VisualizationContainer = (props: VisualizationContainerProps) => {
|
||||
const classes = `visualization ${props.className}`;
|
||||
return <div className={classes}>{props.children}</div>;
|
||||
export const VisualizationContainer = ({
|
||||
className,
|
||||
children,
|
||||
showNoResult = false,
|
||||
}: VisualizationContainerProps) => {
|
||||
const classes = classNames('visualization', className);
|
||||
|
||||
const fallBack = (
|
||||
<div className="visChart__spinner">
|
||||
<EuiLoadingChart mono size="l" />
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={classes}>
|
||||
<Suspense fallback={fallBack}>
|
||||
{showNoResult ? <VisualizationNoResults /> : children}
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue