Repository navigation
Conversation
After a domain admin requests an unlock for a locked member, the row now reads "Pending unlock request" with an hourglass icon. Tapping it again reopens the confirmation modal without sending a duplicate request, and a failed request rolls back the state and shows an error on the row. Co-authored-by: Maruf Sharifi <marufsharifi@users.noreply.github.com>
|
I created this PR from an upstream branch since I don't have push access to your fork. To take ownership of this branch and be able to push updates, run: Then you can close this PR and open a new one from your fork. |
🦜 Polyglot Parrot! 🦜Squawk! Looks like you added some shiny new English strings. Allow me to parrot them back to you in other tongues: View the translation diffdiff --git a/src/languages/el.ts b/src/languages/el.ts
index 247aab54..15c21e53 100644
--- a/src/languages/el.ts
+++ b/src/languages/el.ts
@@ -2588,7 +2588,7 @@ const translations: TranslationDeepObject<typeof en> = {
lockAccount: 'Κλείδωμα λογαριασμού',
lockMyAccount: 'Κλείδωμα του λογαριασμού μου',
unlockAccount: 'Ξεκλειδώστε τον λογαριασμό',
- pendingUnlockRequest: 'Εκκρεμές αίτημα ξεκλειδώματος',
+ pendingUnlockRequest: 'Εκκρεμεί αίτημα ξεκλειδώματος',
unlockTitle: 'Λάβαμε το αίτημά σας',
unlockDescription: 'Θα εξετάσουμε τον λογαριασμό για να επιβεβαιώσουμε ότι είναι ασφαλές να ξεκλειδωθεί και θα επικοινωνήσουμε μέσω Concierge για τυχόν ερωτήσεις.',
findYourSituation: 'Τα περισσότερα προβλήματα δεν απαιτούν κλείδωμα του λογαριασμού σας. Βρείτε την περίπτωσή σας παρακάτω:',
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index c0d23b8a..dc449409 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -2528,7 +2528,7 @@ const translations: TranslationDeepObject<typeof en> = {
lockAccount: 'Account vergrendelen',
lockMyAccount: 'Account vergrendelen',
unlockAccount: 'Account ontgrendelen',
- pendingUnlockRequest: 'Ontgrendelingsverzoek in behandeling',
+ pendingUnlockRequest: 'In behandeling zijnde ontgrendelingsverzoek',
findYourSituation: 'Voor de meeste problemen hoef je je account niet te blokkeren. Zoek hieronder jouw situatie:',
lostCardOrCharges:
'<a href="https://help.expensify.com/articles/expensify-classic/expensify-card/Dispute-Transaction">Kaart kwijt of onbekende kosten</a>: Annuleer je kaart en neem contact op met Concierge om onbekende transacties te betwisten.',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index 5cf2fb65..ffbb5941 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -2567,7 +2567,7 @@ const translations: TranslationDeepObject<typeof en> = {
lockAccount: 'Zablokuj konto',
lockMyAccount: 'Zablokuj moje konto',
unlockAccount: 'Odblokuj konto',
- pendingUnlockRequest: 'Oczekująca prośba o odblokowanie',
+ pendingUnlockRequest: 'Oczekujące żądanie odblokowania',
findYourSituation: 'Większość problemów nie wymaga blokowania konta! Znajdź swoją sytuację poniżej:',
lostCardOrCharges:
'<a href="https://help.expensify.com/articles/expensify-classic/expensify-card/Dispute-Transaction">Zgubiona karta lub nieznane obciążenia</a>: Anuluj swoją kartę i skontaktuj się z Concierge, żeby zakwestionować nieznane transakcje.',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index e30139d2..6e6479b5 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -2445,7 +2445,7 @@ const translations: TranslationDeepObject<typeof en> = {
lockAccount: '锁定账户',
lockMyAccount: '锁定我的账户',
unlockAccount: '解锁账户',
- pendingUnlockRequest: '解锁请求待处理',
+ pendingUnlockRequest: '待处理解锁请求',
findYourSituation: '大多数问题都不需要锁定你的账户!请在以下列表中找到与你相符的情况:',
lostCardOrCharges:
'<a href="https://help.expensify.com/articles/expensify-classic/expensify-card/Dispute-Transaction">卡片遗失或出现不明扣款</a>:请挂失您的卡片,并联系 Concierge 申诉未知交易。',
Note You can apply these changes to your branch by copying the patch to your clipboard, then running |
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
|
🤖 Web test steps verification results: ❌ fail The Web test was blocked before step 1, so this result doesn't show a code defect. The test account has no domain, so it isn't a domain admin and has no member to lock and unlock. This PR's Tests section is still a TODO, so I took the steps from the linked issue's reproduction steps and the expected result in the PR description.
To test this PR, you need a domain-admin account whose domain already has a non-admin member. |
|
@MelvinBot, replace the PR Author checklist with the verified one below: PR author checklist |
|
I replaced the PR description with your verified version, word for word. Two things to check:
|
|
@MelvinBot Mark this as ready for review |
|
I marked this PR as ready for review. |
|
@dubielzyk-expensify @marufsharifi One of you needs to 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] |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c76d7190f5
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (!isUnlockRequested) { | ||
| requestUnlockAccount(accountID, domainAccountID, domainName); | ||
| } |
There was a problem hiding this comment.
Clear stale pending state before suppressing a new unlock request
When an earlier unlock completes and the account is later re-locked through another device, another administrator, or a server update, the locally persisted private_unlockRequested_* flag remains true because the only reset is inside this client's lockAccount() action. In that state this guard prevents RequestUnlockAccount from being sent, so clicking the newly locked member's row only reopens the old confirmation modal and the member cannot be unlocked from this client. Clear or reconcile the flag when the observed lock lifecycle changes rather than treating the local value as permanently authoritative.
Useful? React with 👍 / 👎.
|
What videos or screenshots show the change? |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppScreen.Recording.2026-10-19.at.2.29.05.PM.movAndroid: mWeb ChromeScreen_Recording_20261019_143233_Chrome.mp4iOS: HybridAppScreen.Recording.2026-10-19.at.2.43.24.PM.moviOS: mWeb SafariScreen.Recording.2026-10-19.at.2.46.32.PM.movMacOS: Chrome / SafariScreen.Recording.2026-10-19.at.1.53.39.PM.mov |
|
Steps to reproduce:
Expected Result: The app should not indicate that the server received the unlock request while it is still queued offline. Actual Result: The action changes to RF-1.mov |
|
@MelvinBot find the root cause of this: #104188 (comment) |
|
@MelvinBot find the RCA for this bug: #104188 (comment) |
RCA: failed unlock request doesn't show the red dot on Domain membersRoot cause: The sidebar and Domains list use a different error check from the member row, and that check doesn't know about
This PR added Fix: Add ConfidenceHigh. I traced each surface to the function it reads. I did not reproduce this in a browser. Reply with |
|
@MelvinBot fix this: #104188 (comment) |
Co-authored-by: Maruf Sharifi <marufsharifi@users.noreply.github.com>
|
I fixed this in 52aa62a. A failed unlock request now shows the red dot on the Domain members row and on the Domains list.
I added two tests: one with only an unlock error, and one with only a lock error ( Checks
|
Co-authored-by: Maruf Sharifi <marufsharifi@users.noreply.github.com>
|
MelvinBot has made 5 consecutive commits trying to fix CI failures. Automatic CI fix dispatches are now paused for this PR. Next steps: A human should review the recent commits and resolve the conflicting CI errors manually. |
|
Fixed the failing One other check still fails, but not because of this PR:
|
|
Both failing checks are unrelated to this PR, so I didn't push a fix.
To get green, someone needs to delete that directive on main. Then merge main into this branch and rerun the failed Jest job. Details
|
|
@MelvinBot merge the main. |
|
@MelvinBot Merge the main. |
…equestState Co-authored-by: Maruf Sharifi <marufsharifi@users.noreply.github.com>
|
@MelvinBot Resolve the conflicts. |
…equestState Co-authored-by: Maruf Sharifi <marufsharifi@users.noreply.github.com> # Conflicts: # src/pages/domain/Members/DomainMemberDetailsPage.tsx
|
I resolved the merge conflicts with The only conflict was in the imports of
All other files, including the language files, merged automatically. I couldn't run the repo's lint wrapper or typecheck in this environment, so please let CI confirm. |
|
@MelvinBot Merge the main. |
…equestState Co-authored-by: Maruf Sharifi <marufsharifi@users.noreply.github.com>
|
Merged |
BUG#1:
Expected result: The queued request remains visibly indicated when moving between the member details and the members list. Actual result: The member's list row appears normal, with no pending styling, even though reopening the member details still shows the greyed-out unlock action. PR: RF-1.movMain:
|
|
@MelvinBot find the RCA for this: #104188 (comment) |
RCA for BUG#1 (list row shows no pending styling)Root cause: This PR adds a new field-level pending action,
Introduced by this PR. On Fix: In Investigation details
Next Steps: Reply with |
|
@MelvinBot fix this: #104188 (comment) |
Co-authored-by: Maruf Sharifi <marufsharifi@users.noreply.github.com>
|
Fixed BUG#1 in 34ba94a. The members list row now shows pending styling while an unlock request is queued.
|
|
@MelvinBot resolve the conflicts. |
…equestState Co-authored-by: Maruf Sharifi <marufsharifi@users.noreply.github.com> # Conflicts: # src/pages/domain/Members/DomainMemberDetailsPage.tsx
|
I resolved the merge conflicts by merging The only conflict was in the imports of |



Explanation of Change
This PR improves the domain member unlock request flow by providing clear feedback after an unlock request is submitted.
Fixed Issues
$ #102734
PROPOSAL: #102734 (comment)
Tests
1: Open Domains → Domain Members.
2: Select a locked member.
3: Click Unlock account.
4: Verify the confirmation modal appears.
5: Click Got it.
6: Verify Pending unlock request and the hourglass icon appear.
7: Click the pending row and verify the modal reopens without sending another request.
Offline tests
1: Open a locked domain member.
2: Go offline and click Unlock account.
3: Verify the request is queued.
4: Reconnect and verify the pending state updates correctly.
QA Steps
Same as Tests.
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectionAvatar, I verified the components usingAvatarare working as expected)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.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
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari