// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. // See License.txt for license information. import LoadingScreen from 'components/loading_screen.jsx'; import Banner from 'components/admin_console/banner.jsx'; import * as Utils from 'utils/utils.jsx'; import React from 'react'; import PropTypes from 'prop-types'; import {FormattedMessage, FormattedHTMLMessage} from 'react-intl'; export default class PluginSettings extends React.Component { static propTypes = { /* * The config */ config: PropTypes.object.isRequired, /* * Plugins object with ids as keys and manifests as values */ plugins: PropTypes.object.isRequired, actions: PropTypes.shape({ /* * Function to upload a plugin */ uploadPlugin: PropTypes.func.isRequired, /* * Function to remove a plugin */ removePlugin: PropTypes.func.isRequired, /* * Function to get installed plugins */ getPlugins: PropTypes.func.isRequired }).isRequired } constructor(props) { super(props); this.state = { loading: true, fileSelected: false, fileName: null, serverError: null }; } componentDidMount() { this.props.actions.getPlugins().then( () => this.setState({loading: false}) ); } handleChange = () => { const element = this.refs.fileInput; if (element.files.length > 0) { this.setState({fileSelected: true, fileName: element.files[0].name}); } } handleSubmit = async (e) => { e.preventDefault(); const element = this.refs.fileInput; if (element.files.length === 0) { return; } const file = element.files[0]; this.setState({uploading: true}); const {error} = await this.props.actions.uploadPlugin(file); this.setState({fileSelected: false, fileName: null, uploading: false}); Utils.clearFileInput(element); if (error) { if (error.server_error_id === 'app.plugin.activate.app_error') { this.setState({serverError: Utils.localizeMessage('admin.plugin.error.activate', 'Unable to upload the plugin. It may conflict with another plugin on your server.')}); } else if (error.server_error_id === 'app.plugin.extract.app_error') { this.setState({serverError: Utils.localizeMessage('admin.plugin.error.extract', 'Encountered an error when extracting the plugin. Review your plugin file content and try again.')}); } else { this.setState({serverError: error.message}); } } } handleRemove = async (pluginId) => { this.setState({removing: pluginId}); const {error} = await this.props.actions.removePlugin(pluginId); this.setState({removing: null}); if (error) { this.setState({serverError: error.message}); } } render() { let serverError = ''; if (this.state.serverError) { serverError =
; } let btnClass = 'btn'; if (this.state.fileSelected) { btnClass = 'btn btn-primary'; } let fileName; if (this.state.fileName) { fileName = this.state.fileName; } let uploadButtonText; if (this.state.uploading) { uploadButtonText = ( ); } else { uploadButtonText = ( ); } let activePluginsList; let activePluginsContainer; const plugins = Object.values(this.props.plugins); if (this.state.loading) { activePluginsList = ; } else if (plugins.length === 0) { activePluginsContainer = ( ); } else { activePluginsList = plugins.map( (p) => { let removeButtonText; if (this.state.removing === p.id) { removeButtonText = ( ); } else { removeButtonText = ( ); } return (
{' ' + p.id}
{' ' + p.description}

); } ); activePluginsContainer = (
{activePluginsList}
); } return (

} description={ } />
{fileName}
{serverError}

{activePluginsContainer}
); } }