summaryrefslogtreecommitdiffstats
path: root/web/react/components
diff options
context:
space:
mode:
Diffstat (limited to 'web/react/components')
-rw-r--r--web/react/components/admin_console/admin_sidebar.jsx1
-rw-r--r--web/react/components/admin_console/user_item.jsx2
-rw-r--r--web/react/components/channel_info_modal.jsx2
-rw-r--r--web/react/components/channel_loader.jsx4
-rw-r--r--web/react/components/navbar.jsx2
-rw-r--r--web/react/components/popover_list_members.jsx2
-rw-r--r--web/react/components/post_info.jsx3
-rw-r--r--web/react/components/posts_view.jsx10
-rw-r--r--web/react/components/rhs_comment.jsx22
-rw-r--r--web/react/components/rhs_root_post.jsx22
-rw-r--r--web/react/components/search_results.jsx15
-rw-r--r--web/react/components/team_general_tab.jsx8
-rw-r--r--web/react/components/team_signup_email_item.jsx2
-rw-r--r--web/react/components/team_signup_send_invites_page.jsx4
-rw-r--r--web/react/components/user_settings/manage_command_hooks.jsx4
-rw-r--r--web/react/components/user_settings/manage_incoming_hooks.jsx2
-rw-r--r--web/react/components/user_settings/manage_outgoing_hooks.jsx9
-rw-r--r--web/react/components/user_settings/user_settings_modal.jsx19
-rw-r--r--web/react/components/user_settings/user_settings_security.jsx8
19 files changed, 106 insertions, 35 deletions
diff --git a/web/react/components/admin_console/admin_sidebar.jsx b/web/react/components/admin_console/admin_sidebar.jsx
index eadd8d412..795b19eec 100644
--- a/web/react/components/admin_console/admin_sidebar.jsx
+++ b/web/react/components/admin_console/admin_sidebar.jsx
@@ -50,6 +50,7 @@ export default class AdminSidebar extends React.Component {
removeTeam(teamId, e) {
e.preventDefault();
+ e.stopPropagation();
Reflect.deleteProperty(this.props.selectedTeams, teamId);
this.props.removeSelectedTeam(teamId);
diff --git a/web/react/components/admin_console/user_item.jsx b/web/react/components/admin_console/user_item.jsx
index 0c1a55cc1..009a9f004 100644
--- a/web/react/components/admin_console/user_item.jsx
+++ b/web/react/components/admin_console/user_item.jsx
@@ -353,7 +353,7 @@ export default class UserItem extends React.Component {
return (
<tr>
- <td className='row member-div'>
+ <td className='row member-div padding--equal'>
<img
className='post-profile-img pull-left'
src={`/api/v1/users/${user.id}/image?time=${user.update_at}&${Utils.getSessionIndex()}`}
diff --git a/web/react/components/channel_info_modal.jsx b/web/react/components/channel_info_modal.jsx
index 5067f5913..83f5aba65 100644
--- a/web/react/components/channel_info_modal.jsx
+++ b/web/react/components/channel_info_modal.jsx
@@ -56,7 +56,7 @@ class ChannelInfoModal extends React.Component {
</div>
<div className='col-sm-9'>{channelURL}</div>
</div>
- <div className='row'>
+ <div className='row form-group'>
<div className='col-sm-3 info__label'>
<FormattedMessage
id='channel_info.id'
diff --git a/web/react/components/channel_loader.jsx b/web/react/components/channel_loader.jsx
index 174c8c4e1..f3000ee05 100644
--- a/web/react/components/channel_loader.jsx
+++ b/web/react/components/channel_loader.jsx
@@ -95,6 +95,8 @@ class ChannelLoader extends React.Component {
$(window).on('focus', function windowFocus() {
AsyncClient.updateLastViewedAt();
+ ChannelStore.resetCounts(ChannelStore.getCurrentId());
+ ChannelStore.emitChange();
window.isActive = true;
});
@@ -185,4 +187,4 @@ ChannelLoader.propTypes = {
intl: intlShape.isRequired
};
-export default injectIntl(ChannelLoader); \ No newline at end of file
+export default injectIntl(ChannelLoader);
diff --git a/web/react/components/navbar.jsx b/web/react/components/navbar.jsx
index e6a9fbd25..835298635 100644
--- a/web/react/components/navbar.jsx
+++ b/web/react/components/navbar.jsx
@@ -25,6 +25,7 @@ const ActionTypes = Constants.ActionTypes;
import AppDispatcher from '../dispatcher/app_dispatcher.jsx';
import {FormattedMessage} from 'mm-intl';
+import attachFastClick from 'fastclick';
const Popover = ReactBootstrap.Popover;
const OverlayTrigger = ReactBootstrap.OverlayTrigger;
@@ -59,6 +60,7 @@ export default class Navbar extends React.Component {
ChannelStore.addChangeListener(this.onChange);
ChannelStore.addExtraInfoChangeListener(this.onChange);
$('.inner__wrap').click(this.hideSidebars);
+ attachFastClick(document.body);
}
componentWillUnmount() {
ChannelStore.removeChangeListener(this.onChange);
diff --git a/web/react/components/popover_list_members.jsx b/web/react/components/popover_list_members.jsx
index f217229ed..afff78bae 100644
--- a/web/react/components/popover_list_members.jsx
+++ b/web/react/components/popover_list_members.jsx
@@ -107,7 +107,7 @@ export default class PopoverListMembers extends React.Component {
name = Utils.displayUsername(teamMembers[m.username].id);
}
- if (name && teamMembers[m.username].delete_at <= 0) {
+ if (name) {
popoverHtml.push(
<div
className='text-nowrap'
diff --git a/web/react/components/post_info.jsx b/web/react/components/post_info.jsx
index 6d82423d5..c44223b1f 100644
--- a/web/react/components/post_info.jsx
+++ b/web/react/components/post_info.jsx
@@ -144,7 +144,8 @@ export default class PostInfo extends React.Component {
);
}
- handlePermalink() {
+ handlePermalink(e) {
+ e.preventDefault();
EventHelpers.showGetPostLinkModal(this.props.post);
}
diff --git a/web/react/components/posts_view.jsx b/web/react/components/posts_view.jsx
index ebe19abad..19ab7d5aa 100644
--- a/web/react/components/posts_view.jsx
+++ b/web/react/components/posts_view.jsx
@@ -535,7 +535,15 @@ function FloatingTimestamp({isScrolling, post}) {
return <noscript />;
}
- const dateString = Utils.getDateForUnixTicks(post.create_at).toDateString();
+ const dateString = (
+ <FormattedDate
+ value={post.create_at}
+ weekday='short'
+ day='2-digit'
+ month='short'
+ year='numeric'
+ />
+ );
let className = 'post-list__timestamp';
if (isScrolling) {
diff --git a/web/react/components/rhs_comment.jsx b/web/react/components/rhs_comment.jsx
index 9c85e9940..0d15c8599 100644
--- a/web/react/components/rhs_comment.jsx
+++ b/web/react/components/rhs_comment.jsx
@@ -31,6 +31,7 @@ class RhsComment extends React.Component {
this.retryComment = this.retryComment.bind(this);
this.parseEmojis = this.parseEmojis.bind(this);
+ this.handlePermalink = this.handlePermalink.bind(this);
this.state = {};
}
@@ -67,6 +68,10 @@ class RhsComment extends React.Component {
parseEmojis() {
twemoji.parse(ReactDOM.findDOMNode(this), {size: Constants.EMOJI_SIZE});
}
+ handlePermalink(e) {
+ e.preventDefault();
+ EventHelpers.showGetPostLinkModal(this.props.post);
+ }
componentDidMount() {
this.parseEmojis();
}
@@ -92,6 +97,23 @@ class RhsComment extends React.Component {
var dropdownContents = [];
+ dropdownContents.push(
+ <li
+ key='rhs-root-permalink'
+ role='presentation'
+ >
+ <a
+ href='#'
+ onClick={this.handlePermalink}
+ >
+ <FormattedMessage
+ id='rhs_comment.permalink'
+ defaultMessage='Permalink'
+ />
+ </a>
+ </li>
+ );
+
if (isOwner) {
dropdownContents.push(
<li
diff --git a/web/react/components/rhs_root_post.jsx b/web/react/components/rhs_root_post.jsx
index f9f7f8f81..54f2e8262 100644
--- a/web/react/components/rhs_root_post.jsx
+++ b/web/react/components/rhs_root_post.jsx
@@ -21,6 +21,7 @@ export default class RhsRootPost extends React.Component {
super(props);
this.parseEmojis = this.parseEmojis.bind(this);
+ this.handlePermalink = this.handlePermalink.bind(this);
this.state = {};
}
@@ -31,6 +32,10 @@ export default class RhsRootPost extends React.Component {
folder: Emoji.getImagePathForEmoticon()
});
}
+ handlePermalink(e) {
+ e.preventDefault();
+ EventHelpers.showGetPostLinkModal(this.props.post);
+ }
componentDidMount() {
this.parseEmojis();
}
@@ -83,6 +88,23 @@ export default class RhsRootPost extends React.Component {
var dropdownContents = [];
+ dropdownContents.push(
+ <li
+ key='rhs-root-permalink'
+ role='presentation'
+ >
+ <a
+ href='#'
+ onClick={this.handlePermalink}
+ >
+ <FormattedMessage
+ id='rhs_root.permalink'
+ defaultMessage='Permalink'
+ />
+ </a>
+ </li>
+ );
+
if (isOwner) {
dropdownContents.push(
<li
diff --git a/web/react/components/search_results.jsx b/web/react/components/search_results.jsx
index 4adc3afe0..12c066734 100644
--- a/web/react/components/search_results.jsx
+++ b/web/react/components/search_results.jsx
@@ -15,13 +15,16 @@ function getStateFromStores() {
const results = SearchStore.getSearchResults();
const channels = new Map();
- const channelIds = results.order.map((postId) => results.posts[postId].channel_id);
- for (const id of channelIds) {
- if (channels.has(id)) {
- continue;
- }
- channels.set(id, ChannelStore.get(id));
+ if (results && results.order) {
+ const channelIds = results.order.map((postId) => results.posts[postId].channel_id);
+ for (const id of channelIds) {
+ if (channels.has(id)) {
+ continue;
+ }
+
+ channels.set(id, ChannelStore.get(id));
+ }
}
return {
diff --git a/web/react/components/team_general_tab.jsx b/web/react/components/team_general_tab.jsx
index 0a1b02853..c1b2a2e7f 100644
--- a/web/react/components/team_general_tab.jsx
+++ b/web/react/components/team_general_tab.jsx
@@ -486,13 +486,9 @@ class GeneralTab extends React.Component {
inputs.push(
<div key='teamInviteSetting'>
<div className='row'>
- <label className='col-sm-5 control-label'>
- <FormattedMessage
- id='general_tab.codeTitle'
- defaultMessage='Invite Code'
- />
+ <label className='col-sm-5 control-label visible-xs-block'>
</label>
- <div className='col-sm-7'>
+ <div className='col-sm-12'>
<input
className='form-control'
type='text'
diff --git a/web/react/components/team_signup_email_item.jsx b/web/react/components/team_signup_email_item.jsx
index feb70dc71..790ec2e5d 100644
--- a/web/react/components/team_signup_email_item.jsx
+++ b/web/react/components/team_signup_email_item.jsx
@@ -83,4 +83,4 @@ TeamSignupEmailItem.propTypes = {
email: React.PropTypes.string
};
-export default injectIntl(TeamSignupEmailItem); \ No newline at end of file
+export default injectIntl(TeamSignupEmailItem, {withRef: true});
diff --git a/web/react/components/team_signup_send_invites_page.jsx b/web/react/components/team_signup_send_invites_page.jsx
index 46a6bc68e..343db13e8 100644
--- a/web/react/components/team_signup_send_invites_page.jsx
+++ b/web/react/components/team_signup_send_invites_page.jsx
@@ -33,8 +33,8 @@ export default class TeamSignupSendInvitesPage extends React.Component {
var emails = [];
for (var i = 0; i < this.props.state.invites.length; i++) {
- if (this.refs['email_' + i].validate(this.props.state.team.email)) {
- emails.push(this.refs['email_' + i].getValue());
+ if (this.refs['email_' + i].getWrappedInstance().validate(this.props.state.team.email)) {
+ emails.push(this.refs['email_' + i].getWrappedInstance().getValue());
} else {
valid = false;
}
diff --git a/web/react/components/user_settings/manage_command_hooks.jsx b/web/react/components/user_settings/manage_command_hooks.jsx
index f4009aeaa..bd0659a47 100644
--- a/web/react/components/user_settings/manage_command_hooks.jsx
+++ b/web/react/components/user_settings/manage_command_hooks.jsx
@@ -257,7 +257,7 @@ export default class ManageCommandCmds extends React.Component {
let triggerDiv;
if (cmd.trigger && cmd.trigger.length !== 0) {
triggerDiv = (
- <div className='padding-top'>
+ <div className='padding-top x2'>
<strong>
<FormattedMessage
id='user.settings.cmds.trigger'
@@ -371,7 +371,7 @@ export default class ManageCommandCmds extends React.Component {
/>
</a>
<a
- className='webcmd__remove'
+ className='webhook__remove webcmd__remove'
href='#'
onClick={this.removeCmd.bind(this, cmd.id)}
>
diff --git a/web/react/components/user_settings/manage_incoming_hooks.jsx b/web/react/components/user_settings/manage_incoming_hooks.jsx
index c6532b018..e79ec6f6c 100644
--- a/web/react/components/user_settings/manage_incoming_hooks.jsx
+++ b/web/react/components/user_settings/manage_incoming_hooks.jsx
@@ -183,7 +183,7 @@ export default class ManageIncomingHooks extends React.Component {
<div key='addIncomingHook'>
<FormattedHTMLMessage
id='user.settings.hooks_in.description'
- defaultMessage='Create webhook URLs for use in external integrations. Please see<a href="http://mattermost.org/webhooks" target="_blank">http://mattermost.org/webhooks</a> to learn more.'
+ defaultMessage='Create webhook URLs for use in external integrations. Please see <a href="http://mattermost.org/webhooks" target="_blank">http://mattermost.org/webhooks</a> to learn more.'
/>
<div><label className='control-label padding-top x2'>
<FormattedMessage
diff --git a/web/react/components/user_settings/manage_outgoing_hooks.jsx b/web/react/components/user_settings/manage_outgoing_hooks.jsx
index 3f88e9f41..44aab486e 100644
--- a/web/react/components/user_settings/manage_outgoing_hooks.jsx
+++ b/web/react/components/user_settings/manage_outgoing_hooks.jsx
@@ -18,6 +18,10 @@ const holders = defineMessages({
callbackHolder: {
id: 'user.settings.hooks_out.callbackHolder',
defaultMessage: 'Each URL must start with http:// or https://'
+ },
+ select: {
+ id: 'user.settings.hooks_out.select',
+ defaultMessage: '--- Select a channel ---'
}
});
@@ -153,10 +157,7 @@ class ManageOutgoingHooks extends React.Component {
key='select-channel'
value=''
>
- <FormattedMessage
- id='user.settings.hooks_out.select'
- defaultMessage='--- Select a channel ---'
- />
+ {this.props.intl.formatMessage(holders.select)}
</option>
);
diff --git a/web/react/components/user_settings/user_settings_modal.jsx b/web/react/components/user_settings/user_settings_modal.jsx
index a7541073e..5442f7ac4 100644
--- a/web/react/components/user_settings/user_settings_modal.jsx
+++ b/web/react/components/user_settings/user_settings_modal.jsx
@@ -7,6 +7,7 @@ import SettingsSidebar from '../settings_sidebar.jsx';
import UserStore from '../../stores/user_store.jsx';
import * as Utils from '../../utils/utils.jsx';
+import Constants from '../../utils/constants.jsx';
const Modal = ReactBootstrap.Modal;
@@ -224,14 +225,19 @@ class UserSettingsModal extends React.Component {
resetTheme() {
const user = UserStore.getCurrentUser();
- if (user.theme_props != null) {
+ if (user.theme_props == null) {
+ Utils.applyTheme(Constants.THEMES.default);
+ } else {
Utils.applyTheme(user.theme_props);
}
}
render() {
const {formatMessage} = this.props.intl;
+ var currentUser = UserStore.getCurrentUser();
+ var isAdmin = Utils.isAdmin(currentUser.roles);
var tabs = [];
+
tabs.push({name: 'general', uiName: formatMessage(holders.general), icon: 'glyphicon glyphicon-cog'});
tabs.push({name: 'security', uiName: formatMessage(holders.security), icon: 'glyphicon glyphicon-lock'});
tabs.push({name: 'notifications', uiName: formatMessage(holders.notifications), icon: 'glyphicon glyphicon-exclamation-sign'});
@@ -240,8 +246,17 @@ class UserSettingsModal extends React.Component {
}
if (global.window.mm_config.EnableIncomingWebhooks === 'true' || global.window.mm_config.EnableOutgoingWebhooks === 'true' || global.window.mm_config.EnableCommands === 'true') {
- tabs.push({name: 'integrations', uiName: formatMessage(holders.integrations), icon: 'glyphicon glyphicon-transfer'});
+ var show = global.window.mm_config.EnableOnlyAdminIntegrations !== 'true';
+
+ if (global.window.mm_config.EnableOnlyAdminIntegrations === 'true' && isAdmin) {
+ show = true;
+ }
+
+ if (show) {
+ tabs.push({name: 'integrations', uiName: formatMessage(holders.integrations), icon: 'glyphicon glyphicon-transfer'});
+ }
}
+
tabs.push({name: 'display', uiName: formatMessage(holders.display), icon: 'glyphicon glyphicon-eye-open'});
tabs.push({name: 'advanced', uiName: formatMessage(holders.advanced), icon: 'glyphicon glyphicon-list-alt'});
diff --git a/web/react/components/user_settings/user_settings_security.jsx b/web/react/components/user_settings/user_settings_security.jsx
index 5693047c2..53d79906f 100644
--- a/web/react/components/user_settings/user_settings_security.jsx
+++ b/web/react/components/user_settings/user_settings_security.jsx
@@ -11,6 +11,7 @@ import TeamStore from '../../stores/team_store.jsx';
import * as Client from '../../utils/client.jsx';
import * as AsyncClient from '../../utils/async_client.jsx';
+import * as Utils from '../../utils/utils.jsx';
import Constants from '../../utils/constants.jsx';
import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'mm-intl';
@@ -216,15 +217,12 @@ class SecurityTab extends React.Component {
var describe;
var d = new Date(this.props.user.last_password_update);
- var timeOfDay = ' am';
- if (d.getHours() >= 12) {
- timeOfDay = ' pm';
- }
const locale = global.window.mm_locale;
+ const hours12 = !Utils.isMilitaryTime();
describe = formatMessage(holders.lastUpdated, {
date: d.toLocaleDateString(locale, {month: 'short', day: '2-digit', year: 'numeric'}),
- time: d.toLocaleTimeString(locale, {hours12: true, hour: '2-digit', minute: '2-digit'}) + timeOfDay
+ time: d.toLocaleTimeString(locale, {hour12: hours12, hour: '2-digit', minute: '2-digit'})
});
updateSectionStatus = function updateSection() {