summaryrefslogtreecommitdiffstats
path: root/web/react
diff options
context:
space:
mode:
Diffstat (limited to 'web/react')
-rw-r--r--web/react/components/access_history_modal.jsx64
-rw-r--r--web/react/components/activity_log_modal.jsx17
-rw-r--r--web/react/components/channel_header.jsx12
-rw-r--r--web/react/components/delete_channel_modal.jsx2
-rw-r--r--web/react/components/edit_channel_modal.jsx2
-rw-r--r--web/react/components/email_verify.jsx2
-rw-r--r--web/react/components/invite_member_modal.jsx2
-rw-r--r--web/react/components/post_list.jsx7
-rw-r--r--web/react/components/rename_channel_modal.jsx4
-rw-r--r--web/react/components/rename_team_modal.jsx2
-rw-r--r--web/react/components/search_bar.jsx11
-rw-r--r--web/react/components/setting_picture.jsx30
-rw-r--r--web/react/components/sidebar_header.jsx23
-rw-r--r--web/react/components/signup_team_complete.jsx44
-rw-r--r--web/react/components/signup_user_complete.jsx8
-rw-r--r--web/react/components/user_settings.jsx25
-rw-r--r--web/react/pages/verify.jsx6
-rw-r--r--web/react/stores/user_store.jsx4
-rw-r--r--web/react/utils/utils.jsx14
19 files changed, 170 insertions, 109 deletions
diff --git a/web/react/components/access_history_modal.jsx b/web/react/components/access_history_modal.jsx
index 462f046f6..16768a119 100644
--- a/web/react/components/access_history_modal.jsx
+++ b/web/react/components/access_history_modal.jsx
@@ -3,7 +3,8 @@
var UserStore = require('../stores/user_store.jsx');
var AsyncClient = require('../utils/async_client.jsx');
-var Utils = require('../utils/utils.jsx');
+var LoadingScreen = require('./loading_screen.jsx');
+var utils = require('../utils/utils.jsx');
function getStateFromStoresForAudits() {
return {
@@ -14,23 +15,28 @@ function getStateFromStoresForAudits() {
module.exports = React.createClass({
componentDidMount: function() {
UserStore.addAuditsChangeListener(this._onChange);
- AsyncClient.getAudits();
+ $(this.refs.modal.getDOMNode()).on('shown.bs.modal', function(e) {
+ AsyncClient.getAudits();
+ });
var self = this;
$(this.refs.modal.getDOMNode()).on('hidden.bs.modal', function(e) {
- self.setState({ moreInfo: [] });
+ self.setState({moreInfo: []});
});
},
componentWillUnmount: function() {
UserStore.removeAuditsChangeListener(this._onChange);
},
_onChange: function() {
- this.setState(getStateFromStoresForAudits());
+ var newState = getStateFromStoresForAudits();
+ if (!utils.areStatesEqual(newState.audits, this.state.audits)) {
+ this.setState(newState);
+ }
},
handleMoreInfo: function(index) {
var newMoreInfo = this.state.moreInfo;
newMoreInfo[index] = true;
- this.setState({ moreInfo: newMoreInfo });
+ this.setState({moreInfo: newMoreInfo});
},
getInitialState: function() {
var initialState = getStateFromStoresForAudits();
@@ -51,24 +57,28 @@ module.exports = React.createClass({
newDate = (<div> {currentHistoryDate.toDateString()} </div>);
}
+ if (!currentAudit.session_id && currentAudit.action.search('/users/login') !== -1) {
+ currentAudit.session_id = 'N/A (Login attempt)';
+ }
+
accessList[i] = (
- <div className="access-history__table">
- <div className="access__date">{newDate}</div>
- <div className="access__report">
- <div className="report__time">{newHistoryDate.toLocaleTimeString(navigator.language, {hour: '2-digit', minute:'2-digit'})}</div>
- <div className="report__info">
- <div>{"IP: " + currentAudit.ip_address}</div>
- { this.state.moreInfo[i] ?
+ <div className='access-history__table'>
+ <div className='access__date'>{newDate}</div>
+ <div className='access__report'>
+ <div className='report__time'>{newHistoryDate.toLocaleTimeString(navigator.language, {hour: '2-digit', minute: '2-digit'})}</div>
+ <div className='report__info'>
+ <div>{'IP: ' + currentAudit.ip_address}</div>
+ {this.state.moreInfo[i] ?
<div>
- <div>{"Session ID: " + currentAudit.session_id}</div>
- <div>{"URL: " + currentAudit.action.replace("/api/v1", "")}</div>
+ <div>{'Session ID: ' + currentAudit.session_id}</div>
+ <div>{'URL: ' + currentAudit.action.replace(/\/api\/v[1-9]/, '')}</div>
</div>
:
- <a href="#" className="theme" onClick={this.handleMoreInfo.bind(this, i)}>More info</a>
+ <a href='#' className='theme' onClick={this.handleMoreInfo.bind(this, i)}>More info</a>
}
</div>
{i < this.state.audits.length - 1 ?
- <div className="divider-light"/>
+ <div className='divider-light'/>
:
null
}
@@ -79,17 +89,21 @@ module.exports = React.createClass({
return (
<div>
- <div className="modal fade" ref="modal" id="access-history" tabIndex="-1" role="dialog" aria-hidden="true">
- <div className="modal-dialog modal-lg">
- <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">Access History</h4>
+ <div className='modal fade' ref='modal' id='access-history' tabIndex='-1' role='dialog' aria-hidden='true'>
+ <div className='modal-dialog modal-lg'>
+ <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'>Access History</h4>
</div>
- <div ref="modalBody" className="modal-body">
- <form role="form">
- { accessList }
+ <div ref='modalBody' className='modal-body'>
+ {!this.state.audits.loading ?
+ <form role='form'>
+ {accessList}
</form>
+ :
+ <LoadingScreen />
+ }
</div>
</div>
</div>
diff --git a/web/react/components/activity_log_modal.jsx b/web/react/components/activity_log_modal.jsx
index 90f139e8b..f28f0d5f1 100644
--- a/web/react/components/activity_log_modal.jsx
+++ b/web/react/components/activity_log_modal.jsx
@@ -4,6 +4,8 @@
var UserStore = require('../stores/user_store.jsx');
var Client = require('../utils/client.jsx');
var AsyncClient = require('../utils/async_client.jsx');
+var LoadingScreen = require('./loading_screen.jsx');
+var utils = require('../utils/utils.jsx');
function getStateFromStoresForSessions() {
return {
@@ -29,7 +31,9 @@ module.exports = React.createClass({
},
componentDidMount: function() {
UserStore.addSessionsChangeListener(this._onChange);
- AsyncClient.getSessions();
+ $(this.refs.modal.getDOMNode()).on('shown.bs.modal', function (e) {
+ AsyncClient.getSessions();
+ });
var self = this;
$(this.refs.modal.getDOMNode()).on('hidden.bs.modal', function(e) {
@@ -40,7 +44,10 @@ module.exports = React.createClass({
UserStore.removeSessionsChangeListener(this._onChange);
},
_onChange: function() {
- this.setState(getStateFromStoresForSessions());
+ var newState = getStateFromStoresForSessions();
+ if (!utils.areStatesEqual(newState.sessions, this.state.sessions)) {
+ this.setState(newState);
+ }
},
handleMoreInfo: function(index) {
var newMoreInfo = this.state.moreInfo;
@@ -106,10 +113,16 @@ module.exports = React.createClass({
</div>
<p className="session-help-text">Sessions are created when you log in with your email and password to a new browser on a device. Sessions let you use Mattermost for up to 30 days without having to log in again. If you want to log out sooner, use the "Logout" button below to end a session.</p>
<div ref="modalBody" className="modal-body">
+ { !this.state.sessions.loading ?
+ <div>
<form role="form">
{ activityList }
</form>
{ server_error }
+ </div>
+ :
+ <LoadingScreen />
+ }
</div>
</div>
</div>
diff --git a/web/react/components/channel_header.jsx b/web/react/components/channel_header.jsx
index 7a129f200..76dbe370b 100644
--- a/web/react/components/channel_header.jsx
+++ b/web/react/components/channel_header.jsx
@@ -153,7 +153,7 @@ module.exports = React.createClass({
if (isDirect) {
if (this.state.users.length > 1) {
var contact = this.state.users[((this.state.users[0].id === currentId) ? 1 : 0)];
- channelTitle = <UserProfile userId={contact.id} overwriteName={contact.nickname || contact.username} />;
+ channelTitle = contact.nickname || contact.username;
}
}
@@ -161,13 +161,13 @@ module.exports = React.createClass({
<table className="channel-header alt">
<tr>
<th>
- { !isDirect ?
<div className="channel-header__info">
<div className="dropdown">
<a href="#" className="dropdown-toggle theme" type="button" id="channel_header_dropdown" data-toggle="dropdown" aria-expanded="true">
<strong className="heading">{channelTitle} </strong>
<span className="glyphicon glyphicon-chevron-down header-dropdown__icon"></span>
</a>
+ { !isDirect ?
<ul className="dropdown-menu" role="menu" aria-labelledby="channel_header_dropdown">
<li role="presentation"><a role="menuitem" data-toggle="modal" data-target="#channel_info" data-channelid={channel.id} href="#">View Info</a></li>
{ !ChannelStore.isDefault(channel) ?
@@ -193,12 +193,14 @@ module.exports = React.createClass({
: null
}
</ul>
+ :
+ <ul className="dropdown-menu" role="menu" aria-labelledby="channel_header_dropdown">
+ <li role="presentation"><a role="menuitem" href="#" data-toggle="modal" data-target="#edit_channel" data-desc={channel.description} data-title={channel.display_name} data-channelid={channel.id}>Set Channel Description...</a></li>
+ </ul>
+ }
</div>
<div data-toggle="popover" data-content={popoverContent} className="description">{description}</div>
</div>
- :
- <a href="#"><strong className="heading">{channelTitle}</strong></a>
- }
</th>
<th><PopoverListMembers members={this.state.users} channelId={channel.id} /></th>
<th className="search-bar__container"><NavbarSearchBox /></th>
diff --git a/web/react/components/delete_channel_modal.jsx b/web/react/components/delete_channel_modal.jsx
index e23a37740..64ceec450 100644
--- a/web/react/components/delete_channel_modal.jsx
+++ b/web/react/components/delete_channel_modal.jsx
@@ -47,7 +47,7 @@ module.exports = React.createClass({
</p>
</div>
<div className="modal-footer">
- <button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
+ <button type="button" className="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" className="btn btn-danger" data-dismiss="modal" onClick={this.handleDelete}>Delete</button>
</div>
</div>
diff --git a/web/react/components/edit_channel_modal.jsx b/web/react/components/edit_channel_modal.jsx
index a35a531b5..1b0cc185f 100644
--- a/web/react/components/edit_channel_modal.jsx
+++ b/web/react/components/edit_channel_modal.jsx
@@ -63,7 +63,7 @@ module.exports = React.createClass({
{ server_error }
</div>
<div className="modal-footer">
- <button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
+ <button type="button" className="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" className="btn btn-primary" onClick={this.handleEdit}>Save</button>
</div>
</div>
diff --git a/web/react/components/email_verify.jsx b/web/react/components/email_verify.jsx
index 168608274..678eb9928 100644
--- a/web/react/components/email_verify.jsx
+++ b/web/react/components/email_verify.jsx
@@ -11,7 +11,7 @@ module.exports = React.createClass({
var resend = "";
if (this.props.isVerified === "true") {
title = config.SiteName + " Email Verified";
- body = <p>Your email has been verified! Click <a href="/">here</a> to log in.</p>;
+ body = <p>Your email has been verified! Click <a href={this.props.teamURL + "?email=" + this.props.userEmail}>here</a> to log in.</p>;
} else {
title = config.SiteName + " Email Not Verified";
body = <p>Please verify your email address. Check your inbox for an email.</p>;
diff --git a/web/react/components/invite_member_modal.jsx b/web/react/components/invite_member_modal.jsx
index 94be2acd6..fed96b50a 100644
--- a/web/react/components/invite_member_modal.jsx
+++ b/web/react/components/invite_member_modal.jsx
@@ -212,7 +212,7 @@ module.exports = React.createClass({
<span>People invited automatically join Town Square channel.</span>
</div>
<div className="modal-footer">
- <button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
+ <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>
diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx
index 8dc5013ca..46f77660d 100644
--- a/web/react/components/post_list.jsx
+++ b/web/react/components/post_list.jsx
@@ -309,12 +309,15 @@ module.exports = React.createClass({
var more_messages = <p className="beginning-messages-text">Beginning of Channel</p>;
+ var userStyle = { color: UserStore.getCurrentUser().props.theme }
+
if (channel != null) {
if (order.length > 0 && order.length % Constants.POST_CHUNK_SIZE === 0) {
more_messages = <a ref="loadmore" className="more-messages-text theme" href="#" onClick={this.getMorePosts}>Load more messages</a>;
} else if (channel.type === 'D') {
var teammate = utils.getDirectTeammate(channel.id)
+
if (teammate) {
var teammate_name = teammate.nickname.length > 0 ? teammate.nickname : teammate.username;
more_messages = (
@@ -329,6 +332,7 @@ module.exports = React.createClass({
{"This is the start of your private message history with " + teammate_name + "." }<br/>
{"Private messages and files shared here are not shown to people outside this area."}
</p>
+ <a className="intro-links" href="#" style={userStyle} data-toggle="modal" data-target="#edit_channel" data-desc={channel.description} data-title={channel.display_name} data-channelid={channel.id}><i className="fa fa-pencil"></i>Set a description</a>
</div>
);
} else {
@@ -342,7 +346,6 @@ module.exports = React.createClass({
var ui_name = channel.display_name
var members = ChannelStore.getCurrentExtraInfo().members;
var creator_name = "";
- var userStyle = { color: UserStore.getCurrentUser().props.theme }
for (var i = 0; i < members.length; i++) {
if (members[i].roles.indexOf('admin') > -1) {
@@ -374,7 +377,7 @@ module.exports = React.createClass({
<div className="channel-intro">
<h4 className="channel-intro__title">Beginning of {ui_name}</h4>
<p className="channel-intro__content">
- {"This is the start of " + ui_name + ", a channel for conversations you’d prefer out of more focused channels."}
+ {"This is the start of " + ui_name + ", a channel for non-work-related conversations."}
<br/>
</p>
<a className="intro-links" href="#" style={userStyle} data-toggle="modal" data-target="#edit_channel" data-desc={channel.description} data-title={ui_name} data-channelid={channel.id}><i className="fa fa-pencil"></i>Set a description</a>
diff --git a/web/react/components/rename_channel_modal.jsx b/web/react/components/rename_channel_modal.jsx
index 9e4a25f85..26593b7fa 100644
--- a/web/react/components/rename_channel_modal.jsx
+++ b/web/react/components/rename_channel_modal.jsx
@@ -96,7 +96,7 @@ module.exports = React.createClass({
var self = this;
$(this.refs.modal.getDOMNode()).on('show.bs.modal', function(e) {
var button = $(e.relatedTarget);
- self.setState({ display_name: button.attr('data-display'), title: button.attr('data-name'), channel_id: button.attr('data-channelid') });
+ self.setState({ display_name: button.attr('data-display'), channel_name: button.attr('data-name'), channel_id: button.attr('data-channelid') });
});
$(this.refs.modal.getDOMNode()).on('hidden.bs.modal', this.handleClose);
},
@@ -139,7 +139,7 @@ module.exports = React.createClass({
</form>
</div>
<div className="modal-footer">
- <button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
+ <button type="button" className="btn btn-default" data-dismiss="modal">Cancel</button>
<button onClick={this.handleSubmit} type="button" className="btn btn-primary">Save</button>
</div>
</div>
diff --git a/web/react/components/rename_team_modal.jsx b/web/react/components/rename_team_modal.jsx
index dfd775a3b..bebdd6662 100644
--- a/web/react/components/rename_team_modal.jsx
+++ b/web/react/components/rename_team_modal.jsx
@@ -83,7 +83,7 @@ module.exports = React.createClass({
</form>
</div>
<div className="modal-footer">
- <button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
+ <button type="button" className="btn btn-default" data-dismiss="modal">Cancel</button>
<button onClick={this.handleSubmit} type="button" className="btn btn-primary">Save</button>
</div>
</div>
diff --git a/web/react/components/search_bar.jsx b/web/react/components/search_bar.jsx
index f21f0cd58..e39cf5d46 100644
--- a/web/react/components/search_bar.jsx
+++ b/web/react/components/search_bar.jsx
@@ -36,6 +36,9 @@ module.exports = React.createClass({
}
}
},
+ clearFocus: function(e) {
+ $('.search-bar__container').removeClass('focused');
+ },
handleClose: function(e) {
e.preventDefault();
@@ -57,6 +60,7 @@ module.exports = React.createClass({
},
handleUserFocus: function(e) {
e.target.select();
+ $('.search-bar__container').addClass('focused');
},
performSearch: function(terms, isMentionSearch) {
if (terms.length) {
@@ -92,13 +96,14 @@ module.exports = React.createClass({
render: function() {
return (
<div>
- <div className="sidebar__collapse" onClick={this.handleClose}>Cancel</div>
- <span className="glyphicon glyphicon-search sidebar__search-icon"></span>
+ <div className="sidebar__collapse" onClick={this.handleClose}><span className="fa fa-angle-left"></span></div>
+ <span onClick={this.clearFocus} className="search__clear">Cancel</span>
<form role="form" className="search__form relative-div" onSubmit={this.handleSubmit}>
+ <span className="glyphicon glyphicon-search sidebar__search-icon"></span>
<input
type="text"
ref="search"
- className="form-control search-bar-box"
+ className="form-control search-bar"
placeholder="Search"
value={this.state.search_term}
onFocus={this.handleUserFocus}
diff --git a/web/react/components/setting_picture.jsx b/web/react/components/setting_picture.jsx
index 6cfb74d60..fa4c8bb62 100644
--- a/web/react/components/setting_picture.jsx
+++ b/web/react/components/setting_picture.jsx
@@ -7,8 +7,8 @@ module.exports = React.createClass({
var reader = new FileReader();
var img = this.refs.image.getDOMNode();
- reader.onload = function (e) {
- $(img).attr('src', e.target.result)
+ reader.onload = function(e) {
+ $(img).attr('src', e.target.result);
};
reader.readAsDataURL(file);
@@ -25,27 +25,27 @@ module.exports = React.createClass({
var img = null;
if (this.props.picture) {
- img = (<img ref="image" className="profile-img" src=""/>);
+ img = (<img ref='image' className='profile-img' src=''/>);
} else {
- img = (<img ref="image" className="profile-img" src={this.props.src}/>);
+ img = (<img ref='image' className='profile-img' src={this.props.src}/>);
}
var self = this;
return (
- <ul className="section-max">
- <li className="col-xs-12 section-title">{this.props.title}</li>
- <li className="col-xs-offset-3 col-xs-8">
- <ul className="setting-list">
- <li className="setting-list-item">
+ <ul className='section-max'>
+ <li className='col-xs-12 section-title'>{this.props.title}</li>
+ <li className='col-xs-offset-3 col-xs-8'>
+ <ul className='setting-list'>
+ <li className='setting-list-item'>
{img}
</li>
- <li className="setting-list-item">
- { server_error }
- { client_error }
- <span className="btn btn-sm btn-primary btn-file sel-btn">Upload<input ref="input" accept=".jpg,.png,.bmp" type="file" onChange={this.props.pictureChange}/></span>
- <a className={this.props.submitActive ? "btn btn-sm btn-primary" : "btn btn-sm btn-inactive disabled"} onClick={this.props.submit}>Save</a>
- <a className="btn btn-sm theme" href="#" onClick={self.props.updateSection}>Cancel</a>
+ <li className='setting-list-item'>
+ {server_error}
+ {client_error}
+ <span className='btn btn-sm btn-primary btn-file sel-btn'>Select<input ref='input' accept='.jpg,.png,.bmp' type='file' onChange={this.props.pictureChange}/></span>
+ <a className={this.props.submitActive ? 'btn btn-sm btn-primary' : 'btn btn-sm btn-inactive disabled'} onClick={this.props.submit}>Save</a>
+ <a className='btn btn-sm theme' href='#' onClick={self.props.updateSection}>Cancel</a>
</li>
</ul>
</li>
diff --git a/web/react/components/sidebar_header.jsx b/web/react/components/sidebar_header.jsx
index e7512934a..e01ddcd05 100644
--- a/web/react/components/sidebar_header.jsx
+++ b/web/react/components/sidebar_header.jsx
@@ -17,11 +17,20 @@ var NavbarDropdown = React.createClass({
e.preventDefault();
client.logout();
},
+ blockToggle: false,
componentDidMount: function() {
UserStore.addTeamsChangeListener(this._onChange);
+
+ var self = this;
+ $(this.refs.dropdown.getDOMNode()).on('hide.bs.dropdown', function(e) {
+ self.blockToggle = true;
+ setTimeout(function(){self.blockToggle = false;}, 100);
+ });
},
componentWillUnmount: function() {
UserStore.removeTeamsChangeListener(this._onChange);
+
+ $(this.refs.dropdown.getDOMNode()).off('hide.bs.dropdown');
},
_onChange: function() {
if (this.isMounted()) {
@@ -75,7 +84,7 @@ var NavbarDropdown = React.createClass({
return (
<ul className="nav navbar-nav navbar-right">
- <li className="dropdown">
+ <li ref="dropdown" className="dropdown">
<a href="#" className="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
<span className="dropdown__icon" dangerouslySetInnerHTML={{__html: Constants.MENU_ICON }} />
</a>
@@ -107,6 +116,14 @@ module.exports = React.createClass({
};
},
+ toggleDropdown: function(e) {
+ if (this.refs.dropdown.blockToggle) {
+ this.refs.dropdown.blockToggle = false;
+ return;
+ }
+ $('.team__header').find('.dropdown-toggle').dropdown('toggle');
+ },
+
render: function() {
var me = UserStore.getCurrentUser();
@@ -116,7 +133,7 @@ module.exports = React.createClass({
return (
<div className="team__header theme">
- <a className="settings_link" href="#" data-toggle="modal" data-target="#user_settings1">
+ <a href="#" onClick={this.toggleDropdown}>
{ me.last_picture_update ?
<img className="user__picture" src={"/api/v1/users/" + me.id + "/image?time=" + me.update_at} />
:
@@ -127,7 +144,7 @@ module.exports = React.createClass({
<div className="team__name">{ this.props.teamDisplayName }</div>
</div>
</a>
- <NavbarDropdown teamType={this.props.teamType} />
+ <NavbarDropdown ref="dropdown" teamType={this.props.teamType} />
</div>
);
}
diff --git a/web/react/components/signup_team_complete.jsx b/web/react/components/signup_team_complete.jsx
index 21f9edef1..83daa3b1f 100644
--- a/web/react/components/signup_team_complete.jsx
+++ b/web/react/components/signup_team_complete.jsx
@@ -87,7 +87,7 @@ WelcomePage = React.createClass({
<h3 className="sub-heading">Welcome to:</h3>
<h1 className="margin--top-none">{config.SiteName}</h1>
</p>
- <p className="margin--less">Let's setup your new team</p>
+ <p className="margin--less">Let's set up your new team</p>
<p>
Please confirm your email address:<br />
<div className="inner__content">
@@ -271,7 +271,7 @@ TeamURLPage = React.createClass({
<p>{"Choose the web address of your new " + strings.Team + ":"}</p>
<ul className="color--light">
<li>Short and memorable is best</li>
- <li>Use lower case letters, numbers and dashes</li>
+ <li>Use lowercase letters, numbers and dashes</li>
<li>Must start with a letter and can't end in a dash</li>
</ul>
<button type="submit" className="btn btn-primary margin--extra" onClick={this.submitNext}>Next<i className="glyphicon glyphicon-chevron-right"></i></button>
@@ -587,25 +587,23 @@ PasswordPage = React.createClass({
var props = this.props;
- setTimeout(function() {
- $('#sign-up-button').button('reset');
- props.state.wizard = "finished";
- props.updateParent(props.state, true);
-
- window.location.href = utils.getWindowLocationOrigin() + '/' + props.state.team.name + '/login?email=' + encodeURIComponent(teamSignup.team.email);
-
- // client.loginByEmail(teamSignup.team.domain, teamSignup.team.email, teamSignup.user.password,
- // function(data) {
- // TeamStore.setLastName(teamSignup.team.domain);
- // UserStore.setLastEmail(teamSignup.team.email);
- // UserStore.setCurrentUser(data);
- // window.location.href = '/channels/town-square';
- // }.bind(ctl),
- // function(err) {
- // this.setState({name_error: err.message});
- // }.bind(ctl)
- // );
- }, 5000);
+ $('#sign-up-button').button('reset');
+ props.state.wizard = "finished";
+ props.updateParent(props.state, true);
+
+ window.location.href = utils.getWindowLocationOrigin() + '/' + props.state.team.name + '/login?email=' + encodeURIComponent(teamSignup.team.email);
+
+ // client.loginByEmail(teamSignup.team.domain, teamSignup.team.email, teamSignup.user.password,
+ // function(data) {
+ // TeamStore.setLastName(teamSignup.team.domain);
+ // UserStore.setLastEmail(teamSignup.team.email);
+ // UserStore.setCurrentUser(data);
+ // window.location.href = '/channels/town-square';
+ // }.bind(ctl),
+ // function(err) {
+ // this.setState({name_error: err.message});
+ // }.bind(ctl)
+ // );
}.bind(this),
function(err) {
this.setState({server_error: err.message});
@@ -620,8 +618,8 @@ PasswordPage = React.createClass({
client.track('signup', 'signup_team_07_password');
- var password_error = this.state.password_error ? <label className="control-label">{ this.state.password_error }</label> : null;
- var server_error = this.state.server_error ? <label className="control-label">{ this.state.server_error }</label> : null;
+ var password_error = this.state.password_error ? <div className="form-group has-error"><label className="control-label">{ this.state.password_error }</label></div> : 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;
return (
<div>
diff --git a/web/react/components/signup_user_complete.jsx b/web/react/components/signup_user_complete.jsx
index 670aab943..03808e821 100644
--- a/web/react/components/signup_user_complete.jsx
+++ b/web/react/components/signup_user_complete.jsx
@@ -58,7 +58,7 @@ module.exports = React.createClass({
}.bind(this),
function(err) {
if (err.message == "Login failed because email address has not been verified") {
- window.location.href = "/verify_email?email="+ encodeURIComponent(this.state.user.email) + "&domain=" + encodeURIComponent(this.props.teamName);
+ window.location.href = "/verify_email?email="+ encodeURIComponent(this.state.user.email) + "&teamname=" + encodeURIComponent(this.props.teamName);
} else {
this.state.server_error = err.message;
this.setState(this.state);
@@ -107,7 +107,7 @@ module.exports = React.createClass({
<div className={ this.state.original_email == "" ? "margin--extra" : "hidden"} >
<h5><strong>What's your email address?</strong></h5>
<div className={ email_error ? "form-group has-error" : "form-group" }>
- <input type="email" ref="email" className="form-control" defaultValue={ this.state.user.email } placeholder="" maxLength="128" />
+ <input type="email" ref="email" className="form-control" defaultValue={ this.state.user.email } placeholder="" maxLength="128" autoFocus={true} />
{ email_error }
</div>
</div>
@@ -123,6 +123,7 @@ module.exports = React.createClass({
return (
<div>
+ <form>
<img className="signup-team-logo" src="/static/images/logo.png" />
<h5 className="margin--less">Welcome to:</h5>
<h2 className="signup-team__name">{ this.props.teamDisplayName }</h2>
@@ -148,9 +149,10 @@ module.exports = React.createClass({
</div>
</div>
</div>
- <p className="margin--extra"><button onClick={this.handleSubmit} className="btn-primary btn">Create Account</button></p>
+ <p className="margin--extra"><button type='submit' onClick={this.handleSubmit} className="btn-primary btn">Create Account</button></p>
{ server_error }
<p>By creating an account and using Mattermost you are agreeing to our <a href={ config.TermsLink }>Terms of Service</a>. If you do not agree, you cannot use this service.</p>
+ </form>
</div>
);
}
diff --git a/web/react/components/user_settings.jsx b/web/react/components/user_settings.jsx
index e1ae6da52..902989b7b 100644
--- a/web/react/components/user_settings.jsx
+++ b/web/react/components/user_settings.jsx
@@ -465,17 +465,17 @@ var SecurityTab = React.createClass({
var confirmPassword = this.state.confirm_password;
if (currentPassword === '') {
- this.setState({ password_error: "Please enter your current password" });
+ this.setState({password_error: 'Please enter your current password', server_error: ''});
return;
}
if (newPassword.length < 5) {
- this.setState({ password_error: "New passwords must be at least 5 characters" });
+ this.setState({password_error: 'New passwords must be at least 5 characters', server_error: ''});
return;
}
- if (newPassword != confirmPassword) {
- this.setState({ password_error: "The new passwords you entered do not match" });
+ if (newPassword !== confirmPassword) {
+ this.setState({password_error: 'The new passwords you entered do not match', server_error: ''});
return;
}
@@ -488,11 +488,16 @@ var SecurityTab = React.createClass({
function(data) {
this.props.updateSection("");
AsyncClient.getMe();
- this.setState({ current_password: '', new_password: '', confirm_password: '' });
+ this.setState({current_password: '', new_password: '', confirm_password: ''});
}.bind(this),
function(err) {
- state = this.getInitialState();
- state.server_error = err;
+ var state = this.getInitialState();
+ if (err.message) {
+ state.server_error = err.message;
+ } else {
+ state.server_error = err;
+ }
+ state.password_error = '';
this.setState(state);
}.bind(this)
);
@@ -709,7 +714,11 @@ var GeneralTab = React.createClass({
}.bind(this),
function(err) {
state = this.getInitialState();
- state.server_error = err;
+ if(err.message) {
+ state.server_error = err.message;
+ } else {
+ state.server_error = err
+ }
this.setState(state);
}.bind(this)
);
diff --git a/web/react/pages/verify.jsx b/web/react/pages/verify.jsx
index 69850849f..96b556983 100644
--- a/web/react/pages/verify.jsx
+++ b/web/react/pages/verify.jsx
@@ -3,11 +3,9 @@
var EmailVerify = require('../components/email_verify.jsx');
-global.window.setup_verify_page = function(is_verified) {
-
+global.window.setupVerifyPage = function setupVerifyPage(isVerified, teamURL, userEmail) {
React.render(
- <EmailVerify isVerified={is_verified} />,
+ <EmailVerify isVerified={isVerified} teamURL={teamURL} userEmail={userEmail} />,
document.getElementById('verify')
);
-
};
diff --git a/web/react/stores/user_store.jsx b/web/react/stores/user_store.jsx
index 001162f47..aff5a0bed 100644
--- a/web/react/stores/user_store.jsx
+++ b/web/react/stores/user_store.jsx
@@ -164,13 +164,13 @@ var UserStore = assign({}, EventEmitter.prototype, {
BrowserStore.setItem("sessions", sessions);
},
getSessions: function() {
- return BrowserStore.getItem("sessions", []);
+ return BrowserStore.getItem("sessions", {loading: true});
},
setAudits: function(audits) {
BrowserStore.setItem("audits", audits);
},
getAudits: function() {
- return BrowserStore.getItem("audits", []);
+ return BrowserStore.getItem("audits", {loading: true});
},
setTeams: function(teams) {
BrowserStore.setItem("teams", teams);
diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx
index 09240bf06..e51f7f3f4 100644
--- a/web/react/utils/utils.jsx
+++ b/web/react/utils/utils.jsx
@@ -416,7 +416,7 @@ module.exports.textToJsx = function(text, options) {
var lines = text.split("\n");
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
- var words = line.split(" ");
+ var words = line.split(/(?=\W)/);
var highlightSearchClass = "";
for (var z = 0; z < words.length; z++) {
var word = words[z];
@@ -444,7 +444,7 @@ module.exports.textToJsx = function(text, options) {
highlightSearchClass = " search-highlight";
}
- inner.push(<span key={name+i+z+"_span"}>{prefix}<a className={mClass + highlightSearchClass + " mention-link"} key={name+i+z+"_link"} href="#" onClick={function(value) { return function() { module.exports.searchForTerm(value); } }(name)}>@{name}</a>{suffix} </span>);
+ inner.push(<span key={name+i+z+"_span"}>{prefix}<a className={mClass + highlightSearchClass + " mention-link"} key={name+i+z+"_link"} href="#" onClick={function(value) { return function() { module.exports.searchForTerm(value); } }(name)}>@{name}</a>{suffix}</span>);
} else if (testUrlMatch(word).length) {
var match = testUrlMatch(word)[0];
var link = match.link;
@@ -452,7 +452,7 @@ module.exports.textToJsx = function(text, options) {
var prefix = word.substring(0,word.indexOf(match.text));
var suffix = word.substring(word.indexOf(match.text)+match.text.length);
- inner.push(<span key={word+i+z+"_span"}>{prefix}<a key={word+i+z+"_link"} className={"theme" + highlightSearchClass} target="_blank" href={link}>{match.text}</a>{suffix} </span>);
+ inner.push(<span key={word+i+z+"_span"}>{prefix}<a key={word+i+z+"_link"} className={"theme" + highlightSearchClass} target="_blank" href={link}>{match.text}</a>{suffix}</span>);
} else if (trimWord.match(hashRegex)) {
var suffix = word.match(puncEndRegex);
@@ -463,7 +463,7 @@ module.exports.textToJsx = function(text, options) {
highlightSearchClass = " search-highlight";
}
- inner.push(<span key={word+i+z+"_span"}>{prefix}<a key={word+i+z+"_hash"} className={"theme " + mClass + highlightSearchClass} href="#" onClick={function(value) { return function() { module.exports.searchForTerm(value); } }(trimWord)}>{trimWord}</a>{suffix} </span>);
+ inner.push(<span key={word+i+z+"_span"}>{prefix}<a key={word+i+z+"_hash"} className={"theme " + mClass + highlightSearchClass} href="#" onClick={function(value) { return function() { module.exports.searchForTerm(value); } }(trimWord)}>{trimWord}</a>{suffix}</span>);
} else if (implicitKeywords.indexOf(trimWord) !== -1 || implicitKeywords.indexOf(trimWord.toLowerCase()) !== -1) {
var suffix = word.match(puncEndRegex);
@@ -473,15 +473,15 @@ module.exports.textToJsx = function(text, options) {
if (searchTerm === trimWord.substring(1).toLowerCase()) {
highlightSearchClass = " search-highlight";
}
- inner.push(<span key={word+i+z+"_span"} key={name+i+z+"_span"}>{prefix}<a className={mentionClass + highlightSearchClass} key={name+i+z+"_link"} href="#">{trimWord}</a>{suffix} </span>);
+ inner.push(<span key={word+i+z+"_span"} key={name+i+z+"_span"}>{prefix}<a className={mentionClass + highlightSearchClass} key={name+i+z+"_link"} href="#">{trimWord}</a>{suffix}</span>);
} else {
- inner.push(<span key={word+i+z+"_span"}>{prefix}<span className={mentionClass + highlightSearchClass}>{module.exports.replaceHtmlEntities(trimWord)}</span>{suffix} </span>);
+ inner.push(<span key={word+i+z+"_span"}>{prefix}<span className={mentionClass + highlightSearchClass}>{module.exports.replaceHtmlEntities(trimWord)}</span>{suffix}</span>);
}
} else if (word === "") {
// if word is empty dont include a span
} else {
- inner.push(<span key={word+i+z+"_span"}><span className={highlightSearchClass}>{module.exports.replaceHtmlEntities(word)}</span> </span>);
+ inner.push(<span key={word+i+z+"_span"}><span className={highlightSearchClass}>{module.exports.replaceHtmlEntities(word)}</span></span>);
}
highlightSearchClass = "";
}