Implement Sankey graph report#6068
Implement Sankey graph report#6068andrewhumble wants to merge 24 commits intoactualbudget:masterfrom
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.
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.
There was a problem hiding this comment.
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`.
|
✅ VRT screenshots have been automatically updated. |
|
VRT tests ❌ failed. View the test report. To update the VRT screenshots, comment |
Improvements to Sankey graph from PR actualbudget#6068: Visual enhancements: - Add varied expense colors (10-color palette avoiding green/blue) - Use green for underspent, red for overspent in difference mode - Color "For Next Month" as blue (budget) instead of expense - Fix leaf node text positioning (outside nodes instead of overlapping) - Add header dividers between control groups for clarity New options: - Add Grouped/Flat toggle for category display - Add sorting options: Category order, Value, Alphabetical - "For Next Month" always appears at end regardless of sort Bug fixes: - Fix difference mode to aggregate budgets across all months (was only using first month's budget for multi-month ranges) - Update help text to reflect green/red color scheme Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Auto-generated by VRT workflow PR: actualbudget#6068
Auto-generated by VRT workflow PR: actualbudget#6068
Auto-generated by VRT workflow PR: actualbudget#6068
Auto-generated by VRT workflow PR: actualbudget#6068
Improvements to Sankey graph from PR actualbudget#6068: Visual enhancements: - Add varied expense colors (10-color palette avoiding green/blue) - Use green for underspent, red for overspent in difference mode - Color "For Next Month" as blue (budget) instead of expense - Fix leaf node text positioning (outside nodes instead of overlapping) - Add header dividers between control groups for clarity New options: - Add Grouped/Flat toggle for category display - Add sorting options: Category order, Value, Alphabetical - "For Next Month" always appears at end regardless of sort Bug fixes: - Fix difference mode to aggregate budgets across all months (was only using first month's budget for multi-month ranges) - Update help text to reflect green/red color scheme Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
Looks really good, tested it out on my budget. +1 on adding more time range settings, I would like 1yr/6mo trailing settings as well as "Last year" and "Year to date", that way you could make a sankey for yearly spending for example I would also like the option to skip Category Groups in the sankey chart and just show Available Funds -> Category, for a smaller, more direct sankey chart |
For my opinion, I prefer the Spent view how it is currently with my finances - it's a great way to track cash flow and better than the default cashflow report, but I see the use case for a "budget" spend mode - if someone is relying entirely on savings for expenses for a period they will have no income transactions which would be weird with the spent view. For a "Budget spend" mode, you could just use the "Spent" column from the budget tab as the numbers in stead of the "Budgeted" amount. |
|
This is such a great feature, a dream come true that I had since the first time I saw a Sankey diagram from Finanzfluss many years ago. |
|
Any chance this could make it over the line? I think it would be an awesome feature! |
|
Im going to close this as it seems to have been abandoned by the creator. Anyone else is free to pick it up and finish it in a new PR. |
|
It's a shame to see Sankey charts almost make it into Actual once more. I managed to merge this fork with the most recent changes in actual yesterday and got it working locally. I have a few ideas for improvements and will look thoroughly through the comments in this thread, to see what further needs to be done. Then I will try to submit a new PR soon. |
|
Thank you so much Emil!!!
Emil Tveden Bjerglund ***@***.***> schrieb am Fr. 13. März
2026 um 07:30:
… *emiltb* left a comment (actualbudget/actual#6068)
<#6068 (comment)>
It's a shame to see Sankey charts almost make it into Actual once more. I
managed to merge this fork with the most recent changes in actual yesterday
and got it working locally. I have a few ideas for improvements and will
look thoroughly through the comments in this thread, to see what further
needs to be done. Then I will try to submit a new PR soon.
—
Reply to this email directly, view it on GitHub
<#6068 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AANCRBHNBGCMCLUF5FWSNMT4QOTHFAVCNFSM6AAAAACLDSMQ5CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DANJTGA3TINRWGY>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
* Implement Sankey graph report * Add release notes * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Remove local debug settings * [autofix.ci] apply automated fixes * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Improve graphs from comments * Fix lints * coderabit fixes * Fix filtering and UI enhancements * remove pngs * Fix typecheck * Another type issue * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Fix strict typing issues * Update report page Now better conforms with components from other reports, e.g. by reusing Header Makes it possible to display a period longer than one month. * Change view description order * Formatting and cleanup * Removed difference section, as it will be difficult to get a reliable view across months * Introduce the Timeframe param, similar to Spending report, to allow saving a Live sliding window. * Allow filtering just the last month * Fix linting errors * Remove all information about income * Remove debugging statement * Sort categories and subcategories by amount * Move compact mode to spreadsheet to fix Card view more easily * Update tests file * Add release notes * Rename release notes to match PR# * Fix autofix.ci issues * Update packages/desktop-client/e2e/sankey.test.ts Enable experimental feature fall all tests, pr. coderabbit recommendation Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Add sankey-card to isWidgetType * Gate Sankey routes to prevent direct URL bypass * Fix typo * Change node transformation to work by key instead of name, to remove risk of duplicate issues Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Prevent false-positive pass in month-change test. * Translate mode to a proper label * Fix message for empty data * Enabled LoadingIndicator until data is ready * Change card default mode * More robust filtering * Fixed issue with budgeted spreadsheet not using 'end' date * Allow copying SankeyCard to dashboard * Fix typing and linting issues * Remove e2e tests I cannot currently get them to pass, because I dont fully understand playwright and how they are supposed to work. I can see that they don't exist for other reports. We can add them later if required. * Remove unecessary sankey reference * Refactor spreadsheet * Remove dead code from SankeyGraph * Collect to Other if too many subcategories * Edit wrong comment * Linting and typechecking * Show remaining amount to budget * Hide description on narrow device * Add visual clue if 'To budget' is larger than 'Budgeted' and would extend below the edge of the graph * Add colors to the links * Fix report card showing subcategories instead of main categories * Add tooltip info to Other on SankeyCard * Create globalOther flag and implement greedy category reduction algorithm * Allow user to select between Global or Per category Other * Allow user to choose number of subcategories to show * Allow user to select how subcategories are sorted * Fix budget filtering * [autofix.ci] apply automated fixes * Condense sorting and Other-grouping to one option * Implement Sort as budget option * Dynamically adjust topN based on SankeyCard height * Remove old feature flags from previous PR --------- Co-authored-by: andrewhumble <43395285+andrewhumble@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: youngcw <calebyoung94@gmail.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Implement Sankey graph report * Add release notes * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Remove local debug settings * [autofix.ci] apply automated fixes * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Improve graphs from comments * Fix lints * coderabit fixes * Fix filtering and UI enhancements * remove pngs * Fix typecheck * Another type issue * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Fix strict typing issues * Update report page Now better conforms with components from other reports, e.g. by reusing Header Makes it possible to display a period longer than one month. * Change view description order * Formatting and cleanup * Removed difference section, as it will be difficult to get a reliable view across months * Introduce the Timeframe param, similar to Spending report, to allow saving a Live sliding window. * Allow filtering just the last month * Fix linting errors * Remove all information about income * Remove debugging statement * Sort categories and subcategories by amount * Move compact mode to spreadsheet to fix Card view more easily * Update tests file * Add release notes * Rename release notes to match PR# * Fix autofix.ci issues * Update packages/desktop-client/e2e/sankey.test.ts Enable experimental feature fall all tests, pr. coderabbit recommendation Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Add sankey-card to isWidgetType * Gate Sankey routes to prevent direct URL bypass * Fix typo * Change node transformation to work by key instead of name, to remove risk of duplicate issues Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Prevent false-positive pass in month-change test. * Translate mode to a proper label * Fix message for empty data * Enabled LoadingIndicator until data is ready * Change card default mode * More robust filtering * Fixed issue with budgeted spreadsheet not using 'end' date * Allow copying SankeyCard to dashboard * Fix typing and linting issues * Remove e2e tests I cannot currently get them to pass, because I dont fully understand playwright and how they are supposed to work. I can see that they don't exist for other reports. We can add them later if required. * Remove unecessary sankey reference * Refactor spreadsheet * Remove dead code from SankeyGraph * Collect to Other if too many subcategories * Edit wrong comment * Linting and typechecking * Show remaining amount to budget * Hide description on narrow device * Add visual clue if 'To budget' is larger than 'Budgeted' and would extend below the edge of the graph * Add colors to the links * Fix report card showing subcategories instead of main categories * Add tooltip info to Other on SankeyCard * Create globalOther flag and implement greedy category reduction algorithm * Allow user to select between Global or Per category Other * Allow user to choose number of subcategories to show * Allow user to select how subcategories are sorted * Fix budget filtering * [autofix.ci] apply automated fixes * Condense sorting and Other-grouping to one option * Implement Sort as budget option * Dynamically adjust topN based on SankeyCard height * Remove old feature flags from previous PR --------- Co-authored-by: andrewhumble <43395285+andrewhumble@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: youngcw <calebyoung94@gmail.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Implement Sankey graph report * Add release notes * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Remove local debug settings * [autofix.ci] apply automated fixes * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Improve graphs from comments * Fix lints * coderabit fixes * Fix filtering and UI enhancements * remove pngs * Fix typecheck * Another type issue * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Fix strict typing issues * Update report page Now better conforms with components from other reports, e.g. by reusing Header Makes it possible to display a period longer than one month. * Change view description order * Formatting and cleanup * Removed difference section, as it will be difficult to get a reliable view across months * Introduce the Timeframe param, similar to Spending report, to allow saving a Live sliding window. * Allow filtering just the last month * Fix linting errors * Remove all information about income * Remove debugging statement * Sort categories and subcategories by amount * Move compact mode to spreadsheet to fix Card view more easily * Update tests file * Add release notes * Rename release notes to match PR# * Fix autofix.ci issues * Update packages/desktop-client/e2e/sankey.test.ts Enable experimental feature fall all tests, pr. coderabbit recommendation Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Add sankey-card to isWidgetType * Gate Sankey routes to prevent direct URL bypass * Fix typo * Change node transformation to work by key instead of name, to remove risk of duplicate issues Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Prevent false-positive pass in month-change test. * Translate mode to a proper label * Fix message for empty data * Enabled LoadingIndicator until data is ready * Change card default mode * More robust filtering * Fixed issue with budgeted spreadsheet not using 'end' date * Allow copying SankeyCard to dashboard * Fix typing and linting issues * Remove e2e tests I cannot currently get them to pass, because I dont fully understand playwright and how they are supposed to work. I can see that they don't exist for other reports. We can add them later if required. * Remove unecessary sankey reference * Refactor spreadsheet * Remove dead code from SankeyGraph * Collect to Other if too many subcategories * Edit wrong comment * Linting and typechecking * Show remaining amount to budget * Hide description on narrow device * Add visual clue if 'To budget' is larger than 'Budgeted' and would extend below the edge of the graph * Add colors to the links * Fix report card showing subcategories instead of main categories * Add tooltip info to Other on SankeyCard * Create globalOther flag and implement greedy category reduction algorithm * Allow user to select between Global or Per category Other * Allow user to choose number of subcategories to show * Allow user to select how subcategories are sorted * Fix budget filtering * [autofix.ci] apply automated fixes * Condense sorting and Other-grouping to one option * Implement Sort as budget option * Dynamically adjust topN based on SankeyCard height * Remove old feature flags from previous PR --------- Co-authored-by: andrewhumble <43395285+andrewhumble@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: youngcw <calebyoung94@gmail.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Implement Sankey graph report * Add release notes * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Remove local debug settings * [autofix.ci] apply automated fixes * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Improve graphs from comments * Fix lints * coderabit fixes * Fix filtering and UI enhancements * remove pngs * Fix typecheck * Another type issue * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Fix strict typing issues * Update report page Now better conforms with components from other reports, e.g. by reusing Header Makes it possible to display a period longer than one month. * Change view description order * Formatting and cleanup * Removed difference section, as it will be difficult to get a reliable view across months * Introduce the Timeframe param, similar to Spending report, to allow saving a Live sliding window. * Allow filtering just the last month * Fix linting errors * Remove all information about income * Remove debugging statement * Sort categories and subcategories by amount * Move compact mode to spreadsheet to fix Card view more easily * Update tests file * Add release notes * Rename release notes to match PR# * Fix autofix.ci issues * Update packages/desktop-client/e2e/sankey.test.ts Enable experimental feature fall all tests, pr. coderabbit recommendation Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Add sankey-card to isWidgetType * Gate Sankey routes to prevent direct URL bypass * Fix typo * Change node transformation to work by key instead of name, to remove risk of duplicate issues Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Prevent false-positive pass in month-change test. * Translate mode to a proper label * Fix message for empty data * Enabled LoadingIndicator until data is ready * Change card default mode * More robust filtering * Fixed issue with budgeted spreadsheet not using 'end' date * Allow copying SankeyCard to dashboard * Fix typing and linting issues * Remove e2e tests I cannot currently get them to pass, because I dont fully understand playwright and how they are supposed to work. I can see that they don't exist for other reports. We can add them later if required. * Remove unecessary sankey reference * Refactor spreadsheet * Remove dead code from SankeyGraph * Collect to Other if too many subcategories * Edit wrong comment * Linting and typechecking * Show remaining amount to budget * Hide description on narrow device * Add visual clue if 'To budget' is larger than 'Budgeted' and would extend below the edge of the graph * Add colors to the links * Fix report card showing subcategories instead of main categories * Add tooltip info to Other on SankeyCard * Create globalOther flag and implement greedy category reduction algorithm * Allow user to select between Global or Per category Other * Allow user to choose number of subcategories to show * Allow user to select how subcategories are sorted * Fix budget filtering * [autofix.ci] apply automated fixes * Condense sorting and Other-grouping to one option * Implement Sort as budget option * Dynamically adjust topN based on SankeyCard height * Remove old feature flags from previous PR --------- Co-authored-by: andrewhumble <43395285+andrewhumble@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: youngcw <calebyoung94@gmail.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* trim down some unused/unnecessary dependencies (#7350) * fix github actions inconsistencies * fix pinning of transitive deps in eslint-plugin * drop use of node-fetch in api * drop md5 dependency in favour of node:crypto * drop slash * drop unused top level packages * add note about node-polyfills warning * remove unused deps from desktop-client * drop pegjs types * note * drop node-jq * [Doc] More tour image (mostly) updates & a hotkey fix (#7328) * Fix keyboard shortcut Mac key for undo operations Updated keyboard shortcut instructions for Mac & make consistent. * Add files via upload * Fix undo shortcut from 'K' to 'Z' Updated keyboard shortcut for undo operation in payees guide. COFFEE! * Revise budget section for clarity and consistency Updated category descriptions and improved Markdown support details. * Add files via upload * Fix grammatical error in budget.md * Fix typo and clarify Markdown description in budget.md Corrected a typo in the documentation regarding the chevrons and clarified the description of rendered Markdown. * Fix spelling error in budget documentation Corrected the spelling of 'cheverons' to 'chevrons'. * Add files via upload * Remove redundant text in budget.md * Fix formatting issues in payees.md * count points script should fetch the release note from the PR directly (#7309) * get pr release note from PR, not top of master * note * [AI] Mobile: Post transaction today on global account lists (#7311) (#7322) * [AI] Mobile: pass today for Post transaction today on global account lists (#7311) All Accounts, On budget, and Off budget transaction lists now forward the today flag to schedule/post-transaction, matching single-account mobile and desktop behavior. Made-with: Cursor * [AI] Add release note for PR 7322 (#7311) Made-with: Cursor * [AI] Tighten release note wording for PR 7322 (imperative) Made-with: Cursor --------- Co-authored-by: Pranay Mac M1 <pranayseela@yahoo.com> --------- Co-authored-by: Matt Fiddaman <github@m.fiddaman.uk> Co-authored-by: Pranay S <pranayritvik@gmail.com> Co-authored-by: Pranay Mac M1 <pranayseela@yahoo.com> Co-authored-by: youngcw <calebyoung94@gmail.com> * Implement Sankey report for spent and budgeted money (#7220) * Implement Sankey graph report * Add release notes * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Remove local debug settings * [autofix.ci] apply automated fixes * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Improve graphs from comments * Fix lints * coderabit fixes * Fix filtering and UI enhancements * remove pngs * Fix typecheck * Another type issue * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Fix strict typing issues * Update report page Now better conforms with components from other reports, e.g. by reusing Header Makes it possible to display a period longer than one month. * Change view description order * Formatting and cleanup * Removed difference section, as it will be difficult to get a reliable view across months * Introduce the Timeframe param, similar to Spending report, to allow saving a Live sliding window. * Allow filtering just the last month * Fix linting errors * Remove all information about income * Remove debugging statement * Sort categories and subcategories by amount * Move compact mode to spreadsheet to fix Card view more easily * Update tests file * Add release notes * Rename release notes to match PR# * Fix autofix.ci issues * Update packages/desktop-client/e2e/sankey.test.ts Enable experimental feature fall all tests, pr. coderabbit recommendation Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Add sankey-card to isWidgetType * Gate Sankey routes to prevent direct URL bypass * Fix typo * Change node transformation to work by key instead of name, to remove risk of duplicate issues Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Prevent false-positive pass in month-change test. * Translate mode to a proper label * Fix message for empty data * Enabled LoadingIndicator until data is ready * Change card default mode * More robust filtering * Fixed issue with budgeted spreadsheet not using 'end' date * Allow copying SankeyCard to dashboard * Fix typing and linting issues * Remove e2e tests I cannot currently get them to pass, because I dont fully understand playwright and how they are supposed to work. I can see that they don't exist for other reports. We can add them later if required. * Remove unecessary sankey reference * Refactor spreadsheet * Remove dead code from SankeyGraph * Collect to Other if too many subcategories * Edit wrong comment * Linting and typechecking * Show remaining amount to budget * Hide description on narrow device * Add visual clue if 'To budget' is larger than 'Budgeted' and would extend below the edge of the graph * Add colors to the links * Fix report card showing subcategories instead of main categories * Add tooltip info to Other on SankeyCard * Create globalOther flag and implement greedy category reduction algorithm * Allow user to select between Global or Per category Other * Allow user to choose number of subcategories to show * Allow user to select how subcategories are sorted * Fix budget filtering * [autofix.ci] apply automated fixes * Condense sorting and Other-grouping to one option * Implement Sort as budget option * Dynamically adjust topN based on SankeyCard height * Remove old feature flags from previous PR --------- Co-authored-by: andrewhumble <43395285+andrewhumble@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: youngcw <calebyoung94@gmail.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Fix yarn generate:icons command (#7281) * fix icon templates with `module.exports` to `export default` * Add `@svgr/babel-plugin-add-jsx-attribute` to dependencies * Run `yarn generate:icons`, and set prettier singleQuote to reduce changes * Add release note * Add temporary fix for `SvgChartArea` * Add `ChartArea` svg from the existing tsx * CI rerun * Standardise ledger scrolling when using keyboard shortcuts (#7283) * Standardise table keyboard navigation by preventing browser scroll with arrow keys * Add release note * Apply the preventDefault() in specific cases so that it is not applied to default --------- Co-authored-by: youngcw <calebyoung94@gmail.com> * Bump lodash from 4.17.23 to 4.18.1 Bumps [lodash](https://github.com/lodash/lodash) from 4.17.23 to 4.18.1. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](lodash/lodash@4.17.23...4.18.1) --- updated-dependencies: - dependency-name: lodash dependency-version: 4.18.1 dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com> * note --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Matt Fiddaman <github@m.fiddaman.uk> Co-authored-by: Juulz <julesmcn@gmail.com> Co-authored-by: Pranay S <pranayritvik@gmail.com> Co-authored-by: Pranay Mac M1 <pranayseela@yahoo.com> Co-authored-by: youngcw <calebyoung94@gmail.com> Co-authored-by: Emil Tveden Bjerglund <emilbp@gmail.com> Co-authored-by: andrewhumble <43395285+andrewhumble@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: James Skinner <56730344+JSkinnerUK@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matiss Janis Aboltins <matiss@mja.lv>
) * trim down some unused/unnecessary dependencies (#7350) * fix github actions inconsistencies * fix pinning of transitive deps in eslint-plugin * drop use of node-fetch in api * drop md5 dependency in favour of node:crypto * drop slash * drop unused top level packages * add note about node-polyfills warning * remove unused deps from desktop-client * drop pegjs types * note * drop node-jq * [Doc] More tour image (mostly) updates & a hotkey fix (#7328) * Fix keyboard shortcut Mac key for undo operations Updated keyboard shortcut instructions for Mac & make consistent. * Add files via upload * Fix undo shortcut from 'K' to 'Z' Updated keyboard shortcut for undo operation in payees guide. COFFEE! * Revise budget section for clarity and consistency Updated category descriptions and improved Markdown support details. * Add files via upload * Fix grammatical error in budget.md * Fix typo and clarify Markdown description in budget.md Corrected a typo in the documentation regarding the chevrons and clarified the description of rendered Markdown. * Fix spelling error in budget documentation Corrected the spelling of 'cheverons' to 'chevrons'. * Add files via upload * Remove redundant text in budget.md * Fix formatting issues in payees.md * count points script should fetch the release note from the PR directly (#7309) * get pr release note from PR, not top of master * note * [AI] Mobile: Post transaction today on global account lists (#7311) (#7322) * [AI] Mobile: pass today for Post transaction today on global account lists (#7311) All Accounts, On budget, and Off budget transaction lists now forward the today flag to schedule/post-transaction, matching single-account mobile and desktop behavior. Made-with: Cursor * [AI] Add release note for PR 7322 (#7311) Made-with: Cursor * [AI] Tighten release note wording for PR 7322 (imperative) Made-with: Cursor --------- Co-authored-by: Pranay Mac M1 <pranayseela@yahoo.com> --------- Co-authored-by: Matt Fiddaman <github@m.fiddaman.uk> Co-authored-by: Pranay S <pranayritvik@gmail.com> Co-authored-by: Pranay Mac M1 <pranayseela@yahoo.com> Co-authored-by: youngcw <calebyoung94@gmail.com> * Implement Sankey report for spent and budgeted money (#7220) * Implement Sankey graph report * Add release notes * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Remove local debug settings * [autofix.ci] apply automated fixes * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Improve graphs from comments * Fix lints * coderabit fixes * Fix filtering and UI enhancements * remove pngs * Fix typecheck * Another type issue * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Update VRT screenshots Auto-generated by VRT workflow PR: #6068 * Fix strict typing issues * Update report page Now better conforms with components from other reports, e.g. by reusing Header Makes it possible to display a period longer than one month. * Change view description order * Formatting and cleanup * Removed difference section, as it will be difficult to get a reliable view across months * Introduce the Timeframe param, similar to Spending report, to allow saving a Live sliding window. * Allow filtering just the last month * Fix linting errors * Remove all information about income * Remove debugging statement * Sort categories and subcategories by amount * Move compact mode to spreadsheet to fix Card view more easily * Update tests file * Add release notes * Rename release notes to match PR# * Fix autofix.ci issues * Update packages/desktop-client/e2e/sankey.test.ts Enable experimental feature fall all tests, pr. coderabbit recommendation Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Add sankey-card to isWidgetType * Gate Sankey routes to prevent direct URL bypass * Fix typo * Change node transformation to work by key instead of name, to remove risk of duplicate issues Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Prevent false-positive pass in month-change test. * Translate mode to a proper label * Fix message for empty data * Enabled LoadingIndicator until data is ready * Change card default mode * More robust filtering * Fixed issue with budgeted spreadsheet not using 'end' date * Allow copying SankeyCard to dashboard * Fix typing and linting issues * Remove e2e tests I cannot currently get them to pass, because I dont fully understand playwright and how they are supposed to work. I can see that they don't exist for other reports. We can add them later if required. * Remove unecessary sankey reference * Refactor spreadsheet * Remove dead code from SankeyGraph * Collect to Other if too many subcategories * Edit wrong comment * Linting and typechecking * Show remaining amount to budget * Hide description on narrow device * Add visual clue if 'To budget' is larger than 'Budgeted' and would extend below the edge of the graph * Add colors to the links * Fix report card showing subcategories instead of main categories * Add tooltip info to Other on SankeyCard * Create globalOther flag and implement greedy category reduction algorithm * Allow user to select between Global or Per category Other * Allow user to choose number of subcategories to show * Allow user to select how subcategories are sorted * Fix budget filtering * [autofix.ci] apply automated fixes * Condense sorting and Other-grouping to one option * Implement Sort as budget option * Dynamically adjust topN based on SankeyCard height * Remove old feature flags from previous PR --------- Co-authored-by: andrewhumble <43395285+andrewhumble@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: youngcw <calebyoung94@gmail.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Fix yarn generate:icons command (#7281) * fix icon templates with `module.exports` to `export default` * Add `@svgr/babel-plugin-add-jsx-attribute` to dependencies * Run `yarn generate:icons`, and set prettier singleQuote to reduce changes * Add release note * Add temporary fix for `SvgChartArea` * Add `ChartArea` svg from the existing tsx * CI rerun * Standardise ledger scrolling when using keyboard shortcuts (#7283) * Standardise table keyboard navigation by preventing browser scroll with arrow keys * Add release note * Apply the preventDefault() in specific cases so that it is not applied to default --------- Co-authored-by: youngcw <calebyoung94@gmail.com> * Fix updateTransaction corrupting split parents with partial updates (#7242) * [AI] Fix updateTransaction corrupting split parents with partial updates When `api.updateTransaction(id, { notes: '...' })` is called on a split parent, the `updateTransaction` helper replaces the parent with the sparse update object (`{ id, notes }`) instead of merging it with the existing transaction data. This causes `recalculateSplit` to see `amount` as `undefined` (→ 0), which doesn't match the children's total and sets a `SplitTransactionError` on the parent. `makeChild` also inherits undefined `account`, `date`, and `cleared` values, potentially creating broken child rows. Fix: merge the incoming partial fields (`{ ...trans, ...transaction }`) so all existing properties are preserved. Add a test that performs a notes-only update on a split parent and asserts no error is set and the amount stays intact. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * [AI] Add release notes for PR #7242 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Address review feedback: remove verbose comment and simplify release note Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: L. Warren Thompson <lwarrenthompson@Warren-MBP.local> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * [AI] Add electron conditions to loot-core platform/server exports and fix imports - Add "electron" condition to platform/server exports (asyncStorage, connection, fetch, fs, sqlite) so they resolve to .electron.ts files when using the electron export condition - Remove broken ./client/platform export referencing non-existent files - Convert deep relative imports in electron files to subpath imports (#types/prefs, #server/errors, #server/mutators) https://claude.ai/code/session_01FPpKnozt42Mf79YHAT6ytM * [AI] Convert remaining relative imports to subpath imports in electron files - Convert ../fs, ../log, ../../exceptions to subpath imports (#platform/server/fs, #platform/server/log, #platform/exceptions) - Add electron-conditional entries to the imports field in package.json for all 5 platform/server modules with electron variants - Add resolve.conditions: ['electron'] to vite.desktop.config.ts so the electron condition is recognized during desktop builds https://claude.ai/code/session_01FPpKnozt42Mf79YHAT6ytM * Add release notes for PR #7383 * [AI] Fix API build and test failures from conditional exports - Add "api" condition to all 5 platform/server exports and imports entries so the API build resolves to .api.ts variants correctly - Add resolve.conditions and ssr.resolve.conditions: ['api'] to packages/api/vite.config.ts - Add explicit #platform/server/log and #platform/exceptions entries to the imports field (array fallback in #* wildcard doesn't work for directory modules) - Revert #platform/server/fs back to relative ../fs import in asyncStorage/index.electron.ts — subpath imports for platform modules with electron variants don't work in vitest because the test runner doesn't propagate resolve.conditions to Node's import resolution https://claude.ai/code/session_01FPpKnozt42Mf79YHAT6ytM * fix: apply CodeRabbit auto-fixes Fixed 2 file(s) based on 2 unresolved review comments. Co-authored-by: CodeRabbit <noreply@coderabbit.ai> * [autofix.ci] apply automated fixes * Enhance package.json and Vite configurations for Electron support; refactor imports to use new path aliases. Added new paths for server and shared modules, updated SSR settings, and improved test configurations for better module resolution. * [AI] Merge electron condition with default Vite conditions in vitest config Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com> * [AI] Move @ts-strict-ignore comment to first line in reset.ts Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com> --------- Co-authored-by: Matt Fiddaman <github@m.fiddaman.uk> Co-authored-by: Juulz <julesmcn@gmail.com> Co-authored-by: Pranay S <pranayritvik@gmail.com> Co-authored-by: Pranay Mac M1 <pranayseela@yahoo.com> Co-authored-by: youngcw <calebyoung94@gmail.com> Co-authored-by: Emil Tveden Bjerglund <emilbp@gmail.com> Co-authored-by: andrewhumble <43395285+andrewhumble@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: James Skinner <56730344+JSkinnerUK@users.noreply.github.com> Co-authored-by: L. Warren Thompson <warren.thompson@zuirail.com> Co-authored-by: L. Warren Thompson <lwarrenthompson@Warren-MBP.local> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: CodeRabbit <noreply@coderabbit.ai> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>



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.,