From a6102e27d48d00fcc733c4d16754961903a239e0 Mon Sep 17 00:00:00 2001
From: Elias Nahum
Date: Sun, 31 Jan 2016 22:03:30 -0300
Subject: PLT-7: Refactoring frontend (chunk 8) - Sidebar and related
components - Small Tweak to demotion and add msg for terminal cmd
---
web/react/components/about_build_modal.jsx | 65 ++++++--
web/react/components/admin_console/user_item.jsx | 13 +-
web/react/components/change_url_modal.jsx | 54 ++++++-
web/react/components/get_link_modal.jsx | 22 ++-
.../components/get_team_invite_link_modal.jsx | 27 +++-
web/react/components/invite_member_modal.jsx | 126 ++++++++++++---
web/react/components/member_list_team_item.jsx | 50 +++++-
web/react/components/more_channels.jsx | 45 +++++-
web/react/components/more_direct_channels.jsx | 71 +++++++--
web/react/components/navbar_dropdown.jsx | 68 ++++++--
web/react/components/new_channel_flow.jsx | 66 ++++++--
web/react/components/new_channel_modal.jsx | 118 +++++++++++---
web/react/components/setting_upload.jsx | 21 ++-
web/react/components/sidebar.jsx | 109 +++++++++----
web/react/components/sidebar_header.jsx | 23 ++-
web/react/components/team_export_tab.jsx | 44 +++++-
web/react/components/team_general_tab.jsx | 176 +++++++++++++++++----
web/react/components/team_import_tab.jsx | 67 ++++++--
web/react/components/team_members_modal.jsx | 15 +-
web/react/components/team_settings_modal.jsx | 34 +++-
web/react/components/unread_channel_indicator.jsx | 2 +-
21 files changed, 999 insertions(+), 217 deletions(-)
(limited to 'web/react/components')
diff --git a/web/react/components/about_build_modal.jsx b/web/react/components/about_build_modal.jsx
index f70027498..fe48bb48e 100644
--- a/web/react/components/about_build_modal.jsx
+++ b/web/react/components/about_build_modal.jsx
@@ -3,6 +3,8 @@
var Modal = ReactBootstrap.Modal;
+import {FormattedMessage} from 'mm-intl';
+
export default class AboutBuildModal extends React.Component {
constructor(props) {
super(props);
@@ -17,13 +19,28 @@ export default class AboutBuildModal extends React.Component {
const config = global.window.mm_config;
const license = global.window.mm_license;
- let title = 'Team Edition';
+ let title = (
+
+ );
let licensee;
if (config.BuildEnterpriseReady === 'true' && license.IsLicensed === 'true') {
- title = 'Enterprise Edition';
+ title = (
+
+ );
licensee = (
-
{'Licensed by:'}
+
+
+
{license.Company}
);
@@ -35,25 +52,50 @@ export default class AboutBuildModal extends React.Component {
onHide={this.doHide}
>
- {'About Mattermost'}
+
+
+
- {`Mattermost ${title}`}
+ {'Mattermost'} {title}
{licensee}
-
{'Version:'}
+
+
+
{config.Version}
-
{'Build Number:'}
+
+
+
{config.BuildNumber}
-
{'Build Date:'}
+
+
+
{config.BuildDate}
-
{'Build Hash:'}
+
+
+
{config.BuildHash}
@@ -63,7 +105,10 @@ export default class AboutBuildModal extends React.Component {
className='btn btn-default'
onClick={this.doHide}
>
- {'Close'}
+
diff --git a/web/react/components/admin_console/user_item.jsx b/web/react/components/admin_console/user_item.jsx
index 5ab429dd5..02b01b090 100644
--- a/web/react/components/admin_console/user_item.jsx
+++ b/web/react/components/admin_console/user_item.jsx
@@ -9,7 +9,7 @@ import TeamStore from '../../stores/team_store.jsx';
import {injectIntl, intlShape, defineMessages, FormattedMessage} from 'mm-intl';
-var messages = defineMessages({
+var holders = defineMessages({
confirmDemoteRoleTitle: {
id: 'admin.user_item.confirmDemoteRoleTitle',
defaultMessage: 'Confirm demotion from System Admin role'
@@ -21,6 +21,10 @@ var messages = defineMessages({
confirmDemoteDescription: {
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.'
+ },
+ confirmDemotionCmd: {
+ id: 'admin.user_item.confirmDemotionCmd',
+ defaultMessage: 'platform -assign_role -team_name="yourteam" -email="name@yourcompany.com" -role="system_admin"'
}
});
@@ -332,14 +336,15 @@ export default class UserItem extends React.Component {
);
}
const me = UserStore.getCurrentUser();
+ const {formatMessage} = this.props.intl;
let makeDemoteModal = null;
if (this.props.user.id === me.id) {
makeDemoteModal = (
diff --git a/web/react/components/change_url_modal.jsx b/web/react/components/change_url_modal.jsx
index bbe93f58d..49d1b86b4 100644
--- a/web/react/components/change_url_modal.jsx
+++ b/web/react/components/change_url_modal.jsx
@@ -4,6 +4,8 @@
var Modal = ReactBootstrap.Modal;
import * as Utils from '../utils/utils.jsx';
+import {FormattedMessage} from 'mm-intl';
+
export default class ChangeUrlModal extends React.Component {
constructor(props) {
super(props);
@@ -39,21 +41,58 @@ export default class ChangeUrlModal extends React.Component {
getURLError(url) {
let error = []; //eslint-disable-line prefer-const
if (url.length < 2) {
- error.push({'Must be longer than two characters'} );
+ error.push(
+
+
+
+
+ );
}
if (url.charAt(0) === '-' || url.charAt(0) === '_') {
- error.push({'Must start with a letter or number'} );
+ error.push(
+
+
+
+
+ );
}
if (url.length > 1 && (url.charAt(url.length - 1) === '-' || url.charAt(url.length - 1) === '_')) {
- error.push({'Must end with a letter or number'} );
+ error.push(
+
+
+
+ );
}
if (url.indexOf('__') > -1) {
- error.push({'Can not contain two underscores in a row.'} );
+ error.push(
+
+
+
+ );
}
// In case of error we don't detect
if (error.length === 0) {
- error.push({'Invalid URL'} );
+ error.push(
+
+
+
+ );
}
return error;
}
@@ -137,7 +176,10 @@ export default class ChangeUrlModal extends React.Component {
className='btn btn-default'
onClick={this.doCancel}
>
- {'Close'}
+
- {'Copy Link'}
+
);
}
var copyLinkConfirm = null;
if (this.state.copiedLink) {
- copyLinkConfirm = {' Link copied to clipboard.'}
;
+ copyLinkConfirm = (
+
+
+
+
+ );
}
return (
@@ -92,7 +105,10 @@ export default class GetLinkModal extends React.Component {
className='btn btn-default'
onClick={this.onHide}
>
- {'Close'}
+
{copyLink}
{copyLinkConfirm}
diff --git a/web/react/components/get_team_invite_link_modal.jsx b/web/react/components/get_team_invite_link_modal.jsx
index a926c4451..883871267 100644
--- a/web/react/components/get_team_invite_link_modal.jsx
+++ b/web/react/components/get_team_invite_link_modal.jsx
@@ -6,7 +6,20 @@ import GetLinkModal from './get_link_modal.jsx';
import ModalStore from '../stores/modal_store.jsx';
import TeamStore from '../stores/team_store.jsx';
-export default class GetTeamInviteLinkModal extends React.Component {
+import {intlShape, injectIntl, defineMessages} from 'mm-intl';
+
+const holders = defineMessages({
+ title: {
+ id: 'get_team_invite_link_modal.title',
+ defaultMessage: 'Team Invite Link'
+ },
+ help: {
+ id: 'get_team_invite_link_modal.help',
+ defaultMessage: 'Send teammates the link below for them to sign-up to this team site.'
+ }
+});
+
+class GetTeamInviteLinkModal extends React.Component {
constructor(props) {
super(props);
@@ -32,14 +45,22 @@ export default class GetTeamInviteLinkModal extends React.Component {
}
render() {
+ const {formatMessage} = this.props.intl;
+
return (
this.setState({show: false})}
- title='Team Invite Link'
- helpText='Send teammates the link below for them to sign-up to this team site.'
+ title={formatMessage(holders.title)}
+ helpText={formatMessage(holders.help)}
link={TeamStore.getCurrentInviteLink()}
/>
);
}
}
+
+GetTeamInviteLinkModal.propTypes = {
+ intl: intlShape.isRequired
+};
+
+export default injectIntl(GetTeamInviteLinkModal);
\ No newline at end of file
diff --git a/web/react/components/invite_member_modal.jsx b/web/react/components/invite_member_modal.jsx
index 7e1627555..f2a0a7565 100644
--- a/web/react/components/invite_member_modal.jsx
+++ b/web/react/components/invite_member_modal.jsx
@@ -12,9 +12,38 @@ import ChannelStore from '../stores/channel_store.jsx';
import TeamStore from '../stores/team_store.jsx';
import ConfirmModal from './confirm_modal.jsx';
+import {intlShape, injectIntl, defineMessages, FormattedMessage, FormattedHTMLMessage} from 'mm-intl';
+
const Modal = ReactBootstrap.Modal;
-export default class InviteMemberModal extends React.Component {
+const holders = defineMessages({
+ emailError: {
+ id: 'invite_member.emailError',
+ defaultMessage: 'Please enter a valid email address'
+ },
+ firstname: {
+ id: 'invite_member.firstname',
+ defaultMessage: 'First name'
+ },
+ lastname: {
+ id: 'invite_member.lastname',
+ defaultMessage: 'Last name'
+ },
+ modalTitle: {
+ id: 'invite_member.modalTitle',
+ defaultMessage: 'Discard Invitations?'
+ },
+ modalMessage: {
+ id: 'invite_member.modalMessage',
+ defaultMessage: 'You have unsent invitations, are you sure you want to discard them?'
+ },
+ modalButton: {
+ id: 'invite_member.modalButton',
+ defaultMessage: 'Yes, Discard'
+ }
+});
+
+class InviteMemberModal extends React.Component {
constructor(props) {
super(props);
@@ -72,7 +101,7 @@ export default class InviteMemberModal extends React.Component {
var invite = {};
invite.email = ReactDOM.findDOMNode(this.refs['email' + index]).value.trim();
if (!invite.email || !utils.isEmail(invite.email)) {
- emailErrors[index] = 'Please enter a valid email address';
+ emailErrors[index] = this.props.intl.formatMessage(holders.emailError);
valid = false;
} else {
emailErrors[index] = '';
@@ -103,7 +132,7 @@ export default class InviteMemberModal extends React.Component {
this.setState({isSendingEmails: false});
},
(err) => {
- if (err.message === 'This person is already on your team') {
+ if (err.id === 'api.team.invite_members.already.app_error') {
emailErrors[err.detailed_error] = err.message;
this.setState({emailErrors: emailErrors});
} else {
@@ -199,6 +228,7 @@ export default class InviteMemberModal extends React.Component {
render() {
var currentUser = UserStore.getCurrentUser();
+ const {formatMessage} = this.props.intl;
if (currentUser != null) {
var inviteSections = [];
@@ -252,7 +282,7 @@ export default class InviteMemberModal extends React.Component {
type='text'
className='form-control'
ref={'first_name' + index}
- placeholder='First name'
+ placeholder={formatMessage(holders.firstname)}
maxLength='64'
disabled={!this.state.emailEnabled || !this.state.userCreationEnabled}
spellCheck='false'
@@ -266,7 +296,7 @@ export default class InviteMemberModal extends React.Component {
type='text'
className='form-control'
ref={'last_name' + index}
- placeholder='Last name'
+ placeholder={formatMessage(holders.lastname)}
maxLength='64'
disabled={!this.state.emailEnabled || !this.state.userCreationEnabled}
spellCheck='false'
@@ -318,20 +348,48 @@ export default class InviteMemberModal extends React.Component {
type='button'
className='btn btn-default'
onClick={this.addInviteFields}
- >{'Add another'}
+ >
+
+
- {'People invited automatically join the '}{defaultChannelName} {' channel.'}
+
+
+
);
- var sendButtonLabel = 'Send Invitation';
+ var sendButtonLabel = (
+
+ );
if (this.state.isSendingEmails) {
sendButtonLabel = (
- {' Sending'}
+
+
+
);
} else if (this.state.inviteIds.length > 1) {
- sendButtonLabel = 'Send Invitations';
+ sendButtonLabel = (
+
+ );
}
sendButton = (
@@ -352,27 +410,46 @@ export default class InviteMemberModal extends React.Component {
href='#'
onClick={this.showGetTeamInviteLinkModal}
>
- {'Team Invite Link'}
+
);
teamInviteLink = (
- {'You can also invite people using the '}{link}{'.'}
+
);
}
content = (
-
{'Email is currently disabled for your team, and email invitations cannot be sent. Contact your system administrator to enable email and email invitations.'}
+
+
+
{teamInviteLink}
);
} else {
content = (
-
{'User creation has been disabled for your team. Please ask your team administrator for details.'}
+
+
+
);
}
@@ -387,7 +464,12 @@ export default class InviteMemberModal extends React.Component {
backdrop={this.state.isSendingEmails ? 'static' : true}
>
- {'Invite New Member'}
+
+
+
;
+ displayNameError = (
+
+
+ {this.state.displayNameError}
+
+ );
displayNameClass += ' has-error';
}
@@ -63,29 +81,51 @@ export default class NewChannelModal extends React.Component {
var channelSwitchText = '';
switch (this.props.channelType) {
case 'P':
- channelTerm = 'Group';
+ channelTerm = (
+
+ );
channelSwitchText = (
);
break;
case 'O':
- channelTerm = 'Channel';
+ channelTerm = (
+
+ );
channelSwitchText = (
);
@@ -102,7 +142,13 @@ export default class NewChannelModal extends React.Component {
onHide={this.props.onModalDismissed}
>
- {'New ' + channelTerm}
+
+
+ {channelTerm}
+