diff options
author | Christopher Speller <crspeller@gmail.com> | 2016-02-22 15:03:04 -0500 |
---|---|---|
committer | Christopher Speller <crspeller@gmail.com> | 2016-02-22 15:03:04 -0500 |
commit | 12fd1ddc95e1cc5320aa52afe8adc1937a8d606d (patch) | |
tree | 190ea30915892e1bccae86eb9d8d251c3e5ae42b /web | |
parent | bc69f2aae0cdc030adbebadd51d388d35e63950f (diff) | |
parent | 5ddd227985f5681fb239407397de3784d76bb528 (diff) | |
download | chat-12fd1ddc95e1cc5320aa52afe8adc1937a8d606d.tar.gz chat-12fd1ddc95e1cc5320aa52afe8adc1937a8d606d.tar.bz2 chat-12fd1ddc95e1cc5320aa52afe8adc1937a8d606d.zip |
Merge pull request #2210 from hmhealey/plt1258
PLT-1258 Ported RenameChannelModal to React-Bootstrap
Diffstat (limited to 'web')
-rw-r--r-- | web/react/components/channel_header.jsx | 27 | ||||
-rw-r--r-- | web/react/components/navbar.jsx | 38 | ||||
-rw-r--r-- | web/react/components/rename_channel_modal.jsx | 299 | ||||
-rw-r--r-- | web/react/pages/channel.jsx | 2 |
4 files changed, 207 insertions, 159 deletions
diff --git a/web/react/components/channel_header.jsx b/web/react/components/channel_header.jsx index b5eb546cf..079a9451e 100644 --- a/web/react/components/channel_header.jsx +++ b/web/react/components/channel_header.jsx @@ -11,6 +11,7 @@ import ChannelInviteModal from './channel_invite_modal.jsx'; import ChannelMembersModal from './channel_members_modal.jsx'; import ChannelNotificationsModal from './channel_notifications_modal.jsx'; import DeleteChannelModal from './delete_channel_modal.jsx'; +import RenameChannelModal from './rename_channel_modal.jsx'; import ToggleModalButton from './toggle_modal_button.jsx'; import ChannelStore from '../stores/channel_store.jsx'; @@ -39,10 +40,13 @@ export default class ChannelHeader extends React.Component { this.onListenerChange = this.onListenerChange.bind(this); this.handleLeave = this.handleLeave.bind(this); this.searchMentions = this.searchMentions.bind(this); + this.showRenameChannelModal = this.showRenameChannelModal.bind(this); + this.hideRenameChannelModal = this.hideRenameChannelModal.bind(this); const state = this.getStateFromStores(); state.showEditChannelPurposeModal = false; state.showMembersModal = false; + state.showRenameChannelModal = false; this.state = state; } getStateFromStores() { @@ -120,6 +124,18 @@ export default class ChannelHeader extends React.Component { is_mention_search: true }); } + showRenameChannelModal(e) { + e.preventDefault(); + + this.setState({ + showRenameChannelModal: true + }); + } + hideRenameChannelModal() { + this.setState({ + showRenameChannelModal: false + }); + } render() { if (this.state.channel === null) { return null; @@ -326,11 +342,7 @@ export default class ChannelHeader extends React.Component { <a role='menuitem' href='#' - data-toggle='modal' - data-target='#rename_channel' - data-display={channel.display_name} - data-name={channel.name} - data-channelid={channel.id} + onClick={this.showRenameChannelModal} > <FormattedMessage id='channel_header.rename' @@ -470,6 +482,11 @@ export default class ChannelHeader extends React.Component { onModalDismissed={() => this.setState({showMembersModal: false})} channel={channel} /> + <RenameChannelModal + show={this.state.showRenameChannelModal} + onHide={this.hideRenameChannelModal} + channel={channel} + /> </div> ); } diff --git a/web/react/components/navbar.jsx b/web/react/components/navbar.jsx index a06fb449b..85a6de6c8 100644 --- a/web/react/components/navbar.jsx +++ b/web/react/components/navbar.jsx @@ -5,11 +5,11 @@ import EditChannelHeaderModal from './edit_channel_header_modal.jsx'; import EditChannelPurposeModal from './edit_channel_purpose_modal.jsx'; import MessageWrapper from './message_wrapper.jsx'; import NotifyCounts from './notify_counts.jsx'; -import ChannelMembersModal from './channel_members_modal.jsx'; import ChannelInfoModal from './channel_info_modal.jsx'; import ChannelInviteModal from './channel_invite_modal.jsx'; import ChannelNotificationsModal from './channel_notifications_modal.jsx'; import DeleteChannelModal from './delete_channel_modal.jsx'; +import RenameChannelModal from './rename_channel_modal.jsx'; import ToggleModalButton from './toggle_modal_button.jsx'; import UserStore from '../stores/user_store.jsx'; @@ -39,6 +39,8 @@ export default class Navbar extends React.Component { this.showSearch = this.showSearch.bind(this); this.showEditChannelHeaderModal = this.showEditChannelHeaderModal.bind(this); + this.showRenameChannelModal = this.showRenameChannelModal.bind(this); + this.hideRenameChannelModal = this.hideRenameChannelModal.bind(this); this.createCollapseButtons = this.createCollapseButtons.bind(this); this.createDropdown = this.createDropdown.bind(this); @@ -47,6 +49,7 @@ export default class Navbar extends React.Component { state.showEditChannelPurposeModal = false; state.showEditChannelHeaderModal = false; state.showMembersModal = false; + state.showRenameChannelModal = false; this.state = state; } getStateFromStores() { @@ -128,6 +131,18 @@ export default class Navbar extends React.Component { showEditChannelHeaderModal: true }); } + showRenameChannelModal(e) { + e.preventDefault(); + + this.setState({ + showRenameChannelModal: true + }); + } + hideRenameChannelModal() { + this.setState({ + showRenameChannelModal: false + }); + } createDropdown(channel, channelTitle, isAdmin, isDirect, popoverContent) { if (channel) { var viewInfoOption = ( @@ -253,11 +268,7 @@ export default class Navbar extends React.Component { <a role='menuitem' href='#' - data-toggle='modal' - data-target='#rename_channel' - data-display={channel.display_name} - data-name={channel.name} - data-channelid={channel.id} + onClick={this.showRenameChannelModal} > <FormattedMessage id='navbar.rename' @@ -410,6 +421,7 @@ export default class Navbar extends React.Component { var editChannelHeaderModal = null; var editChannelPurposeModal = null; + let renameChannelModal = null; if (channel) { popoverContent = ( @@ -492,6 +504,14 @@ export default class Navbar extends React.Component { channel={channel} /> ); + + renameChannelModal = ( + <RenameChannelModal + show={this.state.showRenameChannelModal} + onHide={this.hideRenameChannelModal} + channel={channel} + /> + ); } var collapseButtons = this.createCollapseButtons(currentId); @@ -524,11 +544,7 @@ export default class Navbar extends React.Component { </nav> {editChannelHeaderModal} {editChannelPurposeModal} - <ChannelMembersModal - show={this.state.showMembersModal} - onModalDismissed={() => this.setState({showMembersModal: false})} - channel={{channel}} - /> + {renameChannelModal} </div> ); } diff --git a/web/react/components/rename_channel_modal.jsx b/web/react/components/rename_channel_modal.jsx index c467c0d87..49ebccdbb 100644 --- a/web/react/components/rename_channel_modal.jsx +++ b/web/react/components/rename_channel_modal.jsx @@ -4,11 +4,12 @@ import * as Utils from '../utils/utils.jsx'; import * as Client from '../utils/client.jsx'; 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 Modal = ReactBootstrap.Modal; + const holders = defineMessages({ required: { id: 'rename_channel.required', @@ -44,33 +45,81 @@ export default class RenameChannelModal extends React.Component { constructor(props) { super(props); + this.handleShow = this.handleShow.bind(this); + this.handleHide = this.handleHide.bind(this); this.handleSubmit = this.handleSubmit.bind(this); + this.handleCancel = this.handleCancel.bind(this); + this.onNameChange = this.onNameChange.bind(this); this.onDisplayNameChange = this.onDisplayNameChange.bind(this); this.displayNameKeyUp = this.displayNameKeyUp.bind(this); - this.handleClose = this.handleClose.bind(this); - this.handleShow = this.handleShow.bind(this); - this.handleShown = this.handleShown.bind(this); - this.handleSubmit = this.handleSubmit.bind(this); this.state = { - displayName: '', - channelName: '', - channelId: '', + displayName: props.channel.display_name, + channelName: props.channel.name, serverError: '', nameError: '', displayNameError: '', invalid: false }; } - handleSubmit(e) { - e.preventDefault(); - if (this.state.channelId.length !== 26) { - return; + componentWillReceiveProps(nextProps) { + if (!Utils.areObjectsEqual(nextProps.channel, this.props.channel)) { + this.setState({ + displayName: nextProps.channel.display_name, + channelName: nextProps.channel.name + }); } + } + + shouldComponentUpdate(nextProps, nextState) { + if (!nextProps.show && !this.props.show) { + return false; + } + + if (!Utils.areObjectsEqual(nextState, this.state)) { + return true; + } + + if (!Utils.areObjectsEqual(nextProps, this.props)) { + return true; + } + + return false; + } + + componentDidUpdate(prevProps) { + if (!prevProps.show && this.props.show) { + this.handleShow(); + } + } + + handleShow() { + const textbox = ReactDOM.findDOMNode(this.refs.displayName); + textbox.focus(); + Utils.placeCaretAtEnd(textbox); + } + + handleHide(e) { + if (e) { + e.preventDefault(); + } + + this.props.onHide(); + + this.setState({ + serverError: '', + nameError: '', + displayNameError: '', + invalid: false + }); + } - const channel = ChannelStore.get(this.state.channelId); + handleSubmit(e) { + e.preventDefault(); + + const channel = Object.assign({}, this.props.channel); const oldName = channel.name; const oldDisplayName = channel.displayName; const state = {serverError: ''}; @@ -110,29 +159,40 @@ export default class RenameChannelModal extends React.Component { return; } - Client.updateChannel(channel, + Client.updateChannel( + channel, () => { - $(ReactDOM.findDOMNode(this.refs.modal)).modal('hide'); - AsyncClient.getChannel(channel.id); Utils.updateAddressBar(channel.name); - ReactDOM.findDOMNode(this.refs.displayName).value = ''; - ReactDOM.findDOMNode(this.refs.channelName).value = ''; + this.handleHide(); }, (err) => { - state.serverError = err.message; - state.invalid = true; - this.setState(state); + this.setState({ + serverError: err.message, + invalid: true + }); } ); } + + handleCancel(e) { + this.setState({ + displayName: this.props.channel.display_name, + channelName: this.props.channel.name + }); + + this.handleHide(e); + } + onNameChange() { this.setState({channelName: ReactDOM.findDOMNode(this.refs.channelName).value}); } + onDisplayNameChange() { this.setState({displayName: ReactDOM.findDOMNode(this.refs.displayName).value}); } + displayNameKeyUp() { if (this.state.channelName !== Constants.DEFAULT_CHANNEL) { const displayName = ReactDOM.findDOMNode(this.refs.displayName).value.trim(); @@ -141,32 +201,7 @@ export default class RenameChannelModal extends React.Component { this.setState({channelName: channelName}); } } - handleClose() { - this.setState({ - displayName: '', - channelName: '', - channelId: '', - serverError: '', - nameError: '', - displayNameError: '', - invalid: false - }); - } - handleShow(e) { - const button = $(e.relatedTarget); - this.setState({displayName: button.attr('data-display'), channelName: button.attr('data-name'), channelId: button.attr('data-channelid')}); - } - handleShown() { - $('#rename_channel #display_name').focus(); - } - componentDidMount() { - $(ReactDOM.findDOMNode(this.refs.modal)).on('show.bs.modal', this.handleShow); - $(ReactDOM.findDOMNode(this.refs.modal)).on('hidden.bs.modal', this.handleClose); - $(ReactDOM.findDOMNode(this.refs.modal)).on('shown.bs.modal', this.handleShown); - } - componentWillUnmount() { - $(ReactDOM.findDOMNode(this.refs.modal)).off('hidden.bs.modal', this.handleClose); - } + render() { let displayNameError = null; let displayNameClass = 'form-group'; @@ -199,107 +234,89 @@ export default class RenameChannelModal extends React.Component { } return ( - <div - className='modal fade' - ref='modal' - id='rename_channel' - tabIndex='-1' - role='dialog' - aria-hidden='true' + <Modal + show={this.props.show} + onHide={this.handleCancel} > - <div className='modal-dialog'> - <div className='modal-content'> - <div className='modal-header'> - <button - type='button' - className='close' - data-dismiss='modal' - > - <span aria-hidden='true'>{'×'}</span> - <span className='sr-only'> - <FormattedMessage - id='rename_channel.close' - defaultMessage='Close' - /> - </span> - </button> - <h4 className='modal-title'> - <FormattedMessage - id='rename_channel.title' - defaultMessage='Rename Channel' + <Modal.Header closeButton={true}> + <Modal.Title> + <FormattedMessage + id='rename_channel.title' + defaultMessage='Rename Channel' + /> + </Modal.Title> + </Modal.Header> + <form role='form'> + <Modal.Body> + <div className={displayNameClass}> + <label className='control-label'> + <FormattedMessage + id='rename_channel.displayName' + defaultMessage='Display Name' + /> + </label> + <input + onKeyUp={this.displayNameKeyUp} + onChange={this.onDisplayNameChange} + type='text' + ref='displayName' + id='display_name' + className='form-control' + placeholder={formatMessage(holders.displayNameHolder)} + value={this.state.displayName} + maxLength='64' + /> + {displayNameError} + </div> + <div className={nameClass}> + <label className='control-label'>{handleInputLabel}</label> + <input + onChange={this.onNameChange} + type='text' + className={handleInputClass} + ref='channelName' + placeholder={formatMessage(holders.handleHolder)} + value={this.state.channelName} + maxLength='64' + readOnly={readOnlyHandleInput} /> - </h4> + {nameError} </div> - <form role='form'> - <div className='modal-body'> - <div className={displayNameClass}> - <label className='control-label'> - <FormattedMessage - id='rename_channel.displayName' - defaultMessage='Display Name' - /> - </label> - <input - onKeyUp={this.displayNameKeyUp} - onChange={this.onDisplayNameChange} - type='text' - ref='displayName' - id='display_name' - className='form-control' - placeholder={formatMessage(holders.displayNameHolder)} - value={this.state.displayName} - maxLength='64' - /> - {displayNameError} - </div> - <div className={nameClass}> - <label className='control-label'>{handleInputLabel}</label> - <input - onChange={this.onNameChange} - type='text' - className={handleInputClass} - ref='channelName' - placeholder={formatMessage(holders.handleHolder)} - value={this.state.channelName} - maxLength='64' - readOnly={readOnlyHandleInput} - /> - {nameError} - </div> - {serverError} - </div> - <div className='modal-footer'> - <button - type='button' - className='btn btn-default' - data-dismiss='modal' - > - <FormattedMessage - id='rename_channel.cancel' - defaultMessage='Cancel' - /> - </button> - <button - onClick={this.handleSubmit} - type='submit' - className='btn btn-primary' - > - <FormattedMessage - id='rename_channel.save' - defaultMessage='Save' - /> - </button> - </div> - </form> - </div> - </div> - </div> + {serverError} + </Modal.Body> + <Modal.Footer> + <button + type='button' + className='btn btn-default' + onClick={this.handleCancel} + > + <FormattedMessage + id='rename_channel.cancel' + defaultMessage='Cancel' + /> + </button> + <button + onClick={this.handleSubmit} + type='submit' + className='btn btn-primary' + > + <FormattedMessage + id='rename_channel.save' + defaultMessage='Save' + /> + </button> + </Modal.Footer> + </form> + </Modal> ); } } RenameChannelModal.propTypes = { - intl: intlShape.isRequired + intl: intlShape.isRequired, + show: React.PropTypes.bool.isRequired, + onHide: React.PropTypes.func.isRequired, + channel: React.PropTypes.object.isRequired }; -export default injectIntl(RenameChannelModal);
\ No newline at end of file +export default injectIntl(RenameChannelModal); diff --git a/web/react/pages/channel.jsx b/web/react/pages/channel.jsx index 61fa91cf8..bc78c049c 100644 --- a/web/react/pages/channel.jsx +++ b/web/react/pages/channel.jsx @@ -8,7 +8,6 @@ import * as Client from '../utils/client.jsx'; import GetPostLinkModal from '../components/get_post_link_modal.jsx'; import GetTeamInviteLinkModal from '../components/get_team_invite_link_modal.jsx'; -import RenameChannelModal from '../components/rename_channel_modal.jsx'; import EditPostModal from '../components/edit_post_modal.jsx'; import DeletePostModal from '../components/delete_post_modal.jsx'; import MoreChannelsModal from '../components/more_channels.jsx'; @@ -73,7 +72,6 @@ class Root extends React.Component { <InviteMemberModal/> <ImportThemeModal/> <TeamSettingsModal/> - <RenameChannelModal/> <MoreChannelsModal/> <EditPostModal/> <DeletePostModal/> |