2019-03-08 06:30:47 -06:00
|
|
|
// Libraries
|
2019-03-06 17:54:19 -06:00
|
|
|
import React, { PureComponent } from 'react';
|
2019-03-08 06:30:47 -06:00
|
|
|
import { debounce } from 'lodash';
|
2020-04-20 00:37:38 -05:00
|
|
|
import { PanelProps, renderMarkdown, textUtil } from '@grafana/data';
|
2019-03-08 06:30:47 -06:00
|
|
|
// Utils
|
2019-02-23 23:53:20 -06:00
|
|
|
import config from 'app/core/config';
|
|
|
|
// Types
|
|
|
|
import { TextOptions } from './types';
|
|
|
|
|
|
|
|
interface Props extends PanelProps<TextOptions> {}
|
|
|
|
interface State {
|
|
|
|
html: string;
|
|
|
|
}
|
|
|
|
|
2019-03-06 17:54:19 -06:00
|
|
|
export class TextPanel extends PureComponent<Props, State> {
|
2019-06-19 06:40:42 -05:00
|
|
|
constructor(props: Props) {
|
2019-02-23 23:53:20 -06:00
|
|
|
super(props);
|
|
|
|
|
|
|
|
this.state = {
|
2019-03-05 13:14:22 -06:00
|
|
|
html: this.processContent(props.options),
|
2019-02-23 23:53:20 -06:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
updateHTML = debounce(() => {
|
|
|
|
const html = this.processContent(this.props.options);
|
|
|
|
if (html !== this.state.html) {
|
|
|
|
this.setState({ html });
|
|
|
|
}
|
2019-03-06 17:54:19 -06:00
|
|
|
}, 150);
|
2019-02-23 23:53:20 -06:00
|
|
|
|
|
|
|
componentDidUpdate(prevProps: Props) {
|
|
|
|
// Since any change could be referenced in a template variable,
|
2019-03-06 17:54:19 -06:00
|
|
|
// This needs to process everytime (with debounce)
|
2019-02-23 23:53:20 -06:00
|
|
|
this.updateHTML();
|
|
|
|
}
|
|
|
|
|
|
|
|
prepareHTML(html: string): string {
|
2019-03-05 13:14:22 -06:00
|
|
|
const { replaceVariables } = this.props;
|
|
|
|
|
2019-11-22 03:28:54 -06:00
|
|
|
html = replaceVariables(html, {}, 'html');
|
2019-03-08 06:30:47 -06:00
|
|
|
|
2020-04-20 00:37:38 -05:00
|
|
|
return config.disableSanitizeHtml ? html : textUtil.sanitize(html);
|
2019-02-23 23:53:20 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
prepareText(content: string): string {
|
|
|
|
return this.prepareHTML(
|
|
|
|
content
|
|
|
|
.replace(/&/g, '&')
|
|
|
|
.replace(/>/g, '>')
|
|
|
|
.replace(/</g, '<')
|
|
|
|
.replace(/\n/g, '<br/>')
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
prepareMarkdown(content: string): string {
|
2019-06-26 06:15:45 -05:00
|
|
|
return this.prepareHTML(renderMarkdown(content));
|
2019-02-23 23:53:20 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
processContent(options: TextOptions): string {
|
|
|
|
const { mode, content } = options;
|
|
|
|
|
|
|
|
if (!content) {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode === 'markdown') {
|
|
|
|
return this.prepareMarkdown(content);
|
|
|
|
}
|
|
|
|
if (mode === 'html') {
|
|
|
|
return this.prepareHTML(content);
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.prepareText(content);
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const { html } = this.state;
|
|
|
|
|
|
|
|
return <div className="markdown-html panel-text-content" dangerouslySetInnerHTML={{ __html: html }} />;
|
|
|
|
}
|
|
|
|
}
|