Repository navigation
Add Append custom tag list for accounting-connected workspaces on the indirectTagUploads beta - #103359
Conversation
… indirectTagUploads beta Co-authored-by: Cong Pham <[email protected]>
|
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 ddaa7f2e..5f866e68 100644
--- a/src/languages/el.ts
+++ b/src/languages/el.ts
@@ -7037,7 +7037,7 @@ _Για πιο αναλυτικές οδηγίες, [επισκεφθείτε τ
tagRules: 'Κανόνες ετικετών',
approverDescription: 'Έγκριση',
importTags: 'Εισαγωγή ετικετών',
- appendCustomTagList: 'Προσάρτηση προσαρμοσμένης λίστας ετικετών',
+ appendCustomTagList: 'Προσθήκη προσαρμοσμένης λίστας ετικετών',
importTagsSupportingText: 'Κωδικοποιήστε τα έξοδά σας με έναν τύπο ετικέτας ή με πολλούς.',
configureMultiLevelTags: 'Ρυθμίστε τη λίστα με τις ετικέτες σας για πολυεπίπεδη επισήμανση.',
importMultiLevelTagsSupportingText: `Δείτε εδώ μια προεπισκόπηση των ετικετών σας. Αν όλα φαίνονται σωστά, κάντε κλικ παρακάτω για να τις εισαγάγετε.`,
diff --git a/src/languages/es.ts b/src/languages/es.ts
index ab248668..88492037 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -6783,7 +6783,7 @@ ${amount} para ${merchant} - ${date}`,
tagRules: 'Reglas de etiquetas',
approverDescription: 'Aprobador',
importTags: 'Importar categorías',
- appendCustomTagList: 'Añadir lista de etiquetas personalizada',
+ appendCustomTagList: 'Anexar lista de etiquetas personalizadas',
importTagsSupportingText: 'Clasifica tus gastos con un tipo de etiqueta o con varios.',
configureMultiLevelTags: 'Configura etiquetas multinivel',
importMultiLevelTagsSupportingText: `Aquí tienes una vista previa de tus etiquetas. Si todo se ve bien, haz clic abajo para importarlas.`,
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index 8507ec08..6ef565c5 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -6934,7 +6934,7 @@ _Pour des instructions plus détaillées, [visitez notre site d’aide](${CONST.
tagRules: 'Règles de tags',
approverDescription: 'Approbateur',
importTags: 'Importer des tags',
- appendCustomTagList: 'Ajouter une liste de tags personnalisée',
+ appendCustomTagList: 'Ajouter une liste de tags personnalisés',
importTagsSupportingText: 'Codez vos dépenses avec un seul type de tag ou plusieurs.',
configureMultiLevelTags: 'Configurez votre liste de tags pour le multi-niveau.',
importMultiLevelTagsSupportingText: `Voici un aperçu de vos tags. Si tout semble correct, cliquez ci-dessous pour les importer.`,
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 27d543bc..a5630e12 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -6876,7 +6876,7 @@ _Per istruzioni più dettagliate, [visita il nostro sito di assistenza](${CONST.
tagRules: 'Regole dei tag',
approverDescription: 'Approvante',
importTags: 'Importa tag',
- appendCustomTagList: 'Aggiungi elenco di tag personalizzato',
+ appendCustomTagList: 'Aggiungi elenco di tag personalizzati',
importTagsSupportingText: 'Codifica le tue spese con un solo tipo di tag o con molti.',
configureMultiLevelTags: 'Configura il tuo elenco di tag per la codifica multilivello.',
importMultiLevelTagsSupportingText: `Ecco un’anteprima dei tuoi tag. Se ti sembra tutto corretto, fai clic qui sotto per importarli.`,
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index d71046b3..0bb52e57 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -6885,7 +6885,7 @@ _Aby uzyskać bardziej szczegółowe instrukcje, [odwiedź naszą stronę pomocy
tagRules: 'Zasady tagów',
approverDescription: 'Osoba zatwierdzająca',
importTags: 'Importuj tagi',
- appendCustomTagList: 'Dołącz niestandardową listę tagów',
+ appendCustomTagList: 'Dodaj własną listę tagów',
importTagsSupportingText: 'Oznaczaj wydatki jednym typem taga lub wieloma.',
configureMultiLevelTags: 'Skonfiguruj swoją listę tagów do tagowania wielopoziomowego.',
importMultiLevelTagsSupportingText: `Oto podgląd Twoich tagów. Jeśli wszystko wygląda dobrze, kliknij poniżej, aby je zaimportować.`,
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 002e53c2..1735ec54 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -6863,7 +6863,7 @@ _Para instruções mais detalhadas, [visite nossa central de ajuda](${CONST.NETS
tagRules: 'Regras de tag',
approverDescription: 'Aprovador',
importTags: 'Importar tags',
- appendCustomTagList: 'Anexar lista de tags personalizada',
+ appendCustomTagList: 'Anexar lista de tags personalizadas',
importTagsSupportingText: 'Classifique suas despesas com um tipo de etiqueta ou várias.',
configureMultiLevelTags: 'Configure sua lista de tags para marcação em vários níveis.',
importMultiLevelTagsSupportingText: `Aqui está uma prévia de suas tags. Se tudo estiver certo, clique abaixo para importá-las.`,
Note You can apply these changes to your branch by copying the patch to your clipboard, then running |
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.
|
|
🤖 Web test steps verification results: Without an accounting connection, Tags > More shows Settings, Import spreadsheet and Download CSV but not "Append custom tag list", whether the
To finish the last three steps, open the PR build on an account that has a NetSuite connection. Or use a dev build: add a |
|
The implementation matches the design, but on staging server the imported tags still override the existing tag lists instead of appending to them, the request does include CleanShot.2026-10-08.at.18.27.17.1.mp4Note that my test account isn't on the Alias email: [email protected] (primary email: [email protected]) |
|
@MelvinBot Update the Tests / Offline steps / QA steps sections in the PR description Finally update pr status to ready for review |
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
🤖 Done. I added your Tests, Offline tests, and QA Steps text to the PR description and removed the TODO placeholders. I also marked the PR ready for review. |
|
@MelvinBot Update test section |
|
I replaced the Tests section of the PR description with your steps. The other sections are unchanged, and QA Steps still says "Same as test section", so QA uses these steps too. I made two small fixes to your text:
I didn't change the Offline tests section. It still covers going offline before tapping "Append custom tag list". |
|
@suneox reckon you can finish this up today? |
@trjExpensify Overall the changeset looks good without errors and the API params match the spec. The only thing left is the BE confirmation from this comment |
|
@yuwenmemon can you look at this please? #103359 (comment) |
|
Ah crap, WAF param that I missed. |
|
Will spin up a fix in a sec |
…gList Co-authored-by: Cong Pham <[email protected]>
|
Merged the latest |
@yuwenmemon I'm still facing this issue, and no UI error is shown when the error occurs. CleanShot.2026-10-15.at.16.17.55.1.mp4
Could you please add my email to the indirectTagUploads test group? |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppCleanShot.2026-10-16.at.18.57.06.5.mp4Android: mWeb ChromeCleanShot.2026-10-16.at.18.57.06.mp4iOS: HybridAppCleanShot.2026-10-16.at.18.48.50.4.mp4iOS: mWeb SafariCleanShot.2026-10-16.at.18.46.03.3.mp4MacOS: Chrome / SafariCleanShot.2026-10-16.at.18.20.52.2.mp4 |
|
@suneox are you happy? If so, can you approve? |
|
@yuwenmemon could you update test step 5: "Verify the import completes and the imported result is the same as OldDot"? Currently only a single custom tag list can be appended CleanShot.2026-10-16.at.18.20.52.2.mp4 |
|
@suneox conflicts! |
|
Updated the test step for you as well |
|
@MelvinBot merge main & resolve conflict |
…gList Co-authored-by: Cong Pham <[email protected]> # Conflicts: # src/pages/workspace/tags/WorkspaceTagsPage.tsx
|
🤖 Merged The only conflict was in the
All three are used in the file and exported from |
|
🚧 yuwenmemon has triggered a test Expensify/App build. You can view the workflow run here. |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/yuwenmemon in version: 9.5.20-0 🚀
|
|
No help site update needed. Every user-facing change in this PR, the new Append custom tag list option and its import flow, only appears for users on the |
|
What account should we use to test the indirectTagUploads beta? Would Expensifail work? |
@IuliiaHerets Could you please provide the testing email? @yuwenmemon will add it to the I also cannot reproduce this bug on the latest staging. |
|
Deploy Blocker #105001 was identified to be related to this PR. |
|
🚀 Deployed to production by https://github.com/jasperhuangg in version: 9.5.20-5 🚀
Bundle Size Analysis (Sentry): |








Explanation of Change
Customers on the
indirectTagUploadsbeta can append a custom tag list next to their NetSuite (or other accounting connection) tags in Classic, but New Expensify had no way to do it. That blocks their NetSuite workspaces from migrating. This PR adds the same option to New Expensify. It uses the new backendappendToExistingListsparam onImportMultiLevelTags, so the accounting connection lists are kept instead of replaced.CONST.BETAS.INDIRECT_TAG_UPLOADS.!isMultiLevelTags || hasIndependentTags), the same as Classic.setSpreadsheetData) on the imported spreadsheet.ImportTagsPageandImportMultiLevelTagsSettingsPageno longer show not-found for a connected workspace when the beta is on and the user is appending. The independent/dependent toggle is hidden while appending, because appended lists are always independent.importMultiLevelTagssendsappendToExistingLists. When appending, a failed request no longer setshasMultipleTagLists: false, because the existing lists are kept.Fixed Issues
$ #102308
PROPOSAL: #102308 (comment)
Tests
Preconditions: your account has the
indirectTagUploadsbeta; the workspace is connected to NetSuite and currently has a single tag list.Offline tests
QA Steps
Same as test section
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectionAvatar, 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.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.AI Tests
npm run typecheck: passed.npm run lint-changed: passed.npm run spell-changed: passed.npm test -- tests/ui/WorkspaceTagsTest.tsx tests/unit/ImportSpreadsheetTest.ts tests/actions/PolicyTagTest.ts: 84/84 passed, including 3 new tests.react-compiler-compliance-check checkon the changed components:WorkspaceTagsPage,ImportTagsPage, andImportMultiLevelTagsSettingsPagepass.ImportSpreadsheet.tsxfails on existing code (import('xlsx')and a ref read during render), not on the lines changed here.oxfmtformatter couldn't run in this environment, so formatting was matched by hand. The web check couldn't run either, because the dev session rendered a blank page. Test accounts also can't get the beta or a NetSuite connection, so end-to-end testing needs an account on the beta.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari