Skip to content

Commit 2fe1c64

Browse files
committed
adding markdown vis renderer
1 parent 28df926 commit 2fe1c64

File tree

14 files changed

+290
-66
lines changed

14 files changed

+290
-66
lines changed

src/plugins/vis_type_markdown/kibana.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
"ui": true,
55
"server": true,
66
"requiredPlugins": ["expressions", "visualizations"],
7-
"requiredBundles": ["kibanaUtils", "kibanaReact", "data", "charts"]
7+
"requiredBundles": ["kibanaUtils", "kibanaReact", "data", "charts", "visualizations", "expressions"]
88
}

src/plugins/vis_type_markdown/public/__snapshots__/markdown_fn.test.ts.snap

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/plugins/vis_type_markdown/public/__snapshots__/to_ast.test.ts.snap

Lines changed: 67 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/plugins/vis_type_markdown/public/markdown_fn.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,14 @@ interface RenderValue {
2626
visConfig: MarkdownVisParams;
2727
}
2828

29-
export const createMarkdownVisFn = (): ExpressionFunctionDefinition<
29+
export type MarkdownVisExpressionFunctionDefinition = ExpressionFunctionDefinition<
3030
'markdownVis',
3131
unknown,
3232
Arguments,
3333
Render<RenderValue>
34-
> => ({
34+
>;
35+
36+
export const createMarkdownVisFn = (): MarkdownVisExpressionFunctionDefinition => ({
3537
name: 'markdownVis',
3638
type: 'render',
3739
inputTypes: [],
@@ -65,7 +67,7 @@ export const createMarkdownVisFn = (): ExpressionFunctionDefinition<
6567
fn(input, args) {
6668
return {
6769
type: 'render',
68-
as: 'visualization',
70+
as: 'markdown_vis',
6971
value: {
7072
visType: 'markdown',
7173
visConfig: {
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
import React from 'react';
21+
import { render, unmountComponentAtNode } from 'react-dom';
22+
import { VisualizationContainer } from '../../visualizations/public';
23+
import { ExpressionRenderDefinition } from '../../expressions/common/expression_renderers';
24+
import { MarkdownVisWrapper } from './markdown_vis_controller';
25+
import { StartServicesGetter } from '../../kibana_utils/public';
26+
27+
export const getMarkdownRenderer = (start: StartServicesGetter) => {
28+
const markdownVisRenderer: () => ExpressionRenderDefinition = () => ({
29+
name: 'markdown_vis',
30+
displayName: 'markdown visualization',
31+
reuseDomNode: true,
32+
render: async (domNode: HTMLElement, config: any, handlers: any) => {
33+
const { visConfig } = config;
34+
35+
const I18nContext = await start().core.i18n.Context;
36+
37+
handlers.onDestroy(() => {
38+
unmountComponentAtNode(domNode);
39+
});
40+
41+
render(
42+
<I18nContext>
43+
<VisualizationContainer className="markdownVis">
44+
<MarkdownVisWrapper
45+
visParams={visConfig}
46+
renderComplete={handlers.done}
47+
fireEvent={handlers.event}
48+
/>
49+
</VisualizationContainer>
50+
</I18nContext>,
51+
domNode
52+
);
53+
},
54+
});
55+
56+
return markdownVisRenderer;
57+
};

src/plugins/vis_type_markdown/public/markdown_vis.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@
1919

2020
import { i18n } from '@kbn/i18n';
2121

22-
import { MarkdownVisWrapper } from './markdown_vis_controller';
2322
import { MarkdownOptions } from './markdown_options';
2423
import { SettingsOptions } from './settings_options_lazy';
2524
import { DefaultEditorSize } from '../../vis_default_editor/public';
25+
import { toExpressionAst } from './to_ast';
2626

2727
export const markdownVisDefinition = {
2828
name: 'markdown',
@@ -32,8 +32,8 @@ export const markdownVisDefinition = {
3232
description: i18n.translate('visTypeMarkdown.markdownDescription', {
3333
defaultMessage: 'Create a document using markdown syntax',
3434
}),
35+
toExpressionAst,
3536
visConfig: {
36-
component: MarkdownVisWrapper,
3737
defaults: {
3838
fontSize: 12,
3939
openLinksInNewTab: false,

src/plugins/vis_type_markdown/public/markdown_vis_controller.test.tsx

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,39 +25,45 @@ describe('markdown vis controller', () => {
2525
it('should set html from markdown params', () => {
2626
const vis = {
2727
params: {
28+
openLinksInNewTab: false,
29+
fontSize: 16,
2830
markdown:
2931
'This is a test of the [markdown](http://daringfireball.net/projects/markdown) vis.',
3032
},
3133
};
3234

3335
const wrapper = render(
34-
<MarkdownVisWrapper vis={vis} visParams={vis.params} renderComplete={jest.fn()} />
36+
<MarkdownVisWrapper visParams={vis.params} renderComplete={jest.fn()} fireEvent={jest.fn()} />
3537
);
3638
expect(wrapper.find('a').text()).toBe('markdown');
3739
});
3840

3941
it('should not render the html', () => {
4042
const vis = {
4143
params: {
44+
openLinksInNewTab: false,
45+
fontSize: 16,
4246
markdown: 'Testing <a>html</a>',
4347
},
4448
};
4549

4650
const wrapper = render(
47-
<MarkdownVisWrapper vis={vis} visParams={vis.params} renderComplete={jest.fn()} />
51+
<MarkdownVisWrapper visParams={vis.params} renderComplete={jest.fn()} fireEvent={jest.fn()} />
4852
);
4953
expect(wrapper.text()).toBe('Testing <a>html</a>\n');
5054
});
5155

5256
it('should update the HTML when render again with changed params', () => {
5357
const vis = {
5458
params: {
59+
openLinksInNewTab: false,
60+
fontSize: 16,
5561
markdown: 'Initial',
5662
},
5763
};
5864

5965
const wrapper = mount(
60-
<MarkdownVisWrapper vis={vis} visParams={vis.params} renderComplete={jest.fn()} />
66+
<MarkdownVisWrapper visParams={vis.params} renderComplete={jest.fn()} fireEvent={jest.fn()} />
6167
);
6268
expect(wrapper.text().trim()).toBe('Initial');
6369
vis.params.markdown = 'Updated';
@@ -66,52 +72,68 @@ describe('markdown vis controller', () => {
6672
});
6773

6874
describe('renderComplete', () => {
75+
const vis = {
76+
params: {
77+
openLinksInNewTab: false,
78+
fontSize: 16,
79+
markdown: 'test',
80+
},
81+
};
82+
83+
const renderComplete = jest.fn();
84+
85+
beforeEach(() => {
86+
renderComplete.mockClear();
87+
});
88+
6989
it('should be called on initial rendering', () => {
70-
const vis = {
71-
params: {
72-
markdown: 'test',
73-
},
74-
};
75-
const renderComplete = jest.fn();
7690
mount(
77-
<MarkdownVisWrapper vis={vis} visParams={vis.params} renderComplete={renderComplete} />
91+
<MarkdownVisWrapper
92+
visParams={vis.params}
93+
renderComplete={renderComplete}
94+
fireEvent={jest.fn()}
95+
/>
7896
);
7997
expect(renderComplete.mock.calls.length).toBe(1);
8098
});
8199

82100
it('should be called on successive render when params change', () => {
83-
const vis = {
84-
params: {
85-
markdown: 'test',
86-
},
87-
};
88-
const renderComplete = jest.fn();
89101
mount(
90-
<MarkdownVisWrapper vis={vis} visParams={vis.params} renderComplete={renderComplete} />
102+
<MarkdownVisWrapper
103+
visParams={vis.params}
104+
renderComplete={renderComplete}
105+
fireEvent={jest.fn()}
106+
/>
91107
);
92108
expect(renderComplete.mock.calls.length).toBe(1);
93109
renderComplete.mockClear();
94110
vis.params.markdown = 'changed';
95111
mount(
96-
<MarkdownVisWrapper vis={vis} visParams={vis.params} renderComplete={renderComplete} />
112+
<MarkdownVisWrapper
113+
visParams={vis.params}
114+
renderComplete={renderComplete}
115+
fireEvent={jest.fn()}
116+
/>
97117
);
98118
expect(renderComplete.mock.calls.length).toBe(1);
99119
});
100120

101121
it('should be called on successive render even without data change', () => {
102-
const vis = {
103-
params: {
104-
markdown: 'test',
105-
},
106-
};
107-
const renderComplete = jest.fn();
108122
mount(
109-
<MarkdownVisWrapper vis={vis} visParams={vis.params} renderComplete={renderComplete} />
123+
<MarkdownVisWrapper
124+
visParams={vis.params}
125+
renderComplete={renderComplete}
126+
fireEvent={jest.fn()}
127+
/>
110128
);
111129
expect(renderComplete.mock.calls.length).toBe(1);
112130
renderComplete.mockClear();
113131
mount(
114-
<MarkdownVisWrapper vis={vis} visParams={vis.params} renderComplete={renderComplete} />
132+
<MarkdownVisWrapper
133+
visParams={vis.params}
134+
renderComplete={renderComplete}
135+
fireEvent={jest.fn()}
136+
/>
115137
);
116138
expect(renderComplete.mock.calls.length).toBe(1);
117139
});

src/plugins/vis_type_markdown/public/markdown_vis_controller.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { Markdown } from '../../kibana_react/public';
2222
import { MarkdownVisParams } from './types';
2323

2424
interface MarkdownVisComponentProps extends MarkdownVisParams {
25-
renderComplete: () => {};
25+
renderComplete: () => void;
2626
}
2727

2828
/**
@@ -80,7 +80,14 @@ class MarkdownVisComponent extends React.Component<MarkdownVisComponentProps> {
8080
* The way React works, this wrapper nearly brings no overhead, but allows us
8181
* to use proper lifecycle methods in the actual component.
8282
*/
83-
export function MarkdownVisWrapper(props: any) {
83+
84+
export interface MarkdownVisWrapperProps {
85+
visParams: MarkdownVisParams;
86+
fireEvent: (event: any) => void;
87+
renderComplete: () => void;
88+
}
89+
90+
export function MarkdownVisWrapper(props: MarkdownVisWrapperProps) {
8491
return (
8592
<MarkdownVisComponent
8693
fontSize={props.visParams.fontSize}

src/plugins/vis_type_markdown/public/plugin.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import { createMarkdownVisFn } from './markdown_fn';
2626
import { ConfigSchema } from '../config';
2727

2828
import './index.scss';
29+
import { getMarkdownRenderer } from './markdown_renderer';
30+
import { createStartServicesGetter } from '../../kibana_utils/public';
2931

3032
/** @internal */
3133
export interface MarkdownPluginSetupDependencies {
@@ -42,7 +44,9 @@ export class MarkdownPlugin implements Plugin<void, void> {
4244
}
4345

4446
public setup(core: CoreSetup, { expressions, visualizations }: MarkdownPluginSetupDependencies) {
45-
visualizations.createReactVisualization(markdownVisDefinition);
47+
const start = createStartServicesGetter(core.getStartServices);
48+
visualizations.createBaseVisualization(markdownVisDefinition);
49+
expressions.registerRenderer(getMarkdownRenderer(start));
4650
expressions.registerFunction(createMarkdownVisFn);
4751
}
4852

0 commit comments

Comments
 (0)