Skip to content

Commit ce9c90d

Browse files
agarciamontorocrspeller
authored andcommitted
MM-33439: Fetch invited users independently (#486)
* Fetch invited users independently * Use getProfilesByIds * Add a comment clarifying the filter(u => u) idiom * Make useEffect do one thing: get the list of users
1 parent 03d1bff commit ce9c90d

File tree

1 file changed

+39
-26
lines changed

1 file changed

+39
-26
lines changed

webapp/src/components/backstage/automation/invite_users_selector.tsx

+39-26
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React, {FC, useState, useEffect} from 'react';
2+
import {useDispatch, useSelector} from 'react-redux';
23

34
import ReactSelect, {GroupType, ControlProps, OptionsType, MenuListComponentProps} from 'react-select';
45

@@ -7,6 +8,9 @@ import {Scrollbars} from 'react-custom-scrollbars';
78
import styled from 'styled-components';
89
import {ActionFunc} from 'mattermost-redux/types/actions';
910
import {UserProfile} from 'mattermost-redux/types/users';
11+
import {GlobalState} from 'mattermost-redux/types/store';
12+
import {getUser} from 'mattermost-redux/selectors/entities/users';
13+
import {getProfilesByIds} from 'mattermost-redux/actions/users';
1014

1115
import Profile from 'src/components/profile/profile';
1216

@@ -20,11 +24,14 @@ interface Props {
2024
}
2125

2226
const InviteUsersSelector: FC<Props> = (props: Props) => {
23-
// When there are no users invited, options is UserProfile[], a plain list. When there is at least one user invited,
24-
// options contains two groups: the first with invited members, the second with non invited members. This is needed
25-
// because groups are rendered in the selector list only when there is at least one user invited.
26-
const [options, setOptions] = useState<UserProfile[] | GroupType<UserProfile>[]>([]);
27+
const dispatch = useDispatch();
2728
const [searchTerm, setSearchTerm] = useState('');
29+
const invitedUsers = useSelector<GlobalState, UserProfile[]>((state: GlobalState) => props.userIds.map((id) => getUser(state, id)));
30+
const [searchedUsers, setSearchedUsers] = useState<UserProfile[]>([]);
31+
32+
useEffect(() => {
33+
dispatch(getProfilesByIds(props.userIds));
34+
}, [props.userIds]);
2835

2936
// Update the options whenever the passed user IDs or the search term are updated
3037
useEffect(() => {
@@ -38,34 +45,40 @@ const InviteUsersSelector: FC<Props> = (props: Props) => {
3845

3946
//@ts-ignore
4047
profiles.then(({data}: { data: UserProfile[] }) => {
41-
const invitedProfiles: UserProfile[] = [];
42-
const nonInvitedProfiles: UserProfile[] = [];
43-
44-
data.forEach((profile: UserProfile) => {
45-
if (props.userIds.includes(profile.id)) {
46-
invitedProfiles.push(profile);
47-
} else {
48-
nonInvitedProfiles.push(profile);
49-
}
50-
});
51-
52-
if (invitedProfiles.length === 0) {
53-
setOptions(nonInvitedProfiles);
54-
} else {
55-
setOptions([
56-
{label: 'INVITED MEMBERS', options: invitedProfiles},
57-
{label: 'NON INVITED MEMBERS', options: nonInvitedProfiles},
58-
]);
59-
}
60-
}).catch(() => {
61-
// eslint-disable-next-line no-console
62-
console.error('Error searching user profiles in custom attribute settings dropdown.');
48+
setSearchedUsers(data);
6349
});
6450
};
6551

6652
updateOptions(searchTerm);
6753
}, [props.userIds, searchTerm]);
6854

55+
let invitedProfiles: UserProfile[] = [];
56+
let nonInvitedProfiles: UserProfile[] = [];
57+
58+
if (searchTerm.trim().length === 0) {
59+
// Filter out all the undefined users, which will cast to false in the filter predicate
60+
invitedProfiles = invitedUsers.filter((user) => user);
61+
nonInvitedProfiles = searchedUsers.filter(
62+
(profile: UserProfile) => !props.userIds.includes(profile.id),
63+
);
64+
} else {
65+
searchedUsers.forEach((profile: UserProfile) => {
66+
if (props.userIds.includes(profile.id)) {
67+
invitedProfiles.push(profile);
68+
} else {
69+
nonInvitedProfiles.push(profile);
70+
}
71+
});
72+
}
73+
74+
let options: UserProfile[] | GroupType<UserProfile>[] = nonInvitedProfiles;
75+
if (invitedProfiles.length !== 0) {
76+
options = [
77+
{label: 'INVITED MEMBERS', options: invitedProfiles},
78+
{label: 'NON INVITED MEMBERS', options: nonInvitedProfiles},
79+
];
80+
}
81+
6982
let badgeContent = '';
7083
const numInvitedMembers = props.userIds.length;
7184
if (numInvitedMembers > 0) {

0 commit comments

Comments
 (0)