Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved error message handling when searching for multiple emails #29549

Closed
wants to merge 12 commits into from
Closed
1 change: 1 addition & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1209,6 +1209,7 @@ export default {
messages: {
errorMessageInvalidPhone: `Please enter a valid phone number without brackets or dashes. If you're outside the US please include your country code (e.g. ${CONST.EXAMPLE_PHONE_NUMBER}).`,
errorMessageInvalidEmail: 'Invalid email',
errorMessageAllInviteesInvalid: 'All of the invitees are invalid or have been invited already',
userIsAlreadyMember: ({login, name}: UserIsAlreadyMemberParams) => `${login} is already a member of ${name}`,
},
onfidoStep: {
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1226,6 +1226,7 @@ export default {
messages: {
errorMessageInvalidPhone: `Por favor, introduce un número de teléfono válido sin paréntesis o guiones. Si reside fuera de Estados Unidos, por favor incluye el prefijo internacional (p. ej. ${CONST.EXAMPLE_PHONE_NUMBER}).`,
errorMessageInvalidEmail: 'Email inválido',
errorMessageAllInviteesInvalid: 'Todos los invitados son inválidos o ya han sido invitados',
userIsAlreadyMember: ({login, name}: UserIsAlreadyMemberParams) => `${login} ya es miembro de ${name}`,
},
onfidoStep: {
Expand Down
70 changes: 45 additions & 25 deletions src/pages/workspace/WorkspaceInvitePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,23 +84,29 @@ function WorkspaceInvitePage(props) {

const excludedUsers = useMemo(() => PolicyUtils.getIneligibleInvitees(props.policyMembers, props.personalDetails), [props.policyMembers, props.personalDetails]);

useEffect(() => {
let emails = _.compact(
searchTerm
.trim()
.replace(/\s*,\s*/g, ',')
.split(','),
);

if (emails.length === 0) {
emails = [''];
}
const searchEmails = useMemo(
() =>
_.compact(
searchTerm
.trim()
.replace(/\s*,\s*/g, ',')
.split(','),
),
[searchTerm],
);

useEffect(() => {
const newUsersToInviteDict = {};
const newPersonalDetailsDict = {};
const newSelectedOptionsDict = {};

_.each(emails, (email) => {
let emails = searchEmails;

if (searchEmails.length === 0) {
// This ensures suggestions are displayed when there is no search term
emails = [''];
}

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

// Update selectedOptions with the latest personalDetails and policyMembers information
Expand All @@ -119,10 +125,10 @@ function WorkspaceInvitePage(props) {
newUsersToInviteDict[userToInvite.accountID] = userToInvite;
}

// Add all personal details to the new dict
_.each(inviteOptions.personalDetails, (details) => {
newPersonalDetailsDict[details.accountID] = details;
});
// Only show contact suggestions for the last search term
if (i === emails.length - 1) {
setPersonalDetails(inviteOptions.personalDetails);
}

// Add all selected options to the new dict
_.each(newSelectedOptions, (option) => {
Expand All @@ -132,11 +138,10 @@ function WorkspaceInvitePage(props) {

// 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]);
}, [props.personalDetails, props.policyMembers, props.betas, searchEmails, excludedUsers]);

const getSections = () => {
const sections = [];
Expand Down Expand Up @@ -229,14 +234,29 @@ function WorkspaceInvitePage(props) {

const headerMessage = useMemo(() => {
const searchValue = searchTerm.trim().toLowerCase();
if (usersToInvite.length === 0 && CONST.EXPENSIFY_EMAILS.includes(searchValue)) {
return translate('messages.errorMessageInvalidEmail');
}
if (usersToInvite.length === 0 && excludedUsers.includes(searchValue)) {
return translate('messages.userIsAlreadyMember', {login: searchValue, name: policyName});

if (usersToInvite.length === 0) {
// Handle errors when a single email is specified
if (searchEmails.length === 1) {
const email = _.first(searchEmails);

if (CONST.EXPENSIFY_EMAILS.includes(email)) {
return translate('messages.errorMessageInvalidEmail');
}

if (excludedUsers.includes(email)) {
return translate('messages.userIsAlreadyMember', {login: searchValue, name: policyName});
}
}

// Handle errors when multiple emails are specified
if (searchEmails.length > 1 && personalDetails.length === 0) {
return translate('messages.errorMessageAllInviteesInvalid');
}
}

return OptionsListUtils.getHeaderMessage(personalDetails.length !== 0, usersToInvite.length > 0, searchValue);
}, [excludedUsers, translate, searchTerm, policyName, usersToInvite, personalDetails.length]);
}, [excludedUsers, translate, searchTerm, searchEmails, policyName, usersToInvite, personalDetails]);

return (
<ScreenWrapper
Expand Down
Loading