Self approval stays enabled if all members are removed by multi selection#73676
Self approval stays enabled if all members are removed by multi selection#73676inimaga merged 11 commits intoExpensify:mainfrom
Conversation
|
@dominictb Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
Codecov Report❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.
|
|
TS check failed |
| updatedWorkflows.forEach((workflow) => { | ||
| if (workflow?.removeApprovalWorkflow) { | ||
| const {removeApprovalWorkflow, ...updatedWorkflow} = workflow; | ||
| const onyxDataForRemoveApprovalWorkflow = getRemoveApprovalWorkflowOnyxData(updatedWorkflow, policy); |
There was a problem hiding this comment.
Make it let and move the onyx update assignment out of if... else... statement
| policyID, | ||
| }; | ||
|
|
||
| // Update "Prevent Self Approvals" after member removal |
There was a problem hiding this comment.
| // Update "Prevent Self Approvals" after member removal |
| const previousEmployeesCount = Object.values(policy?.employeeList ?? {}).filter((employee) => employee.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE).length; | ||
| const remainingEmployeeCount = previousEmployeesCount - accountIDs.length; | ||
| if (remainingEmployeeCount === 1 && policy?.preventSelfApproval) { | ||
| const onyxDataForSetPolicyPreventSelfApproval = getSetPolicyPreventSelfApprovalOnyxData(policyID, false); | ||
| optimisticData.push(...(onyxDataForSetPolicyPreventSelfApproval.optimisticData ?? [])); | ||
| successData.push(...(onyxDataForSetPolicyPreventSelfApproval.successData ?? [])); | ||
| failureData.push(...(onyxDataForSetPolicyPreventSelfApproval.failureData ?? [])); | ||
| } | ||
|
|
There was a problem hiding this comment.
Move this above const params
| const previousEmployeeList = Object.fromEntries(Object.entries(policy.employeeList ?? {}).map(([key, value]) => [key, {...value, pendingAction: null}])); | ||
| const updatedEmployees = convertApprovalWorkflowToPolicyEmployees({previousEmployeeList, approvalWorkflow, type: CONST.APPROVAL_WORKFLOW.TYPE.REMOVE}); |
There was a problem hiding this comment.
Can we return this from getRemoveApprovalWorkflowOnyxData?
| const previousDefaultApprover = getDefaultApprover(policy); | ||
| const newDefaultApprover = approvalWorkflow.isDefault ? approvalWorkflow.approvers.at(0)?.email : undefined; | ||
| const previousEmployeeList = Object.fromEntries(Object.entries(policy.employeeList ?? {}).map(([key, value]) => [key, {...value, pendingAction: null}])); | ||
| const updatedEmployees = convertApprovalWorkflowToPolicyEmployees({ | ||
| previousEmployeeList, | ||
| approvalWorkflow, | ||
| type: CONST.APPROVAL_WORKFLOW.TYPE.UPDATE, | ||
| membersToRemove, | ||
| approversToRemove, | ||
| defaultApprover: newDefaultApprover ?? previousDefaultApprover ?? '', | ||
| }); | ||
|
|
||
| // If there are no changes to the employees list, we can exit early | ||
| if (isEmptyObject(updatedEmployees) && !newDefaultApprover) { | ||
| return; | ||
| } |
There was a problem hiding this comment.
Can we return this from getUpdateApprovalWorkflowOnyxData?
|
I found a bug that if the workflow for new members include the workspace owner, then when removing all members, all the workflows, including the default one would be removed as well. But that already happens on |
|
Screen.Recording.2025-10-31.at.05.26.05.mov |
|
@dominictb I updated. |
heyjennahay
left a comment
There was a problem hiding this comment.
No concern with product change
|
@dominictb Could you re-review please |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppScreen.Recording.2025-11-24.at.17.48.33.movAndroid: mWeb ChromeiOS: HybridAppScreen.Recording.2025-11-24.at.17.39.12-compressed.moviOS: mWeb SafariScreen.Recording.2025-11-24.at.17.32.55-compressed.movMacOS: Chrome / SafariScreen.Recording.2025-11-12.at.23.51.44-compressed.movScreen.Recording.2025-11-12.at.23.52.55-compressed.movMacOS: Desktop |
|
@inimaga I'm thinking if we really need the "preemptively lock
Do you think we need Product team confirmation on this? |
|
@dominictb I'm not sure I follow what you're trying to say. |
|
Bump @dominictb |
|
We agreed earlier to disable and lock the "Prevent self-approval" option when the workspace has only 1 member #70286 (comment). But after revising, I don't think it's needed because we can always enable "Prevent self-approval" even when the workspace has 1 member both in NewDot and OldDot.
Explained above. It's possible in both OldDot and NewDot. |
|
@dominictb Okay Gotcha. No, I still think we should preemptively disable and lock the "Prevent self-approval" option when the workspace has only 1 member (the owner). So that the user doesn't run into the error displayed of : |
|
🚀 Deployed to staging by https://github.com/inimaga in version: 9.2.64-0 🚀
|
Revert "Merge pull request #73676 from mkzie2/mkzie2-issue/70286"
|
🚀 Deployed to production by https://github.com/marcaaron in version: 9.2.64-5 🚀
|
|
🚀 Deployed to staging by https://github.com/inimaga in version: 9.2.65-0 🚀
|
|
🚀 Deployed to production by https://github.com/marcaaron in version: 9.2.65-6 🚀
|


Explanation of Change
Self approval stays enabled if all members are removed by multi selection
Fixed Issues
$ #70286
PROPOSAL: #70286 (comment)
Tests
Offline tests
Same
QA Steps
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectioncanBeMissingparam foruseOnyxtoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Screen.Recording.2025-10-28.at.23.32.23.mov
Android: mWeb Chrome
Screen.Recording.2025-10-28.at.23.40.02.mov
iOS: Native
Screen.Recording.2025-10-28.at.23.43.02.mov
iOS: mWeb Safari
Screen.Recording.2025-10-28.at.23.41.36.mov
MacOS: Chrome / Safari
Screen.Recording.2025-10-28.at.23.37.57.mov
MacOS: Desktop
Screen.Recording.2025-10-28.at.23.48.13.mov