Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {useNavigationState} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import React, {useCallback, useMemo, useState} from 'react';
import type {SelectionListApprover} from '@components/ApproverSelectionList';
import ApproverSelectionList from '@components/ApproverSelectionList';
import Text from '@components/Text';
Expand Down Expand Up @@ -36,12 +36,17 @@ function WorkspaceWorkflowsApprovalsApproverPage({policy, personalDetails, isLoa
const approverIndex = Number(route.params.approverIndex) ?? 0;
const rhpRoutes = useNavigationState((state) => state.routes);
const defaultApprover = getDefaultApprover(policy);
const firstApprover = approvalWorkflow?.approvers?.[0]?.email ?? '';
const firstApprover = approvalWorkflow?.originalApprovers?.[0]?.email ?? '';
// Keep the removed approver visible until navigation finishes.
// Without this temporary state, clearing the approver immediately causes the empty state to flash
// while this screen is still mounted during the dismiss animation.
const [removingApproverEmail, setRemovingApproverEmail] = useState<string>();

const isChangeApproverRoute = route.name === SCREENS.WORKSPACE.WORKFLOWS_APPROVALS_APPROVER_CHANGE;
const isInitialCreationFlow = approvalWorkflow?.action === CONST.APPROVAL_WORKFLOW.ACTION.CREATE && approvalWorkflow?.isInitialFlow;
const currentApprover = approvalWorkflow?.approvers[approverIndex];
const selectedApproverEmail = currentApprover?.email;
const visibleSelectedApproverEmail = removingApproverEmail ?? selectedApproverEmail;
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you mind explaining in code comment, "why" we need this additional state variable alongside selectedApproverEmail?


const employeeList = policy?.employeeList;
const approversFromWorkflow = approvalWorkflow?.approvers;
Expand All @@ -62,13 +67,13 @@ function WorkspaceWorkflowsApprovalsApproverPage({policy, personalDetails, isLoa
return null;
}

if (!isDefault && policy?.preventSelfApproval && membersEmail?.includes(email)) {
if (!isDefault && policy?.preventSelfApproval && membersEmail?.includes(email) && visibleSelectedApproverEmail !== email) {
return null;
}

// Do not allow the same email to be added twice
const isEmailAlreadyInApprovers = approversFromWorkflow?.some((approver, index) => approver?.email === email && index !== approverIndex);
if (isEmailAlreadyInApprovers && selectedApproverEmail !== email) {
if (isEmailAlreadyInApprovers && visibleSelectedApproverEmail !== email) {
return null;
}

Expand All @@ -90,7 +95,7 @@ function WorkspaceWorkflowsApprovalsApproverPage({policy, personalDetails, isLoa
text: displayName,
alternateText: email,
keyForList: email,
isSelected: selectedApproverEmail === email,
isSelected: visibleSelectedApproverEmail === email,
login: email,
icons: [{source: avatar ?? icons.FallbackAvatar, type: CONST.ICON_TYPE_AVATAR, name: displayName, id: accountID}],
rightElement: (
Expand All @@ -111,14 +116,14 @@ function WorkspaceWorkflowsApprovalsApproverPage({policy, personalDetails, isLoa
policy?.owner,
approvalWorkflow?.members,
approversFromWorkflow,
selectedApproverEmail,
visibleSelectedApproverEmail,
approverIndex,
defaultApprover,
personalDetails,
icons.FallbackAvatar,
]);

const shouldShowListEmptyContent = !!approvalWorkflow && !isApprovalWorkflowLoading;
const shouldShowListEmptyContent = !!approvalWorkflow && !isApprovalWorkflowLoading && !removingApproverEmail;

const goBack = useCallback(() => {
let backToRoute;
Expand All @@ -139,7 +144,12 @@ function WorkspaceWorkflowsApprovalsApproverPage({policy, personalDetails, isLoa
const isRemovingApprover = approvers.length === 0;

if (isRemovingApprover) {
setRemovingApproverEmail(visibleSelectedApproverEmail);
clearApprovalWorkflowApprover({approverIndex, currentApprovalWorkflow: approvalWorkflow});
if (isChangeApproverRoute && approvalWorkflow?.action === CONST.APPROVAL_WORKFLOW.ACTION.EDIT) {
Navigation.goBack(ROUTES.WORKSPACE_WORKFLOWS_APPROVALS_EDIT.getRoute(route.params.policyID, firstApprover));
return;
}
goBack();
return;
}
Expand Down Expand Up @@ -171,7 +181,19 @@ function WorkspaceWorkflowsApprovalsApproverPage({policy, personalDetails, isLoa
Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVALS_APPROVAL_LIMIT.getRoute(route.params.policyID, approverIndex));
}
},
[approverIndex, approvalWorkflow, employeeList, personalDetails, policy, route.params.policyID, goBack, personalDetailsByEmail, isChangeApproverRoute],
[
approverIndex,
approvalWorkflow,
employeeList,
personalDetails,
policy,
route.params.policyID,
goBack,
personalDetailsByEmail,
isChangeApproverRoute,
firstApprover,
visibleSelectedApproverEmail,
],
);

const subtitle = useMemo(
Expand All @@ -195,7 +217,7 @@ function WorkspaceWorkflowsApprovalsApproverPage({policy, personalDetails, isLoa
subtitle={subtitle}
isLoadingReportData={isLoadingReportData}
policy={policy}
initiallyFocusedOptionKey={selectedApproverEmail}
initiallyFocusedOptionKey={visibleSelectedApproverEmail}
shouldShowNotFoundViewLink
allApprovers={allApprovers}
onBackButtonPress={goBack}
Expand Down
Loading