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

feat: Add an "Invite" button to the workspace profile page #53719

Merged
merged 8 commits into from
Dec 24, 2024
4 changes: 2 additions & 2 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -702,11 +702,11 @@ const ROUTES = {
},
WORKSPACE_INVITE: {
route: 'settings/workspaces/:policyID/invite',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/invite` as const,
getRoute: (policyID: string, backTo?: string) => `${getUrlWithBackToParam(`settings/workspaces/${policyID}/invite`, backTo)}` as const,
},
WORKSPACE_INVITE_MESSAGE: {
route: 'settings/workspaces/:policyID/invite-message',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/invite-message` as const,
getRoute: (policyID: string, backTo?: string) => `${getUrlWithBackToParam(`settings/workspaces/${policyID}/invite-message`, backTo)}` as const,
},
WORKSPACE_PROFILE: {
route: 'settings/workspaces/:policyID/profile',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial<Record<FullScreenName, string[]>> = {
SCREENS.WORKSPACE.DOWNGRADE,
],
[SCREENS.WORKSPACE.MEMBERS]: [
SCREENS.WORKSPACE.INVITE,
SCREENS.WORKSPACE.INVITE_MESSAGE,
SCREENS.WORKSPACE.MEMBER_DETAILS,
SCREENS.WORKSPACE.MEMBER_NEW_CARD,
SCREENS.WORKSPACE.OWNER_CHANGE_CHECK,
Expand Down
2 changes: 2 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ type SettingsNavigatorParamList = {
[SCREENS.WORKSPACE.SHARE]: undefined;
[SCREENS.WORKSPACE.INVITE]: {
policyID: string;
backTo?: Routes;
};
[SCREENS.WORKSPACE.MEMBERS_IMPORT]: {
policyID: string;
Expand All @@ -199,6 +200,7 @@ type SettingsNavigatorParamList = {
};
[SCREENS.WORKSPACE.INVITE_MESSAGE]: {
policyID: string;
backTo?: Routes;
};
[SCREENS.WORKSPACE.CATEGORY_CREATE]: {
policyID: string;
Expand Down
11 changes: 8 additions & 3 deletions src/pages/workspace/WorkspaceInviteMessagePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ function WorkspaceInviteMessagePage({policy, route, currentUserPersonalDetails}:
if (isEmptyObject(policy)) {
return;
}
Navigation.goBack(ROUTES.WORKSPACE_INVITE.getRoute(route.params.policyID), true);
Navigation.goBack(ROUTES.WORKSPACE_INVITE.getRoute(route.params.policyID, route.params.backTo), true);
// eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
}, [isOnyxLoading]);

Expand All @@ -103,7 +103,12 @@ function WorkspaceInviteMessagePage({policy, route, currentUserPersonalDetails}:
Member.addMembersToWorkspace(invitedEmailsToAccountIDsDraft ?? {}, `${welcomeNoteSubject}\n\n${welcomeNote}`, route.params.policyID, policyMemberAccountIDs);
Policy.setWorkspaceInviteMessageDraft(route.params.policyID, welcomeNote ?? null);
FormActions.clearDraftValues(ONYXKEYS.FORMS.WORKSPACE_INVITE_MESSAGE_FORM);
Navigation.dismissModal();
if ((route.params?.backTo as string)?.endsWith('members')) {
Navigation.setNavigationActionToMicrotaskQueue(() => Navigation.dismissModal());

return;
}
Navigation.setNavigationActionToMicrotaskQueue(() => Navigation.navigate(ROUTES.WORKSPACE_MEMBERS.getRoute(route.params.policyID)));
};

/** Opens privacy url as an external link */
Expand Down Expand Up @@ -141,7 +146,7 @@ function WorkspaceInviteMessagePage({policy, route, currentUserPersonalDetails}:
guidesCallTaskID={CONST.GUIDES_CALL_TASK_IDS.WORKSPACE_MEMBERS}
shouldShowBackButton
onCloseButtonPress={() => Navigation.dismissModal()}
onBackButtonPress={() => Navigation.goBack(ROUTES.WORKSPACE_INVITE.getRoute(route.params.policyID))}
onBackButtonPress={() => Navigation.goBack(ROUTES.WORKSPACE_INVITE.getRoute(route.params.policyID, route.params.backTo))}
/>
<FormProvider
style={[styles.flexGrow1, styles.ph5]}
Expand Down
4 changes: 2 additions & 2 deletions src/pages/workspace/WorkspaceInvitePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -242,14 +242,14 @@ function WorkspaceInvitePage({route, policy}: WorkspaceInvitePageProps) {
const invitedEmailsToAccountIDs: InvitedEmailsToAccountIDs = {};
selectedOptions.forEach((option) => {
const login = option.login ?? '';
const accountID = option.accountID ?? '-1';
const accountID = option.accountID ?? CONST.DEFAULT_NUMBER_ID;
if (!login.toLowerCase().trim() || !accountID) {
return;
}
invitedEmailsToAccountIDs[login] = Number(accountID);
});
Member.setWorkspaceInviteMembersDraft(route.params.policyID, invitedEmailsToAccountIDs);
Navigation.navigate(ROUTES.WORKSPACE_INVITE_MESSAGE.getRoute(route.params.policyID));
Navigation.navigate(ROUTES.WORKSPACE_INVITE_MESSAGE.getRoute(route.params.policyID, Navigation.getActiveRoute()));
}, [route.params.policyID, selectedOptions]);

const [policyName, shouldShowAlertPrompt] = useMemo(() => [policy?.name ?? '', !isEmptyObject(policy?.errors) || !!policy?.alertMessage], [policy]);
Expand Down
2 changes: 1 addition & 1 deletion src/pages/workspace/WorkspaceMembersPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ function WorkspaceMembersPage({personalDetails, route, policy, currentUserPerson
*/
const inviteUser = () => {
clearInviteDraft();
Navigation.navigate(ROUTES.WORKSPACE_INVITE.getRoute(route.params.policyID));
Navigation.navigate(ROUTES.WORKSPACE_INVITE.getRoute(route.params.policyID, Navigation.getActiveRouteWithoutParams()));
};

/**
Expand Down
10 changes: 10 additions & 0 deletions src/pages/workspace/WorkspaceProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ function WorkspaceProfilePage({policyDraft, policy: policyProp, route}: Workspac

// When we create a new workspace, the policy prop will be empty on the first render. Therefore, we have to use policyDraft until policy has been set in Onyx.
const policy = policyDraft?.id ? policyDraft : policyProp;
const isPolicyAdmin = PolicyUtils.isPolicyAdmin(policy);
const outputCurrency = policy?.outputCurrency ?? DistanceRequestUtils.getDefaultMileageRate(policy)?.currency ?? PolicyUtils.getPersonalPolicy()?.outputCurrency ?? '';
const currencySymbol = currencyList?.[outputCurrency]?.symbol ?? '';
const formattedCurrency = !isEmptyObject(policy) && !isEmptyObject(currencyList) ? `${outputCurrency} - ${currencySymbol}` : '';
Expand Down Expand Up @@ -346,6 +347,15 @@ function WorkspaceProfilePage({policyDraft, policy: policyProp, route}: Workspac
)}
{!readOnly && (
<View style={[styles.flexRow, styles.mt6, styles.mnw120]}>
{isPolicyAdmin && (
<Button
accessibilityLabel={translate('common.invite')}
text={translate('common.invite')}
onPress={() => Navigation.navigate(ROUTES.WORKSPACE_INVITE.getRoute(route.params.policyID, Navigation.getActiveRouteWithoutParams()))}
Copy link
Member

Choose a reason for hiding this comment

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

We didn't clear the draft while reopening the page which caused the previous selection to stay. #54604

icon={Expensicons.UserPlus}
style={[styles.mr2]}
/>
)}
<Button
accessibilityLabel={translate('common.share')}
text={translate('common.share')}
Expand Down
Loading