From 53e495cf335d3c6b44361627288db252aae1f4ad Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Thu, 28 Jan 2016 16:16:39 -0300 Subject: PLT-7: Refactoring frontend (chunk 4) --- web/react/components/authorize.jsx | 42 +++++++++++-- web/react/components/docs.jsx | 2 +- web/react/components/find_team.jsx | 65 ++++++++++++++++--- web/react/components/login.jsx | 76 +++++++++++++++++++---- web/react/components/login_email.jsx | 49 ++++++++++++--- web/react/components/login_ldap.jsx | 48 +++++++++++--- web/react/components/password_reset_form.jsx | 64 ++++++++++++++++--- web/react/components/password_reset_send_link.jsx | 63 ++++++++++++++++--- web/react/components/signup_team.jsx | 43 +++++++++++-- web/react/components/team_signup_choose_auth.jsx | 42 +++++++++++-- web/react/components/team_signup_with_email.jsx | 34 ++++++++-- web/react/components/team_signup_with_sso.jsx | 52 +++++++++++++--- web/react/pages/find_team.jsx | 59 ++++++++++++++++-- web/react/pages/signup_team.jsx | 2 +- web/static/help/Messaging.md | 1 - web/static/help/Messaging_en.md | 1 + web/static/help/Messaging_es.md | 1 + web/static/i18n/en.json | 72 ++++++++++++++++++++- web/static/i18n/es.json | 72 ++++++++++++++++++++- web/templates/find_team.html | 2 +- web/templates/signup_team.html | 2 +- web/web.go | 1 + 22 files changed, 700 insertions(+), 93 deletions(-) delete mode 120000 web/static/help/Messaging.md create mode 120000 web/static/help/Messaging_en.md create mode 120000 web/static/help/Messaging_es.md (limited to 'web') diff --git a/web/react/components/authorize.jsx b/web/react/components/authorize.jsx index 32e39fbff..90cbe3289 100644 --- a/web/react/components/authorize.jsx +++ b/web/react/components/authorize.jsx @@ -3,6 +3,8 @@ import * as Client from '../utils/client.jsx'; +import {FormattedMessage} from 'mm-intl'; + export default class Authorize extends React.Component { constructor(props) { super(props); @@ -35,25 +37,55 @@ export default class Authorize extends React.Component { return (
-

{'An application would like to connect to your '}{this.props.teamName}{' account'}

- +

+ +

+

- +
diff --git a/web/react/components/docs.jsx b/web/react/components/docs.jsx index 188ca340b..6d3a109c2 100644 --- a/web/react/components/docs.jsx +++ b/web/react/components/docs.jsx @@ -13,7 +13,7 @@ export default class Docs extends React.Component { const errorState = {text: '## 404'}; if (props.site) { - $.get('/static/help/' + props.site + '.md').then((response) => { + $.get(`/static/help/${props.site}_${global.window.mm_locale}.md`).then((response) => { this.setState({text: response}); }, () => { this.setState(errorState); diff --git a/web/react/components/find_team.jsx b/web/react/components/find_team.jsx index 94ca48dbf..3ff9787ad 100644 --- a/web/react/components/find_team.jsx +++ b/web/react/components/find_team.jsx @@ -4,7 +4,20 @@ import * as utils from '../utils/utils.jsx'; import * as client from '../utils/client.jsx'; -export default class FindTeam extends React.Component { +import {injectIntl, intlShape, defineMessages, FormattedMessage} from 'mm-intl'; + +var holders = defineMessages({ + submitError: { + id: 'find_team.submitError', + defaultMessage: 'Please enter a valid email address' + }, + placeholder: { + id: 'find_team.placeholder', + defaultMessage: 'you@domain.com' + } +}); + +class FindTeam extends React.Component { constructor(props) { super(props); this.state = {}; @@ -19,7 +32,7 @@ export default class FindTeam extends React.Component { var email = ReactDOM.findDOMNode(this.refs.email).value.trim().toLowerCase(); if (!email || !utils.isEmail(email)) { - state.email_error = 'Please enter a valid email address'; + state.email_error = this.props.intl.formatMessage(holders.submitError); this.setState(state); return; } @@ -50,25 +63,50 @@ export default class FindTeam extends React.Component { if (this.state.sent) { return (
-

{'Find Your teams'}

-

{'An email was sent with links to any teams to which you are a member.'}

+

+ +

+

+ +

); } return (
-

Find Your Team

+

+ +

-

{'Get an email with links to any teams to which you are a member.'}

+

+ +

- +
@@ -79,10 +117,19 @@ export default class FindTeam extends React.Component { className='btn btn-md btn-primary' type='submit' > - Send +
); } } + +FindTeam.propTypes = { + intl: intlShape.isRequired +}; + +export default injectIntl(FindTeam); \ No newline at end of file diff --git a/web/react/components/login.jsx b/web/react/components/login.jsx index 3c1d66334..c4f530af0 100644 --- a/web/react/components/login.jsx +++ b/web/react/components/login.jsx @@ -7,7 +7,7 @@ import LoginLdap from './login_ldap.jsx'; import * as Utils from '../utils/utils.jsx'; import Constants from '../utils/constants.jsx'; -var FormattedMessage = ReactIntl.FormattedMessage; +import {FormattedMessage} from 'mm-intl'; export default class Login extends React.Component { constructor(props) { @@ -24,10 +24,16 @@ export default class Login extends React.Component { loginMessage.push( - {'with GitLab'} + + + ); } @@ -36,10 +42,16 @@ export default class Login extends React.Component { loginMessage.push( - {'with Google Apps'} + + + ); } @@ -49,9 +61,19 @@ export default class Login extends React.Component { if (extraParam) { let msg; if (extraParam === Constants.SIGNIN_CHANGE) { - msg = ' Sign-in method changed successfully'; + msg = ( + + ); } else if (extraParam === Constants.SIGNIN_VERIFIED) { - msg = ' Email Verified'; + msg = ( + + ); } if (msg != null) { @@ -78,7 +100,12 @@ export default class Login extends React.Component {
{loginMessage}
- {'or'} + + +
); @@ -90,7 +117,7 @@ export default class Login extends React.Component {
@@ -102,12 +129,19 @@ export default class Login extends React.Component { if (this.props.inviteId) { userSignUp = (
- {`Don't have an account? `} + + - {'Create one now'} +
@@ -122,7 +156,10 @@ export default class Login extends React.Component { href='/' className='signup-team-login' > - {'Create a new team'} +
); @@ -144,7 +181,7 @@ export default class Login extends React.Component { @@ -154,9 +191,22 @@ export default class Login extends React.Component { return (
-
{'Sign in to:'}
+
+ +

{teamDisplayName}

-

{'on '}{global.window.mm_config.SiteName}

+

+ +

{extraBox} {loginMessage} {emailSignup} diff --git a/web/react/components/login_email.jsx b/web/react/components/login_email.jsx index cfe34d1c7..cf1e1bc40 100644 --- a/web/react/components/login_email.jsx +++ b/web/react/components/login_email.jsx @@ -5,7 +5,32 @@ import * as Utils from '../utils/utils.jsx'; import * as Client from '../utils/client.jsx'; import UserStore from '../stores/user_store.jsx'; -export default class LoginEmail extends React.Component { +import {injectIntl, intlShape, defineMessages, FormattedMessage} from 'mm-intl'; + +var holders = defineMessages({ + badTeam: { + id: 'login_email.badTeam', + defaultMessage: 'Bad team name' + }, + emailReq: { + id: 'login_email.emailReq', + defaultMessage: 'An email is required' + }, + pwdReq: { + id: 'login_email.pwdReq', + defaultMessage: 'A password is required' + }, + email: { + id: 'login_email.email', + defaultMessage: 'Email' + }, + pwd: { + id: 'login_email.pwd', + defaultMessage: 'Password' + } +}); + +class LoginEmail extends React.Component { constructor(props) { super(props); @@ -17,25 +42,26 @@ export default class LoginEmail extends React.Component { } handleSubmit(e) { e.preventDefault(); + const {formatMessage} = this.props.intl; var state = {}; const name = this.props.teamName; if (!name) { - state.serverError = 'Bad team name'; + state.serverError = formatMessage(holders.badTeam); this.setState(state); return; } const email = this.refs.email.value.trim(); if (!email) { - state.serverError = 'An email is required'; + state.serverError = formatMessage(holders.emailReq); this.setState(state); return; } const password = this.refs.password.value.trim(); if (!password) { - state.serverError = 'A password is required'; + state.serverError = formatMessage(holders.pwdReq); this.setState(state); return; } @@ -55,7 +81,7 @@ export default class LoginEmail extends React.Component { } }, (err) => { - if (err.message === 'Login failed because email address has not been verified') { + if (err.id === 'api.user.login.not_verified.app_error') { window.location.href = '/verify_email?teamname=' + encodeURIComponent(name) + '&email=' + encodeURIComponent(email); return; } @@ -87,6 +113,7 @@ export default class LoginEmail extends React.Component { priorEmail = decodeURIComponent(emailParam); } + const {formatMessage} = this.props.intl; return (
@@ -101,7 +128,7 @@ export default class LoginEmail extends React.Component { name='email' defaultValue={priorEmail} ref='email' - placeholder='Email' + placeholder={formatMessage(holders.email)} spellCheck='false' />
@@ -112,7 +139,7 @@ export default class LoginEmail extends React.Component { className='form-control' name='password' ref='password' - placeholder='Password' + placeholder={formatMessage(holders.pwd)} spellCheck='false' />
@@ -121,7 +148,10 @@ export default class LoginEmail extends React.Component { type='submit' className='btn btn-primary' > - {'Sign in'} +
@@ -133,5 +163,8 @@ LoginEmail.defaultProps = { }; LoginEmail.propTypes = { + intl: intlShape.isRequired, teamName: React.PropTypes.string.isRequired }; + +export default injectIntl(LoginEmail); \ No newline at end of file diff --git a/web/react/components/login_ldap.jsx b/web/react/components/login_ldap.jsx index 1e0e32f4f..d67f15fa5 100644 --- a/web/react/components/login_ldap.jsx +++ b/web/react/components/login_ldap.jsx @@ -4,7 +4,32 @@ import * as Utils from '../utils/utils.jsx'; import * as Client from '../utils/client.jsx'; -export default class LoginLdap extends React.Component { +import {injectIntl, intlShape, defineMessages, FormattedMessage} from 'mm-intl'; + +const holders = defineMessages({ + badTeam: { + id: 'login_ldap.badTeam', + defaultMessage: 'Bad team name' + }, + idReq: { + id: 'login_ldap.idlReq', + defaultMessage: 'An LDAP ID is required' + }, + pwdReq: { + id: 'login_ldap.pwdReq', + defaultMessage: 'An LDAP password is required' + }, + username: { + id: 'login_ldap.username', + defaultMessage: 'LDAP Username' + }, + pwd: { + id: 'login_ldap.pwd', + defaultMessage: 'LDAP Password' + } +}); + +class LoginLdap extends React.Component { constructor(props) { super(props); @@ -16,25 +41,26 @@ export default class LoginLdap extends React.Component { } handleSubmit(e) { e.preventDefault(); + const {formatMessage} = this.props.intl; var state = {}; const teamName = this.props.teamName; if (!teamName) { - state.serverError = 'Bad team name'; + state.serverError = formatMessage(holders.badTeam); this.setState(state); return; } const id = this.refs.id.value.trim(); if (!id) { - state.serverError = 'An LDAP ID is required'; + state.serverError = formatMessage(holders.idReq); this.setState(state); return; } const password = this.refs.password.value.trim(); if (!password) { - state.serverError = 'An LDAP password is required'; + state.serverError = formatMessage(holders.pwdReq); this.setState(state); return; } @@ -64,7 +90,7 @@ export default class LoginLdap extends React.Component { serverError = ; errorClass = ' has-error'; } - + const {formatMessage} = this.props.intl; return (
@@ -76,7 +102,7 @@ export default class LoginLdap extends React.Component { autoFocus={true} className='form-control' ref='id' - placeholder='LDAP Username' + placeholder={formatMessage(holders.username)} spellCheck='false' />
@@ -85,7 +111,7 @@ export default class LoginLdap extends React.Component { type='password' className='form-control' ref='password' - placeholder='LDAP Password' + placeholder={formatMessage(holders.pwd)} spellCheck='false' /> @@ -94,7 +120,10 @@ export default class LoginLdap extends React.Component { type='submit' className='btn btn-primary' > - {'Sign in'} + @@ -106,5 +135,8 @@ LoginLdap.defaultProps = { }; LoginLdap.propTypes = { + intl: intlShape.isRequired, teamName: React.PropTypes.string.isRequired }; + +export default injectIntl(LoginLdap); \ No newline at end of file diff --git a/web/react/components/password_reset_form.jsx b/web/react/components/password_reset_form.jsx index 8063db05a..380dbe973 100644 --- a/web/react/components/password_reset_form.jsx +++ b/web/react/components/password_reset_form.jsx @@ -4,7 +4,24 @@ import * as Client from '../utils/client.jsx'; import Constants from '../utils/constants.jsx'; -export default class PasswordResetForm extends React.Component { +import {injectIntl, intlShape, defineMessages, FormattedMessage, FormattedHTMLMessage} from 'mm-intl'; + +const holders = defineMessages({ + error: { + id: 'password_form.error', + defaultMessage: 'Please enter at least {chars} characters.' + }, + update: { + id: 'password_form.update', + defaultMessage: 'Your password has been updated successfully.' + }, + pwd: { + id: 'password_form.pwd', + defaultMessage: 'Password' + } +}); + +class PasswordResetForm extends React.Component { constructor(props) { super(props); @@ -14,11 +31,13 @@ export default class PasswordResetForm extends React.Component { } handlePasswordReset(e) { e.preventDefault(); + + const {formatMessage} = this.props.intl; var state = {}; var password = ReactDOM.findDOMNode(this.refs.password).value.trim(); if (!password || password.length < Constants.MIN_PASSWORD_LENGTH) { - state.error = 'Please enter at least ' + Constants.MIN_PASSWORD_LENGTH + ' characters.'; + state.error = formatMessage(holders.error, {chars: Constants.MIN_PASSWORD_LENGTH}); this.setState(state); return; } @@ -34,7 +53,7 @@ export default class PasswordResetForm extends React.Component { Client.resetPassword(data, function resetSuccess() { - this.setState({error: null, updateText: 'Your password has been updated successfully.'}); + this.setState({error: null, updateText: formatMessage(holders.update)}); }.bind(this), function resetFailure(err) { this.setState({error: err.message, updateText: null}); @@ -44,7 +63,15 @@ export default class PasswordResetForm extends React.Component { render() { var updateText = null; if (this.state.updateText) { - updateText =

; + updateText = (

); } var error = null; @@ -57,19 +84,34 @@ export default class PasswordResetForm extends React.Component { formClass += ' has-error'; } + const {formatMessage} = this.props.intl; return (
-

{'Password Reset'}

+

+ +

-

{'Enter a new password for your ' + this.props.teamDisplayName + ' ' + global.window.mm_config.SiteName + ' account.'}

+

+ +

@@ -78,7 +120,10 @@ export default class PasswordResetForm extends React.Component { type='submit' className='btn btn-primary' > - {'Change my password'} + {updateText} @@ -95,8 +140,11 @@ PasswordResetForm.defaultProps = { data: '' }; PasswordResetForm.propTypes = { + intl: intlShape.isRequired, teamName: React.PropTypes.string, teamDisplayName: React.PropTypes.string, hash: React.PropTypes.string, data: React.PropTypes.string }; + +export default injectIntl(PasswordResetForm); \ No newline at end of file diff --git a/web/react/components/password_reset_send_link.jsx b/web/react/components/password_reset_send_link.jsx index 051b8b02c..8cc8a050d 100644 --- a/web/react/components/password_reset_send_link.jsx +++ b/web/react/components/password_reset_send_link.jsx @@ -4,7 +4,28 @@ import * as Utils from '../utils/utils.jsx'; import * as client from '../utils/client.jsx'; -export default class PasswordResetSendLink extends React.Component { +import {injectIntl, intlShape, defineMessages, FormattedMessage} from 'mm-intl'; + +const holders = defineMessages({ + error: { + id: 'password_send.error', + defaultMessage: 'Please enter a valid email address.' + }, + link: { + id: 'password_send.link', + defaultMessage: '

A password reset link has been sent to {email} for your {teamDisplayName} team on {hostname}.

' + }, + checkInbox: { + id: 'password_send.checkInbox', + defaultMessage: 'Please check your inbox.' + }, + email: { + id: 'password_send.email', + defaultMessage: 'Email' + } +}); + +class PasswordResetSendLink extends React.Component { constructor(props) { super(props); @@ -15,10 +36,11 @@ export default class PasswordResetSendLink extends React.Component { handleSendLink(e) { e.preventDefault(); var state = {}; + const {formatMessage} = this.props.intl; var email = ReactDOM.findDOMNode(this.refs.email).value.trim().toLowerCase(); if (!email || !Utils.isEmail(email)) { - state.error = 'Please enter a valid email address.'; + state.error = formatMessage(holders.error); this.setState(state); return; } @@ -32,7 +54,7 @@ export default class PasswordResetSendLink extends React.Component { client.sendPasswordReset(data, function passwordResetSent() { - this.setState({error: null, updateText:

A password reset link has been sent to {email} for your {this.props.teamDisplayName} team on {window.location.hostname}.

, moreUpdateText: 'Please check your inbox.'}); + this.setState({error: null, updateText: formatMessage(holders.link, {email: email, teamDisplayName: this.props.teamDisplayName, hostname: window.location.hostname}), moreUpdateText: formatMessage(holders.checkInbox)}); $(ReactDOM.findDOMNode(this.refs.reset_form)).hide(); }.bind(this), function passwordResetFailedToSend(err) { @@ -43,7 +65,12 @@ export default class PasswordResetSendLink extends React.Component { render() { var updateText = null; if (this.state.updateText) { - updateText =
{this.state.updateText}{this.state.moreUpdateText}
; + updateText = ( +
+
+ ); } var error = null; @@ -56,23 +83,37 @@ export default class PasswordResetSendLink extends React.Component { formClass += ' has-error'; } + const {formatMessage} = this.props.intl; return (
-

Password Reset

+

+ +

{updateText}
-

{'To reset your password, enter the email address you used to sign up for ' + this.props.teamDisplayName + '.'}

+

+ +

@@ -81,7 +122,10 @@ export default class PasswordResetSendLink extends React.Component { type='submit' className='btn btn-primary' > - Reset my password +
@@ -95,6 +139,9 @@ PasswordResetSendLink.defaultProps = { teamDisplayName: '' }; PasswordResetSendLink.propTypes = { + intl: intlShape.isRequired, teamName: React.PropTypes.string, teamDisplayName: React.PropTypes.string }; + +export default injectIntl(PasswordResetSendLink); \ No newline at end of file diff --git a/web/react/components/signup_team.jsx b/web/react/components/signup_team.jsx index a554427d5..098e9f65a 100644 --- a/web/react/components/signup_team.jsx +++ b/web/react/components/signup_team.jsx @@ -6,6 +6,8 @@ import EmailSignUpPage from './team_signup_with_email.jsx'; import SSOSignupPage from './team_signup_with_sso.jsx'; import Constants from '../utils/constants.jsx'; +import {FormattedMessage} from 'mm-intl'; + export default class TeamSignUp extends React.Component { constructor(props) { super(props); @@ -43,12 +45,24 @@ export default class TeamSignUp extends React.Component { if (global.window.mm_config.EnableTeamListing === 'true') { if (this.props.teams.length === 0) { if (global.window.mm_config.EnableTeamCreation !== 'true') { - teamListing = (
{'There are no teams include in the Team Directory and team creation has been disabled.'}
); + teamListing = ( +
+ +
+ ); } } else { teamListing = (
-

{'Choose a Team'}

+

+ +

{ this.props.teams.map((team) => { @@ -71,7 +85,12 @@ export default class TeamSignUp extends React.Component { }) }
-

{'Or Create a Team'}

+

+ +

); } @@ -79,7 +98,14 @@ export default class TeamSignUp extends React.Component { if (global.window.mm_config.EnableTeamCreation !== 'true') { if (teamListing == null) { - return (
{'Team creation has been disabled. Please contact an administrator for access.'}
); + return ( +
+ +
+ ); } return ( @@ -122,7 +148,14 @@ export default class TeamSignUp extends React.Component {
); } else if (this.state.page === 'none') { - return (
{'No team creation method has been enabled. Please contact an administrator for access.'}
); + return ( +
+ +
+ ); } } } diff --git a/web/react/components/team_signup_choose_auth.jsx b/web/react/components/team_signup_choose_auth.jsx index 19b9750b3..2dc67e92e 100644 --- a/web/react/components/team_signup_choose_auth.jsx +++ b/web/react/components/team_signup_choose_auth.jsx @@ -1,6 +1,8 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. +import {FormattedMessage} from 'mm-intl'; + export default class ChooseAuthPage extends React.Component { constructor(props) { super(props); @@ -12,6 +14,7 @@ export default class ChooseAuthPage extends React.Component { buttons.push( - {'Create new team with GitLab Account'} + + + ); } @@ -30,6 +38,7 @@ export default class ChooseAuthPage extends React.Component { buttons.push( { @@ -39,7 +48,12 @@ export default class ChooseAuthPage extends React.Component { } > - {'Create new team with Google Apps Account'} + + + ); } @@ -48,6 +62,7 @@ export default class ChooseAuthPage extends React.Component { buttons.push( - {'Create new team with email address'} + + + ); } if (buttons.length === 0) { - buttons = {'No sign-up methods configured, please contact your system administrator.'}; + buttons = ( + + + + ); } return (
{buttons}
); diff --git a/web/react/components/team_signup_with_email.jsx b/web/react/components/team_signup_with_email.jsx index 4150a0013..7dd645b25 100644 --- a/web/react/components/team_signup_with_email.jsx +++ b/web/react/components/team_signup_with_email.jsx @@ -4,7 +4,20 @@ import * as Utils from '../utils/utils.jsx'; import * as Client from '../utils/client.jsx'; -export default class EmailSignUpPage extends React.Component { +import {injectIntl, intlShape, defineMessages, FormattedMessage} from 'mm-intl'; + +const holders = defineMessages({ + emailError: { + id: 'email_signup.emailError', + defaultMessage: 'Please enter a valid email address' + }, + address: { + id: 'email_signup.address', + defaultMessage: 'Email Address' + } +}); + +class EmailSignUpPage extends React.Component { constructor() { super(); @@ -20,7 +33,7 @@ export default class EmailSignUpPage extends React.Component { team.email = ReactDOM.findDOMNode(this.refs.email).value.trim().toLowerCase(); if (!team.email || !Utils.isEmail(team.email)) { - state.emailError = 'Please enter a valid email address'; + state.emailError = this.props.intl.formatMessage(holders.emailError); isValid = false; } else { state.emailError = null; @@ -67,7 +80,7 @@ export default class EmailSignUpPage extends React.Component { type='email' ref='email' className='form-control' - placeholder='Email Address' + placeholder={this.props.intl.formatMessage(holders.address)} maxLength='128' spellCheck='false' /> @@ -78,12 +91,20 @@ export default class EmailSignUpPage extends React.Component { className='btn btn-md btn-primary' type='submit' > - {'Create Team'} + {serverError}
- {`Find my teams`} + + +
); @@ -93,4 +114,7 @@ export default class EmailSignUpPage extends React.Component { EmailSignUpPage.defaultProps = { }; EmailSignUpPage.propTypes = { + intl: intlShape.isRequired }; + +export default injectIntl(EmailSignUpPage); \ No newline at end of file diff --git a/web/react/components/team_signup_with_sso.jsx b/web/react/components/team_signup_with_sso.jsx index f4b323956..465f73fd2 100644 --- a/web/react/components/team_signup_with_sso.jsx +++ b/web/react/components/team_signup_with_sso.jsx @@ -5,7 +5,24 @@ import * as utils from '../utils/utils.jsx'; import * as client from '../utils/client.jsx'; import Constants from '../utils/constants.jsx'; -export default class SSOSignUpPage extends React.Component { +import {injectIntl, intlShape, defineMessages, FormattedMessage} from 'mm-intl'; + +const holders = defineMessages({ + team_error: { + id: 'sso_signup.team_error', + defaultMessage: 'Please enter a team name' + }, + length_error: { + id: 'sso_signup.length_error', + defaultMessage: 'Name must be 3 or more characters up to a maximum of 15' + }, + teamName: { + id: 'sso_signup.teamName', + defaultMessage: 'Enter name of new team' + } +}); + +class SSOSignUpPage extends React.Component { constructor(props) { super(props); @@ -16,6 +33,7 @@ export default class SSOSignUpPage extends React.Component { } handleSubmit(e) { e.preventDefault(); + const {formatMessage} = this.props.intl; var team = {}; var state = this.state; state.nameError = null; @@ -24,13 +42,13 @@ export default class SSOSignUpPage extends React.Component { team.display_name = this.state.name; if (!team.display_name) { - state.nameError = 'Please enter a team name'; + state.nameError = formatMessage(holders.team_error); this.setState(state); return; } if (team.display_name.length <= 2) { - state.nameError = 'Name must be 3 or more characters up to a maximum of 15'; + state.nameError = formatMessage(holders.length_error); this.setState(state); return; } @@ -80,24 +98,36 @@ export default class SSOSignUpPage extends React.Component { button = ( - {'Create team with GitLab Account'} + + + ); } else if (this.props.service === Constants.GOOGLE_SERVICE) { button = ( - {'Create team with Google Apps Account'} + + + ); } @@ -113,7 +143,7 @@ export default class SSOSignUpPage extends React.Component { type='text' ref='teamname' className='form-control' - placeholder='Enter name of new team' + placeholder={this.props.intl.formatMessage(holders.teamName)} maxLength='128' onChange={this.nameChange} spellCheck='false' @@ -125,7 +155,12 @@ export default class SSOSignUpPage extends React.Component { {serverError}
- {'Find my teams'} + + +
); @@ -136,5 +171,8 @@ SSOSignUpPage.defaultProps = { service: '' }; SSOSignUpPage.propTypes = { + intl: intlShape.isRequired, service: React.PropTypes.string }; + +export default injectIntl(SSOSignUpPage); \ No newline at end of file diff --git a/web/react/pages/find_team.jsx b/web/react/pages/find_team.jsx index c4653fd77..ee2cf0de1 100644 --- a/web/react/pages/find_team.jsx +++ b/web/react/pages/find_team.jsx @@ -2,12 +2,61 @@ // See License.txt for license information. import FindTeam from '../components/find_team.jsx'; +import * as Client from '../utils/client.jsx'; -function setupFindTeamPage() { +var IntlProvider = ReactIntl.IntlProvider; + +class Root extends React.Component { + constructor() { + super(); + this.state = { + translations: null, + loaded: false + }; + } + + static propTypes() { + return { + map: React.PropTypes.object.isRequired + }; + } + + componentWillMount() { + Client.getTranslations( + this.props.map.Locale, + (data) => { + this.setState({ + translations: data, + loaded: true + }); + }, + () => { + this.setState({ + loaded: true + }); + } + ); + } + + render() { + if (!this.state.loaded) { + return
; + } + + return ( + + + + ); + } +} + +global.window.setup_find_team_page = function setup(props) { ReactDOM.render( - , + , document.getElementById('find-team') ); -} - -global.window.setup_find_team_page = setupFindTeamPage; +}; \ No newline at end of file diff --git a/web/react/pages/signup_team.jsx b/web/react/pages/signup_team.jsx index 8f4f86a7c..c80b65580 100644 --- a/web/react/pages/signup_team.jsx +++ b/web/react/pages/signup_team.jsx @@ -60,7 +60,7 @@ global.window.setup_signup_team_page = function setup(props) { for (var prop in props) { if (props.hasOwnProperty(prop)) { - if (prop !== 'Title') { + if (prop !== 'Title' && prop !== 'Locale' && prop !== 'Info') { teams.push({name: prop, display_name: props[prop]}); } } diff --git a/web/static/help/Messaging.md b/web/static/help/Messaging.md deleted file mode 120000 index f74c0b879..000000000 --- a/web/static/help/Messaging.md +++ /dev/null @@ -1 +0,0 @@ -../../../doc/help/Messaging.md \ No newline at end of file diff --git a/web/static/help/Messaging_en.md b/web/static/help/Messaging_en.md new file mode 120000 index 000000000..f74c0b879 --- /dev/null +++ b/web/static/help/Messaging_en.md @@ -0,0 +1 @@ +../../../doc/help/Messaging.md \ No newline at end of file diff --git a/web/static/help/Messaging_es.md b/web/static/help/Messaging_es.md new file mode 120000 index 000000000..a1890b510 --- /dev/null +++ b/web/static/help/Messaging_es.md @@ -0,0 +1 @@ +../../../doc/help/Messaging_es.md \ No newline at end of file diff --git a/web/static/i18n/en.json b/web/static/i18n/en.json index ae302b86e..5127d38d5 100644 --- a/web/static/i18n/en.json +++ b/web/static/i18n/en.json @@ -396,6 +396,11 @@ "admin.user_item.makeActive": "Make Active", "admin.user_item.makeInactive": "Make Inactive", "admin.user_item.resetPwd": "Reset Password", + "authorize.title": "An application would like to connect to your {teamName} account", + "authorize.app": "The app {appName} would like the ability to access and modify your basic information.", + "authorize.access": "Allow {appName} access?", + "authorize.deny": "Deny", + "authorize.allow": "Allow", "claim.account.noEmail": "No email specified", "claim.email_to_sso.pwdError": "Please enter your password.", "claim.email_to_sso.pwd": "Password", @@ -412,11 +417,76 @@ "claim.sso_to_email_newPwd": "Enter a new password for your {team} {site} account", "claim.sso_to_email.switchTo": "Switch {type} to email and password", "error_bar.preview_mode": "Preview Mode: Email notifications have not been configured", + "find_team.submitError": "Please enter a valid email address", + "find_team.placeholder": "you@domain.com", + "find_team.findTitle": "Find Your Team", + "find_team.findDescription": "An email was sent with links to any teams to which you are a member.", + "find_team.getLinks": "Get an email with links to any teams to which you are a member.", + "find_team.email": "Email", + "find_team.send": "Send", "loading_screen.loading": "Loading", + "login_email.badTeam": "Bad team name", + "login_email.emailReq": "An email is required", + "login_email.pwdReq": "A password is required", + "login_email.email": "Email", + "login_email.pwd": "Password", + "login_email.signin": "Sign in", + "login_ldap.badTeam": "Bad team name", + "login_ldap.idlReq": "An LDAP ID is required", + "login_ldap.pwdReq": "An LDAP password is required", + "login_ldap.username": "LDAP Username", + "login_ldap.pwd": "LDAP Password", + "login_ldap.signin": "Sign in", + "login.gitlab": "with GitLab", + "login.google": "with Google Apps", + "login.changed": " Sign-in method changed successfully", + "login.verified": " Email Verified", + "login.or": "or", + "login.forgot": "I forgot my password", + "login.noAccount": "Don't have an account? ", + "login.create": "Create one now", + "login.createTeam": "Create a new team", + "login.find": "Find your other teams", + "login.signTo": "Sign in to:", + "login.on": "on {siteName}", + "password_form.error": "Please enter at least {chars} characters.", + "password_form.update": "Your password has been updated successfully.", + "password_form.pwd": "Password", + "password_form.click": "Click here to log in.", + "password_form.title": "Password Reset", + "password_form.enter": "Enter a new password for your {teamDisplayName} {siteName} account.", + "password_form.change": "Change my password", + "password_send.error": "Please enter a valid email address.", + "password_send.link": "

A password reset link has been sent to {email} for your {teamDisplayName} team on {hostname}.

", + "password_send.checkInbox": "Please check your inbox.", + "password_send.email": "Email", + "password_send.title": "Password Reset", + "password_send.description": "To reset your password, enter the email address you used to sign up for {teamName}.", + "password_send.reset": "Reset my password", + "signup_team.noTeams": "There are no teams include in the Team Directory and team creation has been disabled.", + "signup_team.choose": "Choose a Team", + "signup_team.createTeam": "Or Create a Team", + "signup_team.disabled": "Team creation has been disabled. Please contact an administrator for access.", + "signup_team.none": "No team creation method has been enabled. Please contact an administrator for access.", "suggestion.mention.all": "Notifies everyone in the team", "suggestion.mention.channel": "Notifies everyone in the channel", "suggestion.search.public": "Public Channels", - "suggestion.search.private": "Private Groups", + "suggestion.search.private": "Public Groups", + "choose_auth_page.gitlabCreate": "Create new team with GitLab Account", + "choose_auth_page.googleCreate": "Create new team with Google Apps Account", + "choose_auth_page.emailCreate": "Create new team with email address", + "choose_auth_page.noSignup": "No sign-up methods configured, please contact your system administrator.", + "choose_auth_page.find": "Find my teams", + "email_signup.emailError": "Please enter a valid email address", + "email_signup.address": "Email Address", + "email_signup.createTeam": "Create Team", + "email_signup.find": "Find my teams", + "sso_signup.team_error": "Please enter a team name", + "sso_signup.length_error": "Name must be 3 or more characters up to a maximum of 15", + "sso_signup.teamName": "Enter name of new team", + "sso_signup.gitlab": "Create team with GitLab Account", + "sso_signup.google": "Create team with Google Apps Account", + "sso_signup.find": "Find my teams", "tutorial_intro.screenOne": "

Welcome to:

\n

Mattermost

\n

Your team communication all in one place, instantly searchable and available anywhere

\n

Keep your team connected to help them achieve what matters most.

", "tutorial_intro.screenTwo": "

How Mattermost works:

\n

Communication happens in public discussion channels, private groups and direct messages.

\n

Everything is archived and searchable from any web-enabled desktop, laptop or phone.

", "tutorial_intro.invite": "Invite teammates", diff --git a/web/static/i18n/es.json b/web/static/i18n/es.json index 12f9b5fc5..8743a9b4f 100644 --- a/web/static/i18n/es.json +++ b/web/static/i18n/es.json @@ -396,6 +396,16 @@ "admin.user_item.resetPwd": "Reiniciar Contraseña", "admin.user_item.sysAdmin": "Admin de Sistema", "admin.user_item.teamAdmin": "Admin de Equipo", + "authorize.access": "¿Permitir acceso a {appName}?", + "authorize.allow": "Permitir", + "authorize.app": "La app {appName} quiere tener la abilidad de accesar y modificar tu información básica.", + "authorize.deny": "Denegar", + "authorize.title": "Una aplicación quiere conectarse con tu cuenta de {teamName}", + "choose_auth_page.emailCreate": "Crea un nuevo equipo con tu cuenta de correo", + "choose_auth_page.find": "Encontrar mi equipo", + "choose_auth_page.gitlabCreate": "Crear un nuevo equipo con una cuenta de GitLab", + "choose_auth_page.googleCreate": "Crear un nuevo equipo con una cuenta de Google Apps", + "choose_auth_page.noSignup": "No hay métodos de inicio de sesión configurad, por favor contacte al administrador de sistemasos", "claim.account.noEmail": "No se especifico un correo electrónico.", "claim.email_to_sso.enterPwd": "Ingresa la contraseña para tu cuenta para {team} {site}", "claim.email_to_sso.pwd": "Contraseña", @@ -411,8 +421,68 @@ "claim.sso_to_email.switchTo": "Cambiar {type} a correo electrónico y contraseña", "claim.sso_to_email.title": "Cambiar la cuenta de {type} a Correo Electrónico", "claim.sso_to_email_newPwd": "Ingresa una nueva contraseña para tu cuenta de {team} {site}", + "email_signup.address": "Correo electrónico", + "email_signup.createTeam": "Crear Equipo", + "email_signup.emailError": "Por favor ingresa una dirección de correos válida", + "email_signup.find": "Encontrar mi equipo", "error_bar.preview_mode": "Modo de prueba: Las notificaciones por correo electrónico no han sido configuradas", + "find_team.email": "Correo electrónico", + "find_team.findDescription": "Enviamos un correo electrónico con los equipos a los que perteneces.", + "find_team.findTitle": "Encuentra tu equipo", + "find_team.getLinks": "Obtén un correo electrónico con los equipos a los que perteneces.", + "find_team.placeholder": "tu@ejemplo.com", + "find_team.send": "Enviar", + "find_team.submitError": "Por favor ingresa una dirección válida", "loading_screen.loading": "Cargando", + "login.changed": " Cambiado el método de inicio de sesión satisfactoriamente", + "login.create": "Crea uno ahora", + "login.createTeam": "Crear un nuevo equipo", + "login.find": "Encuentra tus otros equipos", + "login.forgot": "Olvide mi contraseña", + "login.gitlab": "con GitLab", + "login.google": "con Google Apps", + "login.noAccount": "¿No tienes una cuenta? ", + "login.on": "en {siteName}", + "login.or": "o", + "login.signTo": "Ingresar a:", + "login.verified": " Correo electrónico Verificado", + "login_email.badTeam": "Nombre de Equipo inválido", + "login_email.email": "Correo electrónico", + "login_email.emailReq": "El correo electrónico es obligatorio", + "login_email.pwd": "Contraseña", + "login_email.pwdReq": "La contraseña es obligatoria", + "login_email.signin": "Entrar", + "login_ldap.badTeam": "Nombre de Equipo inválido", + "login_ldap.idlReq": "El ID de LDAP es obligatorio", + "login_ldap.pwd": "Contraseña LDAP", + "login_ldap.pwdReq": "La contraseña LDAP es obligatoria", + "login_ldap.signin": "Entrar", + "login_ldap.username": "Usuario LDAP", + "password_form.change": "Cambiar mi contraseña", + "password_form.click": " Pincha aquí para iniciar sesión.", + "password_form.enter": "Ingresa una nueva contraseña para tu cuenta en {teamDisplayName} {SiteName}.", + "password_form.error": "Por favor ingresa al menos {chars} caracteres.", + "password_form.pwd": "Contraseña", + "password_form.title": "Restablecer Contraseña", + "password_form.update": "Tu contraseña ha sido actualizada satisfactoriamente.", + "password_send.checkInbox": "Por favor revisa tu bandeja de entrada.", + "password_send.description": "Para restablecer tu contraseña, ingresa la dirección de correo electrónico que utilizaste para registrarte en {teamName}.", + "password_send.email": "Correo electrónico", + "password_send.error": "Por favor ingresa una dirección correo electrónico válida.", + "password_send.link": "

Se ha enviado un enlace para restablecer la contraseña a {email} para tu equipo {teamDisplayName} en {hostname}.

", + "password_send.reset": "Restablecer mi contraseña", + "password_send.title": "Restablecer Contraseña", + "signup_team.choose": "Selecciona un Equipo", + "signup_team.createTeam": "O Crea un Equipo", + "signup_team.disabled": "La creación de Equipos ha sido deshabilitada.", + "signup_team.noTeams": "No hay equipos en el Directorio de Equipos y la creación de equipos ha sido deshabilitada.", + "signup_team.none": "No se ha habilitado ningún método para creación de equipos. Por favor contacta a un administrador de sistema para solicitar acceso.", + "sso_signup.find": "Encontrar mi equipo", + "sso_signup.gitlab": "Crea un equipo con una cuenta de GitLab", + "sso_signup.google": "Crea un equipo con una cuenta de Google Apps", + "sso_signup.length_error": "Name must be 3 or more characters up to a maximum of 15", + "sso_signup.teamName": "Ingresa el nombre del nuevo equipo", + "sso_signup.team_error": "Please enter a team name", "suggestion.mention.all": "Notifica a todas las personas en el equipo", "suggestion.mention.channel": "Notifica a todas las personas en el canal", "suggestion.search.private": "Grupos Privados", @@ -420,7 +490,7 @@ "tutorial_intro.allSet": "Ya estás listo para comenzar", "tutorial_intro.end": "Pincha “Siguiente” para entrar al Canal General. Este es el primer canal que ven tus compañeros cuando ingresan. Utilizalo para mandar mensajes que todos deben leer.", "tutorial_intro.invite": "Invitar compañeros", - "tutorial_intro.next": "Seguir", + "tutorial_intro.next": "Siguiente", "tutorial_intro.screenOne": "

Bienvenido a:

Mattermost

Las comunicaciones de tu equipo en un solo lugar, con búsquedas instantáneas y disponible desde donde sea.

Mantén a tu equipo conectado para ayudarlos a conseguir lo que realmente importa.

", "tutorial_intro.screenTwo": "

Cómo funciona Mattermost:

Las comunicaciones ocurren en los canales de discusión los cuales son públicos, o en grupos privados e incluso con mensajes privados.

Todo lo que ocurre es archivado y se puede buscar en cualquier momento desde cualquier dispositivo con acceso a Mattermost.

", "tutorial_intro.skip": "Saltar el tutorial", diff --git a/web/templates/find_team.html b/web/templates/find_team.html index d32ea0dc8..15b8bf463 100644 --- a/web/templates/find_team.html +++ b/web/templates/find_team.html @@ -23,7 +23,7 @@ diff --git a/web/templates/signup_team.html b/web/templates/signup_team.html index 39fd3791b..afba58066 100644 --- a/web/templates/signup_team.html +++ b/web/templates/signup_team.html @@ -10,7 +10,7 @@ diff --git a/web/web.go b/web/web.go index 36349dd5e..c0651c885 100644 --- a/web/web.go +++ b/web/web.go @@ -173,6 +173,7 @@ func root(c *api.Context, w http.ResponseWriter, r *http.Request) { if len(c.Session.UserId) == 0 { page := NewHtmlTemplatePage("signup_team", c.T("web.root.singup_title"), c.Locale) + page.Props["Info"] = c.T("web.root.singup_info") if result := <-api.Srv.Store.Team().GetAllTeamListing(); result.Err != nil { c.Err = result.Err -- cgit v1.2.3-1-g7c22