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
Этот коммит содержится в:
коммит произвёл
Corey Hulen
родитель
a84a300947
Коммит
017cd2a957
@@ -5,7 +5,7 @@ import * as Utils from 'utils/utils.jsx';
|
|||||||
import TeamStore from 'stores/team_store.jsx';
|
import TeamStore from 'stores/team_store.jsx';
|
||||||
import {cleanUpUrlable} from 'utils/url.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 ChangeURLModal from './change_url_modal.jsx';
|
||||||
|
|
||||||
import {FormattedMessage} from 'react-intl';
|
import {FormattedMessage} from 'react-intl';
|
||||||
|
|||||||
21
webapp/components/new_channel_modal/index.js
Обычный файл
21
webapp/components/new_channel_modal/index.js
Обычный файл
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
import {getBool} from 'mattermost-redux/selectors/entities/preferences';
|
||||||
|
import {isCurrentUserSystemAdmin} from 'mattermost-redux/selectors/entities/users';
|
||||||
|
import {isCurrentUserCurrentTeamAdmin} from 'mattermost-redux/selectors/entities/teams';
|
||||||
|
import {Preferences} from 'mattermost-redux/constants';
|
||||||
|
|
||||||
|
import NewChannelModal from './new_channel_modal.jsx';
|
||||||
|
|
||||||
|
function mapStateToProps(state, ownProps) {
|
||||||
|
return {
|
||||||
|
...ownProps,
|
||||||
|
ctrlSend: getBool(state, Preferences.CATEGORY_ADVANCED_SETTINGS, 'send_on_ctrl_enter'),
|
||||||
|
isTeamAdmin: isCurrentUserCurrentTeamAdmin(state),
|
||||||
|
isSystemAdmin: isCurrentUserSystemAdmin(state)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps)(NewChannelModal);
|
||||||
@@ -10,26 +10,88 @@ import * as Utils from 'utils/utils.jsx';
|
|||||||
import * as ChannelUtils from 'utils/channel_utils.jsx';
|
import * as ChannelUtils from 'utils/channel_utils.jsx';
|
||||||
import Constants from 'utils/constants.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 {FormattedMessage} from 'react-intl';
|
||||||
|
|
||||||
import {Modal} from 'react-bootstrap';
|
import {Modal} from 'react-bootstrap';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
export default class NewChannelModal extends React.PureComponent {
|
||||||
|
static propTypes = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether to show the modal or not
|
||||||
|
*/
|
||||||
|
show: PropTypes.bool.isRequired,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of channel to create, 'O' or 'P'
|
||||||
|
*/
|
||||||
|
channelType: PropTypes.string.isRequired,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The data needed to create the channel
|
||||||
|
*/
|
||||||
|
channelData: PropTypes.object.isRequired,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to force form submission on CTRL/CMD + ENTER instead of ENTER
|
||||||
|
*/
|
||||||
|
ctrlSend: PropTypes.bool,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to show options available to team admins
|
||||||
|
*/
|
||||||
|
isTeamAdmin: PropTypes.bool,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to show options available to system admins
|
||||||
|
*/
|
||||||
|
isSystemAdmin: PropTypes.bool,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server error from failed channel creation
|
||||||
|
*/
|
||||||
|
serverError: PropTypes.node,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function used to submit the channel
|
||||||
|
*/
|
||||||
|
onSubmitChannel: PropTypes.func.isRequired,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to call when modal is dimissed
|
||||||
|
*/
|
||||||
|
onModalDismissed: PropTypes.func.isRequired,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to call when modal has exited
|
||||||
|
*/
|
||||||
|
onModalExited: PropTypes.func,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to call to switch channel type
|
||||||
|
*/
|
||||||
|
onTypeSwitched: PropTypes.func.isRequired,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to call when edit URL button is pressed
|
||||||
|
*/
|
||||||
|
onChangeURLPressed: PropTypes.func.isRequired,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to call when channel data is modified
|
||||||
|
*/
|
||||||
|
onDataChanged: PropTypes.func.isRequired
|
||||||
|
}
|
||||||
|
|
||||||
export default class NewChannelModal extends React.Component {
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.handleSubmit = this.handleSubmit.bind(this);
|
this.handleSubmit = this.handleSubmit.bind(this);
|
||||||
this.handleChange = this.handleChange.bind(this);
|
this.handleChange = this.handleChange.bind(this);
|
||||||
this.onEnterKeyDown = this.onEnterKeyDown.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 = {
|
this.state = {
|
||||||
displayNameError: ''
|
displayNameError: ''
|
||||||
@@ -53,22 +115,12 @@ export default class NewChannelModal extends React.Component {
|
|||||||
if (UserAgent.isInternetExplorer()) {
|
if (UserAgent.isInternetExplorer()) {
|
||||||
$('body').addClass('browser--ie');
|
$('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) {
|
onEnterKeyDown(e) {
|
||||||
if (this.ctrlSend && e.keyCode === Constants.KeyCodes.ENTER && e.ctrlKey) {
|
if (this.props.ctrlSend && e.keyCode === Constants.KeyCodes.ENTER && e.ctrlKey) {
|
||||||
this.handleSubmit(e);
|
this.handleSubmit(e);
|
||||||
} else if (!this.ctrlSend && e.keyCode === Constants.KeyCodes.ENTER && !e.shiftKey && !e.altKey) {
|
} else if (!this.props.ctrlSend && e.keyCode === Constants.KeyCodes.ENTER && !e.shiftKey && !e.altKey) {
|
||||||
this.handleSubmit(e);
|
this.handleSubmit(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,14 +192,13 @@ export default class NewChannelModal extends React.Component {
|
|||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
|
|
||||||
const isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser();
|
const isAdmin = this.props.isTeamAdmin || this.props.isSystemAdmin;
|
||||||
const isSystemAdmin = UserStore.isSystemAdminForCurrentUser();
|
|
||||||
|
|
||||||
if (!ChannelUtils.showCreateOption(Constants.OPEN_CHANNEL, isAdmin, isSystemAdmin)) {
|
if (!ChannelUtils.showCreateOption(Constants.OPEN_CHANNEL, isAdmin, this.props.isSystemAdmin)) {
|
||||||
createPublicChannelLink = null;
|
createPublicChannelLink = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ChannelUtils.showCreateOption(Constants.PRIVATE_CHANNEL, isAdmin, isSystemAdmin)) {
|
if (!ChannelUtils.showCreateOption(Constants.PRIVATE_CHANNEL, isAdmin, this.props.isSystemAdmin)) {
|
||||||
createPrivateChannelLink = null;
|
createPrivateChannelLink = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,22 +389,3 @@ export default class NewChannelModal extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NewChannelModal.defaultProps = {
|
|
||||||
show: false,
|
|
||||||
channelType: 'O',
|
|
||||||
serverError: null
|
|
||||||
};
|
|
||||||
NewChannelModal.propTypes = {
|
|
||||||
show: React.PropTypes.bool.isRequired,
|
|
||||||
channelType: React.PropTypes.string.isRequired,
|
|
||||||
channelData: React.PropTypes.object.isRequired,
|
|
||||||
serverError: React.PropTypes.node,
|
|
||||||
onSubmitChannel: React.PropTypes.func.isRequired,
|
|
||||||
onModalDismissed: React.PropTypes.func.isRequired,
|
|
||||||
onModalExited: React.PropTypes.func,
|
|
||||||
onTypeSwitched: React.PropTypes.func.isRequired,
|
|
||||||
onChangeURLPressed: React.PropTypes.func.isRequired,
|
|
||||||
onDataChanged: React.PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
"object-assign": "4.1.1",
|
"object-assign": "4.1.1",
|
||||||
"pdfjs-dist": "1.7.363",
|
"pdfjs-dist": "1.7.363",
|
||||||
"perfect-scrollbar": "0.6.16",
|
"perfect-scrollbar": "0.6.16",
|
||||||
|
"prop-types": "15.5.9",
|
||||||
"react": "15.4.2",
|
"react": "15.4.2",
|
||||||
"react-addons-pure-render-mixin": "15.4.2",
|
"react-addons-pure-render-mixin": "15.4.2",
|
||||||
"react-bootstrap": "0.30.8",
|
"react-bootstrap": "0.30.8",
|
||||||
|
|||||||
@@ -0,0 +1,733 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`components/NewChannelModal should match snapshot, modal not showing 1`] = `
|
||||||
|
<span>
|
||||||
|
<Modal
|
||||||
|
animation={true}
|
||||||
|
autoFocus={true}
|
||||||
|
backdrop={true}
|
||||||
|
bsClass="modal"
|
||||||
|
bsSize="large"
|
||||||
|
dialogClassName="new-channel__modal"
|
||||||
|
dialogComponentClass={[Function]}
|
||||||
|
enforceFocus={true}
|
||||||
|
keyboard={true}
|
||||||
|
manager={
|
||||||
|
ModalManager {
|
||||||
|
"containers": Array [],
|
||||||
|
"data": Array [],
|
||||||
|
"handleContainerOverflow": true,
|
||||||
|
"hideSiblingNodes": true,
|
||||||
|
"modals": Array [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onHide={[Function]}
|
||||||
|
renderBackdrop={[Function]}
|
||||||
|
restoreFocus={true}
|
||||||
|
show={true}
|
||||||
|
>
|
||||||
|
<ModalHeader
|
||||||
|
aria-label="Close"
|
||||||
|
bsClass="modal-header"
|
||||||
|
closeButton={true}
|
||||||
|
>
|
||||||
|
<ModalTitle
|
||||||
|
bsClass="modal-title"
|
||||||
|
componentClass="h4"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="New Channel"
|
||||||
|
id="channel_modal.modalTitle"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</ModalTitle>
|
||||||
|
</ModalHeader>
|
||||||
|
<form
|
||||||
|
className="form-horizontal"
|
||||||
|
role="form"
|
||||||
|
>
|
||||||
|
<ModalBody
|
||||||
|
bsClass="modal-body"
|
||||||
|
componentClass="div"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
className="modal-intro"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Create a new public channel anyone can join. "
|
||||||
|
id="channel_modal.publicChannel2"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Create a private channel"
|
||||||
|
id="channel_modal.privateGroup2"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="form-group"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
className="col-sm-3 form__label control-label"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Name"
|
||||||
|
id="channel_modal.name"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<div
|
||||||
|
className="col-sm-9"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
autoFocus={true}
|
||||||
|
className="form-control"
|
||||||
|
maxLength={22}
|
||||||
|
onChange={[Function]}
|
||||||
|
placeholder="E.g.: \\"Bugs\\", \\"Marketing\\", \\"客户支持\\""
|
||||||
|
tabIndex="1"
|
||||||
|
type="text"
|
||||||
|
value="testchannel"
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
className="input__help dark"
|
||||||
|
>
|
||||||
|
URL: /testchannel (
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Edit"
|
||||||
|
id="channel_modal.edit"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="form-group"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="col-sm-3"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
className="form__label control-label"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Purpose"
|
||||||
|
id="channel_modal.purpose"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<label
|
||||||
|
className="form__label light"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="(optional)"
|
||||||
|
id="channel_modal.optional"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="col-sm-9"
|
||||||
|
>
|
||||||
|
<textarea
|
||||||
|
className="form-control no-resize"
|
||||||
|
maxLength="250"
|
||||||
|
onChange={[Function]}
|
||||||
|
placeholder="E.g.: \\"A channel to file bugs and improvements\\""
|
||||||
|
rows="4"
|
||||||
|
tabIndex="2"
|
||||||
|
value=""
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
className="input__help"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Describe how this channel should be used."
|
||||||
|
id="channel_modal.descriptionHelp"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="form-group less"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="col-sm-3"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
className="form__label control-label"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Header"
|
||||||
|
id="channel_modal.header"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<label
|
||||||
|
className="form__label light"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="(optional)"
|
||||||
|
id="channel_modal.optional"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="col-sm-9"
|
||||||
|
>
|
||||||
|
<textarea
|
||||||
|
className="form-control no-resize"
|
||||||
|
maxLength="1024"
|
||||||
|
onChange={[Function]}
|
||||||
|
placeholder="E.g.: \\"[Link Title](http://example.com)\\""
|
||||||
|
rows="4"
|
||||||
|
tabIndex="2"
|
||||||
|
value=""
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
className="input__help"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Set text that will appear in the header of the channel beside the channel name. For example, include frequently used links by typing [Link Title](http://example.com)."
|
||||||
|
id="channel_modal.headerHelp"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ModalBody>
|
||||||
|
<ModalFooter
|
||||||
|
bsClass="modal-footer"
|
||||||
|
componentClass="div"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="btn btn-default"
|
||||||
|
onClick={[Function]}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Cancel"
|
||||||
|
id="channel_modal.cancel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="btn btn-primary"
|
||||||
|
onClick={[Function]}
|
||||||
|
tabIndex="3"
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Create New Channel"
|
||||||
|
id="channel_modal.createNew"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</ModalFooter>
|
||||||
|
</form>
|
||||||
|
</Modal>
|
||||||
|
</span>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`components/NewChannelModal should match snapshot, modal showing 1`] = `
|
||||||
|
<span>
|
||||||
|
<Modal
|
||||||
|
animation={true}
|
||||||
|
autoFocus={true}
|
||||||
|
backdrop={true}
|
||||||
|
bsClass="modal"
|
||||||
|
bsSize="large"
|
||||||
|
dialogClassName="new-channel__modal"
|
||||||
|
dialogComponentClass={[Function]}
|
||||||
|
enforceFocus={true}
|
||||||
|
keyboard={true}
|
||||||
|
manager={
|
||||||
|
ModalManager {
|
||||||
|
"containers": Array [],
|
||||||
|
"data": Array [],
|
||||||
|
"handleContainerOverflow": true,
|
||||||
|
"hideSiblingNodes": true,
|
||||||
|
"modals": Array [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onHide={[Function]}
|
||||||
|
renderBackdrop={[Function]}
|
||||||
|
restoreFocus={true}
|
||||||
|
show={true}
|
||||||
|
>
|
||||||
|
<ModalHeader
|
||||||
|
aria-label="Close"
|
||||||
|
bsClass="modal-header"
|
||||||
|
closeButton={true}
|
||||||
|
>
|
||||||
|
<ModalTitle
|
||||||
|
bsClass="modal-title"
|
||||||
|
componentClass="h4"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="New Channel"
|
||||||
|
id="channel_modal.modalTitle"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</ModalTitle>
|
||||||
|
</ModalHeader>
|
||||||
|
<form
|
||||||
|
className="form-horizontal"
|
||||||
|
role="form"
|
||||||
|
>
|
||||||
|
<ModalBody
|
||||||
|
bsClass="modal-body"
|
||||||
|
componentClass="div"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
className="modal-intro"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Create a new public channel anyone can join. "
|
||||||
|
id="channel_modal.publicChannel2"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Create a private channel"
|
||||||
|
id="channel_modal.privateGroup2"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="form-group"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
className="col-sm-3 form__label control-label"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Name"
|
||||||
|
id="channel_modal.name"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<div
|
||||||
|
className="col-sm-9"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
autoFocus={true}
|
||||||
|
className="form-control"
|
||||||
|
maxLength={22}
|
||||||
|
onChange={[Function]}
|
||||||
|
placeholder="E.g.: \\"Bugs\\", \\"Marketing\\", \\"客户支持\\""
|
||||||
|
tabIndex="1"
|
||||||
|
type="text"
|
||||||
|
value="testchannel"
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
className="input__help dark"
|
||||||
|
>
|
||||||
|
URL: /testchannel (
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Edit"
|
||||||
|
id="channel_modal.edit"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="form-group"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="col-sm-3"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
className="form__label control-label"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Purpose"
|
||||||
|
id="channel_modal.purpose"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<label
|
||||||
|
className="form__label light"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="(optional)"
|
||||||
|
id="channel_modal.optional"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="col-sm-9"
|
||||||
|
>
|
||||||
|
<textarea
|
||||||
|
className="form-control no-resize"
|
||||||
|
maxLength="250"
|
||||||
|
onChange={[Function]}
|
||||||
|
placeholder="E.g.: \\"A channel to file bugs and improvements\\""
|
||||||
|
rows="4"
|
||||||
|
tabIndex="2"
|
||||||
|
value=""
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
className="input__help"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Describe how this channel should be used."
|
||||||
|
id="channel_modal.descriptionHelp"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="form-group less"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="col-sm-3"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
className="form__label control-label"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Header"
|
||||||
|
id="channel_modal.header"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<label
|
||||||
|
className="form__label light"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="(optional)"
|
||||||
|
id="channel_modal.optional"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="col-sm-9"
|
||||||
|
>
|
||||||
|
<textarea
|
||||||
|
className="form-control no-resize"
|
||||||
|
maxLength="1024"
|
||||||
|
onChange={[Function]}
|
||||||
|
placeholder="E.g.: \\"[Link Title](http://example.com)\\""
|
||||||
|
rows="4"
|
||||||
|
tabIndex="2"
|
||||||
|
value=""
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
className="input__help"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Set text that will appear in the header of the channel beside the channel name. For example, include frequently used links by typing [Link Title](http://example.com)."
|
||||||
|
id="channel_modal.headerHelp"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ModalBody>
|
||||||
|
<ModalFooter
|
||||||
|
bsClass="modal-footer"
|
||||||
|
componentClass="div"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="btn btn-default"
|
||||||
|
onClick={[Function]}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Cancel"
|
||||||
|
id="channel_modal.cancel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="btn btn-primary"
|
||||||
|
onClick={[Function]}
|
||||||
|
tabIndex="3"
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Create New Channel"
|
||||||
|
id="channel_modal.createNew"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</ModalFooter>
|
||||||
|
</form>
|
||||||
|
</Modal>
|
||||||
|
</span>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`components/NewChannelModal should match snapshot, private channel filled in header and purpose 1`] = `
|
||||||
|
<span>
|
||||||
|
<Modal
|
||||||
|
animation={true}
|
||||||
|
autoFocus={true}
|
||||||
|
backdrop={true}
|
||||||
|
bsClass="modal"
|
||||||
|
bsSize="large"
|
||||||
|
dialogClassName="new-channel__modal"
|
||||||
|
dialogComponentClass={[Function]}
|
||||||
|
enforceFocus={true}
|
||||||
|
keyboard={true}
|
||||||
|
manager={
|
||||||
|
ModalManager {
|
||||||
|
"containers": Array [],
|
||||||
|
"data": Array [],
|
||||||
|
"handleContainerOverflow": true,
|
||||||
|
"hideSiblingNodes": true,
|
||||||
|
"modals": Array [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onHide={[Function]}
|
||||||
|
renderBackdrop={[Function]}
|
||||||
|
restoreFocus={true}
|
||||||
|
show={true}
|
||||||
|
>
|
||||||
|
<ModalHeader
|
||||||
|
aria-label="Close"
|
||||||
|
bsClass="modal-header"
|
||||||
|
closeButton={true}
|
||||||
|
>
|
||||||
|
<ModalTitle
|
||||||
|
bsClass="modal-title"
|
||||||
|
componentClass="h4"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="New Channel"
|
||||||
|
id="channel_modal.modalTitle"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</ModalTitle>
|
||||||
|
</ModalHeader>
|
||||||
|
<form
|
||||||
|
className="form-horizontal"
|
||||||
|
role="form"
|
||||||
|
>
|
||||||
|
<ModalBody
|
||||||
|
bsClass="modal-body"
|
||||||
|
componentClass="div"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
className="modal-intro"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Create a new private channel with restricted membership. "
|
||||||
|
id="channel_modal.privateGroup1"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Create a public channel"
|
||||||
|
id="channel_modal.publicChannel1"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="form-group"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
className="col-sm-3 form__label control-label"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Name"
|
||||||
|
id="channel_modal.name"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<div
|
||||||
|
className="col-sm-9"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
autoFocus={true}
|
||||||
|
className="form-control"
|
||||||
|
maxLength={22}
|
||||||
|
onChange={[Function]}
|
||||||
|
placeholder="E.g.: \\"Bugs\\", \\"Marketing\\", \\"客户支持\\""
|
||||||
|
tabIndex="1"
|
||||||
|
type="text"
|
||||||
|
value="testchannel"
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
className="input__help dark"
|
||||||
|
>
|
||||||
|
URL: /testchannel (
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Edit"
|
||||||
|
id="channel_modal.edit"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="form-group"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="col-sm-3"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
className="form__label control-label"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Purpose"
|
||||||
|
id="channel_modal.purpose"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<label
|
||||||
|
className="form__label light"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="(optional)"
|
||||||
|
id="channel_modal.optional"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="col-sm-9"
|
||||||
|
>
|
||||||
|
<textarea
|
||||||
|
className="form-control no-resize"
|
||||||
|
maxLength="250"
|
||||||
|
onChange={[Function]}
|
||||||
|
placeholder="E.g.: \\"A channel to file bugs and improvements\\""
|
||||||
|
rows="4"
|
||||||
|
tabIndex="2"
|
||||||
|
value="some purpose"
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
className="input__help"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Describe how this channel should be used."
|
||||||
|
id="channel_modal.descriptionHelp"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="form-group less"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="col-sm-3"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
className="form__label control-label"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Header"
|
||||||
|
id="channel_modal.header"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<label
|
||||||
|
className="form__label light"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="(optional)"
|
||||||
|
id="channel_modal.optional"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="col-sm-9"
|
||||||
|
>
|
||||||
|
<textarea
|
||||||
|
className="form-control no-resize"
|
||||||
|
maxLength="1024"
|
||||||
|
onChange={[Function]}
|
||||||
|
placeholder="E.g.: \\"[Link Title](http://example.com)\\""
|
||||||
|
rows="4"
|
||||||
|
tabIndex="2"
|
||||||
|
value="some header"
|
||||||
|
/>
|
||||||
|
<p
|
||||||
|
className="input__help"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Set text that will appear in the header of the channel beside the channel name. For example, include frequently used links by typing [Link Title](http://example.com)."
|
||||||
|
id="channel_modal.headerHelp"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ModalBody>
|
||||||
|
<ModalFooter
|
||||||
|
bsClass="modal-footer"
|
||||||
|
componentClass="div"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
className="btn btn-default"
|
||||||
|
onClick={[Function]}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Cancel"
|
||||||
|
id="channel_modal.cancel"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="btn btn-primary"
|
||||||
|
onClick={[Function]}
|
||||||
|
tabIndex="3"
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Create New Channel"
|
||||||
|
id="channel_modal.createNew"
|
||||||
|
values={Object {}}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</ModalFooter>
|
||||||
|
</form>
|
||||||
|
</Modal>
|
||||||
|
</span>
|
||||||
|
`;
|
||||||
79
webapp/tests/components/new_channel_modal.test.jsx
Обычный файл
79
webapp/tests/components/new_channel_modal.test.jsx
Обычный файл
@@ -0,0 +1,79 @@
|
|||||||
|
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import {shallow} from 'enzyme';
|
||||||
|
|
||||||
|
import Constants from 'utils/constants.jsx';
|
||||||
|
|
||||||
|
import NewChannelModal from 'components/new_channel_modal/new_channel_modal.jsx';
|
||||||
|
|
||||||
|
describe('components/NewChannelModal', () => {
|
||||||
|
afterEach(() => {
|
||||||
|
global.window.mm_config = null;
|
||||||
|
global.window.mm_license = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should match snapshot, modal not showing', () => {
|
||||||
|
function emptyFunction() {} //eslint-disable-line no-empty-function
|
||||||
|
|
||||||
|
global.window.mm_license = {};
|
||||||
|
global.window.mm_license.IsLicensed = 'false';
|
||||||
|
|
||||||
|
const wrapper = shallow(
|
||||||
|
<NewChannelModal
|
||||||
|
show={true}
|
||||||
|
channelType={Constants.OPEN_CHANNEL}
|
||||||
|
channelData={{name: 'testchannel', displayName: 'testchannel', header: '', purpose: ''}}
|
||||||
|
onSubmitChannel={emptyFunction}
|
||||||
|
onModalDismissed={emptyFunction}
|
||||||
|
onTypeSwitched={emptyFunction}
|
||||||
|
onChangeURLPressed={emptyFunction}
|
||||||
|
onDataChanged={emptyFunction}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should match snapshot, modal showing', () => {
|
||||||
|
function emptyFunction() {} //eslint-disable-line no-empty-function
|
||||||
|
|
||||||
|
global.window.mm_license = {};
|
||||||
|
global.window.mm_license.IsLicensed = 'false';
|
||||||
|
|
||||||
|
const wrapper = shallow(
|
||||||
|
<NewChannelModal
|
||||||
|
show={true}
|
||||||
|
channelType={Constants.OPEN_CHANNEL}
|
||||||
|
channelData={{name: 'testchannel', displayName: 'testchannel', header: '', purpose: ''}}
|
||||||
|
onSubmitChannel={emptyFunction}
|
||||||
|
onModalDismissed={emptyFunction}
|
||||||
|
onTypeSwitched={emptyFunction}
|
||||||
|
onChangeURLPressed={emptyFunction}
|
||||||
|
onDataChanged={emptyFunction}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should match snapshot, private channel filled in header and purpose', () => {
|
||||||
|
function emptyFunction() {} //eslint-disable-line no-empty-function
|
||||||
|
|
||||||
|
global.window.mm_license = {};
|
||||||
|
global.window.mm_license.IsLicensed = 'false';
|
||||||
|
|
||||||
|
const wrapper = shallow(
|
||||||
|
<NewChannelModal
|
||||||
|
show={true}
|
||||||
|
channelType={Constants.PRIVATE_CHANNEL}
|
||||||
|
channelData={{name: 'testchannel', displayName: 'testchannel', header: 'some header', purpose: 'some purpose'}}
|
||||||
|
onSubmitChannel={emptyFunction}
|
||||||
|
onModalDismissed={emptyFunction}
|
||||||
|
onTypeSwitched={emptyFunction}
|
||||||
|
onChangeURLPressed={emptyFunction}
|
||||||
|
onDataChanged={emptyFunction}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
Ссылка в новой задаче
Block a user