diff options
Diffstat (limited to 'web/react/components/user_settings_general.jsx')
-rw-r--r-- | web/react/components/user_settings_general.jsx | 323 |
1 files changed, 222 insertions, 101 deletions
diff --git a/web/react/components/user_settings_general.jsx b/web/react/components/user_settings_general.jsx index fed11fbe9..184534a9a 100644 --- a/web/react/components/user_settings_general.jsx +++ b/web/react/components/user_settings_general.jsx @@ -11,10 +11,32 @@ var AsyncClient = require('../utils/async_client.jsx'); var utils = require('../utils/utils.jsx'); var assign = require('object-assign'); -module.exports = React.createClass({ - displayName: 'GeneralTab', - submitActive: false, - submitUsername: function(e) { +export default class UserSettingsGeneralTab extends React.Component { + constructor(props) { + super(props); + this.submitActive = false; + + this.submitUsername = this.submitUsername.bind(this); + this.submitNickname = this.submitNickname.bind(this); + this.submitName = this.submitName.bind(this); + this.submitEmail = this.submitEmail.bind(this); + this.submitUser = this.submitUser.bind(this); + this.submitPicture = this.submitPicture.bind(this); + + this.updateUsername = this.updateUsername.bind(this); + this.updateFirstName = this.updateFirstName.bind(this); + this.updateLastName = this.updateLastName.bind(this); + this.updateNickname = this.updateNickname.bind(this); + this.updateEmail = this.updateEmail.bind(this); + this.updatePicture = this.updatePicture.bind(this); + this.updateSection = this.updateSection.bind(this); + + this.handleClose = this.handleClose.bind(this); + this.setupInitialState = this.setupInitialState.bind(this); + + this.state = this.setupInitialState(props); + } + submitUsername(e) { e.preventDefault(); var user = this.props.user; @@ -37,8 +59,8 @@ module.exports = React.createClass({ user.username = username; this.submitUser(user); - }, - submitNickname: function(e) { + } + submitNickname(e) { e.preventDefault(); var user = UserStore.getCurrentUser(); @@ -52,8 +74,8 @@ module.exports = React.createClass({ user.nickname = nickname; this.submitUser(user); - }, - submitName: function(e) { + } + submitName(e) { e.preventDefault(); var user = UserStore.getCurrentUser(); @@ -69,8 +91,8 @@ module.exports = React.createClass({ user.last_name = lastName; this.submitUser(user); - }, - submitEmail: function(e) { + } + submitEmail(e) { e.preventDefault(); var user = UserStore.getCurrentUser(); @@ -88,15 +110,15 @@ module.exports = React.createClass({ user.email = email; this.submitUser(user); - }, - submitUser: function(user) { + } + submitUser(user) { client.updateUser(user, - function() { + function updateSuccess() { this.updateSection(''); AsyncClient.getMe(); }.bind(this), - function(err) { - var state = this.getInitialState(); + function updateFailure(err) { + var state = this.setupInitialState(this.props); if (err.message) { state.serverError = err.message; } else { @@ -105,8 +127,8 @@ module.exports = React.createClass({ this.setState(state); }.bind(this) ); - }, - submitPicture: function(e) { + } + submitPicture(e) { e.preventDefault(); if (!this.state.picture) { @@ -129,34 +151,34 @@ module.exports = React.createClass({ this.setState({loadingPicture: true}); client.uploadProfileImage(formData, - function() { + function imageUploadSuccess() { this.submitActive = false; AsyncClient.getMe(); window.location.reload(); }.bind(this), - function(err) { - var state = this.getInitialState(); + function imageUploadFailure(err) { + var state = this.setupInitialState(this.props); state.serverError = err; this.setState(state); }.bind(this) ); - }, - updateUsername: function(e) { + } + updateUsername(e) { this.setState({username: e.target.value}); - }, - updateFirstName: function(e) { + } + updateFirstName(e) { this.setState({firstName: e.target.value}); - }, - updateLastName: function(e) { + } + updateLastName(e) { this.setState({lastName: e.target.value}); - }, - updateNickname: function(e) { + } + updateNickname(e) { this.setState({nickname: e.target.value}); - }, - updateEmail: function(e) { + } + updateEmail(e) { this.setState({email: e.target.value}); - }, - updatePicture: function(e) { + } + updatePicture(e) { if (e.target.files && e.target.files[0]) { this.setState({picture: e.target.files[0]}); @@ -165,34 +187,33 @@ module.exports = React.createClass({ } else { this.setState({picture: null}); } - }, - updateSection: function(section) { - this.setState(assign({}, this.getInitialState(), {clientError: ''})); + } + updateSection(section) { + this.setState(assign({}, this.setupInitialState(this.props), {clientError: '', serverError: '', emailError: ''})); this.submitActive = false; this.props.updateSection(section); - }, - handleClose: function() { - $(this.getDOMNode()).find('.form-control').each(function() { + } + handleClose() { + $(React.findDOMNode(this)).find('.form-control').each(function clearForms() { this.value = ''; }); - this.setState(assign({}, this.getInitialState(), {clientError: null, serverError: null, emailError: null})); + this.setState(assign({}, this.setupInitialState(this.props), {clientError: null, serverError: null, emailError: null})); this.props.updateSection(''); - }, - componentDidMount: function() { + } + componentDidMount() { $('#user_settings').on('hidden.bs.modal', this.handleClose); - }, - componentWillUnmount: function() { + } + componentWillUnmount() { $('#user_settings').off('hidden.bs.modal', this.handleClose); - }, - getInitialState: function() { - var user = this.props.user; + } + setupInitialState(props) { + var user = props.user; var emailEnabled = !ConfigStore.getSettingAsBoolean('ByPassEmail', false); - return {username: user.username, firstName: user.first_name, lastName: user.last_name, nickname: user.nickname, - email: user.email, picture: null, loadingPicture: false, emailEnabled: emailEnabled}; - }, - render: function() { + email: user.email, picture: null, loadingPicture: false, emailEnabled: emailEnabled}; + } + render() { var user = this.props.user; var clientError = null; @@ -209,28 +230,65 @@ module.exports = React.createClass({ } var nameSection; - var self = this; var inputs = []; if (this.props.activeSection === 'name') { inputs.push( - <div className='form-group'> - <label className='col-sm-5 control-label'>First Name</label> + <div + key='firstNameSetting' + className='form-group' + > + <label className='col-sm-5 control-label'>{'First Name'}</label> <div className='col-sm-7'> - <input className='form-control' type='text' onChange={this.updateFirstName} value={this.state.firstName}/> + <input + className='form-control' + type='text' + onChange={this.updateFirstName} + value={this.state.firstName} + /> </div> </div> ); inputs.push( - <div className='form-group'> - <label className='col-sm-5 control-label'>Last Name</label> + <div + key='lastNameSetting' + className='form-group' + > + <label className='col-sm-5 control-label'>{'Last Name'}</label> <div className='col-sm-7'> - <input className='form-control' type='text' onChange={this.updateLastName} value={this.state.lastName}/> + <input + className='form-control' + type='text' + onChange={this.updateLastName} + value={this.state.lastName} + /> </div> </div> ); + function notifClick(e) { + e.preventDefault(); + this.updateSection(''); + this.props.updateTab('notifications'); + } + + const notifLink = ( + <a + href='#' + onClick={notifClick.bind(this)} + > + {'Notifications'} + </a> + ); + + const extraInfo = ( + <span> + {'By default, you will receive mention notifications when someone types your first name. '} + {'Go to '} {notifLink} {'settings to change this default.'} + </span> + ); + nameSection = ( <SettingItemMax title='Full Name' @@ -238,10 +296,11 @@ module.exports = React.createClass({ submit={this.submitName} server_error={serverError} client_error={clientError} - updateSection={function(e) { - self.updateSection(''); + updateSection={function clearSection(e) { + this.updateSection(''); e.preventDefault(); - }} + }.bind(this)} + extraInfo={extraInfo} /> ); } else { @@ -259,24 +318,44 @@ module.exports = React.createClass({ <SettingItemMin title='Full Name' describe={fullName} - updateSection={function() { - self.updateSection('name'); - }} + updateSection={function updateNameSection() { + this.updateSection('name'); + }.bind(this)} /> ); } var nicknameSection; if (this.props.activeSection === 'nickname') { + let nicknameLabel = 'Nickname'; + if (utils.isMobile()) { + nicknameLabel = ''; + } + inputs.push( - <div className='form-group'> - <label className='col-sm-5 control-label'>{utils.isMobile() ? '' : 'Nickname'}</label> + <div + key='nicknameSetting' + className='form-group' + > + <label className='col-sm-5 control-label'>{nicknameLabel}</label> <div className='col-sm-7'> - <input className='form-control' type='text' onChange={this.updateNickname} value={this.state.nickname}/> + <input + className='form-control' + type='text' + onChange={this.updateNickname} + value={this.state.nickname} + /> </div> </div> ); + const extraInfo = ( + <span> + {'Use Nickname for a name you might be called that is different from your first name and user name.'} + {'This is most often used when two or more people have similar sounding names and usernames.'} + </span> + ); + nicknameSection = ( <SettingItemMax title='Nickname' @@ -284,10 +363,11 @@ module.exports = React.createClass({ submit={this.submitNickname} server_error={serverError} client_error={clientError} - updateSection={function(e) { - self.updateSection(''); + updateSection={function clearSection(e) { + this.updateSection(''); e.preventDefault(); - }} + }.bind(this)} + extraInfo={extraInfo} /> ); } else { @@ -295,24 +375,39 @@ module.exports = React.createClass({ <SettingItemMin title='Nickname' describe={UserStore.getCurrentUser().nickname} - updateSection={function() { - self.updateSection('nickname'); - }} + updateSection={function updateNicknameSection() { + this.updateSection('nickname'); + }.bind(this)} /> ); } var usernameSection; if (this.props.activeSection === 'username') { + let usernameLabel = 'Username'; + if (utils.isMobile()) { + usernameLabel = ''; + } + inputs.push( - <div className='form-group'> - <label className='col-sm-5 control-label'>{utils.isMobile() ? '' : 'Username'}</label> + <div + key='usernameSetting' + className='form-group' + > + <label className='col-sm-5 control-label'>{usernameLabel}</label> <div className='col-sm-7'> - <input className='form-control' type='text' onChange={this.updateUsername} value={this.state.username}/> + <input + className='form-control' + type='text' + onChange={this.updateUsername} + value={this.state.username} + /> </div> </div> ); + const extraInfo = (<span>{'Pick something easy for teammates to recognize and recall.'}</span>); + usernameSection = ( <SettingItemMax title='Username' @@ -320,10 +415,11 @@ module.exports = React.createClass({ submit={this.submitUsername} server_error={serverError} client_error={clientError} - updateSection={function(e) { - self.updateSection(''); + updateSection={function clearSection(e) { + this.updateSection(''); e.preventDefault(); - }} + }.bind(this)} + extraInfo={extraInfo} /> ); } else { @@ -331,9 +427,9 @@ module.exports = React.createClass({ <SettingItemMin title='Username' describe={UserStore.getCurrentUser().username} - updateSection={function() { - self.updateSection('username'); - }} + updateSection={function updateUsernameSection() { + this.updateSection('username'); + }.bind(this)} /> ); } @@ -342,15 +438,20 @@ module.exports = React.createClass({ let helpText = <div>Email is used for notifications, and requires verification if changed.</div>; if (!this.state.emailEnabled) { - helpText = <div className='text-danger'><br />Email has been disabled by your system administrator. No notification emails will be sent until it is enabled.</div>; + helpText = <div className='setting-list__hint text-danger'>{'Email has been disabled by your system administrator. No notification emails will be sent until it is enabled.'}</div>; } inputs.push( - <div> + <div key='emailSetting'> <div className='form-group'> - <label className='col-sm-5 control-label'>Primary Email</label> + <label className='col-sm-5 control-label'>{'Primary Email'}</label> <div className='col-sm-7'> - <input className='form-control' type='text' onChange={this.updateEmail} value={this.state.email}/> + <input + className='form-control' + type='text' + onChange={this.updateEmail} + value={this.state.email} + /> </div> </div> {helpText} @@ -364,10 +465,10 @@ module.exports = React.createClass({ submit={this.submitEmail} server_error={serverError} client_error={emailError} - updateSection={function(e) { - self.updateSection(''); + updateSection={function clearSection(e) { + this.updateSection(''); e.preventDefault(); - }} + }.bind(this)} /> ); } else { @@ -375,9 +476,9 @@ module.exports = React.createClass({ <SettingItemMin title='Email' describe={UserStore.getCurrentUser().email} - updateSection={function() { - self.updateSection('email'); - }} + updateSection={function updateEmailSection() { + this.updateSection('email'); + }.bind(this)} /> ); } @@ -391,10 +492,10 @@ module.exports = React.createClass({ src={'/api/v1/users/' + user.id + '/image?time=' + user.last_picture_update} server_error={serverError} client_error={clientError} - updateSection={function(e) { - self.updateSection(''); + updateSection={function clearSection(e) { + this.updateSection(''); e.preventDefault(); - }} + }.bind(this)} picture={this.state.picture} pictureChange={this.updatePicture} submitActive={this.submitActive} @@ -410,20 +511,33 @@ module.exports = React.createClass({ <SettingItemMin title='Profile Picture' describe={minMessage} - updateSection={function() { - self.updateSection('picture'); - }} + updateSection={function updatePictureSection() { + this.updateSection('picture'); + }.bind(this)} /> ); } return ( <div> <div className='modal-header'> - <button type='button' className='close' data-dismiss='modal' aria-label='Close'><span aria-hidden='true'>×</span></button> - <h4 className='modal-title' ref='title'><i className='modal-back'></i>General Settings</h4> + <button + type='button' + className='close' + data-dismiss='modal' + aria-label='Close' + > + <span aria-hidden='true'>{'×'}</span> + </button> + <h4 + className='modal-title' + ref='title' + > + <i className='modal-back'></i> + {'General Settings'} + </h4> </div> <div className='user-settings'> - <h3 className='tab-header'>General Settings</h3> + <h3 className='tab-header'>{'General Settings'}</h3> <div className='divider-dark first'/> {nameSection} <div className='divider-light'/> @@ -439,4 +553,11 @@ module.exports = React.createClass({ </div> ); } -}); +} + +UserSettingsGeneralTab.propTypes = { + user: React.PropTypes.object, + updateSection: React.PropTypes.func, + updateTab: React.PropTypes.func, + activeSection: React.PropTypes.string +}; |