diff options
Diffstat (limited to 'web/react/components')
-rw-r--r-- | web/react/components/command_list.jsx | 6 | ||||
-rw-r--r-- | web/react/components/post_info.jsx | 17 | ||||
-rw-r--r-- | web/react/components/post_list.jsx | 8 | ||||
-rw-r--r-- | web/react/components/setting_item_max.jsx | 2 | ||||
-rw-r--r-- | web/react/components/sidebar_header.jsx | 2 | ||||
-rw-r--r-- | web/react/components/user_settings_general.jsx | 237 | ||||
-rw-r--r-- | web/react/components/user_settings_notifications.jsx | 16 |
7 files changed, 204 insertions, 84 deletions
diff --git a/web/react/components/command_list.jsx b/web/react/components/command_list.jsx index 5efe98dc6..27264ff6e 100644 --- a/web/react/components/command_list.jsx +++ b/web/react/components/command_list.jsx @@ -48,15 +48,15 @@ module.exports = React.createClass({ if (this.state.suggestions[i].suggestion != this.state.cmd) { suggestions.push( <div key={i} className="command-name" onClick={this.handleClick.bind(this, i)}> - <div className="pull-left"><strong>{ this.state.suggestions[i].suggestion }</strong></div> - <div className="command-desc pull-right">{ this.state.suggestions[i].description }</div> + <div className="command__title"><strong>{ this.state.suggestions[i].suggestion }</strong></div> + <div className="command__desc">{ this.state.suggestions[i].description }</div> </div> ); } } return ( - <div ref="mentionlist" className="command-box" style={{height:(this.state.suggestions.length*37)+2}}> + <div ref="mentionlist" className="command-box" style={{height:(this.state.suggestions.length*56)+2}}> { suggestions } </div> ); diff --git a/web/react/components/post_info.jsx b/web/react/components/post_info.jsx index 73e897f62..c80b287a3 100644 --- a/web/react/components/post_info.jsx +++ b/web/react/components/post_info.jsx @@ -43,13 +43,16 @@ export default class PostInfo extends React.Component { if (isOwner) { dropdownContents.push( - <li role='presentation'> + <li + key='editPost' + role='presentation' + > <a href='#' role='menuitem' data-toggle='modal' data-target='#edit_post' - data-refoucsid="#post_textbox" + data-refoucsid='#post_textbox' data-title={type} data-message={post.message} data-postid={post.id} @@ -64,7 +67,10 @@ export default class PostInfo extends React.Component { if (isOwner || isAdmin) { dropdownContents.push( - <li role='presentation'> + <li + key='deletePost' + role='presentation' + > <a href='#' role='menuitem' @@ -83,7 +89,10 @@ export default class PostInfo extends React.Component { if (this.props.allowReply === 'true') { dropdownContents.push( - <li role='presentation'> + <li + key='replyLink' + role='presentation' + > <a className='reply-link theme' href='#' diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx index 5b0b1f79a..c1e6e490d 100644 --- a/web/react/components/post_list.jsx +++ b/web/react/components/post_list.jsx @@ -401,6 +401,14 @@ export default class PostList extends React.Component { > <i className='fa fa-pencil'></i>Set a description </a> + <a + className='intro-links' + href='#' + data-toggle='modal' + data-target='#channel_invite' + > + <i className='fa fa-user-plus'></i>Invite others to this channel + </a> </div> ); } diff --git a/web/react/components/setting_item_max.jsx b/web/react/components/setting_item_max.jsx index 1599041b0..b978cdb0c 100644 --- a/web/react/components/setting_item_max.jsx +++ b/web/react/components/setting_item_max.jsx @@ -5,6 +5,7 @@ module.exports = React.createClass({ render: function() { var clientError = this.props.client_error ? <div className='form-group'><label className='col-sm-12 has-error'>{ this.props.client_error }</label></div> : null; var server_error = this.props.server_error ? <div className='form-group'><label className='col-sm-12 has-error'>{ this.props.server_error }</label></div> : null; + var extraInfo = this.props.extraInfo ? this.props.extraInfo : null; var inputs = this.props.inputs; @@ -15,6 +16,7 @@ module.exports = React.createClass({ <ul className="setting-list"> <li className="setting-list-item"> {inputs} + {extraInfo} </li> <li className="setting-list-item"> <hr /> diff --git a/web/react/components/sidebar_header.jsx b/web/react/components/sidebar_header.jsx index d5d16816f..af65b7e1d 100644 --- a/web/react/components/sidebar_header.jsx +++ b/web/react/components/sidebar_header.jsx @@ -85,7 +85,7 @@ var NavbarDropdown = React.createClass({ } }); } - teams.push(<li key='newTeam_li'><a key='newTeam_a' href={utils.getWindowLocationOrigin() + '/signup_team' }>Create a New Team</a></li>); + teams.push(<li key='newTeam_li'><a key='newTeam_a' target="_blank" href={utils.getWindowLocationOrigin() + '/signup_team' }>Create a New Team</a></li>); return ( <ul className='nav navbar-nav navbar-right'> diff --git a/web/react/components/user_settings_general.jsx b/web/react/components/user_settings_general.jsx index fed11fbe9..ddd2fb607 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() { + $(this.getDOMNode()).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; @@ -214,19 +235,35 @@ module.exports = React.createClass({ if (this.props.activeSection === 'name') { inputs.push( - <div className='form-group'> + <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'> + <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> ); @@ -238,7 +275,7 @@ module.exports = React.createClass({ submit={this.submitName} server_error={serverError} client_error={clientError} - updateSection={function(e) { + updateSection={function clearSection(e) { self.updateSection(''); e.preventDefault(); }} @@ -259,7 +296,7 @@ module.exports = React.createClass({ <SettingItemMin title='Full Name' describe={fullName} - updateSection={function() { + updateSection={function updateNameSection() { self.updateSection('name'); }} /> @@ -268,11 +305,24 @@ module.exports = React.createClass({ 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> ); @@ -284,7 +334,7 @@ module.exports = React.createClass({ submit={this.submitNickname} server_error={serverError} client_error={clientError} - updateSection={function(e) { + updateSection={function clearSection(e) { self.updateSection(''); e.preventDefault(); }} @@ -295,7 +345,7 @@ module.exports = React.createClass({ <SettingItemMin title='Nickname' describe={UserStore.getCurrentUser().nickname} - updateSection={function() { + updateSection={function updateNicknameSection() { self.updateSection('nickname'); }} /> @@ -304,11 +354,24 @@ module.exports = React.createClass({ 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> ); @@ -320,7 +383,7 @@ module.exports = React.createClass({ submit={this.submitUsername} server_error={serverError} client_error={clientError} - updateSection={function(e) { + updateSection={function clearSection(e) { self.updateSection(''); e.preventDefault(); }} @@ -331,7 +394,7 @@ module.exports = React.createClass({ <SettingItemMin title='Username' describe={UserStore.getCurrentUser().username} - updateSection={function() { + updateSection={function updateUsernameSection() { self.updateSection('username'); }} /> @@ -346,11 +409,16 @@ module.exports = React.createClass({ } inputs.push( - <div> + <div key='emailSetting'> <div className='form-group'> <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,7 +432,7 @@ module.exports = React.createClass({ submit={this.submitEmail} server_error={serverError} client_error={emailError} - updateSection={function(e) { + updateSection={function clearSection(e) { self.updateSection(''); e.preventDefault(); }} @@ -375,7 +443,7 @@ module.exports = React.createClass({ <SettingItemMin title='Email' describe={UserStore.getCurrentUser().email} - updateSection={function() { + updateSection={function updateEmailSection() { self.updateSection('email'); }} /> @@ -391,7 +459,7 @@ 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) { + updateSection={function clearSection(e) { self.updateSection(''); e.preventDefault(); }} @@ -410,7 +478,7 @@ module.exports = React.createClass({ <SettingItemMin title='Profile Picture' describe={minMessage} - updateSection={function() { + updateSection={function updatePictureSection() { self.updateSection('picture'); }} /> @@ -419,8 +487,21 @@ module.exports = React.createClass({ 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> @@ -439,4 +520,10 @@ module.exports = React.createClass({ </div> ); } -}); +} + +UserSettingsGeneralTab.propTypes = { + user: React.PropTypes.object, + updateSection: React.PropTypes.func, + activeSection: React.PropTypes.string +}; diff --git a/web/react/components/user_settings_notifications.jsx b/web/react/components/user_settings_notifications.jsx index b89f72987..ba0bda78e 100644 --- a/web/react/components/user_settings_notifications.jsx +++ b/web/react/components/user_settings_notifications.jsx @@ -1,6 +1,7 @@ // Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved. // See License.txt for license information. +var ChannelStore = require('../stores/channel_store.jsx'); var UserStore = require('../stores/user_store.jsx'); var SettingItemMin = require('./setting_item_min.jsx'); var SettingItemMax = require('./setting_item_max.jsx'); @@ -67,7 +68,11 @@ function getNotificationsStateFromStores() { } } - return {notifyLevel: desktop, enableEmail: email, soundNeeded: soundNeeded, enableSound: sound, usernameKey: usernameKey, mentionKey: mentionKey, customKeys: customKeys, customKeysChecked: customKeys.length > 0, firstNameKey: firstNameKey, allKey: allKey, channelKey: channelKey}; + var curChannel = ChannelStore.getCurrent().display_name; + + return {notifyLevel: desktop, enableEmail: email, soundNeeded: soundNeeded, enableSound: sound, + usernameKey: usernameKey, mentionKey: mentionKey, customKeys: customKeys, customKeysChecked: customKeys.length > 0, + firstNameKey: firstNameKey, allKey: allKey, channelKey: channelKey, curChannel: curChannel}; } export default class NotificationsTab extends React.Component { @@ -141,10 +146,12 @@ export default class NotificationsTab extends React.Component { } componentDidMount() { UserStore.addChangeListener(this.onListenerChange); + ChannelStore.addChangeListener(this.onListenerChange); $('#user_settings').on('hidden.bs.modal', this.handleClose); } componentWillUnmount() { UserStore.removeChangeListener(this.onListenerChange); + ChannelStore.removeChangeListener(this.onListenerChange); $('#user_settings').off('hidden.bs.modal', this.handleClose); this.props.updateSection(''); } @@ -265,6 +272,12 @@ export default class NotificationsTab extends React.Component { e.preventDefault(); }; + let extraInfo = ( + <div className='setting-list__hint'> + These settings will override the global notification settings for the <b>{this.state.curChannel}</b> channel + </div> + ) + desktopSection = ( <SettingItemMax title='Send desktop notifications' @@ -272,6 +285,7 @@ export default class NotificationsTab extends React.Component { submit={this.handleSubmit} server_error={serverError} updateSection={handleUpdateDesktopSection} + extraInfo={extraInfo} /> ); } else { |