Skip to content

Commit

Permalink
Update pendingAction/pendingFields when making an action offline
Browse files Browse the repository at this point in the history
  • Loading branch information
blazejkustra committed Aug 27, 2024
1 parent 79fdc56 commit 3701866
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 23 deletions.
19 changes: 17 additions & 2 deletions src/libs/WorkflowUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,17 @@ function convertPolicyEmployeesToApprovalWorkflows({employees, defaultApprover,

// Add each employee to the appropriate workflow
Object.values(employees).forEach((employee) => {
const {email, submitsTo} = employee;
const {email, submitsTo, pendingAction} = employee;
if (!email || !submitsTo) {
return;
}

const member: Member = {email, avatar: personalDetailsByEmail[email]?.avatar, displayName: personalDetailsByEmail[email]?.displayName ?? email};
const member: Member = {
email,
avatar: personalDetailsByEmail[email]?.avatar,
displayName: personalDetailsByEmail[email]?.displayName ?? email,
};

if (!approvalWorkflows[submitsTo]) {
const approvers = calculateApprovers({employees, firstEmail: submitsTo, personalDetailsByEmail});
if (submitsTo !== firstApprover) {
Expand All @@ -132,9 +137,14 @@ function convertPolicyEmployeesToApprovalWorkflows({employees, defaultApprover,
members: [],
approvers,
isDefault: defaultApprover === submitsTo,
pendingAction,
};
}

approvalWorkflows[submitsTo].members.push(member);
if (pendingAction) {
approvalWorkflows[submitsTo].pendingAction = pendingAction;
}
});

// Sort the workflows by the first approver's name (default workflow has priority)
Expand Down Expand Up @@ -189,25 +199,30 @@ function convertApprovalWorkflowToPolicyEmployees({approvalWorkflow, membersToRe
throw new Error('Approval workflow must have at least one approver');
}

const pendingAction = type === CONST.APPROVAL_WORKFLOW.TYPE.CREATE ? CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD : CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE;

approvalWorkflow.approvers.forEach((approver, index) => {
const nextApprover = approvalWorkflow.approvers.at(index + 1);
updatedEmployeeList[approver.email] = {
email: approver.email,
forwardsTo: type === CONST.APPROVAL_WORKFLOW.TYPE.REMOVE ? '' : nextApprover?.email ?? '',
pendingAction,
};
});

approvalWorkflow.members.forEach(({email}) => {
updatedEmployeeList[email] = {
...(updatedEmployeeList[email] ? updatedEmployeeList[email] : {email}),
submitsTo: type === CONST.APPROVAL_WORKFLOW.TYPE.REMOVE ? '' : firstApprover.email ?? '',
pendingAction,
};
});

membersToRemove?.forEach(({email}) => {
updatedEmployeeList[email] = {
...(updatedEmployeeList[email] ? updatedEmployeeList[email] : {email}),
submitsTo: '',
pendingAction,
};
});

Expand Down
23 changes: 6 additions & 17 deletions src/libs/actions/Workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function createApprovalWorkflow(policyID: string, approvalWorkflow: ApprovalWork
return;
}

const previousEmployeeList = {...policy.employeeList};
const previousEmployeeList = Object.fromEntries(Object.entries(policy.employeeList ?? {}).map(([key, value]) => [key, {...value, pendingAction: null}]));
const previousApprovalMode = policy.approvalMode;
const updatedEmployees = convertApprovalWorkflowToPolicyEmployees({approvalWorkflow, type: CONST.APPROVAL_WORKFLOW.TYPE.CREATE});

Expand All @@ -70,7 +70,6 @@ function createApprovalWorkflow(policyID: string, approvalWorkflow: ApprovalWork
value: {
employeeList: updatedEmployees,
approvalMode: CONST.POLICY.APPROVAL_MODE.ADVANCED,
pendingFields: {employeeList: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD},
},
},
];
Expand All @@ -87,7 +86,6 @@ function createApprovalWorkflow(policyID: string, approvalWorkflow: ApprovalWork
value: {
employeeList: previousEmployeeList,
approvalMode: previousApprovalMode,
pendingFields: {employeeList: null},
},
},
];
Expand All @@ -102,7 +100,7 @@ function createApprovalWorkflow(policyID: string, approvalWorkflow: ApprovalWork
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
value: {
pendingFields: {employeeList: null},
employeeList: Object.fromEntries(Object.keys(updatedEmployees).map((key) => [key, {pendingAction: null}])),
},
},
];
Expand All @@ -120,7 +118,7 @@ function updateApprovalWorkflow(policyID: string, approvalWorkflow: ApprovalWork

const previousDefaultApprover = policy.approver ?? policy.owner;
const newDefaultApprover = approvalWorkflow.isDefault ? approvalWorkflow.approvers[0].email : undefined;
const previousEmployeeList = {...policy.employeeList};
const previousEmployeeList = Object.fromEntries(Object.entries(policy.employeeList ?? {}).map(([key, value]) => [key, {...value, pendingAction: null}]));
const updatedEmployees = convertApprovalWorkflowToPolicyEmployees({approvalWorkflow, type: CONST.APPROVAL_WORKFLOW.TYPE.UPDATE, membersToRemove});

const optimisticData: OnyxUpdate[] = [
Expand All @@ -136,7 +134,6 @@ function updateApprovalWorkflow(policyID: string, approvalWorkflow: ApprovalWork
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
value: {
employeeList: updatedEmployees,
pendingFields: {employeeList: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE},
...(newDefaultApprover ? {approver: newDefaultApprover} : {}),
},
},
Expand Down Expand Up @@ -169,7 +166,7 @@ function updateApprovalWorkflow(policyID: string, approvalWorkflow: ApprovalWork
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
value: {
pendingFields: {employeeList: null},
employeeList: Object.fromEntries(Object.keys(updatedEmployees).map((key) => [key, {pendingAction: null}])),
},
},
];
Expand All @@ -190,8 +187,8 @@ function removeApprovalWorkflow(policyID: string, approvalWorkflow: ApprovalWork
return;
}

const previousEmployeeList = {...policy.employeeList};
const updatedEmployees = convertApprovalWorkflowToPolicyEmployees({approvalWorkflow, type: CONST.APPROVAL_WORKFLOW.TYPE.REMOVE});
const previousEmployeeList = Object.fromEntries(Object.entries(policy.employeeList ?? {}).map(([key, value]) => [key, {...value, pendingAction: null}]));
const updatedEmployeeList = {...previousEmployeeList, ...updatedEmployees};

const defaultApprover = policy.approver ?? policy.owner;
Expand All @@ -212,7 +209,6 @@ function removeApprovalWorkflow(policyID: string, approvalWorkflow: ApprovalWork
value: {
employeeList: updatedEmployees,
approvalMode: hasMoreThanOneWorkflow ? CONST.POLICY.APPROVAL_MODE.ADVANCED : CONST.POLICY.APPROVAL_MODE.BASIC,
pendingFields: {employeeList: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE},
},
},
];
Expand All @@ -231,13 +227,6 @@ function removeApprovalWorkflow(policyID: string, approvalWorkflow: ApprovalWork
approvalMode: CONST.POLICY.APPROVAL_MODE.ADVANCED,
},
},
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
value: {
pendingFields: {employeeList: null},
},
},
];

const successData: OnyxUpdate[] = [
Expand All @@ -250,7 +239,7 @@ function removeApprovalWorkflow(policyID: string, approvalWorkflow: ApprovalWork
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`,
value: {
pendingFields: {employeeList: null},
employeeList: Object.fromEntries(Object.keys(updatedEmployees).map((key) => [key, {pendingAction: null}])),
},
},
];
Expand Down
2 changes: 1 addition & 1 deletion src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ function WorkspaceWorkflowsPage({policy, betas, route}: WorkspaceWorkflowsPagePr
<OfflineWithFeedback
// eslint-disable-next-line react/no-array-index-key
key={`workflow-${index}`}
pendingAction={policy?.pendingFields?.employeeList}
pendingAction={workflow.pendingAction}
>
<ApprovalWorkflowSection
approvalWorkflow={workflow}
Expand Down
5 changes: 3 additions & 2 deletions src/types/onyx/ApprovalWorkflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +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';

/**
* Approver in the approval workflow
Expand Down Expand Up @@ -59,7 +60,7 @@ type Member = {
/**
* Approval workflow for a group of employees
*/
type ApprovalWorkflow = {
type ApprovalWorkflow = OnyxValueWithOfflineFeedback<{
/**
* List of member emails in the workflow
*/
Expand All @@ -76,7 +77,7 @@ type ApprovalWorkflow = {
* Is this the default workflow for the policy (first approver of this workflow is the same as the policy's default approver)
*/
isDefault: boolean;
};
}>;

/**
* Approval workflow for a group of employees with additional properties for the Onyx store
Expand Down
2 changes: 1 addition & 1 deletion src/types/onyx/Policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1564,7 +1564,7 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback<
/** Workspace account ID configured for Expensify Card */
workspaceAccountID?: number;
} & Partial<PendingJoinRequestPolicy>,
'addWorkspaceRoom' | 'employeeList' | keyof ACHAccount | keyof Attributes
'addWorkspaceRoom' | keyof ACHAccount | keyof Attributes
>;

/** Stages of policy connection sync */
Expand Down

0 comments on commit 3701866

Please sign in to comment.