From 85d4ed21c73cf51f112ff944080e8bf54d53608a Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Tue, 26 Jan 2016 22:19:51 -0300 Subject: PLT-7: Refactoring frontend (chunk 1) - System console sidebar - Sytem console email settings - Error Bar - Loading Screen - Select Team Modal - Add npm mm-intl package --- .../admin_console/admin_navbar_dropdown.jsx | 25 +- .../components/admin_console/admin_sidebar.jsx | 134 ++++++-- .../admin_console/admin_sidebar_header.jsx | 9 +- .../components/admin_console/email_settings.jsx | 364 +++++++++++++++++---- .../components/admin_console/select_team_modal.jsx | 21 +- web/react/components/error_bar.jsx | 17 +- web/react/components/loading_screen.jsx | 9 +- 7 files changed, 480 insertions(+), 99 deletions(-) (limited to 'web/react/components') diff --git a/web/react/components/admin_console/admin_navbar_dropdown.jsx b/web/react/components/admin_console/admin_navbar_dropdown.jsx index 783d45de6..dc0b3c4cb 100644 --- a/web/react/components/admin_console/admin_navbar_dropdown.jsx +++ b/web/react/components/admin_console/admin_navbar_dropdown.jsx @@ -7,6 +7,8 @@ import TeamStore from '../../stores/team_store.jsx'; import Constants from '../../utils/constants.jsx'; +import {FormattedMessage} from 'mm-intl'; + function getStateFromStores() { return {currentTeam: TeamStore.getCurrent()}; } @@ -66,7 +68,13 @@ export default class AdminNavbarDropdown extends React.Component { - {'Switch to ' + this.state.currentTeam.display_name} +
  • @@ -74,7 +82,10 @@ export default class AdminNavbarDropdown extends React.Component { href='#' onClick={this.handleLogoutClick} > - {'Logout'} +
  • @@ -83,7 +94,10 @@ export default class AdminNavbarDropdown extends React.Component { target='_blank' href='/static/help/help.html' > - {'Help'} +
  • @@ -91,7 +105,10 @@ export default class AdminNavbarDropdown extends React.Component { target='_blank' href='/static/help/report_problem.html' > - {'Report a Problem'} +
  • diff --git a/web/react/components/admin_console/admin_sidebar.jsx b/web/react/components/admin_console/admin_sidebar.jsx index 66f82c55b..d6bae1feb 100644 --- a/web/react/components/admin_console/admin_sidebar.jsx +++ b/web/react/components/admin_console/admin_sidebar.jsx @@ -5,6 +5,8 @@ import AdminSidebarHeader from './admin_sidebar_header.jsx'; import SelectTeamModal from './select_team_modal.jsx'; import * as Utils from '../../utils/utils.jsx'; +import {FormattedMessage} from 'mm-intl'; + const Tooltip = ReactBootstrap.Tooltip; const OverlayTrigger = ReactBootstrap.OverlayTrigger; @@ -82,12 +84,27 @@ export default class AdminSidebar extends React.Component { render() { var count = '*'; - var teams = 'Loading'; + var teams = ( + + ); const removeTooltip = ( - {'Remove team from sidebar menu'} + + + ); const addTeamTooltip = ( - {'Add team from sidebar menu'} + + + ); if (this.props.teams != null) { @@ -134,7 +151,10 @@ export default class AdminSidebar extends React.Component { className={this.isSelected('team_users', team.id)} onClick={this.handleClick.bind(this, 'team_users', team.id)} > - {'- Users'} +
  • @@ -143,7 +163,10 @@ export default class AdminSidebar extends React.Component { className={this.isSelected('team_analytics', team.id)} onClick={this.handleClick.bind(this, 'team_analytics', team.id)} > - {'- Statistics'} +
  • @@ -166,7 +189,10 @@ export default class AdminSidebar extends React.Component { className={this.isSelected('ldap_settings')} onClick={this.handleClick.bind(this, 'ldap_settings', null)} > - {'LDAP Settings'} + ); @@ -179,7 +205,10 @@ export default class AdminSidebar extends React.Component { className={this.isSelected('license')} onClick={this.handleClick.bind(this, 'license', null)} > - {'Edition and License'} + ); @@ -196,7 +225,12 @@ export default class AdminSidebar extends React.Component {
  • - {'SITE REPORTS'} + + +

  • @@ -207,7 +241,10 @@ export default class AdminSidebar extends React.Component { className={this.isSelected('system_analytics')} onClick={this.handleClick.bind(this, 'system_analytics', null)} > - {'View Statistics'} + @@ -215,7 +252,12 @@ export default class AdminSidebar extends React.Component {
  • - {'SETTINGS'} + + +

  • @@ -226,7 +268,10 @@ export default class AdminSidebar extends React.Component { className={this.isSelected('service_settings')} onClick={this.handleClick.bind(this, 'service_settings', null)} > - {'Service Settings'} +
  • @@ -235,7 +280,10 @@ export default class AdminSidebar extends React.Component { className={this.isSelected('team_settings')} onClick={this.handleClick.bind(this, 'team_settings', null)} > - {'Team Settings'} +
  • @@ -244,7 +292,10 @@ export default class AdminSidebar extends React.Component { className={this.isSelected('sql_settings')} onClick={this.handleClick.bind(this, 'sql_settings', null)} > - {'SQL Settings'} +
  • @@ -253,7 +304,10 @@ export default class AdminSidebar extends React.Component { className={this.isSelected('email_settings')} onClick={this.handleClick.bind(this, 'email_settings', null)} > - {'Email Settings'} +
  • @@ -262,7 +316,10 @@ export default class AdminSidebar extends React.Component { className={this.isSelected('image_settings')} onClick={this.handleClick.bind(this, 'image_settings', null)} > - {'File Settings'} +
  • @@ -271,7 +328,10 @@ export default class AdminSidebar extends React.Component { className={this.isSelected('log_settings')} onClick={this.handleClick.bind(this, 'log_settings', null)} > - {'Log Settings'} +
  • @@ -280,7 +340,10 @@ export default class AdminSidebar extends React.Component { className={this.isSelected('rate_settings')} onClick={this.handleClick.bind(this, 'rate_settings', null)} > - {'Rate Limit Settings'} +
  • @@ -289,7 +352,10 @@ export default class AdminSidebar extends React.Component { className={this.isSelected('privacy_settings')} onClick={this.handleClick.bind(this, 'privacy_settings', null)} > - {'Privacy Settings'} +
  • @@ -298,7 +364,10 @@ export default class AdminSidebar extends React.Component { className={this.isSelected('gitlab_settings')} onClick={this.handleClick.bind(this, 'gitlab_settings', null)} > - {'GitLab Settings'} +
  • {ldapSettings} @@ -308,7 +377,10 @@ export default class AdminSidebar extends React.Component { className={this.isSelected('legal_and_support_settings')} onClick={this.handleClick.bind(this, 'legal_and_support_settings', null)} > - {'Legal and Support Settings'} + @@ -316,7 +388,15 @@ export default class AdminSidebar extends React.Component {
  • - {'TEAMS (' + count + ')'} + + +

    - {'OTHER'} + + +

  • @@ -357,7 +442,10 @@ export default class AdminSidebar extends React.Component { className={this.isSelected('logs')} onClick={this.handleClick.bind(this, 'logs', null)} > - {'Logs'} + diff --git a/web/react/components/admin_console/admin_sidebar_header.jsx b/web/react/components/admin_console/admin_sidebar_header.jsx index bfd479939..db499265e 100644 --- a/web/react/components/admin_console/admin_sidebar_header.jsx +++ b/web/react/components/admin_console/admin_sidebar_header.jsx @@ -5,6 +5,8 @@ import AdminNavbarDropdown from './admin_navbar_dropdown.jsx'; import UserStore from '../../stores/user_store.jsx'; import * as Utils from '../../utils/utils.jsx'; +import {FormattedMessage} from 'mm-intl'; + export default class SidebarHeader extends React.Component { constructor(props) { super(props); @@ -51,7 +53,12 @@ export default class SidebarHeader extends React.Component { {profilePicture}
    {'@' + me.username}
    -
    {'System Console'}
    +
    + +
    diff --git a/web/react/components/admin_console/email_settings.jsx b/web/react/components/admin_console/email_settings.jsx index c568c5a77..ce3c8cd12 100644 --- a/web/react/components/admin_console/email_settings.jsx +++ b/web/react/components/admin_console/email_settings.jsx @@ -5,7 +5,68 @@ import * as Client from '../../utils/client.jsx'; import * as AsyncClient from '../../utils/async_client.jsx'; import crypto from 'crypto'; -export default class EmailSettings extends React.Component { +import {injectIntl, intlShape, defineMessages, FormattedMessage, FormattedHTMLMessage} from 'mm-intl'; + +var holders = defineMessages({ + notificationDisplayExample: { + id: 'admin.email.notificationDisplayExample', + defaultMessage: 'Ex: "Mattermost Notification", "System", "No-Reply"' + }, + notificationEmailExample: { + id: 'admin.email.notificationEmailExample', + defaultMessage: 'Ex: "mattermost@yourcompany.com", "admin@yourcompany.com"' + }, + smtpUsernameExample: { + id: 'admin.email.smtpUsernameExample', + defaultMessage: 'Ex: "admin@yourcompany.com", "AKIADTOVBGERKLCBV"' + }, + smtpPasswordExample: { + id: 'admin.email.smtpPasswordExample', + defaultMessage: 'Ex: "yourpassword", "jcuS8PuvcpGhpgHhlcpT1Mx42pnqMxQY"' + }, + smtpServerExample: { + id: 'admin.email.smtpServerExample', + defaultMessage: 'Ex: "smtp.yourcompany.com", "email-smtp.us-east-1.amazonaws.com"' + }, + smtpPortExample: { + id: 'admin.email.smtpPortExample', + defaultMessage: 'Ex: "25", "465"' + }, + connectionSecurityNone: { + id: 'admin.email.connectionSecurityNone', + defaultMessage: 'None' + }, + connectionSecurityTls: { + id: 'admin.email.connectionSecurityTls', + defaultMessage: 'TLS (Recommended)' + }, + connectionSecurityStart: { + id: 'admin.email.connectionSecurityStart', + defaultMessage: 'STARTTLS' + }, + inviteSaltExample: { + id: 'admin.email.inviteSaltExample', + defaultMessage: 'Ex "bjlSR4QqkXFBr7TP4oDzlfZmcNuH9Yo"' + }, + passwordSaltExample: { + id: 'admin.email.passwordSaltExample', + defaultMessage: 'Ex "bjlSR4QqkXFBr7TP4oDzlfZmcNuH9Yo"' + }, + pushServerEx: { + id: 'admin.email.pushServerEx', + defaultMessage: 'E.g.: "https://push-test.mattermost.com"' + }, + testing: { + id: 'admin.email.testing', + defaultMessage: 'Testing...' + }, + saving: { + id: 'admin.email.saving', + defaultMessage: 'Saving Config...' + } +}); + +class EmailSettings extends React.Component { constructor(props) { super(props); @@ -156,6 +217,7 @@ export default class EmailSettings extends React.Component { } render() { + const {formatMessage} = this.props.intl; var serverError = ''; if (this.state.serverError) { serverError =
    ; @@ -170,7 +232,11 @@ export default class EmailSettings extends React.Component { if (this.state.emailSuccess) { emailSuccess = (
    - {'No errors were reported while sending an email. Please check your inbox to make sure.'} + +
    ); } @@ -179,14 +245,26 @@ export default class EmailSettings extends React.Component { if (this.state.emailFail) { emailSuccess = (
    - {'Connection unsuccessful: ' + this.state.emailFail} + +
    ); } return (
    -

    {'Email Settings'}

    +

    + +

    - {'Allow Sign Up With Email: '} +
    -

    {'When true, Mattermost allows team creation and account signup using email and password. This value should be false only when you want to limit signup to a single-sign-on service like OAuth or LDAP.'}

    +

    + +

    @@ -230,7 +322,10 @@ export default class EmailSettings extends React.Component { className='control-label col-sm-4' htmlFor='sendEmailNotifications' > - {'Send Email Notifications: '} +
    -

    {'Typically set to true in production. When true, Mattermost attempts to send email notifications. Developers may set this field to false to skip email setup for faster development.\nSetting this to true removes the Preview Mode banner (requires logging out and logging back in after setting is changed).'}

    +

    + +

    @@ -263,7 +369,10 @@ export default class EmailSettings extends React.Component { className='control-label col-sm-4' htmlFor='requireEmailVerification' > - {'Require Email Verification: '} +
    -

    {'Typically set to true in production. When true, Mattermost requires email verification after account creation prior to allowing login. Developers may set this field to false so skip sending verification emails for faster development.'}

    +

    + +

    @@ -298,7 +418,10 @@ export default class EmailSettings extends React.Component { className='control-label col-sm-4' htmlFor='feedbackName' > - {'Notification Display Name:'} +
    -

    {'Display name on email account used when sending notification emails from Mattermost.'}

    +

    + +

    @@ -320,7 +448,10 @@ export default class EmailSettings extends React.Component { className='control-label col-sm-4' htmlFor='feedbackEmail' > - {'Notification Email Address:'} +
    -

    {'Email address displayed on email account used when sending notification emails from Mattermost.'}

    +

    + +

    @@ -342,7 +478,10 @@ export default class EmailSettings extends React.Component { className='control-label col-sm-4' htmlFor='SMTPUsername' > - {'SMTP Username:'} +
    -

    {' Obtain this credential from administrator setting up your email server.'}

    +

    + +

    @@ -364,7 +508,10 @@ export default class EmailSettings extends React.Component { className='control-label col-sm-4' htmlFor='SMTPPassword' > - {'SMTP Password:'} +
    -

    {' Obtain this credential from administrator setting up your email server.'}

    +

    + +

    @@ -386,7 +538,10 @@ export default class EmailSettings extends React.Component { className='control-label col-sm-4' htmlFor='SMTPServer' > - {'SMTP Server:'} +
    -

    {'Location of SMTP email server.'}

    +

    + +

    @@ -408,7 +568,10 @@ export default class EmailSettings extends React.Component { className='control-label col-sm-4' htmlFor='SMTPPort' > - {'SMTP Port:'} +
    -

    {'Port of SMTP email server.'}

    +

    + +

    @@ -430,7 +598,10 @@ export default class EmailSettings extends React.Component { className='control-label col-sm-4' htmlFor='ConnectionSecurity' > - {'Connection Security:'} +
    - - - + + +
    {'None'}{'Mattermost will send email over an unsecure connection.'}
    {'TLS'}{'Encrypts the communication between Mattermost and your email server.'}
    {'STARTTLS'}{'Takes an existing insecure connection and attempts to upgrade it to a secure connection using TLS.'}
    + + + +
    {'TLS'} + +
    {'STARTTLS'} + +
    @@ -463,9 +654,12 @@ export default class EmailSettings extends React.Component { onClick={this.handleTestConnection} disabled={!this.state.sendEmailNotifications} id='connection-button' - data-loading-text={' Testing...'} + data-loading-text={' ' + formatMessage(holders.testing)} > - {'Test Connection'} + {emailSuccess} {emailFail} @@ -478,7 +672,10 @@ export default class EmailSettings extends React.Component { className='control-label col-sm-4' htmlFor='InviteSalt' > - {'Invite Salt:'} +
    -

    {'32-character salt added to signing of email invites. Randomly generated on install. Click "Re-Generate" to create new salt.'}

    +

    + +

    @@ -509,7 +714,10 @@ export default class EmailSettings extends React.Component { className='control-label col-sm-4' htmlFor='PasswordResetSalt' > - {'Password Reset Salt:'} +
    -

    {'32-character salt added to signing of password reset emails. Randomly generated on install. Click "Re-Generate" to create new salt.'}

    +

    + +

    @@ -540,7 +756,10 @@ export default class EmailSettings extends React.Component { className='control-label col-sm-4' htmlFor='sendPushNotifications' > - {'Send Push Notifications: '} +
    -

    {'Typically set to true in production. When true, Mattermost attempts to send iOS and Android push notifications through the push notification server.'}

    +

    + +

    @@ -573,7 +803,10 @@ export default class EmailSettings extends React.Component { className='control-label col-sm-4' htmlFor='PushNotificationServer' > - {'Push Notification Server:'} +
    -

    {'Location of Mattermost push notification service you can set up behind your firewall using https://github.com/mattermost/push-proxy. For testing you can use https://push-test.mattermost.com, which connects to the sample Mattermost iOS app in the public Apple AppStore. Please do not use test service for production deployments.'}

    +

    + +

    @@ -599,9 +837,12 @@ export default class EmailSettings extends React.Component { className={saveClass} onClick={this.handleSubmit} id='save-button' - data-loading-text={' Saving Config...'} + data-loading-text={' ' + formatMessage(holders.saving)} > - {'Save'} + @@ -613,5 +854,8 @@ export default class EmailSettings extends React.Component { } EmailSettings.propTypes = { + intl: intlShape.isRequired, config: React.PropTypes.object }; + +export default injectIntl(EmailSettings); \ No newline at end of file diff --git a/web/react/components/admin_console/select_team_modal.jsx b/web/react/components/admin_console/select_team_modal.jsx index 858b6bbfe..e0d070b28 100644 --- a/web/react/components/admin_console/select_team_modal.jsx +++ b/web/react/components/admin_console/select_team_modal.jsx @@ -1,6 +1,8 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. +import {FormattedMessage} from 'mm-intl'; + var Modal = ReactBootstrap.Modal; export default class SelectTeamModal extends React.Component { @@ -45,7 +47,12 @@ export default class SelectTeamModal extends React.Component { onHide={this.doCancel} > - {'Select Team'} + + + - {'Close'} + @@ -96,4 +109,4 @@ SelectTeamModal.propTypes = { show: React.PropTypes.bool.isRequired, onModalSubmit: React.PropTypes.func, onModalDismissed: React.PropTypes.func -}; +}; \ No newline at end of file diff --git a/web/react/components/error_bar.jsx b/web/react/components/error_bar.jsx index e93545c25..e9aa8197c 100644 --- a/web/react/components/error_bar.jsx +++ b/web/react/components/error_bar.jsx @@ -3,6 +3,16 @@ import ErrorStore from '../stores/error_store.jsx'; +// import mm-intl is required for the tool to be able to extract the messages +import {defineMessages} from 'mm-intl'; + +var messages = defineMessages({ + preview: { + id: 'error_bar.preview_mode', + defaultMessage: 'Preview Mode: Email notifications have not been configured' + } +}); + export default class ErrorBar extends React.Component { constructor() { super(); @@ -49,12 +59,7 @@ export default class ErrorBar extends React.Component { componentWillMount() { if (global.window.mm_config.SendEmailNotifications === 'false') { - ErrorStore.storeLastError({message: this.props.intl.formatMessage( - { - id: 'error_bar.preview_mode', - defaultMessage: 'Preview Mode: Email notifications have not been configured' - } - )}); + ErrorStore.storeLastError({message: this.props.intl.formatMessage(messages.preview)}); this.onErrorChange(); } } diff --git a/web/react/components/loading_screen.jsx b/web/react/components/loading_screen.jsx index 9849205f2..143b94467 100644 --- a/web/react/components/loading_screen.jsx +++ b/web/react/components/loading_screen.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 LoadingScreen extends React.Component { constructor(props) { super(props); @@ -13,7 +15,12 @@ export default class LoadingScreen extends React.Component { style={{position: this.props.position}} >
    -

    Loading

    +

    + +

    -- cgit v1.2.3-1-g7c22