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

Commit

Permalink
MM-12710 Migration of team_actions to redux (#1930)
Browse files Browse the repository at this point in the history
* MM-12710 Migrate team_actions to redux

  * removeUserFromTeam(Updated)
  * addUserToTeamFromInvite(Updated)
  * addUsersToTeam(Updated)
  * getInviteInfo(Removed using a redux action instead)
  * switchTeams(Updated)
  * inviteMembers(Removed using a redux action instead)
  * Move removeUserFromTeam to manage_teams_modal
   * Fix for a test issue found where userId is being passed instead of testId
  • Loading branch information
sudheerDev committed Nov 20, 2018
1 parent 6512c40 commit 0d2442e
Show file tree
Hide file tree
Showing 28 changed files with 367 additions and 284 deletions.
94 changes: 25 additions & 69 deletions actions/team_actions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,26 @@ import {TeamTypes} from 'mattermost-redux/action_types';
import {viewChannel, getChannelStats} from 'mattermost-redux/actions/channels';
import * as TeamActions from 'mattermost-redux/actions/teams';
import {getCurrentChannelId} from 'mattermost-redux/selectors/entities/channels';
import {getCurrentTeamId} from 'mattermost-redux/selectors/entities/teams';
import {getUser} from 'mattermost-redux/actions/users';
import {Client4} from 'mattermost-redux/client';

import {browserHistory} from 'utils/browser_history';
import store from 'stores/redux_store.jsx';

const dispatch = store.dispatch;
const getState = store.getState;

export async function removeUserFromTeam(teamId, userId, success, error) {
const {data, error: err} = await dispatch(TeamActions.removeUserFromTeam(teamId, userId));
dispatch(getUser(userId));
dispatch(TeamActions.getTeamStats(teamId));
dispatch(getChannelStats(getCurrentChannelId(getState())));

if (data && success) {
success();
} else if (err && error) {
error({id: err.server_error_id, ...err});
}
export function removeUserFromTeam(teamId, userId) {
return async (dispatch, getState) => {
const response = await dispatch(TeamActions.removeUserFromTeam(teamId, userId));
dispatch(getUser(userId));
dispatch(TeamActions.getTeamStats(teamId));
dispatch(getChannelStats(getCurrentChannelId(getState())));
return response;
};
}

export function addUserToTeamFromInvite(token, inviteId, success, error) {
Client4.addToTeamFromInvite(token, inviteId).then(
async (member) => {
const {data: team} = await TeamActions.getTeam(member.team_id)(dispatch, getState);
export function addUserToTeamFromInvite(token, inviteId) {
return async (dispatch) => {
const {data: member, error} = await dispatch(TeamActions.addUserToTeamFromInvite(token, inviteId));
if (member) {
const {data} = await dispatch(TeamActions.getTeam(member.team_id));

dispatch({
type: TeamTypes.RECEIVED_MY_TEAM_MEMBER,
data: {
Expand All @@ -42,66 +35,29 @@ export function addUserToTeamFromInvite(token, inviteId, success, error) {
},
});

if (success) {
success(team);
}
return {data};
}
).catch(
(err) => {
if (error) {
error(err);
}
}
);
return {error};
};
}

export function addUsersToTeam(teamId, userIds) {
return async (doDispatch, doGetState) => {
const {data, error} = await doDispatch(TeamActions.addUsersToTeam(teamId, userIds));
return async (dispatch, getState) => {
const {data, error} = await dispatch(TeamActions.addUsersToTeam(teamId, userIds));

if (error) {
return {error};
}

doDispatch(getChannelStats(doGetState().entities.channels.currentChannelId));
dispatch(getChannelStats(getCurrentChannelId(getState())));

return {data};
};
}

export function getInviteInfo(inviteId, success, error) {
Client4.getTeamInviteInfo(inviteId).then(
(inviteData) => {
if (success) {
success(inviteData);
}
}
).catch(
(err) => {
if (error) {
error(err);
}
}
);
}

export async function inviteMembers(data, success, error) {
if (!data.invites) {
success();
}
const emails = [];
data.invites.forEach((i) => {
emails.push(i.email);
});
const {data: result, error: err} = await dispatch(TeamActions.sendEmailInvitesToTeam(getCurrentTeamId(getState()), emails));
if (result && success) {
success();
} else if (result == null && error) {
error({id: err.server_error_id, ...err});
}
}

export function switchTeams(url) {
dispatch(viewChannel(getCurrentChannelId(getState())));
browserHistory.push(url);
export function switchTeam(url) {
return (dispatch, getState) => {
dispatch(viewChannel(getCurrentChannelId(getState())));
browserHistory.push(url);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,9 @@ exports[`ManageTeamsModal should save data in state from api calls 1`] = `
className="manage-teams__team-actions"
>
<ManageTeamsDropdown
handleRemoveUserFromTeam={[Function]}
onError={[Function]}
onMemberChange={[Function]}
onMemberRemove={[Function]}
team={
Object {
"delete_at": 0,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`RemoveFromTeamButton should match snapshot init 1`] = `
<button
className="btn btn-danger"
onClick={[Function]}
>
<FormattedMessage
defaultMessage="Remove from Team"
id="team_members_dropdown.leave_team"
values={Object {}}
/>
</button>
`;
2 changes: 2 additions & 0 deletions components/admin_console/manage_teams_modal/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {bindActionCreators} from 'redux';

import {updateTeamMemberSchemeRoles, getTeamMembersForUser, getTeamsForUser} from 'mattermost-redux/actions/teams';

import {removeUserFromTeam} from 'actions/team_actions.jsx';
import {getCurrentLocale} from 'selectors/i18n';

import ManageTeamsModal from './manage_teams_modal';
Expand All @@ -22,6 +23,7 @@ function mapDispatchToProps(dispatch) {
getTeamMembersForUser,
getTeamsForUser,
updateTeamMemberSchemeRoles,
removeUserFromTeam,
}, dispatch),
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import React from 'react';
import {Dropdown, MenuItem} from 'react-bootstrap';
import {FormattedMessage} from 'react-intl';

import {removeUserFromTeam} from 'actions/team_actions.jsx';
import * as Utils from 'utils/utils.jsx';

export default class ManageTeamsDropdown extends React.Component {
Expand All @@ -15,19 +14,16 @@ export default class ManageTeamsDropdown extends React.Component {
teamMember: PropTypes.object.isRequired,
onError: PropTypes.func.isRequired,
onMemberChange: PropTypes.func.isRequired,
onMemberRemove: PropTypes.func.isRequired,
updateTeamMemberSchemeRoles: PropTypes.func.isRequired,
handleRemoveUserFromTeam: PropTypes.func.isRequired,
};

constructor(props) {
super(props);

this.toggleDropdown = this.toggleDropdown.bind(this);

this.removeFromTeam = this.removeFromTeam.bind(this);

this.handleMemberChange = this.handleMemberChange.bind(this);
this.handleMemberRemove = this.handleMemberRemove.bind(this);

this.state = {
show: false,
Expand Down Expand Up @@ -58,23 +54,14 @@ export default class ManageTeamsDropdown extends React.Component {
}
};

removeFromTeam() {
removeUserFromTeam(
this.props.teamMember.team_id,
this.props.user.id,
this.handleMemberRemove,
this.props.onError
);
removeFromTeam = () => {
this.props.handleRemoveUserFromTeam(this.props.teamMember.team_id);
}

handleMemberChange() {
this.props.onMemberChange(this.props.teamMember.team_id);
}

handleMemberRemove() {
this.props.onMemberRemove(this.props.teamMember.team_id);
}

render() {
const isTeamAdmin = Utils.isAdmin(this.props.teamMember.roles) || this.props.teamMember.scheme_admin;

Expand Down
20 changes: 15 additions & 5 deletions components/admin_console/manage_teams_modal/manage_teams_modal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default class ManageTeamsModal extends React.Component {
getTeamMembersForUser: PropTypes.func.isRequired,
getTeamsForUser: PropTypes.func.isRequired,
updateTeamMemberSchemeRoles: PropTypes.func.isRequired,
removeUserFromTeam: PropTypes.func.isRequired,
}).isRequired,
};

Expand Down Expand Up @@ -89,6 +90,17 @@ export default class ManageTeamsModal extends React.Component {
});
}

handleRemoveUserFromTeam = async (teamId) => {
const {actions, user} = this.props;

const {data, error} = await actions.removeUserFromTeam(teamId, user.id);
if (data) {
this.handleMemberRemove(teamId);
} else if (error) {
this.handleError(error.message);
}
}

renderContents = () => {
const {user} = this.props;
const {teams, teamMembers} = this.state;
Expand Down Expand Up @@ -118,10 +130,8 @@ export default class ManageTeamsModal extends React.Component {
if (isSystemAdmin) {
action = (
<RemoveFromTeamButton
user={user}
team={team}
onError={this.handleError}
onMemberRemove={this.handleMemberRemove}
teamId={team.id}
handleRemoveUserFromTeam={this.handleRemoveUserFromTeam}
/>
);
} else {
Expand All @@ -132,8 +142,8 @@ export default class ManageTeamsModal extends React.Component {
teamMember={teamMember}
onError={this.handleError}
onMemberChange={this.getTeamMembers}
onMemberRemove={this.handleMemberRemove}
updateTeamMemberSchemeRoles={this.props.actions.updateTeamMemberSchemeRoles}
handleRemoveUserFromTeam={this.handleRemoveUserFromTeam}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ describe('ManageTeamsModal', () => {
getTeamMembersForUser: jest.fn().mockReturnValue(Promise.resolve({data: []})),
getTeamsForUser: jest.fn().mockReturnValue(Promise.resolve({data: []})),
updateTeamMemberSchemeRoles: jest.fn(),
removeUserFromTeam: jest.fn(),
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,15 @@ import PropTypes from 'prop-types';
import React from 'react';
import {FormattedMessage} from 'react-intl';

import {removeUserFromTeam} from 'actions/team_actions.jsx';

export default class RemoveFromTeamButton extends React.PureComponent {
static propTypes = {
onError: PropTypes.func.isRequired,
onMemberRemove: PropTypes.func.isRequired,
team: PropTypes.object.isRequired,
user: PropTypes.object.isRequired,
teamId: PropTypes.string.isRequired,
handleRemoveUserFromTeam: PropTypes.func.isRequired,
};

constructor(props) {
super(props);

this.handleClick = this.handleClick.bind(this);
this.handleMemberRemove = this.handleMemberRemove.bind(this);
}

handleClick(e) {
handleClick = (e) => {
e.preventDefault();

removeUserFromTeam(
this.props.team.id,
this.props.user.id,
this.handleMemberRemove,
this.props.onError
);
}

handleMemberRemove() {
this.props.onMemberRemove(this.props.team.id);
this.props.handleRemoveUserFromTeam(this.props.teamId);
}

render() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

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

import RemoveFromTeamButton from 'components/admin_console/manage_teams_modal/remove_from_team_button.jsx';

describe('RemoveFromTeamButton', () => {
const baseProps = {
teamId: '1234',
handleRemoveUserFromTeam: jest.fn(),
};

test('should match snapshot init', () => {
const wrapper = shallow(
<RemoveFromTeamButton {...baseProps}/>
);

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

test('should call handleRemoveUserFromTeam on button click', () => {
const wrapper = shallow(
<RemoveFromTeamButton {...baseProps}/>
);
wrapper.find('button').prop('onClick')({preventDefault: jest.fn()});
expect(baseProps.handleRemoveUserFromTeam).toHaveBeenCalledTimes(1);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ describe('components/admin_console/system_users/list', () => {
updateTeamMemberSchemeRoles: jest.fn(),
getTeamMembersForUser: jest.fn(),
getTeamsForUser: jest.fn(),
removeUserFromTeam: jest.fn(),
},
};

Expand Down
14 changes: 13 additions & 1 deletion components/invite_member_modal/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
// See LICENSE.txt for license information.

import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';

import {sendEmailInvitesToTeam} from 'mattermost-redux/actions/teams';
import {getConfig} from 'mattermost-redux/selectors/entities/general';
import {getChannelsNameMapInCurrentTeam} from 'mattermost-redux/selectors/entities/channels';
import {getCurrentUser} from 'mattermost-redux/selectors/entities/users';
Expand All @@ -26,7 +29,16 @@ function mapStateToProps(state) {
currentUser: getCurrentUser(state),
defaultChannelName: defaultChannel ? defaultChannel.display_name : '',
teamType: team ? team.type : '',
teamId: team ? team.id : '',
};
}

function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
sendEmailInvitesToTeam,
}, dispatch),
};
}

export default connect(mapStateToProps)(InviteMemberModal);
export default connect(mapStateToProps, mapDispatchToProps)(InviteMemberModal);
Loading

0 comments on commit 0d2442e

Please sign in to comment.