Skip to content

Commit

Permalink
Merge pull request #37961 from burczu/bugfix/37927-issues-member-details
Browse files Browse the repository at this point in the history
#37927 bugfix: member details issues
  • Loading branch information
luacmartins authored Apr 8, 2024
2 parents 6ec5811 + b2f30db commit 1b6c993
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 118 deletions.
4 changes: 2 additions & 2 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -621,11 +621,11 @@ const ROUTES = {
},
WORKSPACE_MEMBER_DETAILS: {
route: 'settings/workspaces/:policyID/members/:accountID',
getRoute: (policyID: string, accountID: number, backTo?: string) => getUrlWithBackToParam(`settings/workspaces/${policyID}/members/${accountID}`, backTo),
getRoute: (policyID: string, accountID: number) => `settings/workspaces/${policyID}/members/${accountID}` as const,
},
WORKSPACE_MEMBER_ROLE_SELECTION: {
route: 'settings/workspaces/:policyID/members/:accountID/role-selection',
getRoute: (policyID: string, accountID: number, backTo?: string) => getUrlWithBackToParam(`settings/workspaces/${policyID}/members/${accountID}/role-selection`, backTo),
getRoute: (policyID: string, accountID: number) => `settings/workspaces/${policyID}/members/${accountID}/role-selection` as const,
},
WORKSPACE_OWNER_CHANGE_SUCCESS: {
route: 'settings/workspaces/:policyID/change-owner/:accountID/success',
Expand Down
1 change: 0 additions & 1 deletion src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ const SCREENS = {
CATEGORIES_SETTINGS: 'Categories_Settings',
MORE_FEATURES: 'Workspace_More_Features',
MEMBER_DETAILS: 'Workspace_Member_Details',
MEMBER_DETAILS_ROLE_SELECTION: 'Workspace_Member_Details_Role_Selection',
OWNER_CHANGE_CHECK: 'Workspace_Owner_Change_Check',
OWNER_CHANGE_SUCCESS: 'Workspace_Owner_Change_Success',
OWNER_CHANGE_ERROR: 'Workspace_Owner_Change_Error',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,6 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
[SCREENS.WORKSPACE.CATEGORY_SETTINGS]: () => require('../../../../pages/workspace/categories/CategorySettingsPage').default as React.ComponentType,
[SCREENS.WORKSPACE.CATEGORIES_SETTINGS]: () => require('../../../../pages/workspace/categories/WorkspaceCategoriesSettingsPage').default as React.ComponentType,
[SCREENS.WORKSPACE.MEMBER_DETAILS]: () => require('../../../../pages/workspace/members/WorkspaceMemberDetailsPage').default as React.ComponentType,
[SCREENS.WORKSPACE.MEMBER_DETAILS_ROLE_SELECTION]: () => require('../../../../pages/workspace/members/WorkspaceMemberDetailsRoleSelectionPage').default as React.ComponentType,
[SCREENS.WORKSPACE.OWNER_CHANGE_CHECK]: () => require('@pages/workspace/members/WorkspaceOwnerChangeWrapperPage').default as React.ComponentType,
[SCREENS.WORKSPACE.OWNER_CHANGE_SUCCESS]: () => require('../../../../pages/workspace/members/WorkspaceOwnerChangeSuccessPage').default as React.ComponentType,
[SCREENS.WORKSPACE.OWNER_CHANGE_ERROR]: () => require('../../../../pages/workspace/members/WorkspaceOwnerChangeErrorPage').default as React.ComponentType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const FULL_SCREEN_TO_RHP_MAPPING: Partial<Record<FullScreenName, string[]>> = {
SCREENS.WORKSPACE.INVITE,
SCREENS.WORKSPACE.INVITE_MESSAGE,
SCREENS.WORKSPACE.MEMBER_DETAILS,
SCREENS.WORKSPACE.MEMBER_DETAILS_ROLE_SELECTION,
SCREENS.WORKSPACE.OWNER_CHANGE_CHECK,
SCREENS.WORKSPACE.OWNER_CHANGE_SUCCESS,
SCREENS.WORKSPACE.OWNER_CHANGE_ERROR,
Expand Down
3 changes: 0 additions & 3 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,6 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
[SCREENS.WORKSPACE.MEMBER_DETAILS]: {
path: ROUTES.WORKSPACE_MEMBER_DETAILS.route,
},
[SCREENS.WORKSPACE.MEMBER_DETAILS_ROLE_SELECTION]: {
path: ROUTES.WORKSPACE_MEMBER_ROLE_SELECTION.route,
},
[SCREENS.WORKSPACE.OWNER_CHANGE_SUCCESS]: {
path: ROUTES.WORKSPACE_OWNER_CHANGE_SUCCESS.route,
},
Expand Down
6 changes: 0 additions & 6 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,12 +220,6 @@ type SettingsNavigatorParamList = {
[SCREENS.WORKSPACE.MEMBER_DETAILS]: {
policyID: string;
accountID: string;
backTo: Routes;
};
[SCREENS.WORKSPACE.MEMBER_DETAILS_ROLE_SELECTION]: {
policyID: string;
accountID: string;
backTo: Routes;
};
[SCREENS.WORKSPACE.OWNER_CHANGE_SUCCESS]: {
policyID: string;
Expand Down
16 changes: 9 additions & 7 deletions src/libs/actions/Policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1294,7 +1294,10 @@ function addMembersToWorkspace(invitedEmailsToAccountIDs: InvitedEmailsToAccount
const optimisticMembersState: OnyxCollection<PolicyMember> = {};
const failureMembersState: OnyxCollection<PolicyMember> = {};
accountIDs.forEach((accountID) => {
optimisticMembersState[accountID] = {pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD};
optimisticMembersState[accountID] = {
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
role: CONST.POLICY.ROLE.USER,
};
failureMembersState[accountID] = {
errors: ErrorUtils.getMicroSecondOnyxError('workspace.people.error.genericAdd'),
};
Expand All @@ -1321,12 +1324,11 @@ function addMembersToWorkspace(invitedEmailsToAccountIDs: InvitedEmailsToAccount
// Convert to object with each key clearing pendingAction, when it is an existing account.
// Remove the object, when it is a newly created account.
value: accountIDs.reduce((accountIDsWithClearedPendingAction, accountID) => {
let value = null;
const accountAlreadyExists = !isEmptyObject(allPersonalDetails?.[accountID]);

if (accountAlreadyExists) {
value = {pendingAction: null, errors: null};
}
const value = {
...allPolicyMembers?.[accountID],
pendingAction: null,
errors: null,
};

return {...accountIDsWithClearedPendingAction, [accountID]: value};
}, {}),
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 @@ -289,7 +289,7 @@ function WorkspaceMembersPage({
}

Policy.clearWorkspaceOwnerChangeFlow(policyID);
Navigation.navigate(ROUTES.WORKSPACE_MEMBER_DETAILS.getRoute(route.params.policyID, item.accountID, Navigation.getActiveRoute()));
Navigation.navigate(ROUTES.WORKSPACE_MEMBER_DETAILS.getRoute(route.params.policyID, item.accountID));
},
[isPolicyAdmin, policy, policyID, route.params.policyID],
);
Expand Down
50 changes: 41 additions & 9 deletions src/pages/workspace/members/WorkspaceMemberDetailsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React, {useCallback, useEffect} from 'react';
import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
Expand Down Expand Up @@ -29,10 +29,11 @@ import withPolicyAndFullscreenLoading from '@pages/workspace/withPolicyAndFullsc
import * as Policy from '@userActions/Policy';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Route} from '@src/ROUTES';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
import type {PersonalDetails, PersonalDetailsList} from '@src/types/onyx';
import type {ListItemType} from './WorkspaceMemberDetailsRoleSelectionModal';
import WorkspaceMemberDetailsRoleSelectionModal from './WorkspaceMemberDetailsRoleSelectionModal';

type WorkspacePolicyOnyxProps = {
/** Personal details of all users */
Expand All @@ -48,11 +49,11 @@ function WorkspaceMemberDetailsPage({personalDetails, policyMembers, policy, rou
const StyleUtils = useStyleUtils();
const currentUserPersonalDetails = useCurrentUserPersonalDetails();

const [isRemoveMemberConfirmModalVisible, setIsRemoveMemberConfirmModalVisible] = React.useState(false);
const [isRemoveMemberConfirmModalVisible, setIsRemoveMemberConfirmModalVisible] = useState(false);
const [isRoleSelectionModalVisible, setIsRoleSelectionModalVisible] = useState(false);

const accountID = Number(route.params.accountID);
const policyID = route.params.policyID;
const backTo = route.params.backTo ?? ('' as Route);

const member = policyMembers?.[accountID];
const details = personalDetails?.[accountID] ?? ({} as PersonalDetails);
Expand All @@ -64,6 +65,24 @@ function WorkspaceMemberDetailsPage({personalDetails, policyMembers, policy, rou
const isCurrentUserAdmin = policyMembers?.[currentUserPersonalDetails?.accountID]?.role === CONST.POLICY.ROLE.ADMIN;
const isCurrentUserOwner = policy?.owner === currentUserPersonalDetails?.login;

const roleItems: ListItemType[] = useMemo(
() => [
{
value: CONST.POLICY.ROLE.ADMIN,
text: translate('common.admin'),
isSelected: member?.role === CONST.POLICY.ROLE.ADMIN,
keyForList: CONST.POLICY.ROLE.ADMIN,
},
{
value: CONST.POLICY.ROLE.USER,
text: translate('common.member'),
isSelected: member?.role === CONST.POLICY.ROLE.USER,
keyForList: CONST.POLICY.ROLE.USER,
},
],
[member?.role, translate],
);

useEffect(() => {
if (!policy?.errorFields?.changeOwner && policy?.isChangeOwnerSuccessful) {
return;
Expand All @@ -83,16 +102,24 @@ function WorkspaceMemberDetailsPage({personalDetails, policyMembers, policy, rou
const removeUser = useCallback(() => {
Policy.removeMembers([accountID], policyID);
setIsRemoveMemberConfirmModalVisible(false);
Navigation.goBack(backTo);
}, [accountID, backTo, policyID]);
Navigation.goBack();
}, [accountID, policyID]);

const navigateToProfile = useCallback(() => {
Navigation.navigate(ROUTES.PROFILE.getRoute(accountID, Navigation.getActiveRoute()));
}, [accountID]);

const openRoleSelectionModal = useCallback(() => {
Navigation.navigate(ROUTES.WORKSPACE_MEMBER_ROLE_SELECTION.getRoute(policyID, accountID, Navigation.getActiveRoute()));
}, [accountID, policyID]);
setIsRoleSelectionModalVisible(true);
}, []);

const changeRole = useCallback(
({value}: ListItemType) => {
setIsRoleSelectionModalVisible(false);
Policy.updateWorkspaceMembersRole(policyID, [accountID], value);
},
[accountID, policyID],
);

const startChangeOwnershipFlow = useCallback(() => {
Policy.clearWorkspaceOwnerChangeFlow(policyID);
Expand All @@ -107,7 +134,6 @@ function WorkspaceMemberDetailsPage({personalDetails, policyMembers, policy, rou
<HeaderWithBackButton
title={displayName}
subtitle={policy?.name}
onBackButtonPress={() => Navigation.goBack(backTo)}
/>
<View style={[styles.containerWithSpaceBetween, styles.pointerEventsBoxNone, styles.justifyContentStart]}>
<View style={[styles.avatarSectionWrapper, styles.pb0]}>
Expand Down Expand Up @@ -174,6 +200,12 @@ function WorkspaceMemberDetailsPage({personalDetails, policyMembers, policy, rou
onPress={navigateToProfile}
shouldShowRightIcon
/>
<WorkspaceMemberDetailsRoleSelectionModal
isVisible={isRoleSelectionModalVisible}
items={roleItems}
onRoleChange={changeRole}
onClose={() => setIsRoleSelectionModalVisible(false)}
/>
</View>
</View>
</ScreenWrapper>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from 'react';
import {View} from 'react-native';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import Modal from '@components/Modal';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
import RadioListItem from '@components/SelectionList/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import CONST from '@src/CONST';

type ListItemType = {
value: typeof CONST.POLICY.ROLE.ADMIN | typeof CONST.POLICY.ROLE.USER;
text: string;
isSelected: boolean;
keyForList: typeof CONST.POLICY.ROLE.ADMIN | typeof CONST.POLICY.ROLE.USER;
};

type WorkspaceMemberDetailsPageProps = {
/** Whether the modal is visible */
isVisible: boolean;

/** The list of items to render */
items: ListItemType[];

/** Function to call when the user selects a role */
onRoleChange: ({value}: ListItemType) => void;

/** Function to call when the user closes the role selection modal */
onClose: () => void;
};

function WorkspaceMemberDetailsRoleSelectionModal({isVisible, items, onRoleChange, onClose}: WorkspaceMemberDetailsPageProps) {
const {translate} = useLocalize();
const styles = useThemeStyles();

return (
<Modal
type={CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED}
isVisible={isVisible}
onClose={() => onClose?.()}
onModalHide={onClose}
hideModalContentWhileAnimating
useNativeDriver
>
<ScreenWrapper testID={WorkspaceMemberDetailsRoleSelectionModal.displayName}>
<HeaderWithBackButton
title={translate('common.role')}
onBackButtonPress={onClose}
/>
<View style={[styles.containerWithSpaceBetween, styles.pointerEventsBoxNone]}>
<SelectionList
sections={[{data: items}]}
ListItem={RadioListItem}
onSelectRow={onRoleChange}
initiallyFocusedOptionKey={items.find((item) => item.isSelected)?.keyForList}
/>
</View>
</ScreenWrapper>
</Modal>
);
}

WorkspaceMemberDetailsRoleSelectionModal.displayName = 'WorkspaceMemberDetailsRoleSelectionModal';

export type {ListItemType};

export default WorkspaceMemberDetailsRoleSelectionModal;

This file was deleted.

0 comments on commit 1b6c993

Please sign in to comment.