summaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rw-r--r--web/react/components/access_history_modal.jsx16
-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/post_list.jsx7
-rw-r--r--web/react/components/rename_channel_modal.jsx2
-rw-r--r--web/react/components/search_bar.jsx11
-rw-r--r--web/react/components/sidebar_header.jsx6
-rw-r--r--web/react/components/signup_team_complete.jsx44
-rw-r--r--web/react/stores/user_store.jsx4
-rw-r--r--web/sass-files/sass/partials/_headers.scss39
-rw-r--r--web/sass-files/sass/partials/_navbar.scss14
-rw-r--r--web/sass-files/sass/partials/_responsive.scss44
-rw-r--r--web/sass-files/sass/partials/_search.scss37
-rw-r--r--web/sass-files/sass/partials/_signup.scss2
14 files changed, 168 insertions, 87 deletions
diff --git a/web/react/components/access_history_modal.jsx b/web/react/components/access_history_modal.jsx
index 462f046f6..6cc8ec8a9 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,7 +15,9 @@ 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) {
@@ -25,7 +28,10 @@ module.exports = React.createClass({
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;
@@ -87,9 +93,13 @@ module.exports = React.createClass({
<h4 className="modal-title" id="myModalLabel">Access History</h4>
</div>
<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/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..d67ab3afe 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);
},
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/sidebar_header.jsx b/web/react/components/sidebar_header.jsx
index e7512934a..0156dc01a 100644
--- a/web/react/components/sidebar_header.jsx
+++ b/web/react/components/sidebar_header.jsx
@@ -107,6 +107,10 @@ module.exports = React.createClass({
};
},
+ toggleDropdown: function(e) {
+ $('.team__header').find('.dropdown-toggle').trigger('click');
+ },
+
render: function() {
var me = UserStore.getCurrentUser();
@@ -116,7 +120,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} />
:
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/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/sass-files/sass/partials/_headers.scss b/web/sass-files/sass/partials/_headers.scss
index 687e330a6..fb37c43eb 100644
--- a/web/sass-files/sass/partials/_headers.scss
+++ b/web/sass-files/sass/partials/_headers.scss
@@ -84,8 +84,32 @@
// Team Header in Sidebar
.sidebar--left, .sidebar--menu {
.team__header {
+ position: relative;
padding: 10px;
@include legacy-pie-clearfix;
+ &:before {
+ @include single-transition(all, 0.05s, linear);
+ content: "";
+ background: none;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ }
+ &:hover {
+ &:before {
+ background: rgba(black, 0.1);
+ }
+ .user__name {
+ color: #fff;
+ }
+ .navbar-right {
+ .dropdown-toggle {
+ @include opacity(1);
+ }
+ }
+ }
a {
color: #fff;
}
@@ -94,12 +118,11 @@
position: absolute;
top: 10px;
right: 22px;
+ z-index: 5;
.dropdown-toggle {
+ @include single-transition(all, 0.1s, linear);
padding: 10px;
@include opacity(0.8);
- &:hover {
- @include opacity(1);
- }
}
.dropdown-menu {
li a {
@@ -124,6 +147,8 @@
.header__info {
color: #fff;
padding-left: 4px;
+ z-index: 1;
+ position: relative;
}
.team__name, .user__name {
display: block;
@@ -137,9 +162,11 @@
text-decoration: none;
}
.user__name {
+ @include single-transition(all, 0.1s, linear);
font-size: 14px;
font-weight: 400;
color: #eee;
+ color: rgba(#fff, 0.8);
}
> .nav {
> li {
@@ -250,10 +277,10 @@
vertical-align: top;
display: inline-block;
width: 15px;
- margin: 9px 4px 3px 0;
+ margin: 9px 6px 3px 0;
&:hover {
svg {
- fill: #888;
+ fill: #777;
}
}
a {
@@ -263,6 +290,6 @@
svg {
vertical-align: top;
margin-top: 8px;
- fill: #AAA;
+ fill: #aaa;
}
}
diff --git a/web/sass-files/sass/partials/_navbar.scss b/web/sass-files/sass/partials/_navbar.scss
index e5e67a9e0..905907d84 100644
--- a/web/sass-files/sass/partials/_navbar.scss
+++ b/web/sass-files/sass/partials/_navbar.scss
@@ -5,15 +5,15 @@
.navbar-default {
position: absolute;
border: none;
- min-height: 50px;
+ min-height: 45px;
background: $primary-color;
.navbar-nav {
> li {
> a {
- height: 50px;
+ height: 45px;
padding: 0 1.3em;
i {
- line-height: 50px;
+ line-height: 45px;
}
}
}
@@ -24,8 +24,8 @@
border-radius: 0;
margin: 0;
padding: 0 10px;
- line-height: 53px;
- height: 50px;
+ line-height: 48px;
+ height: 44px;
z-index: 5;
fill: #fff;
.icon-bar {
@@ -38,8 +38,8 @@
}
.navbar-brand {
padding: 0 0.5em;
- height: 50px;
- line-height: 50px;
+ height: 45px;
+ line-height: 45px;
float: none;
font-size: 16px;
.heading {
diff --git a/web/sass-files/sass/partials/_responsive.scss b/web/sass-files/sass/partials/_responsive.scss
index 719934638..81b94ab5a 100644
--- a/web/sass-files/sass/partials/_responsive.scss
+++ b/web/sass-files/sass/partials/_responsive.scss
@@ -448,28 +448,39 @@
}
}
.search-bar__container {
- padding: 10px 8px 13px;
+ padding: 0;
+ height: 45px;
background: $primary-color;
color: #fff;
+ &.focused {
+ .sidebar__collapse {
+ @include translateX(-45px);
+ }
+ .search__form {
+ padding-left: 10px;
+ padding-right: 67px;
+ }
+ .search__clear {
+ display: block;
+ }
+ }
.search__form {
border: none;
- padding: 0 60px 0 35px;
+ padding: 7px 20px 0 49px;
+ height: 45px;
+ position: relative;
+ @include single-transition(all, 0.2s, linear);
.form-control {
- line-height: normal;
- background: none;
+ border: none;
+ padding: 0 10px 0 31px;
+ background: rgba(black, 0.2);
+ @include border-radius(3px);
color: #fff;
- border-radius: 0;
- padding: 0;
- border-bottom: 1px solid #FFF;
- border-bottom: 1px solid rgba(#fff, 0.4);
- &:focus {
- border-bottom: 1px solid rgba(#fff, 0.8);
- }
}
input[type=text] {
- @include input-placeholder {
+ @include input-placeholder {
color: #fff;
- color: rgba(#fff, 0.6);
+ color: rgba(#fff, 0.5);
}
}
}
@@ -550,11 +561,6 @@
.sidebar--right__close {
display: none;
}
- .search__form {
- .glyphicon {
- color: #fff;
- }
- }
}
.inner__wrap {
&.move--right {
@@ -650,7 +656,7 @@
display: block;
}
.access__report {
- margin: 0 0 15px 15px;
+ margin: 0 0 15px 15px;
}
.access__date {
div {
diff --git a/web/sass-files/sass/partials/_search.scss b/web/sass-files/sass/partials/_search.scss
index 794358320..e2168ef75 100644
--- a/web/sass-files/sass/partials/_search.scss
+++ b/web/sass-files/sass/partials/_search.scss
@@ -1,23 +1,37 @@
.search-bar__container {
padding: 8px 8px 8px 0;
}
-.sidebar__collapse {
- width: auto;
- height: auto;
+.search__clear {
+ display: none;
position: absolute;
- top: 1px;
- right: 15px;
+ right: 0;
+ line-height: 45px;
+ margin-right: 13px;
+ z-index: 5;
+ cursor: pointer;
+}
+.sidebar__collapse {
cursor: pointer;
- padding: 1em 0;
z-index: 5;
+ fill: #FFF;
+ position: absolute;
+ left: 0;
+ font-size: 35px;
+ width: 49px;
+ @include single-transition(all, 0.2s, linear);
+ @include translateX(0px);
+ text-align: center;
+ padding-left: 1px;
+ line-height: 40px;
display: none;
}
.sidebar__search-icon {
position: absolute;
- left: 15px;
- top: 18px;
- font-size: 16px;
- @include opacity(0.8);
+ top: 15px;
+ margin-left: 10px;
+ font-size: 14px;
+ color: #fff;
+ color: rgba(#fff, 0.5);
display: none;
}
.search__form {
@@ -30,9 +44,8 @@
.sidebar--right & {
width: 100%;
}
- .search-bar-box {
+ .search-bar {
height: 40px;
- border: 1px solid #ddd;
padding-right: 30px;
box-shadow: none;
.search-bar__container & {
diff --git a/web/sass-files/sass/partials/_signup.scss b/web/sass-files/sass/partials/_signup.scss
index 1a0c55f39..4b6ee79a1 100644
--- a/web/sass-files/sass/partials/_signup.scss
+++ b/web/sass-files/sass/partials/_signup.scss
@@ -74,7 +74,7 @@
.form__hint {
font-size: 0.95em;
color: #999;
- margin: 10px 0;
+ margin: 10px 0 0;
}
.signup-team-confirm__container {