import React, {Component} from 'react'; import {RouteComponentProps} from 'react-router'; import {Markdown} from '../common/Markdown'; import {UnControlled as CodeMirror} from 'react-codemirror2'; import 'codemirror/lib/codemirror.css'; import 'codemirror/theme/material.css'; import 'codemirror/mode/yaml/yaml'; import Info from '@material-ui/icons/Info'; import Build from '@material-ui/icons/Build'; import Subject from '@material-ui/icons/Subject'; import Refresh from '@material-ui/icons/Refresh'; import Button from '@material-ui/core/Button'; import Typography from '@material-ui/core/Typography'; import DefaultPage from '../common/DefaultPage'; import * as config from '../config'; import Container from '../common/Container'; import {inject, Stores} from '../inject'; import {IPlugin} from '../types'; type IProps = RouteComponentProps<{id: string}>; interface IState { displayText: string | null; currentConfig: string | null; } class PluginDetailView extends Component, IState> { private pluginID: number = parseInt(this.props.match.params.id, 10); private pluginInfo = () => this.props.pluginStore.getByID(this.pluginID); public state: IState = { displayText: null, currentConfig: null, }; public componentWillMount() { this.refreshFeatures(); } public componentWillReceiveProps(nextProps: IProps & Stores<'pluginStore'>) { this.pluginID = parseInt(nextProps.match.params.id, 10); this.refreshFeatures(); } private refreshFeatures() { return Promise.all([this.refreshConfigurer(), this.refreshDisplayer()]); } private async refreshConfigurer() { const { props: {pluginStore}, } = this; if (this.pluginInfo().capabilities.indexOf('configurer') !== -1) { const response = await pluginStore.requestConfig(this.pluginID); this.setState({currentConfig: response}); } } private async refreshDisplayer() { const { props: {pluginStore}, } = this; if (this.pluginInfo().capabilities.indexOf('displayer') !== -1) { const response = await pluginStore.requestDisplay(this.pluginID); this.setState({displayText: response}); } } public render() { const pluginInfo = this.pluginInfo(); const {name, capabilities} = pluginInfo; return ( {capabilities.indexOf('configurer') !== -1 ? ( { await this.props.pluginStore.changeConfig(this.pluginID, newConfig); await this.refreshFeatures(); }} /> ) : null}{' '} {capabilities.indexOf('displayer') !== -1 ? ( ) : null} ); } } interface IPanelWrapperProps { name: string; description?: string; refresh?: () => Promise; icon?: React.ComponentType; } const PanelWrapper: React.FC = ({ name, description, refresh, icon, children, }) => { const Icon = icon; return (
{Icon ? (   ) : null} {name} {refresh ? ( ) : null} {description ? {description} : null}
{children}
); }; interface IConfigurerPanelProps { pluginInfo: IPlugin; initialConfig: string; save: (newConfig: string) => Promise; } class ConfigurerPanel extends Component { public state = {unsavedChanges: null}; public render() { return (
{ let newConf: string | null = value; if (value === this.props.initialConfig) { newConf = null; } this.setState({unsavedChanges: newConf}); }} />
); } } interface IDisplayerPanelProps { pluginInfo: IPlugin; displayText: string; } const DisplayerPanel: React.FC = ({displayText}) => ( {displayText} ); class PluginInfo extends Component<{pluginInfo: IPlugin}> { public render() { const { props: { pluginInfo: {name, author, modulePath, website, license, capabilities, id, token}, }, } = this; return (
{name ? ( Name: {name} ) : null} {author ? ( Author: {author} ) : null} Module Path: {modulePath} {website ? ( Website: {website} ) : null} {license ? ( License: {license} ) : null} Capabilities: {capabilities.join(', ')} {capabilities.indexOf('webhooker') !== -1 ? ( Custom Route Prefix:{' '} {((url) => ( {url} ))(`${config.get('url')}plugin/${id}/custom/${token}/`)} ) : null}
); } } export default inject('pluginStore')(PluginDetailView);