summaryrefslogtreecommitdiffstats
path: root/web/react
diff options
context:
space:
mode:
Diffstat (limited to 'web/react')
-rw-r--r--web/react/components/delete_channel_modal.jsx2
-rw-r--r--web/react/components/delete_post_modal.jsx2
-rw-r--r--web/react/components/edit_channel_modal.jsx2
-rw-r--r--web/react/components/edit_post_modal.jsx2
-rw-r--r--web/react/components/get_link_modal.jsx49
-rw-r--r--web/react/components/invite_member_modal.jsx270
-rw-r--r--web/react/components/mention_list.jsx180
-rw-r--r--web/react/components/new_channel.jsx134
-rw-r--r--web/react/components/signup_team_complete.jsx6
-rw-r--r--web/react/components/team_settings_modal.jsx2
-rw-r--r--web/react/components/user_settings_modal.jsx2
11 files changed, 358 insertions, 293 deletions
diff --git a/web/react/components/delete_channel_modal.jsx b/web/react/components/delete_channel_modal.jsx
index 64ceec450..589737271 100644
--- a/web/react/components/delete_channel_modal.jsx
+++ b/web/react/components/delete_channel_modal.jsx
@@ -34,7 +34,7 @@ module.exports = React.createClass({
var channelType = ChannelStore.getCurrent() && ChannelStore.getCurrent().type === 'P' ? "private group" : "channel"
return (
- <div className="modal fade" ref="modal" id="delete_channel" role="dialog" aria-hidden="true">
+ <div className="modal fade" ref="modal" id="delete_channel" role="dialog" tabIndex="-1" aria-hidden="true">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
diff --git a/web/react/components/delete_post_modal.jsx b/web/react/components/delete_post_modal.jsx
index f0cb809af..1b6a7e162 100644
--- a/web/react/components/delete_post_modal.jsx
+++ b/web/react/components/delete_post_modal.jsx
@@ -82,7 +82,7 @@ module.exports = React.createClass({
var error = this.state.error ? <div className='form-group has-error'><label className='control-label'>{ this.state.error }</label></div> : null;
return (
- <div className="modal fade" id="delete_post" ref="modal" role="dialog" aria-hidden="true">
+ <div className="modal fade" id="delete_post" ref="modal" role="dialog" tabIndex="-1" aria-hidden="true">
<div className="modal-dialog modal-push-down">
<div className="modal-content">
<div className="modal-header">
diff --git a/web/react/components/edit_channel_modal.jsx b/web/react/components/edit_channel_modal.jsx
index 1b0cc185f..06d7fc3e8 100644
--- a/web/react/components/edit_channel_modal.jsx
+++ b/web/react/components/edit_channel_modal.jsx
@@ -51,7 +51,7 @@ module.exports = React.createClass({
var server_error = this.state.server_error ? <div className='form-group has-error'><br/><label className='control-label'>{ this.state.server_error }</label></div> : null;
return (
- <div className="modal fade" ref="modal" id="edit_channel" role="dialog" aria-hidden="true">
+ <div className="modal fade" ref="modal" id="edit_channel" role="dialog" tabIndex="-1" aria-hidden="true">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
diff --git a/web/react/components/edit_post_modal.jsx b/web/react/components/edit_post_modal.jsx
index 21b75bb6e..064d3fa94 100644
--- a/web/react/components/edit_post_modal.jsx
+++ b/web/react/components/edit_post_modal.jsx
@@ -71,7 +71,7 @@ module.exports = React.createClass({
var error = this.state.error ? <div className='form-group has-error'><label className='control-label'>{ this.state.error }</label></div> : null;
return (
- <div className="modal fade edit-modal" ref="modal" id="edit_post" role="dialog" aria-hidden="true">
+ <div className="modal fade edit-modal" ref="modal" id="edit_post" role="dialog" tabIndex="-1" aria-hidden="true">
<div className="modal-dialog modal-push-down">
<div className="modal-content">
<div className="modal-header">
diff --git a/web/react/components/get_link_modal.jsx b/web/react/components/get_link_modal.jsx
index af5314e64..ea22ad0f3 100644
--- a/web/react/components/get_link_modal.jsx
+++ b/web/react/components/get_link_modal.jsx
@@ -10,46 +10,57 @@ ZeroClipboardMixin.ZeroClipboard.config({
module.exports = React.createClass({
zeroclipboardElementsSelector: '[data-copy-btn]',
- mixins: [ ZeroClipboardMixin ],
+ mixins: [ZeroClipboardMixin],
componentDidMount: function() {
var self = this;
- if(this.refs.modal) {
+ if (this.refs.modal) {
$(this.refs.modal.getDOMNode()).on('show.bs.modal', function(e) {
var button = e.relatedTarget;
- self.setState({title: $(button).attr('data-title'), value: $(button).attr('data-value') });
+ self.setState({title: $(button).attr('data-title'), value: $(button).attr('data-value')});
+ });
+ $(this.refs.modal.getDOMNode()).on('hide.bs.modal', function() {
+ self.setState({copiedLink: false});
});
}
},
getInitialState: function() {
- return { };
+ return {copiedLink: false};
+ },
+ handleClick: function() {
+ this.setState({copiedLink: true});
},
render: function() {
- var currentUser = UserStore.getCurrentUser()
+ var currentUser = UserStore.getCurrentUser();
+ var copyLinkConfirm = null;
+
+ if (this.state.copiedLink) {
+ copyLinkConfirm = <p className='copy-link-confirm'>Link copied to clipboard.</p>;
+ }
if (currentUser != null) {
return (
- <div className="modal fade" ref="modal" id="get_link" tabIndex="-1" role="dialog" aria-hidden="true">
- <div className="modal-dialog">
- <div className="modal-content">
- <div className="modal-header">
- <button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
- <h4 className="modal-title" id="myModalLabel">{this.state.title} Link</h4>
+ <div className='modal fade' ref='modal' id='get_link' tabIndex='-1' role='dialog' aria-hidden='true'>
+ <div className='modal-dialog'>
+ <div className='modal-content'>
+ <div className='modal-header'>
+ <button type='button' className='close' data-dismiss='modal' aria-label='Close'><span aria-hidden='true'>&times;</span></button>
+ <h4 className='modal-title' id='myModalLabel'>{this.state.title} Link</h4>
</div>
- <div className="modal-body">
- <p>{"The link below is used for open " + strings.TeamPlural + " or if you allowed your " + strings.Team + " members to sign up using their " + strings.Company + " email addresses."}
+ <div className='modal-body'>
+ <p>{'The link below is used for open ' + strings.TeamPlural + ' or if you allowed your ' + strings.Team + ' members to sign up using their ' + strings.Company + ' email addresses.'}
</p>
- <textarea className="form-control no-resize" readOnly="true" value={this.state.value}></textarea>
+ <textarea className='form-control no-resize' readOnly='true' value={this.state.value}></textarea>
</div>
- <div className="modal-footer">
- <button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
- <button data-copy-btn type="button" className="btn btn-primary pull-left" data-clipboard-text={this.state.value}>Copy Link</button>
+ <div className='modal-footer'>
+ <button type='button' className='btn btn-default' data-dismiss='modal'>Close</button>
+ <button data-copy-btn='true' type='button' className='btn btn-primary pull-left' onClick={this.handleClick} data-clipboard-text={this.state.value}>Copy Link</button>
+ {copyLinkConfirm}
</div>
</div>
</div>
</div>
);
- } else {
- return <div/>;
}
+ return <div/>;
}
});
diff --git a/web/react/components/invite_member_modal.jsx b/web/react/components/invite_member_modal.jsx
index fed96b50a..3eca79bae 100644
--- a/web/react/components/invite_member_modal.jsx
+++ b/web/react/components/invite_member_modal.jsx
@@ -2,7 +2,7 @@
// See License.txt for license information.
var utils = require('../utils/utils.jsx');
-var Client =require('../utils/client.jsx');
+var Client = require('../utils/client.jsx');
var UserStore = require('../stores/user_store.jsx');
var ConfirmModal = require('./confirm_modal.jsx');
@@ -15,20 +15,19 @@ module.exports = React.createClass({
return;
}
- var not_empty = false;
- for (var i = 0; i < self.state.invite_ids.length; i++) {
- var index = self.state.invite_ids[i];
- if (self.refs["email"+index].getDOMNode().value.trim() !== '') {
- not_empty = true;
+ var notEmpty = false;
+ for (var i = 0; i < self.state.inviteIds.length; i++) {
+ var index = self.state.inviteIds[i];
+ if (self.refs['email' + index].getDOMNode().value.trim() !== '') {
+ notEmpty = true;
break;
}
}
- if (not_empty) {
+ if (notEmpty) {
$('#confirm_invite_modal').modal('show');
e.preventDefault();
}
-
});
$('#invite_member').on('hidden.bs.modal', function() {
@@ -36,52 +35,54 @@ module.exports = React.createClass({
});
},
handleSubmit: function(e) {
- var invite_ids = this.state.invite_ids;
- var count = invite_ids.length;
+ var inviteIds = this.state.inviteIds;
+ var count = inviteIds.length;
var invites = [];
- var email_errors = this.state.email_errors;
- var first_name_errors = this.state.first_name_errors;
- var last_name_errors = this.state.last_name_errors;
+ var emailErrors = this.state.emailErrors;
+ var firstNameErrors = this.state.firstNameErrors;
+ var lastNameErrors = this.state.lastNameErrors;
var valid = true;
for (var i = 0; i < count; i++) {
- var index = invite_ids[i];
+ var index = inviteIds[i];
var invite = {};
- invite.email = this.refs["email"+index].getDOMNode().value.trim();
+ invite.email = this.refs['email' + index].getDOMNode().value.trim();
if (!invite.email || !utils.isEmail(invite.email)) {
- email_errors[index] = "Please enter a valid email address";
+ emailErrors[index] = 'Please enter a valid email address';
valid = false;
} else {
- email_errors[index] = "";
+ emailErrors[index] = '';
}
if (config.AllowInviteNames) {
- invite.first_name = this.refs["first_name"+index].getDOMNode().value.trim();
- if (!invite.first_name && config.RequireInviteNames) {
- first_name_errors[index] = "This is a required field";
+ invite.firstName = this.refs['first_name' + index].getDOMNode().value.trim();
+ if (!invite.firstName && config.RequireInviteNames) {
+ firstNameErrors[index] = 'This is a required field';
valid = false;
} else {
- first_name_errors[index] = "";
+ firstNameErrors[index] = '';
}
- invite.last_name = this.refs["last_name"+index].getDOMNode().value.trim();
- if (!invite.last_name && config.RequireInviteNames) {
- last_name_errors[index] = "This is a required field";
+ invite.lastName = this.refs['last_name' + index].getDOMNode().value.trim();
+ if (!invite.lastName && config.RequireInviteNames) {
+ lastNameErrors[index] = 'This is a required field';
valid = false;
} else {
- last_name_errors[index] = "";
+ lastNameErrors[index] = '';
}
}
invites.push(invite);
}
- this.setState({ email_errors: email_errors, first_name_errors: first_name_errors, last_name_errors: last_name_errors });
+ this.setState({emailErrors: emailErrors, firstNameErrors: firstNameErrors, lastNameErrors: lastNameErrors});
- if (!valid || invites.length === 0) return;
+ if (!valid || invites.length === 0) {
+ return;
+ }
- var data = {}
- data["invites"] = invites;
+ var data = {};
+ data.invites = invites;
Client.inviteMembers(data,
function() {
@@ -89,146 +90,177 @@ module.exports = React.createClass({
$(this.refs.modal.getDOMNode()).modal('hide');
}.bind(this),
function(err) {
- if (err.message === "This person is already on your team") {
- email_errors[err.detailed_error] = err.message;
- this.setState({ email_errors: email_errors });
+ if (err.message === 'This person is already on your team') {
+ emailErrors[err.detailed_error] = err.message;
+ this.setState({emailErrors: emailErrors});
+ } else {
+ this.setState({serverError: err.message});
}
- else
- this.setState({ server_error: err.message});
}.bind(this)
);
-
},
componentDidUpdate: function() {
$(this.refs.modalBody.getDOMNode()).css('max-height', $(window).height() - 200);
$(this.refs.modalBody.getDOMNode()).css('overflow-y', 'scroll');
},
addInviteFields: function() {
- var count = this.state.id_count + 1;
- var invite_ids = this.state.invite_ids;
- invite_ids.push(count);
- this.setState({ invite_ids: invite_ids, id_count: count });
+ var count = this.state.idCount + 1;
+ var inviteIds = this.state.inviteIds;
+ inviteIds.push(count);
+ this.setState({inviteIds: inviteIds, idCount: count});
},
clearFields: function() {
- var invite_ids = this.state.invite_ids;
+ var inviteIds = this.state.inviteIds;
- for (var i = 0; i < invite_ids.length; i++) {
- var index = invite_ids[i];
- this.refs["email"+index].getDOMNode().value = "";
+ for (var i = 0; i < inviteIds.length; i++) {
+ var index = inviteIds[i];
+ this.refs['email' + index].getDOMNode().value = '';
if (config.AllowInviteNames) {
- this.refs["first_name"+index].getDOMNode().value = "";
- this.refs["last_name"+index].getDOMNode().value = "";
+ this.refs['first_name' + index].getDOMNode().value = '';
+ this.refs['last_name' + index].getDOMNode().value = '';
}
}
this.setState({
- invite_ids: [0],
- id_count: 0,
- email_errors: {},
- first_name_errors: {},
- last_name_errors: {}
+ inviteIds: [0],
+ idCount: 0,
+ emailErrors: {},
+ firstNameErrors: {},
+ lastNameErrors: {}
});
},
removeInviteFields: function(index) {
- var count = this.state.id_count;
- var invite_ids = this.state.invite_ids;
- var i = invite_ids.indexOf(index);
- if (i > -1) invite_ids.splice(i, 1);
- if (!invite_ids.length) invite_ids.push(++count);
- this.setState({ invite_ids: invite_ids, id_count: count });
+ var count = this.state.idCount;
+ var inviteIds = this.state.inviteIds;
+ var i = inviteIds.indexOf(index);
+ if (i > -1) {
+ inviteIds.splice(i, 1);
+ }
+ if (!inviteIds.length) {
+ inviteIds.push(++count);
+ }
+ this.setState({inviteIds: inviteIds, idCount: count});
},
getInitialState: function() {
return {
- invite_ids: [0],
- id_count: 0,
- email_errors: {},
- first_name_errors: {},
- last_name_errors: {}
+ inviteIds: [0],
+ idCount: 0,
+ emailErrors: {},
+ firstNameErrors: {},
+ lastNameErrors: {}
};
},
render: function() {
- var currentUser = UserStore.getCurrentUser()
+ var currentUser = UserStore.getCurrentUser();
if (currentUser != null) {
- var invite_sections = [];
- var invite_ids = this.state.invite_ids;
- var self = this;
- for (var i = 0; i < invite_ids.length; i++) {
- var index = invite_ids[i];
- var email_error = this.state.email_errors[index] ? <label className='control-label'>{ this.state.email_errors[index] }</label> : null;
- var first_name_error = this.state.first_name_errors[index] ? <label className='control-label'>{ this.state.first_name_errors[index] }</label> : null;
- var last_name_error = this.state.last_name_errors[index] ? <label className='control-label'>{ this.state.last_name_errors[index] }</label> : null;
-
- invite_sections[index] = (
- <div key={"key" + index}>
- <div>
- <button type="button" className="btn btn-link remove__member" onClick={this.removeInviteFields.bind(this, index)}><span className="fa fa-trash"></span></button>
- </div>
- <div className={ email_error ? "form-group invite has-error" : "form-group invite" }>
- <input onKeyUp={this.displayNameKeyUp} type="text" ref={"email"+index} className="form-control" placeholder="email@domain.com" maxLength="64" />
- { email_error }
- </div>
- <div className="row--invite">
- { config.AllowInviteNames ?
- <div className="col-sm-6">
- <div className={ first_name_error ? "form-group has-error" : "form-group" }>
- <input type="text" className="form-control" ref={"first_name"+index} placeholder="First name" maxLength="64" />
- { first_name_error }
- </div>
- </div>
- : "" }
- { config.AllowInviteNames ?
- <div className="col-sm-6">
- <div className={ last_name_error ? "form-group has-error" : "form-group" }>
- <input type="text" className="form-control" ref={"last_name"+index} placeholder="Last name" maxLength="64" />
- { last_name_error }
- </div>
- </div>
- : "" }
+ var inviteSections = [];
+ var inviteIds = this.state.inviteIds;
+ for (var i = 0; i < inviteIds.length; i++) {
+ var index = inviteIds[i];
+ var emailError = null;
+ if (this.state.emailErrors[index]) {
+ emailError = <label className='control-label'>{this.state.emailErrors[index]}</label>;
+ }
+ var firstNameError = null;
+ if (this.state.firstNameErrors[index]) {
+ firstNameError = <label className='control-label'>{this.state.firstNameErrors[index]}</label>;
+ }
+ var lastNameError = null;
+ if (this.state.lastNameErrors[index]) {
+ lastNameError = <label className='control-label'>{this.state.lastNameErrors[index]}</label>;
+ }
+
+ var removeButton = null;
+ if (index) {
+ removeButton = (<div>
+ <button type='button' className='btn btn-link remove__member' onClick={this.removeInviteFields.bind(this, index)}><span className='fa fa-trash'></span></button>
+ </div>);
+ }
+ var emailClass = 'form-group invite';
+ if (emailError) {
+ emailClass += ' has-error';
+ }
+
+ var nameFields = null;
+ if (config.AllowInviteNames) {
+ var firstNameClass = 'form-group';
+ if (firstNameError) {
+ firstNameClass += ' has-error';
+ }
+ var lastNameClass = 'form-group';
+ if (lastNameError) {
+ lastNameClass += ' has-error';
+ }
+ nameFields = (<div className='row--invite'>
+ <div className='col-sm-6'>
+ <div className={firstNameClass}>
+ <input type='text' className='form-control' ref={'first_name' + index} placeholder='First name' maxLength='64' />
+ {firstNameError}
+ </div>
+ </div>
+ <div className='col-sm-6'>
+ <div className={lastNameClass}>
+ <input type='text' className='form-control' ref={'last_name' + index} placeholder='Last name' maxLength='64' />
+ {lastNameError}
+ </div>
+ </div>
+ </div>);
+ }
+
+ inviteSections[index] = (
+ <div key={'key' + index}>
+ {removeButton}
+ <div className={emailClass}>
+ <input onKeyUp={this.displayNameKeyUp} type='text' ref={'email' + index} className='form-control' placeholder='email@domain.com' maxLength='64' />
+ {emailError}
</div>
+ {nameFields}
</div>
);
}
- var server_error = this.state.server_error ? <div className='form-group has-error'><label className='control-label'>{ this.state.server_error }</label></div> : null;
+ var serverError = null;
+ if (this.state.serverError) {
+ serverError = <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div>;
+ }
return (
<div>
- <div className="modal fade" ref="modal" id="invite_member" tabIndex="-1" role="dialog" aria-hidden="true">
- <div className="modal-dialog">
- <div className="modal-content">
- <div className="modal-header">
- <button type="button" className="close" data-dismiss="modal" aria-label="Close" data-reactid=".5.0.0.0.0"><span aria-hidden="true" data-reactid=".5.0.0.0.0.0">×</span></button>
- <h4 className="modal-title" id="myModalLabel">Invite New Member</h4>
+ <div className='modal fade' ref='modal' id='invite_member' tabIndex='-1' role='dialog' aria-hidden='true'>
+ <div className='modal-dialog'>
+ <div className='modal-content'>
+ <div className='modal-header'>
+ <button type='button' className='close' data-dismiss='modal' aria-label='Close' data-reactid='.5.0.0.0.0'><span aria-hidden='true' data-reactid='.5.0.0.0.0.0'>×</span></button>
+ <h4 className='modal-title' id='myModalLabel'>Invite New Member</h4>
</div>
- <div ref="modalBody" className="modal-body">
- <form role="form">
- { invite_sections }
+ <div ref='modalBody' className='modal-body'>
+ <form role='form'>
+ {inviteSections}
</form>
- { server_error }
- <button type="button" className="btn btn-default" onClick={this.addInviteFields}>Add another</button>
+ {serverError}
+ <button type='button' className='btn btn-default' onClick={this.addInviteFields}>Add another</button>
<br/>
<br/>
<span>People invited automatically join Town Square channel.</span>
</div>
- <div className="modal-footer">
- <button type="button" className="btn btn-default" data-dismiss="modal">Cancel</button>
- <button onClick={this.handleSubmit} type="button" className="btn btn-primary">Send Invitations</button>
+ <div className='modal-footer'>
+ <button type='button' className='btn btn-default' data-dismiss='modal'>Cancel</button>
+ <button onClick={this.handleSubmit} type='button' className='btn btn-primary'>Send Invitations</button>
</div>
</div>
</div>
</div>
<ConfirmModal
- id="confirm_invite_modal"
- parent_id="invite_member"
- title="Discard Invitations?"
- message="You have unsent invitations, are you sure you want to discard them?"
- confirm_button="Yes, Discard"
+ id='confirm_invite_modal'
+ parent_id='invite_member'
+ title='Discard Invitations?'
+ message='You have unsent invitations, are you sure you want to discard them?'
+ confirm_button='Yes, Discard/'
/>
</div>
);
- } else {
- return <div/>;
}
+ return <div/>;
}
});
diff --git a/web/react/components/mention_list.jsx b/web/react/components/mention_list.jsx
index 71a6083d2..a0f68df98 100644
--- a/web/react/components/mention_list.jsx
+++ b/web/react/components/mention_list.jsx
@@ -15,81 +15,78 @@ var MAX_ITEMS_IN_LIST = 25;
var ITEM_HEIGHT = 36;
module.exports = React.createClass({
- displayName: "MentionList",
+ displayName: 'MentionList',
componentDidMount: function() {
- PostStore.addMentionDataChangeListener(this._onChange);
+ PostStore.addMentionDataChangeListener(this.onListenerChange);
var self = this;
- $('body').on('keydown.mentionlist', '#'+this.props.id,
+ $('body').on('keydown.mentionlist', '#' + this.props.id,
function(e) {
- if (!self.isEmpty() && self.state.mentionText != '-1' && (e.which === 13 || e.which === 9)) {
+ if (!self.isEmpty() && self.state.mentionText !== '-1' && (e.which === 13 || e.which === 9)) {
e.stopPropagation();
e.preventDefault();
self.addCurrentMention();
- }
- else if (!self.isEmpty() && self.state.mentionText != '-1' && (e.which === 38 || e.which === 40)) {
+ } else if (!self.isEmpty() && self.state.mentionText !== '-1' && (e.which === 38 || e.which === 40)) {
e.stopPropagation();
e.preventDefault();
- var tempSelectedMention = -1;
- if (e.which === 38) {
- if (self.getSelection(self.state.selectedMention - 1))
- self.setState({ selectedMention: self.state.selectedMention - 1, selectedUsername: self.refs['mention' + (self.state.selectedMention - 1)].props.username });
- else {
- while (self.getSelection(++tempSelectedMention))
- ; //Need to find the top of the list
- self.setState({ selectedMention: tempSelectedMention - 1, selectedUsername: self.refs['mention' + (tempSelectedMention - 1)].props.username });
+ if (e.which === 38) {
+ if (self.getSelection(self.state.selectedMention - 1)) {
+ self.setState({selectedMention: self.state.selectedMention - 1, selectedUsername: self.refs['mention' + (self.state.selectedMention - 1)].props.username});
+ }
+ } else if (e.which === 40) {
+ if (self.getSelection(self.state.selectedMention + 1)) {
+ self.setState({selectedMention: self.state.selectedMention + 1, selectedUsername: self.refs['mention' + (self.state.selectedMention + 1)].props.username});
}
- }
- else if (e.which === 40) {
- if (self.getSelection(self.state.selectedMention + 1))
- self.setState({ selectedMention: self.state.selectedMention + 1, selectedUsername: self.refs['mention' + (self.state.selectedMention + 1)].props.username });
- else
- self.setState({ selectedMention: 0, selectedUsername: self.refs.mention0.props.username });
}
- self.scrollToMention(e.which, tempSelectedMention);
+ self.scrollToMention(e.which);
}
}
);
$(document).click(function(e) {
- if (!($('#'+self.props.id).is(e.target) || $('#'+self.props.id).has(e.target).length ||
- ('mentionlist' in self.refs && $(self.refs['mentionlist'].getDOMNode()).has(e.target).length))) {
- self.setState({mentionText: "-1"})
+ if (!($('#' + self.props.id).is(e.target) || $('#' + self.props.id).has(e.target).length ||
+ ('mentionlist' in self.refs && $(self.refs.mentionlist.getDOMNode()).has(e.target).length))) {
+ self.setState({mentionText: '-1'});
}
});
},
componentWillUnmount: function() {
- PostStore.removeMentionDataChangeListener(this._onChange);
- $('body').off('keydown.mentionlist', '#'+this.props.id);
+ PostStore.removeMentionDataChangeListener(this.onListenerChange);
+ $('body').off('keydown.mentionlist', '#' + this.props.id);
},
componentDidUpdate: function() {
- if (this.state.mentionText != "-1") {
- if (this.state.selectedUsername !== "" && (!this.getSelection(this.state.selectedMention) || this.state.selectedUsername !== this.refs['mention' + this.state.selectedMention].props.username)) {
+ if (this.state.mentionText !== '-1') {
+ if (this.state.selectedUsername !== '' && (!this.getSelection(this.state.selectedMention) || this.state.selectedUsername !== this.refs['mention' + this.state.selectedMention].props.username)) {
var tempSelectedMention = -1;
var foundMatch = false;
while (tempSelectedMention < this.state.selectedMention && this.getSelection(++tempSelectedMention)) {
if (this.state.selectedUsername === this.refs['mention' + tempSelectedMention].props.username) {
- this.setState({ selectedMention: tempSelectedMention });
+ this.setState({selectedMention: tempSelectedMention});
foundMatch = true;
break;
}
}
if (this.getSelection(0) && !foundMatch) {
- this.setState({ selectedMention: 0, selectedUsername: this.refs.mention0.props.username });
+ this.setState({selectedMention: 0, selectedUsername: this.refs.mention0.props.username});
}
}
- }
- else if (this.state.selectedMention !== 0) {
- this.setState({ selectedMention: 0, selectedUsername: "" });
+ } else if (this.state.selectedMention !== 0) {
+ this.setState({selectedMention: 0, selectedUsername: ''});
}
},
- _onChange: function(id, mentionText, excludeList) {
- if (id !== this.props.id) return;
+ onListenerChange: function(id, mentionText, excludeList) {
+ if (id !== this.props.id) {
+ return;
+ }
var newState = this.state;
- if (mentionText != null) newState.mentionText = mentionText;
- if (excludeList != null) newState.excludeUsers = excludeList;
+ if (mentionText != null) {
+ newState.mentionText = mentionText;
+ }
+ if (excludeList != null) {
+ newState.excludeUsers = excludeList;
+ }
this.setState(newState);
},
@@ -100,44 +97,49 @@ module.exports = React.createClass({
username: name
});
- this.setState({ mentionText: '-1' });
+ this.setState({mentionText: '-1'});
},
handleMouseEnter: function(listId) {
- this.setState({ selectedMention: listId, selectedUsername: this.refs['mention' + listId].props.username });
+ this.setState({selectedMention: listId, selectedUsername: this.refs['mention' + listId].props.username});
},
getSelection: function(listId) {
- if (!this.refs['mention' + listId])
+ if (!this.refs['mention' + listId]) {
return false;
- else
- return true;
+ }
+ return true;
},
addCurrentMention: function() {
- if (!this.getSelection(this.state.selectedMention))
+ if (!this.getSelection(this.state.selectedMention)) {
this.addFirstMention();
- else
+ } else {
this.refs['mention' + this.state.selectedMention].handleClick();
+ }
},
addFirstMention: function() {
- if (!this.refs.mention0) return;
+ if (!this.refs.mention0) {
+ return;
+ }
this.refs.mention0.handleClick();
},
isEmpty: function() {
return (!this.refs.mention0);
},
- scrollToMention: function(keyPressed, ifLoopUp) {
- var direction = keyPressed === 38 ? "up" : "down";
+ scrollToMention: function(keyPressed) {
+ var direction;
+ if (keyPressed === 38) {
+ direction = 'up';
+ } else {
+ direction = 'down';
+ }
var scrollAmount = 0;
- if (direction === "up" && ifLoopUp !== -1)
- scrollAmount = $("#mentionsbox").height() * 100; //Makes sure that it scrolls all the way to the bottom
- else if (direction === "down" && this.state.selectedMention === 0)
- scrollAmount = 0;
- else if (direction === "up")
- scrollAmount = "-=" + ($('#'+this.refs['mention' + this.state.selectedMention].props.id +"_mentions").innerHeight() - 5);
- else if (direction === "down")
- scrollAmount = "+=" + ($('#'+this.refs['mention' + this.state.selectedMention].props.id +"_mentions").innerHeight() - 5);
+ if (direction === 'up') {
+ scrollAmount = '-=' + ($('#' + this.refs['mention' + this.state.selectedMention].props.id + '_mentions').innerHeight() - 5);
+ } else if (direction === 'down') {
+ scrollAmount = '+=' + ($('#' + this.refs['mention' + this.state.selectedMention].props.id + '_mentions').innerHeight() - 5);
+ }
- $("#mentionsbox").animate({
+ $('#mentionsbox').animate({
scrollTop: scrollAmount
}, 75);
},
@@ -151,12 +153,14 @@ module.exports = React.createClass({
return false;
},
getInitialState: function() {
- return { excludeUsers: [], mentionText: "-1", selectedMention: 0, selectedUsername: "" };
+ return {excludeUsers: [], mentionText: '-1', selectedMention: 0, selectedUsername: ''};
},
render: function() {
var self = this;
var mentionText = this.state.mentionText;
- if (mentionText === '-1') return null;
+ if (mentionText === '-1') {
+ return null;
+ }
var profiles = UserStore.getActiveOnlyProfiles();
var users = [];
@@ -165,32 +169,38 @@ module.exports = React.createClass({
}
var all = {};
- all.username = "all";
- all.nickname = "";
- all.secondary_text = "Notifies everyone in the team";
- all.id = "allmention";
+ all.username = 'all';
+ all.nickname = '';
+ all.secondary_text = 'Notifies everyone in the team';
+ all.id = 'allmention';
users.push(all);
var channel = {};
- channel.username = "channel";
- channel.nickname = "";
- channel.secondary_text = "Notifies everyone in the channel";
- channel.id = "channelmention";
+ channel.username = 'channel';
+ channel.nickname = '';
+ channel.secondary_text = 'Notifies everyone in the channel';
+ channel.id = 'channelmention';
users.push(channel);
- users.sort(function(a,b) {
- if (a.username < b.username) return -1;
- if (a.username > b.username) return 1;
+ users.sort(function(a, b) {
+ if (a.username < b.username) {
+ return -1;
+ }
+ if (a.username > b.username) {
+ return 1;
+ }
return 0;
});
var mentions = {};
var index = 0;
for (var i = 0; i < users.length && index < MAX_ITEMS_IN_LIST; i++) {
- if (this.alreadyMentioned(users[i].username)) continue;
-
- if ((users[i].first_name && users[i].first_name.lastIndexOf(mentionText,0) === 0)
- || (users[i].last_name && users[i].last_name.lastIndexOf(mentionText,0) === 0) || users[i].username.lastIndexOf(mentionText,0) === 0) {
+ if (this.alreadyMentioned(users[i].username)) {
+ continue;
+ }
+ if ((users[i].first_name && users[i].first_name.lastIndexOf(mentionText, 0) === 0) ||
+ (users[i].last_name && users[i].last_name.lastIndexOf(mentionText, 0) === 0) ||
+ users[i].username.lastIndexOf(mentionText, 0) === 0) {
mentions[index] = (
<Mention
ref={'mention' + index}
@@ -198,7 +208,7 @@ module.exports = React.createClass({
secondary_text={Utils.getFullName(users[i])}
id={users[i].id}
listId={index}
- isFocused={this.state.selectedMention === index ? "mentions-focus" : ""}
+ isFocused={this.state.selectedMention === index ? 'mentions-focus' : ''}
handleMouseEnter={function(value) { return function() { self.handleMouseEnter(value); } }(index)}
handleClick={this.handleClick} />
);
@@ -208,21 +218,23 @@ module.exports = React.createClass({
var numMentions = Object.keys(mentions).length;
- if (numMentions < 1) return null;
+ if (numMentions < 1) {
+ return null;
+ }
- var $mention_tab = $('#'+this.props.id);
- var maxHeight = Math.min(MAX_HEIGHT_LIST, $mention_tab.offset().top - 10);
+ var $mentionTab = $('#' + this.props.id);
+ var maxHeight = Math.min(MAX_HEIGHT_LIST, $mentionTab.offset().top - 10);
var style = {
- height: Math.min(maxHeight, (numMentions*ITEM_HEIGHT) + 4),
- width: $mention_tab.parent().width(),
- bottom: $(window).height() - $mention_tab.offset().top,
- left: $mention_tab.offset().left
+ height: Math.min(maxHeight, (numMentions * ITEM_HEIGHT) + 4),
+ width: $mentionTab.parent().width(),
+ bottom: $(window).height() - $mentionTab.offset().top,
+ left: $mentionTab.offset().left
};
return (
- <div className="mentions--top" style={style}>
- <div ref="mentionlist" className="mentions-box" id="mentionsbox">
- { mentions }
+ <div className='mentions--top' style={style}>
+ <div ref='mentionlist' className='mentions-box' id='mentionsbox'>
+ {mentions}
</div>
</div>
);
diff --git a/web/react/components/new_channel.jsx b/web/react/components/new_channel.jsx
index 49e088458..93884f6eb 100644
--- a/web/react/components/new_channel.jsx
+++ b/web/react/components/new_channel.jsx
@@ -1,138 +1,146 @@
// Copyright (c) 2015 Spinpunch, Inc. All Rights Reserved.
// See License.txt for license information.
-
var utils = require('../utils/utils.jsx');
var client = require('../utils/client.jsx');
var asyncClient = require('../utils/async_client.jsx');
var UserStore = require('../stores/user_store.jsx');
var TeamStore = require('../stores/team_store.jsx');
-var Constants = require('../utils/constants.jsx');
module.exports = React.createClass({
+ displayName: 'NewChannelModal',
handleSubmit: function(e) {
e.preventDefault();
var channel = {};
- var state = { server_error: "" };
+ var state = {serverError: ''};
channel.display_name = this.refs.display_name.getDOMNode().value.trim();
if (!channel.display_name) {
- state.display_name_error = "This field is required";
+ state.displayNameError = 'This field is required';
state.inValid = true;
- }
- else if (channel.display_name.length > 22) {
- state.display_name_error = "This field must be less than 22 characters";
+ } else if (channel.display_name.length > 22) {
+ state.displayNameError = 'This field must be less than 22 characters';
state.inValid = true;
- }
- else {
- state.display_name_error = "";
+ } else {
+ state.displayNameError = '';
}
channel.name = this.refs.channel_name.getDOMNode().value.trim();
if (!channel.name) {
- state.name_error = "This field is required";
+ state.nameError = 'This field is required';
state.inValid = true;
- }
- else if(channel.name.length > 22){
- state.name_error = "This field must be less than 22 characters";
+ } else if (channel.name.length > 22) {
+ state.nameError = 'This field must be less than 22 characters';
state.inValid = true;
- }
- else {
- var cleaned_name = utils.cleanUpUrlable(channel.name);
- if (cleaned_name != channel.name) {
- state.name_error = "Must be lowercase alphanumeric characters, allowing '-' but not starting or ending with '-'";
+ } else {
+ var cleanedName = utils.cleanUpUrlable(channel.name);
+ if (cleanedName !== channel.name) {
+ state.nameError = "Must be lowercase alphanumeric characters, allowing '-' but not starting or ending with '-'";
state.inValid = true;
- }
- else {
- state.name_error = "";
+ } else {
+ state.nameError = '';
}
}
this.setState(state);
- if (state.inValid)
+ if (state.inValid) {
return;
+ }
var cu = UserStore.getCurrentUser();
channel.team_id = cu.team_id;
channel.description = this.refs.channel_desc.getDOMNode().value.trim();
- channel.type = this.state.channel_type;
+ channel.type = this.state.channelType;
var self = this;
client.createChannel(channel,
function() {
- this.refs.display_name.getDOMNode().value = "";
- this.refs.channel_name.getDOMNode().value = "";
- this.refs.channel_desc.getDOMNode().value = "";
+ this.refs.display_name.getDOMNode().value = '';
+ this.refs.channel_name.getDOMNode().value = '';
+ this.refs.channel_desc.getDOMNode().value = '';
$(self.refs.modal.getDOMNode()).modal('hide');
- window.location = TeamStore.getCurrentTeamUrl() + "/channels/" + channel.name;
+ window.location = TeamStore.getCurrentTeamUrl() + '/channels/' + channel.name;
asyncClient.getChannels(true);
}.bind(this),
function(err) {
- state.server_error = err.message;
+ state.serverError = err.message;
state.inValid = true;
this.setState(state);
}.bind(this)
);
},
- displayNameKeyUp: function(e) {
- var display_name = this.refs.display_name.getDOMNode().value.trim();
- var channel_name = utils.cleanUpUrlable(display_name);
- this.refs.channel_name.getDOMNode().value = channel_name;
+ displayNameKeyUp: function() {
+ var displayName = this.refs.display_name.getDOMNode().value.trim();
+ var channelName = utils.cleanUpUrlable(displayName);
+ this.refs.channel_name.getDOMNode().value = channelName;
},
componentDidMount: function() {
var self = this;
$(this.refs.modal.getDOMNode()).on('show.bs.modal', function(e) {
var button = e.relatedTarget;
- self.setState({ channel_type: $(button).attr('data-channeltype') });
+ self.setState({channelType: $(button).attr('data-channeltype')});
});
},
getInitialState: function() {
- return { channel_type: "" };
+ return {channelType: ''};
},
render: function() {
+ var displayNameError = null;
+ var nameError = null;
+ var serverError = null;
+ var displayNameClass = 'form-group';
+ var nameClass = 'form-group';
- var display_name_error = this.state.display_name_error ? <label className='control-label'>{ this.state.display_name_error }</label> : null;
- var name_error = this.state.name_error ? <label className='control-label'>{ this.state.name_error }</label> : null;
- var server_error = this.state.server_error ? <div className='form-group has-error'><label className='control-label'>{ this.state.server_error }</label></div> : null;
+ if (this.state.displayNameError) {
+ displayNameError = <label className='control-label'>{this.state.displayNameError}</label>;
+ displayNameClass += ' has-error';
+ }
+ if (this.state.nameError) {
+ nameError = <label className='control-label'>{this.state.nameError}</label>;
+ nameClass += ' has-error';
+ }
+ if (this.state.serverError) {
+ serverError = <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div>;
+ }
return (
- <div className="modal fade" id="new_channel" ref="modal" tabIndex="-1" role="dialog" aria-hidden="true">
- <div className="modal-dialog">
- <div className="modal-content">
- <div className="modal-header">
- <button type="button" className="close" data-dismiss="modal">
- <span aria-hidden="true">&times;</span>
- <span className="sr-only">Close</span>
+ <div className='modal fade' id='new_channel' ref='modal' tabIndex='-1' role='dialog' aria-hidden='true'>
+ <div className='modal-dialog'>
+ <div className='modal-content'>
+ <div className='modal-header'>
+ <button type='button' className='close' data-dismiss='modal'>
+ <span aria-hidden='true'>&times;</span>
+ <span className='sr-only'>Cancel</span>
</button>
- <h4 className="modal-title">New Channel</h4>
+ <h4 className='modal-title'>New Channel</h4>
</div>
- <div className="modal-body">
- <form role="form">
- <div className={ this.state.display_name_error ? "form-group has-error" : "form-group" }>
+ <form role='form'>
+ <div className='modal-body'>
+ <div className={displayNameClass}>
<label className='control-label'>Display Name</label>
- <input onKeyUp={this.displayNameKeyUp} type="text" ref="display_name" className="form-control" placeholder="Enter display name" maxLength="64" />
- { display_name_error }
+ <input onKeyUp={this.displayNameKeyUp} type='text' ref='display_name' className='form-control' placeholder='Enter display name' maxLength='64' />
+ {displayNameError}
</div>
- <div className={ this.state.name_error ? "form-group has-error" : "form-group" }>
+ <div className={nameClass}>
<label className='control-label'>Handle</label>
- <input type="text" className="form-control" ref="channel_name" placeholder="lowercase alphanumeric's only" maxLength="64" />
- { name_error }
+ <input type='text' className='form-control' ref='channel_name' placeholder="lowercase alphanumeric's only" maxLength='64' />
+ {nameError}
</div>
- <div className="form-group">
+ <div className='form-group'>
<label className='control-label'>Description</label>
- <textarea className="form-control no-resize" ref="channel_desc" rows="3" placeholder="Description" maxLength="1024"></textarea>
+ <textarea className='form-control no-resize' ref='channel_desc' rows='3' placeholder='Description' maxLength='1024'></textarea>
</div>
- { server_error }
- </form>
- </div>
- <div className="modal-footer">
- <button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
- <button onClick={this.handleSubmit} type="button" className="btn btn-primary">Create New Channel</button>
- </div>
+ {serverError}
+ </div>
+ <div className='modal-footer'>
+ <button type='button' className='btn btn-default' data-dismiss='modal'>Cancel</button>
+ <button onClick={this.handleSubmit} type='submit' className='btn btn-primary'>Create New Channel</button>
+ </div>
+ </form>
</div>
</div>
</div>
diff --git a/web/react/components/signup_team_complete.jsx b/web/react/components/signup_team_complete.jsx
index 447a405bd..3f35a5912 100644
--- a/web/react/components/signup_team_complete.jsx
+++ b/web/react/components/signup_team_complete.jsx
@@ -248,6 +248,8 @@ TeamURLPage = React.createClass({
},
render: function() {
+ $('body').tooltip( {selector: '[data-toggle=tooltip]', trigger: 'hover click'} );
+
client.track('signup', 'signup_team_03_url');
var name_error = this.state.name_error ? <label className="control-label">{ this.state.name_error }</label> : null;
@@ -260,8 +262,8 @@ TeamURLPage = React.createClass({
<div className={ name_error ? "form-group has-error" : "form-group" }>
<div className="row">
<div className="col-sm-11">
- <div className="input-group">
- <span className="input-group-addon">{ utils.getWindowLocationOrigin() + "/" }</span>
+ <div className="input-group input-group--limit">
+ <span data-toggle="tooltip" title={ utils.getWindowLocationOrigin() + "/" } className="input-group-addon">{ utils.getWindowLocationOrigin() + "/" }</span>
<input type="text" ref="name" className="form-control" placeholder="" maxLength="128" defaultValue={this.props.state.team.name} autoFocus={true} onFocus={this.handleFocus}/>
</div>
</div>
diff --git a/web/react/components/team_settings_modal.jsx b/web/react/components/team_settings_modal.jsx
index e50378b7f..b1c38fd16 100644
--- a/web/react/components/team_settings_modal.jsx
+++ b/web/react/components/team_settings_modal.jsx
@@ -29,7 +29,7 @@ module.exports = React.createClass({
tabs.push({name: "feature", ui_name: "Features", icon: "glyphicon glyphicon-wrench"});
return (
- <div className="modal fade" ref="modal" id="team_settings" role="dialog" aria-hidden="true">
+ <div className="modal fade" ref="modal" id="team_settings" role="dialog" tabIndex="-1" aria-hidden="true">
<div className="modal-dialog settings-modal">
<div className="modal-content">
<div className="modal-header">
diff --git a/web/react/components/user_settings_modal.jsx b/web/react/components/user_settings_modal.jsx
index d1aff74f2..702e7ad7a 100644
--- a/web/react/components/user_settings_modal.jsx
+++ b/web/react/components/user_settings_modal.jsx
@@ -32,7 +32,7 @@ module.exports = React.createClass({
tabs.push({name: "appearance", ui_name: "Appearance", icon: "glyphicon glyphicon-wrench"});
return (
- <div className="modal fade" ref="modal" id="user_settings1" role="dialog" aria-hidden="true">
+ <div className="modal fade" ref="modal" id="user_settings1" role="dialog" tabIndex="-1" aria-hidden="true">
<div className="modal-dialog settings-modal">
<div className="modal-content">
<div className="modal-header">