Skip to content

Commit

Permalink
Merge pull request #50991 from nkdengineer/fix/50477
Browse files Browse the repository at this point in the history
fix: in offline approver selected is not greyed out
  • Loading branch information
tgolen authored Oct 24, 2024
2 parents ff349bb + 3f8fe77 commit 476ad6b
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 32 deletions.
7 changes: 7 additions & 0 deletions src/libs/WorkflowUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ function convertPolicyEmployeesToApprovalWorkflows({employees, defaultApprover,
email,
avatar: personalDetailsByEmail[email]?.avatar,
displayName: personalDetailsByEmail[email]?.displayName ?? email,
pendingFields: employee.pendingFields,
};

if (!approvalWorkflows[submitsTo]) {
Expand Down Expand Up @@ -234,6 +235,9 @@ function convertApprovalWorkflowToPolicyEmployees({
email: approver.email,
forwardsTo,
pendingAction,
pendingFields: {
forwardsTo: pendingAction,
},
};
});

Expand All @@ -250,6 +254,9 @@ function convertApprovalWorkflowToPolicyEmployees({
...(updatedEmployeeList[email] ? updatedEmployeeList[email] : {email}),
submitsTo,
pendingAction,
pendingFields: {
submitsTo: pendingAction,
},
};
});

Expand Down
2 changes: 1 addition & 1 deletion src/libs/actions/Workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ function updateApprovalWorkflow(policyID: string, approvalWorkflow: ApprovalWork
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
value: {
employeeList: Object.fromEntries(Object.keys(updatedEmployees).map((key) => [key, {pendingAction: null}])),
employeeList: Object.fromEntries(Object.keys(updatedEmployees).map((key) => [key, {pendingAction: null, pendingFields: null}])),
},
},
];
Expand Down
52 changes: 36 additions & 16 deletions src/pages/workspace/workflows/approvals/ApprovalWorkflowEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {OnyxEntry} from 'react-native-onyx';
import * as Expensicons from '@components/Icon/Expensicons';
import MenuItem from '@components/MenuItem';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import ScrollView from '@components/ScrollView';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
Expand All @@ -18,6 +19,7 @@ import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
import type {ApprovalWorkflowOnyx, Policy} from '@src/types/onyx';
import type {Approver} from '@src/types/onyx/ApprovalWorkflow';
import type {PendingAction} from '@src/types/onyx/OnyxCommon';

type ApprovalWorkflowEditorProps = {
/** The approval workflow to display */
Expand All @@ -43,6 +45,22 @@ function ApprovalWorkflowEditor({approvalWorkflow, removeApprovalWorkflow, polic
[approverCount, toLocaleOrdinal, translate],
);

const getApprovalPendingAction = useCallback(
(index: number) => {
let pendingAction: PendingAction | undefined;
if (index === 0) {
approvalWorkflow?.members?.forEach((member) => {
pendingAction = pendingAction ?? member.pendingFields?.submitsTo;
});
return pendingAction;
}
const previousApprover = approvalWorkflow?.approvers.at(index - 1);
const previousMember = approvalWorkflow?.members?.find((member) => member?.email === previousApprover?.email);
return previousMember?.pendingFields?.forwardsTo;
},
[approvalWorkflow],
);

const members = useMemo(() => {
if (approvalWorkflow.isDefault) {
return translate('workspace.common.everyone');
Expand Down Expand Up @@ -134,22 +152,24 @@ function ApprovalWorkflowEditor({approvalWorkflow, removeApprovalWorkflow, polic
: undefined;

return (
<MenuItemWithTopDescription
// eslint-disable-next-line react/no-array-index-key
key={`approver-${approver?.email}-${approverIndex}`}
title={approver?.displayName}
titleStyle={styles.textNormalThemeText}
wrapperStyle={styles.sectionMenuItemTopDescription}
description={approverDescription(approverIndex)}
descriptionTextStyle={!!approver?.displayName && styles.textLabelSupportingNormal}
onPress={() => editApprover(approverIndex)}
shouldShowRightIcon
hintText={hintText}
shouldRenderHintAsHTML
brickRoadIndicator={errorText ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined}
errorText={errorText}
shouldRenderErrorAsHTML
/>
<OfflineWithFeedback pendingAction={getApprovalPendingAction(approverIndex)}>
<MenuItemWithTopDescription
// eslint-disable-next-line react/no-array-index-key
key={`approver-${approver?.email}-${approverIndex}`}
title={approver?.displayName}
titleStyle={styles.textNormalThemeText}
wrapperStyle={styles.sectionMenuItemTopDescription}
description={approverDescription(approverIndex)}
descriptionTextStyle={!!approver?.displayName && styles.textLabelSupportingNormal}
onPress={() => editApprover(approverIndex)}
shouldShowRightIcon
hintText={hintText}
shouldRenderHintAsHTML
brickRoadIndicator={errorText ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined}
errorText={errorText}
shouldRenderErrorAsHTML
/>
</OfflineWithFeedback>
);
})}

Expand Down
7 changes: 6 additions & 1 deletion src/types/onyx/ApprovalWorkflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type {ValueOf} from 'type-fest';
import type {AvatarSource} from '@libs/UserUtils';
import type CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import type {OnyxValueWithOfflineFeedback} from './OnyxCommon';
import type {OnyxValueWithOfflineFeedback, PendingFields} from './OnyxCommon';

/**
* Approver in the approval workflow
Expand Down Expand Up @@ -55,6 +55,11 @@ type Member = {
* Avatar URL of the current user from their personal details
*/
avatar?: AvatarSource;

/**
* Pending states for offline updates
*/
pendingFields?: PendingFields<'submitsTo' | 'forwardsTo'>;
};

/**
Expand Down
28 changes: 14 additions & 14 deletions tests/unit/WorkflowUtilsTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,8 @@ describe('WorkflowUtils', () => {
const convertedEmployees = WorkflowUtils.convertApprovalWorkflowToPolicyEmployees({previousEmployeeList: {}, approvalWorkflow, type: 'create'});

expect(convertedEmployees).toEqual({
'1@example.com': buildPolicyEmployee(1, {forwardsTo: '', submitsTo: '1@example.com'}),
'2@example.com': buildPolicyEmployee(2, {submitsTo: '1@example.com'}),
'1@example.com': buildPolicyEmployee(1, {forwardsTo: '', submitsTo: '1@example.com', pendingFields: {submitsTo: 'add'}}),
'2@example.com': buildPolicyEmployee(2, {submitsTo: '1@example.com', pendingFields: {submitsTo: 'add'}}),
});
});

Expand All @@ -412,12 +412,12 @@ describe('WorkflowUtils', () => {
const convertedEmployees = WorkflowUtils.convertApprovalWorkflowToPolicyEmployees({previousEmployeeList: {}, approvalWorkflow, type: 'create'});

expect(convertedEmployees).toEqual({
'1@example.com': buildPolicyEmployee(1, {forwardsTo: '2@example.com'}),
'2@example.com': buildPolicyEmployee(2, {forwardsTo: '3@example.com'}),
'3@example.com': buildPolicyEmployee(3, {forwardsTo: ''}),
'4@example.com': buildPolicyEmployee(4, {submitsTo: '1@example.com'}),
'5@example.com': buildPolicyEmployee(5, {submitsTo: '1@example.com'}),
'6@example.com': buildPolicyEmployee(6, {submitsTo: '1@example.com'}),
'1@example.com': buildPolicyEmployee(1, {forwardsTo: '2@example.com', pendingFields: {forwardsTo: 'add'}}),
'2@example.com': buildPolicyEmployee(2, {forwardsTo: '3@example.com', pendingFields: {forwardsTo: 'add'}}),
'3@example.com': buildPolicyEmployee(3, {forwardsTo: '', pendingFields: {forwardsTo: 'add'}}),
'4@example.com': buildPolicyEmployee(4, {submitsTo: '1@example.com', pendingFields: {submitsTo: 'add'}}),
'5@example.com': buildPolicyEmployee(5, {submitsTo: '1@example.com', pendingFields: {submitsTo: 'add'}}),
'6@example.com': buildPolicyEmployee(6, {submitsTo: '1@example.com', pendingFields: {submitsTo: 'add'}}),
});
});

Expand All @@ -431,12 +431,12 @@ describe('WorkflowUtils', () => {
const convertedEmployees = WorkflowUtils.convertApprovalWorkflowToPolicyEmployees({previousEmployeeList: {}, approvalWorkflow, type: 'remove'});

expect(convertedEmployees).toEqual({
'1@example.com': buildPolicyEmployee(1, {forwardsTo: '', pendingAction: 'update'}),
'2@example.com': buildPolicyEmployee(2, {forwardsTo: '', pendingAction: 'update'}),
'3@example.com': buildPolicyEmployee(3, {forwardsTo: '', pendingAction: 'update'}),
'4@example.com': buildPolicyEmployee(4, {submitsTo: '', pendingAction: 'update'}),
'5@example.com': buildPolicyEmployee(5, {submitsTo: '', pendingAction: 'update'}),
'6@example.com': buildPolicyEmployee(6, {submitsTo: '', pendingAction: 'update'}),
'1@example.com': buildPolicyEmployee(1, {forwardsTo: '', pendingAction: 'update', pendingFields: {forwardsTo: 'update'}}),
'2@example.com': buildPolicyEmployee(2, {forwardsTo: '', pendingAction: 'update', pendingFields: {forwardsTo: 'update'}}),
'3@example.com': buildPolicyEmployee(3, {forwardsTo: '', pendingAction: 'update', pendingFields: {forwardsTo: 'update'}}),
'4@example.com': buildPolicyEmployee(4, {submitsTo: '', pendingAction: 'update', pendingFields: {submitsTo: 'update'}}),
'5@example.com': buildPolicyEmployee(5, {submitsTo: '', pendingAction: 'update', pendingFields: {submitsTo: 'update'}}),
'6@example.com': buildPolicyEmployee(6, {submitsTo: '', pendingAction: 'update', pendingFields: {submitsTo: 'update'}}),
});
});
});
Expand Down

0 comments on commit 476ad6b

Please sign in to comment.