diff options
Diffstat (limited to 'webapp/components')
-rw-r--r-- | webapp/components/admin_console/configuration_settings.jsx | 76 | ||||
-rw-r--r-- | webapp/components/admin_console/database_settings.jsx | 52 | ||||
-rw-r--r-- | webapp/components/admin_console/ldap_settings.jsx | 50 | ||||
-rw-r--r-- | webapp/components/admin_console/ldap_test_button.jsx | 146 | ||||
-rw-r--r-- | webapp/components/admin_console/purge_caches.jsx | 108 | ||||
-rw-r--r-- | webapp/components/admin_console/recycle_db.jsx | 111 | ||||
-rw-r--r-- | webapp/components/admin_console/reload_config.jsx | 111 | ||||
-rw-r--r-- | webapp/components/admin_console/request_button/request_button.jsx | 234 | ||||
-rw-r--r-- | webapp/components/admin_console/sync_now_button.jsx | 115 |
9 files changed, 401 insertions, 602 deletions
diff --git a/webapp/components/admin_console/configuration_settings.jsx b/webapp/components/admin_console/configuration_settings.jsx index 449b4f549..72bd0e330 100644 --- a/webapp/components/admin_console/configuration_settings.jsx +++ b/webapp/components/admin_console/configuration_settings.jsx @@ -9,12 +9,12 @@ import ErrorStore from 'stores/error_store.jsx'; import {ErrorBarTypes} from 'utils/constants.jsx'; import * as Utils from 'utils/utils.jsx'; +import {invalidateAllCaches, reloadConfig} from 'actions/admin_actions.jsx'; import AdminSettings from './admin_settings.jsx'; import BooleanSetting from './boolean_setting.jsx'; import {ConnectionSecurityDropdownSettingWebserver} from './connection_security_dropdown_setting.jsx'; -import PurgeCachesButton from './purge_caches.jsx'; -import ReloadConfigButton from './reload_config.jsx'; import SettingsGroup from './settings_group.jsx'; +import RequestButton from './request_button/request_button'; import TextSetting from './text_setting.jsx'; import WebserverModeDropdownSetting from './webserver_mode_dropdown_setting.jsx'; @@ -83,6 +83,54 @@ export default class ConfigurationSettings extends AdminSettings { } renderSettings() { + const reloadConfigurationHelpText = ( + <FormattedMessage + id='admin.reload.reloadDescription' + defaultMessage='Deployments using multiple databases can switch from one master database to another without restarting the Mattermost server by updating "config.json" to the new desired configuration and using the {featureName} feature to load the new settings while the server is running. The administrator should then use the {recycleDatabaseConnections} feature to recycle the database connections based on the new settings.' + values={{ + featureName: ( + <b> + <FormattedMessage + id='admin.reload.reloadDescription.featureName' + defaultMessage='Reload Configuration from Disk' + /> + </b> + ), + recycleDatabaseConnections: ( + <a href='../advanced/database'> + <b> + <FormattedMessage + id='admin.reload.reloadDescription.recycleDatabaseConnections' + defaultMessage='Database > Recycle Database Connections' + /> + </b> + </a> + ) + }} + /> + ); + + let reloadConfigButton = <div/>; + if (global.window.mm_license.IsLicensed === 'true') { + reloadConfigButton = ( + <RequestButton + requestAction={reloadConfig} + helpText={reloadConfigurationHelpText} + buttonText={ + <FormattedMessage + id='admin.reload.button' + defaultMessage='Reload Configuration From Disk' + /> + } + showSuccessMessage={false} + errorMessage={{ + id: 'admin.reload.reloadFail', + defaultMessage: 'Reload unsuccessful: {error}' + }} + /> + ); + } + return ( <SettingsGroup> <div className='banner'> @@ -261,8 +309,28 @@ export default class ConfigurationSettings extends AdminSettings { onChange={this.handleChange} disabled={false} /> - <ReloadConfigButton/> - <PurgeCachesButton/> + {reloadConfigButton} + <RequestButton + requestAction={invalidateAllCaches} + helpText={ + <FormattedMessage + id='admin.purge.purgeDescription' + defaultMessage='This will purge all the in-memory caches for things like sessions, accounts, channels, etc. Deployments using High Availability will attempt to purge all the servers in the cluster. Purging the caches may adversely impact performance.' + /> + } + buttonText={ + <FormattedMessage + id='admin.purge.button' + defaultMessage='Purge All Caches' + /> + } + showSuccessMessage={false} + includeDetailedError={true} + errorMessage={{ + id: 'admin.purge.purgeFail', + defaultMessage: 'Purging unsuccessful: {error}' + }} + /> </SettingsGroup> ); } diff --git a/webapp/components/admin_console/database_settings.jsx b/webapp/components/admin_console/database_settings.jsx index e182db70e..303865d91 100644 --- a/webapp/components/admin_console/database_settings.jsx +++ b/webapp/components/admin_console/database_settings.jsx @@ -3,6 +3,7 @@ import React from 'react'; +import {recycleDatabaseConnection} from 'actions/admin_actions.jsx'; import * as Utils from 'utils/utils.jsx'; import AdminSettings from './admin_settings.jsx'; @@ -11,7 +12,7 @@ import {FormattedMessage} from 'react-intl'; import GeneratedSetting from './generated_setting.jsx'; import SettingsGroup from './settings_group.jsx'; import TextSetting from './text_setting.jsx'; -import RecycleDbButton from './recycle_db.jsx'; +import RequestButton from './request_button/request_button.jsx'; export default class DatabaseSettings extends AdminSettings { constructor(props) { @@ -58,6 +59,53 @@ export default class DatabaseSettings extends AdminSettings { renderSettings() { const dataSource = '**********' + this.state.dataSource.substring(this.state.dataSource.indexOf('@')); + let recycleDbButton = <div/>; + if (global.window.mm_license.IsLicensed === 'true') { + recycleDbButton = ( + <RequestButton + requestAction={recycleDatabaseConnection} + helpText={ + <FormattedMessage + id='admin.recycle.recycleDescription' + defaultMessage='Deployments using multiple databases can switch from one master database to another without restarting the Mattermost server by updating "config.json" to the new desired configuration and using the {reloadConfiguration} feature to load the new settings while the server is running. The administrator should then use {featureName} feature to recycle the database connections based on the new settings.' + values={{ + featureName: ( + <b> + <FormattedMessage + id='admin.recycle.recycleDescription.featureName' + defaultMessage='Recycle Database Connections' + /> + </b> + ), + reloadConfiguration: ( + <a href='../general/configuration'> + <b> + <FormattedMessage + id='admin.recycle.recycleDescription.reloadConfiguration' + defaultMessage='Configuration > Reload Configuration from Disk' + /> + </b> + </a> + ) + }} + /> + } + buttonText={ + <FormattedMessage + id='admin.recycle.button' + defaultMessage='Recycle Database Connections' + /> + } + showSuccessMessage={false} + errorMessage={{ + id: 'admin.recycle.reloadFail', + defaultMessage: 'Recycling unsuccessful: {error}' + }} + includeDetailedError={true} + /> + ); + } + return ( <SettingsGroup> <p> @@ -183,7 +231,7 @@ export default class DatabaseSettings extends AdminSettings { value={this.state.trace} onChange={this.handleChange} /> - <RecycleDbButton/> + {recycleDbButton} </SettingsGroup> ); } diff --git a/webapp/components/admin_console/ldap_settings.jsx b/webapp/components/admin_console/ldap_settings.jsx index 87eab8004..9ffbe3b0e 100644 --- a/webapp/components/admin_console/ldap_settings.jsx +++ b/webapp/components/admin_console/ldap_settings.jsx @@ -7,13 +7,13 @@ import {ConnectionSecurityDropdownSettingLdap} from './connection_security_dropd import SettingsGroup from './settings_group.jsx'; import TextSetting from './text_setting.jsx'; -import SyncNowButton from './sync_now_button.jsx'; -import LdapTestButton from './ldap_test_button.jsx'; +import {ldapSyncNow, ldapTest} from 'actions/admin_actions.jsx'; import * as Utils from 'utils/utils.jsx'; import React from 'react'; import {FormattedMessage} from 'react-intl'; +import RequestButton from './request_button/request_button.jsx'; export default class LdapSettings extends AdminSettings { constructor(props) { @@ -450,13 +450,53 @@ export default class LdapSettings extends AdminSettings { onChange={this.handleChange} disabled={!this.state.enable} /> - <SyncNowButton + <RequestButton + requestAction={ldapSyncNow} + helpText={ + <FormattedMessage + id='admin.ldap.syncNowHelpText' + defaultMessage='Initiates an AD/LDAP synchronization immediately.' + /> + } + buttonText={ + <FormattedMessage + id='admin.ldap.sync_button' + defaultMessage='AD/LDAP Synchronize Now' + /> + } disabled={!this.state.enable} + showSuccessMessage={false} + errorMessage={{ + id: 'admin.ldap.syncFailure', + defaultMessage: 'Sync Failure: {error}' + }} + includeDetailedError={true} /> - <LdapTestButton + <RequestButton + requestAction={ldapTest} + helpText={ + <FormattedMessage + id='admin.ldap.testHelpText' + defaultMessage='Tests if the Mattermost server can connect to the AD/LDAP server specified. See log file for more detailed error messages.' + /> + } + buttonText={ + <FormattedMessage + id='admin.ldap.ldap_test_button' + defaultMessage='AD/LDAP Test' + /> + } disabled={!this.state.enable} - submitFunction={this.doSubmit} saveNeeded={this.state.saveNeeded} + saveConfigAction={this.doSubmit} + errorMessage={{ + id: 'admin.ldap.testFailure', + defaultMessage: 'AD/LDAP Test Failure: {error}' + }} + successMessage={{ + id: 'admin.ldap.testSuccess', + defaultMessage: 'AD/LDAP Test Successful' + }} /> </SettingsGroup> ); diff --git a/webapp/components/admin_console/ldap_test_button.jsx b/webapp/components/admin_console/ldap_test_button.jsx deleted file mode 100644 index e785d0f78..000000000 --- a/webapp/components/admin_console/ldap_test_button.jsx +++ /dev/null @@ -1,146 +0,0 @@ -import PropTypes from 'prop-types'; - -// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import React from 'react'; - -import * as Utils from 'utils/utils.jsx'; - -import {FormattedMessage, FormattedHTMLMessage} from 'react-intl'; - -import {ldapTest} from 'actions/admin_actions.jsx'; - -export default class LdapTestButton extends React.Component { - static get propTypes() { - return { - disabled: PropTypes.bool, - submitFunction: PropTypes.func, - saveNeeded: PropTypes.bool - }; - } - constructor(props) { - super(props); - - this.handleLdapTest = this.handleLdapTest.bind(this); - - this.state = { - buisy: false, - fail: null, - success: false - }; - } - - handleLdapTest(e) { - e.preventDefault(); - - this.setState({ - buisy: true, - fail: null, - success: false - }); - - const doRequest = () => { //eslint-disable-line func-style - ldapTest( - () => { - this.setState({ - buisy: false, - success: true - }); - }, - (err) => { - this.setState({ - buisy: false, - fail: err.message - }); - } - ); - }; - - // If we need to run the save function then run it with our request function as callback - if (this.props.saveNeeded) { - this.props.submitFunction(doRequest); - } else { - doRequest(); - } - } - - render() { - let message = null; - if (this.state.fail) { - message = ( - <div> - <div className='alert alert-warning'> - <i className='fa fa-warning'/> - <FormattedMessage - id='admin.ldap.testFailure' - defaultMessage='AD/LDAP Test Failure: {error}' - values={{ - error: this.state.fail - }} - /> - </div> - </div> - ); - } else if (this.state.success) { - message = ( - <div> - <div className='alert alert-success'> - <i className='fa fa-success'/> - <FormattedMessage - id='admin.ldap.testSuccess' - defaultMessage='AD/LDAP Test Successful' - values={{ - error: this.state.fail - }} - /> - </div> - </div> - ); - } - - const helpText = ( - <FormattedHTMLMessage - id='admin.ldap.testHelpText' - defaultMessage='Tests if the Mattermost server can connect to the AD/LDAP server specified. See log file for more detailed error messages.' - /> - ); - - let contents = null; - if (this.state.loading) { - contents = ( - <span> - <span className='fa fa-refresh icon--rotate'/> - {Utils.localizeMessage('admin.reload.loading', ' Loading...')} - </span> - ); - } else { - contents = ( - <FormattedMessage - id='admin.ldap.ldap_test_button' - defaultMessage='AD/LDAP Test' - /> - ); - } - - return ( - <div className='form-group reload-config'> - <div className='col-sm-offset-4 col-sm-8'> - <div> - <button - className='btn btn-default' - onClick={this.handleLdapTest} - disabled={this.props.disabled} - > - {contents} - </button> - {message} - </div> - <div className='help-text'> - {helpText} - </div> - </div> - </div> - ); - } -} diff --git a/webapp/components/admin_console/purge_caches.jsx b/webapp/components/admin_console/purge_caches.jsx deleted file mode 100644 index d2337d587..000000000 --- a/webapp/components/admin_console/purge_caches.jsx +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import React from 'react'; - -import {FormattedMessage} from 'react-intl'; - -import {invalidateAllCaches} from 'actions/admin_actions.jsx'; - -export default class PurgeCachesButton extends React.Component { - constructor(props) { - super(props); - - this.handlePurge = this.handlePurge.bind(this); - - this.state = { - loading: false, - fail: null - }; - } - - handlePurge(e) { - e.preventDefault(); - - this.setState({ - loading: true, - fail: null - }); - - invalidateAllCaches( - () => { - this.setState({ - loading: false - }); - }, - (err) => { - this.setState({ - loading: false, - fail: err.message + ' - ' + err.detailed_error - }); - } - ); - } - - render() { - let testMessage = null; - if (this.state.fail) { - testMessage = ( - <div className='alert alert-warning'> - <i className='fa fa-warning'/> - <FormattedMessage - id='admin.purge.purgeFail' - defaultMessage='Purging unsuccessful: {error}' - values={{ - error: this.state.fail - }} - /> - </div> - ); - } - - const helpText = ( - <FormattedMessage - id='admin.purge.purgeDescription' - defaultMessage='This will purge all the in-memory caches for things like sessions, accounts, channels, etc. Deployments using High Availability will attempt to purge all the servers in the cluster. Purging the caches may adversly impact performance.' - /> - ); - - let contents = null; - if (this.state.loading) { - contents = ( - <span> - <span className='fa fa-refresh icon--rotate'/> - <FormattedMessage - id='admin.purge.loading' - defaultMessage='Loading...' - /> - </span> - ); - } else { - contents = ( - <FormattedMessage - id='admin.purge.button' - defaultMessage='Purge All Caches' - /> - ); - } - - return ( - <div className='form-group reload-config'> - <div className='col-sm-offset-4 col-sm-8'> - <div> - <button - className='btn btn-default' - onClick={this.handlePurge} - > - {contents} - </button> - {testMessage} - </div> - <div className='help-text'> - {helpText} - </div> - </div> - </div> - ); - } -} diff --git a/webapp/components/admin_console/recycle_db.jsx b/webapp/components/admin_console/recycle_db.jsx deleted file mode 100644 index 5e536d908..000000000 --- a/webapp/components/admin_console/recycle_db.jsx +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import React from 'react'; - -import * as Utils from 'utils/utils.jsx'; - -import {FormattedMessage, FormattedHTMLMessage} from 'react-intl'; - -import {recycleDatabaseConnection} from 'actions/admin_actions.jsx'; - -export default class RecycleDbButton extends React.Component { - constructor(props) { - super(props); - - this.handleRecycle = this.handleRecycle.bind(this); - - this.state = { - loading: false, - fail: null - }; - } - - handleRecycle(e) { - e.preventDefault(); - - this.setState({ - loading: true, - fail: null - }); - - recycleDatabaseConnection( - () => { - this.setState({ - loading: false - }); - }, - (err) => { - this.setState({ - loading: false, - fail: err.message + ' - ' + err.detailed_error - }); - } - ); - } - - render() { - if (global.window.mm_license.IsLicensed !== 'true') { - return <div/>; - } - - let testMessage = null; - if (this.state.fail) { - testMessage = ( - <div className='alert alert-warning'> - <i className='fa fa-warning'/> - <FormattedMessage - id='admin.recycle.reloadFail' - defaultMessage='Recycling unsuccessful: {error}' - values={{ - error: this.state.fail - }} - /> - </div> - ); - } - - const helpText = ( - <FormattedHTMLMessage - id='admin.recycle.recycleDescription' - defaultMessage='Deployments using multiple databases can switch from one master database to another without restarting the Mattermost server by updating "config.json" to the new desired configuration and using the <a href="../general/configuration"><b>Configuration > Reload Configuration from Disk</b></a> feature to load the new settings while the server is running. The administrator should then use <b>Recycle Database Connections</b> feature to recycle the database connections based on the new settings.' - /> - ); - - let contents = null; - if (this.state.loading) { - contents = ( - <span> - <span className='fa fa-refresh icon--rotate'/> - {Utils.localizeMessage('admin.recycle.loading', ' Recycling...')} - </span> - ); - } else { - contents = ( - <FormattedMessage - id='admin.recycle.button' - defaultMessage='Recycle Database Connections' - /> - ); - } - - return ( - <div className='form-group recycle-db'> - <div className='col-sm-offset-4 col-sm-8'> - <div> - <button - className='btn btn-default' - onClick={this.handleRecycle} - > - {contents} - </button> - {testMessage} - </div> - <div className='help-text'> - {helpText} - </div> - </div> - </div> - ); - } -} diff --git a/webapp/components/admin_console/reload_config.jsx b/webapp/components/admin_console/reload_config.jsx deleted file mode 100644 index ad3d9cca7..000000000 --- a/webapp/components/admin_console/reload_config.jsx +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import React from 'react'; - -import * as Utils from 'utils/utils.jsx'; - -import {FormattedMessage, FormattedHTMLMessage} from 'react-intl'; - -import {reloadConfig} from 'actions/admin_actions.jsx'; - -export default class ReloadConfigButton extends React.Component { - constructor(props) { - super(props); - - this.handleReloadConfig = this.handleReloadConfig.bind(this); - - this.state = { - loading: false, - fail: null - }; - } - - handleReloadConfig(e) { - e.preventDefault(); - - this.setState({ - loading: true, - fail: null - }); - - reloadConfig( - () => { - this.setState({ - loading: false - }); - }, - (err) => { - this.setState({ - loading: false, - fail: err.message + ' - ' + err.detailed_error - }); - } - ); - } - - render() { - if (global.window.mm_license.IsLicensed !== 'true') { - return <div/>; - } - - let testMessage = null; - if (this.state.fail) { - testMessage = ( - <div className='alert alert-warning'> - <i className='fa fa-warning'/> - <FormattedMessage - id='admin.reload.reloadFail' - defaultMessage='Reload unsuccessful: {error}' - values={{ - error: this.state.fail - }} - /> - </div> - ); - } - - const helpText = ( - <FormattedHTMLMessage - id='admin.reload.reloadDescription' - defaultMessage='Deployments using multiple databases can switch from one master database to another without restarting the Mattermost server by updating "config.json" to the new desired configuration and using the <b>Reload Configuration from Disk</b> feature to load the new settings while the server is running. The administrator should then use the <a href="../advanced/database"><b>Database > Recycle Database Connections</b></a> feature to recycle the database connections based on the new settings.' - /> - ); - - let contents = null; - if (this.state.loading) { - contents = ( - <span> - <span className='fa fa-refresh icon--rotate'/> - {Utils.localizeMessage('admin.reload.loading', ' Loading...')} - </span> - ); - } else { - contents = ( - <FormattedMessage - id='admin.reload.button' - defaultMessage='Reload Configuration From Disk' - /> - ); - } - - return ( - <div className='form-group reload-config'> - <div className='col-sm-offset-4 col-sm-8'> - <div> - <button - className='btn btn-default' - onClick={this.handleReloadConfig} - > - {contents} - </button> - {testMessage} - </div> - <div className='help-text'> - {helpText} - </div> - </div> - </div> - ); - } -} diff --git a/webapp/components/admin_console/request_button/request_button.jsx b/webapp/components/admin_console/request_button/request_button.jsx new file mode 100644 index 000000000..4aad287d2 --- /dev/null +++ b/webapp/components/admin_console/request_button/request_button.jsx @@ -0,0 +1,234 @@ +// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import React from 'react'; + +import {FormattedMessage} from 'react-intl'; +import PropTypes from 'prop-types'; + +import * as Utils from 'utils/utils.jsx'; + +/** + * A button which, when clicked, performs an action and displays + * its outcome as either success, or failure accompanied by the + * `message` property of the `err` object. + */ +export default class RequestButton extends React.Component { + static propTypes = { + + /** + * The action to be called to carry out the request. + */ + requestAction: PropTypes.func.isRequired, + + /** + * A component that displays help text for the request button. + * + * Typically, this will be a <FormattedMessage/>. + */ + helpText: PropTypes.element.isRequired, + + /** + * A component to be displayed on the button. + * + * Typically, this will be a <FormattedMessage/> + */ + buttonText: PropTypes.element.isRequired, + + /** + * True if the button form control should be disabled, otherwise false. + */ + disabled: PropTypes.bool, + + /** + * True if the config needs to be saved before running the request, otherwise false. + * + * If set to true, the action provided in the `saveConfigAction` property will be + * called before the action provided in the `requestAction` property, with the later + * only being called if the former is successful. + */ + saveNeeded: PropTypes.bool, + + /** + * Action to be called to save the config, if saveNeeded is set to true. + */ + saveConfigAction: PropTypes.func, + + /** + * True if the success message should be show when the request completes successfully, + * otherwise false. + */ + showSuccessMessage: PropTypes.bool, + + /** + * The message to show when the request completes successfully. + */ + successMessage: PropTypes.shape({ + + /** + * The i18n string ID for the success message. + */ + id: PropTypes.string.isRequired, + + /** + * The i18n default value for the success message. + */ + defaultMessage: PropTypes.string.isRequired + }), + + /** + * The message to show when the request returns an error. + */ + errorMessage: PropTypes.shape({ + + /** + * The i18n string ID for the error message. + */ + id: PropTypes.string.isRequired, + + /** + * The i18n default value for the error message. + * + * The placeholder {error} may be used to include the error message returned + * by the server in response to the failed request. + */ + defaultMessage: PropTypes.string.isRequired + }), + + /** + * True if the {error} placeholder for the `errorMessage` property should include both + * the `message` and `detailed_error` properties of the error returned from the server, + * otherwise false to include only the `message` property. + */ + includeDetailedError: PropTypes.bool + } + + static defaultProps = { + disabled: false, + saveNeeded: false, + showSuccessMessage: true, + includeDetailedError: false, + successMessage: { + id: 'admin.requestButton.requestSuccess', + defaultMessage: 'Test Successful' + }, + errorMessage: { + id: 'admin.requestButton.requestFailure', + defaultMessage: 'Test Failure: {error}' + } + } + + constructor(props) { + super(props); + + this.handleRequest = this.handleRequest.bind(this); + + this.state = { + busy: false, + fail: null, + success: false + }; + } + + handleRequest(e) { + e.preventDefault(); + + this.setState({ + busy: true, + fail: null, + success: false + }); + + const doRequest = () => { //eslint-disable-line func-style + this.props.requestAction( + () => { + this.setState({ + busy: false, + success: true + }); + }, + (err) => { + let errMsg = err.message; + if (this.props.includeDetailedError) { + errMsg += ' - ' + err.detailed_error; + } + + this.setState({ + busy: false, + fail: errMsg + }); + } + ); + }; + + if (this.props.saveNeeded) { + this.props.saveConfigAction(doRequest); + } else { + doRequest(); + } + } + + render() { + let message = null; + if (this.state.fail) { + message = ( + <div> + <div className='alert alert-warning'> + <i className='fa fa-warning'/> + <FormattedMessage + id={this.props.errorMessage.id} + defaultMessage={this.props.errorMessage.defaultMessage} + values={{ + error: this.state.fail + }} + /> + </div> + </div> + ); + } else if (this.state.success && this.props.showSuccessMessage) { + message = ( + <div> + <div className='alert alert-success'> + <i className='fa fa-success'/> + <FormattedMessage + id={this.props.successMessage.id} + defaultMessage={this.props.successMessage.defaultMessage} + /> + </div> + </div> + ); + } + + let contents = null; + if (this.state.busy) { + contents = ( + <span> + <span className='fa fa-refresh icon--rotate'/> + {Utils.localizeMessage('admin.requestButton.loading', ' Loading...')} + </span> + ); + } else { + contents = this.props.buttonText; + } + + return ( + <div className='form-group reload-config'> + <div className='col-sm-offset-4 col-sm-8'> + <div> + <button + className='btn btn-default' + onClick={this.handleRequest} + disabled={this.props.disabled} + > + {contents} + </button> + {message} + </div> + <div className='help-text'> + {this.props.helpText} + </div> + </div> + </div> + ); + } +} diff --git a/webapp/components/admin_console/sync_now_button.jsx b/webapp/components/admin_console/sync_now_button.jsx deleted file mode 100644 index b2a5a001d..000000000 --- a/webapp/components/admin_console/sync_now_button.jsx +++ /dev/null @@ -1,115 +0,0 @@ -import PropTypes from 'prop-types'; - -// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import React from 'react'; - -import * as Utils from 'utils/utils.jsx'; - -import {FormattedMessage, FormattedHTMLMessage} from 'react-intl'; - -import {ldapSyncNow} from 'actions/admin_actions.jsx'; - -export default class SyncNowButton extends React.Component { - static get propTypes() { - return { - disabled: PropTypes.bool - }; - } - constructor(props) { - super(props); - - this.handleSyncNow = this.handleSyncNow.bind(this); - - this.state = { - buisy: false, - fail: null - }; - } - - handleSyncNow(e) { - e.preventDefault(); - - this.setState({ - buisy: true, - fail: null - }); - - ldapSyncNow( - () => { - this.setState({ - buisy: false - }); - }, - (err) => { - this.setState({ - buisy: false, - fail: err.message + ' - ' + err.detailed_error - }); - } - ); - } - - render() { - let failMessage = null; - if (this.state.fail) { - failMessage = ( - <div className='alert alert-warning'> - <i className='fa fa-warning'/> - <FormattedMessage - id='admin.ldap.syncFailure' - defaultMessage='Sync Failure: {error}' - values={{ - error: this.state.fail - }} - /> - </div> - ); - } - - const helpText = ( - <FormattedHTMLMessage - id='admin.ldap.syncNowHelpText' - defaultMessage='Initiates an AD/LDAP synchronization immediately.' - /> - ); - - let contents = null; - if (this.state.loading) { - contents = ( - <span> - <span className='fa fa-refresh icon--rotate'/> - {Utils.localizeMessage('admin.reload.loading', ' Loading...')} - </span> - ); - } else { - contents = ( - <FormattedMessage - id='admin.ldap.sync_button' - defaultMessage='AD/LDAP Synchronize Now' - /> - ); - } - - return ( - <div className='form-group reload-config'> - <div className='col-sm-offset-4 col-sm-8'> - <div> - <button - className='btn btn-default' - onClick={this.handleSyncNow} - disabled={this.props.disabled} - > - {contents} - </button> - {failMessage} - </div> - <div className='help-text'> - {helpText} - </div> - </div> - </div> - ); - } -} |