From 017cd2a9575149bb87f382f441b9c960b6816c9d Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Wed, 17 May 2017 11:29:41 -0400 Subject: PLT-6406 Migrate new channel modal to be pure and use redux (#6416) * Migrate new channel modal to be pure and use redux * Add component tests --- webapp/components/new_channel_flow.jsx | 2 +- webapp/components/new_channel_modal.jsx | 359 ---------- webapp/components/new_channel_modal/index.js | 21 + .../new_channel_modal/new_channel_modal.jsx | 391 +++++++++++ webapp/package.json | 1 + .../__snapshots__/new_channel_modal.test.jsx.snap | 733 +++++++++++++++++++++ webapp/tests/components/new_channel_modal.test.jsx | 79 +++ 7 files changed, 1226 insertions(+), 360 deletions(-) delete mode 100644 webapp/components/new_channel_modal.jsx create mode 100644 webapp/components/new_channel_modal/index.js create mode 100644 webapp/components/new_channel_modal/new_channel_modal.jsx create mode 100644 webapp/tests/components/__snapshots__/new_channel_modal.test.jsx.snap create mode 100644 webapp/tests/components/new_channel_modal.test.jsx diff --git a/webapp/components/new_channel_flow.jsx b/webapp/components/new_channel_flow.jsx index 91dd04c0c..69c2f1c4c 100644 --- a/webapp/components/new_channel_flow.jsx +++ b/webapp/components/new_channel_flow.jsx @@ -5,7 +5,7 @@ import * as Utils from 'utils/utils.jsx'; import TeamStore from 'stores/team_store.jsx'; import {cleanUpUrlable} from 'utils/url.jsx'; -import NewChannelModal from './new_channel_modal.jsx'; +import NewChannelModal from 'components/new_channel_modal'; import ChangeURLModal from './change_url_modal.jsx'; import {FormattedMessage} from 'react-intl'; diff --git a/webapp/components/new_channel_modal.jsx b/webapp/components/new_channel_modal.jsx deleted file mode 100644 index 49103b7a8..000000000 --- a/webapp/components/new_channel_modal.jsx +++ /dev/null @@ -1,359 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import $ from 'jquery'; -import ReactDOM from 'react-dom'; - -import {getShortenedURL} from 'utils/url.jsx'; -import * as UserAgent from 'utils/user_agent.jsx'; -import * as Utils from 'utils/utils.jsx'; -import * as ChannelUtils from 'utils/channel_utils.jsx'; -import Constants from 'utils/constants.jsx'; - -import UserStore from 'stores/user_store.jsx'; -import TeamStore from 'stores/team_store.jsx'; -import PreferenceStore from 'stores/preference_store.jsx'; - -import {FormattedMessage} from 'react-intl'; - -import {Modal} from 'react-bootstrap'; - -import React from 'react'; - -export default class NewChannelModal extends React.Component { - constructor(props) { - super(props); - - this.handleSubmit = this.handleSubmit.bind(this); - this.handleChange = this.handleChange.bind(this); - this.onEnterKeyDown = this.onEnterKeyDown.bind(this); - this.onPreferenceChange = this.onPreferenceChange.bind(this); - - this.ctrlSend = PreferenceStore.getBool(Constants.Preferences.CATEGORY_ADVANCED_SETTINGS, 'send_on_ctrl_enter'); - - this.state = { - displayNameError: '' - }; - } - - componentWillReceiveProps(nextProps) { - if (nextProps.show === true && this.props.show === false) { - this.setState({ - displayNameError: '' - }); - - document.addEventListener('keydown', this.onEnterKeyDown); - } else if (nextProps.show === false && this.props.show === true) { - document.removeEventListener('keydown', this.onEnterKeyDown); - } - } - - componentDidMount() { - // ??? - if (UserAgent.isInternetExplorer()) { - $('body').addClass('browser--ie'); - } - - PreferenceStore.addChangeListener(this.onPreferenceChange); - } - - componentWillUnmount() { - PreferenceStore.removeChangeListener(this.onPreferenceChange); - } - - onPreferenceChange() { - this.ctrlSend = PreferenceStore.getBool(Constants.Preferences.CATEGORY_ADVANCED_SETTINGS, 'send_on_ctrl_enter'); - } - - onEnterKeyDown(e) { - if (this.ctrlSend && e.keyCode === Constants.KeyCodes.ENTER && e.ctrlKey) { - this.handleSubmit(e); - } else if (!this.ctrlSend && e.keyCode === Constants.KeyCodes.ENTER && !e.shiftKey && !e.altKey) { - this.handleSubmit(e); - } - } - - handleSubmit(e) { - e.preventDefault(); - - const displayName = ReactDOM.findDOMNode(this.refs.display_name).value.trim(); - if (displayName.length < Constants.MIN_CHANNELNAME_LENGTH) { - this.setState({displayNameError: true}); - return; - } - - this.props.onSubmitChannel(); - } - - handleChange() { - const newData = { - displayName: this.refs.display_name.value, - header: this.refs.channel_header.value, - purpose: this.refs.channel_purpose.value - }; - this.props.onDataChanged(newData); - } - - render() { - var displayNameError = null; - var serverError = null; - var displayNameClass = 'form-group'; - - if (this.state.displayNameError) { - displayNameError = ( -

- - {this.state.displayNameError} -

- ); - displayNameClass += ' has-error'; - } - - if (this.props.serverError) { - serverError =

{this.props.serverError}

; - } - - let createPublicChannelLink = ( - - - - ); - - let createPrivateChannelLink = ( - - - - ); - - const isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser(); - const isSystemAdmin = UserStore.isSystemAdminForCurrentUser(); - - if (!ChannelUtils.showCreateOption(Constants.OPEN_CHANNEL, isAdmin, isSystemAdmin)) { - createPublicChannelLink = null; - } - - if (!ChannelUtils.showCreateOption(Constants.PRIVATE_CHANNEL, isAdmin, isSystemAdmin)) { - createPrivateChannelLink = null; - } - - var channelSwitchText = ''; - switch (this.props.channelType) { - case 'P': - channelSwitchText = ( -
- - {createPublicChannelLink} -
- ); - break; - case 'O': - channelSwitchText = ( -
- - {createPrivateChannelLink} -
- ); - break; - } - - const prettyTeamURL = getShortenedURL(); - - return ( - - - - - - - -
- -
- {channelSwitchText} -
-
- -
- - {displayNameError} -

- {'URL: ' + prettyTeamURL + this.props.channelData.name + ' ('} - - - - {')'} -

-
-
-
-
- - -
-
-