diff --git a/public/app/core/components/PanelHelp/PluginHelp.tsx b/public/app/core/components/PanelHelp/PluginHelp.tsx new file mode 100644 index 00000000000..b43efae2d15 --- /dev/null +++ b/public/app/core/components/PanelHelp/PluginHelp.tsx @@ -0,0 +1,96 @@ +import React, { PureComponent } from 'react'; +import Remarkable from 'remarkable'; +import { getBackendSrv } from '../../services/backend_srv'; +import { PluginMeta } from 'app/types'; + +interface Props { + plugin: PluginMeta; + type: string; +} + +interface State { + isError: boolean; + isLoading: boolean; + help: string; +} + +export default class PluginHelp extends PureComponent { + state = { + isError: false, + isLoading: false, + help: '', + }; + + componentDidMount(): void { + this.loadHelp(); + } + + constructPlaceholderInfo = () => { + const { plugin } = this.props; + const markdown = new Remarkable(); + + const fallBack = markdown.render( + `## ${plugin.name} \n by _${plugin.info.author.name} (<${plugin.info.author.url}>)_\n\n${ + plugin.info.description + }\n\n${ + plugin.info.links + ? `### Links \n ${plugin.info.links.map(link => { + return `${link.name}: <${link.url}>\n`; + })}` + : '' + }` + ); + + return fallBack; + }; + + loadHelp = () => { + const { plugin, type } = this.props; + this.setState({ isLoading: true }); + + getBackendSrv() + .get(`/api/plugins/${plugin.id}/markdown/${type}`) + .then(response => { + const markdown = new Remarkable(); + const helpHtml = markdown.render(response); + + if (response === '' && type === 'help') { + this.setState({ + isError: false, + isLoading: false, + help: this.constructPlaceholderInfo(), + }); + } else { + this.setState({ + isError: false, + isLoading: false, + help: helpHtml, + }); + } + }) + .catch(() => { + this.setState({ + isError: true, + isLoading: false, + }); + }); + }; + + render() { + const { type } = this.props; + const { isError, isLoading, help } = this.state; + + if (isLoading) { + return

Loading help...

; + } + + if (isError) { + return

'Error occurred when loading help'

; + } + + if (type === 'panel_help' && help === '') { + } + + return
; + } +} diff --git a/public/app/features/dashboard/dashgrid/QueriesTab.tsx b/public/app/features/dashboard/dashgrid/QueriesTab.tsx index 8513f061b74..36f38cadbd3 100644 --- a/public/app/features/dashboard/dashgrid/QueriesTab.tsx +++ b/public/app/features/dashboard/dashgrid/QueriesTab.tsx @@ -1,6 +1,5 @@ // Libraries import React, { SFC, PureComponent } from 'react'; -import Remarkable from 'remarkable'; import _ from 'lodash'; // Components @@ -22,6 +21,7 @@ import config from 'app/core/config'; import { PanelModel } from '../panel_model'; import { DashboardModel } from '../dashboard_model'; import { DataSourceSelectItem, DataQuery } from 'app/types'; +import PluginHelp from '../../../core/components/PanelHelp/PluginHelp'; interface Props { panel: PanelModel; @@ -128,43 +128,13 @@ export class QueriesTab extends PureComponent { }); }; - loadHelp = () => { - const { currentDS } = this.state; - const hasHelp = currentDS.meta.hasQueryHelp; - - if (hasHelp) { - this.setState({ - helpContent:

Loading help...

, - isLoadingHelp: true, - }); - - this.backendSrv - .get(`/api/plugins/${currentDS.meta.id}/markdown/query_help`) - .then(res => { - const md = new Remarkable(); - const helpHtml = md.render(res); - this.setState({ - helpContent:
, - isLoadingHelp: false, - }); - }) - .catch(() => { - this.setState({ - helpContent:

'Error occured when loading help'

, - isLoadingHelp: false, - }); - }); - } - }; - renderQueryInspector = () => { const { panel } = this.props; return ; }; renderHelp = () => { - const { helpContent, isLoadingHelp } = this.state; - return isLoadingHelp ? : helpContent; + return ; }; onAddQuery = (query?: Partial) => { @@ -244,7 +214,6 @@ export class QueriesTab extends PureComponent { heading: 'Help', icon: 'fa fa-question', disabled: !hasQueryHelp, - onClick: this.loadHelp, render: this.renderHelp, }; diff --git a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx index 0e31d7cdafc..70285124b16 100644 --- a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx +++ b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx @@ -3,10 +3,12 @@ import React, { PureComponent } from 'react'; // Utils & Services import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader'; +import { getDatasourceSrv } from '../../plugins/datasource_srv'; // Components import { EditorTabBody } from './EditorTabBody'; import { VizTypePicker } from './VizTypePicker'; +import PluginHelp from 'app/core/components/PanelHelp/PluginHelp'; import { FadeIn } from 'app/core/components/Animations/FadeIn'; import { PanelOptionSection } from './PanelOptionSection'; @@ -14,6 +16,7 @@ import { PanelOptionSection } from './PanelOptionSection'; import { PanelModel } from '../panel_model'; import { DashboardModel } from '../dashboard_model'; import { PanelPlugin } from 'app/types/plugins'; +import { DataSourceSelectItem } from 'app/types'; interface Props { panel: PanelModel; @@ -24,6 +27,7 @@ interface Props { } interface State { + currentDataSource: DataSourceSelectItem; isVizPickerOpen: boolean; searchQuery: string; } @@ -32,13 +36,16 @@ export class VisualizationTab extends PureComponent { element: HTMLElement; angularOptions: AngularComponent; searchInput: HTMLElement; + dataSources: DataSourceSelectItem[] = getDatasourceSrv().getMetricSources(); constructor(props) { super(props); + const { panel } = props; this.state = { isVizPickerOpen: false, searchQuery: '', + currentDataSource: this.dataSources.find(datasource => datasource.value === panel.datasource), }; } @@ -198,12 +205,20 @@ export class VisualizationTab extends PureComponent { } }; + renderHelp = () => ; + render() { const { plugin } = this.props; const { isVizPickerOpen, searchQuery } = this.state; + const pluginHelp = { + heading: 'Help', + icon: 'fa fa-question', + render: this.renderHelp, + }; + return ( - + <> { url: 'url/to/GrafanaLabs', }, description: 'pretty decent plugin', - links: ['one link'], + links: [{ name: 'project', url: 'one link' }], logos: { small: 'small/logo', large: 'large/logo' }, screenshots: [{ path: `screenshot` }], updated: '2018-09-26', diff --git a/public/app/types/plugins.ts b/public/app/types/plugins.ts index bc33ec80409..a3519e5b5cc 100644 --- a/public/app/types/plugins.ts +++ b/public/app/types/plugins.ts @@ -57,13 +57,18 @@ export interface PluginInclude { path: string; } +interface PluginMetaInfoLink { + name: string; + url: string; +} + export interface PluginMetaInfo { author: { name: string; url?: string; }; description: string; - links: string[]; + links: PluginMetaInfoLink[]; logos: { large: string; small: string;