-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Implement Sankey graph report #6068
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Implement Sankey graph report #6068
Conversation
✅ Deploy Preview for actualbudget ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Bundle Stats — desktop-clientHey 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
Changeset
View detailed bundle breakdownAdded No assets were added Removed No assets were removed Bigger
Smaller No assets were smaller Unchanged
|
Bundle Stats — loot-coreHey 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
Changeset No files were changed View detailed bundle breakdownAdded No assets were added Removed No assets were removed Bigger No assets were bigger Smaller No assets were smaller Unchanged
|
Auto-generated by VRT workflow PR: actualbudget#6068
|
✅ VRT screenshots have been automatically updated. |
…/actual into sankey-graph-report
Auto-generated by VRT workflow PR: actualbudget#6068
|
✅ VRT screenshots have been automatically updated. |
|
Hi @YesWeCandrew. Thank you for your comment and glad you like the feature. To respond to your suggestions:
Feel free to throw any more idea or critiques my way! Totally open to it and appreciate your help and thoughts here :)
|
…/actual into sankey-graph-report
|
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+ |
|
@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! |
WalkthroughAdds 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:
Pre-merge checks and finishing touches✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used🧠 Learnings (1)📚 Learning: 2025-01-18T20:08:55.203ZApplied to files:
⏰ 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)
🔇 Additional comments (1)
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.
Example:
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. Comment |
There was a problem hiding this 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 modelHard-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
⛔ 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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-help-menu-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-help-menu-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-help-menu-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/settings.mobile.test.ts-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/settings.mobile.test.ts-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-5-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/settings.mobile.test.ts-snapshots/Mobile-Settings-checks-that-settings-page-can-be-opened-6-chromium-linux.pngis excluded by!**/*.pngupcoming-release-notes/6068.mdis 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}: Prefertypeoverinterfacein TypeScript
Avoidenum; use objects or maps instead
Avoidanyandunknownunless absolutely necessary
Avoid type assertions (as, non-null!); prefersatisfiesfor narrowing
Use inline type imports:import { type X } from '...'
Favor functional/declarative patterns; avoid classes
Use thefunctionkeyword 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.tspackages/desktop-client/e2e/page-models/reports-page.tspackages/loot-core/src/types/prefs.tspackages/desktop-client/src/components/reports/reports/Sankey.tsxpackages/desktop-client/src/components/reports/Overview.tsxpackages/desktop-client/src/hooks/useFeatureFlag.tspackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/desktop-client/src/components/settings/Experimental.tsxpackages/desktop-client/src/components/reports/reports/SankeyCard.tsxpackages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.tspackages/desktop-client/e2e/page-models/sankey-page.tspackages/desktop-client/src/components/reports/ReportRouter.tsxpackages/loot-core/src/types/models/dashboard.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Do not useconsole.*; use the logger instead
Importuuidwith destructuring:import { v4 as uuidv4 } from 'uuid'
Files:
packages/desktop-client/e2e/sankey.test.tspackages/desktop-client/e2e/page-models/reports-page.tspackages/loot-core/src/types/prefs.tspackages/desktop-client/src/components/reports/reports/Sankey.tsxpackages/desktop-client/src/components/reports/Overview.tsxpackages/desktop-client/src/hooks/useFeatureFlag.tspackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/desktop-client/src/components/settings/Experimental.tsxpackages/desktop-client/src/components/reports/reports/SankeyCard.tsxpackages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.tspackages/desktop-client/e2e/page-models/sankey-page.tspackages/desktop-client/src/components/reports/ReportRouter.tsxpackages/loot-core/src/types/models/dashboard.ts
**/*.{test,spec}.{js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Name unit tests with
.testor.specextensions (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.tspackages/desktop-client/e2e/page-models/reports-page.tspackages/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/*fromloot-core
Files:
packages/loot-core/src/types/prefs.tspackages/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 overt()when possible
Do not useReact.*namespace imports; use named imports
Use theme tokens; do not import colors directly
Files:
packages/desktop-client/src/components/reports/reports/Sankey.tsxpackages/desktop-client/src/components/reports/Overview.tsxpackages/desktop-client/src/hooks/useFeatureFlag.tspackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/desktop-client/src/components/settings/Experimental.tsxpackages/desktop-client/src/components/reports/reports/SankeyCard.tsxpackages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.tspackages/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 useReact.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.tsxpackages/desktop-client/src/components/reports/Overview.tsxpackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/desktop-client/src/components/settings/Experimental.tsxpackages/desktop-client/src/components/reports/reports/SankeyCard.tsxpackages/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.tsxpackages/desktop-client/src/components/reports/Overview.tsxpackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/desktop-client/src/components/settings/Experimental.tsxpackages/desktop-client/src/components/reports/reports/SankeyCard.tsxpackages/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 fromsrc/hooksinstead of react-router directly
UseuseDispatch,useSelector,useStorefromsrc/redux(not react-redux)
Use absolute imports in desktop-client
Files:
packages/desktop-client/src/components/reports/reports/Sankey.tsxpackages/desktop-client/src/components/reports/Overview.tsxpackages/desktop-client/src/hooks/useFeatureFlag.tspackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/desktop-client/src/components/settings/Experimental.tsxpackages/desktop-client/src/components/reports/reports/SankeyCard.tsxpackages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.tspackages/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.tspackages/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.tspackages/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.tsxpackages/desktop-client/src/components/reports/Overview.tsxpackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/desktop-client/src/components/reports/reports/SankeyCard.tsxpackages/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.tsxpackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/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.tsxpackages/desktop-client/src/components/reports/Overview.tsxpackages/desktop-client/src/components/reports/reports/SankeyCard.tsxpackages/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.tsxpackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/desktop-client/src/components/reports/reports/SankeyCard.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tspackages/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
sankeyReportfeature 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 --writeon 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 JSXLearnt 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 groupsLearnt 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>` tagsLearnt 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 importspackages/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
crossoverReportfeature flag (lines 25-30), but the new Sankey routes are not gated behind thesankeyReportflag. 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 viapage.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
sankeyReportflag defaults totruewhile all other feature flags default tofalse. 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: Removeconsole.errorProject 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 insteadLearnt 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 nullWhile
useReportis still fetching, thisreturn nullblanks the entire page (no header or spinner). Render the existingLoadingIndicator(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.
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
Outdated
Show resolved
Hide resolved
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
Outdated
Show resolved
Hide resolved
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsx
Outdated
Show resolved
Hide resolved
packages/desktop-client/src/components/reports/reports/Sankey.tsx
Outdated
Show resolved
Hide resolved
packages/desktop-client/src/components/reports/reports/SankeyCard.tsx
Outdated
Show resolved
Hide resolved
packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
Outdated
Show resolved
Hide resolved
packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
Show resolved
Hide resolved
packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
Show resolved
Hide resolved
There was a problem hiding this 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
RuleConditionEntityfields to filter objects, butopvalues 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, importingtdirectly fromi18nextshould 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
📒 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}: Prefertypeoverinterfacein TypeScript
Avoidenum; use objects or maps instead
Avoidanyandunknownunless absolutely necessary
Avoid type assertions (as, non-null!); prefersatisfiesfor narrowing
Use inline type imports:import { type X } from '...'
Favor functional/declarative patterns; avoid classes
Use thefunctionkeyword 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.tsxpackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Do not useconsole.*; use the logger instead
Importuuidwith destructuring:import { v4 as uuidv4 } from 'uuid'
Files:
packages/desktop-client/src/components/reports/reports/Sankey.tsxpackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/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 overt()when possible
Do not useReact.*namespace imports; use named imports
Use theme tokens; do not import colors directly
Files:
packages/desktop-client/src/components/reports/reports/Sankey.tsxpackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/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 useReact.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.tsxpackages/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.tsxpackages/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 fromsrc/hooksinstead of react-router directly
UseuseDispatch,useSelector,useStorefromsrc/redux(not react-redux)
Use absolute imports in desktop-client
Files:
packages/desktop-client/src/components/reports/reports/Sankey.tsxpackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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:
- Import the logger utility (check other report spreadsheet files for the pattern)
- Replace the console.error call
- 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 insteadLearnt 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`.
|
@andrewhumble Thanks for making those changes, latest pushes look great. Filtering Bug 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”. Income in Spent tab |
|
Oh my! This is great! Next iteration... color! |
❌ Deploy Preview for actual-docs-new failed.
|
|
@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 —
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 |
There was a problem hiding this 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'int(), 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 unusedcurrencyCodeparameter.The
currencyCodeprop is passed toSankeyNodeat line 371 but never referenced in the component body (lines 150-302). Currency formatting is handled by theuseFormathook 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
📒 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}: Prefertypeoverinterfacein TypeScript
Avoidenum; use objects or maps instead
Avoidanyandunknownunless absolutely necessary
Avoid type assertions (as, non-null!); prefersatisfiesfor narrowing
Use inline type imports:import { type X } from '...'
Favor functional/declarative patterns; avoid classes
Use thefunctionkeyword 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.tsxpackages/desktop-client/src/components/reports/reports/Sankey.tsxpackages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Do not useconsole.*; use the logger instead
Importuuidwith destructuring:import { v4 as uuidv4 } from 'uuid'
Files:
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/desktop-client/src/components/reports/reports/Sankey.tsxpackages/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 overt()when possible
Do not useReact.*namespace imports; use named imports
Use theme tokens; do not import colors directly
Files:
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/desktop-client/src/components/reports/reports/Sankey.tsxpackages/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 useReact.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.tsxpackages/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.tsxpackages/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 fromsrc/hooksinstead of react-router directly
UseuseDispatch,useSelector,useStorefromsrc/redux(not react-redux)
Use absolute imports in desktop-client
Files:
packages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/desktop-client/src/components/reports/reports/Sankey.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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: Replaceconsole.errorwith 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 insteadLearnt 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.
✅ Deploy Preview for actualbudget-website canceled.
|
There was a problem hiding this 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
concatwith spread operator can be replaced withflatMapfor 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
transformToSankeyDatafunction parameters and return value lack explicit types, reducing type safety and developer ergonomics. Consider adding type annotations forcategoryData,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
📒 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
isNegativeflag for differential rendering.
packages/desktop-client/src/components/reports/spreadsheets/sankey-spreadsheet.ts
Show resolved
Hide resolved
There was a problem hiding this 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
⛔ 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.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-5-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-6-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-7-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-8-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-9-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-import-csv-file-twice-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-import-csv-file-twice-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-import-csv-file-twice-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-imports-transactions-from-a-CSV-file-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-imports-transactions-from-a-CSV-file-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-imports-transactions-from-a-CSV-file-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-5-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-6-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-creates-a-new-account-and-views-the-initial-balance-transaction-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-creates-a-new-account-and-views-the-initial-balance-transaction-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-creates-a-new-account-and-views-the-initial-balance-transaction-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-checks-the-page-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-checks-the-page-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-checks-the-page-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-page-handles-empty-state-gracefully-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-page-handles-empty-state-gracefully-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-page-handles-empty-state-gracefully-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-searches-for-accounts-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-searches-for-accounts-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-searches-for-accounts-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.test.ts-snapshots/Bank-Sync-checks-the-page-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.test.ts-snapshots/Bank-Sync-checks-the-page-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.test.ts-snapshots/Bank-Sync-checks-the-page-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-applies-budget-template-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-applies-budget-template-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-applies-budget-template-3-chromium-linux.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-copies-last-month-s-budget-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-copies-last-month-s-budget-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-copies-last-month-s-budget-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-12-month-average-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-12-month-average-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-12-month-average-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-3-month-average-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-3-month-average-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-3-month-average-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-6-month-average-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-6-month-average-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-6-month-average-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-applies-budget-template-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-applies-budget-template-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-applies-budget-template-3-chromium-linux.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/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.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-copies-last-month-s-budget-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-copies-last-month-s-budget-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-copies-last-month-s-budget-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-12-month-average-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-12-month-average-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-12-month-average-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-3-month-average-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-3-month-average-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-3-month-average-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-6-month-average-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-6-month-average-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-6-month-average-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-renders-the-summary-information-available-funds-overspent-budgeted-and-for-next-month-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-renders-the-summary-information-available-funds-overspent-budgeted-and-for-next-month-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-renders-the-summary-information-available-funds-overspent-budgeted-and-for-next-month-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-transfer-funds-to-another-category-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-transfer-funds-to-another-category-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-transfer-funds-to-another-category-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-search-works-correctly-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-search-works-correctly-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-search-works-correctly-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-help-menu-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-help-menu-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-help-menu-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-5-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-6-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-7-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-8-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-9-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-5-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-6-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-checks-the-page-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-checks-the-page-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-checks-the-page-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-payee-edit-page-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-payee-edit-page-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-payee-edit-page-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-rule-creation-form-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-rule-creation-form-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-rule-creation-form-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-filters-out-unrelated-payees-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-filters-out-unrelated-payees-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-filters-out-unrelated-payees-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-page-handles-empty-state-gracefully-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-page-handles-empty-state-gracefully-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-page-handles-empty-state-gracefully-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-5-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-6-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-5-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-6-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Area-Graph-and-checks-the-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Area-Graph-and-checks-the-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Area-Graph-and-checks-the-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Bar-Graph-and-checks-the-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Bar-Graph-and-checks-the-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Bar-Graph-and-checks-the-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Data-Table-and-checks-the-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Data-Table-and-checks-the-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Data-Table-and-checks-the-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Donut-Graph-and-checks-the-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Donut-Graph-and-checks-the-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Donut-Graph-and-checks-the-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Line-Graph-and-checks-the-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Line-Graph-and-checks-the-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Line-Graph-and-checks-the-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-labels-button-shows-the-labels-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-labels-button-shows-the-labels-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-labels-button-shows-the-labels-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-legend-button-shows-the-legend-side-bar-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-legend-button-shows-the-legend-side-bar-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-legend-button-shows-the-legend-side-bar-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-summary-button-shows-the-summary-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-summary-button-shows-the-summary-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-summary-button-shows-the-summary-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-cash-flow-graph-and-checks-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-cash-flow-graph-and-checks-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-cash-flow-graph-and-checks-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-and-cash-flow-reports-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-and-cash-flow-reports-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-and-cash-flow-reports-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-graph-and-checks-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-graph-and-checks-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-graph-and-checks-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-checks-the-page-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-checks-the-page-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-checks-the-page-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-add-button-opens-rule-creation-form-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-add-button-opens-rule-creation-form-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-add-button-opens-rule-creation-form-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-on-a-rule-opens-edit-form-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-on-a-rule-opens-edit-form-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-on-a-rule-opens-edit-form-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-displays-the-rules-page-with-proper-header-and-search-bar-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-displays-the-rules-page-with-proper-header-and-search-bar-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-displays-the-rules-page-with-proper-header-and-search-bar-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-page-handles-empty-state-gracefully-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-page-handles-empty-state-gracefully-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-page-handles-empty-state-gracefully-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-search-functionality-filters-rules-correctly-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-search-functionality-filters-rules-correctly-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-search-functionality-filters-rules-correctly-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-checks-the-page-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-checks-the-page-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-checks-the-page-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-5-chromium-linux.pngis 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 useupstream/masteror another default branch). If uncertain, check your repository's configuration or contributing guidelines.
70615db to
c91ac19
Compare
There was a problem hiding this 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 flagRight now the Sankey routes are always registered, so anyone can deep-link to
/reports/sankeyeven when thesankeyReportflag 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 thetimport) 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
trueforcategoryMatchesConditionswhenever we hitcontains/doesNotContain/matchesmeans 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 memberThe 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
⛔ Files ignored due to path filters (1)
upcoming-release-notes/6068.mdis 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.tsxpackages/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.tsxpackages/desktop-client/src/components/reports/reports/SankeyCard.tsxpackages/desktop-client/src/components/reports/reports/Sankey.tsxpackages/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.tsxpackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/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.tspackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/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.tsxpackages/desktop-client/src/components/reports/reports/SankeyCard.tsxpackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/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.tsxpackages/desktop-client/src/components/reports/reports/SankeyCard.tsxpackages/desktop-client/src/components/reports/reports/Sankey.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/desktop-client/src/components/reports/reports/Sankey.tsxpackages/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.tsxpackages/desktop-client/src/components/reports/reports/Sankey.tsxpackages/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.tsxpackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/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.tsxpackages/desktop-client/src/components/reports/reports/Sankey.tsxpackages/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.tsxpackages/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.tsxpackages/desktop-client/src/components/reports/reports/Sankey.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/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.tsxpackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/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.tsxpackages/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.tsxpackages/desktop-client/src/components/reports/graphs/SankeyGraph.tsxpackages/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
Bundle Statsdesktop-clientTotal
Changeset
View detailed bundle breakdownAdded Removed Bigger
Smaller Unchanged
loot-coreTotal
View detailed bundle breakdownAdded Removed Bigger Smaller Unchanged
apiTotal
View detailed bundle breakdownAdded Removed Bigger Smaller Unchanged
|
Auto-generated by VRT workflow PR: actualbudget#6068
|
✅ VRT screenshots have been automatically updated. |
|
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. |
Auto-generated by VRT workflow PR: actualbudget#6068
|
✅ VRT screenshots have been automatically updated. |
|
VRT tests ❌ failed. View the test report. To update the VRT screenshots, comment |




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.
Spent — Displays actual spending by category from transactions.
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.,