Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Commit

Permalink
Migrate team members modal to be pure and use Redux (#253)
Browse files Browse the repository at this point in the history
* Migrate team members modal to be pure and use Redux

* Add component tests
  • Loading branch information
tkbky authored and saturninoabril committed Nov 7, 2017
1 parent 475236a commit f80656d
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 29 deletions.
2 changes: 1 addition & 1 deletion components/popover_list_members/popover_list_members.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import * as Utils from 'utils/utils.jsx';
import ChannelInviteModal from 'components/channel_invite_modal';
import ChannelMembersModal from 'components/channel_members_modal.jsx';
import ProfilePicture from 'components/profile_picture.jsx';
import TeamMembersModal from 'components/team_members_modal.jsx';
import TeamMembersModal from 'components/team_members_modal';

export default class PopoverListMembers extends React.Component {
static propTypes = {
Expand Down
2 changes: 1 addition & 1 deletion components/sidebar_header_dropdown.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ import * as Utils from 'utils/utils.jsx';

import AboutBuildModal from 'components/about_build_modal';
import AddUsersToTeam from 'components/add_users_to_team';
import TeamMembersModal from 'components/team_members_modal';

import SidebarHeaderDropdownButton from './sidebar_header_dropdown_button.jsx';
import TeamMembersModal from './team_members_modal.jsx';

export default class SidebarHeaderDropdown extends React.Component {
static propTypes = {
Expand Down
2 changes: 1 addition & 1 deletion components/sidebar_right_menu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ import * as Utils from 'utils/utils.jsx';

import AboutBuildModal from 'components/about_build_modal';
import AddUsersToTeam from 'components/add_users_to_team';
import TeamMembersModal from 'components/team_members_modal';
import {createMenuTip} from 'components/tutorial/tutorial_tip.jsx';

import TeamMembersModal from './team_members_modal.jsx';
import ToggleModalButton from './toggle_modal_button.jsx';

const Preferences = Constants.Preferences;
Expand Down
17 changes: 17 additions & 0 deletions components/team_members_modal/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2017 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

import {connect} from 'react-redux';

import {getCurrentTeam} from 'mattermost-redux/selectors/entities/teams';

import TeamMembersModal from './team_members_modal.jsx';

function mapStateToProps(state, ownProps) {
return {
...ownProps,
currentTeam: getCurrentTeam(state)
};
}

export default connect(mapStateToProps)(TeamMembersModal);
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,53 @@ import React from 'react';
import {Modal} from 'react-bootstrap';
import {FormattedMessage} from 'react-intl';

import TeamStore from 'stores/team_store.jsx';

import MemberListTeam from 'components/member_list_team';

export default class TeamMembersModal extends React.Component {
constructor(props) {
super(props);
export default class TeamMembersModal extends React.PureComponent {
static propTypes = {

/**
* Current team object
*/
currentTeam: PropTypes.object.isRequired,

this.teamChanged = this.teamChanged.bind(this);
this.onHide = this.onHide.bind(this);
/**
* Function called when modal is dismissed
*/
onHide: PropTypes.func.isRequired,

/**
* Set if user is admin
*/
isAdmin: PropTypes.bool.isRequired,

/**
* Function called when modal is loaded
*/
onLoad: PropTypes.func
}

constructor(props) {
super(props);
this.state = {
team: TeamStore.getCurrent(),
show: true
};
}

componentDidMount() {
TeamStore.addChangeListener(this.teamChanged);
if (this.props.onLoad) {
this.props.onLoad();
}
}

componentWillUnmount() {
TeamStore.removeChangeListener(this.teamChanged);
}

teamChanged() {
this.setState({team: TeamStore.getCurrent()});
}

onHide() {
onHide = () => {
this.setState({show: false});
}

render() {
let teamDisplayName = '';
if (this.state.team) {
teamDisplayName = this.state.team.display_name;
if (this.props.currentTeam) {
teamDisplayName = this.props.currentTeam.display_name;
}

return (
Expand Down Expand Up @@ -75,9 +82,3 @@ export default class TeamMembersModal extends React.Component {
);
}
}

TeamMembersModal.propTypes = {
onHide: PropTypes.func.isRequired,
isAdmin: PropTypes.bool.isRequired,
onLoad: PropTypes.func
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`components/TeamMembersModal should match snapshot 1`] = `
<Modal
animation={true}
autoFocus={true}
backdrop={true}
bsClass="modal"
dialogClassName="more-modal"
dialogComponentClass={[Function]}
enforceFocus={true}
keyboard={true}
manager={
ModalManager {
"add": [Function],
"containers": Array [],
"data": Array [],
"handleContainerOverflow": true,
"hideSiblingNodes": true,
"isTopModal": [Function],
"modals": Array [],
"remove": [Function],
}
}
onExited={[Function]}
onHide={[Function]}
renderBackdrop={[Function]}
restoreFocus={true}
show={true}
>
<ModalHeader
bsClass="modal-header"
closeButton={true}
closeLabel="Close"
>
<ModalTitle
bsClass="modal-title"
componentClass="h4"
>
<FormattedMessage
defaultMessage="{team} Members"
id="team_member_modal.members"
values={
Object {
"team": "display name",
}
}
/>
</ModalTitle>
</ModalHeader>
<ModalBody
bsClass="modal-body"
componentClass="div"
>
<Connect(MemberListTeam)
isAdmin={false}
/>
</ModalBody>
</Modal>
`;
59 changes: 59 additions & 0 deletions tests/components/team_members_modal/team_members_modal.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

import React from 'react';
import {shallow} from 'enzyme';

import {Modal} from 'react-bootstrap';

import TeamMembersModal from 'components/team_members_modal/team_members_modal.jsx';

describe('components/TeamMembersModal', () => {
test('should match snapshot', () => {
function emptyFunction() {} //eslint-disable-line no-empty-function

const wrapper = shallow(
<TeamMembersModal
currentTeam={{display_name: 'display name'}}
onHide={emptyFunction}
onLoad={emptyFunction}
isAdmin={false}
/>
);

expect(wrapper).toMatchSnapshot();
});

test('should set show to false on Modal\'s onHide', () => {
function emptyFunction() {} //eslint-disable-line no-empty-function

const wrapper = shallow(
<TeamMembersModal
currentTeam={{display_name: 'display name'}}
onHide={emptyFunction}
onLoad={emptyFunction}
isAdmin={false}
/>
);

wrapper.find(Modal).first().props().onHide();
expect(wrapper.state('show')).toBe(false);
});

test('should call onHide on Modal\'s onExited', () => {
function emptyFunction() {} //eslint-disable-line no-empty-function
const onHide = jest.fn();

const wrapper = shallow(
<TeamMembersModal
currentTeam={{display_name: 'display name'}}
onHide={onHide}
onLoad={emptyFunction}
isAdmin={false}
/>
);

wrapper.find(Modal).first().props().onExited();
expect(onHide).toHaveBeenCalledTimes(1);
});
});

0 comments on commit f80656d

Please sign in to comment.