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

[MM-12743] Migrate loadProfilesAndTeamMembers of user actions into redux-style #2017

Merged
merged 3 commits into from
Nov 23, 2018
Merged

[MM-12743] Migrate loadProfilesAndTeamMembers of user actions into redux-style #2017

merged 3 commits into from
Nov 23, 2018

Conversation

saturninoabril
Copy link
Member

@saturninoabril saturninoabril commented Nov 7, 2018

Summary

This PR migrates the following user_actions into redux-style:

  • loadProfilesAndTeamMembers
  • loadProfilesAndTeamMembersAndChannelMembers
  • loadTeamMembersForProfilesList
  • loadTeamMembersAndChannelMembersForProfilesList
  • loadChannelMembersForProfilesList

and removed the following since it's not being used elsewhere:

  • loadChannelMembersForProfilesMap

Affected Area:

  • Viewing team members at "Main Menu > View Members"
  • Viewing system users at "System Console > Users"
  • And paging and searching to those pages/modal

@DHaussermann Above were tested and looks good.

Ticket Link

Jira ticket: MM-12743

Checklist

  • Ran make check-style to check for style errors (required for all pull requests)
  • Ran make test to ensure unit and component tests passed
  • Added or updated unit tests (required for all new features)

@saturninoabril saturninoabril added the 2: Dev Review Requires review by a core commiter label Nov 7, 2018
@saturninoabril saturninoabril added this to the v5.6.0 milestone Nov 7, 2018
actualActions = testStore.getActions();
expect(actualActions[0].args).toEqual(expectedActions[0].args);
expect(actualActions[0].type).toEqual(expectedActions[0].type);
});
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, can't do much testing as I'm not able to spy on below codeblock. Maybe, it's something to think about on how to do it.

if (data) {
    loadTeamMembersForProfilesList(data, newTeamId, success);
    doDispatch(loadStatusesForProfilesList(data));
}

const {data} = await UserActions.getProfilesInTeam(teamId, page, perPage)(dispatch, getState);
loadTeamMembersForProfilesList(data, teamId, success);
dispatch(loadStatusesForProfilesList(data));
export function loadProfilesAndTeamMembers(page, perPage, teamId = getCurrentTeamId(getState()), success) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove the default argument here? That's using the global state which is going to get confusing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, sorry about this, I thought I removed it.

@@ -40,10 +40,15 @@ export async function switchFromLdapToEmail(email, password, token, ldapPassword
}
}

export async function loadProfilesAndTeamMembers(page, perPage, teamId = getCurrentTeamId(getState()), success) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove the success callback and have callers use .then(success) instead?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we're passing it to loadTeamMembersForProfilesList and you're not changing that function right now, we can get around that for now by explicitly returning an explicit Promise instead of using an async function for the body of the action like

function doSomething() {
    return (dispatch, getState) => {
        return new Promise((resolve) => {
            loadTeamMembersForProfilesList(resolve);
        });
    };
);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @hmhealey! I managed to remove success and error callbacks (although error callback is really not being used elsewhere). Could you please take a look again?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really surprised. We probably just added success and error for consistency with all the other actions

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is working properly, I'm ok with it, but looks like this is not exactly the same behavior under the hood. Here, the promise is resolved when the getProfilesInTeam is success, in the previous implementation it the success call was made after the loadTeamMembersForProfilesList.

Copy link
Member Author

@saturninoabril saturninoabril Nov 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's working properly after testing several cases, and yes, it's a bit different since it only dispatches loadTeamMembersForProfilesList and loadStatusesForProfilesList after success call in getProfilesInTeam which I believe makes sense.
The loadProfilesAndTeamMembers returns {data: true} which can be consumed when a callback is necessary.

}
}

export function loadChannelMembersForProfilesMap(profiles, channelId = getCurrentChannelId(getState()), success, error) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

loadChannelMembersForProfilesMap is not being used elsewhere.

const channelIdParam = channelId || getCurrentChannelId(state);
const {data} = await doDispatch(UserActions.getProfilesInChannel(channelIdParam, page, perPage));
if (data) {
doDispatch(loadTeamMembersForProfilesList(data, teamIdParam)).then(() => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use await there (I think) instead of .then.


loadTeamMembersForProfiles(list, teamId, success, error);
doDispatch(getTeamMembersByIds(teamIdParam, userIdsToLoad));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, the .then is called before the getTeamMembersByIds returns, with the other implementation is called after it returns. It can be solved adding an await here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. I'll add it.

const state = doGetState();
const teamIdParam = teamId || getCurrentTeamId(state);
const channelIdParam = channelId || getCurrentChannelId(state);
doDispatch(loadTeamMembersForProfilesList(profiles, teamIdParam)).then(() => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use await here, I think.

success(result.data);
}
});
doDispatch(getChannelMembersByIds(channelIdParam, list));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't await here, we are returning on .then before the getChannelMembersById action is run.

@@ -116,7 +115,12 @@ export default class SystemUsers extends React.Component {
} else if (teamId === SearchUserTeamFilter.NO_TEAM) {
loadProfilesWithoutTeam(0, Constants.PROFILE_CHUNK_SIZE, this.loadComplete);
} else {
loadProfilesAndTeamMembers(0, Constants.PROFILE_CHUNK_SIZE, teamId, this.loadComplete);
this.props.actions.loadProfilesAndTeamMembers(0, Constants.PROFILE_CHUNK_SIZE, teamId).then(({data}) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you going to use async you should use await here, if not, you can leave the function without async and handle here the promise. I prefer the former option.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I totally missed that. I'll use the async/await.

// Paging isn't supported while searching

if (this.props.teamId === SearchUserTeamFilter.ALL_USERS) {
loadProfiles(page + 1, USERS_PER_PAGE, this.loadComplete);
} else if (this.props.teamId === SearchUserTeamFilter.NO_TEAM) {
loadProfilesWithoutTeam(page + 1, USERS_PER_PAGE, this.loadComplete);
} else {
loadProfilesAndTeamMembers(page + 1, USERS_PER_PAGE, this.props.teamId, this.loadComplete);
this.props.actions.loadProfilesAndTeamMembers(page + 1, USERS_PER_PAGE, this.props.teamId).then(({data}) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, if this not propage the async to other functions, makes sense to keep this function consistent with the loadDataForTeam function. I mean, set the function as async and use await instead of .then.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, changing since I'm 0/5 with that and yours make sense 💯

Copy link
Member

@jespino jespino left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general looks good to me, but I see some inconsistencies and subtle changes of behavior in the async requests. Maybe I'm wrong, but I prefer to clarify it before we merge :)

@saturninoabril
Copy link
Member Author

Thanks @jespino for your feedbacks, please take a look again.

@saturninoabril saturninoabril merged commit b3edb1f into mattermost:master Nov 23, 2018
@amyblais amyblais added Changelog/Done Required changelog entry has been written Docs/Not Needed Does not require documentation labels Nov 23, 2018
@saturninoabril saturninoabril deleted the MM-12743-loadProfilesAndTeamMembers branch November 24, 2018 00:46
@lindy65 lindy65 added Tests/Done Release tests have been written and removed 2: Dev Review Requires review by a core commiter labels Dec 4, 2018
@JtheBAB JtheBAB mentioned this pull request Jan 15, 2019
9 tasks
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Changelog/Done Required changelog entry has been written Docs/Not Needed Does not require documentation Tests/Done Release tests have been written
Projects
None yet
5 participants