From e5ce7591677976768fa3877eac240a4a3f94d9be Mon Sep 17 00:00:00 2001 From: ryan Date: Sat, 23 Feb 2019 21:53:20 -0800 Subject: [PATCH 1/3] update --- public/app/plugins/panel/text2/TextPanel.tsx | 100 ++++++++++++++++++ .../plugins/panel/text2/TextPanelEditor.tsx | 32 ++++++ public/app/plugins/panel/text2/module.tsx | 18 ++-- public/app/plugins/panel/text2/types.ts | 14 +++ 4 files changed, 153 insertions(+), 11 deletions(-) create mode 100644 public/app/plugins/panel/text2/TextPanel.tsx create mode 100644 public/app/plugins/panel/text2/TextPanelEditor.tsx create mode 100644 public/app/plugins/panel/text2/types.ts diff --git a/public/app/plugins/panel/text2/TextPanel.tsx b/public/app/plugins/panel/text2/TextPanel.tsx new file mode 100644 index 00000000000..9e9210df119 --- /dev/null +++ b/public/app/plugins/panel/text2/TextPanel.tsx @@ -0,0 +1,100 @@ +import React, { Component } from 'react'; + +import Remarkable from 'remarkable'; +import { sanitize } from 'app/core/utils/text'; +import config from 'app/core/config'; +import templateSrv from 'app/features/templating/template_srv'; +import { debounce } from 'lodash'; + +// Types +import { TextOptions } from './types'; +import { PanelProps } from '@grafana/ui/src/types'; + +interface Props extends PanelProps {} +interface State { + html: string; +} + +export class TextPanel extends Component { + remarkable: Remarkable; + + constructor(props) { + super(props); + + // TODO thre must be some better way to start with defualt options! + let opts = props.options; + if (opts && opts['options']) { + opts = opts['options']; + console.log('WEIRD!', opts); + } + + this.state = { + html: this.processContent(opts), + }; + } + + updateHTML = debounce(() => { + const html = this.processContent(this.props.options); + if (html !== this.state.html) { + this.setState({ html }); + } + }, 100); + + componentDidUpdate(prevProps: Props) { + // Since any change could be referenced in a template variable, + // This needs to process everything + this.updateHTML(); + } + + prepareHTML(html: string): string { + const scopedVars = {}; // TODO?? = this.props.; + html = config.disableSanitizeHtml ? html : sanitize(html); + try { + return templateSrv.replace(html, scopedVars); + } catch (e) { + // TODO -- put the error in the header window + console.log('Text panel error: ', e); + return html; + } + } + + prepareText(content: string): string { + return this.prepareHTML( + content + .replace(/&/g, '&') + .replace(/>/g, '>') + .replace(/') + ); + } + + prepareMarkdown(content: string): string { + if (!this.remarkable) { + this.remarkable = new Remarkable(); + } + return this.prepareHTML(this.remarkable.render(content)); + } + + 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
; + } +} diff --git a/public/app/plugins/panel/text2/TextPanelEditor.tsx b/public/app/plugins/panel/text2/TextPanelEditor.tsx new file mode 100644 index 00000000000..2581384af9a --- /dev/null +++ b/public/app/plugins/panel/text2/TextPanelEditor.tsx @@ -0,0 +1,32 @@ +import React, { PureComponent } from 'react'; +import { PanelEditorProps, PanelOptionsGroup, Select, SelectOptionItem } from '@grafana/ui'; + +import { TextOptions } from './types'; + +export class TextPanelEditor extends PureComponent> { + modes: SelectOptionItem[] = [ + { value: 'markdown', label: 'Markdown' }, + { value: 'text', label: 'Text' }, + { value: 'html', label: 'HTML' }, + ]; + + onModeChange = (item: SelectOptionItem) => this.props.onChange({ ...this.props.options, mode: item.value }); + + onContentChange = evt => this.props.onChange({ ...this.props.options, content: (event.target as any).value }); + + render() { + const { mode, content } = this.props.options; + + return ( + +
+ Mode +