From d424c9eaf12653332f15afa2cb9dfc6684fa95d8 Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Tue, 2 Feb 2016 19:39:56 -0300 Subject: PLT-7: Refactoring frontend (chunk 10) - Modals - Fix bug on msg_typing - Add missing translations in es.json for EE --- web/react/components/channel_header.jsx | 94 ++++++++++++++--- web/react/components/channel_info_modal.jsx | 57 +++++++++-- web/react/components/channel_invite_modal.jsx | 15 ++- web/react/components/channel_members_modal.jsx | 21 +++- .../components/channel_notifications_modal.jsx | 111 +++++++++++++++++---- web/react/components/delete_channel_modal.jsx | 45 +++++++-- web/react/components/delete_post_modal.jsx | 53 ++++++++-- web/react/components/edit_channel_header_modal.jsx | 45 +++++++-- .../components/edit_channel_purpose_modal.jsx | 72 +++++++++++-- web/react/components/edit_post_modal.jsx | 40 +++++++- web/react/components/member_list_item.jsx | 28 +++++- web/react/components/msg_typing.jsx | 6 +- web/react/components/popover_list_members.jsx | 15 ++- web/react/components/post_deleted_modal.jsx | 20 +++- .../components/removed_from_channel_modal.jsx | 41 +++++++- web/react/components/rename_channel_modal.jsx | 91 ++++++++++++++--- web/react/components/setting_item_max.jsx | 2 +- web/react/components/setting_item_min.jsx | 4 +- web/static/i18n/en.json | 90 +++++++++++++++++ web/static/i18n/es.json | 90 +++++++++++++++++ 20 files changed, 821 insertions(+), 119 deletions(-) (limited to 'web') 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 = {'Recent Mentions'}; + const recentMentionsTooltip = ( + + + + ); const popoverContent = ( + ); + if (channel.type === Constants.PRIVATE_CHANNEL) { + channelTerm = ( + + ); } const dropdownContents = []; @@ -174,7 +193,10 @@ export default class ChannelHeader extends React.Component { dialogType={EditChannelHeaderModal} dialogProps={{channel}} > - {'Set Channel Header...'} + ); @@ -189,7 +211,10 @@ export default class ChannelHeader extends React.Component { dialogType={ChannelInfoModal} dialogProps={{channel}} > - {'View Info'} + ); @@ -205,7 +230,10 @@ export default class ChannelHeader extends React.Component { dialogType={ChannelInviteModal} dialogProps={{channel}} > - {'Add Members'} + ); @@ -221,7 +249,10 @@ export default class ChannelHeader extends React.Component { href='#' onClick={() => this.setState({showMembersModal: true})} > - {'Manage Members'} + ); @@ -238,7 +269,13 @@ export default class ChannelHeader extends React.Component { dialogType={EditChannelHeaderModal} dialogProps={{channel}} > - {`Set ${channelTerm} Header...`} + ); @@ -252,7 +289,13 @@ export default class ChannelHeader extends React.Component { href='#' onClick={() => this.setState({showEditChannelPurposeModal: true})} > - {'Set '}{channelTerm}{' Purpose...'} + ); @@ -266,7 +309,10 @@ export default class ChannelHeader extends React.Component { dialogType={ChannelNotificationsModal} dialogProps={{channel}} > - {'Notification Preferences'} + ); @@ -286,7 +332,13 @@ export default class ChannelHeader extends React.Component { data-name={channel.name} data-channelid={channel.id} > - {'Rename '}{channelTerm}{'...'} + ); @@ -302,7 +354,13 @@ export default class ChannelHeader extends React.Component { dialogType={DeleteChannelModal} dialogProps={{channel}} > - {'Delete '}{channelTerm}{'...'} + ); @@ -320,7 +378,13 @@ export default class ChannelHeader extends React.Component { href='#' onClick={this.handleLeave} > - {'Leave '}{channelTerm} + ); 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 {
-
{'Channel Name:'}
+
+ +
{channel.display_name}
-
{'Channel URL:'}
+
+ +
{channelURL}
-
{'Channel ID:'}
+
+ +
{channel.id}
-
{'Channel Purpose:'}
+
+ +
{channel.purpose}
@@ -50,7 +81,10 @@ export default class ChannelInfoModal extends React.Component { className='btn btn-default' onClick={this.props.onHide} > - {'Close'} + @@ -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} > - {'Add New Members to '}{this.props.channel.display_name} + + + {this.props.channel.display_name} + - {'Close'} + 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} > - {this.props.channel.display_name}{' Members'} + + {this.props.channel.display_name} + + - {' Add New Members'} + + - {'Close'} + 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 = ( + + ); } else if (globalNotifyLevel === 'mention') { - globalNotifyLevelName = 'Only for mentions'; + globalNotifyLevelName = ( + + ); } else { - globalNotifyLevelName = 'Never'; + globalNotifyLevelName = ( + + ); } + const sendDesktop = ( + + ); + 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})`} +
@@ -138,7 +168,7 @@ export default class ChannelNotificationsModal extends React.Component { checked={notifyActive[1]} onChange={this.handleUpdateNotifyLevel.bind(this, 'all')} /> - {'For all activity'} +
@@ -149,7 +179,7 @@ export default class ChannelNotificationsModal extends React.Component { checked={notifyActive[2]} onChange={this.handleUpdateNotifyLevel.bind(this, 'mention')} /> - {'Only for mentions'} +
@@ -160,7 +190,7 @@ export default class ChannelNotificationsModal extends React.Component { checked={notifyActive[3]} onChange={this.handleUpdateNotifyLevel.bind(this, 'none')} /> - {'Never'} + @@ -174,13 +204,16 @@ export default class ChannelNotificationsModal extends React.Component { const extraInfo = ( - {'Selecting an option other than "Default" will override the global notification settings. Desktop notifications are available on Firefox, Safari, and Chrome.'} + ); return ( + ); } else if (this.state.notifyLevel === 'mention') { - describe = 'Only for mentions'; + describe = (); } else if (this.state.notifyLevel === 'all') { - describe = 'For all activity'; + describe = (); } else { - describe = 'Never'; + describe = (); } handleUpdateSection = function updateSection(e) { @@ -208,7 +248,7 @@ export default class ChannelNotificationsModal extends React.Component { return ( @@ -250,6 +290,12 @@ export default class ChannelNotificationsModal extends React.Component { createMarkUnreadLevelSection(serverError) { let content; + const markUnread = ( + + ); if (this.state.activeSection === 'markUnreadLevel') { const inputs = [(
@@ -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'} +
@@ -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'} +
@@ -284,11 +333,18 @@ export default class ChannelNotificationsModal extends React.Component { e.preventDefault(); }.bind(this); - const extraInfo = {'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.'}; + const extraInfo = ( + + + + ); content = ( + ); } else { - describe = 'Only for mentions'; + describe = (); } const handleUpdateSection = function handleUpdateSection(e) { @@ -312,7 +373,7 @@ export default class ChannelNotificationsModal extends React.Component { content = ( @@ -335,7 +396,13 @@ export default class ChannelNotificationsModal extends React.Component { onHide={this.props.onHide} > - {'Notification Preferences for '}{this.props.channel.display_name} + + + {this.props.channel.display_name} +
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 = ( + + ); + if (this.props.channel.type === Constants.PRIVATE_CHANNEL) { + channelTerm = ( + + ); + } return ( -

{'Confirm DELETE Channel'}

+

+ +

- {`Are you sure you wish to delete the ${this.props.channel.display_name} ${channelTerm}?`} +
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 = ( + + ); } - const postTerm = Utils.getPostTerm(this.state.post); + const postTerm = this.state.post.root_id ? ( + + ) : ( + + ); return ( - {`Confirm ${postTerm} Delete`} + + + - {`Are you sure you want to delete this ${postTerm.toLowerCase()}?`} +

{commentWarning} @@ -154,7 +189,10 @@ export default class DeletePostModal extends React.Component { className='btn btn-default' onClick={this.handleHide} > - {'Cancel'} +
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} > - {'Edit Header for ' + this.props.channel.display_name} + + + -

{'Edit the text appearing next to the channel name in the channel header.'}

+

+ +