Repository navigation
[NoQA] [Insights] Draw multi-series bar charts - #104085
luacmartins merged 18 commits into
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 bun ./scripts/generateTranslations.ts --helpTypically, you'd want to translate only what you changed by running |
🦜 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 0cea6445..1b9a1120 100644
--- a/src/languages/de.ts
+++ b/src/languages/de.ts
@@ -1176,7 +1176,7 @@ const translations: TranslationDeepObject<typeof en> = {
viewOnSpend: 'In Ausgaben anzeigen',
emptyState: {title: 'Nichts anzuzeigen', subtitle: 'Versuchen Sie, Ihre Kriterien oben anzupassen'},
noExpensesState: {title: 'Sehen Sie, wohin Ihr Geld fließt', subtitle: 'Sobald Sie Ausgaben haben, finden Sie Ausgabentrends, Top-Händler und mehr.'},
- compare: {label: 'Vergleichen', previousPeriod: 'Vorheriger Zeitraum', average: 'Durchschnitt'},
+ compare: {label: 'Vergleichen', previousPeriod: 'Vorheriger Zeitraum', average: 'Durchschnitt', typical: 'Typisch'},
},
allSettingsScreen: {
subscription: 'Abonnement',
diff --git a/src/languages/el.ts b/src/languages/el.ts
index 8ae8d6e7..48be3f96 100644
--- a/src/languages/el.ts
+++ b/src/languages/el.ts
@@ -1221,7 +1221,7 @@ const translations: TranslationDeepObject<typeof en> = {
viewOnSpend: 'Προβολή στο Spend',
emptyState: {title: 'Τίποτα προς εμφάνιση', subtitle: 'Δοκιμάστε να προσαρμόσετε τα κριτήριά σας παραπάνω'},
noExpensesState: {title: 'Δείτε πού πηγαίνουν τα χρήματά σας', subtitle: 'Μόλις έχετε δαπάνες, θα βλέπετε τάσεις δαπανών, κορυφαίους εμπόρους και άλλα.'},
- compare: {label: 'Σύγκριση', previousPeriod: 'Προηγούμενη περίοδος', average: 'Μέσος όρος'},
+ compare: {label: 'Σύγκριση', previousPeriod: 'Προηγούμενη περίοδος', average: 'Μέσος όρος', typical: 'Τυπικό'},
},
allSettingsScreen: {
subscription: 'Συνδρομή',
diff --git a/src/languages/es.ts b/src/languages/es.ts
index 23fc4be3..0c4acc63 100644
--- a/src/languages/es.ts
+++ b/src/languages/es.ts
@@ -1171,7 +1171,7 @@ const translations: TranslationDeepObject<typeof en> = {
viewOnSpend: 'Ver en Gastos',
emptyState: {title: 'Nada que mostrar', subtitle: 'Prueba a ajustar tus criterios de arriba'},
noExpensesState: {title: 'Ve adónde va tu dinero', subtitle: 'Una vez que tengas gastos, encontrarás tendencias de gasto, principales comercios y mucho más.'},
- compare: {label: 'Comparar', previousPeriod: 'Periodo anterior', average: 'Promedio'},
+ compare: {label: 'Comparar', previousPeriod: 'Periodo anterior', average: 'Promedio', typical: 'Típico'},
},
allSettingsScreen: {
subscription: 'Suscripcion',
diff --git a/src/languages/fr.ts b/src/languages/fr.ts
index 7f37b163..7300244c 100644
--- a/src/languages/fr.ts
+++ b/src/languages/fr.ts
@@ -1180,7 +1180,7 @@ const translations: TranslationDeepObject<typeof en> = {
title: 'Voyez où va votre argent',
subtitle: 'Une fois que vous aurez des dépenses, vous verrez des tendances de dépenses, les principaux marchands et plus encore.',
},
- compare: {label: 'Comparer', previousPeriod: 'Période précédente', average: 'Moyenne'},
+ compare: {label: 'Comparer', previousPeriod: 'Période précédente', average: 'Moyenne', typical: 'Typique'},
},
allSettingsScreen: {
subscription: 'Abonnement',
diff --git a/src/languages/it.ts b/src/languages/it.ts
index bd8eb402..5173e86a 100644
--- a/src/languages/it.ts
+++ b/src/languages/it.ts
@@ -1176,7 +1176,7 @@ const translations: TranslationDeepObject<typeof en> = {
viewOnSpend: 'Visualizza in Spese',
emptyState: {title: 'Niente da mostrare', subtitle: 'Prova a modificare i criteri qui sopra'},
noExpensesState: {title: 'Scopri dove va il tuo denaro', subtitle: 'Una volta che avrai delle spese, troverai tendenze di spesa, principali esercenti e altro ancora.'},
- compare: {label: 'Confronta', previousPeriod: 'Periodo precedente', average: 'Media'},
+ compare: {label: 'Confronta', previousPeriod: 'Periodo precedente', average: 'Media', typical: 'Tipico'},
},
allSettingsScreen: {
subscription: 'Abbonamento',
diff --git a/src/languages/ja.ts b/src/languages/ja.ts
index 7da59e4d..b0e3d84b 100644
--- a/src/languages/ja.ts
+++ b/src/languages/ja.ts
@@ -1164,7 +1164,7 @@ const translations: TranslationDeepObject<typeof en> = {
viewOnSpend: '支出で表示',
emptyState: {title: '表示するものはありません', subtitle: '上の条件を調整してみてください'},
noExpensesState: {title: 'お金の使い道を確認する', subtitle: '経費が登録されると、支出の傾向や上位の加盟店など、さまざまな情報を確認できるようになります。'},
- compare: {label: '比較', previousPeriod: '前の期間', average: '平均'},
+ compare: {label: '比較', previousPeriod: '前の期間', average: '平均', typical: '標準'},
},
allSettingsScreen: {
subscription: 'サブスクリプション',
diff --git a/src/languages/nl.ts b/src/languages/nl.ts
index b96c6121..0baa78b1 100644
--- a/src/languages/nl.ts
+++ b/src/languages/nl.ts
@@ -1175,7 +1175,7 @@ const translations: TranslationDeepObject<typeof en> = {
viewOnSpend: 'Bekijken in Uitgaven',
emptyState: {title: 'Niets om weer te geven', subtitle: 'Probeer je criteria hierboven aan te passen'},
noExpensesState: {title: 'Zie waar je geld naartoe gaat', subtitle: 'Zodra je uitgaven hebt, zie je bestedingspatronen, topverkopers en meer.'},
- compare: {label: 'Vergelijken', previousPeriod: 'Vorige periode', average: 'Gemiddeld'},
+ compare: {label: 'Vergelijken', previousPeriod: 'Vorige periode', average: 'Gemiddeld', typical: 'Typisch'},
},
allSettingsScreen: {
subscription: 'Abonnement',
diff --git a/src/languages/pl.ts b/src/languages/pl.ts
index 95e7b90a..8e943df6 100644
--- a/src/languages/pl.ts
+++ b/src/languages/pl.ts
@@ -1197,7 +1197,7 @@ const translations: TranslationDeepObject<typeof en> = {
viewOnSpend: 'Zobacz w Wydatkach',
emptyState: {title: 'Nic do wyświetlenia', subtitle: 'Spróbuj zmienić kryteria powyżej'},
noExpensesState: {title: 'Zobacz, na co idą twoje pieniądze', subtitle: 'Gdy będziesz mieć wydatki, zobaczysz trendy w wydawaniu, najważniejszych sprzedawców i więcej.'},
- compare: {label: 'Porównaj', previousPeriod: 'Poprzedni okres', average: 'Średnia'},
+ compare: {label: 'Porównaj', previousPeriod: 'Poprzedni okres', average: 'Średnia', typical: 'Typowe'},
},
allSettingsScreen: {
subscription: 'Subskrypcja',
diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts
index 0a675362..cbf83371 100644
--- a/src/languages/pt-BR.ts
+++ b/src/languages/pt-BR.ts
@@ -1175,7 +1175,7 @@ const translations: TranslationDeepObject<typeof en> = {
viewOnSpend: 'Ver em Gastos',
emptyState: {title: 'Nada para mostrar', subtitle: 'Tente ajustar seus critérios acima'},
noExpensesState: {title: 'Veja para onde vai o seu dinheiro', subtitle: 'Quando você tiver despesas, vai encontrar tendências de gastos, principais estabelecimentos e muito mais.'},
- compare: {label: 'Comparar', previousPeriod: 'Período anterior', average: 'Média'},
+ compare: {label: 'Comparar', previousPeriod: 'Período anterior', average: 'Média', typical: 'Típico'},
},
allSettingsScreen: {
subscription: 'Assinatura',
diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts
index 3b4ae9ff..f12bc305 100644
--- a/src/languages/zh-hans.ts
+++ b/src/languages/zh-hans.ts
@@ -1129,7 +1129,7 @@ const translations: TranslationDeepObject<typeof en> = {
viewOnSpend: '在支出中查看',
emptyState: {title: '没有可显示的内容', subtitle: '请尝试调整上面的条件'},
noExpensesState: {title: '查看你的资金流向', subtitle: '添加报销后,您就能查看消费趋势、主要商家等更多信息。'},
- compare: {label: '比较', previousPeriod: '上一期', average: '平均'},
+ compare: {label: '比较', previousPeriod: '上一期', average: '平均', typical: '典型'},
},
allSettingsScreen: {
subscription: '订阅',
Note You can apply these changes to your branch by copying the patch to your clipboard, then running |
|
@MelvinBot review, but only the changes on top of this other PR's branch: #103989 |
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.
|
Review: changes on top of [NoQA] [Insights] Draw Average mode baseline on Spend over timeI reviewed only the 6 commits from The changes look good. Please address two issues and consider one nit. 1. The $0 fallback may be wrong if the backend limits the compared rows. 2. Screen readers can't tell whether spend went up or down. Nit: A group with no spend in the compared period shows "∞%" in the table and tooltip (formatTooltipComparison.ts:45). Consider checking with design whether "New" would read better. What I checked that looks correct
|
I tested and it works correctly. The backend does not simply send top 10 of previous period, but values in previous period of items in current period's top 10. we still need to drop the limit, cause the limit is 5 and the backend sends 10 though
true, done, I went with "Up x%" and "Down x%"
👍 |
@dannymcclain @JmillsExpensify is this correct? up infinity for new items, shorter row for no change
|
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. |
Would love @JmillsExpensify to weigh in here with what he thinks, but |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c2236c57a5
ℹ️ 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".
|
That looks good to me, though defer to @dannymcclain when he's online in a bit. |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppScreen.Recording.2026-10-19.at.17.25.32.movAndroid: mWeb ChromeScreen.Recording.2026-10-19.at.17.30.52.moviOS: HybridAppiOS: mWeb SafariMacOS: Chrome / SafariScreen.Recording.2026-10-19.at.17.21.30.mov |
OlGierd03
left a comment
There was a problem hiding this comment.
Great work! Few small comments 🚀
| } | ||
|
|
||
| /** Resolves the period the Date filter covers and the one before it, which name the compared series. The backend picks the compared rows itself. */ | ||
| function resolveComparisonPeriods(dateFilter: InsightsFilters['date']): ChartComparisonPeriods | undefined { |
There was a problem hiding this comment.
NAB: Since we're mirroring the backend's previous-period math here, the label and the data could drift apart if that logic changes. Fine for now, but returning the resolved range from the backend could be a nice follow-up
There was a problem hiding this comment.
yeah, it's a very good idea and I wish we had thought about this when writing the design doc. I agree that we shouldn't block the PR on this and instead do it in a follow-up
|
🚧 JmillsExpensify has triggered a test Expensify/App build. You can view the workflow run here. |
This comment has been minimized.
This comment has been minimized.
JmillsExpensify
left a comment
There was a problem hiding this comment.
Looks really great!
Yeah that seems like a great starting point 👍 |
|
The build is looking good to me too |
|
@truph01 are you good with the PR as well? |
luacmartins
left a comment
There was a problem hiding this comment.
LGTM @truph01 please priority this review
|
I'm gonna merge this given the checklist here |
|
🚧 luacmartins 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/luacmartins in version: 9.5.15-1 🚀
|
|
🚀 Deployed to production by https://github.com/grgia in version: 9.5.15-3 🚀
Bundle Size Analysis (Sentry): |
|
Just noticed a small issue from this PR for Android native Sometimes we have this error in the console
To fix this, we can update the key for Bar |
thanks! we'll fix it |
|
included the fix here: #104578 |

Explanation of Change
Bar charts on Insights now draw the comparison picked in the Compare filter as a second bar in each group (both Average and Previous period)
buildChartSeriesdecides each bar's color, and the tooltip dots use the same colors.Fixed Issues
$ #103769
PROPOSAL: N/A
Tests
insightsPageandinsightsComparebetas. Go to Insights and set Date to This month and Compare to Average. Verify that Top spenders and Top merchants show two bars per group: the current one, and a lighter shade of the same color next to it.Offline tests
QA Steps
No 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
Nagranie.z.ekranu.2026-10-15.o.15.26.06.mov