summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rw-r--r--web/react/components/channel_header.jsx2
-rw-r--r--web/react/components/mention_list.jsx6
-rw-r--r--web/react/components/new_channel.jsx2
-rw-r--r--web/react/components/post_list.jsx15
-rw-r--r--web/react/components/setting_picture.jsx30
-rw-r--r--web/react/components/sidebar_header.jsx117
-rw-r--r--web/react/components/signup_team_complete.jsx6
-rw-r--r--web/react/components/user_profile.jsx3
-rw-r--r--web/react/components/user_settings.jsx107
-rw-r--r--web/sass-files/sass/partials/_base.scss10
-rw-r--r--web/sass-files/sass/partials/_files.scss68
-rw-r--r--web/sass-files/sass/partials/_headers.scss14
-rw-r--r--web/sass-files/sass/partials/_modal.scss9
-rw-r--r--web/sass-files/sass/partials/_navbar.scss1
-rw-r--r--web/sass-files/sass/partials/_popover.scss7
-rw-r--r--web/sass-files/sass/partials/_responsive.scss10
-rw-r--r--web/sass-files/sass/partials/_signup.scss22
-rw-r--r--web/templates/channel.html4
-rw-r--r--web/templates/signup_team.html2
19 files changed, 279 insertions, 156 deletions
diff --git a/web/react/components/channel_header.jsx b/web/react/components/channel_header.jsx
index b6182cfa5..a79d3547f 100644
--- a/web/react/components/channel_header.jsx
+++ b/web/react/components/channel_header.jsx
@@ -67,7 +67,7 @@ var PopoverListMembers = React.createClass({
return (
<div id='member_popover' data-toggle='popover' data-content={popoverHtml} data-original-title='Members' >
- <div id='member_tooltip' data-toggle='tooltip' title='View Channel Members'>
+ <div id='member_tooltip' data-placement='left' data-toggle='tooltip' title='View Channel Members'>
{count} <span className='glyphicon glyphicon-user' aria-hidden='true'></span>
</div>
</div>
diff --git a/web/react/components/mention_list.jsx b/web/react/components/mention_list.jsx
index a0f68df98..5f1bb6d0e 100644
--- a/web/react/components/mention_list.jsx
+++ b/web/react/components/mention_list.jsx
@@ -20,6 +20,12 @@ module.exports = React.createClass({
PostStore.addMentionDataChangeListener(this.onListenerChange);
var self = this;
+ $('.post-right__scroll').scroll(function(){
+ if($('.mentions--top').length){
+ $('#reply_mention_tab .mentions--top').css({ bottom: $(window).height() - $('.post-right__scroll #reply_textbox').offset().top });
+ }
+ });
+
$('body').on('keydown.mentionlist', '#' + this.props.id,
function(e) {
if (!self.isEmpty() && self.state.mentionText !== '-1' && (e.which === 13 || e.which === 9)) {
diff --git a/web/react/components/new_channel.jsx b/web/react/components/new_channel.jsx
index 6cf195795..93884f6eb 100644
--- a/web/react/components/new_channel.jsx
+++ b/web/react/components/new_channel.jsx
@@ -53,7 +53,7 @@ module.exports = React.createClass({
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,
diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx
index 3f59d5843..bb1b1704c 100644
--- a/web/react/components/post_list.jsx
+++ b/web/react/components/post_list.jsx
@@ -37,15 +37,23 @@ module.exports = React.createClass({
componentDidMount: function() {
var user = UserStore.getCurrentUser();
if (user.props && user.props.theme) {
- utils.changeCss('a.theme', 'color:'+user.props.theme+'; fill:'+user.props.theme+'!important;');
utils.changeCss('div.theme', 'background-color:'+user.props.theme+';');
utils.changeCss('.btn.btn-primary', 'background: ' + user.props.theme+';');
- utils.changeCss('.btn.btn-primary:hover, .btn.btn-primary:active, .btn.btn-primary:focus', 'background: ' + utils.changeColor(user.props.theme, -10) +';');
utils.changeCss('.modal .modal-header', 'background: ' + user.props.theme+';');
utils.changeCss('.mention', 'background: ' + user.props.theme+';');
utils.changeCss('.mention-link', 'color: ' + user.props.theme+';');
utils.changeCss('@media(max-width: 768px){.search-bar__container', 'background: ' + user.props.theme+';}');
}
+ if (user.props.theme != '#000000' && user.props.theme != '#585858') {
+ utils.changeCss('.btn.btn-primary:hover, .btn.btn-primary:active, .btn.btn-primary:focus', 'background: ' + utils.changeColor(user.props.theme, -10) +';');
+ utils.changeCss('a.theme', 'color:'+user.props.theme+'; fill:'+user.props.theme+'!important;');
+ } else if (user.props.theme == '#000000') {
+ utils.changeCss('.btn.btn-primary:hover, .btn.btn-primary:active, .btn.btn-primary:focus', 'background: ' + utils.changeColor(user.props.theme, +50) +';');
+ $('.team__header').addClass('theme--black');
+ } else if (user.props.theme == '#585858') {
+ utils.changeCss('.btn.btn-primary:hover, .btn.btn-primary:active, .btn.btn-primary:focus', 'background: ' + utils.changeColor(user.props.theme, +10) +';');
+ $('.team__header').addClass('theme--gray');
+ }
PostStore.addChangeListener(this._onChange);
ChannelStore.addChangeListener(this._onChange);
@@ -311,7 +319,6 @@ module.exports = React.createClass({
} 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 = (
@@ -399,7 +406,7 @@ module.exports = React.createClass({
var postCtls = [];
if (posts) {
- var previousPostDay = posts[order[order.length-1]] ? utils.getDateForUnixTicks(posts[order[order.length-1]].create_at): new Date();
+ var previousPostDay = new Date(0);
var currentPostDay;
for (var i = order.length-1; i >= 0; i--) {
diff --git a/web/react/components/setting_picture.jsx b/web/react/components/setting_picture.jsx
index fa4c8bb62..e97b67706 100644
--- a/web/react/components/setting_picture.jsx
+++ b/web/react/components/setting_picture.jsx
@@ -20,8 +20,14 @@ module.exports = React.createClass({
}
},
render: function() {
- var client_error = this.props.client_error ? <div className='form-group has-error'><label className='control-label'>{ this.props.client_error }</label></div> : null;
- var server_error = this.props.server_error ? <div className='form-group has-error'><label className='control-label'>{ this.props.server_error }</label></div> : null;
+ var clientError = null;
+ if (this.props.client_error) {
+ clientError = <div className='form-group has-error'><label className='control-label'>{this.props.client_error}</label></div>;
+ }
+ var serverError = null;
+ if (this.props.server_error) {
+ serverError = <div className='form-group has-error'><label className='control-label'>{this.props.server_error}</label></div>;
+ }
var img = null;
if (this.props.picture) {
@@ -30,8 +36,20 @@ module.exports = React.createClass({
img = (<img ref='image' className='profile-img' src={this.props.src}/>);
}
- var self = this;
+ var confirmButton;
+ if (this.props.loadingPicture) {
+ confirmButton = <img className='spinner' src='/static/images/load.gif'/>;
+ } else {
+ var confirmButtonClass = 'btn btn-sm';
+ if (this.props.submitActive) {
+ confirmButtonClass += ' btn-primary';
+ } else {
+ confirmButtonClass += ' btn-inactive disabled';
+ }
+ confirmButton = <a className={confirmButtonClass} onClick={this.props.submit}>Save</a>;
+ }
+ var self = this;
return (
<ul className='section-max'>
<li className='col-xs-12 section-title'>{this.props.title}</li>
@@ -41,10 +59,10 @@ module.exports = React.createClass({
{img}
</li>
<li className='setting-list-item'>
- {server_error}
- {client_error}
+ {serverError}
+ {clientError}
<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>
+ {confirmButton}
<a className='btn btn-sm theme' href='#' onClick={self.props.updateSection}>Cancel</a>
</li>
</ul>
diff --git a/web/react/components/sidebar_header.jsx b/web/react/components/sidebar_header.jsx
index e01ddcd05..ba8f9bacd 100644
--- a/web/react/components/sidebar_header.jsx
+++ b/web/react/components/sidebar_header.jsx
@@ -1,15 +1,15 @@
// 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 UserStore = require('../stores/user_store.jsx');
+var TeamStore = require('../stores/team_store.jsx');
var Constants = require('../utils/constants.jsx');
function getStateFromStores() {
- return { teams: UserStore.getTeams() };
+ return {teams: UserStore.getTeams(), currentTeam: TeamStore.getCurrent()};
}
var NavbarDropdown = React.createClass({
@@ -19,20 +19,24 @@ var NavbarDropdown = React.createClass({
},
blockToggle: false,
componentDidMount: function() {
- UserStore.addTeamsChangeListener(this._onChange);
+ UserStore.addTeamsChangeListener(this.onListenerChange);
+ TeamStore.addChangeListener(this.onListenerChange);
var self = this;
- $(this.refs.dropdown.getDOMNode()).on('hide.bs.dropdown', function(e) {
+ $(this.refs.dropdown.getDOMNode()).on('hide.bs.dropdown', function() {
self.blockToggle = true;
- setTimeout(function(){self.blockToggle = false;}, 100);
+ setTimeout(function() {
+ self.blockToggle = false;
+ }, 100);
});
},
componentWillUnmount: function() {
- UserStore.removeTeamsChangeListener(this._onChange);
+ UserStore.removeTeamsChangeListener(this.onListenerChange);
+ TeamStore.removeChangeListener(this.onListenerChange);
$(this.refs.dropdown.getDOMNode()).off('hide.bs.dropdown');
},
- _onChange: function() {
+ onListenerChange: function() {
if (this.isMounted()) {
var newState = getStateFromStores();
if (!utils.areStatesEqual(newState, this.state)) {
@@ -44,62 +48,65 @@ var NavbarDropdown = React.createClass({
return getStateFromStores();
},
render: function() {
- var team_link = "";
- var invite_link = "";
- var manage_link = "";
- var rename_link = "";
+ var teamLink = '';
+ var inviteLink = '';
+ var manageLink = '';
+ var renameLink = '';
var currentUser = UserStore.getCurrentUser();
var isAdmin = false;
+ var teamSettings = null;
if (currentUser != null) {
- isAdmin = currentUser.roles.indexOf("admin") > -1;
+ isAdmin = currentUser.roles.indexOf('admin') > -1;
- invite_link = ( <li> <a href="#" data-toggle="modal" data-target="#invite_member">Invite New Member</a> </li>);
+ inviteLink = (<li> <a href='#' data-toggle='modal' data-target='#invite_member'>Invite New Member</a> </li>);
- if (this.props.teamType == "O") {
- team_link = (
+ if (this.props.teamType === 'O') {
+ teamLink = (
<li>
- <a href="#" data-toggle="modal" data-target="#get_link" data-title="Team Invite" data-value={location.origin+"/signup_user_complete/?id="+currentUser.team_id}>Get Team Invite Link</a>
+ <a href='#' data-toggle='modal' data-target='#get_link' data-title='Team Invite' data-value={location.origin + '/signup_user_complete/?id=' + currentUser.team_id}>Get Team Invite Link</a>
</li>
);
}
}
if (isAdmin) {
- manage_link = ( <li> <a href="#" data-toggle="modal" data-target="#team_members">Manage Team</a> </li>);
- rename_link = ( <li> <a href="#" data-toggle="modal" data-target="#rename_team_link">Rename</a> </li>);
+ manageLink = (<li> <a href='#' data-toggle='modal' data-target='#team_members'>Manage Team</a> </li>);
+ renameLink = (<li> <a href='#' data-toggle='modal' data-target='#rename_team_link'>Rename</a> </li>);
+ teamSettings = (<li> <a href='#' data-toggle='modal' data-target='#team_settings'>Team Settings</a> </li>);
}
var teams = [];
- teams.push(<li className="divider" key="div"></li>);
- if (this.state.teams.length > 1) {
- for (var i = 0; i < this.state.teams.length; i++) {
- var teamName = this.state.teams[i];
-
- teams.push(<li key={ teamName }><a href={utils.getWindowLocationOrigin() + "/" + teamName }>Switch to { teamName }</a></li>);
- }
+ teams.push(<li className='divider' key='div'></li>);
+ if (this.state.teams.length > 1 && this.state.currentTeam) {
+ var curTeamName = this.state.currentTeam.name;
+ this.state.teams.forEach(function(teamName) {
+ if (teamName !== curTeamName) {
+ teams.push(<li key={teamName}><a href={utils.getWindowLocationOrigin() + '/' + teamName}>Switch to {teamName}</a></li>);
+ }
+ });
}
- teams.push(<li><a href={utils.getWindowLocationOrigin() + "/signup_team" }>Create a New Team</a></li>);
+ teams.push(<li><a href={utils.getWindowLocationOrigin() + '/signup_team'}>Create a New Team</a></li>);
return (
- <ul className="nav navbar-nav navbar-right">
- <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 }} />
+ <ul className='nav navbar-nav navbar-right'>
+ <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>
- <ul className="dropdown-menu" role="menu">
- <li><a href="#" data-toggle="modal" data-target="#user_settings1">Account Settings</a></li>
- { isAdmin ? <li><a href="#" data-toggle="modal" data-target="#team_settings">Team Settings</a></li> : null }
- { invite_link }
- { team_link }
- { manage_link }
- { rename_link }
- <li><a href="#" onClick={this.handleLogoutClick}>Logout</a></li>
- { teams }
- <li className="divider"></li>
- <li><a target="_blank" href={config.HelpLink}>Help</a></li>
- <li><a target="_blank" href={config.ReportProblemLink}>Report a Problem</a></li>
+ <ul className='dropdown-menu' role='menu'>
+ <li><a href='#' data-toggle='modal' data-target='#user_settings1'>Account Settings</a></li>
+ {teamSettings}
+ {inviteLink}
+ {teamLink}
+ {manageLink}
+ {renameLink}
+ <li><a href='#' onClick={this.handleLogoutClick}>Logout</a></li>
+ {teams}
+ <li className='divider'></li>
+ <li><a target='_blank' href={config.HelpLink}>Help</a></li>
+ <li><a target='_blank' href={config.ReportProblemLink}>Report a Problem</a></li>
</ul>
</li>
</ul>
@@ -109,14 +116,13 @@ var NavbarDropdown = React.createClass({
module.exports = React.createClass({
displayName: 'SidebarHeader',
-
getDefaultProps: function() {
return {
teamDisplayName: config.SiteName
};
},
- toggleDropdown: function(e) {
+ toggleDropdown: function() {
if (this.refs.dropdown.blockToggle) {
this.refs.dropdown.blockToggle = false;
return;
@@ -126,25 +132,26 @@ module.exports = React.createClass({
render: function() {
var me = UserStore.getCurrentUser();
+ var profilePicture = null;
if (!me) {
return null;
}
+ if (me.last_picture_update) {
+ profilePicture = (<img className='user__picture' src={'/api/v1/users/' + me.id + '/image?time=' + me.update_at} />);
+ }
+
return (
- <div className="team__header theme">
- <a href="#" onClick={this.toggleDropdown}>
- { me.last_picture_update ?
- <img className="user__picture" src={"/api/v1/users/" + me.id + "/image?time=" + me.update_at} />
- :
- null
- }
- <div className="header__info">
- <div className="user__name">{ '@' + me.username}</div>
- <div className="team__name">{ this.props.teamDisplayName }</div>
+ <div className='team__header theme'>
+ <a href='#' onClick={this.toggleDropdown}>
+ {profilePicture}
+ <div className='header__info'>
+ <div className='user__name'>{'@' + me.username}</div>
+ <div className='team__name'>{this.props.teamDisplayName }</div>
</div>
</a>
- <NavbarDropdown ref="dropdown" 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 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/user_profile.jsx b/web/react/components/user_profile.jsx
index 65f025919..5c4d26a23 100644
--- a/web/react/components/user_profile.jsx
+++ b/web/react/components/user_profile.jsx
@@ -28,6 +28,7 @@ module.exports = React.createClass({
componentDidMount: function() {
UserStore.addChangeListener(this._onChange);
$("#profile_" + this.uniqueId).popover({placement : 'right', container: 'body', trigger: 'hover', html: true, delay: { "show": 200, "hide": 100 }});
+ $('body').tooltip( {selector: '[data-toggle=tooltip]', trigger: 'hover click'} );
},
componentWillUnmount: function() {
UserStore.removeChangeListener(this._onChange);
@@ -57,7 +58,7 @@ module.exports = React.createClass({
if (!config.ShowEmail) {
data_content += "<div class='text-nowrap'>Email not shared</div>";
} else {
- data_content += "<div><a href='mailto:" + this.state.profile.email + "' class='text-nowrap text-lowercase'>" + this.state.profile.email + "</a></div>";
+ data_content += "<div data-toggle='tooltip' title= '" + this.state.profile.email + "'><a href='mailto:" + this.state.profile.email + "' class='text-nowrap text-lowercase user-popover__email'>" + this.state.profile.email + "</a></div>";
}
return (
diff --git a/web/react/components/user_settings.jsx b/web/react/components/user_settings.jsx
index c574d2365..e224f2a87 100644
--- a/web/react/components/user_settings.jsx
+++ b/web/react/components/user_settings.jsx
@@ -5,8 +5,6 @@ var UserStore = require('../stores/user_store.jsx');
var SettingItemMin = require('./setting_item_min.jsx');
var SettingItemMax = require('./setting_item_max.jsx');
var SettingPicture = require('./setting_picture.jsx');
-var AccessHistoryModal = require('./access_history_modal.jsx');
-var ActivityLogModal = require('./activity_log_modal.jsx');
var client = require('../utils/client.jsx');
var AsyncClient = require('../utils/async_client.jsx');
var utils = require('../utils/utils.jsx');
@@ -642,17 +640,17 @@ var GeneralTab = React.createClass({
var user = this.props.user;
var username = this.state.username.trim();
- var username_error = utils.isValidUsername(username);
- if (username_error === 'Cannot use a reserved word as a username.') {
- this.setState({client_error: 'This username is reserved, please choose a new one.' });
+ var usernameError = utils.isValidUsername(username);
+ if (usernameError === 'Cannot use a reserved word as a username.') {
+ this.setState({clientError: 'This username is reserved, please choose a new one.'});
return;
- } else if (username_error) {
- this.setState({client_error: "Username must begin with a letter, and contain between 3 to 15 lowercase characters made up of numbers, letters, and the symbols '.', '-' and '_'." });
+ } else if (usernameError) {
+ this.setState({clientError: "Username must begin with a letter, and contain between 3 to 15 lowercase characters made up of numbers, letters, and the symbols '.', '-' and '_'."});
return;
}
if (user.username === username) {
- this.setState({client_error: 'You must submit a new username'});
+ this.setState({clientError: 'You must submit a new username'});
return;
}
@@ -667,7 +665,7 @@ var GeneralTab = React.createClass({
var nickname = this.state.nickname.trim();
if (user.nickname === nickname) {
- this.setState({client_error: 'You must submit a new nickname'})
+ this.setState({clientError: 'You must submit a new nickname'});
return;
}
@@ -679,11 +677,11 @@ var GeneralTab = React.createClass({
e.preventDefault();
var user = UserStore.getCurrentUser();
- var firstName = this.state.first_name.trim();
- var lastName = this.state.last_name.trim();
+ var firstName = this.state.firstName.trim();
+ var lastName = this.state.lastName.trim();
if (user.first_name === firstName && user.last_name === lastName) {
- this.setState({client_error: 'You must submit a new first or last name'})
+ this.setState({clientError: 'You must submit a new first or last name'});
return;
}
@@ -703,7 +701,7 @@ var GeneralTab = React.createClass({
}
if (email === '' || !utils.isEmail(email)) {
- this.setState({ email_error: 'Please enter a valid email address' });
+ this.setState({emailError: 'Please enter a valid email address'});
return;
}
@@ -718,11 +716,11 @@ var GeneralTab = React.createClass({
AsyncClient.getMe();
}.bind(this),
function(err) {
- state = this.getInitialState();
+ var state = this.getInitialState();
if (err.message) {
- state.server_error = err.message;
+ state.serverError = err.message;
} else {
- state.server_error = err;
+ state.serverError = err;
}
this.setState(state);
}.bind(this)
@@ -742,12 +740,13 @@ var GeneralTab = React.createClass({
var picture = this.state.picture;
if (picture.type !== 'image/jpeg' && picture.type !== 'image/png') {
- this.setState({client_error: 'Only JPG or PNG images may be used for profile pictures'});
+ this.setState({clientError: 'Only JPG or PNG images may be used for profile pictures'});
return;
}
var formData = new FormData();
formData.append('image', picture, picture.name);
+ this.setState({loadingPicture: true});
client.uploadProfileImage(formData,
function() {
@@ -756,8 +755,8 @@ var GeneralTab = React.createClass({
window.location.reload();
}.bind(this),
function(err) {
- state = this.getInitialState();
- state.server_error = err;
+ var state = this.getInitialState();
+ state.serverError = err;
this.setState(state);
}.bind(this)
);
@@ -766,10 +765,10 @@ var GeneralTab = React.createClass({
this.setState({username: e.target.value});
},
updateFirstName: function(e) {
- this.setState({first_name: e.target.value});
+ this.setState({firstName: e.target.value});
},
updateLastName: function(e) {
- this.setState({last_name: e.target.value});
+ this.setState({lastName: e.target.value});
},
updateNickname: function(e) {
this.setState({nickname: e.target.value});
@@ -779,17 +778,16 @@ var GeneralTab = React.createClass({
},
updatePicture: function(e) {
if (e.target.files && e.target.files[0]) {
- this.setState({ picture: e.target.files[0] });
+ this.setState({picture: e.target.files[0]});
this.submitActive = true;
- this.setState({client_error: null});
-
+ this.setState({clientError: null});
} else {
this.setState({picture: null});
}
},
updateSection: function(section) {
- this.setState({client_error:''});
+ this.setState({clientError: ''});
this.submitActive = false;
this.props.updateSection(section);
},
@@ -798,7 +796,7 @@ var GeneralTab = React.createClass({
this.value = '';
});
- this.setState(assign({}, this.getInitialState(), {client_error: null, server_error: null, email_error: null}));
+ this.setState(assign({}, this.getInitialState(), {clientError: null, serverError: null, emailError: null}));
this.props.updateSection('');
},
componentDidMount: function() {
@@ -810,15 +808,24 @@ var GeneralTab = React.createClass({
getInitialState: function() {
var user = this.props.user;
- return { username: user.username, first_name: user.first_name, last_name: user.last_name, nickname: user.nickname,
- email: user.email, picture: null };
+ return {username: user.username, firstName: user.first_name, lastName: user.last_name, nickname: user.nickname,
+ email: user.email, picture: null, loadingPicture: false};
},
render: function() {
var user = this.props.user;
- var client_error = this.state.client_error ? this.state.client_error : null;
- var server_error = this.state.server_error ? this.state.server_error : null;
- var email_error = this.state.email_error ? this.state.email_error : null;
+ var clientError = null;
+ if (this.state.clientError) {
+ clientError = this.state.clientError;
+ }
+ var serverError = null;
+ if (this.state.serverError) {
+ serverError = this.state.serverError;
+ }
+ var emailError = null;
+ if (this.state.emailError) {
+ emailError = this.state.emailError;
+ }
var nameSection;
var self = this;
@@ -829,7 +836,7 @@ var GeneralTab = React.createClass({
<div 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.first_name}/>
+ <input className='form-control' type='text' onChange={this.updateFirstName} value={this.state.firstName}/>
</div>
</div>
);
@@ -838,7 +845,7 @@ var GeneralTab = React.createClass({
<div 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.last_name}/>
+ <input className='form-control' type='text' onChange={this.updateLastName} value={this.state.lastName}/>
</div>
</div>
);
@@ -848,8 +855,8 @@ var GeneralTab = React.createClass({
title='Full Name'
inputs={inputs}
submit={this.submitName}
- server_error={server_error}
- client_error={client_error}
+ server_error={serverError}
+ client_error={clientError}
updateSection={function(e) {
self.updateSection('');
e.preventDefault();
@@ -857,20 +864,20 @@ var GeneralTab = React.createClass({
/>
);
} else {
- var full_name = '';
+ var fullName = '';
if (user.first_name && user.last_name) {
- full_name = user.first_name + ' ' + user.last_name;
+ fullName = user.first_name + ' ' + user.last_name;
} else if (user.first_name) {
- full_name = user.first_name;
+ fullName = user.first_name;
} else if (user.last_name) {
- full_name = user.last_name;
+ fullName = user.last_name;
}
nameSection = (
<SettingItemMin
title='Full Name'
- describe={full_name}
+ describe={fullName}
updateSection={function() {
self.updateSection('name');
}}
@@ -880,7 +887,6 @@ var GeneralTab = React.createClass({
var nicknameSection;
if (this.props.activeSection === 'nickname') {
-
inputs.push(
<div className='form-group'>
<label className='col-sm-5 control-label'>{utils.isMobile() ? '' : 'Nickname'}</label>
@@ -895,8 +901,8 @@ var GeneralTab = React.createClass({
title='Nickname'
inputs={inputs}
submit={this.submitNickname}
- server_error={server_error}
- client_error={client_error}
+ server_error={serverError}
+ client_error={clientError}
updateSection={function(e) {
self.updateSection('');
e.preventDefault();
@@ -919,7 +925,7 @@ var GeneralTab = React.createClass({
if (this.props.activeSection === 'username') {
inputs.push(
<div className='form-group'>
- <label className='col-sm-5 control-label'>{utils.isMobile() ? '': 'Username'}</label>
+ <label className='col-sm-5 control-label'>{utils.isMobile() ? '' : 'Username'}</label>
<div className='col-sm-7'>
<input className='form-control' type='text' onChange={this.updateUsername} value={this.state.username}/>
</div>
@@ -931,8 +937,8 @@ var GeneralTab = React.createClass({
title='Username'
inputs={inputs}
submit={this.submitUsername}
- server_error={server_error}
- client_error={client_error}
+ server_error={serverError}
+ client_error={clientError}
updateSection={function(e) {
self.updateSection('');
e.preventDefault();
@@ -966,8 +972,8 @@ var GeneralTab = React.createClass({
title='Email'
inputs={inputs}
submit={this.submitEmail}
- server_error={server_error}
- client_error={email_error}
+ server_error={serverError}
+ client_error={emailError}
updateSection={function(e) {
self.updateSection('');
e.preventDefault();
@@ -993,8 +999,8 @@ var GeneralTab = React.createClass({
title='Profile Picture'
submit={this.submitPicture}
src={'/api/v1/users/' + user.id + '/image?time=' + user.last_picture_update}
- server_error={server_error}
- client_error={client_error}
+ server_error={serverError}
+ client_error={clientError}
updateSection={function(e) {
self.updateSection('');
e.preventDefault();
@@ -1002,6 +1008,7 @@ var GeneralTab = React.createClass({
picture={this.state.picture}
pictureChange={this.updatePicture}
submitActive={this.submitActive}
+ loadingPicture={this.state.loadingPicture}
/>
);
} else {
diff --git a/web/sass-files/sass/partials/_base.scss b/web/sass-files/sass/partials/_base.scss
index 52659521d..78006ff18 100644
--- a/web/sass-files/sass/partials/_base.scss
+++ b/web/sass-files/sass/partials/_base.scss
@@ -49,6 +49,12 @@ div.theme {
background-color: $primary-color;
}
+.tooltip {
+ .tooltip-inner {
+ word-break: break-word;
+ }
+}
+
.nopadding {
padding: 0;
margin: 0;
@@ -61,6 +67,10 @@ div.theme {
}
}
+.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control {
+ cursor: auto;
+}
+
.form-group {
&.form-group--small {
margin-bottom: 10px;
diff --git a/web/sass-files/sass/partials/_files.scss b/web/sass-files/sass/partials/_files.scss
index ddc5e98bb..65775f01e 100644
--- a/web/sass-files/sass/partials/_files.scss
+++ b/web/sass-files/sass/partials/_files.scss
@@ -4,7 +4,8 @@
max-height: 110px;
height: 110px;
white-space: nowrap;
- overflow: auto;
+ overflow-x: auto;
+ overflow-y: hidden;
.preview-div {
display: inline-block;
width: 120px;
@@ -28,9 +29,9 @@
}
}
.preview-img {
- display: block;
- height: auto;
- max-width: 100%;
+ display: block;
+ height: auto;
+ max-width: 100%;
}
.remove-preview {
position: absolute;
@@ -114,8 +115,7 @@
height: 100px;
float: left;
margin: 5px 10px 5px 0;
- @include display-flex;
- display: -ms-flexbox;
+ display: table;
border: 1px solid lightgrey;
.post__load {
height: 100%;
@@ -130,17 +130,23 @@
background-color: #FFF;
background-repeat: no-repeat;
&.small {
- background-position: center;
+ background-position: center;
}
&.normal {
- background-position: top left;
+ background-position: top left;
}
}
.post-image__thumbnail {
+ display: table-cell;
+ vertical-align: top;
width: 50%;
height: 100%;
+ cursor: zoom-in;
+ cursor: -webkit-zoom-in;
}
.post-image__details {
+ display: table-cell;
+ vertical-align: top;
width: 50%;
height: 100%;
background: white;
@@ -165,34 +171,34 @@
}
.file-details__container {
- @include display-flex;
- display: -ms-flexbox;
+ @include display-flex;
+ display: -ms-flexbox;
- .file-details {
- width: 320px;
- height: 270px;
- padding: 14px;
- text-align: left;
- vertical-align: top;
+ .file-details {
+ width: 320px;
+ height: 270px;
+ padding: 14px;
+ text-align: left;
+ vertical-align: top;
- .file-details__name {
- font-size: 16px;
- }
- .file-details__info {
- color: grey;
- }
+ .file-details__name {
+ font-size: 16px;
+ }
+ .file-details__info {
+ color: grey;
}
- .file-details__preview {
- width: 320px;
- height: 270px;
- border-right: 1px solid #ddd;
- vertical-align: center;
+ }
+ .file-details__preview {
+ width: 320px;
+ height: 270px;
+ border-right: 1px solid #ddd;
+ vertical-align: center;
// helper to center the image icon in the preview window
.file-details__preview-helper {
- height: 100%;
- display: inline-block;
- vertical-align: middle;
+ height: 100%;
+ display: inline-block;
+ vertical-align: middle;
}
+ }
}
-}
diff --git a/web/sass-files/sass/partials/_headers.scss b/web/sass-files/sass/partials/_headers.scss
index fb37c43eb..da648a170 100644
--- a/web/sass-files/sass/partials/_headers.scss
+++ b/web/sass-files/sass/partials/_headers.scss
@@ -110,6 +110,20 @@
}
}
}
+ &.theme--black {
+ &:hover {
+ &:before {
+ background: rgba(white, 0.2);
+ }
+ }
+ }
+ &.theme--gray {
+ &:hover {
+ &:before {
+ background: rgba(white, 0.1);
+ }
+ }
+ }
a {
color: #fff;
}
diff --git a/web/sass-files/sass/partials/_modal.scss b/web/sass-files/sass/partials/_modal.scss
index f359037c5..014f834ed 100644
--- a/web/sass-files/sass/partials/_modal.scss
+++ b/web/sass-files/sass/partials/_modal.scss
@@ -15,10 +15,13 @@
}
.remove__member {
float: right;
- color: #E56565;
+ color: #999;
font-size: 20px;
line-height: 0;
padding: 6px;
+ &:hover {
+ color: #E56565;
+ }
}
.modal-dialog {
max-width: 95%;
@@ -151,10 +154,9 @@
height: 100%;
margin: 0 auto;
.image-wrapper {
- background: #FFF;
position: relative;
max-width: 90%;
- min-height: 50px;
+ min-height: 100px;
min-width: 320px;
@include border-radius(3px);
display: table;
@@ -182,6 +184,7 @@
z-index: 9999;
}
> a {
+ background: #FFF;
display: table-cell;
vertical-align: middle;
}
diff --git a/web/sass-files/sass/partials/_navbar.scss b/web/sass-files/sass/partials/_navbar.scss
index 905907d84..2e78a8728 100644
--- a/web/sass-files/sass/partials/_navbar.scss
+++ b/web/sass-files/sass/partials/_navbar.scss
@@ -19,6 +19,7 @@
}
}
.navbar-toggle {
+ width: 43px;
float: left;
border-color: transparent;
border-radius: 0;
diff --git a/web/sass-files/sass/partials/_popover.scss b/web/sass-files/sass/partials/_popover.scss
index fa1b44841..5008331b4 100644
--- a/web/sass-files/sass/partials/_popover.scss
+++ b/web/sass-files/sass/partials/_popover.scss
@@ -6,4 +6,11 @@
.user-popover__image {
margin: 0 0 10px;
@include border-radius(128px);
+}
+
+.user-popover__email {
+ max-width: 200px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: block;
} \ No newline at end of file
diff --git a/web/sass-files/sass/partials/_responsive.scss b/web/sass-files/sass/partials/_responsive.scss
index e3f140413..47b2b6bd7 100644
--- a/web/sass-files/sass/partials/_responsive.scss
+++ b/web/sass-files/sass/partials/_responsive.scss
@@ -229,6 +229,16 @@
}
}
+@media screen and (max-height: 640px) {
+ .signup-team__container {
+ padding: 30px 0;
+ margin-bottom: 30px;
+ font-size: 0.9em;
+ .signup-team__name {
+ font-size: 2em;
+ }
+ }
+}
@media screen and (max-width: 768px) {
.date-separator, .new-separator {
&.hovered--after {
diff --git a/web/sass-files/sass/partials/_signup.scss b/web/sass-files/sass/partials/_signup.scss
index 4b6ee79a1..3a6f73316 100644
--- a/web/sass-files/sass/partials/_signup.scss
+++ b/web/sass-files/sass/partials/_signup.scss
@@ -54,6 +54,28 @@
margin-bottom: 1em;
}
+ .input-group {
+ &.input-group--limit {
+ table-layout: fixed;
+ width: 100%;
+ .tooltip-inner {
+ word-wrap: break-word;
+ }
+ .form-control {
+ text-align: left;
+ display: table-cell;
+ width: 100%;
+ }
+ .input-group-addon {
+ text-align: left;
+ width: 50%;
+ display: table-cell;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+ }
+ }
+
.inner__content {
padding: 0 15px;
margin: 30px 0 20px;
diff --git a/web/templates/channel.html b/web/templates/channel.html
index 6325069ee..da6fed97d 100644
--- a/web/templates/channel.html
+++ b/web/templates/channel.html
@@ -49,7 +49,9 @@
<div id="activity_log_modal"></div>
<div id="removed_from_channel_modal"></div>
<script>
-window.setup_channel_page('{{ .Props.TeamDisplayName }}', '{{ .Props.TeamType }}', '{{ .Props.TeamId }}', '{{ .Props.ChannelName }}', '{{ .Props.ChannelId }}');
+ window.setup_channel_page('{{ .Props.TeamDisplayName }}', '{{ .Props.TeamType }}', '{{ .Props.TeamId }}', '{{ .Props.ChannelName }}', '{{ .Props.ChannelId }}');
+ $('body').tooltip( {selector: '[data-toggle=tooltip]'} );
+ $('.modal-body').perfectScrollbar();
</script>
</body>
</html>
diff --git a/web/templates/signup_team.html b/web/templates/signup_team.html
index b84b8e486..313ed9d5f 100644
--- a/web/templates/signup_team.html
+++ b/web/templates/signup_team.html
@@ -10,7 +10,7 @@
<div class="signup-team__container">
<img class="signup-team-logo" src="/static/images/logo.png" />
<h1>Mattermost</h1>
- <h4 class="color--light">All team communication in one place, searchable and accesible anywhere</h4>
+ <h4 class="color--light">All team communication in one place, searchable and accessible anywhere</h4>
<div id="signup-team"></div>
</div>
</div>