diff options
22 files changed, 887 insertions, 153 deletions
diff --git a/i18n/en.json b/i18n/en.json index 7b7ee344a..8cbdd4993 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -1648,6 +1648,38 @@ "translation": "Inappropriate permissions to regenerate outcoming webhook token" }, { + "id": "ent.ldap.do_login.bind_admin_user.app_error", + "translation": "Unable to bind to LDAP server. Check BindUsername and BindPassword." + }, + { + "id": "ent.ldap.do_login.invalid_password.app_error", + "translation": "Invalid Password" + }, + { + "id": "ent.ldap.do_login.licence_disable.app_error", + "translation": "LDAP functionality disabled by current license. Please contact your system administrator about upgrading your enterprise license." + }, + { + "id": "ent.ldap.do_login.matched_to_many_users.app_error", + "translation": "Username given matches multiple users" + }, + { + "id": "ent.ldap.do_login.search_ldap_server.app_error", + "translation": "Failed to search LDAP server" + }, + { + "id": "ent.ldap.do_login.unable_to_connect.app_error", + "translation": "Unable to connect to LDAP server" + }, + { + "id": "ent.ldap.do_login.unable_to_create_user.app_error", + "translation": "Credentials valid but unable to create user." + }, + { + "id": "ent.ldap.do_login.user_not_registered.app_error", + "translation": "User not registered on LDAP server" + }, + { "id": "manaultesting.get_channel_id.no_found.debug", "translation": "Could not find channel: %v, %v possibilites searched" }, @@ -3406,37 +3438,5 @@ { "id": "web.watcher_fail.error", "translation": "Failed to add directory to watcher %v" - }, - { - "id": "ent.ldap.do_login.licence_disable.app_error", - "translation": "LDAP functionality disabled by current license. Please contact your system administrator about upgrading your enterprise license." - }, - { - "id": "ent.ldap.do_login.unable_to_connect.app_error", - "translation": "Unable to connect to LDAP server" - }, - { - "id": "ent.ldap.do_login.bind_admin_user.app_error", - "translation": "Unable to bind to LDAP server. Check BindUsername and BindPassword." - }, - { - "id": "ent.ldap.do_login.search_ldap_server.app_error", - "translation": "Failed to search LDAP server" - }, - { - "id": "ent.ldap.do_login.user_not_registered.app_error", - "translation": "User not registered on LDAP server" - }, - { - "id": "ent.ldap.do_login.matched_to_many_users.app_error", - "translation": "Username given matches multiple users" - }, - { - "id": "ent.ldap.do_login.invalid_password.app_error", - "translation": "Invalid Password" - }, - { - "id": "ent.ldap.do_login.unable_to_create_user.app_error", - "translation": "Credentials valid but unable to create user." } -] +]
\ No newline at end of file diff --git a/i18n/es.json b/i18n/es.json index f0f157474..bd29c9860 100644 --- a/i18n/es.json +++ b/i18n/es.json @@ -1648,6 +1648,38 @@ "translation": "Permisos inapropiados para regenerar un token para el Webhook saliente" }, { + "id": "ent.ldap.do_login.bind_admin_user.app_error", + "translation": "No se pudo enlazar con el servidor LDAP. Revisa las opciones de BindUsername y BindPassword." + }, + { + "id": "ent.ldap.do_login.invalid_password.app_error", + "translation": "Contraseña inválida" + }, + { + "id": "ent.ldap.do_login.licence_disable.app_error", + "translation": "Las funcionalidades de LDAP están deshabilitadas con la licencia actual. Por favor contacta a un administrador del sistema acerca de mejorar la licencia enterprise." + }, + { + "id": "ent.ldap.do_login.matched_to_many_users.app_error", + "translation": "Nombre de usuario dado coincide con varios usuarios" + }, + { + "id": "ent.ldap.do_login.search_ldap_server.app_error", + "translation": "Falla al buscar en el servidor LDAP" + }, + { + "id": "ent.ldap.do_login.unable_to_connect.app_error", + "translation": "No se pudo conectar con el servidor LDAP" + }, + { + "id": "ent.ldap.do_login.unable_to_create_user.app_error", + "translation": "Credenciales válidas pero no se pudo crear el usuario." + }, + { + "id": "ent.ldap.do_login.user_not_registered.app_error", + "translation": "Usuario no registrado en el servidor LDAP" + }, + { "id": "manaultesting.get_channel_id.no_found.debug", "translation": "No pudimos encontrar el canal: %v, búsqueda realizada con estas posibilidades %v" }, @@ -3407,4 +3439,4 @@ "id": "web.watcher_fail.error", "translation": "Falla al agregar el directorio a ser vigilado %v" } -] +]
\ No newline at end of file diff --git a/web/react/components/channel_header.jsx b/web/react/components/channel_header.jsx index f64834775..005a82209 100644 --- a/web/react/components/channel_header.jsx +++ b/web/react/components/channel_header.jsx @@ -24,8 +24,10 @@ import * as TextFormatting from '../utils/text_formatting.jsx'; import * as AsyncClient from '../utils/async_client.jsx'; import * as Client from '../utils/client.jsx'; import Constants from '../utils/constants.jsx'; -const ActionTypes = Constants.ActionTypes; +import {FormattedMessage} from 'mm-intl'; + +const ActionTypes = Constants.ActionTypes; const Popover = ReactBootstrap.Popover; const OverlayTrigger = ReactBootstrap.OverlayTrigger; const Tooltip = ReactBootstrap.Tooltip; @@ -124,7 +126,14 @@ export default class ChannelHeader extends React.Component { } const channel = this.state.channel; - const recentMentionsTooltip = <Tooltip id='recentMentionsTooltip'>{'Recent Mentions'}</Tooltip>; + const recentMentionsTooltip = ( + <Tooltip id='recentMentionsTooltip'> + <FormattedMessage + id='channel_header.recentMentions' + defaultMessage='Recent Mentions' + /> + </Tooltip> + ); const popoverContent = ( <Popover id='hader-popover' @@ -157,9 +166,19 @@ export default class ChannelHeader extends React.Component { } } - let channelTerm = 'Channel'; - if (channel.type === 'P') { - channelTerm = 'Group'; + let channelTerm = ( + <FormattedMessage + id='channel_header.channel' + defaultMessage='Channel' + /> + ); + if (channel.type === Constants.PRIVATE_CHANNEL) { + channelTerm = ( + <FormattedMessage + id='channel_header.group' + defaultMessage='Group' + /> + ); } const dropdownContents = []; @@ -174,7 +193,10 @@ export default class ChannelHeader extends React.Component { dialogType={EditChannelHeaderModal} dialogProps={{channel}} > - {'Set Channel Header...'} + <FormattedMessage + id='channel_header.channelHeader' + defaultMessage='Set Channel Header...' + /> </ToggleModalButton> </li> ); @@ -189,7 +211,10 @@ export default class ChannelHeader extends React.Component { dialogType={ChannelInfoModal} dialogProps={{channel}} > - {'View Info'} + <FormattedMessage + id='channel_header.viewInfo' + defaultMessage='View Info' + /> </ToggleModalButton> </li> ); @@ -205,7 +230,10 @@ export default class ChannelHeader extends React.Component { dialogType={ChannelInviteModal} dialogProps={{channel}} > - {'Add Members'} + <FormattedMessage + id='chanel_header.addMembers' + defaultMessage='Add Members' + /> </ToggleModalButton> </li> ); @@ -221,7 +249,10 @@ export default class ChannelHeader extends React.Component { href='#' onClick={() => this.setState({showMembersModal: true})} > - {'Manage Members'} + <FormattedMessage + id='channel_header.manageMembers' + defaultMessage='Manage Members' + /> </a> </li> ); @@ -238,7 +269,13 @@ export default class ChannelHeader extends React.Component { dialogType={EditChannelHeaderModal} dialogProps={{channel}} > - {`Set ${channelTerm} Header...`} + <FormattedMessage + id='channel_header.setHeader' + defaultMessage='Set {term} Header...' + values={{ + term: (channelTerm) + }} + /> </ToggleModalButton> </li> ); @@ -252,7 +289,13 @@ export default class ChannelHeader extends React.Component { href='#' onClick={() => this.setState({showEditChannelPurposeModal: true})} > - {'Set '}{channelTerm}{' Purpose...'} + <FormattedMessage + id='channel_header.setPurpose' + defaultMessage='Set {term} Purpose...' + values={{ + term: (channelTerm) + }} + /> </a> </li> ); @@ -266,7 +309,10 @@ export default class ChannelHeader extends React.Component { dialogType={ChannelNotificationsModal} dialogProps={{channel}} > - {'Notification Preferences'} + <FormattedMessage + id='channel_header.notificationPreferences' + defaultMessage='Notification Preferences' + /> </ToggleModalButton> </li> ); @@ -286,7 +332,13 @@ export default class ChannelHeader extends React.Component { data-name={channel.name} data-channelid={channel.id} > - {'Rename '}{channelTerm}{'...'} + <FormattedMessage + id='channel_header.rename' + defaultMessage='Rename {term}...' + values={{ + term: (channelTerm) + }} + /> </a> </li> ); @@ -302,7 +354,13 @@ export default class ChannelHeader extends React.Component { dialogType={DeleteChannelModal} dialogProps={{channel}} > - {'Delete '}{channelTerm}{'...'} + <FormattedMessage + id='channel_header.delete' + defaultMessage='Delete {term}...' + values={{ + term: (channelTerm) + }} + /> </ToggleModalButton> </li> ); @@ -320,7 +378,13 @@ export default class ChannelHeader extends React.Component { href='#' onClick={this.handleLeave} > - {'Leave '}{channelTerm} + <FormattedMessage + id='channel_header.leave' + defaultMessage='Leave {term}' + values={{ + term: (channelTerm) + }} + /> </a> </li> ); diff --git a/web/react/components/channel_info_modal.jsx b/web/react/components/channel_info_modal.jsx index 72c7c3daa..5067f5913 100644 --- a/web/react/components/channel_info_modal.jsx +++ b/web/react/components/channel_info_modal.jsx @@ -2,17 +2,28 @@ // See License.txt for license information. import * as Utils from '../utils/utils.jsx'; + +import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'mm-intl'; + const Modal = ReactBootstrap.Modal; -export default class ChannelInfoModal extends React.Component { +const holders = defineMessages({ + notFound: { + id: 'channel_info.notFound', + defaultMessage: 'No Channel Found' + } +}); + +class ChannelInfoModal extends React.Component { render() { + const {formatMessage} = this.props.intl; let channel = this.props.channel; if (!channel) { channel = { - display_name: 'No Channel Found', - name: 'No Channel Found', - purpose: 'No Channel Found', - id: 'No Channel Found' + display_name: formatMessage(holders.notFound), + name: formatMessage(holders.notFound), + purpose: formatMessage(holders.notFound), + id: formatMessage(holders.notFound) }; } @@ -28,19 +39,39 @@ export default class ChannelInfoModal extends React.Component { </Modal.Header> <Modal.Body ref='modalBody'> <div className='row form-group'> - <div className='col-sm-3 info__label'>{'Channel Name:'}</div> + <div className='col-sm-3 info__label'> + <FormattedMessage + id='channel_info.name' + defaultMessage='Channel Name:' + /> + </div> <div className='col-sm-9'>{channel.display_name}</div> </div> <div className='row form-group'> - <div className='col-sm-3 info__label'>{'Channel URL:'}</div> + <div className='col-sm-3 info__label'> + <FormattedMessage + id='channel_info.url' + defaultMessage='Channel URL:' + /> + </div> <div className='col-sm-9'>{channelURL}</div> </div> <div className='row'> - <div className='col-sm-3 info__label'>{'Channel ID:'}</div> + <div className='col-sm-3 info__label'> + <FormattedMessage + id='channel_info.id' + defaultMessage='Channel ID:' + /> + </div> <div className='col-sm-9'>{channel.id}</div> </div> <div className='row'> - <div className='col-sm-3 info__label'>{'Channel Purpose:'}</div> + <div className='col-sm-3 info__label'> + <FormattedMessage + id='channel_info.purpose' + defaultMessage='Channel Purpose:' + /> + </div> <div className='col-sm-9'>{channel.purpose}</div> </div> </Modal.Body> @@ -50,7 +81,10 @@ export default class ChannelInfoModal extends React.Component { className='btn btn-default' onClick={this.props.onHide} > - {'Close'} + <FormattedMessage + id='channel_info.close' + defaultMessage='Close' + /> </button> </Modal.Footer> </Modal> @@ -59,7 +93,10 @@ export default class ChannelInfoModal extends React.Component { } ChannelInfoModal.propTypes = { + intl: intlShape.isRequired, show: React.PropTypes.bool.isRequired, onHide: React.PropTypes.func.isRequired, channel: React.PropTypes.object.isRequired }; + +export default injectIntl(ChannelInfoModal);
\ No newline at end of file diff --git a/web/react/components/channel_invite_modal.jsx b/web/react/components/channel_invite_modal.jsx index 8b7485e5f..7dc2c0a11 100644 --- a/web/react/components/channel_invite_modal.jsx +++ b/web/react/components/channel_invite_modal.jsx @@ -11,6 +11,8 @@ import * as Utils from '../utils/utils.jsx'; import * as Client from '../utils/client.jsx'; import * as AsyncClient from '../utils/async_client.jsx'; +import {FormattedMessage} from 'mm-intl'; + const Modal = ReactBootstrap.Modal; export default class ChannelInviteModal extends React.Component { @@ -154,7 +156,13 @@ export default class ChannelInviteModal extends React.Component { onHide={this.props.onHide} > <Modal.Header closeButton={true}> - <Modal.Title>{'Add New Members to '}<span className='name'>{this.props.channel.display_name}</span></Modal.Title> + <Modal.Title> + <FormattedMessage + id='channel_invite.addNewMembers' + defaultMessage='Add New Members to ' + /> + <span className='name'>{this.props.channel.display_name}</span> + </Modal.Title> </Modal.Header> <Modal.Body ref='modalBody' @@ -168,7 +176,10 @@ export default class ChannelInviteModal extends React.Component { className='btn btn-default' onClick={this.props.onHide} > - {'Close'} + <FormattedMessage + id='channel_invite.close' + defaultMessage='Close' + /> </button> </Modal.Footer> </Modal> diff --git a/web/react/components/channel_members_modal.jsx b/web/react/components/channel_members_modal.jsx index 513a720e7..f3cbef719 100644 --- a/web/react/components/channel_members_modal.jsx +++ b/web/react/components/channel_members_modal.jsx @@ -12,6 +12,8 @@ import * as AsyncClient from '../utils/async_client.jsx'; import * as Client from '../utils/client.jsx'; import * as Utils from '../utils/utils.jsx'; +import {FormattedMessage} from 'mm-intl'; + const Modal = ReactBootstrap.Modal; export default class ChannelMembersModal extends React.Component { @@ -191,7 +193,13 @@ export default class ChannelMembersModal extends React.Component { onHide={this.props.onModalDismissed} > <Modal.Header closeButton={true}> - <Modal.Title><span className='name'>{this.props.channel.display_name}</span>{' Members'}</Modal.Title> + <Modal.Title> + <span className='name'>{this.props.channel.display_name}</span> + <FormattedMessage + id='channel_memebers_modal.members' + defaultMessage=' Members' + /> + </Modal.Title> <a className='btn btn-md btn-primary' href='#' @@ -200,7 +208,11 @@ export default class ChannelMembersModal extends React.Component { this.props.onModalDismissed(); }} > - <i className='glyphicon glyphicon-envelope'/>{' Add New Members'} + <i className='glyphicon glyphicon-envelope'/> + <FormattedMessage + id='channel_members_modal.addNew' + defaultMessage=' Add New Members' + /> </a> </Modal.Header> <Modal.Body @@ -215,7 +227,10 @@ export default class ChannelMembersModal extends React.Component { className='btn btn-default' onClick={this.props.onModalDismissed} > - {'Close'} + <FormattedMessage + id='channel_members_modal.close' + defaultMessage='Close' + /> </button> </Modal.Footer> </Modal> diff --git a/web/react/components/channel_notifications_modal.jsx b/web/react/components/channel_notifications_modal.jsx index e70d3a634..59ef8966e 100644 --- a/web/react/components/channel_notifications_modal.jsx +++ b/web/react/components/channel_notifications_modal.jsx @@ -9,6 +9,8 @@ import * as Client from '../utils/client.jsx'; import UserStore from '../stores/user_store.jsx'; import ChannelStore from '../stores/channel_store.jsx'; +import {FormattedMessage} from 'mm-intl'; + export default class ChannelNotificationsModal extends React.Component { constructor(props) { super(props); @@ -97,13 +99,35 @@ export default class ChannelNotificationsModal extends React.Component { let globalNotifyLevelName; if (globalNotifyLevel === 'all') { - globalNotifyLevelName = 'For all activity'; + globalNotifyLevelName = ( + <FormattedMessage + id='channel_notifications.allActivity' + defaultMessage='For all activity' + /> + ); } else if (globalNotifyLevel === 'mention') { - globalNotifyLevelName = 'Only for mentions'; + globalNotifyLevelName = ( + <FormattedMessage + id='channel_notifications.onlyMentions' + defaultMessage='Only for mentions' + /> + ); } else { - globalNotifyLevelName = 'Never'; + globalNotifyLevelName = ( + <FormattedMessage + id='channel_notifications.never' + defaultMessage='Never' + /> + ); } + const sendDesktop = ( + <FormattedMessage + id='channel_notifications.sendDesktop' + defaultMessage='Send desktop notifications' + /> + ); + if (this.state.activeSection === 'desktop') { var notifyActive = [false, false, false, false]; if (this.state.notifyLevel === 'default') { @@ -127,7 +151,13 @@ export default class ChannelNotificationsModal extends React.Component { checked={notifyActive[0]} onChange={this.handleUpdateNotifyLevel.bind(this, 'default')} /> - {`Global default (${globalNotifyLevelName})`} + <FormattedMessage + id='channel_notifications.globalDefault' + defaultMessage='Global default ({notifyLevel}' + values={{ + notifyLevel: (globalNotifyLevelName) + }} + /> </label> <br/> </div> @@ -138,7 +168,7 @@ export default class ChannelNotificationsModal extends React.Component { checked={notifyActive[1]} onChange={this.handleUpdateNotifyLevel.bind(this, 'all')} /> - {'For all activity'} + <FormattedMessage id='channel_notifications.allActivity' /> </label> <br/> </div> @@ -149,7 +179,7 @@ export default class ChannelNotificationsModal extends React.Component { checked={notifyActive[2]} onChange={this.handleUpdateNotifyLevel.bind(this, 'mention')} /> - {'Only for mentions'} + <FormattedMessage id='channel_notifications.onlyMentions' /> </label> <br/> </div> @@ -160,7 +190,7 @@ export default class ChannelNotificationsModal extends React.Component { checked={notifyActive[3]} onChange={this.handleUpdateNotifyLevel.bind(this, 'none')} /> - {'Never'} + <FormattedMessage id='channel_notifications.never' /> </label> </div> </div> @@ -174,13 +204,16 @@ export default class ChannelNotificationsModal extends React.Component { const extraInfo = ( <span> - {'Selecting an option other than "Default" will override the global notification settings. Desktop notifications are available on Firefox, Safari, and Chrome.'} + <FormattedMessage + id='channel_notifications.override' + defaultMessage='Selecting an option other than "Default" will override the global notification settings. Desktop notifications are available on Firefox, Safari, and Chrome.' + /> </span> ); return ( <SettingItemMax - title='Send desktop notifications' + title={sendDesktop} inputs={inputs} submit={this.handleSubmitNotifyLevel} server_error={serverError} @@ -192,13 +225,20 @@ export default class ChannelNotificationsModal extends React.Component { var describe; if (this.state.notifyLevel === 'default') { - describe = `Global default (${globalNotifyLevelName})`; + describe = ( + <FormattedMessage + id='channel_notifications.globalDefault' + values={{ + notifyLevel: (globalNotifyLevelName) + }} + /> + ); } else if (this.state.notifyLevel === 'mention') { - describe = 'Only for mentions'; + describe = (<FormattedMessage id='channel_notifications.onlyMentions' />); } else if (this.state.notifyLevel === 'all') { - describe = 'For all activity'; + describe = (<FormattedMessage id='channel_notifications.allActivity' />); } else { - describe = 'Never'; + describe = (<FormattedMessage id='channel_notifications.never' />); } handleUpdateSection = function updateSection(e) { @@ -208,7 +248,7 @@ export default class ChannelNotificationsModal extends React.Component { return ( <SettingItemMin - title='Send desktop notifications' + title={sendDesktop} describe={describe} updateSection={handleUpdateSection} /> @@ -250,6 +290,12 @@ export default class ChannelNotificationsModal extends React.Component { createMarkUnreadLevelSection(serverError) { let content; + const markUnread = ( + <FormattedMessage + id='channel_notifications.markUnread' + defaultMessage='Mark Channel Unread' + /> + ); if (this.state.activeSection === 'markUnreadLevel') { const inputs = [( <div key='channel-notification-unread-radio'> @@ -260,7 +306,10 @@ export default class ChannelNotificationsModal extends React.Component { checked={this.state.markUnreadLevel === 'all'} onChange={this.handleUpdateMarkUnreadLevel.bind(this, 'all')} /> - {'For all unread messages'} + <FormattedMessage + id='channel_notifications.allUnread' + defaultMessage='For all unread messages' + /> </label> <br /> </div> @@ -271,7 +320,7 @@ export default class ChannelNotificationsModal extends React.Component { checked={this.state.markUnreadLevel === 'mention'} onChange={this.handleUpdateMarkUnreadLevel.bind(this, 'mention')} /> - {'Only for mentions'} + <FormattedMessage id='channel_notifications.onlyMentions' /> </label> <br /> </div> @@ -284,11 +333,18 @@ export default class ChannelNotificationsModal extends React.Component { e.preventDefault(); }.bind(this); - const extraInfo = <span>{'The channel name is bolded in the sidebar when there are unread messages. Selecting "Only for mentions" will bold the channel only when you are mentioned.'}</span>; + const extraInfo = ( + <span> + <FormattedMessage + id='channel_notifications.unreadInfo' + defaultMessage='The channel name is bolded in the sidebar when there are unread messages. Selecting "Only for mentions" will bold the channel only when you are mentioned.' + /> + </span> + ); content = ( <SettingItemMax - title='Mark Channel Unread' + title={markUnread} inputs={inputs} submit={this.handleSubmitMarkUnreadLevel} server_error={serverError} @@ -300,9 +356,14 @@ export default class ChannelNotificationsModal extends React.Component { let describe; if (!this.state.markUnreadLevel || this.state.markUnreadLevel === 'all') { - describe = 'For all unread messages'; + describe = ( + <FormattedMessage + id='channel_notifications.allUnread' + defaultMessage='For all unread messages' + /> + ); } else { - describe = 'Only for mentions'; + describe = (<FormattedMessage id='channel_notifications.onlyMentions' />); } const handleUpdateSection = function handleUpdateSection(e) { @@ -312,7 +373,7 @@ export default class ChannelNotificationsModal extends React.Component { content = ( <SettingItemMin - title='Mark Channel Unread' + title={markUnread} describe={describe} updateSection={handleUpdateSection} /> @@ -335,7 +396,13 @@ export default class ChannelNotificationsModal extends React.Component { onHide={this.props.onHide} > <Modal.Header closeButton={true}> - <Modal.Title>{'Notification Preferences for '}<span className='name'>{this.props.channel.display_name}</span></Modal.Title> + <Modal.Title> + <FormattedMessage + id='channel_notifications.preferences' + defaultMessage='Notification Preferences for ' + /> + <span className='name'>{this.props.channel.display_name}</span> + </Modal.Title> </Modal.Header> <Modal.Body> <div className='settings-table'> diff --git a/web/react/components/delete_channel_modal.jsx b/web/react/components/delete_channel_modal.jsx index 1255067fd..d9113bc9f 100644 --- a/web/react/components/delete_channel_modal.jsx +++ b/web/react/components/delete_channel_modal.jsx @@ -5,7 +5,9 @@ import * as AsyncClient from '../utils/async_client.jsx'; import * as Client from '../utils/client.jsx'; const Modal = ReactBootstrap.Modal; import TeamStore from '../stores/team_store.jsx'; -import * as Utils from '../utils/utils.jsx'; +import Constants from '../utils/constants.jsx'; + +import {FormattedMessage} from 'mm-intl'; export default class DeleteChannelModal extends React.Component { constructor(props) { @@ -32,7 +34,20 @@ export default class DeleteChannelModal extends React.Component { } render() { - const channelTerm = Utils.getChannelTerm(this.props.channel.type).toLowerCase(); + let channelTerm = ( + <FormattedMessage + id='delete_channel.channel' + defaultMessage='channel' + /> + ); + if (this.props.channel.type === Constants.PRIVATE_CHANNEL) { + channelTerm = ( + <FormattedMessage + id='delete_channel.group' + defaultMessage='group' + /> + ); + } return ( <Modal @@ -40,10 +55,22 @@ export default class DeleteChannelModal extends React.Component { onHide={this.props.onHide} > <Modal.Header closeButton={true}> - <h4 className='modal-title'>{'Confirm DELETE Channel'}</h4> + <h4 className='modal-title'> + <FormattedMessage + id='delete_channel.confirm' + defaultMessage='Confirm DELETE Channel' + /> + </h4> </Modal.Header> <Modal.Body> - {`Are you sure you wish to delete the ${this.props.channel.display_name} ${channelTerm}?`} + <FormattedMessage + id='delete_channel.question' + defaultMessage='Are you sure you wish to delete the {display_name} {term}?' + values={{ + display_name: this.props.channel.display_name, + term: (channelTerm) + }} + /> </Modal.Body> <Modal.Footer> <button @@ -51,7 +78,10 @@ export default class DeleteChannelModal extends React.Component { className='btn btn-default' onClick={this.props.onHide} > - {'Cancel'} + <FormattedMessage + id='delete_channel.cancel' + defaultMessage='Cancel' + /> </button> <button type='button' @@ -59,7 +89,10 @@ export default class DeleteChannelModal extends React.Component { data-dismiss='modal' onClick={this.handleDelete} > - {'Delete'} + <FormattedMessage + id='delete_channel.del' + defaultMessage='Delete' + /> </button> </Modal.Footer> </Modal> diff --git a/web/react/components/delete_post_modal.jsx b/web/react/components/delete_post_modal.jsx index 4cde5feed..34fd724f5 100644 --- a/web/react/components/delete_post_modal.jsx +++ b/web/react/components/delete_post_modal.jsx @@ -9,6 +9,9 @@ import * as Utils from '../utils/utils.jsx'; import * as AsyncClient from '../utils/async_client.jsx'; import AppDispatcher from '../dispatcher/app_dispatcher.jsx'; import Constants from '../utils/constants.jsx'; + +import {FormattedMessage} from 'mm-intl'; + var ActionTypes = Constants.ActionTypes; export default class DeletePostModal extends React.Component { @@ -128,10 +131,28 @@ export default class DeletePostModal extends React.Component { var commentWarning = ''; if (this.state.commentCount > 0) { - commentWarning = 'This post has ' + this.state.commentCount + ' comment(s) on it.'; + commentWarning = ( + <FormattedMessage + id='delete_post.warning' + defaultMessage='This post has {count} comment(s) on it.' + values={{ + count: this.state.commentCount + }} + /> + ); } - const postTerm = Utils.getPostTerm(this.state.post); + const postTerm = this.state.post.root_id ? ( + <FormattedMessage + id='delete_post.comment' + defaultMessage='Comment' + /> + ) : ( + <FormattedMessage + id='delete_post.post' + defaultMessage='Post' + /> + ); return ( <Modal @@ -139,10 +160,24 @@ export default class DeletePostModal extends React.Component { onHide={this.handleHide} > <Modal.Header closeButton={true}> - <Modal.Title>{`Confirm ${postTerm} Delete`}</Modal.Title> + <Modal.Title> + <FormattedMessage + id='delete_post.confirm' + defaultMessage='Confirm {term} Delete' + values={{ + term: (postTerm) + }} + /> + </Modal.Title> </Modal.Header> <Modal.Body> - {`Are you sure you want to delete this ${postTerm.toLowerCase()}?`} + <FormattedMessage + id='delete_post.question' + defaultMessage='Are you sure you want to delete this ${term}?' + values={{ + term: (postTerm) + }} + /> <br /> <br /> {commentWarning} @@ -154,7 +189,10 @@ export default class DeletePostModal extends React.Component { className='btn btn-default' onClick={this.handleHide} > - {'Cancel'} + <FormattedMessage + id='delete_post.cancel' + defaultMessage='Cancel' + /> </button> <button ref='deletePostBtn' @@ -162,7 +200,10 @@ export default class DeletePostModal extends React.Component { className='btn btn-danger' onClick={this.handleDelete} > - {'Delete'} + <FormattedMessage + id='delete_post.del' + defaultMessage='Delete' + /> </button> </Modal.Footer> </Modal> diff --git a/web/react/components/edit_channel_header_modal.jsx b/web/react/components/edit_channel_header_modal.jsx index e4817f6e4..1066d123e 100644 --- a/web/react/components/edit_channel_header_modal.jsx +++ b/web/react/components/edit_channel_header_modal.jsx @@ -6,9 +6,18 @@ import * as Client from '../utils/client.jsx'; import Constants from '../utils/constants.jsx'; import * as Utils from '../utils/utils.jsx'; +import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'mm-intl'; + const Modal = ReactBootstrap.Modal; -export default class EditChannelHeaderModal extends React.Component { +const holders = defineMessages({ + error: { + id: 'edit_channel_header_modal.error', + defaultMessage: 'This channel header is too long, please enter a shorter one' + } +}); + +class EditChannelHeaderModal extends React.Component { constructor(props) { super(props); @@ -64,8 +73,8 @@ export default class EditChannelHeaderModal extends React.Component { }); }, (err) => { - if (err.message === 'Invalid channel_header parameter') { - this.setState({serverError: 'This channel header is too long, please enter a shorter one'}); + if (err.id === 'api.context.invalid_param.app_error') { + this.setState({serverError: this.props.intl.formatMessage(holders.error)}); } else { this.setState({serverError: err.message}); } @@ -99,10 +108,23 @@ export default class EditChannelHeaderModal extends React.Component { onHide={this.onHide} > <Modal.Header closeButton={true}> - <Modal.Title>{'Edit Header for ' + this.props.channel.display_name}</Modal.Title> + <Modal.Title> + <FormattedMessage + id='edit_channel_header_modal.title' + defaultMessage='Edit Header for {channel}' + values={{ + channel: this.props.channel.display_name + }} + /> + </Modal.Title> </Modal.Header> <Modal.Body> - <p>{'Edit the text appearing next to the channel name in the channel header.'}</p> + <p> + <FormattedMessage + id='edit_channel_header_modal.description' + defaultMessage='Edit the text appearing next to the channel name in the channel header.' + /> + </p> <textarea ref='textarea' className='form-control no-resize' @@ -120,14 +142,20 @@ export default class EditChannelHeaderModal extends React.Component { className='btn btn-default' onClick={this.onHide} > - {'Cancel'} + <FormattedMessage + id='edit_channel_header_modal.cancel' + defaultMessage='Cancel' + /> </button> <button type='button' className='btn btn-primary' onClick={this.handleSubmit} > - {'Save'} + <FormattedMessage + id='edit_channel_header_modal.save' + defaultMessage='Save' + /> </button> </Modal.Footer> </Modal> @@ -136,7 +164,10 @@ export default class EditChannelHeaderModal extends React.Component { } EditChannelHeaderModal.propTypes = { + intl: intlShape.isRequired, show: React.PropTypes.bool.isRequired, onHide: React.PropTypes.func.isRequired, channel: React.PropTypes.object.isRequired }; + +export default injectIntl(EditChannelHeaderModal); diff --git a/web/react/components/edit_channel_purpose_modal.jsx b/web/react/components/edit_channel_purpose_modal.jsx index af23342ae..d8354f59d 100644 --- a/web/react/components/edit_channel_purpose_modal.jsx +++ b/web/react/components/edit_channel_purpose_modal.jsx @@ -3,10 +3,19 @@ import * as AsyncClient from '../utils/async_client.jsx'; import * as Client from '../utils/client.jsx'; -import * as Utils from '../utils/utils.jsx'; +import Constants from '../utils/constants.jsx'; + +import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'mm-intl'; const Modal = ReactBootstrap.Modal; +const holders = defineMessages({ + error: { + id: 'edit_channel_purpose_modal.error', + defaultMessage: 'This channel purpose is too long, please enter a shorter one' + } +}); + export default class EditChannelPurposeModal extends React.Component { constructor(props) { super(props); @@ -48,8 +57,8 @@ export default class EditChannelPurposeModal extends React.Component { this.handleHide(); }, (err) => { - if (err.message === 'Invalid channel_purpose parameter') { - this.setState({serverError: 'This channel purpose is too long, please enter a shorter one'}); + if (err.id === 'api.context.invalid_param.app_error') { + this.setState({serverError: this.props.intl.formatMessage(holders.error)}); } else { this.setState({serverError: err.message}); } @@ -72,9 +81,39 @@ export default class EditChannelPurposeModal extends React.Component { ); } - let title = <span>{'Edit Purpose'}</span>; + let title = ( + <span> + <FormattedMessage + id='edit_channel_purpose_modal.title1' + defaultMessage='Edit Purpose' + /> + </span> + ); if (this.props.channel.display_name) { - title = <span>{'Edit Purpose for '}<span className='name'>{this.props.channel.display_name}</span></span>; + title = ( + <span> + <FormattedMessage + id='edit_channel_purpose_modal.title2' + defaultMessage='Edit Purpose for ' + /> + <span className='name'>{this.props.channel.display_name}</span> + </span> + ); + } + + let channelType = ( + <FormattedMessage + id='edit_channel_purpose_modal.channel' + defaultMessage='Channel' + /> + ); + if (this.props.channel.type === Constants.PRIVATE_CHANNEL) { + channelType = ( + <FormattedMessage + id='edit_channel_purpose_modal.group' + defaultMessage='Group' + /> + ); } return ( @@ -90,7 +129,15 @@ export default class EditChannelPurposeModal extends React.Component { </Modal.Title> </Modal.Header> <Modal.Body> - <p>{`Describe how this ${Utils.getChannelTerm(this.props.channel.channelType)} should be used. This text appears in the channel list in the "More..." menu and helps others decide whether to join.`}</p> + <p> + <FormattedMessage + id='edit_channel_purpose_modal.body' + defaultMessage='Describe how this {type} should be used. This text appears in the channel list in the "More..." menu and helps others decide whether to join.' + values={{ + type: (channelType) + }} + /> + </p> <textarea ref='purpose' className='form-control no-resize' @@ -106,14 +153,20 @@ export default class EditChannelPurposeModal extends React.Component { className='btn btn-default' onClick={this.handleHide} > - {'Cancel'} + <FormattedMessage + id='edit_channel_purpose_modal.cancel' + defaultMessage='Cancel' + /> </button> <button type='button' className='btn btn-primary' onClick={this.handleSave} > - {'Save'} + <FormattedMessage + id='edit_channel_purpose_modal.save' + defaultMessage='Save' + /> </button> </Modal.Footer> </Modal> @@ -122,7 +175,10 @@ export default class EditChannelPurposeModal extends React.Component { } EditChannelPurposeModal.propTypes = { + intl: intlShape.isRequired, show: React.PropTypes.bool.isRequired, channel: React.PropTypes.object, onModalDismissed: React.PropTypes.func.isRequired }; + +export default injectIntl(EditChannelPurposeModal);
\ No newline at end of file diff --git a/web/react/components/edit_post_modal.jsx b/web/react/components/edit_post_modal.jsx index e4e77a943..e54b7d9b8 100644 --- a/web/react/components/edit_post_modal.jsx +++ b/web/react/components/edit_post_modal.jsx @@ -10,9 +10,19 @@ import PostStore from '../stores/post_store.jsx'; import PreferenceStore from '../stores/preference_store.jsx'; import Constants from '../utils/constants.jsx'; + +import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'mm-intl'; + var KeyCodes = Constants.KeyCodes; -export default class EditPostModal extends React.Component { +const holders = defineMessages({ + editPost: { + id: 'edit_post.editPost', + defaultMessage: 'Edit the post...' + } +}); + +class EditPostModal extends React.Component { constructor() { super(); @@ -151,7 +161,15 @@ export default class EditPostModal extends React.Component { > <span aria-hidden='true'>×</span> </button> - <h4 className='modal-title'>Edit {this.state.title}</h4> + <h4 className='modal-title'> + <FormattedMessage + id='edit_post.edit' + defaultMessage='Edit {title}' + values={{ + title: this.state.title + }} + /> + </h4> </div> <div className='edit-modal-body modal-body'> <Textbox @@ -159,7 +177,7 @@ export default class EditPostModal extends React.Component { onKeyPress={this.handleEditKeyPress} onKeyDown={this.handleKeyDown} messageText={this.state.editText} - createMessage='Edit the post...' + createMessage={this.props.intl.formatMessage(holders.editPost)} supportsCommands={false} id='edit_textbox' ref='editbox' @@ -172,14 +190,20 @@ export default class EditPostModal extends React.Component { className='btn btn-default' data-dismiss='modal' > - Cancel + <FormattedMessage + id='edit_post.cancel' + defaultMessage='Cancel' + /> </button> <button type='button' className='btn btn-primary' onClick={this.handleEdit} > - Save + <FormattedMessage + id='edit_post.save' + defaultMessage='Save' + /> </button> </div> </div> @@ -188,3 +212,9 @@ export default class EditPostModal extends React.Component { ); } } + +EditPostModal.propTypes = { + intl: intlShape.isRequired +}; + +export default injectIntl(EditPostModal);
\ No newline at end of file diff --git a/web/react/components/member_list_item.jsx b/web/react/components/member_list_item.jsx index a7273f280..c50ee5c96 100644 --- a/web/react/components/member_list_item.jsx +++ b/web/react/components/member_list_item.jsx @@ -4,6 +4,8 @@ import UserStore from '../stores/user_store.jsx'; import * as Utils from '../utils/utils.jsx'; +import {FormattedMessage} from 'mm-intl'; + export default class MemberListItem extends React.Component { constructor(props) { super(props); @@ -38,7 +40,10 @@ export default class MemberListItem extends React.Component { className='btn btn-sm btn-primary' > <i className='glyphicon glyphicon-envelope'/> - {' Add'} + <FormattedMessage + id='member_item.add' + defaultMessage=' Add' + /> </a> ); } else if (isAdmin && !isMemberAdmin && (member.id !== UserStore.getCurrentId())) { @@ -53,7 +58,10 @@ export default class MemberListItem extends React.Component { role='menuitem' onClick={self.handleMakeAdmin} > - Make Admin + <FormattedMessage + id='member_item.makeAdmin' + defaultMessage='Make Admin' + /> </a> </li>); } @@ -67,7 +75,10 @@ export default class MemberListItem extends React.Component { role='menuitem' onClick={self.handleRemove} > - Remove Member + <FormattedMessage + id='member_item.removeMember' + defaultMessage='Remove Member' + /> </a> </li>); } @@ -82,7 +93,14 @@ export default class MemberListItem extends React.Component { aria-expanded='true' > <span className='fa fa-pencil'></span> - <span className='text-capitalize'>{member.roles || 'Member'} </span> + <span className='text-capitalize'> + {member.roles || + <FormattedMessage + id='member_item.member' + defaultMessage='Member' + /> + } + </span> </a> <ul className='dropdown-menu member-menu' @@ -94,7 +112,7 @@ export default class MemberListItem extends React.Component { </div> ); } else { - invite = <div className='member-role text-capitalize'><span className='fa fa-pencil hidden'></span>{member.roles || 'Member'}</div>; + invite = (<div className='member-role text-capitalize'><span className='fa fa-pencil hidden'></span>{member.roles || <FormattedMessage id='member_item.member' />}</div>); } return ( diff --git a/web/react/components/msg_typing.jsx b/web/react/components/msg_typing.jsx index b95b06260..f7a40b54e 100644 --- a/web/react/components/msg_typing.jsx +++ b/web/react/components/msg_typing.jsx @@ -106,9 +106,9 @@ class MsgTyping extends React.Component { <FormattedMessage id='msg_typing.areTyping' defaultMessage='{users} and {last} are typing...' - vaues={{ - users: users.join(', '), - last: last + values={{ + users: (users.join(', ')), + last: (last) }} /> ); diff --git a/web/react/components/popover_list_members.jsx b/web/react/components/popover_list_members.jsx index f4cb542e4..f217229ed 100644 --- a/web/react/components/popover_list_members.jsx +++ b/web/react/components/popover_list_members.jsx @@ -9,6 +9,8 @@ import Constants from '../utils/constants.jsx'; import ChannelStore from '../stores/channel_store.jsx'; +import {FormattedMessage} from 'mm-intl'; + export default class PopoverListMembers extends React.Component { constructor(props) { super(props); @@ -92,7 +94,10 @@ export default class PopoverListMembers extends React.Component { className='btn-message' onClick={(e) => this.handleShowDirectChannel(m, e)} > - {'Message'} + <FormattedMessage + id='members_popover.msg' + defaultMessage='Message' + /> </a> ); } @@ -147,6 +152,12 @@ export default class PopoverListMembers extends React.Component { countText = count.toString(); } + const title = ( + <FormattedMessage + id='members_popover.title' + defaultMessage='Members' + /> + ); return ( <div> <div @@ -171,7 +182,7 @@ export default class PopoverListMembers extends React.Component { > <Popover ref='memebersPopover' - title='Members' + title={title} id='member-list-popover' > {popoverHtml} diff --git a/web/react/components/post_deleted_modal.jsx b/web/react/components/post_deleted_modal.jsx index 3723bcaba..218f57eb5 100644 --- a/web/react/components/post_deleted_modal.jsx +++ b/web/react/components/post_deleted_modal.jsx @@ -4,6 +4,9 @@ import UserStore from '../stores/user_store.jsx'; import AppDispatcher from '../dispatcher/app_dispatcher.jsx'; import Constants from '../utils/constants.jsx'; + +import {FormattedMessage} from 'mm-intl'; + var ActionTypes = Constants.ActionTypes; export default class PostDeletedModal extends React.Component { @@ -65,11 +68,19 @@ export default class PostDeletedModal extends React.Component { className='modal-title' id='myModalLabel' > - {'Comment could not be posted'} + <FormattedMessage + id='post_delete.notPosted' + defaultMessage='Comment could not be posted' + /> </h4> </div> <div className='modal-body'> - <p>{'Someone deleted the message on which you tried to post a comment.'}</p> + <p> + <FormattedMessage + id='post_delete.someone' + defaultMessage='Someone deleted the message on which you tried to post a comment.' + /> + </p> </div> <div className='modal-footer'> <button @@ -77,7 +88,10 @@ export default class PostDeletedModal extends React.Component { className='btn btn-primary' data-dismiss='modal' > - {'Okay'} + <FormattedMessage + id='post_delete.okay' + defaultMessage='Okay' + /> </button> </div> </div> diff --git a/web/react/components/removed_from_channel_modal.jsx b/web/react/components/removed_from_channel_modal.jsx index 69d038c22..748baa32b 100644 --- a/web/react/components/removed_from_channel_modal.jsx +++ b/web/react/components/removed_from_channel_modal.jsx @@ -6,6 +6,8 @@ import UserStore from '../stores/user_store.jsx'; import BrowserStore from '../stores/browser_store.jsx'; import * as utils from '../utils/utils.jsx'; +import {FormattedMessage} from 'mm-intl'; + export default class RemovedFromChannelModal extends React.Component { constructor(props) { super(props); @@ -49,12 +51,22 @@ export default class RemovedFromChannelModal extends React.Component { render() { var currentUser = UserStore.getCurrentUser(); - var channelName = 'the channel'; + var channelName = ( + <FormattedMessage + id='removed_channel.channelName' + defaultMessage='the channel' + /> + ); if (this.state.channelName) { channelName = this.state.channelName; } - var remover = 'Someone'; + var remover = ( + <FormattedMessage + id='removed_channel.someone' + defaultMessage='Someone' + /> + ); if (this.state.remover) { remover = this.state.remover; } @@ -78,17 +90,36 @@ export default class RemovedFromChannelModal extends React.Component { data-dismiss='modal' aria-label='Close' ><span aria-hidden='true'>×</span></button> - <h4 className='modal-title'>Removed from <span className='name'>{channelName}</span></h4> + <h4 className='modal-title'> + <FormattedMessage + id='removed_channel.from' + defaultMessage='Removed from ' + /> + <span className='name'>{channelName}</span></h4> </div> <div className='modal-body'> - <p>{remover} removed you from {channelName}</p> + <p> + <FormattedMessage + id='removed_channel.remover' + defaultMessage='{remover} removed you from {channel}' + values={{ + remover: (remover), + channel: (channelName) + }} + /> + </p> </div> <div className='modal-footer'> <button type='button' className='btn btn-primary' data-dismiss='modal' - >Okay</button> + > + <FormattedMessage + id='removed_channel.okay' + defaultMessage='Okay' + /> + </button> </div> </div> </div> diff --git a/web/react/components/rename_channel_modal.jsx b/web/react/components/rename_channel_modal.jsx index c16216c68..c467c0d87 100644 --- a/web/react/components/rename_channel_modal.jsx +++ b/web/react/components/rename_channel_modal.jsx @@ -7,6 +7,39 @@ import * as AsyncClient from '../utils/async_client.jsx'; import ChannelStore from '../stores/channel_store.jsx'; import Constants from '../utils/constants.jsx'; +import {intlShape, injectIntl, defineMessages, FormattedMessage} from 'mm-intl'; + +const holders = defineMessages({ + required: { + id: 'rename_channel.required', + defaultMessage: 'This field is required' + }, + maxLength: { + id: 'rename_channel.maxLength', + defaultMessage: 'This field must be less than 22 characters' + }, + lowercase: { + id: 'rename_channel.lowercase', + defaultMessage: 'Must be lowercase alphanumeric characters' + }, + handle: { + id: 'rename_channel.handle', + defaultMessage: 'Handle' + }, + defaultError: { + id: 'rename_channel.defaultError', + defaultMessage: ' - Cannot be changed for the default channel' + }, + displayNameHolder: { + id: 'rename_channel.displayNameHolder', + defaultMessage: 'Enter display name' + }, + handleHolder: { + id: 'rename_channel.handleHolder', + defaultMessage: 'lowercase alphanumeric's only' + } +}); + export default class RenameChannelModal extends React.Component { constructor(props) { super(props); @@ -41,13 +74,14 @@ export default class RenameChannelModal extends React.Component { const oldName = channel.name; const oldDisplayName = channel.displayName; const state = {serverError: ''}; + const {formatMessage} = this.props.intl; channel.display_name = this.state.displayName.trim(); if (!channel.display_name) { - state.displayNameError = 'This field is required'; + state.displayNameError = formatMessage(holders.required); state.invalid = true; } else if (channel.display_name.length > 22) { - state.displayNameError = 'This field must be less than 22 characters'; + state.displayNameError = formatMessage(holders.maxLength); state.invalid = true; } else { state.displayNameError = ''; @@ -55,17 +89,17 @@ export default class RenameChannelModal extends React.Component { channel.name = this.state.channelName.trim(); if (!channel.name) { - state.nameError = 'This field is required'; + state.nameError = formatMessage(holders.required); state.invalid = true; } else if (channel.name.length > 22) { - state.nameError = 'This field must be less than 22 characters'; + state.nameError = formatMessage(holders.maxLength); state.invalid = true; } else { const cleanedName = Utils.cleanUpUrlable(channel.name); if (cleanedName === channel.name) { state.nameError = ''; } else { - state.nameError = 'Must be lowercase alphanumeric characters'; + state.nameError = formatMessage(holders.lowercase); state.invalid = true; } } @@ -153,11 +187,13 @@ export default class RenameChannelModal extends React.Component { serverError = <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div>; } - let handleInputLabel = 'Handle'; + const {formatMessage} = this.props.intl; + + let handleInputLabel = formatMessage(holders.handle); let handleInputClass = 'form-control'; let readOnlyHandleInput = false; if (this.state.channelName === Constants.DEFAULT_CHANNEL) { - handleInputLabel += ' - Cannot be changed for the default channel'; + handleInputLabel += formatMessage(holders.defaultError); handleInputClass += ' disabled-input'; readOnlyHandleInput = true; } @@ -180,14 +216,29 @@ export default class RenameChannelModal extends React.Component { data-dismiss='modal' > <span aria-hidden='true'>{'×'}</span> - <span className='sr-only'>{'Close'}</span> + <span className='sr-only'> + <FormattedMessage + id='rename_channel.close' + defaultMessage='Close' + /> + </span> </button> - <h4 className='modal-title'>{'Rename Channel'}</h4> + <h4 className='modal-title'> + <FormattedMessage + id='rename_channel.title' + defaultMessage='Rename Channel' + /> + </h4> </div> <form role='form'> <div className='modal-body'> <div className={displayNameClass}> - <label className='control-label'>{'Display Name'}</label> + <label className='control-label'> + <FormattedMessage + id='rename_channel.displayName' + defaultMessage='Display Name' + /> + </label> <input onKeyUp={this.displayNameKeyUp} onChange={this.onDisplayNameChange} @@ -195,7 +246,7 @@ export default class RenameChannelModal extends React.Component { ref='displayName' id='display_name' className='form-control' - placeholder='Enter display name' + placeholder={formatMessage(holders.displayNameHolder)} value={this.state.displayName} maxLength='64' /> @@ -208,7 +259,7 @@ export default class RenameChannelModal extends React.Component { type='text' className={handleInputClass} ref='channelName' - placeholder='lowercase alphanumeric's only' + placeholder={formatMessage(holders.handleHolder)} value={this.state.channelName} maxLength='64' readOnly={readOnlyHandleInput} @@ -223,14 +274,20 @@ export default class RenameChannelModal extends React.Component { className='btn btn-default' data-dismiss='modal' > - {'Cancel'} + <FormattedMessage + id='rename_channel.cancel' + defaultMessage='Cancel' + /> </button> <button onClick={this.handleSubmit} type='submit' className='btn btn-primary' > - {'Save'} + <FormattedMessage + id='rename_channel.save' + defaultMessage='Save' + /> </button> </div> </form> @@ -240,3 +297,9 @@ export default class RenameChannelModal extends React.Component { ); } } + +RenameChannelModal.propTypes = { + intl: intlShape.isRequired +}; + +export default injectIntl(RenameChannelModal);
\ No newline at end of file diff --git a/web/react/components/setting_item_max.jsx b/web/react/components/setting_item_max.jsx index 52f1906c3..537055641 100644 --- a/web/react/components/setting_item_max.jsx +++ b/web/react/components/setting_item_max.jsx @@ -85,6 +85,6 @@ SettingItemMax.propTypes = { extraInfo: React.PropTypes.element, updateSection: React.PropTypes.func, submit: React.PropTypes.func, - title: React.PropTypes.string, + title: React.PropTypes.node, width: React.PropTypes.string }; diff --git a/web/react/components/setting_item_min.jsx b/web/react/components/setting_item_min.jsx index db5513b14..868b7e1b2 100644 --- a/web/react/components/setting_item_min.jsx +++ b/web/react/components/setting_item_min.jsx @@ -38,8 +38,8 @@ export default class SettingItemMin extends React.Component { } SettingItemMin.propTypes = { - title: React.PropTypes.string, + title: React.PropTypes.node, disableOpen: React.PropTypes.bool, updateSection: React.PropTypes.func, - describe: React.PropTypes.string + describe: React.PropTypes.node }; diff --git a/web/static/i18n/en.json b/web/static/i18n/en.json index d6401ab6e..52b8fc5e4 100644 --- a/web/static/i18n/en.json +++ b/web/static/i18n/en.json @@ -480,6 +480,40 @@ "change_url.noUnderscore": "Can not contain two underscores in a row.", "change_url.invalidUrl": "Invalid URL", "change_url.close": "Close", + "channel_header.recentMentions": "Recent Mentions", + "channel_header.channel": "Channel", + "channel_header.group": "Group", + "channel_header.channelHeader": "Set Channel Header...", + "channel_header.viewInfo": "View Info", + "chanel_header.addMembers": "Add Members", + "channel_header.manageMembers": "Manage Members", + "channel_header.setHeader": "Set {term} Header...", + "channel_header.setPurpose": "Set {term} Purpose...", + "channel_header.notificationPreferences": "Notification Preferences", + "channel_header.rename": "Rename {term}...", + "channel_header.delete": "Delete {term}...", + "channel_header.leave": "Leave {term}", + "channel_info.notFound": "No Channel Found", + "channel_info.name": "Channel Name:", + "channel_info.url": "Channel URL:", + "channel_info.id": "Channel ID:", + "channel_info.purpose": "Channel Purpose:", + "channel_info.close": "Close", + "channel_invite.addNewMembers": "Add New Members to ", + "channel_invite.close": "Close", + "channel_memebers_modal.members": " Members", + "channel_members_modal.addNew": " Add New Members", + "channel_members_modal.close": "Close", + "channel_notifications.allActivity": "For all activity", + "channel_notifications.onlyMentions": "Only for mentions", + "channel_notifications.never": "Never", + "channel_notifications.sendDesktop": "Send desktop notifications", + "channel_notifications.globalDefault": "Global default ({notifyLevel}", + "channel_notifications.override": "Selecting an option other than \"Default\" will override the global notification settings. Desktop notifications are available on Firefox, Safari, and Chrome.", + "channel_notifications.markUnread": "Mark Channel Unread", + "channel_notifications.allUnread": "For all unread messages", + "channel_notifications.unreadInfo": "The channel name is bolded in the sidebar when there are unread messages. Selecting \"Only for mentions\" will bold the channel only when you are mentioned.", + "channel_notifications.preferences": "Notification Preferences for ", "claim.account.noEmail": "No email specified", "claim.email_to_sso.pwdError": "Please enter your password.", "claim.email_to_sso.pwd": "Password", @@ -502,6 +536,36 @@ "create_comment.commentTitle": "Comment", "create_comment.file": "File uploading", "create_comment.files": "Files uploading", + "delete_channel.channel": "channel", + "delete_channel.group": "group", + "delete_channel.confirm": "Confirm DELETE Channel", + "delete_channel.question": "Are you sure you wish to delete the {display_name} {term}?", + "delete_channel.cancel": "Cancel", + "delete_channel.del": "Delete", + "delete_post.warning": "This post has {count} comment(s) on it.", + "delete_post.comment": "Comment", + "delete_post.post": "Post", + "delete_post.confirm": "Confirm {term} Delete", + "delete_post.question": "Are you sure you want to delete this ${term}?", + "delete_post.cancel": "Cancel", + "delete_post.del": "Delete", + "edit_channel_header_modal.error": "This channel header is too long, please enter a shorter one", + "edit_channel_header_modal.title": "Edit Header for {channel}", + "edit_channel_header_modal.description": "Edit the text appearing next to the channel name in the channel header.", + "edit_channel_header_modal.cancel": "Cancel", + "edit_channel_header_modal.save": "Save", + "edit_channel_purpose_modal.error": "This channel purpose is too long, please enter a shorter one", + "edit_channel_purpose_modal.title1": "Edit Purpose", + "edit_channel_purpose_modal.title2": "Edit Purpose for ", + "edit_channel_purpose_modal.channel": "Channel", + "edit_channel_purpose_modal.group": "Group", + "edit_channel_purpose_modal.body": "Describe how this {type} should be used. This text appears in the channel list in the \"More...\" menu and helps others decide whether to join.", + "edit_channel_purpose_modal.cancel": "Cancel", + "edit_channel_purpose_modal.save": "Save", + "edit_post.editPost": "Edit the post...", + "edit_post.edit": "Edit {title}", + "edit_post.cancel": "Cancel", + "edit_post.save": "Save", "email_verify.verified": "{siteName} Email Verified", "email_verify.verifiedBody": "<p>Your email has been verified! Click <a href={url}>here</a> to log in.</p>", "email_verify.almost": "{siteName}: You are almost done", @@ -568,6 +632,10 @@ "login.find": "Find your other teams", "login.signTo": "Sign in to:", "login.on": "on {siteName}", + "member_item.add": " Add", + "member_item.makeAdmin": "Make Admin", + "member_item.removeMember": "Remove Member", + "member_item.member": "Member", "member_team_item.member": "Member", "member_team_item.systemAdmin": "System Admin", "member_team_item.teamAdmin": "Team Admin", @@ -643,6 +711,11 @@ "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", + "members_popover.msg": "Message", + "members_popover.title": "Members", + "post_delete.notPosted": "Comment could not be posted", + "post_delete.someone": "Someone deleted the message on which you tried to post a comment.", + "post_delete.okay": "Okay", "register_app.required": "Required", "register_app.optional": "Optional", "register_app.nameError": "Application name must be filled in.", @@ -662,6 +735,23 @@ "register_app.credentialsSave": "I have saved both my Client Id and Client Secret somewhere safe", "register_app.close": "Close", "register_app.dev": "Developer Applications", + "removed_channel.channelName": "the channel", + "removed_channel.someone": "Someone", + "removed_channel.from": "Removed from ", + "removed_channel.remover": "{remover} removed you from {channel}", + "removed_channel.okay": "Okay", + "rename_channel.required": "This field is required", + "rename_channel.maxLength": "This field must be less than 22 characters", + "rename_channel.lowercase": "Must be lowercase alphanumeric characters", + "rename_channel.handle": "Handle", + "rename_channel.defaultError": " - Cannot be changed for the default channel", + "rename_channel.displayNameHolder": "Enter display name", + "rename_channel.handleHolder": "lowercase alphanumeric's only", + "rename_channel.close": "Close", + "rename_channel.title": "Rename Channel", + "rename_channel.displayName": "Display Name", + "rename_channel.cancel": "Cancel", + "rename_channel.save": "Save", "rhs_comment.comment": "Comment", "rhs_comment.edit": "Edit", "rhs_comment.del": "Delete", diff --git a/web/static/i18n/es.json b/web/static/i18n/es.json index cb3e8a199..74b5666c4 100644 --- a/web/static/i18n/es.json +++ b/web/static/i18n/es.json @@ -474,6 +474,7 @@ "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}", + "chanel_header.addMembers": "Agregar Miembros", "change_url.close": "Cerrar", "change_url.endWithLetter": "Debe terminar con una letra o número", "change_url.invalidUrl": "URL Inválida", @@ -488,6 +489,29 @@ "channel_flow.group": "Grupo", "channel_flow.invalidName": "Nombre de Canal Inválido", "channel_flow.set_url_title": "Asignar URL de {term}", + "channel_header.channel": "Canal", + "channel_header.channelHeader": "Encabezado del Canal...", + "channel_header.delete": "Eliminar {term}...", + "channel_header.group": "Grupo", + "channel_header.leave": "Abondanar {term}", + "channel_header.manageMembers": "Administrar Miembros", + "channel_header.notificationPreferences": "Preferencias de Notificación", + "channel_header.recentMentions": "Menciones recientes", + "channel_header.rename": "Renombrar {term}...", + "channel_header.setHeader": "Encabezado del {term}...", + "channel_header.setPurpose": "Propósito del {term}...", + "channel_header.viewInfo": "Ver Info", + "channel_info.close": "Cerrar", + "channel_info.id": "ID del Canal:", + "channel_info.name": "Nombre del Canal:", + "channel_info.notFound": "Canal no encontrado", + "channel_info.purpose": "Propósito del Canal:", + "channel_info.url": "URL del Canal:", + "channel_invite.addNewMembers": "Agregar nuevos Miembros a ", + "channel_invite.close": "Cerrar", + "channel_members_modal.addNew": " Agregar nuevos Miembros", + "channel_members_modal.close": "Cerrar", + "channel_memebers_modal.members": " Miembros", "channel_modal.cancel": "Cancelar", "channel_modal.channel": "Canal", "channel_modal.createNew": "Crear Nuevo ", @@ -504,6 +528,16 @@ "channel_modal.publicChannel1": "Crear un canal público", "channel_modal.publicChannel2": "Crear un canal público al que cualquiera puede unirse. ", "channel_modal.purpose": "Propósito", + "channel_notifications.allActivity": "Para toda actividad", + "channel_notifications.allUnread": "Para todos los mensajes sin leer", + "channel_notifications.globalDefault": "Predeterminado global ({notifyLevel})", + "channel_notifications.markUnread": "Marcar Canal como No Leido", + "channel_notifications.never": "Nunca", + "channel_notifications.onlyMentions": "Sólo para menciones", + "channel_notifications.override": "Seleccionar una opción diferente a \"Predeterminada\" anulará las configuraciones globales de notificación. Las notificaciones de Escritorio están disponibles para Firefox, Safari, y Chrome.", + "channel_notifications.preferences": "Preferencias de Notificación de ", + "channel_notifications.sendDesktop": "Enviar notificaciones de escritorio", + "channel_notifications.unreadInfo": "El nombre del canal está en negritas en la barra lateral cuando hay mensajes sin leer. Al elegir \"Sólo para menciones\" sólo lo dejará en negritas cuando seas mencionado.", "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", @@ -531,6 +565,36 @@ "create_comment.commentTitle": "Comentario", "create_comment.file": "Subiendo archivo", "create_comment.files": "Subiendo archivos", + "delete_channel.cancel": "Cancelar", + "delete_channel.channel": "canal", + "delete_channel.confirm": "Confirmar la ELIMINACIÓN del Canal", + "delete_channel.del": "Eliminar", + "delete_channel.group": "grupo", + "delete_channel.question": "¿Estás seguro de querer eliminar el {term} {display_name}?", + "delete_post.cancel": "Cancelar", + "delete_post.comment": "Comentario", + "delete_post.confirm": "Confirmar Eliminación del {term}", + "delete_post.del": "Eliminar", + "delete_post.post": "Mensaje", + "delete_post.question": "¿Estás seguro(a) de querer eliminar este {term}?", + "delete_post.warning": "Este mensaje tiene {count} comentario(s).", + "edit_channel_header_modal.cancel": "Cancelar", + "edit_channel_header_modal.description": "Edita el texto que aparece al lado del nombre del canal en el encabezado del canal.", + "edit_channel_header_modal.error": "Este encabezado es demasiado largo, por favor ingresa uno más corto", + "edit_channel_header_modal.save": "Guardar", + "edit_channel_header_modal.title": "Edita el Encabezado de {channel}", + "edit_channel_purpose_modal.body": "Describe como este {type} debería ser usado. Este texto aparace en la lista de canales dentro del menú de \"Más...\" y ayuda a otros en decidir si unirse.", + "edit_channel_purpose_modal.cancel": "Cancelar", + "edit_channel_purpose_modal.channel": "Canal", + "edit_channel_purpose_modal.error": "El propósito de este canal es muy largo, por favor ingresa uno más corto", + "edit_channel_purpose_modal.group": "Grupo", + "edit_channel_purpose_modal.save": "Guardar", + "edit_channel_purpose_modal.title1": "Editar Propósito", + "edit_channel_purpose_modal.title2": "Editar el Propósito de ", + "edit_post.cancel": "Cancelar", + "edit_post.edit": "Editar {title}", + "edit_post.editPost": "Editar el mensaje...", + "edit_post.save": "Guardar", "email_signup.address": "Correo electrónico", "email_signup.createTeam": "Crear Equipo", "email_signup.emailError": "Por favor ingresa una dirección de correos válida", @@ -619,6 +683,10 @@ "login_ldap.pwdReq": "La contraseña LDAP es obligatoria", "login_ldap.signin": "Entrar", "login_ldap.username": "Usuario LDAP", + "member_item.add": " Agregar", + "member_item.makeAdmin": "Convertir en Admin de Equipo", + "member_item.member": "Miembro", + "member_item.removeMember": "Elminar Miembro", "member_team_item.inactive": "Inactivo", "member_team_item.makeActive": "Activar", "member_team_item.makeAdmin": "Convertir a Admin de Equipo", @@ -627,6 +695,8 @@ "member_team_item.member": "Miembro", "member_team_item.systemAdmin": "Administrador de Sistema", "member_team_item.teamAdmin": "Admin de Equipo", + "members_popover.msg": "Mensaje", + "members_popover.title": "Miembros", "more_channels.close": "Cerrar", "more_channels.create": "Crear Nuevo Canal", "more_channels.createClick": "Pincha 'Crear Nuevo Canal' para crear uno nuevo", @@ -670,6 +740,9 @@ "password_send.link": "<p>Se ha enviado un enlace para restablecer la contraseña a <b>{email}</b> para tu equipo <b>{teamDisplayName}</b> en {hostname}.</p>", "password_send.reset": "Restablecer mi contraseña", "password_send.title": "Restablecer Contraseña", + "post_delete.notPosted": "No se pudo enviar el comentario", + "post_delete.okay": "Ok", + "post_delete.someone": "Alguien borró el mensaje que querías comentar.", "register_app.callback": "Callback URL", "register_app.callbackError": "Al menos un callback URL debe ser ingresado.", "register_app.cancel": "Cancelar", @@ -689,6 +762,23 @@ "register_app.register": "Registrar", "register_app.required": "Requerido", "register_app.title": "Registra una Nueva Aplicación", + "removed_channel.channelName": "el canal", + "removed_channel.from": "Removido de ", + "removed_channel.okay": "OK", + "removed_channel.remover": "{remover} te removió de {channel}", + "removed_channel.someone": "Alguien", + "rename_channel.cancel": "Cancelar", + "rename_channel.close": "Cerrado", + "rename_channel.defaultError": " - No se puede cambiar el del canal predeterminado", + "rename_channel.displayName": "Nombre a Mostrar", + "rename_channel.displayNameHolder": "Ingresa el nombre a mostrar", + "rename_channel.handle": "Identificador", + "rename_channel.handleHolder": "Sólo caracteres alfanumericos y en minúscula", + "rename_channel.lowercase": "Debe tener caracteres alfanumericos y minúscula", + "rename_channel.maxLength": "Este campo debe tener menos de 22 caracteres", + "rename_channel.required": "Este campo es obligatorio", + "rename_channel.save": "Guardar", + "rename_channel.title": "Renombrar Canal", "rhs_comment.comment": "Comentario", "rhs_comment.del": "Borrar", "rhs_comment.edit": "Editar", |