Ported RenameChannelModal to React-Bootstrap

This commit is contained in:
hmhealey
2016-02-18 15:22:11 -05:00
parent bc69f2aae0
commit 5ddd227985
4 changed files with 207 additions and 159 deletions

View File

@@ -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>
);
}

View File

@@ -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>
);
}

View File

@@ -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
};
}
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
});
}
handleSubmit(e) {
e.preventDefault();
if (this.state.channelId.length !== 26) {
return;
}
const channel = ChannelStore.get(this.state.channelId);
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'
/>
</h4>
{displayNameError}
</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>
<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}
</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);
export default injectIntl(RenameChannelModal);

View File

@@ -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/>