Skip to content

[Duplicate Expenses] Re-enable Distance Expense Support with fixes#82005

Merged
JS00001 merged 21 commits intoExpensify:mainfrom
jjcoffee:fix/duplicate-distance-expense-blockers
Mar 4, 2026
Merged

[Duplicate Expenses] Re-enable Distance Expense Support with fixes#82005
JS00001 merged 21 commits intoExpensify:mainfrom
jjcoffee:fix/duplicate-distance-expense-blockers

Conversation

@jjcoffee
Copy link
Contributor

@jjcoffee jjcoffee commented Feb 10, 2026

Explanation of Change

Fixed Issues

$ #65948
$ #80420
$ #80392
$ #80399
$ #82274
PROPOSAL: N/A

Tests

Same as QA.

  • Verify that no errors appear in the JS console

Offline tests

Same as QA.

QA Steps

  • Have a self-DM
  • Have no enabled workspaces
  1. Go to self DM.
  2. Create a distance expense (map or manual).
  3. Go offline.
  4. Open the distance expense.
  5. Click More > Duplicate.
  6. Go back and open the duplicated expense.
  7. Verify that Distance and Rate fields are shown.
  8. Go back online.
  9. Create a workspace.
  10. Create a distance expense.
  11. Open the distance expense.
  12. Click More > Split > Save.
  13. Open any of the splits and go to More > Duplicate.
  14. Open the duplicated split distance expense.
  15. Verify that the amount is the same as the split's amount, and that it is a normal distance expense (not a split). Note that for a map distance expense the waypoints will be removed and no map will display.
  16. Go to the self DM.
  17. Open any expense created earlier.
  18. Click More > Duplicate.
  19. Verify that an error modal is displayed.
  20. Create a P2P distance expense to any user.
  21. Open the distance expense.
  22. Click More > Duplicate.
  23. Verify that an error modal is displayed.
  24. Create a second workspace.
  25. Go to the second workspace chat.
  26. Create a distance expense.
  27. Delete the second workspace.
  28. Open the distance expense in the deleted workspace.
  29. Click More > Duplicate.
  30. Verify that an error modal is displayed.

Duplicating Per Diem (#82274)
Precondition:

  • Primary workspace has per diem rates.
  • Primary workspace has no other open expense reports
  1. Go to workspace chat.
  2. Click + > Create expense > Per diem.
  3. Create a per diem expense.
  4. Open the report.
  5. Click More > Duplicate.
  6. Verify that the report switches to the transaction list view with the duplicated expense highlighted.
  • Verify that no errors appear in the JS console

PR Author Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for the expected offline behavior in the Offline steps section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
    • I tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android: Native
    • Android: mWeb Chrome
    • iOS: Native
    • iOS: mWeb Safari
    • MacOS: Chrome / Safari
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I verified there are no new alerts related to the canBeMissing param for useOnyx
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product is localized by adding it to src/languages/* files and using the translation method
    • I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is either coming verbatim from figma or has been approved by marketing (in order to get marketing approval, ask the Bug Zero team member to add the Waiting for copy label to the issue)
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.ts or at the top of the file that uses the constant) are defined as such
  • I verified that if a function's arguments changed that all usages have also been updated correctly
  • If any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))
  • If new assets were added or existing ones were modified, I verified that:
    • The assets are optimized and compressed (for SVG files, run npm run compress-svg)
    • The assets load correctly across all supported platforms.
  • If the PR modifies code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • If the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the UI (e.g. new buttons, new UI components, changing the padding/spacing/sizing, moving components, etc) or modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label and/or tagged @Expensify/design so the design team can review the changes.
  • If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
  • I added unit tests for any new feature or bug fix in this PR to help automatically prevent regressions in this user flow.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.

Screenshots/Videos

Android: Native
android-app-2026-03-03_15.27.41.mp4
Android: mWeb Chrome
android-chrome-2026-03-03_15.33.39.mp4
iOS: Native
ios-app-2026-03-03_13.32.46.mp4
iOS: mWeb Safari
ios-safari-2026-03-03_14.21.12.mp4
MacOS: Chrome / Safari
desktop-chrome-2026-03-03_10.04.46.mp4

@codecov
Copy link

codecov bot commented Feb 12, 2026

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.

Files with missing lines Coverage Δ
src/libs/ReportSecondaryActionUtils.ts 92.20% <ø> (+0.18%) ⬆️
src/libs/actions/IOU/index.ts 72.48% <100.00%> (+<0.01%) ⬆️
src/libs/actions/IOU/Duplicate.ts 97.76% <75.00%> (-0.53%) ⬇️
src/components/MoneyRequestHeader.tsx 0.00% <0.00%> (ø)
src/components/MoneyReportHeader.tsx 0.00% <0.00%> (ø)
... and 11 files with indirect coverage changes

@JS00001
Copy link
Contributor

JS00001 commented Feb 19, 2026

@jjcoffee hows this one going?

@jjcoffee
Copy link
Contributor Author

@JS00001 Waiting on confirmation for the right behaviour here.

@melvin-bot
Copy link

melvin-bot bot commented Mar 2, 2026

Hey, I noticed you changed src/languages/en.ts in a PR from a fork. For security reasons, translations are not generated automatically for PRs from forks.

If you want to automatically generate translations for other locales, an Expensify employee will have to:

  1. Look at the code and make sure there are no malicious changes.
  2. Run the Generate static translations GitHub workflow. If you have write access and the K2 extension, you can simply click: [this button]

Alternatively, if you are an external contributor, you can run the translation script locally with your own OpenAI API key. To learn more, try running:

npx ts-node ./scripts/generateTranslations.ts --help

Typically, you'd want to translate only what you changed by running npx ts-node ./scripts/generateTranslations.ts --compare-ref main

@JS00001 JS00001 requested a review from hoangzinh March 2, 2026 15:23
@jjcoffee jjcoffee marked this pull request as ready for review March 2, 2026 15:32
@jjcoffee jjcoffee requested review from a team as code owners March 2, 2026 15:32
@jjcoffee
Copy link
Contributor Author

jjcoffee commented Mar 2, 2026

Unable to test the Per Diem fix (a6b912f) at the moment due to BE issues, but it follows the same idea as what we did for distance expenses, so should work fine.

Will add screenshots tomorrow since BE was down 😅. Please don't let that delay your review @hoangzinh 🙏

@jjcoffee
Copy link
Contributor Author

jjcoffee commented Mar 2, 2026

@JS00001 Could you run the generate translations workflow when you get a chance? Thanks 🙏

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a6b912fb36

ℹ️ 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".

@melvin-bot melvin-bot bot requested review from joekaufmanexpensify and removed request for a team March 2, 2026 15:45
@JS00001
Copy link
Contributor

JS00001 commented Mar 4, 2026

Ran

@OSBotify

This comment has been minimized.

@jjcoffee
Copy link
Contributor Author

jjcoffee commented Mar 4, 2026

@JS00001 Sorry, apparently I needed to merge main first! Can you run it again?

@JS00001
Copy link
Contributor

JS00001 commented Mar 4, 2026

Haha no worries, ran again

@OSBotify
Copy link
Contributor

OSBotify commented Mar 4, 2026

🦜 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 diff
diff --git a/src/languages/de.ts b/src/languages/de.ts
index 032bb690..e9e25d8e 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -1600,6 +1600,8 @@ const translations: TranslationDeepObject<typeof en> = {
         failedToSubmitViaDEW: (reason: string) => `Der Bericht konnte nicht übermittelt werden. ${reason}`,
         failedToAutoApproveViaDEW: (reason: string) => `Genehmigung über <a href="${CONST.CONFIGURE_EXPENSE_REPORT_RULES_HELP_URL}">Workspace-Regeln</a> fehlgeschlagen. ${reason}`,
         failedToApproveViaDEW: (reason: string) => `Genehmigung fehlgeschlagen. ${reason}`,
+        cannotDuplicateDistanceExpense:
+            'Sie können Entfernungsausgaben nicht über mehrere Arbeitsbereiche hinweg duplizieren, da sich die Sätze zwischen den Arbeitsbereichen unterscheiden können.',
     },
     transactionMerge: {
         listPage: {
@@ -8596,7 +8598,6 @@ Hier ist ein *Testbeleg*, um dir zu zeigen, wie es funktioniert:`,
                 addMember: 'Dieses Mitglied kann nicht hinzugefügt werden. Bitte versuche es erneut.',
                 vacationDelegate: 'Dieser Benutzer kann nicht als Urlaubsvertretung festgelegt werden. Bitte versuche es erneut.',
             },
-
             reportSuspiciousActivityPrompt: (email: string) =>
                 `Bist du sicher? Dadurch wird das Konto von <strong>${email}</strong> gesperrt. <br /><br /> Unser Team wird das Konto anschließend überprüfen und unbefugten Zugriff entfernen. Um den Zugriff wiederherzustellen, muss die Person mit Concierge zusammenarbeiten.`,
             reportSuspiciousActivityConfirmationPrompt: 'Wir überprüfen das Konto, um sicherzustellen, dass es sicher entsperrt werden kann, und melden uns bei Fragen über Concierge.',
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index 4e3309f1..fa75cf03 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -1606,6 +1606,7 @@ const translations: TranslationDeepObject<typeof en> = {
         failedToAutoApproveViaDEW: (reason: string) =>
             `impossible d’approuver via les <a href="${CONST.CONFIGURE_EXPENSE_REPORT_RULES_HELP_URL}">règles de l’espace de travail</a>. ${reason}`,
         failedToApproveViaDEW: (reason: string) => `échec de l’approbation. ${reason}`,
+        cannotDuplicateDistanceExpense: 'Vous ne pouvez pas dupliquer des dépenses de distance entre espaces de travail, car les taux peuvent différer d’un espace de travail à l’autre.',
     },
     transactionMerge: {
         listPage: {
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 21557b04..9e78b24f 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -1597,6 +1597,7 @@ const translations: TranslationDeepObject<typeof en> = {
         failedToAutoApproveViaDEW: (reason: string) =>
             `approvazione non riuscita tramite le <a href="${CONST.CONFIGURE_EXPENSE_REPORT_RULES_HELP_URL}">regole dello spazio di lavoro</a>. ${reason}`,
         failedToApproveViaDEW: (reason: string) => `approvazione non riuscita. ${reason}`,
+        cannotDuplicateDistanceExpense: 'Non puoi duplicare le spese chilometriche tra diversi spazi di lavoro perché le tariffe potrebbero essere diverse.',
     },
     transactionMerge: {
         listPage: {
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index 90d56d21..f7f87c71 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -1586,6 +1586,7 @@ const translations: TranslationDeepObject<typeof en> = {
         failedToSubmitViaDEW: (reason: string) => `レポートの送信に失敗しました。${reason}`,
         failedToAutoApproveViaDEW: (reason: string) => `<a href="${CONST.CONFIGURE_EXPENSE_REPORT_RULES_HELP_URL}">ワークスペースルール</a>で承認に失敗しました。${reason}`,
         failedToApproveViaDEW: (reason: string) => `承認に失敗しました。${reason}`,
+        cannotDuplicateDistanceExpense: '距離精算はワークスペースごとにレートが異なる可能性があるため、ワークスペース間で複製することはできません。',
     },
     transactionMerge: {
         listPage: {
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index 5b0bf0ee..7de585af 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -1594,6 +1594,7 @@ const translations: TranslationDeepObject<typeof en> = {
         failedToSubmitViaDEW: (reason: string) => `het is niet gelukt om het rapport in te dienen. ${reason}`,
         failedToAutoApproveViaDEW: (reason: string) => `goedkeuren via <a href="${CONST.CONFIGURE_EXPENSE_REPORT_RULES_HELP_URL}">werkruimte­regels</a> is mislukt. ${reason}`,
         failedToApproveViaDEW: (reason: string) => `goedkeuren mislukt. ${reason}`,
+        cannotDuplicateDistanceExpense: 'Je kunt afstandsvergoedingen niet dupliceren tussen werkruimtes, omdat de tarieven per werkruimte kunnen verschillen.',
     },
     transactionMerge: {
         listPage: {
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index 20148b5e..af0b92ef 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -1595,6 +1595,7 @@ const translations: TranslationDeepObject<typeof en> = {
         failedToAutoApproveViaDEW: (reason: string) =>
             `nie udało się zatwierdzić przez <a href="${CONST.CONFIGURE_EXPENSE_REPORT_RULES_HELP_URL}">zasady w przestrzeni roboczej</a>. ${reason}`,
         failedToApproveViaDEW: (reason: string) => `nie udało się zaakceptować. ${reason}`,
+        cannotDuplicateDistanceExpense: 'Nie możesz duplikować wydatków za przejazdy między przestrzeniami roboczymi, ponieważ stawki mogą się różnić między poszczególnymi przestrzeniami.',
     },
     transactionMerge: {
         listPage: {
@@ -8546,7 +8547,6 @@ Oto *paragon testowy*, żeby pokazać Ci, jak to działa:`,
                 vacationDelegate: 'Nie można ustawić tego użytkownika jako zastępującego na czas nieobecności. Spróbuj ponownie.',
             },
             cannotSetVacationDelegateForMember: (email: string) => `Nie możesz ustawić zastępstwa urlopowego dla ${email}, ponieważ jest on/ona obecnie zastępcą dla następujących członków:`,
-
             reportSuspiciousActivityPrompt: (email: string) =>
                 `Czy na pewno? To zablokuje konto użytkownika <strong>${email}</strong>. <br /><br /> Nasz zespół następnie przejrzy konto i usunie wszelki nieautoryzowany dostęp. Aby odzyskać dostęp, będą musieli współpracować z Concierge.`,
             reportSuspiciousActivityConfirmationPrompt: 'Przejrzymy konto, aby potwierdzić, że bezpiecznie je odblokować, i skontaktujemy się przez Concierge w razie pytań.',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index ba6fc695..f6b5054d 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -1591,6 +1591,7 @@ const translations: TranslationDeepObject<typeof en> = {
         failedToSubmitViaDEW: (reason: string) => `falha ao enviar o relatório. ${reason}`,
         failedToAutoApproveViaDEW: (reason: string) => `falha ao aprovar pelas <a href="${CONST.CONFIGURE_EXPENSE_REPORT_RULES_HELP_URL}">regras do workspace</a>. ${reason}`,
         failedToApproveViaDEW: (reason: string) => `falha ao aprovar. ${reason}`,
+        cannotDuplicateDistanceExpense: 'Você não pode duplicar despesas de distância entre espaços de trabalho porque as tarifas podem ser diferentes entre eles.',
     },
     transactionMerge: {
         listPage: {
@@ -8551,7 +8552,6 @@ Aqui está um *comprovante de teste* para mostrar como funciona:`,
                 vacationDelegate: 'Não foi possível definir este usuário como delegado de férias. Tente novamente.',
             },
             cannotSetVacationDelegateForMember: (email: string) => `Você não pode definir um procurador de férias para ${email} porque esta pessoa já é procuradora dos seguintes membros:`,
-
             reportSuspiciousActivityPrompt: (email: string) =>
                 `Tem certeza? Isso irá bloquear a conta de <strong>${email}</strong>. <br /><br /> Nossa equipe irá então analisar a conta e remover qualquer acesso não autorizado. Para recuperar o acesso, será necessário que trabalhem com a Concierge.`,
             reportSuspiciousActivityConfirmationPrompt: 'Vamos revisar a conta para verificar se é seguro desbloqueá-la e entraremos em contato via Concierge caso haja dúvidas.',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index 2b4d9d8d..479231cc 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -1563,6 +1563,7 @@ const translations: TranslationDeepObject<typeof en> = {
         failedToSubmitViaDEW: (reason: string) => `报表提交失败。${reason}`,
         failedToAutoApproveViaDEW: (reason: string) => `未能通过<a href="${CONST.CONFIGURE_EXPENSE_REPORT_RULES_HELP_URL}">工作区规则</a>批准。${reason}`,
         failedToApproveViaDEW: (reason: string) => `批准失败。${reason}`,
+        cannotDuplicateDistanceExpense: '你无法在不同工作区之间复制里程报销,因为各个工作区的费率可能不同。',
     },
     transactionMerge: {
         listPage: {

Note

You can apply these changes to your branch by copying the patch to your clipboard, then running pbpaste | git apply 😉

View workflow run

@jjcoffee
Copy link
Contributor Author

jjcoffee commented Mar 4, 2026

Translations done! cc @hoangzinh

Copy link
Contributor

@hoangzinh hoangzinh left a comment

Choose a reason for hiding this comment

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

LGTM 🚢

@melvin-bot melvin-bot bot requested a review from JS00001 March 4, 2026 17:01
Copy link
Contributor

@JS00001 JS00001 left a comment

Choose a reason for hiding this comment

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

Nice work! Please keep an eye out for blockers

@JS00001 JS00001 merged commit 95001cf into Expensify:main Mar 4, 2026
31 of 32 checks passed
@github-actions
Copy link
Contributor

github-actions bot commented Mar 4, 2026

🚧 @JS00001 has triggered a test Expensify/App build. You can view the workflow run here.

@OSBotify
Copy link
Contributor

OSBotify commented Mar 4, 2026

🚀 Deployed to staging by https://github.com/JS00001 in version: 9.3.31-0 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 failure ❌
🍎 iOS 🍎 success ✅

@lanitochka17
Copy link

Deploy Blocker ##84194 was identified to be related to this PR.

@mitarachim
Copy link

Deploy Blocker #84228 was identified to be related to this PR.

@OSBotify
Copy link
Contributor

OSBotify commented Mar 6, 2026

🚀 Deployed to production by https://github.com/blimpich in version: 9.3.31-12 🚀

platform result
🕸 web 🕸 success ✅
🤖 android 🤖 success ✅
🍎 iOS 🍎 success ✅

policyRecentlyUsedCurrencies,
betas,
customUnitPolicyID,
shouldHandleNavigation = true,
Copy link
Contributor

Choose a reason for hiding this comment

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

@jjcoffee I'm concerned that this is becoming a bad code smell. It looks like you're passing this down to handleNavigateAfterExpenseCreate(), so it's not your fault, but I think seeing the need to pass down a boolean argument is the exact reason why it's bad.

Functions ideally shouldn't have boolean arguments that change the flow of the function (it should be two separate functions).

The most common practice for navigation is to handle it in the view components. Action files should ONLY be for making API requests which trigger changes to Onyx.

If you could find a way to clean this up, I think it would be really great and help improve code quality.

cc @mountiny @luacmartins

Copy link
Contributor

@mountiny mountiny Mar 6, 2026

Choose a reason for hiding this comment

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

cc @jjcoffee @JS00001 could you please create an issue for this so we dont forget to refactor it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@tgolen Thanks for bringing this up! Definitely agree that it's not best practise, though as you point out it's already a pattern being used elsewhere in the same file, e.g.

if (shouldHandleNavigation) {

if (shouldHandleNavigation) {
// eslint-disable-next-line @typescript-eslint/no-deprecated
InteractionManager.runAfterInteractions(() => removeDraftTransactions());
}

So I would say that it makes sense to open up an issue to the community for a broader refactor to cover all instances.

Copy link
Contributor

Choose a reason for hiding this comment

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

I've created #84631 to improve this.

@parasharrajat
Copy link
Member

We had a issue where seconday action menu is not closed automatically after duplicate action #84237

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.