Add filter negation feature#93909
Conversation
|
Hey, I noticed you changed If you want to automatically generate translations for other locales, an Expensify employee will have to:
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 --helpTypically, you'd want to translate only what you changed by running |
|
@DylanDylann 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] |
|
Can I run the translation script myself? |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d5746a1607
ℹ️ 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".
|
Btw, when we apply a negated HAS filter with a Tag value, it will be applied as "Tag: No tag". w.mp4It's from this code. It causes weird buggy behavior with the Has filter component, as shown in the video above. App/src/libs/SearchQueryUtils.ts Lines 1110 to 1112 in e5928ed Is that expected? |
|
🚧 @dubielzyk-expensify has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
This is looking great already @bernhardoj. Let's make this text
|
|
I'm not convinced we should use the is/is not in the chip itself:
I have to go and will have a noodle, but I think we might want an icon or do cc @Expensify/design @trjExpensify @JmillsExpensify |
Done |
I'm fine with what I'm seeing in the adhoc. |
|
@bernhardoj Looks like we're still missing support for
|
|
Status and workspace are still having their BE PRs worked on: https://github.com/Expensify/Auth/pull/22241 |
|
|
|
Updated filter label to use @JS00001 how is the BE going? Also, can you help run the translation script? |
|
We've merged the first PR, waiting on another cc @c3024 |
🦜 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/de.ts b/src/languages/de.ts
index 12d27fb508c..3e8c5c6288f 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -8542,6 +8542,7 @@ Fügen Sie weitere Ausgabelimits hinzu, um den Cashflow Ihres Unternehmens zu sc
[CONST.SEARCH.ACTION_FILTERS.PAY]: 'Bezahlen',
[CONST.SEARCH.ACTION_FILTERS.EXPORT]: 'Export',
},
+ filterType: {label: 'Filtertyp', has: {positive: 'hat', negative: 'hat nicht'}, is: {positive: 'ist', negative: 'ist nicht'}},
},
display: {
label: 'Anzeige',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 2791a9678c9..2f9f9299682 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -8358,6 +8358,7 @@ ${amount} para ${merchant} - ${date}`,
[CONST.SEARCH.ACTION_FILTERS.EXPORT]: 'Exportar',
},
reportField: (name, value) => `${name} es ${value}`,
+ filterType: {label: 'Tipo de filtro', has: {positive: 'tiene', negative: 'no tiene'}, is: {positive: 'es', negative: 'no es'}},
},
chartTitles: {
[CONST.SEARCH.GROUP_BY.FROM]: 'De',
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index cffe9d13cca..2d3dcc17e2a 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -8576,6 +8576,7 @@ Ajoutez davantage de règles de dépenses pour protéger la trésorerie de l’e
[CONST.SEARCH.ACTION_FILTERS.PAY]: 'Payer',
[CONST.SEARCH.ACTION_FILTERS.EXPORT]: 'Exporter',
},
+ filterType: {label: 'Type de filtre', has: {positive: 'a', negative: 'n’a pas'}, is: {positive: 'est', negative: 'n’est pas'}},
},
display: {
label: 'Affichage',
diff --git a/src/languages/it.ts b/src/languages/it.ts
index 4d43c2004aa..96fc08e8326 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -8531,6 +8531,7 @@ Aggiungi altre regole di spesa per proteggere il flusso di cassa aziendale.`,
[CONST.SEARCH.ACTION_FILTERS.PAY]: 'Paga',
[CONST.SEARCH.ACTION_FILTERS.EXPORT]: 'Esporta',
},
+ filterType: {label: 'Tipo di filtro', has: {positive: 'ha', negative: 'non ha'}, is: {positive: 'è', negative: 'non è'}},
},
display: {
label: 'Visualizza',
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index ae730f5c5f8..e89dc723301 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -8430,6 +8430,7 @@ ${reportName}`,
[CONST.SEARCH.ACTION_FILTERS.PAY]: '支払う',
[CONST.SEARCH.ACTION_FILTERS.EXPORT]: 'エクスポート',
},
+ filterType: {label: 'フィルタータイプ', has: {positive: '持っています', negative: '持っていません'}, is: {positive: 'は', negative: 'ではありません'}},
},
display: {
label: '表示',
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index 273fdc657b3..2f238e038d4 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -8498,6 +8498,7 @@ er bestedingsregels toe om de kasstroom van het bedrijf te beschermen.`,
[CONST.SEARCH.ACTION_FILTERS.PAY]: 'Betalen',
[CONST.SEARCH.ACTION_FILTERS.EXPORT]: 'Exporteren',
},
+ filterType: {label: 'Filtertype', has: {positive: 'heeft', negative: 'heeft niet'}, is: {positive: 'is', negative: 'is niet'}},
},
display: {
label: 'Weergave',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index e7222b6076b..4a964fb4ea5 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -8491,6 +8491,7 @@ Dodaj więcej zasad wydatków, żeby chronić płynność finansową firmy.`,
[CONST.SEARCH.ACTION_FILTERS.PAY]: 'Zapłać',
[CONST.SEARCH.ACTION_FILTERS.EXPORT]: 'Eksportuj',
},
+ filterType: {label: 'Typ filtra', has: {positive: 'ma', negative: 'nie ma'}, is: {positive: 'jest', negative: 'nie jest'}},
},
display: {
label: 'Wyświetl',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 77235795833..41af9cb5dd3 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -8489,6 +8489,7 @@ Adicione mais regras de gasto para proteger o fluxo de caixa da empresa.`,
[CONST.SEARCH.ACTION_FILTERS.PAY]: 'Pagar',
[CONST.SEARCH.ACTION_FILTERS.EXPORT]: 'Exportar',
},
+ filterType: {label: 'Tipo de filtro', has: {positive: 'tem', negative: 'não tem'}, is: {positive: 'é', negative: 'não é'}},
},
display: {
label: 'Exibir',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index 0276d29afd7..92897194fb5 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -8260,6 +8260,7 @@ ${reportName}`,
[CONST.SEARCH.ACTION_FILTERS.PAY]: '支付',
[CONST.SEARCH.ACTION_FILTERS.EXPORT]: '导出',
},
+ filterType: {label: '筛选类型', has: {positive: '有', negative: '没有'}, is: {positive: '是', negative: '不是'}},
},
display: {
label: '显示',
Note You can apply these changes to your branch by copying the patch to your clipboard, then running |
|
@bernhardoj The backend PR required for this PR has been deployed. Could you please check whether the backend responses are as required for this PR? |
|
@c3024 can you share how the BE would receive the query? Currently, this is the query built from the parser of Compared to normal filters such as merchant, where the If I enter |
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
|
TL;DR: A top-level field can't be negated. Negation ( A couple of key things:
{ "operator": "eq", "left": "policyID", "right": "0142A68214A45343" } // workspace:0142A68214A45343
{ "operator": "neq", "left": "policyID", "right": "0142A68214A45343" } // -workspace:0142A68214A45343
{ "operator": "eq", "left": "status", "right": "drafts" } // status:drafts
{ "operator": "neq", "left": "status", "right": "drafts" } // -status:draftsSo The reason it currently doesn't work is that in App/src/libs/SearchParser/searchParser.peggy Lines 221 to 254 in 9f3578c So, cc: @JS00001 |
|
Thanks for the clarification. I think I'll prepare a new PR for refactoring the policyID and status filter. I'm currently doing it, but I need another clarification. Filter like policyID is used for some filters, for example, exported to filters. Exported to filter will show the options scoped to the selected policyID (workspace). App/src/hooks/useExportedToFilterOptions.ts Lines 51 to 52 in 1eee891 But when a user applies a negated policyID, should we "select" the non-selected policyID? For example, we have policyID A, B, C, and D. The user applies a negated filter and chooses B. Should the exported to filter be scoped to policyID A, C, and D? |
|
@c3024 also, maybe we should remove
|
|
On the Lines 4688 to 4696 in 6f69123 So the backend will keep sending Looking at that data-loaded logic more closely, So I think the path is:
What do you think @luacmartins and @JS00001 ? |
|
I think updating to use the hash to compare makes sense! |
Yeah I think we should select the correct policies that should be included |
|
@JS00001 does QueueExportSearchToCSV and ExportSearchToCSV still require the |
|
@bernhardoj where is 'query' passed? I dont see any reference to it in the BE, is it a part of the jsonQuery? |
|
It's passed as a top-level param alongside jsonQuery. App/src/libs/actions/Search.ts Lines 1392 to 1406 in fb967fe App/src/libs/actions/Search.ts Lines 1335 to 1364 in fb967fe |
|
Hmm, yeah it looks like we just use jsonQuery, so we may not need |
|
Cool, thanks for the confirmation! |
|
Let me know when we are ready for another round of adhoc product testing. |
|
Opened a seperate PR (because it's quite big) to allow workspace and status to be negatable. cc: @aimane-chnaif |
|
Works for me. |





Explanation of Change
Fixed Issues
$ #93208
PROPOSAL:
Tests
Same as QA Steps
Offline tests
Same as QA Steps
QA Steps
[filter name] is: [value]/Has: [value](e.g., Merchant is: test, Has: Receipt)[filter name] is not: [value]/Doesn't have: [value](e.g., Merchant is not: test, Doesn't have: Receipt)For steps 3-7, if you want more test steps, follow this:
No filter is applied yet
For filter chip/bar:
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)Avatar, 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.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
web.mp4