summaryrefslogtreecommitdiffstats
path: root/web/react/components/user_settings/user_settings_general.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'web/react/components/user_settings/user_settings_general.jsx')
-rw-r--r--web/react/components/user_settings/user_settings_general.jsx254
1 files changed, 213 insertions, 41 deletions
diff --git a/web/react/components/user_settings/user_settings_general.jsx b/web/react/components/user_settings/user_settings_general.jsx
index df7ae4a25..f20b4b807 100644
--- a/web/react/components/user_settings/user_settings_general.jsx
+++ b/web/react/components/user_settings/user_settings_general.jsx
@@ -13,7 +13,84 @@ import Constants from '../../utils/constants.jsx';
import * as AsyncClient from '../../utils/async_client.jsx';
import * as Utils from '../../utils/utils.jsx';
-export default class UserSettingsGeneralTab extends React.Component {
+import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'mm-intl';
+
+const holders = defineMessages({
+ usernameReserved: {
+ id: 'user.settings.general.usernameReserved',
+ defaultMessage: 'This username is reserved, please choose a new one.'
+ },
+ usernameRestrictions: {
+ id: 'user.settings.general.usernameRestrictions',
+ defaultMessage: "'Username must begin with a letter, and contain between {min} to {max} lowercase characters made up of numbers, letters, and the symbols '.', '-' and '_'."
+ },
+ validEmail: {
+ id: 'user.settings.general.validEmail',
+ defaultMessage: 'Please enter a valid email address'
+ },
+ emailMatch: {
+ id: 'user.settings.general.emailMatch',
+ defaultMessage: 'The new emails you entered do not match.'
+ },
+ checkEmail: {
+ id: 'user.settings.general.checkEmail',
+ defaultMessage: 'Check your email at {email} to verify the address.'
+ },
+ newAddress: {
+ id: 'user.settings.general.newAddress',
+ defaultMessage: 'New Address: {email}<br />Check your email to verify the above address.'
+ },
+ checkEmailNoAddress: {
+ id: 'user.settings.general.checkEmailNoAddress',
+ defaultMessage: 'Check your email to verify your new address'
+ },
+ loginGitlab: {
+ id: 'user.settings.general.loginGitlab',
+ defaultMessage: 'Log in done through GitLab'
+ },
+ validImage: {
+ id: 'user.settings.general.validImage',
+ defaultMessage: 'Only JPG or PNG images may be used for profile pictures'
+ },
+ imageTooLarge: {
+ id: 'user.settings.general.imageTooLarge',
+ defaultMessage: 'Unable to upload profile image. File is too large.'
+ },
+ uploadImage: {
+ id: 'user.settings.general.uploadImage',
+ defaultMessage: "Click 'Edit' to upload an image."
+ },
+ imageUpdated: {
+ id: 'user.settings.general.imageUpdated',
+ defaultMessage: 'Image last updated {date}'
+ },
+ fullName: {
+ id: 'user.settings.general.fullName',
+ defaultMessage: 'Full Name'
+ },
+ nickname: {
+ id: 'user.settings.general.nickname',
+ defaultMessage: 'Nickname'
+ },
+ username: {
+ id: 'user.settings.general.username',
+ defaultMessage: 'Username'
+ },
+ email: {
+ id: 'user.settings.general.email',
+ defaultMessage: 'Email'
+ },
+ profilePicture: {
+ id: 'user.settings.general.profilePicture',
+ defaultMessage: 'Profile Picture'
+ },
+ close: {
+ id: 'user.settings.general.close',
+ defaultMessage: 'Close'
+ }
+});
+
+class UserSettingsGeneralTab extends React.Component {
constructor(props) {
super(props);
this.submitActive = false;
@@ -42,12 +119,13 @@ export default class UserSettingsGeneralTab extends React.Component {
const user = Object.assign({}, this.props.user);
const username = this.state.username.trim().toLowerCase();
+ const {formatMessage} = this.props.intl;
const 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.'});
+ this.setState({clientError: formatMessage(holders.usernameReserved)});
return;
} else if (usernameError) {
- this.setState({clientError: 'Username must begin with a letter, and contain between ' + Constants.MIN_USERNAME_LENGTH + ' to ' + Constants.MAX_USERNAME_LENGTH + " lowercase characters made up of numbers, letters, and the symbols '.', '-' and '_'."});
+ this.setState({clientError: formatMessage(holders.usernameRestrictions, {min: Constants.MIN_USERNAME_LENGTH, max: Constants.MAX_USERNAME_LENGTH})});
return;
}
@@ -99,13 +177,14 @@ export default class UserSettingsGeneralTab extends React.Component {
const email = this.state.email.trim().toLowerCase();
const confirmEmail = this.state.confirmEmail.trim().toLowerCase();
+ const {formatMessage} = this.props.intl;
if (email === '' || !Utils.isEmail(email)) {
- this.setState({emailError: 'Please enter a valid email address.', clientError: '', serverError: ''});
+ this.setState({emailError: formatMessage(holders.validEmail), clientError: '', serverError: ''});
return;
}
if (email !== confirmEmail) {
- this.setState({emailError: 'The new emails you entered do not match.', clientError: '', serverError: ''});
+ this.setState({emailError: formatMessage(holders.emailMatch), clientError: '', serverError: ''});
return;
}
@@ -125,7 +204,7 @@ export default class UserSettingsGeneralTab extends React.Component {
const verificationEnabled = global.window.mm_config.SendEmailNotifications === 'true' && global.window.mm_config.RequireEmailVerification === 'true' && emailUpdated;
if (verificationEnabled) {
- ErrorStore.storeLastError({message: 'Check your email at ' + user.email + ' to verify the address.'});
+ ErrorStore.storeLastError({message: this.props.intl.formatMessage(holders.checkEmail, {email: user.email})});
ErrorStore.emitChange();
this.setState({emailChangeInProgress: true});
}
@@ -152,13 +231,14 @@ export default class UserSettingsGeneralTab extends React.Component {
return;
}
+ const {formatMessage} = this.props.intl;
const picture = this.state.picture;
if (picture.type !== 'image/jpeg' && picture.type !== 'image/png') {
- this.setState({clientError: 'Only JPG or PNG images may be used for profile pictures.'});
+ this.setState({clientError: formatMessage(holders.validImage)});
return;
} else if (picture.size > Constants.MAX_FILE_SIZE) {
- this.setState({clientError: 'Unable to upload profile image. File is too large.'});
+ this.setState({clientError: formatMessage(holders.imageTooLarge)});
return;
}
@@ -221,6 +301,7 @@ export default class UserSettingsGeneralTab extends React.Component {
}
render() {
const user = this.props.user;
+ const {formatMessage, formatHTMLMessage} = this.props.intl;
let clientError = null;
if (this.state.clientError) {
@@ -244,7 +325,12 @@ export default class UserSettingsGeneralTab extends React.Component {
key='firstNameSetting'
className='form-group'
>
- <label className='col-sm-5 control-label'>{'First Name'}</label>
+ <label className='col-sm-5 control-label'>
+ <FormattedMessage
+ id='user.settings.general.firstName'
+ defaultMessage='First Name'
+ />
+ </label>
<div className='col-sm-7'>
<input
className='form-control'
@@ -261,7 +347,12 @@ export default class UserSettingsGeneralTab extends React.Component {
key='lastNameSetting'
className='form-group'
>
- <label className='col-sm-5 control-label'>{'Last Name'}</label>
+ <label className='col-sm-5 control-label'>
+ <FormattedMessage
+ id='user.settings.general.lastName'
+ defaultMessage='Last Name'
+ />
+ </label>
<div className='col-sm-7'>
<input
className='form-control'
@@ -284,20 +375,28 @@ export default class UserSettingsGeneralTab extends React.Component {
href='#'
onClick={notifClick.bind(this)}
>
- {'Notifications'}
+ <FormattedMessage
+ id='user.settings.general.notificationsLink'
+ defaultMessage='Notifications'
+ />
</a>
);
const extraInfo = (
<span>
- {'By default, you will receive mention notifications when someone types your first name. '}
- {'Go to '} {notifLink} {'settings to change this default.'}
+ <FormattedMessage
+ id='user.settings.general.notificationsExtra'
+ defaultMessage='By default, you will receive mention notifications when someone types your first name. Go to {notify} settings to change this default.'
+ values={{
+ notify: (notifLink)
+ }}
+ />
</span>
);
nameSection = (
<SettingItemMax
- title='Full Name'
+ title={formatMessage(holders.fullName)}
inputs={inputs}
submit={this.submitName}
server_error={serverError}
@@ -322,7 +421,7 @@ export default class UserSettingsGeneralTab extends React.Component {
nameSection = (
<SettingItemMin
- title='Full Name'
+ title={formatMessage(holders.fullName)}
describe={fullName}
updateSection={() => {
this.updateSection('name');
@@ -333,7 +432,12 @@ export default class UserSettingsGeneralTab extends React.Component {
let nicknameSection;
if (this.props.activeSection === 'nickname') {
- let nicknameLabel = 'Nickname';
+ let nicknameLabel = (
+ <FormattedMessage
+ id='user.settings.general.nickname'
+ defaultMessage='Nickname'
+ />
+ );
if (Utils.isMobile()) {
nicknameLabel = '';
}
@@ -357,13 +461,16 @@ export default class UserSettingsGeneralTab extends React.Component {
const extraInfo = (
<span>
- {'Use Nickname for a name you might be called that is different from your first name and username. This is most often used when two or more people have similar sounding names and usernames.'}
+ <FormattedMessage
+ id='user.settings.general.nicknameExtra'
+ defaultMessage='Use Nickname for a name you might be called that is different from your first name and username. This is most often used when two or more people have similar sounding names and usernames.'
+ />
</span>
);
nicknameSection = (
<SettingItemMax
- title='Nickname'
+ title={formatMessage(holders.nickname)}
inputs={inputs}
submit={this.submitNickname}
server_error={serverError}
@@ -378,7 +485,7 @@ export default class UserSettingsGeneralTab extends React.Component {
} else {
nicknameSection = (
<SettingItemMin
- title='Nickname'
+ title={formatMessage(holders.nickname)}
describe={UserStore.getCurrentUser().nickname}
updateSection={() => {
this.updateSection('nickname');
@@ -389,7 +496,12 @@ export default class UserSettingsGeneralTab extends React.Component {
let usernameSection;
if (this.props.activeSection === 'username') {
- let usernameLabel = 'Username';
+ let usernameLabel = (
+ <FormattedMessage
+ id='user.settings.general.username'
+ defaultMessage='Username'
+ />
+ );
if (Utils.isMobile()) {
usernameLabel = '';
}
@@ -411,11 +523,18 @@ export default class UserSettingsGeneralTab extends React.Component {
</div>
);
- const extraInfo = (<span>{'Pick something easy for teammates to recognize and recall.'}</span>);
+ const extraInfo = (
+ <span>
+ <FormattedMessage
+ id='user.settings.general.usernameInfo'
+ defaultMessage='Pick something easy for teammates to recognize and recall.'
+ />
+ </span>
+ );
usernameSection = (
<SettingItemMax
- title='Username'
+ title={formatMessage(holders.username)}
inputs={inputs}
submit={this.submitUsername}
server_error={serverError}
@@ -430,7 +549,7 @@ export default class UserSettingsGeneralTab extends React.Component {
} else {
usernameSection = (
<SettingItemMin
- title='Username'
+ title={formatMessage(holders.username)}
describe={UserStore.getCurrentUser().username}
updateSection={() => {
this.updateSection('username');
@@ -443,16 +562,41 @@ export default class UserSettingsGeneralTab extends React.Component {
if (this.props.activeSection === 'email') {
const emailEnabled = global.window.mm_config.SendEmailNotifications === 'true';
const emailVerificationEnabled = global.window.mm_config.RequireEmailVerification === 'true';
- let helpText = 'Email is used for sign-in, notifications, and password reset. Email requires verification if changed.';
+ let helpText = (
+ <FormattedMessage
+ id='user.settings.general.emailHelp1'
+ defaultMessage='Email is used for sign-in, notifications, and password reset. Email requires verification if changed.'
+ />
+ );
if (!emailEnabled) {
- helpText = <div className='setting-list__hint text-danger'>{'Email has been disabled by your system administrator. No notification emails will be sent until it is enabled.'}</div>;
+ helpText = (
+ <div className='setting-list__hint text-danger'>
+ <FormattedMessage
+ id='user.settings.general.emailHelp2'
+ defaultMessage='Email has been disabled by your system administrator. No notification emails will be sent until it is enabled.'
+ />
+ </div>
+ );
} else if (!emailVerificationEnabled) {
- helpText = 'Email is used for sign-in, notifications, and password reset.';
+ helpText = (
+ <FormattedMessage
+ id='user.settings.general.emailHelp3'
+ defaultMessage='Email is used for sign-in, notifications, and password reset.'
+ />
+ );
} else if (this.state.emailChangeInProgress) {
const newEmail = UserStore.getCurrentUser().email;
if (newEmail) {
- helpText = 'A verification email was sent to ' + newEmail + '.';
+ helpText = (
+ <FormattedMessage
+ id='user.settings.general.emailHelp4'
+ defaultMessage='A verification email was sent to {email}.'
+ values={{
+ email: newEmail
+ }}
+ />
+ );
}
}
@@ -462,7 +606,12 @@ export default class UserSettingsGeneralTab extends React.Component {
inputs.push(
<div key='emailSetting'>
<div className='form-group'>
- <label className='col-sm-5 control-label'>{'Primary Email'}</label>
+ <label className='col-sm-5 control-label'>
+ <FormattedMessage
+ id='user.settings.general.primaryEmail'
+ defaultMessage='Primary Email'
+ />
+ </label>
<div className='col-sm-7'>
<input
className='form-control'
@@ -478,7 +627,12 @@ export default class UserSettingsGeneralTab extends React.Component {
inputs.push(
<div key='confirmEmailSetting'>
<div className='form-group'>
- <label className='col-sm-5 control-label'>{'Confirm Email'}</label>
+ <label className='col-sm-5 control-label'>
+ <FormattedMessage
+ id='user.settings.general.confirmEmail'
+ defaultMessage='Confirm Email'
+ />
+ </label>
<div className='col-sm-7'>
<input
className='form-control'
@@ -499,7 +653,12 @@ export default class UserSettingsGeneralTab extends React.Component {
key='oauthEmailInfo'
className='form-group'
>
- <div className='setting-list__hint'>{'Log in occurs through GitLab. Email cannot be updated.'}</div>
+ <div className='setting-list__hint'>
+ <FormattedMessage
+ id='user.settings.general.emailCantUpdate'
+ defaultMessage='Log in occurs through GitLab. Email cannot be updated.'
+ />
+ </div>
{helpText}
</div>
);
@@ -524,20 +683,20 @@ export default class UserSettingsGeneralTab extends React.Component {
if (this.state.emailChangeInProgress) {
const newEmail = UserStore.getCurrentUser().email;
if (newEmail) {
- describe = 'New Address: ' + newEmail + '\nCheck your email to verify the above address.';
+ describe = formatHTMLMessage(holders.newAddress, {email: newEmail});
} else {
- describe = 'Check your email to verify your new address';
+ describe = formatMessage(holders.checkEmailNoAddress);
}
} else {
describe = UserStore.getCurrentUser().email;
}
} else if (this.props.user.auth_service === Constants.GITLAB_SERVICE) {
- describe = 'Log in done through GitLab';
+ describe = formatMessage(holders.loginGitlab);
}
emailSection = (
<SettingItemMin
- title='Email'
+ title={formatMessage(holders.email)}
describe={describe}
updateSection={() => {
this.updateSection('email');
@@ -550,7 +709,7 @@ export default class UserSettingsGeneralTab extends React.Component {
if (this.props.activeSection === 'picture') {
pictureSection = (
<SettingPicture
- title='Profile Picture'
+ title={formatMessage(holders.profilePicture)}
submit={this.submitPicture}
src={'/api/v1/users/' + user.id + '/image?time=' + user.last_picture_update + '&' + Utils.getSessionIndex()}
server_error={serverError}
@@ -566,13 +725,15 @@ export default class UserSettingsGeneralTab extends React.Component {
/>
);
} else {
- let minMessage = 'Click \'Edit\' to upload an image.';
+ let minMessage = formatMessage(holders.uploadImage);
if (user.last_picture_update) {
- minMessage = 'Image last updated ' + Utils.displayDate(user.last_picture_update);
+ minMessage = formatMessage(holders.imageUpdated, {
+ date: new Date(user.last_picture_update).toLocaleDateString(global.window.mm_locale, {month: 'short', day: '2-digit', year: 'numeric'})
+ });
}
pictureSection = (
<SettingItemMin
- title='Profile Picture'
+ title={formatMessage(holders.profilePicture)}
describe={minMessage}
updateSection={() => {
this.updateSection('picture');
@@ -588,7 +749,7 @@ export default class UserSettingsGeneralTab extends React.Component {
type='button'
className='close'
data-dismiss='modal'
- aria-label='Close'
+ aria-label={formatMessage(holders.close)}
onClick={this.props.closeModal}
>
<span aria-hidden='true'>{'×'}</span>
@@ -601,11 +762,19 @@ export default class UserSettingsGeneralTab extends React.Component {
className='modal-back'
onClick={this.props.collapseModal}
/>
- {'General Settings'}
+ <FormattedMessage
+ id='user.settings.general.title'
+ defaultMessage='General Settings'
+ />
</h4>
</div>
<div className='user-settings'>
- <h3 className='tab-header'>{'General Settings'}</h3>
+ <h3 className='tab-header'>
+ <FormattedMessage
+ id='user.settings.general.title'
+ defaultMessage='General Settings'
+ />
+ </h3>
<div className='divider-dark first'/>
{nameSection}
<div className='divider-light'/>
@@ -624,6 +793,7 @@ export default class UserSettingsGeneralTab extends React.Component {
}
UserSettingsGeneralTab.propTypes = {
+ intl: intlShape.isRequired,
user: React.PropTypes.object.isRequired,
updateSection: React.PropTypes.func.isRequired,
updateTab: React.PropTypes.func.isRequired,
@@ -631,3 +801,5 @@ UserSettingsGeneralTab.propTypes = {
closeModal: React.PropTypes.func.isRequired,
collapseModal: React.PropTypes.func.isRequired
};
+
+export default injectIntl(UserSettingsGeneralTab); \ No newline at end of file