Skip to content

Commit

Permalink
Merge pull request #29044 from Samueljh1/main
Browse files Browse the repository at this point in the history
  • Loading branch information
francoisl authored Oct 12, 2023
2 parents fc44fb7 + 268be07 commit 5606309
Showing 1 changed file with 61 additions and 25 deletions.
86 changes: 61 additions & 25 deletions src/pages/workspace/WorkspaceInvitePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function WorkspaceInvitePage(props) {
const [searchTerm, setSearchTerm] = useState('');
const [selectedOptions, setSelectedOptions] = useState([]);
const [personalDetails, setPersonalDetails] = useState([]);
const [userToInvite, setUserToInvite] = useState(null);
const [usersToInvite, setUsersToInvite] = useState([]);
const openWorkspaceInvitePage = () => {
const policyMemberEmailsToAccountIDs = PolicyUtils.getMemberAccountIDsForWorkspace(props.policyMembers, props.personalDetails);
Policy.openWorkspaceInvitePage(props.route.params.policyID, _.keys(policyMemberEmailsToAccountIDs));
Expand All @@ -84,19 +84,52 @@ function WorkspaceInvitePage(props) {
const excludedUsers = useMemo(() => PolicyUtils.getIneligibleInvitees(props.policyMembers, props.personalDetails), [props.policyMembers, props.personalDetails]);

useEffect(() => {
const inviteOptions = OptionsListUtils.getMemberInviteOptions(props.personalDetails, props.betas, searchTerm, excludedUsers);

// Update selectedOptions with the latest personalDetails and policyMembers information
const detailsMap = {};
_.forEach(inviteOptions.personalDetails, (detail) => (detailsMap[detail.login] = OptionsListUtils.formatMemberForList(detail)));
const newSelectedOptions = [];
_.forEach(selectedOptions, (option) => {
newSelectedOptions.push(_.has(detailsMap, option.login) ? {...detailsMap[option.login], isSelected: true} : option);
const emails = _.compact(
searchTerm
.trim()
.replace(/\s*,\s*/g, ',')
.split(','),
);

const newUsersToInviteDict = {};
const newPersonalDetailsDict = {};
const newSelectedOptionsDict = {};

_.each(emails, (email) => {
const inviteOptions = OptionsListUtils.getMemberInviteOptions(props.personalDetails, props.betas, email, excludedUsers);

// Update selectedOptions with the latest personalDetails and policyMembers information
const detailsMap = {};
_.each(inviteOptions.personalDetails, (detail) => (detailsMap[detail.login] = OptionsListUtils.formatMemberForList(detail)));

const newSelectedOptions = [];
_.each(selectedOptions, (option) => {
newSelectedOptions.push(_.has(detailsMap, option.login) ? {...detailsMap[option.login], isSelected: true} : option);
});

const userToInvite = inviteOptions.userToInvite;

// Only add the user to the invites list if it is valid
if (userToInvite) {
newUsersToInviteDict[userToInvite.accountID] = userToInvite;
}

// Add all personal details to the new dict
_.each(inviteOptions.personalDetails, (details) => {
newPersonalDetailsDict[details.accountID] = details;
});

// Add all selected options to the new dict
_.each(newSelectedOptions, (option) => {
newSelectedOptionsDict[option.accountID] = option;
});
});

setUserToInvite(inviteOptions.userToInvite);
setPersonalDetails(inviteOptions.personalDetails);
setSelectedOptions(newSelectedOptions);
// Strip out dictionary keys and update arrays
setUsersToInvite(_.values(newUsersToInviteDict));
setPersonalDetails(_.values(newPersonalDetailsDict));
setSelectedOptions(_.values(newSelectedOptionsDict));

// eslint-disable-next-line react-hooks/exhaustive-deps -- we don't want to recalculate when selectedOptions change
}, [props.personalDetails, props.policyMembers, props.betas, searchTerm, excludedUsers]);

Expand All @@ -116,7 +149,6 @@ function WorkspaceInvitePage(props) {
const selectedLogins = _.map(selectedOptions, ({login}) => login);
const personalDetailsWithoutSelected = _.filter(personalDetails, ({login}) => !_.contains(selectedLogins, login));
const personalDetailsFormatted = _.map(personalDetailsWithoutSelected, OptionsListUtils.formatMemberForList);
const hasUnselectedUserToInvite = userToInvite && !_.contains(selectedLogins, userToInvite.login);

sections.push({
title: translate('common.contacts'),
Expand All @@ -126,14 +158,18 @@ function WorkspaceInvitePage(props) {
});
indexOffset += personalDetailsFormatted.length;

if (hasUnselectedUserToInvite) {
sections.push({
title: undefined,
data: [OptionsListUtils.formatMemberForList(userToInvite)],
shouldShow: true,
indexOffset,
});
}
_.each(usersToInvite, (userToInvite) => {
const hasUnselectedUserToInvite = !_.contains(selectedLogins, userToInvite.login);

if (hasUnselectedUserToInvite) {
sections.push({
title: undefined,
data: [OptionsListUtils.formatMemberForList(userToInvite)],
shouldShow: true,
indexOffset: indexOffset++,
});
}
});

return sections;
};
Expand Down Expand Up @@ -188,14 +224,14 @@ function WorkspaceInvitePage(props) {

const headerMessage = useMemo(() => {
const searchValue = searchTerm.trim().toLowerCase();
if (!userToInvite && CONST.EXPENSIFY_EMAILS.includes(searchValue)) {
if (usersToInvite.length === 0 && CONST.EXPENSIFY_EMAILS.includes(searchValue)) {
return translate('messages.errorMessageInvalidEmail');
}
if (!userToInvite && excludedUsers.includes(searchValue)) {
if (usersToInvite.length === 0 && excludedUsers.includes(searchValue)) {
return translate('messages.userIsAlreadyMemberOfWorkspace', {login: searchValue, workspace: policyName});
}
return OptionsListUtils.getHeaderMessage(personalDetails.length !== 0, Boolean(userToInvite), searchValue);
}, [excludedUsers, translate, searchTerm, policyName, userToInvite, personalDetails]);
return OptionsListUtils.getHeaderMessage(personalDetails.length !== 0, usersToInvite.length > 0, searchValue);
}, [excludedUsers, translate, searchTerm, policyName, usersToInvite, personalDetails]);

return (
<ScreenWrapper
Expand Down

0 comments on commit 5606309

Please sign in to comment.