diff options
Diffstat (limited to 'webapp/components')
-rw-r--r-- | webapp/components/admin_console/compliance_settings.jsx | 2 | ||||
-rw-r--r-- | webapp/components/admin_console/service_settings.jsx | 5 | ||||
-rw-r--r-- | webapp/components/admin_console/user_item.jsx | 2 | ||||
-rw-r--r-- | webapp/components/analytics/team_analytics.jsx | 2 | ||||
-rw-r--r-- | webapp/components/channel_header.jsx | 2 | ||||
-rw-r--r-- | webapp/components/channel_view.jsx | 19 | ||||
-rw-r--r-- | webapp/components/invite_member_modal.jsx | 18 | ||||
-rw-r--r-- | webapp/components/logged_in.jsx | 23 | ||||
-rw-r--r-- | webapp/components/msg_typing.jsx | 12 | ||||
-rw-r--r-- | webapp/components/permalink_view.jsx | 25 | ||||
-rw-r--r-- | webapp/components/popover_list_members.jsx | 9 | ||||
-rw-r--r-- | webapp/components/post.jsx | 2 | ||||
-rw-r--r-- | webapp/components/posts_view.jsx | 26 | ||||
-rw-r--r-- | webapp/components/posts_view_container.jsx | 12 | ||||
-rw-r--r-- | webapp/components/rhs_root_post.jsx | 2 | ||||
-rw-r--r-- | webapp/components/search_results_item.jsx | 3 | ||||
-rw-r--r-- | webapp/components/user_settings/user_settings_display.jsx | 2 | ||||
-rw-r--r-- | webapp/components/user_settings/user_settings_security.jsx | 3 |
18 files changed, 76 insertions, 93 deletions
diff --git a/webapp/components/admin_console/compliance_settings.jsx b/webapp/components/admin_console/compliance_settings.jsx index fb2ae26f9..206bb0faa 100644 --- a/webapp/components/admin_console/compliance_settings.jsx +++ b/webapp/components/admin_console/compliance_settings.jsx @@ -223,7 +223,7 @@ export default class ComplianceSettings extends React.Component { </label> <p className='help-text'> <FormattedMessage - id='admin.compliance.enableDesc' + id='admin.compliance.enableDailyDesc' defaultMessage='When true, Mattermost will generate a daily compliance report.' /> </p> diff --git a/webapp/components/admin_console/service_settings.jsx b/webapp/components/admin_console/service_settings.jsx index 41ea5ea34..c72c97326 100644 --- a/webapp/components/admin_console/service_settings.jsx +++ b/webapp/components/admin_console/service_settings.jsx @@ -84,10 +84,13 @@ class ServiceSettings extends React.Component { config.ServiceSettings.EnableDeveloper = ReactDOM.findDOMNode(this.refs.EnableDeveloper).checked; config.ServiceSettings.EnableSecurityFixAlert = ReactDOM.findDOMNode(this.refs.EnableSecurityFixAlert).checked; config.ServiceSettings.EnableInsecureOutgoingConnections = ReactDOM.findDOMNode(this.refs.EnableInsecureOutgoingConnections).checked; - config.ServiceSettings.EnableMultifactorAuthentication = ReactDOM.findDOMNode(this.refs.EnableMultifactorAuthentication).checked; config.ServiceSettings.EnableCommands = ReactDOM.findDOMNode(this.refs.EnableCommands).checked; config.ServiceSettings.EnableOnlyAdminIntegrations = ReactDOM.findDOMNode(this.refs.EnableOnlyAdminIntegrations).checked; + if (this.refs.EnablMultifactorAuthentication) { + config.ServiceSettings.EnableMultifactorAuthentication = ReactDOM.findDOMNode(this.refs.EnableMultifactorAuthentication).checked; + } + //config.ServiceSettings.EnableOAuthServiceProvider = ReactDOM.findDOMNode(this.refs.EnableOAuthServiceProvider).checked; var MaximumLoginAttempts = DefaultMaximumLoginAttempts; diff --git a/webapp/components/admin_console/user_item.jsx b/webapp/components/admin_console/user_item.jsx index 91f567d4d..c00050584 100644 --- a/webapp/components/admin_console/user_item.jsx +++ b/webapp/components/admin_console/user_item.jsx @@ -333,7 +333,7 @@ export default class UserItem extends React.Component { <div> <FormattedMessage id='admin.user_item.confirmDemoteDescription' - defaultMessage="If you demote yourself from the System Admin role and there is not another user with System Admin privileges, you\'ll need to re-assign a System Admin by accessing the Mattermost server through a terminal and running the following command." + defaultMessage="If you demote yourself from the System Admin role and there is not another user with System Admin privileges, you'll need to re-assign a System Admin by accessing the Mattermost server through a terminal and running the following command." /> <br/> <br/> diff --git a/webapp/components/analytics/team_analytics.jsx b/webapp/components/analytics/team_analytics.jsx index efc965f24..9b4eb1f94 100644 --- a/webapp/components/analytics/team_analytics.jsx +++ b/webapp/components/analytics/team_analytics.jsx @@ -154,7 +154,7 @@ class TeamAnalytics extends React.Component { <TableChart title={ <FormattedMessage - id='analytics.team.activeUsers' + id='analytics.team.recentUsers' defaultMessage='Recent Active Users' /> } diff --git a/webapp/components/channel_header.jsx b/webapp/components/channel_header.jsx index 6bb466c3e..482aabc01 100644 --- a/webapp/components/channel_header.jsx +++ b/webapp/components/channel_header.jsx @@ -216,9 +216,9 @@ export default class ChannelHeader extends React.Component { if (!isDirect) { popoverListMembers = ( <PopoverListMembers + channel={channel} members={this.state.users} memberCount={this.state.userCount} - channelId={channel.id} /> ); } diff --git a/webapp/components/channel_view.jsx b/webapp/components/channel_view.jsx index 54d796ac1..4cca5aa98 100644 --- a/webapp/components/channel_view.jsx +++ b/webapp/components/channel_view.jsx @@ -8,7 +8,6 @@ import PostsViewContainer from 'components/posts_view_container.jsx'; import CreatePost from 'components/create_post.jsx'; import ChannelStore from 'stores/channel_store.jsx'; -import UserStore from 'stores/user_store.jsx'; export default class ChannelView extends React.Component { constructor(props) { @@ -23,14 +22,12 @@ export default class ChannelView extends React.Component { getStateFromStores(props) { const channel = ChannelStore.getByName(props.params.channel); const channelId = channel ? channel.id : ''; - const profiles = JSON.parse(JSON.stringify(UserStore.getProfiles())); return { - channelId, - profiles + channelId }; } isStateValid() { - return this.state.channelId !== '' && this.state.profiles; + return this.state.channelId !== ''; } updateState() { this.setState(this.getStateFromStores(this.props)); @@ -44,13 +41,6 @@ export default class ChannelView extends React.Component { componentWillReceiveProps(nextProps) { this.setState(this.getStateFromStores(nextProps)); } - shouldComponentUpdate(nextProps, nextState) { - if (nextState.channelId !== this.state.channelId) { - return true; - } - - return false; - } render() { return ( <div @@ -60,7 +50,7 @@ export default class ChannelView extends React.Component { <ChannelHeader channelId={this.state.channelId} /> - <PostsViewContainer profiles={this.state.profiles}/> + <PostsViewContainer profiles={this.props.profiles}/> <div className='post-create__container' id='post-create' @@ -75,5 +65,6 @@ ChannelView.defaultProps = { }; ChannelView.propTypes = { - params: React.PropTypes.object.isRequired + params: React.PropTypes.object.isRequired, + profiles: React.PropTypes.object }; diff --git a/webapp/components/invite_member_modal.jsx b/webapp/components/invite_member_modal.jsx index 1f8fd6133..81c3a9629 100644 --- a/webapp/components/invite_member_modal.jsx +++ b/webapp/components/invite_member_modal.jsx @@ -50,6 +50,7 @@ class InviteMemberModal extends React.Component { constructor(props) { super(props); + this.teamChange = this.teamChange.bind(this); this.handleToggle = this.handleToggle.bind(this); this.handleSubmit = this.handleSubmit.bind(this); this.handleHide = this.handleHide.bind(this); @@ -68,16 +69,27 @@ class InviteMemberModal extends React.Component { emailEnabled: global.window.mm_config.SendEmailNotifications === 'true', userCreationEnabled: global.window.mm_config.EnableUserCreation === 'true', showConfirmModal: false, - isSendingEmails: false + isSendingEmails: false, + teamType: null }; } + teamChange() { + const team = TeamStore.getCurrent(); + const teamType = team ? team.type : null; + this.setState({ + teamType + }); + } + componentDidMount() { ModalStore.addModalListener(ActionTypes.TOGGLE_INVITE_MEMBER_MODAL, this.handleToggle); + TeamStore.addChangeListener(this.teamChange); } componentWillUnmount() { ModalStore.removeModalListener(ActionTypes.TOGGLE_INVITE_MEMBER_MODAL, this.handleToggle); + TeamStore.removeChangeListener(this.teamChange); } handleToggle(value) { @@ -224,7 +236,7 @@ class InviteMemberModal extends React.Component { var currentUser = UserStore.getCurrentUser(); const {formatMessage} = this.props.intl; - if (currentUser != null) { + if (currentUser != null && this.state.teamType != null) { var inviteSections = []; var inviteIds = this.state.inviteIds; for (var i = 0; i < inviteIds.length; i++) { @@ -398,7 +410,7 @@ class InviteMemberModal extends React.Component { ); } else if (this.state.userCreationEnabled) { var teamInviteLink = null; - if (currentUser && TeamStore.getCurrent().type === 'O') { + if (currentUser && this.state.teamType === 'O') { var link = ( <a href='#' diff --git a/webapp/components/logged_in.jsx b/webapp/components/logged_in.jsx index f7a6be647..0c4571083 100644 --- a/webapp/components/logged_in.jsx +++ b/webapp/components/logged_in.jsx @@ -47,11 +47,12 @@ export default class LoggedIn extends React.Component { this.onUserChanged = this.onUserChanged.bind(this); this.state = { - user: null + user: null, + profiles: null }; } isValidState() { - return this.state.user != null; + return this.state.user != null && this.state.profiles != null; } onUserChanged() { // Grab the current user @@ -84,7 +85,13 @@ export default class LoggedIn extends React.Component { browserHistory.push(Utils.getTeamURLFromAddressBar() + '/tutorial'); } - this.setState({user}); + // Get profiles + const profiles = UserStore.getProfiles(); + + this.setState({ + user, + profiles + }); } componentWillMount() { // Emit view action @@ -232,7 +239,10 @@ export default class LoggedIn extends React.Component { </div> </div> <div className='row main'> - {this.props.center} + {React.cloneElement(this.props.center, { + user: this.state.user, + profiles: this.state.profiles + })} </div> </div> ); @@ -266,7 +276,10 @@ LoggedIn.defaultProps = { }; LoggedIn.propTypes = { - children: React.PropTypes.arrayOf(React.PropTypes.element), + children: React.PropTypes.oneOfType([ + React.PropTypes.arrayOf(React.PropTypes.element), + React.PropTypes.element + ]), navbar: React.PropTypes.element, sidebar: React.PropTypes.element, center: React.PropTypes.element, diff --git a/webapp/components/msg_typing.jsx b/webapp/components/msg_typing.jsx index b2d414287..631eea78d 100644 --- a/webapp/components/msg_typing.jsx +++ b/webapp/components/msg_typing.jsx @@ -40,13 +40,15 @@ class MsgTyping extends React.Component { } updateTypingText(typingUsers) { - if (!typingUsers) { - return; + let text = ''; + let users = {}; + let numUsers = 0; + if (typingUsers) { + users = Object.keys(typingUsers); + numUsers = users.length; } - const users = Object.keys(typingUsers); - let text = ''; - switch (users.length) { + switch (numUsers) { case 0: text = ''; break; diff --git a/webapp/components/permalink_view.jsx b/webapp/components/permalink_view.jsx index 2ebe52356..2c32d643d 100644 --- a/webapp/components/permalink_view.jsx +++ b/webapp/components/permalink_view.jsx @@ -7,7 +7,6 @@ import ChannelHeader from 'components/channel_header.jsx'; import PostFocusView from 'components/post_focus_view.jsx'; import ChannelStore from 'stores/channel_store.jsx'; -import UserStore from 'stores/user_store.jsx'; import TeamStore from 'stores/team_store.jsx'; import {Link} from 'react-router'; @@ -30,17 +29,15 @@ export default class PermalinkView extends React.Component { const channelName = channel ? channel.name : ''; const team = TeamStore.getCurrent(); const teamName = team ? team.name : ''; - const profiles = JSON.parse(JSON.stringify(UserStore.getProfiles())); return { channelId, channelName, - profiles, teamName, postId }; } isStateValid() { - return this.state.channelId !== '' && this.state.profiles && this.state.teamName; + return this.state.channelId !== '' && this.state.teamName; } updateState() { this.setState(this.getStateFromStores(this.props)); @@ -56,21 +53,6 @@ export default class PermalinkView extends React.Component { componentWillReceiveProps(nextProps) { this.setState(this.getStateFromStores(nextProps)); } - shouldComponentUpdate(nextProps, nextState) { - if (nextState.postId !== this.state.postId) { - return true; - } - - if (nextState.channelId !== this.state.channelId) { - return true; - } - - if (nextState.teamName !== this.state.teamName) { - return true; - } - - return false; - } render() { if (!this.isStateValid()) { return null; @@ -83,7 +65,7 @@ export default class PermalinkView extends React.Component { <ChannelHeader channelId={this.state.channelId} /> - <PostFocusView profiles={this.state.profiles}/> + <PostFocusView profiles={this.props.profiles}/> <div id='archive-link-home' > @@ -106,5 +88,6 @@ PermalinkView.defaultProps = { }; PermalinkView.propTypes = { - params: React.PropTypes.object.isRequired + params: React.PropTypes.object.isRequired, + profiles: React.PropTypes.object }; diff --git a/webapp/components/popover_list_members.jsx b/webapp/components/popover_list_members.jsx index cd583e4c3..226a1889c 100644 --- a/webapp/components/popover_list_members.jsx +++ b/webapp/components/popover_list_members.jsx @@ -9,8 +9,6 @@ import * as Utils from 'utils/utils.jsx'; import * as GlobalActions from 'action_creators/global_actions.jsx'; import Constants from 'utils/constants.jsx'; -import ChannelStore from 'stores/channel_store.jsx'; - import {FormattedMessage} from 'react-intl'; import React from 'react'; @@ -57,7 +55,6 @@ export default class PopoverListMembers extends React.Component { const members = this.props.members; const teamMembers = UserStore.getProfilesUsernameMap(); const currentUserId = UserStore.getCurrentId(); - const ch = ChannelStore.getCurrent(); if (members && teamMembers) { members.sort((a, b) => { @@ -69,7 +66,7 @@ export default class PopoverListMembers extends React.Component { members.forEach((m, i) => { let button = ''; - if (currentUserId !== m.id && ch.type !== 'D') { + if (currentUserId !== m.id && this.props.channel.type !== 'D') { button = ( <a href='#' @@ -177,7 +174,7 @@ export default class PopoverListMembers extends React.Component { } PopoverListMembers.propTypes = { + channel: React.PropTypes.object.isRequired, members: React.PropTypes.array.isRequired, - memberCount: React.PropTypes.number, - channelId: React.PropTypes.string.isRequired + memberCount: React.PropTypes.number }; diff --git a/webapp/components/post.jsx b/webapp/components/post.jsx index f2818188a..30c47ee22 100644 --- a/webapp/components/post.jsx +++ b/webapp/components/post.jsx @@ -188,6 +188,8 @@ export default class Post extends React.Component { if (post.props && post.props.from_webhook && global.window.mm_config.EnablePostIconOverride === 'true') { if (post.props.override_icon_url) { src = post.props.override_icon_url; + } else { + src = Constants.DEFAULT_WEBHOOK_LOGO; } } else if (Utils.isSystemMessage(post)) { src = Constants.SYSTEM_MESSAGE_PROFILE_IMAGE; diff --git a/webapp/components/posts_view.jsx b/webapp/components/posts_view.jsx index 647c7f086..ffe04daa1 100644 --- a/webapp/components/posts_view.jsx +++ b/webapp/components/posts_view.jsx @@ -173,24 +173,15 @@ export default class PostsView extends React.Component { const postFromWebhook = Boolean(post.props && post.props.from_webhook); const prevPostFromWebhook = Boolean(prevPost.props && prevPost.props.from_webhook); const prevPostUserId = Utils.isSystemMessage(prevPost) ? '' : prevPost.user_id; - let prevWebhookName = ''; - if (prevPost.props && prevPost.props.override_username) { - prevWebhookName = prevPost.props.override_username; - } - let curWebhookName = ''; - if (post.props && post.props.override_username) { - curWebhookName = post.props.override_username; - } // consider posts from the same user if: // the previous post was made by the same user as the current post, // the previous post was made within 5 minutes of the current post, - // the previous post and current post are both from webhooks or both not, - // the previous post and current post have the same webhook usernames + // the current post is not from a webhook + // the previous post is not from a webhook if (prevPostUserId === postUserId && post.create_at - prevPost.create_at <= 1000 * 60 * 5 && - postFromWebhook === prevPostFromWebhook && - prevWebhookName === curWebhookName) { + !postFromWebhook && !prevPostFromWebhook) { sameUser = true; } @@ -213,13 +204,11 @@ export default class PostsView extends React.Component { // the previous post was made by the same user as the current post, // the previous post is not a comment, // the current post is not a comment, - // the previous post and current post are both from webhooks or both not, - // the previous post and current post have the same webhook usernames + // the current post is not from a webhook if (prevPostUserId === postUserId && !prevPostIsComment && !postIsComment && - postFromWebhook === prevPostFromWebhook && - prevWebhookName === curWebhookName) { + !postFromWebhook) { hideProfilePic = true; } } @@ -319,7 +308,7 @@ export default class PostsView extends React.Component { if (this.props.scrollType === PostsView.SCROLL_TYPE_BOTTOM) { this.scrollToBottom(); } else if (this.props.scrollType === PostsView.SCROLL_TYPE_NEW_MESSAGE) { - window.requestAnimationFrame(() => { + window.setTimeout(window.requestAnimationFrame(() => { // If separator exists scroll to it. Otherwise scroll to bottom. if (this.refs.newMessageSeparator) { var objDiv = this.refs.postlist; @@ -327,7 +316,7 @@ export default class PostsView extends React.Component { } else if (this.refs.postlist) { this.refs.postlist.scrollTop = this.refs.postlist.scrollHeight; } - }); + }), 0); } else if (this.props.scrollType === PostsView.SCROLL_TYPE_POST && this.props.scrollPostId) { window.requestAnimationFrame(() => { const postNode = ReactDOM.findDOMNode(this.refs[this.props.scrollPostId]); @@ -385,6 +374,7 @@ export default class PostsView extends React.Component { componentWillUnmount() { window.removeEventListener('resize', this.handleResize); this.scrollStopAction.cancel(); + PreferenceStore.removeChangeListener(this.updateState); } componentDidUpdate() { if (this.props.postList != null) { diff --git a/webapp/components/posts_view_container.jsx b/webapp/components/posts_view_container.jsx index 7e334d4b0..a49c77f8d 100644 --- a/webapp/components/posts_view_container.jsx +++ b/webapp/components/posts_view_container.jsx @@ -8,7 +8,6 @@ import ChannelStore from 'stores/channel_store.jsx'; import PostStore from 'stores/post_store.jsx'; import UserStore from 'stores/user_store.jsx'; -import * as Utils from 'utils/utils.jsx'; import * as GlobalActions from 'action_creators/global_actions.jsx'; import Constants from 'utils/constants.jsx'; @@ -158,17 +157,6 @@ export default class PostsViewContainer extends React.Component { this.setState({scrollType: PostsView.SCROLL_TYPE_FREE}); } } - shouldComponentUpdate(nextProps, nextState) { - if (!Utils.areObjectsEqual(this.state, nextState)) { - return true; - } - - if (!Utils.areObjectsEqual(this.props, nextProps)) { - return true; - } - - return false; - } render() { const postLists = this.state.postLists; const channels = this.state.channels; diff --git a/webapp/components/rhs_root_post.jsx b/webapp/components/rhs_root_post.jsx index 26b392aa1..7a7c5f692 100644 --- a/webapp/components/rhs_root_post.jsx +++ b/webapp/components/rhs_root_post.jsx @@ -217,6 +217,8 @@ export default class RhsRootPost extends React.Component { if (post.props && post.props.from_webhook && global.window.mm_config.EnablePostIconOverride === 'true') { if (post.props.override_icon_url) { src = post.props.override_icon_url; + } else { + src = Constants.DEFAULT_WEBHOOK_LOGO; } } else if (Utils.isSystemMessage(post)) { src = Constants.SYSTEM_MESSAGE_PROFILE_IMAGE; diff --git a/webapp/components/search_results_item.jsx b/webapp/components/search_results_item.jsx index 219aa7093..75cbcb2a0 100644 --- a/webapp/components/search_results_item.jsx +++ b/webapp/components/search_results_item.jsx @@ -5,7 +5,6 @@ import UserStore from 'stores/user_store.jsx'; import UserProfile from './user_profile.jsx'; import * as GlobalActions from 'action_creators/global_actions.jsx'; import * as TextFormatting from 'utils/text_formatting.jsx'; -import * as Utils from 'utils/utils.jsx'; import Constants from 'utils/constants.jsx'; @@ -88,7 +87,7 @@ export default class SearchResultsItem extends React.Component { </li> <li> <Link - to={Utils.getTeamURLFromAddressBar() + '/pl/' + this.props.post.id} + to={'/' + window.location.pathname.split('/')[1] + '/pl/' + this.props.post.id} className='search-item__jump' > <FormattedMessage diff --git a/webapp/components/user_settings/user_settings_display.jsx b/webapp/components/user_settings/user_settings_display.jsx index d815bd371..d169e01b5 100644 --- a/webapp/components/user_settings/user_settings_display.jsx +++ b/webapp/components/user_settings/user_settings_display.jsx @@ -304,7 +304,7 @@ export default class UserSettingsDisplay extends React.Component { describe = ( <FormattedMessage id='user.settings.display.showUsername' - defaultMessage='Show username (team default)' + defaultMessage='Show username (default)' /> ); } else if (this.state.nameFormat === 'full_name') { diff --git a/webapp/components/user_settings/user_settings_security.jsx b/webapp/components/user_settings/user_settings_security.jsx index e4044e6d0..ff5a898a9 100644 --- a/webapp/components/user_settings/user_settings_security.jsx +++ b/webapp/components/user_settings/user_settings_security.jsx @@ -1,6 +1,7 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. +import $ from 'jquery'; import SettingItemMin from '../setting_item_min.jsx'; import SettingItemMax from '../setting_item_max.jsx'; import AccessHistoryModal from '../access_history_modal.jsx'; @@ -247,7 +248,7 @@ class SecurityTab extends React.Component { extraInfo = ( <span> <FormattedMessage - id='user.settings.mfa.addHelp' + id='user.settings.mfa.addHelpQr' defaultMessage='Please scan the QR code with the Google Authenticator app on your smartphone and fill in the token with one provided by the app.' /> </span> |