* add a bottom sheet version of Modal
* add mobile sheet building blocks
* add budget menu hooks
* swap mobile menus to bottom sheets
* [AI] Update mobile e2e page models for sheets
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #9127
* [AI] Update mobile e2e for sheets
Sheets are labelled by their title and have no close button, so the page models find them by role alone and dismiss with Escape. Menu actions are rows, deleting a category or group confirms inside the sheet, the Reconcile row is matched exactly, and the budget amount is tapped before it is filled because the sheet no longer autofocuses it.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #9127
* [AI] Make sheet row text one size larger
Review feedback: the 13px rows read a touch small on a phone. Rows and disabled menu entries now use the 15px medium text size.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #9127
* keep the edit notes row in the same place on every sheet
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #9127
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* [AI] Import from PR #8707
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* clean up the imported settings navigation
* move payees, rules and bank sync into a settings menu on mobile
* split out appearance settings
* remove payees, rules, bank sync and tags from the redesigned sidebar
* add accent based colour tokens for the settings nav
* match settings card colours to the tables
* [AI] update tests for the settings navigation
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #9110
* move appearance back to general
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #9110
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #9110
---------
Co-authored-by: Stephen Brown II <Stephen.Brown2@gmail.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* [AI] Add standard size system to Button, Text and Input components
* [AI] Migrate modals, settings, rules, schedules and sidebar text to standard sizes
* [AI] Migrate mobile, budget, manager, banksync and transactions text to standard sizes
* [AI] Migrate reports, formula and news text to standard sizes
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #9002
* Revert "Update VRT screenshots"
This reverts commit 35c947ef54.
* [AI] Fix line-height rendering as px strings in size tokens
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #9002
* [AI] Tighten bank sync mobile row gap so larger labels fit on one line
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #9002
* [AI] Restore amount display size to preserve underline spacing
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #9002
* [AI] Pass caller-provided size through SingleAutocomplete render input
* [AI] Omit forced line-height on medium-sized controls to match the default look
* [AI] Document standard component sizes in DESIGN.md
* [AI] Adopt sidebar spacing tokens where values match exactly
* [AI] Scope the mobile touch-target rule to touch-primary control sizes
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* monte carlo income streams
* simplify release note
* enhancement
* fix withdrawal rule floor when income is specified
* update screenshots
* suplus pot and images
* way better description in the run details
* covering case where income is all thats setup and spending is the same as the income
* feedback
* screenshots and rename of minimum withdrawal to min spending
* additional docs
* Bump @vitest/mocker in the npm_and_yarn group across 0 directory
Updates `@vitest/mocker` from 4.1.10 to 5.0.0
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v5.0.0/packages/mocker)
---
updated-dependencies:
- dependency-name: "@vitest/mocker"
dependency-version: 5.0.0
dependency-type: indirect
dependency-group: npm_and_yarn
...
Signed-off-by: dependabot[bot] <support@github.com>
* [AI] Fix typecheck failures under vitest 5
Vitest 5 changed two things that broke the typecheck/build jobs:
- `vi.fn()`'s inferred type now references `Procedure` from an internal
vitest chunk that cannot be named from outside, so the hoisted mocks in
`cloud-storage.test.ts` tripped TS2883. Annotate them as `Mock`.
- The `expect` package was inlined and the global `jest.Matchers`
declaration dropped, so `@testing-library/jest-dom`'s default entry no
longer augments vitest's `Assertion`. Use the `/vitest` entry point
instead.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bvwt76cXUoLwfHiy1jhToc
* [AI] Bump @actual-app/crdt to 3.1.3
The dependency bump touches packages/crdt/package.json, so the CRDT
version bump check requires a new version. Matches how the previous
dependabot group bump (#8921) was handled.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bvwt76cXUoLwfHiy1jhToc
* [AI] Add release note for the vitest bump
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bvwt76cXUoLwfHiy1jhToc
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: MatissJanis <matiss@mja.lv>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
* [AI] Merge duplicate Themes/themes directories
`packages/component-library/src/Themes` and
`packages/component-library/src/themes` collide on case-insensitive
filesystems (macOS), which makes checkouts of the repo hash differently
there than on Linux. Move the single file in `Themes/` (`Theming.mdx`)
into `themes/` and point the Storybook stories glob at the merged
directory. The docs entry keeps its id and sidebar title.
Fixes#8843
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* [AI] Fix broken custom themes docs link
The Theming page linked to /docs/experimental/custom-themes, which 404s —
the page lives at /docs/custom-themes/.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
* add account group balance bindings, collapse pref and expand
* add the sidebar account and collapse hooks
* add the redesigned sidebar account list components
* add the account, group and section components
* use the new account list
* increase account row spacing
* declutter pill
* icon hover
* icon tooltips
* change case and maintain heirarchy of on/off budget headers
* dynamically show/hide sync dot based on whether there are bank synced accounts
* tweak expand/collapse icon
* swap icon on expand/collapse
* remove templates in padding
* add sidebar theme tokens and shared text styles
* extract useSyncStatus hook
* extract SidebarShell from the old sidebar
* add the redesigned sidebar shell
* [Enhancements] Add quarter date range presets
* Revert unnecessary changes
* Add back changes
* do not need .yarn/release file
* [AI] Update date range picker VRT snapshots for quarter presets
The Current quarter/Previous quarter presets added to the date range
picker grew the popover height, invalidating the committed VRT
screenshots.
* Add max height
* VRT regenerated
The React Compiler include regex only matched .jsx/.tsx, so hooks and
components defined in plain .ts/.js files were never compiled. The babel
plugin already selects the TypeScript parser for .ts files, and the
compiler's code pre-filter keeps non-React files cheap to skip, so
widening the include to .[jt]sx? is all that's needed.
Claude-Session: https://claude.ai/code/session_013D6rbX4YueKKPZing9DRgm
Co-authored-by: Claude <noreply@anthropic.com>
* [AI] Add a column manager to the transaction table
Adds a modal for showing, hiding, and reordering transaction table
columns, saved per view or budget-wide.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Fix running balance e2e test to use the column manager
The 'Show running balance' menu item was replaced by the column manager,
so this test now toggles the column via the modal instead.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Address code review feedback for the column manager
- Apply-to-all now clears every stored view override, derived from the
synced prefs themselves (covers closed/deleted accounts)
- The column manager shows the user's underlying cleared-column
preference while a reconciliation is in progress
- At least one amount column always stays visible so new transactions
keep an amount input (enforced at parse time and in the modal)
- Column toggles now have an accessible name (Toggle forwards aria-label)
- E2e: idempotent setTransactionColumnVisibility page-model helper,
shared openTransactionColumnsModal, and a fixed expected header order
in the reorder test so a skipped reorder cannot pass
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Assert the exact header cell sequence in the reorder e2e test
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Use a checkbox instead of a toggle for applying columns to all views
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 12:58:55 +00:00
Matt FiddamanGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>Matiss Janis Aboltins
* [AI] feat(reports): add browser-independent month range picker
Replace the report date dropdowns with a popover month range picker built
from React and Actual's own components instead of a native month input
(which does not work in Firefox). Includes start/end month grids,
quick-select presets folded into the popover, a draft selection that only
recomputes the report on close, today highlighting, and an unbounded future
range.
Assisted-by: ClaudeCode:claude-opus-4.8
Co-authored-by: rznn7 <160644362+rznn7@users.noreply.github.com>
* [AI] refactor(desktop-client): replace pikaday with react-aria in DateSelect
Swap the Pikaday-based day picker in DateSelect for react-aria-components'
Calendar primitives (backed by @internationalized/date). The user's
firstDayOfWeekIdx preference is encoded via the Unicode 'fw' locale
extension, and the prev/next arrows now use the existing SvgCheveron
icons instead of the two bundled PNGs.
Removes the pikaday and @types/pikaday dependencies, deletes the unused
DateSelect.left/right.png assets, and adds @internationalized/date as a
direct dependency.
Assisted-by: ClaudeCode:claude-opus-4.8
* [AI] fix(desktop-client): resolve CI failures in month picker PR
Remove four devDependencies (@juggle/resize-observer, @types/lodash, @types/promise-retry, memoize-one) that were added but never used, fixing the knip check. Dedupe the split @codemirror/state and @codemirror/view resolutions that the added/removed deps introduced, fixing typecheck. Pin shell-quote (a transitive dependency of launch-editor/npm-run-all) to >=1.8.4 via resolutions, matching the existing socks/serialize-javascript overrides, to clear the critical CVE flagged by Dependency Review.
Assisted-by: ClaudeCode:claude-sonnet-5
* updated yarn.lock
* Updated yarn.lock to address dependency issue
* address more dependency issues
* `yarn up -R '**'` to hopefully address all dependency issues
* fixed donutgraph.tsx typing
* [AI] feat(reports): add Month/Day granularity toggle to range picker
Add a Month/Day toggle above the quick-select column in the report range
picker so users can pick exact days, not just whole months. Switching to Day
expands the range to cover whole days (start -> first of month, end -> last of
month); switching back collapses to months. In day mode the picker emits
yyyy-MM-dd start/end.
Make the month-based reports tolerate day-level values: month range helpers in
monthUtils already coerce day strings to months, and this replaces the few
fragile 'start + "-01"' concatenations (BalanceForecast, BalanceForecastCard,
BudgetAnalysis, balanceForecastChartData) with firstDayOfMonth/getMonth so a
yyyy-MM-dd value is normalized instead of corrupted.
Assisted-by: ClaudeCode:claude-opus-4.8
* [AI] feat(reports): honor day granularity, live end-offset, format-aware picker
Task 3: derive the range picker trigger's display format from the committed
value's shape (yyyy-MM-dd vs yyyy-MM) via a new valueIsDay() helper instead of
the granularity flag, so the label stays correct (day vs month) after the
popover closes.
Task 1: let a live/sliding range end before the current month.
getLatestRange(offset, endOffset=0) and calculateTimeRange's sliding-window
branch derives endOffset from the saved frame (clamped >= 0) so the window's
gap-from-now is preserved as months roll over. Surface it with an 'Exclude
current month' checkbox in the picker popover (shifts the whole range back one
month, keeping its width), enabled for past ranges only.
Task 2: add a maintainer-facing granularities prop on MonthRangePicker (threaded
through Header), defaulting to ['month','day']. Pass ['month'] to hide the Day
toggle on month-only reports; Budget Analysis is locked to month. AgeOfMoney's
granularity stays a distinct concept.
Add unit tests for getLatestRange/calculateTimeRange endOffset and the picker
util helpers. Use named imports throughout.
Assisted-by: ClaudeCode:claude-opus-4.8
Co-authored-by: rznn7 <rznn7@users.noreply.github.com>
* [AI] feat(reports): single-calendar range picker, fix granularity reset on remount
Replaces the two side-by-side Start/End calendar grids in the reports date-range picker with a single calendar (RangeSelector) supporting click-to-pick range selection with a live hover preview, for both Month and Day granularity.
Also fixes the Month/Day toggle silently reverting after a pick: CashFlow, NetWorth, AgeOfMoney, and BalanceForecast unmount their Header/MonthRangePicker subtree on every date change (useReport nulls out data during refetch), which wiped the picker's internal granularity state. Lifted that state into each report so it survives the remount.
Assisted-by: ClaudeCode:claude-sonnet-5
* [AI] fix(reports): persist sliding-window endOffset so live ranges actually slide forward
calculateTimeRange's sliding-window branch re-derived the gap between a saved end date and 'now' on every call, using the stale, decaying persisted end. Since most reports only rewrite that persisted end when the user explicitly saves the widget, the derived gap grew by however much time had passed since the last save — meaning a live range never actually advanced once its gap was nonzero; it stayed pinned to the last-saved dates indefinitely. Caught by useFormulaExecution.test.ts's 'shifts each formula report query window when the current month changes' test, which was failing on this branch.
Adds TimeFrame.endOffset, persisted explicitly alongside start/end/mode instead of re-derived from decaying absolute dates. getLatestRange and calculateTimeRange now return the resolved endOffset as a 4th tuple element; MonthRangePicker computes it at commit time and threads it through Header's onChangeDates into every report that persists a timeFrame (CashFlow, NetWorth, AgeOfMoney, BalanceForecast, Calendar, Sankey, Crossover, Summary, BudgetAnalysis). Legacy saved widgets without endOffset fall back to the old derivation once, as a migration.
Assisted-by: ClaudeCode:claude-sonnet-5
* [AI] fix(reports): route day-grid clicks through pick directly
DayGrid's per-day onSelect was wired to selectMonth, a handler meant for
month-grid clicks and month-navigation day-carry-over. Fed a full day
string it built a malformed candidate (e.g. 2026-07-20-10) that never
string-matched the clicked day, so the range endpoint lost its selected
(primary) styling and only showed as part of the in-range band.
Assisted-by: ClaudeCode:claude-sonnet-5
* [AI] fix(reports): keep day-mode range width when reopening picker
openPopover unconditionally expanded start/end to the full month via
toDayStart/toDayEnd whenever reopening in day mode, even when the range
was already day-shaped from a prior precise pick. Only expand when the
incoming value is still month-shaped (an actual month-to-day switch).
Assisted-by: ClaudeCode:claude-sonnet-5
* [AI] fix(reports): address code review findings on month/day range picker
Fix clamp() returning granularity-mismatched bounds when min/max are month-shaped but the picker is in day mode. Add accessible labels to NavRow's prev/next icon buttons. Deduplicate the Pie shape index coercion in DonutGraph into a shared helper. Drop the unnecessary useMemo around MonthRangePicker's label string.
Skipped: the Header.tsx allMonths[allMonths.length - 1] access can't crash since every caller already guards on allMonths being non-empty before rendering Header. The RangeEndSelector.tsx dead-code finding refers to a file that no longer exists in this codebase. The DateSelect.tsx firstDayOfWeek suggestion doesn't apply: react-aria-components' public CalendarGrid props don't expose firstDayOfWeek in the installed version, so the locale '-u-fw-' extension is still the only way to configure it.
Assisted-by: ClaudeCode:claude-sonnet-5
* [AI] fix(reports): stop widening day-shaped bounds in balance forecast chart data
buildBalanceForecastChartData's Daily branch applied firstDayOfMonth/lastDayOfMonth to start/end unconditionally, which expanded an already day-shaped range (e.g. 2024-03-15) out to its whole month. Only expand when the bound is month-shaped (isValidYearMonth), otherwise use it as-is.
Assisted-by: ClaudeCode:claude-sonnet-5
* [AI] fix(reports): address CodeRabbit findings on month/day range picker (round 2)
Header: fall back minDate to the current month when allMonths is still empty (Summary/Calendar render before their async load populates it). RangeSelector/DayGrid: normalize min/max to day granularity in DayGrid so a month-shaped bound doesn't disable every day in its own month. AgeOfMoney: derive the picker's initial Month/Day mode from the restored range's shape instead of hardcoding month, since that mode isn't persisted separately from timeFrame. BudgetAnalysis: normalize start/end to yyyy-MM inside calculateIsConcise so a legacy day-shaped persisted timeFrame can't corrupt the date-fns parse. DonutGraph: read props.index directly instead of coercing a second shape-callback argument. MonthRangePicker: use && short-circuit JSX per the style guide. AgeOfMoney: drop an unnecessary useCallback with no deps, matching sibling reports. DayGrid/RangeSelector/MonthRangePicker/Header: thread firstDayOfWeekIdx through so the day grid's weekday header and alignment follow the user's configured first day of week instead of hardcoding Sunday-first.
Skipped: the Crossover.tsx 'double shift' finding — the extra -1 month shift is pre-existing, documented, intentional business logic (excludes the current month), applied symmetrically on both load and onChangeDates regardless of whether endOffset was legacy-derived or explicitly persisted; the suggested fix wouldn't touch that code path anyway.
Assisted-by: ClaudeCode:claude-sonnet-5
* Update category and authors in release notes
Address technical debt by introducing a day picker for the calendar.
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #8427
* [AI] Address review feedback on month/day range picker and DateSelect
- Crossover: treat legacy widgets' missing endOffset as 0 (no double shift)
- Only offer "Exclude current month" in month mode for ranges ending at the
current or previous month
- Cap past-oriented reports at the newest month; future stays for forecasts
- Don't commit on Month/Day switch so the popover survives report reloads
- Month-only picker for Calendar, Summary, Sankey and Crossover
- Transaction date picker: visible month-nav arrows that keep focus in the
input, normal-sized heading, square day cells, tighter popover
- Give unselected grid cells a transparent border so selecting doesn't
resize the grid
- Derive picker granularity from the committed value shape and drop the
lifted per-report state and Header props
- Simplify per review: reuse ModeButton/monthUtils/Calendar firstDayOfWeek,
remove allowFuture, add useLanguage, fix double render on keystroke,
strip prose comments
- Restore master's yarn.lock (only the pikaday removal remains), drop the
shell-quote resolution, revert unrelated DonutGraph change
- Release note: describe the feature, add MatissJanis to authors
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #8427
* [AI] Cap day-mode picking at today and clamp exclude-toggle shifts
- A month-shaped max that reaches the current month no longer widens to the
month's last day in day mode; day cells after today are disabled and the
Month->Day draft widening clamps its end to today
- DayGrid and clamp() keep already day-shaped bounds exact instead of
widening them back to whole months
- toggleExcludeCurrentMonth clamps the shifted range to minDate/maxDate like
every other draft mutation
- granFor: function declaration per code style
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Use one SpaceBetween for consistent report header spacing
The header row was two SpaceBetween groups (gap 15 and gap 3) with no gap
between them, and reports wrapped their own controls in ad-hoc gap-10 Views.
Merge the mode toggle, date picker, filter button and report controls into a
single SpaceBetween, render header children through one too, and drop the
per-report wrappers (Balance Forecast, Cash Flow, Budget Analysis, Sankey).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Drop endOffset; sliding windows always anchor to the current month
Remove the persisted TimeFrame.endOffset and its wiring through
reportRanges, the range picker, Header and all report pages. A live
(sliding-window) range now always ends at the current month; "Exclude
current month" still shifts the draft range and commits it as static.
Also address code review findings: guard the "All time" preset while
allMonths is still loading, remount the range selector on granularity
switch so a month-shaped click-anchor can't produce a mixed-shape range,
only offer the exclude toggle when both of its states fit the configured
bounds, and give the month/day grid cells full localized accessible
names and a pressed state.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #8427
* [AI] Remove the "Exclude current month" checkbox
Its only unique capability was creating a live range ending last month via
endOffset, which is gone; picking the end month in the grid now does the
same thing. Deletes the toggle component, the allowExcludeCurrentMonth
prop and Header wiring, and the now-unused shiftMonths util.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Simplify month-range picker after cleanup review
Drop the util.ts aliases of shared months.ts helpers, derive picker
granularity from the draft value's shape instead of separate state,
normalize min/max bounds once in MonthRangePicker, inline the Header
preset builders, and make month-only the default granularity with
day-capable reports opting in explicitly.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Rebuild day-mode picking on react-aria RangeCalendar
Replace the hand-rolled DayGrid with react-aria's RangeCalendar, which
adds keyboard navigation and built-in hover range preview, and use
month/year dropdowns (CalendarMonthPicker plus a bounds-based year
select) in the calendar header for quick jumping. The month grid stays
custom since react-aria has no month-granularity range picker.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Address review feedback and fix picker styling glitches
Validate the full yyyy-MM-dd shape in valueIsDay instead of negating
the year-month check, cap the year dropdown when the report has no
upper date bound (the far-future sentinel would render ~8000 options),
use the bare-button hover color so hovered dates and month/year
selects stay readable, and stretch the day grid to the calendar's
full width.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Simplify month-range picker after cleanup review
- YearSelect reads bounds from RangeCalendarStateContext instead of props
- Dedupe first-day-of-week pref decoding into getFirstDayOfWeek in DateSelect
- Hoist the day-calendar emotion css() call to module scope
- RangeSelector tracks viewYear directly instead of a month it only read the year from
- Inline the single-consumer Grid component into MonthGrid
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Let live report ranges slide by days for day-shaped windows
Day-shaped sliding-window ranges now keep their width in days and
re-anchor to today, so Live works with day granularity in reports.
Formula queries stay month-granular via asMonthSlidingTimeFrame.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #8427
* [AI] Move the date range picker into the component library
Extract the reports MonthRangePicker into @actual-app/components as
DateRangePicker: translated strings arrive via a labels prop, date
formatting runs on Intl.DateTimeFormat with a BCP 47 locale string
instead of loot-core's date-fns wrappers, and the first-day-of-week
pref is resolved by the caller. Header.tsx supplies all of these; the
component library gains @internationalized/date and subpath import
mappings for the picker's internals.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Add VRT for the reports date range picker
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Add VRT snapshots for the reports date range picker
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Clean up the date range picker after review
- Move ModeButton into the component library and reuse it for the
granularity toggle instead of a near-identical SegmentButton copy
- Move the day-shaped value check into loot-core as isValidYearMonthDay
so reportRanges no longer imports it through the picker component
- Cache Intl.DateTimeFormat instances in formatDate
- Build lastDayOfMonth/currentDay on @internationalized/date
- Pass label subsets as one labels object instead of scalar props
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #8427
* [AI] Revert "Update VRT screenshots"
This reverts commit 8cd01e5148.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Hoist DateRangePicker to src root, add ModeButton story, respect app date format
- Move DateRangePicker.tsx and its stories out of the date-range-picker/
folder so the story sorts alphabetically in the Storybook sidenav; only
child components remain in the folder.
- Add a Storybook file for ModeButton.
- Add an optional formatDayLabel prop so day-shaped trigger labels can
follow the app's date format preference; reports Header now passes the
dateFormat synced pref instead of falling back to locale-numeric dates.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Address review feedback on the date range picker
- Bound scheduled-occurrence counts to the visible chart range so day-mode
ranges don't count occurrences outside the selected days
- Carry the running balance forward from points before a day-shaped start
instead of starting the daily chart at zero
- Drop the day granularity from the tracking-budget forecast header, which
only resolves monthly
- Validate the day against the month and year (incl. leap years) in
isValidYearMonthDay
- Target the date range picker trigger by test id in the reports e2e test
- Drop a redundant useMemo in useLocale (React Compiler memoizes)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Keep the date range picker open when a quick-select preset is clicked
Presets now preview their range in the open picker draft, like manual
selection, and commit on close so live-range modes are preserved.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* [AI] Improve date range picker colors and highlight the active preset
Style the calendar header dropdown options so they stay readable in dark
themes, introduce a datePickerRangeBackground theme variable so the light
theme's range band is purple like the other themes, and derive the active
quick-select preset from the current range so it stays highlighted when
reopening.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #8427
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #8427
---------
Co-authored-by: rznn7 <160644362+rznn7@users.noreply.github.com>
Co-authored-by: rznn7 <rznn7@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <matiss@mja.lv>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* [AI] Enable React Compiler for all monorepo packages with React code
The compiler was previously scoped to desktop-client/src only. Now:
- desktop-client's Vite build also compiles component-library source
(consumed as raw source through the same build), covering web,
desktop, and mobile bundles
- component-library's Storybook and Vitest pipelines apply the compiler
so they exercise the same compiled output
- docs (Docusaurus) enables babel-plugin-react-compiler for the site's
own React components
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PdcKq244khwKhedvLCwu7p
* [AI] Declare npm-run-all in component-library so its test script resolves
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PdcKq244khwKhedvLCwu7p
* [AI] Generalize React Compiler include to any workspace package source
Match packages/<name>/src instead of enumerating package names, so a
future workspace library with React components is compiled automatically.
Third-party code stays out via the babel plugin's default node_modules
exclude, which applies alongside a custom include.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PdcKq244khwKhedvLCwu7p
* [AI] Inline component-library test script instead of using npm-run-all
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PdcKq244khwKhedvLCwu7p
* [AI] Drop React Compiler from docs
The docs site is static content with a handful of simple components, so
auto-memoization buys nothing there, and an unscoped babel plugin would
also process Docusaurus theme code and every MDX page. Reverting keeps
the compiler where it pays off: desktop-client and component-library.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PdcKq244khwKhedvLCwu7p
---------
Co-authored-by: Claude <noreply@anthropic.com>
* added hash button to enable one-click mobile usage of tags feature
* added tags to demo
* release notes
* [autofix.ci] apply automated fixes
* fixed long tags wrapping
* removed duplicate <Button> usages and fixed coderabbit smell
* removed lint
* added null check per coderabbit
* moved Menus to after the menu to be consistent with transaction menus
* textWrap => whiteSpace for coderabbit
* updated tsconfig to fix typecheck issue
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #8344
* typecheck
* improved button ergonomics
* also don't add space if beginning of note
* fixed not working on iOS
* handle focus properly for add tag button
* fixed focus issue when clicking button on new transaction
* added delay because without it chrome doesnt work
* Added some more logic for button focusing
* fix typecheck
* extracted common style into iconStyle
* added aria label
* removed log statement
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* Context Menu is implemented
* allow Document and Window in ref event listener hook
* did stupid examples to showcase api usage
* recreated TransactionMenu using new context action
* fixed styling and removed excess calls to useContextMenuAction
* removed extra call
* extra imports
* started converting files to useContextMenu
* fixed context menus in reports
* linting and formatting
* deleted TransactionMenu
* release notes
* fixed coderabbit
* light context menu refactor
* added nested contexts for state and actions
* refactored useContextMenuAction
* [autofix.ci] apply automated fixes
* removed log
* updated contextMenuSlice
* removed package.json change
* filter => some
* tried to improve test
* [AI] test: fix payees e2e right-click test by scoping row query to table
* linting
* [AI] chore: fix all linting issues from new context menu files
* fixed compiler
* fixed linting/formatting
* coderabbit fix
* [AI] fix(electron): connect to sync server on 127.0.0.1 instead of localhost
Node.js > 17 resolves localhost to ::1 (IPv6) by default, while the Electron
sync server binds explicitly to 127.0.0.1 (IPv4). This caused setServerUrl to
fail when the desktop app starts its internal sync server, trapping the user
in an onboarding loop between /config-server and /bootstrap.
This commit updates the URL to use 127.0.0.1 to match the server binding.
* [AI] Fix isPlaywright detection for Electron Playwright tests
The userAgent check was changed from includes('playwright') to
=== 'playwright', but the Electron main process appends ' playwright'
to the default userAgent (preserving the 'Electron' substring that
isElectron() relies on). Use includes() so the flag is detected
correctly in Electron e2e tests.
Also reverts the localhost→127.0.0.1 change which did not resolve the
VRT pixel diffs.
* re-added missing menu option
---------
Co-authored-by: Alec Bakholdin <alecbakholdin.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Adds the knip tool with a monorepo-tuned config (knip.json) and a CI gate
in check.yml, plus the dead-code and dependency cleanup it surfaced. The
unused-export/type/duplicate rules are disabled so exporting an unused
symbol is allowed.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 22:11:48 +00:00
Matt FiddamanGitHubautofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* [AI] Replace vite-plugin-peggy-loader with in-repo Peggy plugin
Drop the third-party vite-plugin-peggy-loader dependency in favor of a
small in-repo Vite plugin (packages/loot-core/scripts/peggy.mts) that
compiles .pegjs grammars using the existing peggy dependency. Wire it
into the loot-core and api vite/vitest configs, and remove the now-dead
loader from the component-library config (it imports no grammars).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Up3H4YR7L8Qb4UKxbasyMp
* [AI] Host the Peggy Vite plugin in a workspace package
Move the in-repo Peggy loader out of packages/loot-core/scripts and into a
dedicated private workspace package, @actual-app/vite-plugin-peggy, so the
loot-core and api configs reference it as a normal workspace dependency
instead of reaching across packages with ../loot-core relative imports.
The peggy dependency now lives with the plugin that uses it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Up3H4YR7L8Qb4UKxbasyMp
* [AI] Rename release note to match PR number
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Up3H4YR7L8Qb4UKxbasyMp
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Update bare button colors to use page color variables
* Refactor button text color variables in dark theme
Updated button text colors to use page text variables.
* Refactor button text color variables in light.css
Updated button text colors to use page text variables.
* Fix indentation for buttonBareText variable
* Update button text colors in midnight theme
* Refactor Titlebar component styles and props
Updated button text color and removed unnecessary color styles.
* Fix button text color styling in LoggedInUser component
* Correct color style in LoggedInUser Button
Fix color style assignment in Button component.
* Remove color prop from LoggedInUser component
Removed the 'color' prop from LoggedInUser component.
* [autofix.ci] apply automated fixes
* Update VRT screenshots
Auto-generated by VRT workflow
PR: #8267
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-06-19 20:44:33 +00:00
Matt FiddamanGitHubautofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* Add new CSS variables for text items in dark theme
* Add new CSS variables for table and sidebar items
* Add new CSS variables for table and sidebar items
* Update sidebar account style for updated state
* Enhance valueStyle with color for added items
* [autofix.ci] apply automated fixes
* Add new theme variables for table and sidebar
* Add color variables to added sync items
Add color variables for enhanced visibility of items.
* [AI] Apply added-row styling to transaction notes cell
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* [AI] Convert theme color TS modules to CSS files with CSS variables
Replace `palette.ts` and `themes/{light,dark,midnight}.ts` with plain CSS
files that declare the same variables directly via `:root` blocks. The
palette becomes `--palette-*` variables; each theme defines `--color-*`
variables referencing those (or other `--color-*` for intra-theme aliases).
`theme.tsx` and Storybook's `preview.tsx` now import each CSS file as a
string via Vite's `?inline` query and render two `<style>` tags (palette +
active theme) instead of building the variable declarations at runtime
from a TS object.
Auto/dark-preference selection, `prefers-color-scheme` listening, the
custom-theme baseTheme override, and the `CustomThemeStyle` override layer
are all preserved.
* [AI] Move theme CSS files to component-library
Move palette.css and themes/{light,dark,midnight}.css from desktop-client's
style/ directory into component-library at src/themes/, and add explicit
package.json exports for each. desktop-client's theme.tsx now imports them
via `@actual-app/components/themes/*.css?inline`, and Storybook's
preview.tsx uses a normal relative path inside its own package instead of
reaching across the monorepo boundary.
* [AI] Minimize theme.tsx rename churn
Keep the original variable names — `themes[*].colors`, `themeColors` state,
`lightColors` / `darkColors` locals, and `getBaseThemeColors` — even though
they now hold CSS strings rather than color objects. Limits the diff to the
import changes, the state type, and the render path.
* [AI] Add release note for theme CSS conversion
---------
Co-authored-by: Claude <noreply@anthropic.com>
* [AI] Enable subpath imports across all packages
Generalize the prefer-subpath-imports ESLint rule to work with any
package (not just loot-core) and enable it globally. Add subpath import
mappings to cli, component-library, and sync-server package.json files.
Auto-fix all backtracked relative imports to use #-prefixed subpath
imports.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Add release notes for #7462
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Fix mock specifiers in accounts.test.ts to use aliased imports
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
* [AI] Fix mock specifiers in query.test.ts to use aliased imports
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
* [AI] Fix ESLint rule to properly validate src/ directory paths
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
* [AI] Add publishConfig.imports for sync-server to remap aliases to build directory
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
* [AI] Consolidate loot-core connection: default web path, electron split, drop .browser
* [autofix.ci] apply automated fixes
* [AI] Replace browser-preload .browser extension with package.json subpath imports
Use the imports field in desktop-client/package.json with conditional
resolution (electron → empty stub, default → real implementation) to
eliminate the last .browser file extension from the codebase.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Refactor connection imports to use @actual-app/core
* Implement connection mock for desktop-client tests and update import path
* [AI] Fix formatting and update imports after master merge
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Fix connection mock in TransactionsTable tests and use electron-renderer condition
Wire up the manual connection mock for TransactionsTable tests since the
__mocks__ directory was removed, and restore electron-renderer condition
in loot-core package.json exports.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [autofix.ci] apply automated fixes
* [AI] Remove redundant resolveExtensions from vite configs
These arrays were identical to Vite's built-in default and served no purpose.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Remove remaining resolveExtensions from vite/vitest configs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Fix build failures: update browser-preload import path and condition
- Change loot-core/shared/platform to @actual-app/core/shared/platform
- Use electron-renderer condition for #browser-preload to match vite resolve
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* [AI] Remove redundant resolveExtensions from api and loot-core desktop configs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Remove '*.browser.ts' extension and alias resolutions
Removed the special '*.browser.ts' file extension and file resolutions via alias, preferring conditions.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 21:32:51 +00:00
James SkinnerGitHubautofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* 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
* [AI] Remove development theme
Delete the development theme that was only available in non-production
environments. Removes the theme file, its registration in the theme
registry, type definitions, preference validation, ThemeSelector icon
mapping, and Storybook configuration.
https://claude.ai/code/session_01A1aEippeWppuwoRSCBPwby
* Add release notes for PR #7232
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* [AI] Remove @actual-app/crdt Vite aliases and redundant config
* Release notes
* Enhance CRDT package configuration and clean up Vite settings
* Added `publishConfig` to `crdt/package.json` to specify exports for types and default files.
* Removed unused `crdtDir` references from `vite.config.ts` and `vite.desktop.config.ts` to streamline configuration.
* [AI] Switch typecheck from tsc to tsgo and fix Menu type narrowing
* [autofix.ci] apply automated fixes
* Add .gitignore for dist directory, update typecheck script in package.json to use -b flag, and remove noEmit option from tsconfig.json files in ci-actions and desktop-electron packages. Introduce typesVersions in loot-core package.json for improved type handling.
* Refactor SelectedTransactionsButton to improve type safety and readability. Updated items prop to use spread operator for conditional rendering of menu items, ensuring proper type annotations with MenuItem. This change enhances the clarity of the component's structure and maintains TypeScript compliance.
* Update tsconfig.json in desktop-electron package to maintain consistent formatting for plugins section. No functional changes made.
* [autofix.ci] apply automated fixes
* Update package.json and yarn.lock to add TypeScript 5.8.0 dependency. Adjust typesVersions in loot-core package.json for improved type handling. Enhance tsconfig.json in sync-server package to enable strictFunctionTypes for better type safety.
* Enhance tsconfig.json in ci-actions package by adding composite option for improved project references and build performance.
* [AI] Revert typescript to 5.9.3 for ts-node compatibility
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
* [AI] Update yarn.lock after TypeScript version change
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
* Refactor Menu component for improved type safety and readability. Updated type assertions for Menu.line and Menu.label, simplified type checks in filtering and selection logic, and enhanced conditional rendering of menu items. This change ensures better TypeScript compliance and maintains clarity in the component's structure.
* Refactor Select and OpenIdForm components to improve type safety and simplify logic. Updated item mapping to handle Menu.line more effectively, enhancing clarity in selection processes. Adjusted SelectedTransactionsButton to streamline item creation and improve readability.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Matiss Janis Aboltins <MatissJanis@users.noreply.github.com>
* [AI] Enable TypeScript composite project references across monorepo
- Add composite and declaration emit to all package tsconfigs
- Wire root and per-package project references in dependency order
- Replace cross-package include-based typing with referenced outputs
- Fix api TS5055 by emitting declarations to decl-output
- Add desktop-client alias for tests; fix oxlint import order in vite.config
- Add UsersState.data null type and openDatabase return type for strict emit
Co-authored-by: Cursor <cursoragent@cursor.com>
* Remove obsolete TypeScript configuration for API and update build script to emit declarations directly to the output directory. This streamlines the build process and ensures compatibility with the new project structure.
* Refactor TypeScript configuration in API package to remove obsolete decl-output directory and update build scripts. The changes streamline the build process by directing declaration outputs to the @types directory, ensuring better organization and compatibility with the new project structure.
* Add TypeScript declaration emission for loot-core in desktop-electron build process
* Refactor TypeScript configuration in API package to utilize composite references and streamline build scripts. Update include and exclude patterns for improved file management, ensuring better organization of declaration outputs and migration SQL files.
* Refactor TypeScript configuration in loot-core and desktop-client packages to streamline path management and remove obsolete dependencies. Update paths in tsconfig.json files for better organization and compatibility, and adjust yarn.lock to reflect changes in workspace dependencies.
* Update desktop-electron package to utilize loot-core as a workspace dependency. Adjust TypeScript import paths and tsconfig references for improved organization and compatibility across packages.
* Enhance Vite configuration for desktop-client to support Electron-specific conditions and update loot-core package.json to include Electron as a platform for client connection. This improves compatibility for Electron builds.
* Refactor TypeScript configuration across multiple packages to streamline path management. Update tsconfig.json files in root, api, and loot-core packages to improve import paths and maintain compatibility with internal typings.
* Update package dependencies and Vite configuration across component-library and desktop-client. Add vite-tsconfig-paths to component-library and remove it from desktop-client. Refactor Storybook preview file to include a TODO for future refactoring.
* Remove Node-specific path from loot-core package.json for client connection, streamlining platform configuration for Electron.
* Remove loot-core as a workspace dependency from desktop-electron package.json
* Update tsconfig.json to remove reference to desktop-client
---------
Co-authored-by: Cursor <cursoragent@cursor.com>