Skip to content

Conversation

@andrewhumble
Copy link

@andrewhumble andrewhumble commented Nov 4, 2025

Fixes #1716

Add Sankey diagram report with three view modes (budgeted, spent, difference) to visualize money flow through categories.

Budgeted — Shows how income flows into your budget and is allocated across categories.

Screenshot 2025-11-04 at 10 34 34 AM

 
Spent — Displays actual spending by category from transactions.

Screenshot 2025-11-04 at 10 35 44 AM

 
Difference — Highlights budget vs. actual variance, showing overspent categories in red and unspent amounts. For a successfully zero-based budget, this should have no outgoing budget streams by the end of the month (i.e., $budgeted - spent = 0$ for each category).

Screenshot 2025-11-04 at 10 36 01 AM

@netlify
Copy link

netlify bot commented Nov 4, 2025

Deploy Preview for actualbudget ready!

Name Link
🔨 Latest commit e2de4d6
🔍 Latest deploy log https://app.netlify.com/projects/actualbudget/deploys/695d3a6e4a4f0d00080e380e
😎 Deploy Preview https://deploy-preview-6068.demo.actualbudget.org
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 4, 2025

Bundle Stats — desktop-client

Hey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle.

As this PR is updated, I'll keep you updated on how the bundle size is impacted.

Total

Files count Total bundle size % Changed
25 13.84 MB → 13.91 MB (+76.49 kB) +0.54%
Changeset
File Δ Size
node_modules/recharts/es6/chart/Sankey.js 🆕 +23.32 kB 0 B → 23.32 kB
src/components/reports/reports/Sankey.tsx 🆕 +15.23 kB 0 B → 15.23 kB
src/components/reports/graphs/SankeyGraph.tsx 🆕 +15.08 kB 0 B → 15.08 kB
src/components/reports/spreadsheets/sankey-spreadsheet.ts 🆕 +12.76 kB 0 B → 12.76 kB
src/components/reports/reports/SankeyCard.tsx 🆕 +5.3 kB 0 B → 5.3 kB
node_modules/es-toolkit/dist/compat/math/sumBy.js 🆕 +931 B 0 B → 931 B
node_modules/es-toolkit/dist/array/maxBy.js 🆕 +722 B 0 B → 722 B
node_modules/es-toolkit/dist/compat/math/maxBy.js 🆕 +641 B 0 B → 641 B
node_modules/es-toolkit/compat/maxBy.js 🆕 +192 B 0 B → 192 B
node_modules/es-toolkit/compat/sumBy.js 🆕 +192 B 0 B → 192 B
node_modules/es-toolkit/compat/maxBy.js?commonjs-es-import 🆕 +114 B 0 B → 114 B
node_modules/es-toolkit/compat/sumBy.js?commonjs-es-import 🆕 +114 B 0 B → 114 B
node_modules/es-toolkit/dist/compat/math/maxBy.js?commonjs-exports 🆕 +17 B 0 B → 17 B
node_modules/es-toolkit/dist/compat/math/sumBy.js?commonjs-exports 🆕 +17 B 0 B → 17 B
node_modules/es-toolkit/dist/array/maxBy.js?commonjs-exports 🆕 +17 B 0 B → 17 B
node_modules/recharts/es6/context/chartDataContext.js 📈 +301 B (+56.47%) 533 B → 834 B
src/components/reports/ReportRouter.tsx 📈 +538 B (+11.00%) 4.78 kB → 5.3 kB
src/hooks/useFeatureFlag.ts 📈 +23 B (+5.50%) 418 B → 441 B
node_modules/recharts/es6/context/chartLayoutContext.js 📈 +210 B (+4.22%) 4.86 kB → 5.06 kB
src/components/reports/Overview.tsx 📈 +560 B (+2.85%) 19.17 kB → 19.72 kB
src/components/settings/Experimental.tsx 📈 +241 B (+2.50%) 9.42 kB → 9.66 kB
node_modules/recharts/es6/chart/PolarChart.js 📈 +20 B (+0.52%) 3.77 kB → 3.79 kB
node_modules/recharts/es6/cartesian/Line.js 📈 +46 B (+0.21%) 21.66 kB → 21.7 kB
node_modules/recharts/es6/cartesian/XAxis.js 📈 +4 B (+0.07%) 5.69 kB → 5.69 kB
src/components/reports/spreadsheets/net-worth-spreadsheet.ts 📈 +2 B (+0.04%) 5.32 kB → 5.32 kB
src/components/reports/reports/NetWorthCard.tsx 📈 +2 B (+0.02%) 8.01 kB → 8.01 kB
src/components/reports/reports/NetWorth.tsx 📈 +2 B (+0.02%) 10.19 kB → 10.19 kB
View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

Asset File Size % Changed
static/js/ReportRouter.js 1.08 MB → 1.16 MB (+75.74 kB) +6.84%
static/js/index.js 9.02 MB → 9.02 MB (+775 B) +0.01%

Smaller

No assets were smaller

Unchanged

Asset File Size % Changed
static/js/indexeddb-main-thread-worker-e59fee74.js 12.94 kB 0%
static/js/workbox-window.prod.es5.js 5.64 kB 0%
static/js/da.js 110.41 kB 0%
static/js/de.js 163.91 kB 0%
static/js/en-GB.js 6.84 kB 0%
static/js/en.js 154.21 kB 0%
static/js/fr.js 171.96 kB 0%
static/js/it.js 165.78 kB 0%
static/js/nl.js 99.93 kB 0%
static/js/pl.js 90.75 kB 0%
static/js/pt-BR.js 147.06 kB 0%
static/js/ru.js 112.25 kB 0%
static/js/th.js 187.39 kB 0%
static/js/uk.js 213.33 kB 0%
static/js/resize-observer.js 18.37 kB 0%
static/js/BackgroundImage.js 120.48 kB 0%
static/js/narrow.js 611.45 kB 0%
static/js/TransactionList.js 101.29 kB 0%
static/js/wide.js 185.6 kB 0%
static/js/AppliedFilters.js 9.42 kB 0%
static/js/usePayeeRuleCounts.js 11.79 kB 0%
static/js/useTransactionBatchActions.js 12.98 kB 0%
static/js/FormulaEditor.js 1.08 MB 0%

@github-actions
Copy link
Contributor

github-actions bot commented Nov 4, 2025

Bundle Stats — loot-core

Hey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle.

As this PR is updated, I'll keep you updated on how the bundle size is impacted.

Total

Files count Total bundle size % Changed
1 5.79 MB 0%

Changeset

No files were changed

View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

No assets were bigger

Smaller

No assets were smaller

Unchanged

Asset File Size % Changed
kcab.worker.B0YqDUqb.js 5.79 MB 0%

@andrewhumble andrewhumble changed the title Implement Sankey graph report [WIP] Implement Sankey graph report Nov 4, 2025
Auto-generated by VRT workflow

PR: actualbudget#6068
@github-actions
Copy link
Contributor

github-actions bot commented Nov 4, 2025

✅ VRT screenshots have been automatically updated.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 4, 2025

✅ VRT screenshots have been automatically updated.

@YesWeCandrew
Copy link

Hi @andrewhumble

This is such an awesome feature, thank you for working on it. The three modes are very useful, especially the 'Difference' option. Not many of the other chart options can present progress to budget as well as this one can.

I know this is a WIP, so please feel free to ignore this suggestion, but I found the word 'Budget' here a little confusing, because the value it's referring to is labelled as 'Available Funds' in the budget view. Perhaps we should rename that to Available Funds?

image

IMO, this looks like a great feature and could be released as is, but if you are looking to expand it out with some more features, I'd be keen to see:

  • More date options (so you can see the Sankey over last year, last x months etc)
  • The Spend option still include the income information, as this helps complete the picture more and would show people their savings for the period
  • Super stretch goal: If we could overlay the spend information on top of the budget one, by using perhaps shading or colour to indicate how spent the category is, that would be amazing.

Sorry to be chucking loads of ideas at you - feel free to ignore me completely. I don't know TypeScript much but if I can help at all with testing / ideating, very happy to!

@andrewhumble
Copy link
Author

Hi @YesWeCandrew. Thank you for your comment and glad you like the feature. To respond to your suggestions:

  • "Perhaps we should rename that to Available Funds?"
    • After taking a second look at it, I agree as this would align with the first line item on the budget itself. The goal of the "Budgeted" version is to provide a different view of the user's budget, so keeping this 1:1 when possible is definitely the goal. I will change that for the "Difference" version as well.
  • "More date options (so you can see the Sankey over last year, last x months etc)"
    • While I agree this would be a useful feature, it would only really work for the "Spent" view by querying for all incoming and outgoing transactions to show their flow for the given time horizon. I don't think it would make sense for the "Budgeted" or "Difference" views as those are tied to the monthly budgets themselves. Perhaps we could add a 4th "Over Time" view to have that functionality distinct from the others. For the sake of keeping this PR solely for the initial release of the Sankey reports, I will plan to implement the Sankey over time view in a different PR.
  • "The Spend option still include the income information, as this helps complete the picture more and would show people their savings for the period"
    • Sure, I agree that makes sense and will help quickly highlight overspending vs saving. Here's an example below. Let me know how that looks. I'll go ahead and push these changes as well if you'd like to take a look.
  • "Super stretch goal: If we could overlay the spend information on top of the budget one, by using perhaps shading or colour to indicate how spent the category is, that would be amazing."
    • I actually experimented with this a bit but haven't found a way to do it cleanly quite yet, but I agree it would be an awesome improvement for the "Difference" view in the future.

Feel free to throw any more idea or critiques my way! Totally open to it and appreciate your help and thoughts here :)

Screenshot 2025-11-07 at 10 24 22 PM

@tomasgriffin
Copy link
Contributor

tomasgriffin commented Nov 8, 2025

There have been a couple implementations of a Sankey report already, I haven’t had a chance to play around with it yet but does it cover the edge cases identified in those PRs?

Would love to see this merged as it’s something I’d love to use!

https://github.com/actualbudget/actual/pulls?q=is%3Apr+is%3Aclosed+sankey+

@andrewhumble
Copy link
Author

@tomasgriffin This is based off of @spezzino's PR, so all of the concerns mentioned there should be inheritantly addressed, for the most part. My PR extends @spezzino's work (essential the "Spent" view that I have) by adding the "Budgeted" view, which leverages the budget instead of querying for transactions, along with the "Difference" view.

I also see this PR from @shaankhosla, which looks to be an old feature that was merged for some time but rolled back to due not being maintained. I see a comment for adding the percentages alongside the flow values, which I can add if that is desired. It might begin to crowd the view, so maybe putting it in the popup on hover would be cleaner.

I also see some other UI-related comments from @MatissJanis and looks like the one about the view from the Reports dashboard is applicable, so will fix that.

Overall it looks like all the main concerns are already covered, but happy to change anything based on feedback. Given this will be behind a feature flag, we can also continue to test and refine once it is merged.

Thanks for the comment @tomasgriffin!

@andrewhumble andrewhumble marked this pull request as ready for review November 8, 2025 14:13
@actual-github-bot actual-github-bot bot changed the title [WIP] Implement Sankey graph report Implement Sankey graph report Nov 8, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 8, 2025

Walkthrough

Adds a Sankey report feature to the desktop client: new React UI (Sankey, SankeyCard, SankeyGraph), data-preparation utilities (sankey-spreadsheet) supporting budgeted/spent/difference modes and category filters, dashboard widget support and types (SankeyWidget), routes (/sankey, /sankey/:id), an experimental feature flag (sankeyReport), E2E page model and tests, and associated prefs/type updates.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45–75 minutes

Areas needing focused review:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx — custom Recharts node/link rendering, compact/collapse logic, tooltip, privacy handling, and canvas/DOM performance.
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts — three-mode data pipelines, category filtering (filterCategoryGroups), aggregation correctness, handling of negatives, and transformToSankeyData mapping.
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx and SankeyCard.tsx — state management (filters, month/timeFrame, mode), save/persist flows, conditional rendering for “no data,” and async data handling.
  • Types and prefs — packages/loot-core/src/types/models/dashboard.ts and packages/loot-core/src/types/prefs.ts for SankeyWidget and feature-flag additions; ensure type alignment and backwards compatibility.
  • Feature-flag and settings wiring — packages/desktop-client/src/hooks/useFeatureFlag.ts and packages/desktop-client/src/components/settings/Experimental.tsx for default state and UI exposure.
  • E2E tests and page models — packages/desktop-client/e2e/page-models/sankey-page.ts, sankey.test.ts, and reports-page.ts for selector robustness, timing/wait logic, and screenshot stability.

Pre-merge checks and finishing touches

✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Implement Sankey graph report' clearly and concisely summarizes the main change—adding a Sankey diagram report feature to the application.
Description check ✅ Passed The description is related to the changeset, explaining the three view modes (Budgeted, Spent, Difference), providing context via screenshots, and linking to the fixed issue #1716.
Linked Issues check ✅ Passed The PR meets the objectives from issue #1716: implements a Sankey diagram in Reports with category-based flows, supports period/filtering selection, enables income-to-category visualization, and provides Budgeted, Spent, and Difference modes.
Out of Scope Changes check ✅ Passed All code changes are directly related to implementing the Sankey report feature: new components, page models, spreadsheet functions, routing, feature flagging, and type definitions are all in scope.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c1a3582 and 1e6d4d5.

📒 Files selected for processing (1)
  • packages/desktop-client/src/components/settings/Experimental.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-01-18T20:08:55.203Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4181
File: packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx:252-254
Timestamp: 2025-01-18T20:08:55.203Z
Learning: Notification messages in BudgetTable.jsx will be translated in a separate PR to handle all translations together, as there are multiple messages to go through.

Applied to files:

  • packages/desktop-client/src/components/settings/Experimental.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: Generate VRT Updates
  • GitHub Check: lint
  • GitHub Check: validate-cli
  • GitHub Check: test
  • GitHub Check: Wait for Netlify build to finish
  • GitHub Check: Functional Desktop App
  • GitHub Check: Analyze
  • GitHub Check: build (ubuntu-22.04)
  • GitHub Check: build (windows-latest)
  • GitHub Check: build (macos-latest)
  • GitHub Check: web
  • GitHub Check: compare
🔇 Additional comments (1)
packages/desktop-client/src/components/settings/Experimental.tsx (1)

167-172: No action needed—feedback link is correct.

The feedback link to issue #1919 is appropriate. Issue #1716 is the original feature request that this PR implements, while issue #1919 is the dedicated feedback/discussion channel for the Sankey chart (labeled "feedback" with 24 comments tracking known issues and upcoming additions). Linking to #1919 allows users to report issues and provide feedback about the experimental feature.

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example:

"Create a concise high-level summary as a bullet-point list. Then include a Markdown table showing lines added and removed by each contributing author."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 10

🧹 Nitpick comments (2)
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (1)

256-276: Extract magic string to a named constant.

The string 'Available Funds' appears in multiple locations (lines 119, 257, 364, 402), making it error-prone if the label needs to change. Consider extracting it to a constant at the top of the file.

Add this constant near the top of the file:

const BUDGET_NODE_NAME = 'Available Funds';

Then replace all hardcoded occurrences with this constant.

packages/desktop-client/e2e/page-models/sankey-page.ts (1)

36-55: Avoid fixed 500 ms sleeps in the page model

Hard-coded waitForTimeout(500) calls make the test suite brittle and slow. Please wait for a meaningful UI state (e.g., expect the graph container or updated button to become visible/enabled) instead of inserting fixed sleeps.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2e7e0b5 and 815ddc8.

⛔ Files ignored due to path filters (19)
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--6ab37-roup-name-opens-the-category-group-menu-modal-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--94a79-roup-name-opens-the-category-group-menu-modal-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--bbde3-roup-name-opens-the-category-group-menu-modal-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--5f098-roup-name-opens-the-category-group-menu-modal-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--929be-roup-name-opens-the-category-group-menu-modal-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--dc927-roup-name-opens-the-category-group-menu-modal-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-help-menu-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-help-menu-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-help-menu-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/settings.mobile.test.ts-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-4-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/settings.mobile.test.ts-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-5-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/settings.mobile.test.ts-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-6-chromium-linux.png is excluded by !**/*.png
  • upcoming-release-notes/6068.md is excluded by !**/*.md
📒 Files selected for processing (13)
  • packages/desktop-client/e2e/page-models/reports-page.ts (2 hunks)
  • packages/desktop-client/e2e/page-models/sankey-page.ts (1 hunks)
  • packages/desktop-client/e2e/sankey.test.ts (1 hunks)
  • packages/desktop-client/src/components/reports/Overview.tsx (4 hunks)
  • packages/desktop-client/src/components/reports/ReportRouter.tsx (2 hunks)
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (1 hunks)
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx (1 hunks)
  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx (1 hunks)
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (1 hunks)
  • packages/desktop-client/src/components/settings/Experimental.tsx (1 hunks)
  • packages/desktop-client/src/hooks/useFeatureFlag.ts (1 hunks)
  • packages/loot-core/src/types/models/dashboard.ts (2 hunks)
  • packages/loot-core/src/types/prefs.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Prefer type over interface in TypeScript
Avoid enum; use objects or maps instead
Avoid any and unknown unless absolutely necessary
Avoid type assertions (as, non-null !); prefer satisfies for narrowing
Use inline type imports: import { type X } from '...'
Favor functional/declarative patterns; avoid classes
Use the function keyword for pure functions
Use named exports for components and utilities (avoid default exports except specific cases)
Maintain import order groups (React, Node built-ins, externals, Actual packages, parent, sibling, index) with newlines between groups
Do not directly reference platform-specific imports by extension (.api, .web, .electron)

Files:

  • packages/desktop-client/e2e/sankey.test.ts
  • packages/desktop-client/e2e/page-models/reports-page.ts
  • packages/loot-core/src/types/prefs.ts
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/Overview.tsx
  • packages/desktop-client/src/hooks/useFeatureFlag.ts
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/settings/Experimental.tsx
  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
  • packages/desktop-client/e2e/page-models/sankey-page.ts
  • packages/desktop-client/src/components/reports/ReportRouter.tsx
  • packages/loot-core/src/types/models/dashboard.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Do not use console.*; use the logger instead
Import uuid with destructuring: import { v4 as uuidv4 } from 'uuid'

Files:

  • packages/desktop-client/e2e/sankey.test.ts
  • packages/desktop-client/e2e/page-models/reports-page.ts
  • packages/loot-core/src/types/prefs.ts
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/Overview.tsx
  • packages/desktop-client/src/hooks/useFeatureFlag.ts
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/settings/Experimental.tsx
  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
  • packages/desktop-client/e2e/page-models/sankey-page.ts
  • packages/desktop-client/src/components/reports/ReportRouter.tsx
  • packages/loot-core/src/types/models/dashboard.ts
**/*.{test,spec}.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Name unit tests with .test or .spec extensions (Vitest)

Files:

  • packages/desktop-client/e2e/sankey.test.ts
packages/desktop-client/e2e/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Place E2E tests for web/desktop under packages/desktop-client/e2e/ (Playwright)

Files:

  • packages/desktop-client/e2e/sankey.test.ts
  • packages/desktop-client/e2e/page-models/reports-page.ts
  • packages/desktop-client/e2e/page-models/sankey-page.ts
packages/loot-core/**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

Do not import @actual-app/web/* from loot-core

Files:

  • packages/loot-core/src/types/prefs.ts
  • packages/loot-core/src/types/models/dashboard.ts
packages/{desktop-client,component-library}/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

packages/{desktop-client,component-library}/src/**/*.{ts,tsx}: All user-facing strings must be translated
Prefer <Trans> component over t() when possible
Do not use React.* namespace imports; use named imports
Use theme tokens; do not import colors directly

Files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/Overview.tsx
  • packages/desktop-client/src/hooks/useFeatureFlag.ts
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/settings/Experimental.tsx
  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
  • packages/desktop-client/src/components/reports/ReportRouter.tsx
packages/{desktop-client,component-library}/src/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

packages/{desktop-client,component-library}/src/**/*.tsx: Do not use React.FC/React.FunctionComponent; type props directly
Avoid unstable nested components in JSX
Prefer declarative, minimal JSX; avoid unnecessary curly braces and prefer concise conditional expressions (condition && <Component />)

Files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/Overview.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/settings/Experimental.tsx
  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/ReportRouter.tsx
packages/desktop-client/src/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Use <Link> instead of <a> tags

Files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/Overview.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/settings/Experimental.tsx
  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/ReportRouter.tsx
packages/desktop-client/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

packages/desktop-client/src/**/*.{ts,tsx}: Use custom navigation hook from src/hooks instead of react-router directly
Use useDispatch, useSelector, useStore from src/redux (not react-redux)
Use absolute imports in desktop-client

Files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/Overview.tsx
  • packages/desktop-client/src/hooks/useFeatureFlag.ts
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/settings/Experimental.tsx
  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
  • packages/desktop-client/src/components/reports/ReportRouter.tsx
🧠 Learnings (18)
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/desktop-client/e2e/**/*.ts : Place E2E tests for web/desktop under `packages/desktop-client/e2e/` (Playwright)

Applied to files:

  • packages/desktop-client/e2e/sankey.test.ts
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to **/*.mobile.test.ts : Suffix mobile E2E tests with `.mobile.test.ts`

Applied to files:

  • packages/desktop-client/e2e/sankey.test.ts
📚 Learning: 2024-10-08T15:46:15.739Z
Learnt from: UnderKoen
Repo: actualbudget/actual PR: 3499
File: packages/desktop-client/e2e/accounts.test.js:134-136
Timestamp: 2024-10-08T15:46:15.739Z
Learning: In the 'accounts.test.js' test suite, when testing CSV import functionality, the test results are verified visually through screenshots rather than with explicit assertions.

Applied to files:

  • packages/desktop-client/e2e/sankey.test.ts
📚 Learning: 2025-01-22T15:51:34.900Z
Learnt from: joel-jeremy
Repo: actualbudget/actual PR: 4217
File: packages/desktop-client/e2e/fixtures.ts:26-28
Timestamp: 2025-01-22T15:51:34.900Z
Learning: In Playwright, `locator.page` is a function that returns the page that the locator belongs to, not a property. The correct way to check if a locator has a page is using `typeof locator.page === 'function'`.

Applied to files:

  • packages/desktop-client/e2e/page-models/reports-page.ts
  • packages/desktop-client/e2e/page-models/sankey-page.ts
📚 Learning: 2024-09-17T20:04:47.663Z
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3458
File: packages/loot-core/src/client/state-types/prefs.d.ts:5-5
Timestamp: 2024-09-17T20:04:47.663Z
Learning: In future reviews, ensure that changes related to `PrefsState` in `prefs.d.ts` do not incorrectly assume necessary updates in other parts of the codebase. Verify the impact thoroughly before making suggestions.

Applied to files:

  • packages/loot-core/src/types/prefs.ts
📚 Learning: 2025-10-12T04:07:06.002Z
Learnt from: lelemm
Repo: actualbudget/actual PR: 5786
File: packages/api/tsconfig.dist.json:14-14
Timestamp: 2025-10-12T04:07:06.002Z
Learning: In the Actual Budget codebase, when rootDir is removed from packages/loot-core/tsconfig.api.json to allow referencing files outside the loot-core directory, the declaration output structure changes. The path alias for loot-core in packages/api/tsconfig.dist.json must be updated from "./types/loot-core/src/*" to "./types/loot-core/loot-core/src/*" to match the new emitted declaration paths, as TypeScript preserves the full directory structure from the project root when rootDir is not specified.

Applied to files:

  • packages/loot-core/src/types/prefs.ts
  • packages/loot-core/src/types/models/dashboard.ts
📚 Learning: 2024-11-01T20:29:18.673Z
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3744
File: packages/desktop-client/src/components/reports/reports/CustomReport.tsx:157-157
Timestamp: 2024-11-01T20:29:18.673Z
Learning: In the `CustomReport` component (`packages/desktop-client/src/components/reports/reports/CustomReport.tsx`), the session storage references are necessary and should not be removed.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/Overview.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/ReportRouter.tsx
📚 Learning: 2024-10-24T17:05:41.415Z
Learnt from: joel-jeremy
Repo: actualbudget/actual PR: 3685
File: packages/desktop-client/src/components/accounts/Account.tsx:655-665
Timestamp: 2024-10-24T17:05:41.415Z
Learning: The Account component in 'packages/desktop-client/src/components/accounts/Account.tsx' is being rewritten in a separate PR.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
📚 Learning: 2024-10-04T18:16:45.140Z
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3566
File: packages/desktop-client/src/components/reports/Overview.tsx:100-101
Timestamp: 2024-10-04T18:16:45.140Z
Learning: In `packages/desktop-client/src/components/reports/Overview.tsx`, when filtering `baseLayout`, if `item.type === 'custom-report'`, `item.meta.id` will always be defined.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/Overview.tsx
  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/ReportRouter.tsx
📚 Learning: 2024-11-12T19:52:52.889Z
Learnt from: lelemm
Repo: actualbudget/actual PR: 3792
File: packages/desktop-client/src/components/reports/reports/Summary.tsx:134-161
Timestamp: 2024-11-12T19:52:52.889Z
Learning: In `packages/desktop-client/src/components/reports/reports/Summary.tsx`, API calls like `get-earliest-transaction` are used without explicit error handling to maintain consistency with other components.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2024-10-10T02:29:05.655Z
Learnt from: tlesicka
Repo: actualbudget/actual PR: 3593
File: packages/desktop-client/src/components/sidebar/Sidebar.tsx:112-116
Timestamp: 2024-10-10T02:29:05.655Z
Learning: In `packages/desktop-client/src/components/sidebar/BudgetName.tsx`, the `BudgetName` component consists of three parts: `BudgetName`, `EditBudgetName`, and the Menu. Keeping `EditBudgetName` as a separate component helps maintain cleaner code by separating concerns.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.{ts,tsx} : Do not use `React.*` namespace imports; use named imports

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-06-03T23:19:44.814Z
Learnt from: elijaholmos
Repo: actualbudget/actual PR: 5076
File: packages/desktop-client/src/components/CommandBar.tsx:70-70
Timestamp: 2025-06-03T23:19:44.814Z
Learning: The useReports hook in packages/desktop-client/src/hooks/useReports.ts always returns an array for the data property due to initialData: [] and default value fallback (data: customReports = []), so it never returns undefined and doesn't need additional undefined checks when used.

Applied to files:

  • packages/desktop-client/src/components/reports/Overview.tsx
  • packages/desktop-client/src/hooks/useFeatureFlag.ts
📚 Learning: 2025-06-03T23:19:44.814Z
Learnt from: elijaholmos
Repo: actualbudget/actual PR: 5076
File: packages/desktop-client/src/components/CommandBar.tsx:70-70
Timestamp: 2025-06-03T23:19:44.814Z
Learning: The useReports hook in packages/desktop-client/src/hooks/useReports.ts always returns an array for the data property due to the ternary operator at line 62: `queryData ? [...queryData] : []`, ensuring data is never undefined even if the underlying query returns undefined.

Applied to files:

  • packages/desktop-client/src/components/reports/Overview.tsx
  • packages/desktop-client/src/hooks/useFeatureFlag.ts
📚 Learning: 2025-01-18T20:08:55.203Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4181
File: packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx:252-254
Timestamp: 2025-01-18T20:08:55.203Z
Learning: Notification messages in BudgetTable.jsx will be translated in a separate PR to handle all translations together, as there are multiple messages to go through.

Applied to files:

  • packages/desktop-client/src/components/settings/Experimental.tsx
📚 Learning: 2025-08-16T16:42:08.306Z
Learnt from: sjones512
Repo: actualbudget/actual PR: 5554
File: packages/desktop-client/src/components/reports/spreadsheets/crossover-spreadsheet.ts:7-8
Timestamp: 2025-08-16T16:42:08.306Z
Learning: In the Actual Budget codebase, it's the established pattern and acceptable to import useSpreadsheet as a type-only import and then use ReturnType<typeof useSpreadsheet> in type annotations. This pattern is used consistently across all spreadsheet files including custom-spreadsheet.ts, grouped-spreadsheet.ts, spending-spreadsheet.ts, net-worth-spreadsheet.ts, cash-flow-spreadsheet.tsx, calendar-spreadsheet.ts, summary-spreadsheet.ts, and crossover-spreadsheet.ts.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
  • packages/desktop-client/src/components/reports/ReportRouter.tsx
📚 Learning: 2025-08-16T16:42:08.306Z
Learnt from: sjones512
Repo: actualbudget/actual PR: 5554
File: packages/desktop-client/src/components/reports/spreadsheets/crossover-spreadsheet.ts:7-8
Timestamp: 2025-08-16T16:42:08.306Z
Learning: In the Actual Budget codebase, it's acceptable and consistent to import useSpreadsheet as a type-only import and then use ReturnType<typeof useSpreadsheet> in type annotations. This pattern is used consistently across spreadsheet files like custom-spreadsheet.ts and crossover-spreadsheet.ts.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/desktop-client/src/**/*.{ts,tsx} : Use custom navigation hook from `src/hooks` instead of react-router directly

Applied to files:

  • packages/desktop-client/src/components/reports/ReportRouter.tsx
🧬 Code graph analysis (9)
packages/desktop-client/e2e/sankey.test.ts (4)
packages/desktop-client/e2e/page-models/navigation.ts (1)
  • Navigation (17-119)
packages/desktop-client/e2e/page-models/reports-page.ts (1)
  • ReportsPage (6-49)
packages/desktop-client/e2e/page-models/sankey-page.ts (1)
  • SankeyPage (3-62)
packages/desktop-client/e2e/page-models/configuration-page.ts (1)
  • ConfigurationPage (6-72)
packages/desktop-client/e2e/page-models/reports-page.ts (1)
packages/desktop-client/e2e/page-models/sankey-page.ts (1)
  • SankeyPage (3-62)
packages/desktop-client/src/components/reports/reports/Sankey.tsx (13)
packages/desktop-client/src/hooks/useWidget.ts (1)
  • useWidget (8-21)
packages/loot-core/src/types/models/dashboard.ts (1)
  • SankeyWidget (174-183)
packages/desktop-client/src/components/reports/LoadingIndicator.tsx (1)
  • LoadingIndicator (13-32)
packages/desktop-client/src/hooks/useLocale.ts (1)
  • useLocale (7-14)
packages/desktop-client/src/redux/index.ts (1)
  • useDispatch (18-18)
packages/desktop-client/src/hooks/useNavigate.ts (1)
  • useNavigate (12-48)
packages/component-library/src/hooks/useResponsive.ts (1)
  • useResponsive (5-23)
packages/desktop-client/src/hooks/useRuleConditionFilters.ts (1)
  • useRuleConditionFilters (5-75)
packages/desktop-client/src/hooks/useCategories.ts (1)
  • useCategories (8-22)
packages/desktop-client/src/components/Page.tsx (3)
  • Page (115-155)
  • MobilePageHeader (47-105)
  • PageHeader (16-38)
packages/desktop-client/src/components/EditablePageHeaderTitle.tsx (1)
  • EditablePageHeaderTitle (15-88)
packages/desktop-client/src/components/filters/AppliedFilters.tsx (1)
  • AppliedFilters (21-55)
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (1)
  • SankeyGraph (285-334)
packages/desktop-client/src/components/reports/Overview.tsx (2)
packages/desktop-client/src/hooks/useFeatureFlag.ts (1)
  • useFeatureFlag (16-22)
packages/desktop-client/src/components/reports/reports/SankeyCard.tsx (1)
  • SankeyCard (25-120)
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (4)
packages/component-library/src/theme.ts (1)
  • theme (1-204)
packages/desktop-client/src/hooks/usePrivacyMode.ts (1)
  • usePrivacyMode (3-6)
packages/component-library/src/styles.ts (1)
  • CSSProperties (7-7)
packages/desktop-client/src/components/reports/Container.tsx (1)
  • Container (14-31)
packages/desktop-client/src/components/reports/reports/SankeyCard.tsx (9)
packages/loot-core/src/types/models/dashboard.ts (1)
  • SankeyWidget (174-183)
packages/desktop-client/src/hooks/useCategories.ts (1)
  • useCategories (8-22)
packages/desktop-client/src/components/reports/reportRanges.ts (1)
  • calculateTimeRange (177-238)
packages/desktop-client/src/components/reports/ReportCard.tsx (1)
  • ReportCard (34-119)
packages/component-library/src/View.tsx (1)
  • View (14-33)
packages/desktop-client/src/components/reports/ReportCardName.tsx (1)
  • ReportCardName (17-55)
packages/desktop-client/src/components/reports/DateRange.tsx (1)
  • DateRange (29-89)
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (1)
  • SankeyGraph (285-334)
packages/desktop-client/src/components/reports/LoadingIndicator.tsx (1)
  • LoadingIndicator (13-32)
packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (3)
packages/loot-core/src/types/models/category-group.ts (1)
  • CategoryGroupEntity (3-11)
packages/loot-core/src/types/models/rule.ts (1)
  • RuleConditionEntity (73-137)
packages/desktop-client/src/hooks/useSpreadsheet.tsx (1)
  • useSpreadsheet (19-25)
packages/desktop-client/src/components/reports/ReportRouter.tsx (1)
packages/desktop-client/src/components/reports/reports/Sankey.tsx (1)
  • Sankey (48-60)
packages/loot-core/src/types/models/dashboard.ts (1)
packages/loot-core/src/types/models/rule.ts (1)
  • RuleConditionEntity (73-137)
🪛 GitHub Actions: autofix.ci
packages/desktop-client/e2e/sankey.test.ts

[warning] 8-8: ESLint: 'SettingsPage' is defined but never used. (no-unused-vars)

🪛 GitHub Actions: E2E Tests
packages/desktop-client/e2e/sankey.test.ts

[error] 33-33: Snapshot doesn't exist at /__w/actual/actual/packages/desktop-client/e2e/sankey.test.ts-snapshots/Sankey-Report-loads-sankey-report-and-checks-budgeted-view-1-chromium-linux.png; Received actual screenshot. Expected snapshot path: e2e/sankey.test.ts-snapshots/Sankey-Report-loads-sankey-report-and-checks-budgeted-view-1-chromium-linux.png


[error] 38-38: Snapshot doesn't exist at /__w/actual/actual/packages/desktop-client/e2e/sankey.test.ts-snapshots/Sankey-Report-loads-sankey-report-and-checks-budgeted-view-2-chromium-linux.png; Received actual screenshot. Expected snapshot path: e2e/sankey.test.ts-snapshots/Sankey-Report-loads-sankey-report-and-checks-budgeted-view-2-chromium-linux.png


[error] 46-46: Snapshot doesn't exist at /__w/actual/actual/packages/desktop-client/e2e/sankey.test.ts-snapshots/Sankey-Report-loads-sankey-report-and-checks-budgeted-view-3-chromium-linux.png; Received actual screenshot. Expected snapshot path: e2e/sankey.test.ts-snapshots/Sankey-Report-loads-sankey-report-and-checks-budgeted-view-3-chromium-linux.png


[error] 46-46: Snapshot doesn't exist at /__w/actual/actual/packages/desktop-client/e2e/sankey.test.ts-snapshots/Sankey-Report-loads-sankey-report-and-checks-budgeted-view-4-chromium-linux.png; Received actual screenshot. Expected snapshot path: e2e/sankey.test.ts-snapshots/Sankey-Report-loads-sankey-report-and-checks-budgeted-view-4-chromium-linux.png


[error] 50-50: Snapshot doesn't exist at /__w/actual/actual/packages/desktop-client/e2e/sankey.test.ts-snapshots/Sankey-Report-switches-to-spent-view-and-checks-visuals-1-chromium-linux.png; Received actual screenshot. Expected snapshot path: e2e/sankey.test.ts-snapshots/Sankey-Report-switches-to-spent-view-and-checks-visuals-1-chromium-linux.png


[error] 56-56: Snapshot doesn't exist at /__w/actual/actual/packages/desktop-client/e2e/sankey.test.ts-snapshots/Sankey-Report-switches-to-spent-view-and-checks-visuals-2-chromium-linux.png; Received actual screenshot. Expected snapshot path: e2e/sankey.test.ts-snapshots/Sankey-Report-switches-to-spent-view-and-checks-visuals-2-chromium-linux.png


[error] 63-63: Snapshot doesn't exist at /__w/actual/actual/packages/desktop-client/e2e/sankey.test.ts-snapshots/Sankey-Report-switches-to-spent-view-and-checks-visuals-3-chromium-linux.png; Received actual screenshot. Expected snapshot path: e2e/sankey.test.ts-snapshots/Sankey-Report-switches-to-spent-view-and-checks-visuals-3-chromium-linux.png


[error] 81-81: Snapshot doesn't exist at /__w/actual/actual/packages/desktop-client/e2e/sankey.test.ts-snapshots/Sankey-Report-verifies-all-three-modes-work-correctly-1-chromium-linux.png; Received actual screenshot. Expected snapshot path: e2e/sankey.test.ts-snapshots/Sankey-Report-verifies-all-three-modes-work-correctly-1-chromium-linux.png


[error] 92-92: Snapshot doesn't exist at /__w/actual/actual/packages/desktop-client/e2e/sankey.test.ts-snapshots/Sankey-Report-verifies-all-three-modes-work-correctly-2-chromium-linux.png; Received actual screenshot. Expected snapshot path: e2e/sankey.test.ts-snapshots/Sankey-Report-verifies-all-three-modes-work-correctly-2-chromium-linux.png


[error] 101-101: Snapshot doesn't exist at /__w/actual/actual/packages/desktop-client/e2e/sankey.test.ts-snapshots/Sankey-Report-verifies-all-three-modes-work-correctly-3-chromium-linux.png; Received actual screenshot. Expected snapshot path: e2e/sankey.test.ts-snapshots/Sankey-Report-verifies-all-three-modes-work-correctly-3-chromium-linux.png

🪛 GitHub Actions: Test
packages/desktop-client/e2e/sankey.test.ts

[warning] 1-1: Code style issues found. Run 'Prettier --write' to fix formatting.

packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx

[warning] 1-1: Code style issues found. Run 'Prettier --write' to fix formatting.

packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts

[warning] 1-1: Code style issues found. Run 'Prettier --write' to fix formatting.

packages/desktop-client/e2e/page-models/sankey-page.ts

[warning] 1-1: Code style issues found. Run 'Prettier --write' to fix formatting.

🪛 GitHub Check: autofix
packages/desktop-client/e2e/sankey.test.ts

[warning] 8-8:
'SettingsPage' is defined but never used. Allowed unused vars must match /^(_|React)/u

🔇 Additional comments (10)
packages/loot-core/src/types/prefs.ts (1)

7-9: LGTM!

The new sankeyReport feature flag is correctly added to the type union and will enable gating Sankey-related UI behind this flag throughout the codebase.

packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (2)

336-445: Logic for collapsing Sankey branches looks sound.

The implementation correctly:

  • Builds node-to-index mappings
  • Recursively finds children of collapsed nodes
  • Filters links to exclude hidden nodes
  • Always includes the Available Funds node
  • Remaps indices for the filtered graph

1-456: Run Prettier to fix formatting.

The pipeline indicates code style issues. Please run prettier --write on this file to fix formatting.

npx prettier --write packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
⛔ Skipped due to learnings
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.tsx : Prefer declarative, minimal JSX; avoid unnecessary curly braces and prefer concise conditional expressions (`condition && <Component />`)
Learnt from: lelemm
Repo: actualbudget/actual PR: 3792
File: packages/desktop-client/src/components/reports/reports/Summary.tsx:134-161
Timestamp: 2024-11-12T19:52:52.889Z
Learning: In `packages/desktop-client/src/components/reports/reports/Summary.tsx`, API calls like `get-earliest-transaction` are used without explicit error handling to maintain consistency with other components.
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3744
File: packages/desktop-client/src/components/reports/reports/CustomReport.tsx:157-157
Timestamp: 2024-11-01T20:29:18.673Z
Learning: In the `CustomReport` component (`packages/desktop-client/src/components/reports/reports/CustomReport.tsx`), the session storage references are necessary and should not be removed.
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.tsx : Avoid unstable nested components in JSX
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3566
File: packages/desktop-client/src/components/reports/Overview.tsx:100-101
Timestamp: 2024-10-08T15:46:15.739Z
Learning: In `packages/desktop-client/src/components/reports/Overview.tsx`, when filtering `baseLayout`, if `item.type === 'custom-report'`, `item.meta.id` will always be defined.
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3566
File: packages/desktop-client/src/components/reports/Overview.tsx:100-101
Timestamp: 2024-10-04T18:16:45.140Z
Learning: In `packages/desktop-client/src/components/reports/Overview.tsx`, when filtering `baseLayout`, if `item.type === 'custom-report'`, `item.meta.id` will always be defined.
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to **/*.{ts,tsx} : Maintain import order groups (React, Node built-ins, externals, Actual packages, parent, sibling, index) with newlines between groups
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3458
File: packages/loot-core/src/client/state-types/prefs.d.ts:5-5
Timestamp: 2024-09-17T20:04:47.663Z
Learning: In future reviews, ensure that changes related to `PrefsState` in `prefs.d.ts` do not incorrectly assume necessary updates in other parts of the codebase. Verify the impact thoroughly before making suggestions.
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/desktop-client/src/**/*.tsx : Use `<Link>` instead of `<a>` tags
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.{ts,tsx} : Do not use `React.*` namespace imports; use named imports
packages/desktop-client/src/components/reports/ReportRouter.tsx (1)

43-44: Consider gating Sankey routes behind feature flag for consistency.

The Crossover report routes are conditionally rendered behind the crossoverReport feature flag (lines 25-30), but the new Sankey routes are not gated behind the sankeyReport flag. This creates inconsistency and could allow direct URL access to the Sankey report even when the feature is disabled.

If Sankey routes should be feature-gated, apply this diff:

+  const sankeyReportEnabled = useFeatureFlag('sankeyReport');
+
   return (
     <Routes>
       <Route path="/" element={<Overview />} />
       ...
+      {sankeyReportEnabled && (
+        <>
+          <Route path="/sankey" element={<Sankey />} />
+          <Route path="/sankey/:id" element={<Sankey />} />
+        </>
+      )}
-      <Route path="/sankey" element={<Sankey />} />
-      <Route path="/sankey/:id" element={<Sankey />} />
     </Routes>
   );

Confirm whether routes should be accessible regardless of feature flag state.

packages/desktop-client/e2e/page-models/reports-page.ts (1)

29-33: Different navigation pattern for Sankey page.

Unlike other report navigation methods that click buttons (e.g., goToNetWorthPage, goToCashFlowPage), this method uses direct URL navigation via page.goto('/reports/sankey'). This is acceptable if the Sankey report doesn't have a corresponding button in the overview, or if it's behind a feature flag that might not be visible in tests.

Consider documenting this distinction if Sankey is intentionally accessed differently from other reports.

packages/desktop-client/src/hooks/useFeatureFlag.ts (1)

13-13: Sankey feature enabled by default differs from other experimental features.

The sankeyReport flag defaults to true while all other feature flags default to false. This means the Sankey report will be enabled by default for users. Please confirm this is intentional, especially given the PR is marked as [WIP] and the feature is described as experimental.

If this should follow the same pattern as other experimental features, consider:

- sankeyReport: true,
+ sankeyReport: false,
packages/desktop-client/src/components/reports/Overview.tsx (1)

82-82: Clean integration of Sankey card behind feature flag.

The Sankey card is properly integrated:

  • Feature flag checked at line 82
  • Widget menu item conditionally added (lines 460-467)
  • Card rendering gated behind feature flag (lines 652-659)

This follows the same pattern used for other experimental features like Crossover and Formula cards.

Also applies to: 460-467, 652-659

packages/desktop-client/src/components/settings/Experimental.tsx (1)

167-172: The feedback link is correct. Issue #1919 is the designated feedback channel for the Sankey chart feature, making it the appropriate target for this FeatureToggle component. PR objectives and feedback issue numbers can differ when an initial feature request (#1716) and feedback collection issue (#1919) are tracked separately.

packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (1)

191-193: Remove console.error

Project guidelines forbid console.*. Since the error is rethrown, drop the log (or switch to the shared logger).

-        console.error('Error fetching category data:', error);
-        throw error;
+        throw error;
⛔ Skipped due to learnings
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Do not use `console.*`; use the logger instead
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 3581
File: packages/loot-core/src/server/main.ts:1188-1198
Timestamp: 2024-10-25T00:12:14.939Z
Learning: In `packages/loot-core/src/server/main.ts`, when handling errors, the error properties `error_code` and `error_type` may already be mapped to `code` and `category` before being passed to `handleSyncError`.
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 5978
File: packages/desktop-client/src/components/mobile/banksync/MobileBankSyncAccountEditPage.tsx:54-57
Timestamp: 2025-10-22T00:50:31.002Z
Learning: The logger should only be used in loot-core code. In desktop-client code, using console methods (console.error, console.log, etc.) is acceptable.
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 6010
File: packages/sync-server/src/app-sync.ts:331-331
Timestamp: 2025-10-27T17:06:08.172Z
Learning: The logger should only be used in loot-core code. In sync-server code (packages/sync-server), using console methods (console.error, console.log, etc.) is acceptable.
Learnt from: tlesicka
Repo: actualbudget/actual PR: 3689
File: packages/loot-core/src/server/main.ts:1807-1809
Timestamp: 2024-10-23T07:38:25.699Z
Learning: In the function `delete-budget` in `packages/loot-core/src/server/main.ts`, the function `removeAllBackups(id)` handles its own errors internally, so additional error handling when calling it is unnecessary.
Learnt from: tlesicka
Repo: actualbudget/actual PR: 3689
File: packages/loot-core/src/server/backups.web.ts:203-207
Timestamp: 2024-10-24T05:09:44.115Z
Learning: In `packages/loot-core/src/server/backups.web.ts`, developers prefer to keep the error handling for cloud storage uploads inline rather than extracting it into a separate function. Avoid suggesting this refactoring in future reviews.
packages/desktop-client/src/components/reports/reports/Sankey.tsx (1)

197-199: Show a loading state instead of returning null

While useReport is still fetching, this return null blanks the entire page (no header or spinner). Render the existing LoadingIndicator (or a similar placeholder) so the user sees feedback until data arrives.

-  if (!data) {
-    return null;
-  }
+  if (!data) {
+    return <LoadingIndicator />;
+  }
⛔ Skipped due to learnings
Learnt from: elijaholmos
Repo: actualbudget/actual PR: 5076
File: packages/desktop-client/src/components/CommandBar.tsx:70-70
Timestamp: 2025-06-03T23:19:44.814Z
Learning: The useReports hook in packages/desktop-client/src/hooks/useReports.ts always returns an array for the data property due to initialData: [] and default value fallback (data: customReports = []), so it never returns undefined and doesn't need additional undefined checks when used.
Learnt from: elijaholmos
Repo: actualbudget/actual PR: 5076
File: packages/desktop-client/src/components/CommandBar.tsx:70-70
Timestamp: 2025-06-03T23:19:44.814Z
Learning: The useReports hook in packages/desktop-client/src/hooks/useReports.ts always returns an array for the data property due to the ternary operator at line 62: `queryData ? [...queryData] : []`, ensuring data is never undefined even if the underlying query returns undefined.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (1)

330-335: Critical: Difference mode filters are not applied.

The current filter construction directly maps RuleConditionEntity fields to filter objects, but op values like 'is', 'contains', and 'oneOf' are not valid AQL operators. This causes user-selected filters to be silently ignored in Difference mode.

Apply this diff to use the correct filter builder:

     // Fetch spent data using transactions
     const conditionsOpKey = conditionsOp === 'or' ? '$or' : '$and';
-    const filters = conditions.map(f => ({
-      [f.field]: { [f.op]: f.value },
-    }));
+    const { filters } = await send('make-filters-from-conditions', {
+      conditions: conditions.filter(cond => !cond.customName),
+    });

This matches the pattern used in createTransactionsSpreadsheet (lines 154-156) and ensures filters work correctly.

packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (1)

6-6: Remove incorrect translation function usage for CSS properties.

The t() function is for translating user-facing strings, not CSS property values. Font family names should be literal strings. Additionally, importing t directly from i18next should be avoided in React components.

Apply this diff to remove the import and fix all usages:

-import { t } from 'i18next';
-            {...(privacyMode && { fontFamily: t('Redacted Script') })}
+            {...(privacyMode && { fontFamily: 'Redacted Script' })}

Apply the same fix at lines 216 and 251.

As per coding guidelines.

Also applies to: 192-192, 216-216, 251-251

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 828e577 and eedc5fb.

📒 Files selected for processing (5)
  • packages/desktop-client/e2e/page-models/sankey-page.ts (1 hunks)
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (1 hunks)
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx (1 hunks)
  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx (1 hunks)
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/desktop-client/e2e/page-models/sankey-page.ts
  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Prefer type over interface in TypeScript
Avoid enum; use objects or maps instead
Avoid any and unknown unless absolutely necessary
Avoid type assertions (as, non-null !); prefer satisfies for narrowing
Use inline type imports: import { type X } from '...'
Favor functional/declarative patterns; avoid classes
Use the function keyword for pure functions
Use named exports for components and utilities (avoid default exports except specific cases)
Maintain import order groups (React, Node built-ins, externals, Actual packages, parent, sibling, index) with newlines between groups
Do not directly reference platform-specific imports by extension (.api, .web, .electron)

Files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Do not use console.*; use the logger instead
Import uuid with destructuring: import { v4 as uuidv4 } from 'uuid'

Files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
packages/{desktop-client,component-library}/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

packages/{desktop-client,component-library}/src/**/*.{ts,tsx}: All user-facing strings must be translated
Prefer <Trans> component over t() when possible
Do not use React.* namespace imports; use named imports
Use theme tokens; do not import colors directly

Files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
packages/{desktop-client,component-library}/src/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

packages/{desktop-client,component-library}/src/**/*.tsx: Do not use React.FC/React.FunctionComponent; type props directly
Avoid unstable nested components in JSX
Prefer declarative, minimal JSX; avoid unnecessary curly braces and prefer concise conditional expressions (condition && <Component />)

Files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
packages/desktop-client/src/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Use <Link> instead of <a> tags

Files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
packages/desktop-client/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

packages/desktop-client/src/**/*.{ts,tsx}: Use custom navigation hook from src/hooks instead of react-router directly
Use useDispatch, useSelector, useStore from src/redux (not react-redux)
Use absolute imports in desktop-client

Files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
🧠 Learnings (40)
📚 Learning: 2024-11-01T20:29:18.673Z
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3744
File: packages/desktop-client/src/components/reports/reports/CustomReport.tsx:157-157
Timestamp: 2024-11-01T20:29:18.673Z
Learning: In the `CustomReport` component (`packages/desktop-client/src/components/reports/reports/CustomReport.tsx`), the session storage references are necessary and should not be removed.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2024-10-24T17:05:41.415Z
Learnt from: joel-jeremy
Repo: actualbudget/actual PR: 3685
File: packages/desktop-client/src/components/accounts/Account.tsx:655-665
Timestamp: 2024-10-24T17:05:41.415Z
Learning: The Account component in 'packages/desktop-client/src/components/accounts/Account.tsx' is being rewritten in a separate PR.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2024-10-04T18:16:45.140Z
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3566
File: packages/desktop-client/src/components/reports/Overview.tsx:100-101
Timestamp: 2024-10-04T18:16:45.140Z
Learning: In `packages/desktop-client/src/components/reports/Overview.tsx`, when filtering `baseLayout`, if `item.type === 'custom-report'`, `item.meta.id` will always be defined.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2024-11-12T19:52:52.889Z
Learnt from: lelemm
Repo: actualbudget/actual PR: 3792
File: packages/desktop-client/src/components/reports/reports/Summary.tsx:134-161
Timestamp: 2024-11-12T19:52:52.889Z
Learning: In `packages/desktop-client/src/components/reports/reports/Summary.tsx`, API calls like `get-earliest-transaction` are used without explicit error handling to maintain consistency with other components.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.{ts,tsx} : Do not use `React.*` namespace imports; use named imports

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-10-10T02:29:05.655Z
Learnt from: tlesicka
Repo: actualbudget/actual PR: 3593
File: packages/desktop-client/src/components/sidebar/Sidebar.tsx:112-116
Timestamp: 2024-10-10T02:29:05.655Z
Learning: In `packages/desktop-client/src/components/sidebar/BudgetName.tsx`, the `BudgetName` component consists of three parts: `BudgetName`, `EditBudgetName`, and the Menu. Keeping `EditBudgetName` as a separate component helps maintain cleaner code by separating concerns.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.tsx : Prefer declarative, minimal JSX; avoid unnecessary curly braces and prefer concise conditional expressions (`condition && <Component />`)

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.tsx : Do not use `React.FC`/`React.FunctionComponent`; type props directly

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/desktop-client/src/**/*.{ts,tsx} : Use `useDispatch`, `useSelector`, `useStore` from `src/redux` (not react-redux)

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-10-25T18:30:24.287Z
Learnt from: lelemm
Repo: actualbudget/actual PR: 3309
File: packages/desktop-client/src/components/ColumnWidthContext.jsx:17-17
Timestamp: 2024-10-25T18:30:24.287Z
Learning: In `packages/desktop-client/src/components/ColumnWidthContext.jsx`, replacing `useState` with `useRef` for `positionAccumulator` causes the resize action to become unpredictable. Therefore, it's preferable to keep using `useState` for `positionAccumulator` in this context.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.tsx : Avoid unstable nested components in JSX

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to **/*.{ts,tsx} : Use named exports for components and utilities (avoid default exports except specific cases)

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/desktop-client/src/**/*.{ts,tsx} : Use custom navigation hook from `src/hooks` instead of react-router directly

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/desktop-client/src/**/*.tsx : Use `<Link>` instead of `<a>` tags

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.{ts,tsx} : Use theme tokens; do not import colors directly

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/desktop-client/src/**/*.{ts,tsx} : Use absolute imports in desktop-client

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to **/*.{ts,tsx} : Maintain import order groups (React, Node built-ins, externals, Actual packages, parent, sibling, index) with newlines between groups

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-10-24T16:51:43.421Z
Learnt from: StephenBrown2
Repo: actualbudget/actual PR: 5908
File: packages/desktop-client/src/components/settings/Currency.tsx:38-38
Timestamp: 2025-10-24T16:51:43.421Z
Learning: In the actualbudget/actual repository, JPY (Japanese Yen) currency support can remain enabled in packages/desktop-client/src/components/settings/Currency.tsx and packages/loot-core/src/shared/currencies.ts even though not all features fully support zero-decimal currencies yet, because the currency feature is experimental. The team decided to keep JPY active to avoid repeatedly removing and re-adding it during testing.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-08-16T07:09:15.691Z
Learnt from: sjones512
Repo: actualbudget/actual PR: 5554
File: packages/desktop-client/src/components/reports/spreadsheets/crossover-spreadsheet.ts:375-387
Timestamp: 2025-08-16T07:09:15.691Z
Learning: When handling financial data consistency issues in the desktop client, prefer keeping the data layer (spreadsheets) in raw integer cents and use the useFormat hook for all presentation formatting, rather than converting to display amounts in the data layer.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-06-16T17:45:40.807Z
Learnt from: misu-dev
Repo: actualbudget/actual PR: 5167
File: packages/desktop-client/src/components/spreadsheet/useFormat.ts:64-72
Timestamp: 2025-06-16T17:45:40.807Z
Learning: The user misu-dev prefers strict type checking for financial format types in useFormat.ts as a long-term goal, but acknowledges that creating follow-up issues for cleanup should wait until after the current PR is merged, not during the development phase.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-09-28T08:34:21.188Z
Learnt from: misu-dev
Repo: actualbudget/actual PR: 5639
File: packages/desktop-client/src/components/util/GenericInput.jsx:68-73
Timestamp: 2025-09-28T08:34:21.188Z
Learning: In packages/desktop-client/src/components/util/GenericInput.jsx, for amount filtering with inflow/outflow options, the sign prop should always be '+' (for both inflow and outflow) because the UI layer keeps all amounts positive, while the server-side transaction rules engine handles the actual sign conversion and negation logic when querying the database.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-06-16T17:41:34.452Z
Learnt from: misu-dev
Repo: actualbudget/actual PR: 5167
File: packages/desktop-client/src/components/spreadsheet/useFormat.ts:64-72
Timestamp: 2025-06-16T17:41:34.452Z
Learning: The format function in useFormat.ts is widely used across the application and currently needs to accept both string and number inputs for financial format types. While strict type checking is preferred long-term, string parsing is maintained as a pragmatic compromise during the currency feature development phase.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-11-09T20:18:28.468Z
Learnt from: csenel
Repo: actualbudget/actual PR: 3810
File: packages/desktop-client/src/components/transactions/SelectedTransactionsButton.tsx:150-161
Timestamp: 2024-11-09T20:18:28.468Z
Learning: In `packages/desktop-client/src/components/transactions/SelectedTransactionsButton.tsx`, prefer to keep the implementation of checks consistent with similar patterns elsewhere in the codebase, even if alternative implementations are more concise.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.{ts,tsx} : All user-facing strings must be translated

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.{ts,tsx} : Prefer `<Trans>` component over `t()` when possible

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-06-14T21:20:46.938Z
Learnt from: misu-dev
Repo: actualbudget/actual PR: 5167
File: packages/desktop-client/src/components/spreadsheet/useFormat.ts:161-166
Timestamp: 2025-06-14T21:20:46.938Z
Learning: In the useFormat hook's formatDisplay function, there's an intentional separation between displayDecimalPlaces (used for Intl.NumberFormat display formatting) and activeCurrency.decimalPlaces (used for integerToCurrency conversion logic). These should not be mixed as displayDecimalPlaces controls how many decimals to show while activeCurrency.decimalPlaces controls the mathematical conversion from integer amounts to decimal amounts.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-10-08T15:46:15.739Z
Learnt from: qedi-r
Repo: actualbudget/actual PR: 3527
File: packages/desktop-client/src/components/accounts/Header.jsx:0-0
Timestamp: 2024-10-08T15:46:15.739Z
Learning: In the Actual Budget project, importing `t` directly from 'i18next' is best avoided, and we should almost always prefer using the useTranslation hook if possible.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-01-21T11:39:38.461Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4154
File: packages/desktop-client/src/components/spreadsheet/CellValue.tsx:47-47
Timestamp: 2025-01-21T11:39:38.461Z
Learning: In the CellValue component of packages/desktop-client/src/components/spreadsheet/CellValue.tsx, the children prop needs an additional length check (children && children.length > 0) because the Trans component can pass an empty array at runtime despite the type definition expecting a function.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-10-25T04:49:31.861Z
Learnt from: tlesicka
Repo: actualbudget/actual PR: 3689
File: packages/desktop-client/src/components/modals/manager/DuplicateFileModal.tsx:144-156
Timestamp: 2024-10-25T04:49:31.861Z
Learning: In `packages/desktop-client/src/components/modals/manager/DuplicateFileModal.tsx`, styles for buttons may differ for each button in the future, so avoid suggesting extraction of common styles in this file.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-10-12T23:57:22.683Z
Learnt from: jfdoming
Repo: actualbudget/actual PR: 3648
File: packages/desktop-client/src/components/HelpMenu.tsx:25-47
Timestamp: 2024-10-12T23:57:22.683Z
Learning: In `packages/desktop-client/src/components/HelpMenu.tsx`, when a `<Button>` component includes text content as a child, an explicit `aria-label` may not be required for accessibility, as the text content provides the accessible name.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-01-17T12:11:23.669Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 3840
File: packages/loot-core/src/server/budget/template-notes.ts:12-12
Timestamp: 2025-01-17T12:11:23.669Z
Learning: In server-side code or non-React contexts where React hooks cannot be used, prefer using `import { t } from 'i18next'` and directly using `t(string)` for translations, instead of using react-i18next hooks or other approaches.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-08-16T16:42:08.306Z
Learnt from: sjones512
Repo: actualbudget/actual PR: 5554
File: packages/desktop-client/src/components/reports/spreadsheets/crossover-spreadsheet.ts:7-8
Timestamp: 2025-08-16T16:42:08.306Z
Learning: In the Actual Budget codebase, it's the established pattern and acceptable to import useSpreadsheet as a type-only import and then use ReturnType<typeof useSpreadsheet> in type annotations. This pattern is used consistently across all spreadsheet files including custom-spreadsheet.ts, grouped-spreadsheet.ts, spending-spreadsheet.ts, net-worth-spreadsheet.ts, cash-flow-spreadsheet.tsx, calendar-spreadsheet.ts, summary-spreadsheet.ts, and crossover-spreadsheet.ts.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-08-16T16:42:08.306Z
Learnt from: sjones512
Repo: actualbudget/actual PR: 5554
File: packages/desktop-client/src/components/reports/spreadsheets/crossover-spreadsheet.ts:7-8
Timestamp: 2025-08-16T16:42:08.306Z
Learning: In the Actual Budget codebase, it's acceptable and consistent to import useSpreadsheet as a type-only import and then use ReturnType<typeof useSpreadsheet> in type annotations. This pattern is used consistently across spreadsheet files like custom-spreadsheet.ts and crossover-spreadsheet.ts.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-01-17T12:00:27.629Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4170
File: packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx:570-581
Timestamp: 2025-01-17T12:00:27.629Z
Learning: The transaction amount conversion for income categories in TransactionEdit.jsx is intended as a quality-of-life feature to help users who forget to set the correct direction, not as a preventative measure. Users should still be able to manually enter negative amounts even for income categories.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2024-10-09T20:17:46.493Z
Learnt from: UnderKoen
Repo: actualbudget/actual PR: 3619
File: packages/loot-core/src/server/accounts/transaction-rules.ts:551-0
Timestamp: 2024-10-09T20:17:46.493Z
Learning: When finalizing transactions that involve inserting or retrieving payees, avoid using `Promise.all` as it may result in duplicate payees due to concurrent operations. Sequential processing ensures payees are correctly handled without duplication.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2024-10-09T20:30:39.127Z
Learnt from: UnderKoen
Repo: actualbudget/actual PR: 3619
File: packages/loot-core/src/server/accounts/transaction-rules.ts:795-801
Timestamp: 2024-10-09T20:30:39.127Z
Learning: In the `finalizeTransactionForRules` function within `packages/loot-core/src/server/accounts/transaction-rules.ts`, potential race conditions when inserting payees are handled in the method that calls this function, so additional safeguards within `finalizeTransactionForRules` are unnecessary.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-11-04T00:47:00.968Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 6065
File: packages/desktop-client/src/components/transactions/TransactionList.tsx:197-205
Timestamp: 2025-11-04T00:47:00.968Z
Learning: In packages/desktop-client/src/components/transactions/TransactionList.tsx and similar schedule creation code, when using schedule/create with conditions and then updating the rule's actions, it's correct to filter rule.actions to keep only 'link-schedule' and append custom actions. Transactions created by schedules are defined by a mix of conditions (which create the base transaction with date, amount, payee, account) and actions (which apply additional modifications like category, notes, splits). The filtering pattern replaces any auto-generated actions with the desired custom actions.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-01-14T06:17:55.345Z
Learnt from: jfdoming
Repo: actualbudget/actual PR: 4146
File: packages/desktop-client/src/components/reports/spreadsheets/summary-spreadsheet.ts:30-30
Timestamp: 2025-01-14T06:17:55.345Z
Learning: The `make-filters-from-conditions` function in the Actual Budget codebase returns a complex type that is not explicitly defined. While improving its type definition would be beneficial, it should be handled in a dedicated project due to its complexity.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-01-12T20:22:02.704Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4141
File: packages/desktop-client/src/components/reports/spreadsheets/sortData.ts:15-26
Timestamp: 2025-01-12T20:22:02.704Z
Learning: In the custom reports feature of Actual, the `balanceTypeOp` and `sortByOp` parameters in the `sortData` function are always set and should not be marked as optional.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2024-10-08T23:41:32.134Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 3609
File: packages/loot-core/src/server/db/index.ts:583-598
Timestamp: 2024-10-08T23:41:32.134Z
Learning: In `packages/loot-core/src/server/db/index.ts`, the `orphanedPayeesQuery` uses a subquery with `json_each(r.conditions) AS cond` to loop through JSON conditions because the "description" field may not be the first index. This implementation must remain as is to ensure correct functionality.

Additionally, table aliases are already used consistently in the SQL queries within this file.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
🧬 Code graph analysis (3)
packages/desktop-client/src/components/reports/reports/Sankey.tsx (13)
packages/desktop-client/src/hooks/useWidget.ts (1)
  • useWidget (8-21)
packages/loot-core/src/types/models/dashboard.ts (1)
  • SankeyWidget (174-183)
packages/desktop-client/src/components/reports/LoadingIndicator.tsx (1)
  • LoadingIndicator (13-32)
packages/desktop-client/src/hooks/useLocale.ts (1)
  • useLocale (7-14)
packages/desktop-client/src/redux/index.ts (1)
  • useDispatch (18-18)
packages/desktop-client/src/hooks/useRuleConditionFilters.ts (1)
  • useRuleConditionFilters (5-75)
packages/desktop-client/src/hooks/useCategories.ts (1)
  • useCategories (8-22)
packages/desktop-client/src/notifications/notificationsSlice.ts (1)
  • addNotification (58-68)
packages/desktop-client/src/components/Page.tsx (3)
  • Page (115-155)
  • MobilePageHeader (47-105)
  • PageHeader (16-38)
packages/desktop-client/src/components/mobile/MobileBackButton.tsx (1)
  • MobileBackButton (13-44)
packages/desktop-client/src/components/EditablePageHeaderTitle.tsx (1)
  • EditablePageHeaderTitle (15-88)
packages/desktop-client/src/components/filters/AppliedFilters.tsx (1)
  • AppliedFilters (21-55)
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (1)
  • SankeyGraph (296-354)
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (5)
packages/component-library/src/theme.ts (1)
  • theme (1-204)
packages/desktop-client/src/hooks/usePrivacyMode.ts (1)
  • usePrivacyMode (3-6)
packages/component-library/src/styles.ts (1)
  • CSSProperties (7-7)
packages/desktop-client/src/hooks/useSyncedPref.ts (1)
  • useSyncedPref (12-29)
packages/desktop-client/src/components/reports/Container.tsx (1)
  • Container (14-31)
packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (3)
packages/loot-core/src/types/models/category-group.ts (1)
  • CategoryGroupEntity (3-11)
packages/loot-core/src/types/models/rule.ts (1)
  • RuleConditionEntity (73-137)
packages/desktop-client/src/hooks/useSpreadsheet.tsx (1)
  • useSpreadsheet (19-25)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: build (ubuntu-22.04)
  • GitHub Check: build (macos-latest)
  • GitHub Check: build (windows-latest)
  • GitHub Check: Wait for Netlify build to finish
  • GitHub Check: Functional Desktop App
  • GitHub Check: Generate VRT Updates
🔇 Additional comments (1)
packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (1)

196-199: Replace console.error with proper logger.

Direct console.* usage violates project guidelines. Use the logger instead for consistent error handling and observability.

However, I notice no logger is currently imported. You'll need to:

  1. Import the logger utility (check other report spreadsheet files for the pattern)
  2. Replace the console.error call
  3. Consider whether the comment on line 198 adds value—it reads like placeholder text

As per coding guidelines.

⛔ Skipped due to learnings
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Do not use `console.*`; use the logger instead
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 5978
File: packages/desktop-client/src/components/mobile/banksync/MobileBankSyncAccountEditPage.tsx:54-57
Timestamp: 2025-10-22T00:50:31.002Z
Learning: The logger should only be used in loot-core code. In desktop-client code, using console methods (console.error, console.log, etc.) is acceptable.
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 6010
File: packages/sync-server/src/app-sync.ts:331-331
Timestamp: 2025-10-27T17:06:08.172Z
Learning: The logger should only be used in loot-core code. In sync-server code (packages/sync-server), using console methods (console.error, console.log, etc.) is acceptable.
Learnt from: tlesicka
Repo: actualbudget/actual PR: 3689
File: packages/loot-core/src/server/backups.web.ts:203-207
Timestamp: 2024-10-24T05:09:44.115Z
Learning: In `packages/loot-core/src/server/backups.web.ts`, developers prefer to keep the error handling for cloud storage uploads inline rather than extracting it into a separate function. Avoid suggesting this refactoring in future reviews.
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 3581
File: packages/loot-core/src/server/main.ts:1188-1198
Timestamp: 2024-10-25T00:12:14.939Z
Learning: In `packages/loot-core/src/server/main.ts`, when handling errors, the error properties `error_code` and `error_type` may already be mapped to `code` and `category` before being passed to `handleSyncError`.

@YesWeCandrew
Copy link

@andrewhumble Thanks for making those changes, latest pushes look great.

Filtering Bug
I’ve discovered a bug with filtering unfortunately. When filtering Categories if you exclude a category it will not appear in the Spent tab, but still appears in the Budgeted tab. When you then click on Difference, error notifications appear.

The multiple errors is also occurring for me on the Budgeted tab with any other filter that I use, such as when filtering on Account.

To reproduce: Use test budget > create Sankey Chart > Filter > Not “Food”.
Expected: Food category would disappear from budgeted, spent and difference tab.
Actual: Food category remains in budgeted, disappears from spent, and errors appear in Difference.

Income in Spent tab
Thanks for adding income into the Spent chart. Currently though it doesn’t include the income carried over from last month like the Budgeted tab does, and the labels are different too. Ideally, the income amounts in the two tabs should match, so this should be included on the Spent tab too if possible, but understand this could be a future fix post merge.

IMG_3054
IMG_3053

@Juulz
Copy link
Contributor

Juulz commented Nov 10, 2025

Oh my! This is great!

Next iteration... color!

@netlify
Copy link

netlify bot commented Nov 11, 2025

Deploy Preview for actual-docs-new failed.

Name Link
🔨 Latest commit 1334b8e
🔍 Latest deploy log https://app.netlify.com/projects/actual-docs-new/deploys/69128b1b1bce2c0007626823

@andrewhumble
Copy link
Author

@YesWeCandrew Thanks for following up. I added the filtering capabilities in so that should be resolved now. Please let me know if you notice any more issues.

For your note on the income on the Spent tab, there are a couple different options here —

  1. (Current approach) Show income transactions. This compiles all of the transactions in is_income categories. To me, this is consistent with the view overall because the outgoing flows are also showing transactions, rather than budget amounts. If we go this route, perhaps this should be renamed the "Transactions" view for clarity.
    • I'll note that the Test Budget isn't great for this view since there aren't very specific income transactions. In a real world budget, this should look more dynamic ("Work Income", "Interest Payment", "Dividend", "Venmo").
  2. (Your suggestion) Show budget income. This would be less consistent with the outgoing side of the view, but I do understand your reasoning here. With this, the income flows would be identical across all three views, which may be preferred and a more logical layout.

I would love to get some additional input on which way might be preferred if anyone else has thoughts. I'm happy to do it either way, but wanted to point out the logic behind

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (1)

7-7: Remove translation wrapper from CSS font-family values.

The t() function is for translating user-facing strings, not CSS property values. Lines 243, 263, and 295 incorrectly wrap the literal font name 'Redacted Script' in t(), and the import on line 7 serves only this incorrect usage.

Apply this diff:

-import { t } from 'i18next';
-            fontFamily={privacyMode ? t('Redacted Script') : undefined}
+            fontFamily={privacyMode ? 'Redacted Script' : undefined}

Apply the same fix at lines 263 and 295.

Also applies to: 243-243, 263-263, 295-295

🧹 Nitpick comments (1)
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (1)

148-148: Remove unused currencyCode parameter.

The currencyCode prop is passed to SankeyNode at line 371 but never referenced in the component body (lines 150-302). Currency formatting is handled by the useFormat hook at line 162.

Apply this diff:

 type SankeyNodeProps = {
   x: number;
   y: number;
   width: number;
   height: number;
   index: number;
   payload: SankeyGraphNode;
   containerWidth: number;
-  currencyCode: string;
 };
 function SankeyNode({
   x,
   y,
   width,
   height,
   index,
   payload,
   containerWidth,
 }: SankeyNodeProps) {
             node={props => (
               <SankeyNode
                 {...props}
                 containerWidth={width}
-                currencyCode={currencyCode}
               />
             )}

Also applies to: 371-371

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eedc5fb and 1334b8e.

📒 Files selected for processing (3)
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (1 hunks)
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx (1 hunks)
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Prefer type over interface in TypeScript
Avoid enum; use objects or maps instead
Avoid any and unknown unless absolutely necessary
Avoid type assertions (as, non-null !); prefer satisfies for narrowing
Use inline type imports: import { type X } from '...'
Favor functional/declarative patterns; avoid classes
Use the function keyword for pure functions
Use named exports for components and utilities (avoid default exports except specific cases)
Maintain import order groups (React, Node built-ins, externals, Actual packages, parent, sibling, index) with newlines between groups
Do not directly reference platform-specific imports by extension (.api, .web, .electron)

Files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Do not use console.*; use the logger instead
Import uuid with destructuring: import { v4 as uuidv4 } from 'uuid'

Files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
packages/{desktop-client,component-library}/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

packages/{desktop-client,component-library}/src/**/*.{ts,tsx}: All user-facing strings must be translated
Prefer <Trans> component over t() when possible
Do not use React.* namespace imports; use named imports
Use theme tokens; do not import colors directly

Files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
packages/{desktop-client,component-library}/src/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

packages/{desktop-client,component-library}/src/**/*.tsx: Do not use React.FC/React.FunctionComponent; type props directly
Avoid unstable nested components in JSX
Prefer declarative, minimal JSX; avoid unnecessary curly braces and prefer concise conditional expressions (condition && <Component />)

Files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
packages/desktop-client/src/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Use <Link> instead of <a> tags

Files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
packages/desktop-client/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

packages/desktop-client/src/**/*.{ts,tsx}: Use custom navigation hook from src/hooks instead of react-router directly
Use useDispatch, useSelector, useStore from src/redux (not react-redux)
Use absolute imports in desktop-client

Files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
🧠 Learnings (45)
📚 Learning: 2024-10-10T02:29:05.655Z
Learnt from: tlesicka
Repo: actualbudget/actual PR: 3593
File: packages/desktop-client/src/components/sidebar/Sidebar.tsx:112-116
Timestamp: 2024-10-10T02:29:05.655Z
Learning: In `packages/desktop-client/src/components/sidebar/BudgetName.tsx`, the `BudgetName` component consists of three parts: `BudgetName`, `EditBudgetName`, and the Menu. Keeping `EditBudgetName` as a separate component helps maintain cleaner code by separating concerns.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-11-01T20:29:18.673Z
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3744
File: packages/desktop-client/src/components/reports/reports/CustomReport.tsx:157-157
Timestamp: 2024-11-01T20:29:18.673Z
Learning: In the `CustomReport` component (`packages/desktop-client/src/components/reports/reports/CustomReport.tsx`), the session storage references are necessary and should not be removed.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2024-10-24T17:05:41.415Z
Learnt from: joel-jeremy
Repo: actualbudget/actual PR: 3685
File: packages/desktop-client/src/components/accounts/Account.tsx:655-665
Timestamp: 2024-10-24T17:05:41.415Z
Learning: The Account component in 'packages/desktop-client/src/components/accounts/Account.tsx' is being rewritten in a separate PR.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.tsx : Prefer declarative, minimal JSX; avoid unnecessary curly braces and prefer concise conditional expressions (`condition && <Component />`)

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.{ts,tsx} : Do not use `React.*` namespace imports; use named imports

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.tsx : Do not use `React.FC`/`React.FunctionComponent`; type props directly

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/desktop-client/src/**/*.{ts,tsx} : Use `useDispatch`, `useSelector`, `useStore` from `src/redux` (not react-redux)

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.tsx : Avoid unstable nested components in JSX

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to **/*.{ts,tsx} : Use named exports for components and utilities (avoid default exports except specific cases)

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2024-10-25T18:30:24.287Z
Learnt from: lelemm
Repo: actualbudget/actual PR: 3309
File: packages/desktop-client/src/components/ColumnWidthContext.jsx:17-17
Timestamp: 2024-10-25T18:30:24.287Z
Learning: In `packages/desktop-client/src/components/ColumnWidthContext.jsx`, replacing `useState` with `useRef` for `positionAccumulator` causes the resize action to become unpredictable. Therefore, it's preferable to keep using `useState` for `positionAccumulator` in this context.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.{ts,tsx} : Use theme tokens; do not import colors directly

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/desktop-client/src/**/*.{ts,tsx} : Use absolute imports in desktop-client

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to **/*.{ts,tsx} : Maintain import order groups (React, Node built-ins, externals, Actual packages, parent, sibling, index) with newlines between groups

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-10-24T16:51:43.421Z
Learnt from: StephenBrown2
Repo: actualbudget/actual PR: 5908
File: packages/desktop-client/src/components/settings/Currency.tsx:38-38
Timestamp: 2025-10-24T16:51:43.421Z
Learning: In the actualbudget/actual repository, JPY (Japanese Yen) currency support can remain enabled in packages/desktop-client/src/components/settings/Currency.tsx and packages/loot-core/src/shared/currencies.ts even though not all features fully support zero-decimal currencies yet, because the currency feature is experimental. The team decided to keep JPY active to avoid repeatedly removing and re-adding it during testing.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-08-16T07:09:15.691Z
Learnt from: sjones512
Repo: actualbudget/actual PR: 5554
File: packages/desktop-client/src/components/reports/spreadsheets/crossover-spreadsheet.ts:375-387
Timestamp: 2025-08-16T07:09:15.691Z
Learning: When handling financial data consistency issues in the desktop client, prefer keeping the data layer (spreadsheets) in raw integer cents and use the useFormat hook for all presentation formatting, rather than converting to display amounts in the data layer.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-06-16T17:45:40.807Z
Learnt from: misu-dev
Repo: actualbudget/actual PR: 5167
File: packages/desktop-client/src/components/spreadsheet/useFormat.ts:64-72
Timestamp: 2025-06-16T17:45:40.807Z
Learning: The user misu-dev prefers strict type checking for financial format types in useFormat.ts as a long-term goal, but acknowledges that creating follow-up issues for cleanup should wait until after the current PR is merged, not during the development phase.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-09-28T08:34:21.188Z
Learnt from: misu-dev
Repo: actualbudget/actual PR: 5639
File: packages/desktop-client/src/components/util/GenericInput.jsx:68-73
Timestamp: 2025-09-28T08:34:21.188Z
Learning: In packages/desktop-client/src/components/util/GenericInput.jsx, for amount filtering with inflow/outflow options, the sign prop should always be '+' (for both inflow and outflow) because the UI layer keeps all amounts positive, while the server-side transaction rules engine handles the actual sign conversion and negation logic when querying the database.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-06-16T17:41:34.452Z
Learnt from: misu-dev
Repo: actualbudget/actual PR: 5167
File: packages/desktop-client/src/components/spreadsheet/useFormat.ts:64-72
Timestamp: 2025-06-16T17:41:34.452Z
Learning: The format function in useFormat.ts is widely used across the application and currently needs to accept both string and number inputs for financial format types. While strict type checking is preferred long-term, string parsing is maintained as a pragmatic compromise during the currency feature development phase.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-11-09T20:18:28.468Z
Learnt from: csenel
Repo: actualbudget/actual PR: 3810
File: packages/desktop-client/src/components/transactions/SelectedTransactionsButton.tsx:150-161
Timestamp: 2024-11-09T20:18:28.468Z
Learning: In `packages/desktop-client/src/components/transactions/SelectedTransactionsButton.tsx`, prefer to keep the implementation of checks consistent with similar patterns elsewhere in the codebase, even if alternative implementations are more concise.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.{ts,tsx} : All user-facing strings must be translated

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2024-11-12T19:52:52.889Z
Learnt from: lelemm
Repo: actualbudget/actual PR: 3792
File: packages/desktop-client/src/components/reports/reports/Summary.tsx:134-161
Timestamp: 2024-11-12T19:52:52.889Z
Learning: In `packages/desktop-client/src/components/reports/reports/Summary.tsx`, API calls like `get-earliest-transaction` are used without explicit error handling to maintain consistency with other components.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/{desktop-client,component-library}/src/**/*.{ts,tsx} : Prefer `<Trans>` component over `t()` when possible

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-06-14T21:20:46.938Z
Learnt from: misu-dev
Repo: actualbudget/actual PR: 5167
File: packages/desktop-client/src/components/spreadsheet/useFormat.ts:161-166
Timestamp: 2025-06-14T21:20:46.938Z
Learning: In the useFormat hook's formatDisplay function, there's an intentional separation between displayDecimalPlaces (used for Intl.NumberFormat display formatting) and activeCurrency.decimalPlaces (used for integerToCurrency conversion logic). These should not be mixed as displayDecimalPlaces controls how many decimals to show while activeCurrency.decimalPlaces controls the mathematical conversion from integer amounts to decimal amounts.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-10-08T15:46:15.739Z
Learnt from: qedi-r
Repo: actualbudget/actual PR: 3527
File: packages/desktop-client/src/components/accounts/Header.jsx:0-0
Timestamp: 2024-10-08T15:46:15.739Z
Learning: In the Actual Budget project, importing `t` directly from 'i18next' is best avoided, and we should almost always prefer using the useTranslation hook if possible.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-01-21T11:39:38.461Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4154
File: packages/desktop-client/src/components/spreadsheet/CellValue.tsx:47-47
Timestamp: 2025-01-21T11:39:38.461Z
Learning: In the CellValue component of packages/desktop-client/src/components/spreadsheet/CellValue.tsx, the children prop needs an additional length check (children && children.length > 0) because the Trans component can pass an empty array at runtime despite the type definition expecting a function.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-10-25T04:49:31.861Z
Learnt from: tlesicka
Repo: actualbudget/actual PR: 3689
File: packages/desktop-client/src/components/modals/manager/DuplicateFileModal.tsx:144-156
Timestamp: 2024-10-25T04:49:31.861Z
Learning: In `packages/desktop-client/src/components/modals/manager/DuplicateFileModal.tsx`, styles for buttons may differ for each button in the future, so avoid suggesting extraction of common styles in this file.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2024-10-12T23:57:22.683Z
Learnt from: jfdoming
Repo: actualbudget/actual PR: 3648
File: packages/desktop-client/src/components/HelpMenu.tsx:25-47
Timestamp: 2024-10-12T23:57:22.683Z
Learning: In `packages/desktop-client/src/components/HelpMenu.tsx`, when a `<Button>` component includes text content as a child, an explicit `aria-label` may not be required for accessibility, as the text content provides the accessible name.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-01-17T12:11:23.669Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 3840
File: packages/loot-core/src/server/budget/template-notes.ts:12-12
Timestamp: 2025-01-17T12:11:23.669Z
Learning: In server-side code or non-React contexts where React hooks cannot be used, prefer using `import { t } from 'i18next'` and directly using `t(string)` for translations, instead of using react-i18next hooks or other approaches.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-10-04T18:16:45.140Z
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3566
File: packages/desktop-client/src/components/reports/Overview.tsx:100-101
Timestamp: 2024-10-04T18:16:45.140Z
Learning: In `packages/desktop-client/src/components/reports/Overview.tsx`, when filtering `baseLayout`, if `item.type === 'custom-report'`, `item.meta.id` will always be defined.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/desktop-client/src/**/*.{ts,tsx} : Use custom navigation hook from `src/hooks` instead of react-router directly

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-10-21T06:59:54.870Z
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to packages/desktop-client/src/**/*.tsx : Use `<Link>` instead of `<a>` tags

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-10-24T21:29:26.090Z
Learnt from: csenel
Repo: actualbudget/actual PR: 5991
File: packages/desktop-client/src/components/mobile/budget/BudgetCell.tsx:82-89
Timestamp: 2025-10-24T21:29:26.090Z
Learning: Notification messages in BudgetCell.tsx will be translated in a separate PR to handle all translations together, as there are multiple messages to go through.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-01-18T20:08:55.203Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4181
File: packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx:252-254
Timestamp: 2025-01-18T20:08:55.203Z
Learning: Notification messages in BudgetTable.jsx will be translated in a separate PR to handle all translations together, as there are multiple messages to go through.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-10-22T16:22:17.482Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 5978
File: packages/desktop-client/src/components/mobile/banksync/BankSyncAccountsListItem.tsx:58-67
Timestamp: 2025-10-22T16:22:17.482Z
Learning: In react-i18next, the Trans component supports interpolation using the syntax `<Trans>Text {{ variable: value }}</Trans>` where the double curly braces are special syntax recognized by react-i18next for variable substitution. This is valid and should not be flagged as incorrect.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2024-10-16T03:51:04.683Z
Learnt from: tlesicka
Repo: actualbudget/actual PR: 3593
File: packages/desktop-client/src/components/sidebar/BudgetName.tsx:114-136
Timestamp: 2024-10-16T03:51:04.683Z
Learning: In 'packages/desktop-client/src/components/sidebar/BudgetName.tsx', empty budget names are handled elsewhere, so additional error handling within the 'EditableBudgetName' component is unnecessary.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-02-19T20:40:35.656Z
Learnt from: lelemm
Repo: actualbudget/actual PR: 4408
File: packages/desktop-client/src/components/mobile/accounts/Accounts.tsx:80-80
Timestamp: 2025-02-19T20:40:35.656Z
Learning: In the Accounts list view, the section headers "On budget" and "Off budget" should be translatable strings as they are UI elements, not user data.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2025-08-16T16:42:08.306Z
Learnt from: sjones512
Repo: actualbudget/actual PR: 5554
File: packages/desktop-client/src/components/reports/spreadsheets/crossover-spreadsheet.ts:7-8
Timestamp: 2025-08-16T16:42:08.306Z
Learning: In the Actual Budget codebase, it's the established pattern and acceptable to import useSpreadsheet as a type-only import and then use ReturnType<typeof useSpreadsheet> in type annotations. This pattern is used consistently across all spreadsheet files including custom-spreadsheet.ts, grouped-spreadsheet.ts, spending-spreadsheet.ts, net-worth-spreadsheet.ts, cash-flow-spreadsheet.tsx, calendar-spreadsheet.ts, summary-spreadsheet.ts, and crossover-spreadsheet.ts.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-08-16T16:42:08.306Z
Learnt from: sjones512
Repo: actualbudget/actual PR: 5554
File: packages/desktop-client/src/components/reports/spreadsheets/crossover-spreadsheet.ts:7-8
Timestamp: 2025-08-16T16:42:08.306Z
Learning: In the Actual Budget codebase, it's acceptable and consistent to import useSpreadsheet as a type-only import and then use ReturnType<typeof useSpreadsheet> in type annotations. This pattern is used consistently across spreadsheet files like custom-spreadsheet.ts and crossover-spreadsheet.ts.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-01-17T12:00:27.629Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4170
File: packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx:570-581
Timestamp: 2025-01-17T12:00:27.629Z
Learning: The transaction amount conversion for income categories in TransactionEdit.jsx is intended as a quality-of-life feature to help users who forget to set the correct direction, not as a preventative measure. Users should still be able to manually enter negative amounts even for income categories.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2024-10-09T20:17:46.493Z
Learnt from: UnderKoen
Repo: actualbudget/actual PR: 3619
File: packages/loot-core/src/server/accounts/transaction-rules.ts:551-0
Timestamp: 2024-10-09T20:17:46.493Z
Learning: When finalizing transactions that involve inserting or retrieving payees, avoid using `Promise.all` as it may result in duplicate payees due to concurrent operations. Sequential processing ensures payees are correctly handled without duplication.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2024-10-09T20:30:39.127Z
Learnt from: UnderKoen
Repo: actualbudget/actual PR: 3619
File: packages/loot-core/src/server/accounts/transaction-rules.ts:795-801
Timestamp: 2024-10-09T20:30:39.127Z
Learning: In the `finalizeTransactionForRules` function within `packages/loot-core/src/server/accounts/transaction-rules.ts`, potential race conditions when inserting payees are handled in the method that calls this function, so additional safeguards within `finalizeTransactionForRules` are unnecessary.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-11-04T00:47:00.968Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 6065
File: packages/desktop-client/src/components/transactions/TransactionList.tsx:197-205
Timestamp: 2025-11-04T00:47:00.968Z
Learning: In packages/desktop-client/src/components/transactions/TransactionList.tsx and similar schedule creation code, when using schedule/create with conditions and then updating the rule's actions, it's correct to filter rule.actions to keep only 'link-schedule' and append custom actions. Transactions created by schedules are defined by a mix of conditions (which create the base transaction with date, amount, payee, account) and actions (which apply additional modifications like category, notes, splits). The filtering pattern replaces any auto-generated actions with the desired custom actions.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-01-14T06:17:55.345Z
Learnt from: jfdoming
Repo: actualbudget/actual PR: 4146
File: packages/desktop-client/src/components/reports/spreadsheets/summary-spreadsheet.ts:30-30
Timestamp: 2025-01-14T06:17:55.345Z
Learning: The `make-filters-from-conditions` function in the Actual Budget codebase returns a complex type that is not explicitly defined. While improving its type definition would be beneficial, it should be handled in a dedicated project due to its complexity.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-01-12T20:22:02.704Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4141
File: packages/desktop-client/src/components/reports/spreadsheets/sortData.ts:15-26
Timestamp: 2025-01-12T20:22:02.704Z
Learning: In the custom reports feature of Actual, the `balanceTypeOp` and `sortByOp` parameters in the `sortData` function are always set and should not be marked as optional.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2024-10-08T23:41:32.134Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 3609
File: packages/loot-core/src/server/db/index.ts:583-598
Timestamp: 2024-10-08T23:41:32.134Z
Learning: In `packages/loot-core/src/server/db/index.ts`, the `orphanedPayeesQuery` uses a subquery with `json_each(r.conditions) AS cond` to loop through JSON conditions because the "description" field may not be the first index. This implementation must remain as is to ensure correct functionality.

Additionally, table aliases are already used consistently in the SQL queries within this file.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
🧬 Code graph analysis (3)
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (5)
packages/desktop-client/src/hooks/useFormat.ts (1)
  • useFormat (109-282)
packages/component-library/src/theme.ts (1)
  • theme (1-204)
packages/desktop-client/src/hooks/usePrivacyMode.ts (1)
  • usePrivacyMode (3-6)
packages/desktop-client/src/hooks/useSyncedPref.ts (1)
  • useSyncedPref (12-29)
packages/desktop-client/src/components/reports/Container.tsx (1)
  • Container (14-31)
packages/desktop-client/src/components/reports/reports/Sankey.tsx (14)
packages/desktop-client/src/hooks/useWidget.ts (1)
  • useWidget (8-21)
packages/loot-core/src/types/models/dashboard.ts (1)
  • SankeyWidget (174-183)
packages/desktop-client/src/components/reports/LoadingIndicator.tsx (1)
  • LoadingIndicator (13-32)
packages/desktop-client/src/hooks/useLocale.ts (1)
  • useLocale (7-14)
packages/desktop-client/src/redux/index.ts (1)
  • useDispatch (18-18)
packages/desktop-client/src/hooks/useNavigate.ts (1)
  • useNavigate (12-48)
packages/component-library/src/hooks/useResponsive.ts (1)
  • useResponsive (5-23)
packages/desktop-client/src/hooks/useRuleConditionFilters.ts (1)
  • useRuleConditionFilters (5-75)
packages/desktop-client/src/hooks/useCategories.ts (1)
  • useCategories (8-22)
packages/desktop-client/src/components/Page.tsx (3)
  • Page (115-155)
  • MobilePageHeader (47-105)
  • PageHeader (16-38)
packages/desktop-client/src/components/EditablePageHeaderTitle.tsx (1)
  • EditablePageHeaderTitle (15-88)
packages/desktop-client/src/components/filters/FiltersMenu.jsx (1)
  • FilterButton (292-473)
packages/desktop-client/src/components/filters/AppliedFilters.tsx (1)
  • AppliedFilters (21-55)
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (1)
  • SankeyGraph (340-405)
packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (3)
packages/loot-core/src/types/models/rule.ts (1)
  • RuleConditionEntity (73-137)
packages/loot-core/src/types/models/category-group.ts (1)
  • CategoryGroupEntity (3-11)
packages/desktop-client/src/hooks/useSpreadsheet.tsx (1)
  • useSpreadsheet (19-25)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: compare
🔇 Additional comments (1)
packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (1)

294-297: Replace console.error with logger.

Per coding guidelines, console.* should not be used. Import and use the logger instead.

Apply this diff:

+import { logger } from 'loot-core/platform/server/log';
       } catch (error) {
-        console.error('Error fetching category data:', error);
+        logger.error('Error fetching category data:', error);
         throw error; // Re-throw if you want the error to propagate
       }

As per coding guidelines.

⛔ Skipped due to learnings
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 5978
File: packages/desktop-client/src/components/mobile/banksync/MobileBankSyncAccountEditPage.tsx:54-57
Timestamp: 2025-10-22T00:50:31.002Z
Learning: The logger should only be used in loot-core code. In desktop-client code, using console methods (console.error, console.log, etc.) is acceptable.
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 6010
File: packages/sync-server/src/app-sync.ts:331-331
Timestamp: 2025-10-27T17:06:08.172Z
Learning: The logger should only be used in loot-core code. In sync-server code (packages/sync-server), using console methods (console.error, console.log, etc.) is acceptable.
Learnt from: CR
Repo: actualbudget/actual PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-21T06:59:54.870Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Do not use `console.*`; use the logger instead
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 3581
File: packages/loot-core/src/server/main.ts:1188-1198
Timestamp: 2024-10-25T00:12:14.939Z
Learning: In `packages/loot-core/src/server/main.ts`, when handling errors, the error properties `error_code` and `error_type` may already be mapped to `code` and `category` before being passed to `handleSyncError`.
Learnt from: tlesicka
Repo: actualbudget/actual PR: 3689
File: packages/loot-core/src/server/backups.web.ts:203-207
Timestamp: 2024-10-24T05:09:44.115Z
Learning: In `packages/loot-core/src/server/backups.web.ts`, developers prefer to keep the error handling for cloud storage uploads inline rather than extracting it into a separate function. Avoid suggesting this refactoring in future reviews.
Learnt from: tlesicka
Repo: actualbudget/actual PR: 3689
File: packages/loot-core/src/platform/server/fs/index.web.ts:319-340
Timestamp: 2024-10-25T05:04:40.902Z
Learning: In `packages/loot-core/src/platform/server/fs/index.web.ts`, errors are already handled in other locations, so additional error handling in `copyFile` is unnecessary.
Learnt from: tlesicka
Repo: actualbudget/actual PR: 3689
File: packages/loot-core/src/server/main.ts:1873-1877
Timestamp: 2024-10-23T07:39:50.053Z
Learning: In the `duplicate-budget` function in `packages/loot-core/src/server/main.ts`, when `loadBudget` returns an object with an `error` property where `error` is a string, returning `error` directly is consistent with the function's declared return type `Promise<string>`.
Learnt from: tlesicka
Repo: actualbudget/actual PR: 3689
File: packages/loot-core/src/server/main.ts:1807-1809
Timestamp: 2024-10-23T07:38:25.699Z
Learning: In the function `delete-budget` in `packages/loot-core/src/server/main.ts`, the function `removeAllBackups(id)` handles its own errors internally, so additional error handling when calling it is unnecessary.
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 3581
File: packages/loot-core/src/client/actions/account.ts:180-194
Timestamp: 2024-11-04T00:34:13.035Z
Learning: In `packages/loot-core/src/client/actions/account.ts`, within the `syncAccounts` function, the batch sync request for SimpleFin accounts handles errors by returning error objects instead of throwing exceptions. Therefore, wrapping this block in a try-catch is unnecessary.

@netlify
Copy link

netlify bot commented Nov 12, 2025

Deploy Preview for actualbudget-website canceled.

Name Link
🔨 Latest commit e2de4d6
🔍 Latest deploy log https://app.netlify.com/projects/actualbudget-website/deploys/695d3a6e1bdc9200076fa467

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (2)

302-306: Simplify income subcategory collection.

The concat with spread operator can be replaced with flatMap for clearer intent and better readability.

Apply this diff:

-  const allIncomeSubcategories = [].concat(
-    ...categories
-      .filter(category => category.is_income)
-      .map(category => category.categories),
-  );
+  const allIncomeSubcategories = categories
+    .filter(category => category.is_income)
+    .flatMap(category => category.categories ?? []);

550-636: Add explicit type annotations for better type safety.

The transformToSankeyData function parameters and return value lack explicit types, reducing type safety and developer ergonomics. Consider adding type annotations for categoryData, incomeData, and the return type.

Consider defining and using explicit types:

type CategoryBalance = {
  subcategory: string;
  value: number;
  isNegative?: boolean;
  actualValue?: number;
};

type CategoryData = {
  name: string;
  balances: CategoryBalance[];
};

type IncomeData = Record<string, number>;

type SankeyNode = {
  name: string;
  toBudget?: number;
  nodeType?: 'budget' | 'income' | 'expense';
  isNegative?: boolean;
};

type SankeyLink = {
  source: string | number;
  target: string | number;
  value: number;
  isNegative?: boolean;
};

type SankeyData = {
  nodes: SankeyNode[];
  links: SankeyLink[];
};

function transformToSankeyData(
  categoryData: CategoryData[],
  incomeData: IncomeData,
  toBudgetAmount: number = 0,
  rootNodeName: string = 'Available Funds',
): SankeyData {
  // ... function body
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1334b8e and f433d7f.

📒 Files selected for processing (2)
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (1 hunks)
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
🧰 Additional context used
🧠 Learnings (10)
📚 Learning: 2025-08-16T16:42:08.306Z
Learnt from: sjones512
Repo: actualbudget/actual PR: 5554
File: packages/desktop-client/src/components/reports/spreadsheets/crossover-spreadsheet.ts:7-8
Timestamp: 2025-08-16T16:42:08.306Z
Learning: In the Actual Budget codebase, it's the established pattern and acceptable to import useSpreadsheet as a type-only import and then use ReturnType<typeof useSpreadsheet> in type annotations. This pattern is used consistently across all spreadsheet files including custom-spreadsheet.ts, grouped-spreadsheet.ts, spending-spreadsheet.ts, net-worth-spreadsheet.ts, cash-flow-spreadsheet.tsx, calendar-spreadsheet.ts, summary-spreadsheet.ts, and crossover-spreadsheet.ts.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-08-16T16:42:08.306Z
Learnt from: sjones512
Repo: actualbudget/actual PR: 5554
File: packages/desktop-client/src/components/reports/spreadsheets/crossover-spreadsheet.ts:7-8
Timestamp: 2025-08-16T16:42:08.306Z
Learning: In the Actual Budget codebase, it's acceptable and consistent to import useSpreadsheet as a type-only import and then use ReturnType<typeof useSpreadsheet> in type annotations. This pattern is used consistently across spreadsheet files like custom-spreadsheet.ts and crossover-spreadsheet.ts.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-01-17T12:00:27.629Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4170
File: packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx:570-581
Timestamp: 2025-01-17T12:00:27.629Z
Learning: The transaction amount conversion for income categories in TransactionEdit.jsx is intended as a quality-of-life feature to help users who forget to set the correct direction, not as a preventative measure. Users should still be able to manually enter negative amounts even for income categories.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2024-10-09T20:17:46.493Z
Learnt from: UnderKoen
Repo: actualbudget/actual PR: 3619
File: packages/loot-core/src/server/accounts/transaction-rules.ts:551-0
Timestamp: 2024-10-09T20:17:46.493Z
Learning: When finalizing transactions that involve inserting or retrieving payees, avoid using `Promise.all` as it may result in duplicate payees due to concurrent operations. Sequential processing ensures payees are correctly handled without duplication.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2024-10-09T20:30:39.127Z
Learnt from: UnderKoen
Repo: actualbudget/actual PR: 3619
File: packages/loot-core/src/server/accounts/transaction-rules.ts:795-801
Timestamp: 2024-10-09T20:30:39.127Z
Learning: In the `finalizeTransactionForRules` function within `packages/loot-core/src/server/accounts/transaction-rules.ts`, potential race conditions when inserting payees are handled in the method that calls this function, so additional safeguards within `finalizeTransactionForRules` are unnecessary.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2024-10-08T15:46:15.739Z
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3566
File: packages/desktop-client/src/components/reports/Overview.tsx:100-101
Timestamp: 2024-10-08T15:46:15.739Z
Learning: In `packages/desktop-client/src/components/reports/Overview.tsx`, when filtering `baseLayout`, if `item.type === 'custom-report'`, `item.meta.id` will always be defined.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-11-04T00:47:00.968Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 6065
File: packages/desktop-client/src/components/transactions/TransactionList.tsx:197-205
Timestamp: 2025-11-04T00:47:00.968Z
Learning: In packages/desktop-client/src/components/transactions/TransactionList.tsx and similar schedule creation code, when using schedule/create with conditions and then updating the rule's actions, it's correct to filter rule.actions to keep only 'link-schedule' and append custom actions. Transactions created by schedules are defined by a mix of conditions (which create the base transaction with date, amount, payee, account) and actions (which apply additional modifications like category, notes, splits). The filtering pattern replaces any auto-generated actions with the desired custom actions.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-01-14T06:17:55.345Z
Learnt from: jfdoming
Repo: actualbudget/actual PR: 4146
File: packages/desktop-client/src/components/reports/spreadsheets/summary-spreadsheet.ts:30-30
Timestamp: 2025-01-14T06:17:55.345Z
Learning: The `make-filters-from-conditions` function in the Actual Budget codebase returns a complex type that is not explicitly defined. While improving its type definition would be beneficial, it should be handled in a dedicated project due to its complexity.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-01-12T20:22:02.704Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4141
File: packages/desktop-client/src/components/reports/spreadsheets/sortData.ts:15-26
Timestamp: 2025-01-12T20:22:02.704Z
Learning: In the custom reports feature of Actual, the `balanceTypeOp` and `sortByOp` parameters in the `sortData` function are always set and should not be marked as optional.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2024-10-08T23:41:32.134Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 3609
File: packages/loot-core/src/server/db/index.ts:583-598
Timestamp: 2024-10-08T23:41:32.134Z
Learning: In `packages/loot-core/src/server/db/index.ts`, the `orphanedPayeesQuery` uses a subquery with `json_each(r.conditions) AS cond` to loop through JSON conditions because the "description" field may not be the first index. This implementation must remain as is to ensure correct functionality.

Additionally, table aliases are already used consistently in the SQL queries within this file.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
🧬 Code graph analysis (1)
packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (4)
packages/loot-core/src/types/models/rule.ts (1)
  • RuleConditionEntity (73-137)
packages/loot-core/src/types/models/category-group.ts (1)
  • CategoryGroupEntity (3-11)
packages/desktop-client/src/hooks/useSpreadsheet.tsx (1)
  • useSpreadsheet (19-25)
packages/loot-core/src/platform/server/log/index.ts (1)
  • logger (11-43)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: compare
🔇 Additional comments (2)
packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (2)

152-239: LGTM!

The budgeted mode correctly separates income and expense groups using boolean checks, applies filtering, and constructs the Sankey data structure with budget allocations.


371-548: LGTM!

The difference mode correctly fetches budgeted and spent data, calculates variance, and marks overspent categories with the isNegative flag for differential rendering.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f433d7f and 7de708a.

⛔ Files ignored due to path filters (257)
  • packages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-4-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-5-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-6-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-7-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-8-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-9-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-import-csv-file-twice-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-import-csv-file-twice-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-import-csv-file-twice-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-imports-transactions-from-a-CSV-file-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-imports-transactions-from-a-CSV-file-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-imports-transactions-from-a-CSV-file-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-4-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-5-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-6-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-creates-a-new-account-and-views-the-initial-balance-transaction-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-creates-a-new-account-and-views-the-initial-balance-transaction-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-creates-a-new-account-and-views-the-initial-balance-transaction-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-checks-the-page-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-checks-the-page-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-checks-the-page-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-page-handles-empty-state-gracefully-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-page-handles-empty-state-gracefully-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-page-handles-empty-state-gracefully-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-searches-for-accounts-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-searches-for-accounts-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-searches-for-accounts-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/bank-sync.test.ts-snapshots/Bank-Sync-checks-the-page-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/bank-sync.test.ts-snapshots/Bank-Sync-checks-the-page-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/bank-sync.test.ts-snapshots/Bank-Sync-checks-the-page-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-applies-budget-template-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-applies-budget-template-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-applies-budget-template-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--14404-in-the-page-header-opens-the-month-menu-modal-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--321fd-ed-amount-opens-the-budget-summary-menu-modal-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--4bb70-ed-amount-opens-the-budget-summary-menu-modal-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--589a6-the-page-header-shows-the-next-month-s-budget-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--6ab37-roup-name-opens-the-category-group-menu-modal-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--6dbdb-page-header-shows-the-previous-month-s-budget-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--7bd8f-the-page-header-shows-the-next-month-s-budget-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--884ac-the-page-header-shows-the-next-month-s-budget-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--94a79-roup-name-opens-the-category-group-menu-modal-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--94a85-ed-amount-opens-the-budget-summary-menu-modal-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--96ebb-page-header-shows-the-previous-month-s-budget-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--9e6aa-in-the-page-header-opens-the-budget-page-menu-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--bbde3-roup-name-opens-the-category-group-menu-modal-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--bed18-in-the-page-header-opens-the-month-menu-modal-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--c18ad-l-redirects-to-the-category-transactions-page-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--ceb3a-in-the-page-header-opens-the-month-menu-modal-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--d270d-in-the-page-header-opens-the-budget-page-menu-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--d7184-page-header-shows-the-previous-month-s-budget-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--e995e-l-redirects-to-the-category-transactions-page-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--fdd57-in-the-page-header-opens-the-budget-page-menu-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--ff568-l-redirects-to-the-category-transactions-page-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-category-name-opens-the-category-menu-modal-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-category-name-opens-the-category-menu-modal-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-category-name-opens-the-category-menu-modal-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-copies-last-month-s-budget-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-copies-last-month-s-budget-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-copies-last-month-s-budget-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-12-month-average-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-12-month-average-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-12-month-average-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-3-month-average-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-3-month-average-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-3-month-average-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-6-month-average-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-6-month-average-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-6-month-average-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-applies-budget-template-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-applies-budget-template-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-applies-budget-template-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--0ba04-nt-amount-opens-the-budget-summary-menu-modal-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--0dfe7-page-header-shows-the-previous-month-s-budget-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--11290-l-redirects-to-the-category-transactions-page-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--1ce6d-nt-amount-opens-the-budget-summary-menu-modal-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--42062-in-the-page-header-opens-the-month-menu-modal-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--49fb6-in-the-page-header-opens-the-month-menu-modal-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--57d88-l-redirects-to-the-category-transactions-page-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--5d90c-l-redirects-to-the-category-transactions-page-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--5f098-roup-name-opens-the-category-group-menu-modal-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--7c353-the-page-header-shows-the-next-month-s-budget-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--929be-roup-name-opens-the-category-group-menu-modal-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--a3783-in-the-page-header-opens-the-budget-page-menu-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--a8b5e-in-the-page-header-opens-the-budget-page-menu-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--b1562-in-the-page-header-opens-the-month-menu-modal-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--cfb69-page-header-shows-the-previous-month-s-budget-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--d5af6-the-page-header-shows-the-next-month-s-budget-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--dc927-roup-name-opens-the-category-group-menu-modal-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f2198-the-page-header-shows-the-next-month-s-budget-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f224f-nt-amount-opens-the-budget-summary-menu-modal-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f7fa3-page-header-shows-the-previous-month-s-budget-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f8a19-in-the-page-header-opens-the-budget-page-menu-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-category-name-opens-the-category-menu-modal-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-category-name-opens-the-category-menu-modal-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-category-name-opens-the-category-menu-modal-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-copies-last-month-s-budget-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-copies-last-month-s-budget-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-copies-last-month-s-budget-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-12-month-average-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-12-month-average-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-12-month-average-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-3-month-average-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-3-month-average-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-3-month-average-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-6-month-average-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-6-month-average-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-6-month-average-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.test.ts-snapshots/Budget-renders-the-summary-information-available-funds-overspent-budgeted-and-for-next-month-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.test.ts-snapshots/Budget-renders-the-summary-information-available-funds-overspent-budgeted-and-for-next-month-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.test.ts-snapshots/Budget-renders-the-summary-information-available-funds-overspent-budgeted-and-for-next-month-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.test.ts-snapshots/Budget-transfer-funds-to-another-category-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.test.ts-snapshots/Budget-transfer-funds-to-another-category-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/budget.test.ts-snapshots/Budget-transfer-funds-to-another-category-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-search-works-correctly-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-search-works-correctly-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-search-works-correctly-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-help-menu-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-help-menu-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-help-menu-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-4-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-5-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-6-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-7-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-8-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-9-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-4-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-5-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-6-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-checks-the-page-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-checks-the-page-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-checks-the-page-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-payee-edit-page-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-payee-edit-page-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-payee-edit-page-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-rule-creation-form-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-rule-creation-form-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-rule-creation-form-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-filters-out-unrelated-payees-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-filters-out-unrelated-payees-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-filters-out-unrelated-payees-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-page-handles-empty-state-gracefully-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-page-handles-empty-state-gracefully-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-page-handles-empty-state-gracefully-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-4-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-5-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-6-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-4-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-5-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-6-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Area-Graph-and-checks-the-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Area-Graph-and-checks-the-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Area-Graph-and-checks-the-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Bar-Graph-and-checks-the-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Bar-Graph-and-checks-the-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Bar-Graph-and-checks-the-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Data-Table-and-checks-the-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Data-Table-and-checks-the-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Data-Table-and-checks-the-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Donut-Graph-and-checks-the-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Donut-Graph-and-checks-the-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Donut-Graph-and-checks-the-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Line-Graph-and-checks-the-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Line-Graph-and-checks-the-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Line-Graph-and-checks-the-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-labels-button-shows-the-labels-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-labels-button-shows-the-labels-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-labels-button-shows-the-labels-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-legend-button-shows-the-legend-side-bar-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-legend-button-shows-the-legend-side-bar-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-legend-button-shows-the-legend-side-bar-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-summary-button-shows-the-summary-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-summary-button-shows-the-summary-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-summary-button-shows-the-summary-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-cash-flow-graph-and-checks-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-cash-flow-graph-and-checks-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-cash-flow-graph-and-checks-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-and-cash-flow-reports-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-and-cash-flow-reports-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-and-cash-flow-reports-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-graph-and-checks-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-graph-and-checks-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-graph-and-checks-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-checks-the-page-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-checks-the-page-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-checks-the-page-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-add-button-opens-rule-creation-form-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-add-button-opens-rule-creation-form-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-add-button-opens-rule-creation-form-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-on-a-rule-opens-edit-form-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-on-a-rule-opens-edit-form-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-on-a-rule-opens-edit-form-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-displays-the-rules-page-with-proper-header-and-search-bar-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-displays-the-rules-page-with-proper-header-and-search-bar-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-displays-the-rules-page-with-proper-header-and-search-bar-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-page-handles-empty-state-gracefully-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-page-handles-empty-state-gracefully-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-page-handles-empty-state-gracefully-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-search-functionality-filters-rules-correctly-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-search-functionality-filters-rules-correctly-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-search-functionality-filters-rules-correctly-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.test.ts-snapshots/Rules-checks-the-page-visuals-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.test.ts-snapshots/Rules-checks-the-page-visuals-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.test.ts-snapshots/Rules-checks-the-page-visuals-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-1-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-2-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-3-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-4-chromium-linux.png is excluded by !**/*.png
  • packages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-5-chromium-linux.png is excluded by !**/*.png
📒 Files selected for processing (1)
  • commands.txt (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: Analyze
  • GitHub Check: test
  • GitHub Check: Wait for Netlify build to finish
  • GitHub Check: Functional Desktop App
  • GitHub Check: Generate VRT Updates
  • GitHub Check: build (ubuntu-22.04)
  • GitHub Check: build (windows-latest)
  • GitHub Check: build (macos-latest)
🔇 Additional comments (1)
commands.txt (1)

5-6: Verify merge target branch.

Line 6 merges upstream/main. Confirm this is the correct target branch for your repository's upstream (many projects use upstream/master or another default branch). If uncertain, check your repository's configuration or contributing guidelines.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/desktop-client/src/components/reports/ReportRouter.tsx (1)

17-45: Gate Sankey routes behind the feature flag

Right now the Sankey routes are always registered, so anyone can deep-link to /reports/sankey even when the sankeyReport flag is off, effectively bypassing the experimental gate. Mirror the crossover pattern: pull the flag and wrap these routes so they only exist when the feature is enabled.

Apply this diff:

 export function ReportRouter() {
   const crossoverReportEnabled = useFeatureFlag('crossoverReport');
+  const sankeyReportEnabled = useFeatureFlag('sankeyReport');

   return (
     <Routes>
@@
-      <Route path="/sankey" element={<Sankey />} />
-      <Route path="/sankey/:id" element={<Sankey />} />
+      {sankeyReportEnabled && (
+        <>
+          <Route path="/sankey" element={<Sankey />} />
+          <Route path="/sankey/:id" element={<Sankey />} />
+        </>
+      )}
     </Routes>
   );
 }
♻️ Duplicate comments (2)
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (1)

241-298: Hard-code the font name instead of translating it.

fontFamily={privacyMode ? t('Redacted Script') : undefined} still runs the font name through i18n. Translators can (and some already do) change keys, which would break the font. Switch to the literal string (and drop the t import) for all occurrences.

-import { t } from 'i18next';
@@
-            fontFamily={privacyMode ? t('Redacted Script') : undefined}
+            fontFamily={privacyMode ? 'Redacted Script' : undefined}
@@
-            fontFamily={privacyMode ? t('Redacted Script') : undefined}
+            fontFamily={privacyMode ? 'Redacted Script' : undefined}
@@
-            fontFamily={privacyMode ? t('Redacted Script') : undefined}
+            fontFamily={privacyMode ? 'Redacted Script' : undefined}

Based on learnings

packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (1)

62-91: Stop defaulting unsupported category operators to “match everything”.

Returning true for categoryMatchesConditions whenever we hit contains / doesNotContain / matches means those filters quietly include every category, so Sankey reports ignore legitimate user filters. Handle the string operators explicitly and fail closed on unknown ops.

@@
-  const categoryMatchesConditions = (categoryId: string): boolean => {
-    if (conditionsOp === 'or') {
-      // For OR, category matches if it matches ANY condition
-      return categoryConditions.some(cond => {
+  const categoryMatchesConditions = (categoryId: string): boolean => {
+    const categoryName =
+      categoryIdToNameMap.get(categoryId)?.toLowerCase() ?? '';
+    const groupName =
+      categoryIdToGroupMap.get(categoryId)?.toLowerCase() ?? '';
+
+    const stringMatches = (value: unknown) => {
+      const query = String(value ?? '').toLowerCase();
+      if (!query) {
+        return false;
+      }
+      return categoryName.includes(query) || groupName.includes(query);
+    };
+
+    const patternMatches = (value: unknown) => {
+      if (typeof value !== 'string' || value === '') {
+        return false;
+      }
+      try {
+        const regex = new RegExp(value, 'i');
+        return regex.test(categoryName) || regex.test(groupName);
+      } catch {
+        return false;
+      }
+    };
+
+    if (conditionsOp === 'or') {
+      // For OR, category matches if it matches ANY condition
+      return categoryConditions.some(cond => {
@@
-        } else if (cond.op === 'notOneOf') {
+        } else if (cond.op === 'notOneOf') {
           return !Array.isArray(cond.value) || !cond.value.includes(categoryId);
+        } else if (cond.op === 'contains') {
+          return stringMatches(cond.value);
+        } else if (cond.op === 'doesNotContain') {
+          return !stringMatches(cond.value);
+        } else if (cond.op === 'matches') {
+          return patternMatches(cond.value);
         }
-        return true;
+        return false;
       });
     } else {
       // For AND, category matches if it matches ALL conditions
       return categoryConditions.every(cond => {
@@
-        } else if (cond.op === 'notOneOf') {
+        } else if (cond.op === 'notOneOf') {
           return !Array.isArray(cond.value) || !cond.value.includes(categoryId);
+        } else if (cond.op === 'contains') {
+          return stringMatches(cond.value);
+        } else if (cond.op === 'doesNotContain') {
+          return !stringMatches(cond.value);
+        } else if (cond.op === 'matches') {
+          return patternMatches(cond.value);
         }
-        return true;
+        return false;
       });
     }
   };
🧹 Nitpick comments (1)
packages/loot-core/src/types/prefs.ts (1)

1-11: Remove duplicate 'plugins' union member

The FeatureFlag union now includes 'plugins' twice, which is redundant noise. Please collapse it to a single entry to keep the type definition tidy.

Apply this diff:

   | 'currency'
-  | 'plugins'
   | 'crossoverReport'
-  | 'plugins'
   | 'forceReload'
   | 'sankeyReport';
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 70615db and aa9d7aa.

⛔ Files ignored due to path filters (1)
  • upcoming-release-notes/6068.md is excluded by !**/*.md
📒 Files selected for processing (12)
  • packages/desktop-client/e2e/page-models/sankey-page.ts (1 hunks)
  • packages/desktop-client/e2e/sankey.test.ts (1 hunks)
  • packages/desktop-client/src/components/reports/Overview.tsx (4 hunks)
  • packages/desktop-client/src/components/reports/ReportRouter.tsx (2 hunks)
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (1 hunks)
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx (1 hunks)
  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx (1 hunks)
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (1 hunks)
  • packages/desktop-client/src/components/settings/Experimental.tsx (1 hunks)
  • packages/desktop-client/src/hooks/useFeatureFlag.ts (1 hunks)
  • packages/loot-core/src/types/models/dashboard.ts (2 hunks)
  • packages/loot-core/src/types/prefs.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (51)
📚 Learning: 2025-01-18T20:08:55.203Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4181
File: packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx:252-254
Timestamp: 2025-01-18T20:08:55.203Z
Learning: Notification messages in BudgetTable.jsx will be translated in a separate PR to handle all translations together, as there are multiple messages to go through.

Applied to files:

  • packages/desktop-client/src/components/settings/Experimental.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2024-11-01T20:29:18.673Z
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3744
File: packages/desktop-client/src/components/reports/reports/CustomReport.tsx:157-157
Timestamp: 2024-11-01T20:29:18.673Z
Learning: In the `CustomReport` component (`packages/desktop-client/src/components/reports/reports/CustomReport.tsx`), the session storage references are necessary and should not be removed.

Applied to files:

  • packages/desktop-client/src/components/reports/ReportRouter.tsx
  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-08-16T16:42:08.306Z
Learnt from: sjones512
Repo: actualbudget/actual PR: 5554
File: packages/desktop-client/src/components/reports/spreadsheets/crossover-spreadsheet.ts:7-8
Timestamp: 2025-08-16T16:42:08.306Z
Learning: In the Actual Budget codebase, it's the established pattern and acceptable to import useSpreadsheet as a type-only import and then use ReturnType<typeof useSpreadsheet> in type annotations. This pattern is used consistently across all spreadsheet files including custom-spreadsheet.ts, grouped-spreadsheet.ts, spending-spreadsheet.ts, net-worth-spreadsheet.ts, cash-flow-spreadsheet.tsx, calendar-spreadsheet.ts, summary-spreadsheet.ts, and crossover-spreadsheet.ts.

Applied to files:

  • packages/desktop-client/src/components/reports/ReportRouter.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2024-09-17T20:04:47.663Z
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3458
File: packages/loot-core/src/client/state-types/prefs.d.ts:5-5
Timestamp: 2024-09-17T20:04:47.663Z
Learning: In future reviews, ensure that changes related to `PrefsState` in `prefs.d.ts` do not incorrectly assume necessary updates in other parts of the codebase. Verify the impact thoroughly before making suggestions.

Applied to files:

  • packages/loot-core/src/types/prefs.ts
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/e2e/sankey.test.ts
📚 Learning: 2025-10-12T04:07:06.002Z
Learnt from: lelemm
Repo: actualbudget/actual PR: 5786
File: packages/api/tsconfig.dist.json:14-14
Timestamp: 2025-10-12T04:07:06.002Z
Learning: In the Actual Budget codebase, when rootDir is removed from packages/loot-core/tsconfig.api.json to allow referencing files outside the loot-core directory, the declaration output structure changes. The path alias for loot-core in packages/api/tsconfig.dist.json must be updated from "./types/loot-core/src/*" to "./types/loot-core/loot-core/src/*" to match the new emitted declaration paths, as TypeScript preserves the full directory structure from the project root when rootDir is not specified.

Applied to files:

  • packages/loot-core/src/types/prefs.ts
📚 Learning: 2025-01-16T14:30:36.518Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4166
File: packages/loot-core/src/client/data-hooks/transactions.ts:155-158
Timestamp: 2025-01-16T14:30:36.518Z
Learning: In packages/loot-core/src/client/data-hooks/transactions.ts, the `upcomingLength` preference is always stored as a number in string format, so no additional type checking is needed when using `parseInt`.

Applied to files:

  • packages/loot-core/src/types/prefs.ts
📚 Learning: 2025-09-30T00:28:46.031Z
Learnt from: lelemm
Repo: actualbudget/actual PR: 5786
File: packages/plugins-core/src/types/actualPluginManifest.ts:10-10
Timestamp: 2025-09-30T00:28:46.031Z
Learning: The `ActualPluginManifest` interface in packages/plugins-core/src/types/actualPluginManifest.ts must be used with DOM contexts and requires the `plugin?: Blob` field to remain as Blob type.

Applied to files:

  • packages/loot-core/src/types/prefs.ts
📚 Learning: 2025-01-02T18:25:14.566Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4041
File: packages/loot-core/src/types/util.d.ts:13-16
Timestamp: 2025-01-02T18:25:14.566Z
Learning: In `packages/loot-core/src/types/util.d.ts`, `TransObjectLiteral` remains typed as `any` due to the react-i18next issue (https://github.com/i18next/react-i18next/issues/1483) not being resolved yet.

Applied to files:

  • packages/loot-core/src/types/prefs.ts
📚 Learning: 2024-10-08T15:46:15.739Z
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3566
File: packages/desktop-client/src/components/reports/Overview.tsx:100-101
Timestamp: 2024-10-08T15:46:15.739Z
Learning: In `packages/desktop-client/src/components/reports/Overview.tsx`, when filtering `baseLayout`, if `item.type === 'custom-report'`, `item.meta.id` will always be defined.

Applied to files:

  • packages/desktop-client/src/components/reports/Overview.tsx
  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-06-03T23:19:44.814Z
Learnt from: elijaholmos
Repo: actualbudget/actual PR: 5076
File: packages/desktop-client/src/components/CommandBar.tsx:70-70
Timestamp: 2025-06-03T23:19:44.814Z
Learning: The useReports hook in packages/desktop-client/src/hooks/useReports.ts always returns an array for the data property due to initialData: [] and default value fallback (data: customReports = []), so it never returns undefined and doesn't need additional undefined checks when used.

Applied to files:

  • packages/desktop-client/src/components/reports/Overview.tsx
  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/hooks/useFeatureFlag.ts
📚 Learning: 2025-06-03T23:19:44.814Z
Learnt from: elijaholmos
Repo: actualbudget/actual PR: 5076
File: packages/desktop-client/src/components/CommandBar.tsx:70-70
Timestamp: 2025-06-03T23:19:44.814Z
Learning: The useReports hook in packages/desktop-client/src/hooks/useReports.ts always returns an array for the data property due to the ternary operator at line 62: `queryData ? [...queryData] : []`, ensuring data is never undefined even if the underlying query returns undefined.

Applied to files:

  • packages/desktop-client/src/components/reports/Overview.tsx
  • packages/desktop-client/src/hooks/useFeatureFlag.ts
📚 Learning: 2024-10-24T17:05:41.415Z
Learnt from: joel-jeremy
Repo: actualbudget/actual PR: 3685
File: packages/desktop-client/src/components/accounts/Account.tsx:655-665
Timestamp: 2024-10-24T17:05:41.415Z
Learning: The Account component in 'packages/desktop-client/src/components/accounts/Account.tsx' is being rewritten in a separate PR.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-10-25T18:30:24.287Z
Learnt from: lelemm
Repo: actualbudget/actual PR: 3309
File: packages/desktop-client/src/components/ColumnWidthContext.jsx:17-17
Timestamp: 2024-10-25T18:30:24.287Z
Learning: In `packages/desktop-client/src/components/ColumnWidthContext.jsx`, replacing `useState` with `useRef` for `positionAccumulator` causes the resize action to become unpredictable. Therefore, it's preferable to keep using `useState` for `positionAccumulator` in this context.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-11-09T20:18:28.468Z
Learnt from: csenel
Repo: actualbudget/actual PR: 3810
File: packages/desktop-client/src/components/transactions/SelectedTransactionsButton.tsx:150-161
Timestamp: 2024-11-09T20:18:28.468Z
Learning: In `packages/desktop-client/src/components/transactions/SelectedTransactionsButton.tsx`, prefer to keep the implementation of checks consistent with similar patterns elsewhere in the codebase, even if alternative implementations are more concise.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-09-26T19:32:57.858Z
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3507
File: packages/desktop-client/src/components/table.tsx:1220-1220
Timestamp: 2024-09-26T19:32:57.858Z
Learning: The `TableNavigator` type in `packages/desktop-client/src/components/table.tsx` is not used outside of this file and can safely be made private by removing the `export` keyword.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/e2e/sankey.test.ts
📚 Learning: 2024-10-22T05:34:56.976Z
Learnt from: joel-jeremy
Repo: actualbudget/actual PR: 3685
File: packages/desktop-client/src/components/mobile/accounts/AccountTransactions.tsx:261-277
Timestamp: 2024-10-22T05:34:56.976Z
Learning: In React components (TypeScript), avoid using hooks like `useCallback` inside callbacks or nested functions. Hooks must be called at the top level of functional components.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-10-22T02:08:48.162Z
Learnt from: joel-jeremy
Repo: actualbudget/actual PR: 3685
File: packages/loot-core/src/client/data-hooks/transactions.ts:32-88
Timestamp: 2024-10-22T02:08:48.162Z
Learning: In the React `useTransactions` hook defined in `packages/loot-core/src/client/data-hooks/transactions.ts`, changes to `options` (e.g., `options.pageCount`) should be applied on the next query without adding them to the `useEffect` dependency array, to avoid unnecessary rerenders when options change.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2024-10-05T10:58:13.598Z
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3570
File: packages/desktop-client/src/components/modals/ImportTransactionsModal/Transaction.tsx:83-90
Timestamp: 2024-10-05T10:58:13.598Z
Learning: In the `Transaction` component in `Transaction.tsx`, both `rawTransaction` and `transaction` should be included in the dependency arrays of `useMemo` hooks, even though `transaction` derives from `rawTransaction`.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-10-22T05:32:57.033Z
Learnt from: joel-jeremy
Repo: actualbudget/actual PR: 3685
File: packages/desktop-client/src/components/schedules/index.tsx:33-35
Timestamp: 2024-10-22T05:32:57.033Z
Learning: In the project's React components, when using `dispatch` from `useDispatch` in `useCallback` or `useEffect` hooks, `dispatch` must be included in the dependency array due to the `react-hooks/exhaustive-deps` ESLint rule.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2024-10-22T05:32:30.530Z
Learnt from: joel-jeremy
Repo: actualbudget/actual PR: 3685
File: packages/desktop-client/src/components/schedules/index.tsx:37-39
Timestamp: 2024-10-22T05:32:30.530Z
Learning: In our React function components, we should include `dispatch` in the dependency array of `useCallback` hooks to comply with ESLint rules, even though `dispatch` is a stable function.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-01-16T14:28:00.133Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4166
File: packages/loot-core/src/client/data-hooks/transactions.ts:258-258
Timestamp: 2025-01-16T14:28:00.133Z
Learning: Variables defined within React hooks like `useMemo` or `useEffect` are not dependencies of other hooks. Only external variables and values from the component scope need to be included in the dependency arrays.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-10-24T21:29:26.090Z
Learnt from: csenel
Repo: actualbudget/actual PR: 5991
File: packages/desktop-client/src/components/mobile/budget/BudgetCell.tsx:82-89
Timestamp: 2025-10-24T21:29:26.090Z
Learning: Notification messages in BudgetCell.tsx will be translated in a separate PR to handle all translations together, as there are multiple messages to go through.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2024-10-08T15:46:15.739Z
Learnt from: qedi-r
Repo: actualbudget/actual PR: 3527
File: packages/desktop-client/src/components/accounts/Header.jsx:0-0
Timestamp: 2024-10-08T15:46:15.739Z
Learning: In the Actual Budget project, importing `t` directly from 'i18next' is best avoided, and we should almost always prefer using the useTranslation hook if possible.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-11-04T00:47:00.968Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 6065
File: packages/desktop-client/src/components/transactions/TransactionList.tsx:197-205
Timestamp: 2025-11-04T00:47:00.968Z
Learning: In packages/desktop-client/src/components/transactions/TransactionList.tsx and similar schedule creation code, when using schedule/create with conditions and then updating the rule's actions, it's correct to filter rule.actions to keep only 'link-schedule' and append custom actions. Transactions created by schedules are defined by a mix of conditions (which create the base transaction with date, amount, payee, account) and actions (which apply additional modifications like category, notes, splits). The filtering pattern replaces any auto-generated actions with the desired custom actions.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2024-10-16T03:51:04.683Z
Learnt from: tlesicka
Repo: actualbudget/actual PR: 3593
File: packages/desktop-client/src/components/sidebar/BudgetName.tsx:114-136
Timestamp: 2024-10-16T03:51:04.683Z
Learning: In 'packages/desktop-client/src/components/sidebar/BudgetName.tsx', empty budget names are handled elsewhere, so additional error handling within the 'EditableBudgetName' component is unnecessary.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/e2e/sankey.test.ts
📚 Learning: 2025-02-19T20:40:35.656Z
Learnt from: lelemm
Repo: actualbudget/actual PR: 4408
File: packages/desktop-client/src/components/mobile/accounts/Accounts.tsx:80-80
Timestamp: 2025-02-19T20:40:35.656Z
Learning: In the Accounts list view, the section headers "On budget" and "Off budget" should be translatable strings as they are UI elements, not user data.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2024-10-25T04:49:31.861Z
Learnt from: tlesicka
Repo: actualbudget/actual PR: 3689
File: packages/desktop-client/src/components/modals/manager/DuplicateFileModal.tsx:144-156
Timestamp: 2024-10-25T04:49:31.861Z
Learning: In `packages/desktop-client/src/components/modals/manager/DuplicateFileModal.tsx`, styles for buttons may differ for each button in the future, so avoid suggesting extraction of common styles in this file.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-10-22T16:22:17.482Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 5978
File: packages/desktop-client/src/components/mobile/banksync/BankSyncAccountsListItem.tsx:58-67
Timestamp: 2025-10-22T16:22:17.482Z
Learning: In react-i18next, the Trans component supports interpolation using the syntax `<Trans>Text {{ variable: value }}</Trans>` where the double curly braces are special syntax recognized by react-i18next for variable substitution. This is valid and should not be flagged as incorrect.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
📚 Learning: 2024-11-12T19:52:52.889Z
Learnt from: lelemm
Repo: actualbudget/actual PR: 3792
File: packages/desktop-client/src/components/reports/reports/Summary.tsx:134-161
Timestamp: 2024-11-12T19:52:52.889Z
Learning: In `packages/desktop-client/src/components/reports/reports/Summary.tsx`, API calls like `get-earliest-transaction` are used without explicit error handling to maintain consistency with other components.

Applied to files:

  • packages/desktop-client/src/components/reports/reports/Sankey.tsx
  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
  • packages/desktop-client/e2e/sankey.test.ts
📚 Learning: 2024-10-10T02:29:05.655Z
Learnt from: tlesicka
Repo: actualbudget/actual PR: 3593
File: packages/desktop-client/src/components/sidebar/Sidebar.tsx:112-116
Timestamp: 2024-10-10T02:29:05.655Z
Learning: In `packages/desktop-client/src/components/sidebar/BudgetName.tsx`, the `BudgetName` component consists of three parts: `BudgetName`, `EditBudgetName`, and the Menu. Keeping `EditBudgetName` as a separate component helps maintain cleaner code by separating concerns.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-10-24T16:51:43.421Z
Learnt from: StephenBrown2
Repo: actualbudget/actual PR: 5908
File: packages/desktop-client/src/components/settings/Currency.tsx:38-38
Timestamp: 2025-10-24T16:51:43.421Z
Learning: In the actualbudget/actual repository, JPY (Japanese Yen) currency support can remain enabled in packages/desktop-client/src/components/settings/Currency.tsx and packages/loot-core/src/shared/currencies.ts even though not all features fully support zero-decimal currencies yet, because the currency feature is experimental. The team decided to keep JPY active to avoid repeatedly removing and re-adding it during testing.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-08-16T07:09:15.691Z
Learnt from: sjones512
Repo: actualbudget/actual PR: 5554
File: packages/desktop-client/src/components/reports/spreadsheets/crossover-spreadsheet.ts:375-387
Timestamp: 2025-08-16T07:09:15.691Z
Learning: When handling financial data consistency issues in the desktop client, prefer keeping the data layer (spreadsheets) in raw integer cents and use the useFormat hook for all presentation formatting, rather than converting to display amounts in the data layer.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-06-16T17:45:40.807Z
Learnt from: misu-dev
Repo: actualbudget/actual PR: 5167
File: packages/desktop-client/src/components/spreadsheet/useFormat.ts:64-72
Timestamp: 2025-06-16T17:45:40.807Z
Learning: The user misu-dev prefers strict type checking for financial format types in useFormat.ts as a long-term goal, but acknowledges that creating follow-up issues for cleanup should wait until after the current PR is merged, not during the development phase.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-09-28T08:34:21.188Z
Learnt from: misu-dev
Repo: actualbudget/actual PR: 5639
File: packages/desktop-client/src/components/util/GenericInput.jsx:68-73
Timestamp: 2025-09-28T08:34:21.188Z
Learning: In packages/desktop-client/src/components/util/GenericInput.jsx, for amount filtering with inflow/outflow options, the sign prop should always be '+' (for both inflow and outflow) because the UI layer keeps all amounts positive, while the server-side transaction rules engine handles the actual sign conversion and negation logic when querying the database.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-06-16T17:41:34.452Z
Learnt from: misu-dev
Repo: actualbudget/actual PR: 5167
File: packages/desktop-client/src/components/spreadsheet/useFormat.ts:64-72
Timestamp: 2025-06-16T17:41:34.452Z
Learning: The format function in useFormat.ts is widely used across the application and currently needs to accept both string and number inputs for financial format types. While strict type checking is preferred long-term, string parsing is maintained as a pragmatic compromise during the currency feature development phase.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-06-14T21:20:46.938Z
Learnt from: misu-dev
Repo: actualbudget/actual PR: 5167
File: packages/desktop-client/src/components/spreadsheet/useFormat.ts:161-166
Timestamp: 2025-06-14T21:20:46.938Z
Learning: In the useFormat hook's formatDisplay function, there's an intentional separation between displayDecimalPlaces (used for Intl.NumberFormat display formatting) and activeCurrency.decimalPlaces (used for integerToCurrency conversion logic). These should not be mixed as displayDecimalPlaces controls how many decimals to show while activeCurrency.decimalPlaces controls the mathematical conversion from integer amounts to decimal amounts.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-01-28T23:24:32.957Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4253
File: packages/desktop-client/src/components/banksync/AccountRow.tsx:0-0
Timestamp: 2025-01-28T23:24:32.957Z
Learning: In the Actual codebase, timestamp formatting should use date-fns' `format` function with explicit format strings (e.g., 'HH:mm:ss' for time) instead of JavaScript's built-in `toLocaleTimeString()` for consistency.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-10-05T10:58:55.008Z
Learnt from: MatissJanis
Repo: actualbudget/actual PR: 3570
File: packages/desktop-client/src/components/modals/ImportTransactionsModal/utils.ts:16-24
Timestamp: 2024-10-05T10:58:55.008Z
Learning: In `packages/desktop-client/src/components/modals/ImportTransactionsModal/utils.ts`, the `parseDate` function's `str` parameter should maintain its current type `string | number | null | Array<unknown> | object`, as narrowing it to `string | null` is not suitable.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-01-21T11:39:38.461Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4154
File: packages/desktop-client/src/components/spreadsheet/CellValue.tsx:47-47
Timestamp: 2025-01-21T11:39:38.461Z
Learning: In the CellValue component of packages/desktop-client/src/components/spreadsheet/CellValue.tsx, the children prop needs an additional length check (children && children.length > 0) because the Trans component can pass an empty array at runtime despite the type definition expecting a function.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-10-12T23:57:22.683Z
Learnt from: jfdoming
Repo: actualbudget/actual PR: 3648
File: packages/desktop-client/src/components/HelpMenu.tsx:25-47
Timestamp: 2024-10-12T23:57:22.683Z
Learning: In `packages/desktop-client/src/components/HelpMenu.tsx`, when a `<Button>` component includes text content as a child, an explicit `aria-label` may not be required for accessibility, as the text content provides the accessible name.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2025-01-17T12:11:23.669Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 3840
File: packages/loot-core/src/server/budget/template-notes.ts:12-12
Timestamp: 2025-01-17T12:11:23.669Z
Learning: In server-side code or non-React contexts where React hooks cannot be used, prefer using `import { t } from 'i18next'` and directly using `t(string)` for translations, instead of using react-i18next hooks or other approaches.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-11-26T13:07:02.794Z
Learnt from: lelemm
Repo: actualbudget/actual PR: 3891
File: packages/loot-core/src/shared/rules.ts:209-212
Timestamp: 2024-11-26T13:07:02.794Z
Learning: The file `packages/loot-core/src/shared/rules.ts` is not yet translated, so internationalization using the `t()` function is not required here.

Applied to files:

  • packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
📚 Learning: 2024-10-08T15:46:15.739Z
Learnt from: tlesicka
Repo: actualbudget/actual PR: 3457
File: packages/desktop-client/e2e/page-models/navigation.js:50-50
Timestamp: 2024-10-08T15:46:15.739Z
Learning: In the e2e tests, the budget name is 'Test Budget', so when navigating to the 'Settings' page, references to the 'More' menu are now replaced with 'Test Budget' to reflect the new placement of the 'Settings' option under the budget name dropdown.

Applied to files:

  • packages/desktop-client/e2e/sankey.test.ts
📚 Learning: 2024-10-08T15:46:15.739Z
Learnt from: UnderKoen
Repo: actualbudget/actual PR: 3499
File: packages/desktop-client/e2e/accounts.test.js:134-136
Timestamp: 2024-10-08T15:46:15.739Z
Learning: In the 'accounts.test.js' test suite, when testing CSV import functionality, the test results are verified visually through screenshots rather than with explicit assertions.

Applied to files:

  • packages/desktop-client/e2e/sankey.test.ts
📚 Learning: 2025-01-22T15:51:34.900Z
Learnt from: joel-jeremy
Repo: actualbudget/actual PR: 4217
File: packages/desktop-client/e2e/fixtures.ts:26-28
Timestamp: 2025-01-22T15:51:34.900Z
Learning: In Playwright, `locator.page` is a function that returns the page that the locator belongs to, not a property. The correct way to check if a locator has a page is using `typeof locator.page === 'function'`.

Applied to files:

  • packages/desktop-client/e2e/page-models/sankey-page.ts
📚 Learning: 2025-01-17T12:00:27.629Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4170
File: packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx:570-581
Timestamp: 2025-01-17T12:00:27.629Z
Learning: The transaction amount conversion for income categories in TransactionEdit.jsx is intended as a quality-of-life feature to help users who forget to set the correct direction, not as a preventative measure. Users should still be able to manually enter negative amounts even for income categories.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2024-10-09T20:17:46.493Z
Learnt from: UnderKoen
Repo: actualbudget/actual PR: 3619
File: packages/loot-core/src/server/accounts/transaction-rules.ts:551-0
Timestamp: 2024-10-09T20:17:46.493Z
Learning: When finalizing transactions that involve inserting or retrieving payees, avoid using `Promise.all` as it may result in duplicate payees due to concurrent operations. Sequential processing ensures payees are correctly handled without duplication.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2024-10-09T20:30:39.127Z
Learnt from: UnderKoen
Repo: actualbudget/actual PR: 3619
File: packages/loot-core/src/server/accounts/transaction-rules.ts:795-801
Timestamp: 2024-10-09T20:30:39.127Z
Learning: In the `finalizeTransactionForRules` function within `packages/loot-core/src/server/accounts/transaction-rules.ts`, potential race conditions when inserting payees are handled in the method that calls this function, so additional safeguards within `finalizeTransactionForRules` are unnecessary.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-01-14T06:17:55.345Z
Learnt from: jfdoming
Repo: actualbudget/actual PR: 4146
File: packages/desktop-client/src/components/reports/spreadsheets/summary-spreadsheet.ts:30-30
Timestamp: 2025-01-14T06:17:55.345Z
Learning: The `make-filters-from-conditions` function in the Actual Budget codebase returns a complex type that is not explicitly defined. While improving its type definition would be beneficial, it should be handled in a dedicated project due to its complexity.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-01-12T20:22:02.704Z
Learnt from: matt-fidd
Repo: actualbudget/actual PR: 4141
File: packages/desktop-client/src/components/reports/spreadsheets/sortData.ts:15-26
Timestamp: 2025-01-12T20:22:02.704Z
Learning: In the custom reports feature of Actual, the `balanceTypeOp` and `sortByOp` parameters in the `sortData` function are always set and should not be marked as optional.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
📚 Learning: 2025-08-16T16:42:08.306Z
Learnt from: sjones512
Repo: actualbudget/actual PR: 5554
File: packages/desktop-client/src/components/reports/spreadsheets/crossover-spreadsheet.ts:7-8
Timestamp: 2025-08-16T16:42:08.306Z
Learning: In the Actual Budget codebase, it's acceptable and consistent to import useSpreadsheet as a type-only import and then use ReturnType<typeof useSpreadsheet> in type annotations. This pattern is used consistently across spreadsheet files like custom-spreadsheet.ts and crossover-spreadsheet.ts.

Applied to files:

  • packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
🧬 Code graph analysis (8)
packages/desktop-client/src/components/reports/ReportRouter.tsx (1)
packages/desktop-client/src/components/reports/reports/Sankey.tsx (1)
  • Sankey (48-60)
packages/desktop-client/src/components/reports/Overview.tsx (2)
packages/desktop-client/src/hooks/useFeatureFlag.ts (1)
  • useFeatureFlag (17-23)
packages/desktop-client/src/components/reports/reports/SankeyCard.tsx (1)
  • SankeyCard (25-120)
packages/desktop-client/src/components/reports/reports/SankeyCard.tsx (9)
packages/loot-core/src/types/models/dashboard.ts (1)
  • SankeyWidget (174-183)
packages/desktop-client/src/hooks/useCategories.ts (1)
  • useCategories (8-22)
packages/desktop-client/src/components/reports/reportRanges.ts (1)
  • calculateTimeRange (177-238)
packages/desktop-client/src/components/reports/ReportCard.tsx (1)
  • ReportCard (34-119)
packages/component-library/src/View.tsx (1)
  • View (14-33)
packages/desktop-client/src/components/reports/ReportCardName.tsx (1)
  • ReportCardName (17-55)
packages/desktop-client/src/components/reports/DateRange.tsx (1)
  • DateRange (29-89)
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (1)
  • SankeyGraph (340-405)
packages/desktop-client/src/components/reports/LoadingIndicator.tsx (1)
  • LoadingIndicator (13-32)
packages/desktop-client/src/components/reports/reports/Sankey.tsx (10)
packages/desktop-client/src/hooks/useWidget.ts (1)
  • useWidget (8-21)
packages/loot-core/src/types/models/dashboard.ts (1)
  • SankeyWidget (174-183)
packages/desktop-client/src/components/reports/LoadingIndicator.tsx (1)
  • LoadingIndicator (13-32)
packages/desktop-client/src/hooks/useLocale.ts (1)
  • useLocale (7-14)
packages/desktop-client/src/hooks/useRuleConditionFilters.ts (1)
  • useRuleConditionFilters (5-75)
packages/desktop-client/src/hooks/useCategories.ts (1)
  • useCategories (8-22)
packages/desktop-client/src/components/Page.tsx (3)
  • Page (115-155)
  • MobilePageHeader (47-105)
  • PageHeader (16-38)
packages/desktop-client/src/components/filters/FiltersMenu.tsx (1)
  • FilterButton (327-528)
packages/desktop-client/src/components/filters/AppliedFilters.tsx (1)
  • AppliedFilters (21-55)
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (1)
  • SankeyGraph (340-405)
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx (5)
packages/desktop-client/src/hooks/useFormat.ts (1)
  • useFormat (109-282)
packages/component-library/src/theme.ts (1)
  • theme (1-204)
packages/component-library/src/styles.ts (1)
  • CSSProperties (7-7)
packages/desktop-client/src/hooks/useSyncedPref.ts (1)
  • useSyncedPref (12-29)
packages/desktop-client/src/components/reports/Container.tsx (1)
  • Container (14-31)
packages/loot-core/src/types/models/dashboard.ts (1)
packages/loot-core/src/types/models/rule.ts (1)
  • RuleConditionEntity (56-120)
packages/desktop-client/e2e/sankey.test.ts (4)
packages/desktop-client/e2e/page-models/navigation.ts (1)
  • Navigation (17-119)
packages/desktop-client/e2e/page-models/reports-page.ts (1)
  • ReportsPage (5-42)
packages/desktop-client/e2e/page-models/sankey-page.ts (1)
  • SankeyPage (3-59)
packages/desktop-client/e2e/page-models/configuration-page.ts (1)
  • ConfigurationPage (6-72)
packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts (3)
packages/loot-core/src/types/models/rule.ts (1)
  • RuleConditionEntity (56-120)
packages/loot-core/src/types/models/category-group.ts (1)
  • CategoryGroupEntity (3-11)
packages/desktop-client/src/hooks/useSpreadsheet.tsx (1)
  • useSpreadsheet (19-25)
🪛 GitHub Check: typecheck
packages/desktop-client/e2e/sankey.test.ts

[failure] 82-82:
Property 'goToSankeyPage' does not exist on type 'ReportsPage'.


[failure] 60-60:
Property 'goToSankeyPage' does not exist on type 'ReportsPage'.


[failure] 51-51:
Property 'goToSankeyPage' does not exist on type 'ReportsPage'.


[failure] 42-42:
Property 'goToSankeyPage' does not exist on type 'ReportsPage'.


[failure] 33-33:
Property 'goToSankeyPage' does not exist on type 'ReportsPage'.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: compare
  • GitHub Check: web
  • GitHub Check: Functional Desktop App
  • GitHub Check: Wait for Netlify build to finish
  • GitHub Check: Analyze
  • GitHub Check: build (ubuntu-22.04)
  • GitHub Check: build (macos-latest)
  • GitHub Check: build (windows-latest)
  • GitHub Check: test
  • GitHub Check: Generate VRT Updates
  • GitHub Check: validate-cli

@github-actions
Copy link
Contributor

github-actions bot commented Nov 17, 2025

Bundle Stats

desktop-client

Total

Files count Total bundle size % Changed
26 13.96 MB → 14.04 MB (+76.96 kB) +0.54%
Changeset
File Δ Size
node_modules/recharts/es6/chart/Sankey.js 🆕 +23.8 kB 0 B → 23.8 kB
src/components/reports/reports/Sankey.tsx 🆕 +15.23 kB 0 B → 15.23 kB
src/components/reports/graphs/SankeyGraph.tsx 🆕 +15.08 kB 0 B → 15.08 kB
src/components/reports/spreadsheets/sankey-spreadsheet.ts 🆕 +12.76 kB 0 B → 12.76 kB
src/components/reports/reports/SankeyCard.tsx 🆕 +5.3 kB 0 B → 5.3 kB
node_modules/es-toolkit/dist/compat/math/sumBy.js 🆕 +931 B 0 B → 931 B
node_modules/es-toolkit/dist/array/maxBy.js 🆕 +722 B 0 B → 722 B
node_modules/es-toolkit/dist/compat/math/maxBy.js 🆕 +641 B 0 B → 641 B
node_modules/es-toolkit/compat/maxBy.js 🆕 +192 B 0 B → 192 B
node_modules/es-toolkit/compat/sumBy.js 🆕 +192 B 0 B → 192 B
node_modules/es-toolkit/compat/maxBy.js?commonjs-es-import 🆕 +114 B 0 B → 114 B
node_modules/es-toolkit/compat/sumBy.js?commonjs-es-import 🆕 +114 B 0 B → 114 B
node_modules/es-toolkit/dist/compat/math/maxBy.js?commonjs-exports 🆕 +17 B 0 B → 17 B
node_modules/es-toolkit/dist/compat/math/sumBy.js?commonjs-exports 🆕 +17 B 0 B → 17 B
node_modules/es-toolkit/dist/array/maxBy.js?commonjs-exports 🆕 +17 B 0 B → 17 B
node_modules/recharts/es6/context/chartDataContext.js 📈 +301 B (+56.47%) 533 B → 834 B
src/components/reports/ReportRouter.tsx 📈 +538 B (+11.00%) 4.78 kB → 5.3 kB
src/hooks/useFeatureFlag.ts 📈 +23 B (+5.50%) 418 B → 441 B
node_modules/recharts/es6/context/chartLayoutContext.js 📈 +210 B (+3.49%) 5.88 kB → 6.08 kB
src/components/reports/Overview.tsx 📈 +560 B (+2.85%) 19.17 kB → 19.72 kB
src/components/settings/Experimental.tsx 📈 +241 B (+2.50%) 9.42 kB → 9.66 kB
node_modules/recharts/es6/chart/PolarChart.js 📈 +20 B (+0.51%) 3.8 kB → 3.82 kB
node_modules/recharts/es6/cartesian/Line.js 📈 +40 B (+0.19%) 20.84 kB → 20.88 kB
node_modules/recharts/es6/cartesian/XAxis.js 📈 +4 B (+0.07%) 5.71 kB → 5.72 kB
src/components/reports/spreadsheets/net-worth-spreadsheet.ts 📈 +2 B (+0.04%) 5.32 kB → 5.32 kB
src/components/reports/reports/NetWorthCard.tsx 📈 +2 B (+0.02%) 8.01 kB → 8.01 kB
src/components/reports/reports/NetWorth.tsx 📈 +2 B (+0.02%) 10.68 kB → 10.68 kB
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger

Asset File Size % Changed
static/js/ReportRouter.js 1.09 MB → 1.16 MB (+76.21 kB) +6.85%
static/js/index.js 9.09 MB → 9.09 MB (+775 B) +0.01%

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
static/js/indexeddb-main-thread-worker-e59fee74.js 12.94 kB 0%
static/js/workbox-window.prod.es5.js 5.64 kB 0%
static/js/da.js 107.68 kB 0%
static/js/de.js 168.92 kB 0%
static/js/en-GB.js 6.84 kB 0%
static/js/en.js 155.32 kB 0%
static/js/es.js 87.6 kB 0%
static/js/fr.js 176.65 kB 0%
static/js/it.js 168.68 kB 0%
static/js/nl.js 99.88 kB 0%
static/js/pl.js 89.3 kB 0%
static/js/pt-BR.js 148.77 kB 0%
static/js/ru.js 108.47 kB 0%
static/js/th.js 183.6 kB 0%
static/js/uk.js 218.27 kB 0%
static/js/resize-observer.js 18.37 kB 0%
static/js/BackgroundImage.js 120.48 kB 0%
static/js/narrow.js 638.64 kB 0%
static/js/TransactionList.js 101.33 kB 0%
static/js/wide.js 158.92 kB 0%
static/js/AppliedFilters.js 9.62 kB 0%
static/js/usePayeeRuleCounts.js 11.79 kB 0%
static/js/useTransactionBatchActions.js 12.98 kB 0%
static/js/FormulaEditor.js 1.04 MB 0%

loot-core

Total

Files count Total bundle size % Changed
1 5.79 MB 0%
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger
No assets were bigger

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
kcab.worker.CxTWk3qm.js 5.79 MB 0%

api

Total

Files count Total bundle size % Changed
1 4.33 MB 0%
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger
No assets were bigger

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
bundle.api.js 4.33 MB 0%

Auto-generated by VRT workflow

PR: actualbudget#6068
@github-actions
Copy link
Contributor

✅ VRT screenshots have been automatically updated.

@youngcw
Copy link
Member

youngcw commented Nov 19, 2025

The dashboard card doesn't render right. It usually is empty.

It would be nice to have the ability to select a range of months.

@github-actions
Copy link
Contributor

✅ VRT screenshots have been automatically updated.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 6, 2026

VRT tests ❌ failed. View the test report.

To update the VRT screenshots, comment /update-vrt on this PR. The VRT update operation takes about 50 minutes.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Report - Sankey diagram from group categories and categories

5 participants