Commit Graph

58 Commits

Author SHA1 Message Date
Guillem Arias Fauste
0d32bb70ec chore(design-system): swap raw gray classes for semantic tokens across remaining views (#1655)
* chore(design-system): swap raw gray classes for semantic tokens across remaining views

Finalizes the raw-color sweep started in #1652 (settings) and continued
in #1654 (holdings). Covers accounts, budgets, chats, pages, imports,
provider integrations (mercury, lunchflow, sophtron, enable_banking,
coinstats), auth flows (password reset, MFA, registrations), shared
layouts, and selected DS component hover states. 35 files, ~56 line
changes.

Mappings (matching the patterns established in the prior sweeps):

- text-white bg-gray-900 hover:bg-gray-800 (with optional focus:ring-gray-900)
  -> text-inverse button-bg-primary hover:button-bg-primary-hover
  -> focus:ring-button-bg-primary
- text-gray-500 / 600 / 700 -> text-secondary
- text-gray-800 -> text-primary
- text-gray-400 -> text-subdued
- hover:text-gray-700 / hover:text-gray-100 -> hover:text-primary
- bg-gray-50 / 100 / 200 (standalone) -> bg-surface-inset
- bg-gray-500/5 -> bg-gray-tint-5
- bg-gray-500/10 -> bg-gray-tint-10
- bg-gray-900 (decorative active states) -> bg-inverse
- hover:bg-gray-50 / 100 (standalone) -> hover:bg-surface-inset
- hover:bg-gray-300 -> hover:bg-surface-inset-hover
- bg-white hover:bg-gray-100 -> bg-container hover:bg-container-hover
- border-gray-300 -> border-secondary
- focus:border-gray-200 -> focus:border-secondary
- focus-within:border-gray-900 -> focus-within:border-primary
- DS::Buttonish outline / ghost / icon hover:
  hover:bg-gray-100 theme-dark:hover:bg-gray-700
  -> hover:bg-container-inset-hover

Left intentionally raw, with rationale:

- bg-gray-300 / bg-gray-400 decorative dots and avatar circles. The
  raw value reads OK against both bg-container variants; no semantic
  "neutral indicator" token exists. Same pattern as #1652 / #1654.
- bg-gray-400/20 theme-dark:bg-gray-500/20 (onboardings/trial). Custom
  alpha tint with no equivalent token.
- bg-white theme-dark:bg-gray-700 (DS::Tabs active pill, budgets tabs).
  Custom tab-pill pattern; gray-700 in dark mode (one shade lighter
  than page bg-gray-900) is intentional for visibility.
- bg-gray-100 theme-dark:bg-gray-700 (DS::Toggle base bg). Closest
  match (bg-container-inset-hover) is semantically a hover state.
- DS::Buttonish secondary variant gray-200/300/700/600 pattern. Same
  pattern as #1654 holdings; needs button-bg-secondary-strong from
  that PR. Will swap in a follow-up after #1654 merges.
- disabled:bg-gray-500 theme-dark:disabled:bg-gray-400 on inverse
  buttons (DS::Buttonish primary, enable_banking, coinstats). Custom
  disabled state for the inverse pair; no token.
- text-gray-300 SVG stroke (shared/_progress_circle).
- bg-white text-gray-900 (layouts/print). Print contexts intentionally
  light regardless of theme.
- bg-gray-800 / border-gray-700 / text-white / hover:text-gray-100
  (impersonation_sessions/_super_admin_bar). Admin overlay styled to
  remain dark in both modes; not a theme-aware component.

Files covered by other in-flight PRs were skipped to avoid rebase
conflicts: chats/_ai_consent's fg-inverse swap (#1626), shared/_text_tooltip
and shared/_money_field tooltip pills (#1626), investments/_value_tooltip
(#1626), components/DS/tooltip (#1626).

* fix(design-system): keep changelog avatar text raw to preserve dark-mode contrast

The changelog avatar fallback (when @release_notes[:avatar] is missing)
sits inside the "decorative + raw" exception list — bg-gray-300 stays
fixed across themes since no semantic neutral-indicator token exists.

The earlier sweep partially themed the pair: bg-gray-300 stayed raw but
text-gray-600 became text-secondary. text-secondary resolves to gray-300
in dark mode, which matches the bg → text became invisible against its
own background.

Reverting only the text class to text-gray-600 restores the original
fixed-light placeholder behavior. Both classes raw, both themes
readable.

* fix(design-system): address review feedback on raw-color-sweep-finalize

Six issues caught by CodeRabbit + Codex review:

1. focus:ring-button-bg-primary silently emits no CSS (×6 files).
   button-bg-primary is a custom @utility, not a theme color, so Tailwind's
   ring-{name} resolution finds no --color-button-bg-primary. Replaces with
   focus:ring-gray-900 theme-dark:focus:ring-white — same color flip as the
   button bg, but resolved through theme colors so the ring actually renders.
   Files: lunchflow/mercury/sophtron _api_error + _setup_required, coinstats_items/new.

2. accounts/show/_activity.html.erb: focus-within:ring-gray-100 was dead
   (no ring-width on the parent). Removed.

3. import/confirms/show.html.erb: uniform hover:bg-surface-inset-hover
   applied to both active and inactive step indicators created a jarring
   dark-to-light flip on the active step (bg-inverse → bg-surface-inset-hover).
   Now hover follows the resting state: active uses hover:bg-inverse-hover,
   inactive uses hover:bg-surface-inset-hover.

4. password_resets/new.html.erb: bg-white left raw alongside the migrated
   hover:bg-surface-inset. Swapped to bg-container so dark mode flips properly.

5. registrations/new.html.erb + password_validator_controller.js: view now
   uses bg-surface-inset on password strength block lines, but the Stimulus
   controller still toggled bg-gray-200 on validate. Updated controller to
   add/remove bg-surface-inset matching the view, so unmet states reset to
   the tokenized class instead of leaving raw gray-200 stuck on the element.
2026-05-04 21:47:01 +02:00
Guillem Arias Fauste
99844c1b90 chore(design-system): swap raw gray classes for semantic tokens in holdings/ (#1654)
* chore(design-system): swap raw gray classes for semantic tokens in holdings/

Continues the raw-color sweep on the holdings/ domain plus the related
account activity feed component. 11 occurrences across 5 files.

Token additions:

- button-bg-secondary-strong (gray-200 / gray-700) and -hover (gray-300 /
  gray-600). Holdings CTAs (Add Trade, Add Holding, Edit Cost Basis,
  Sync Prices, etc.) used a hand-rolled "secondary-strong" pattern that
  doesn't match the existing button-bg-secondary token (which is gray-50
  / gray-700, much subtler). Adding the strong variant preserves the
  intentional visual weight of these CTAs and gives future PRs a name
  to reuse.
- $version bump 1.0.0 -> 1.1.0 (additive).

Mappings:

- 8x text-primary bg-gray-200 hover:bg-gray-300 theme-dark:bg-gray-700
  theme-dark:hover:bg-gray-600 (holdings/show + sync_prices +
  cost_basis_cell)
  -> text-primary button-bg-secondary-strong hover:button-bg-secondary-strong-hover
- 1x bg-gray-50 theme-dark:bg-gray-700 hover:bg-gray-100
  theme-dark:hover:bg-gray-600 (holdings/index search button)
  -> button-bg-secondary hover:button-bg-secondary-hover
- 1x hover:bg-gray-100 theme-dark:hover:bg-gray-700 (cost_basis_cell
  hover row)
  -> hover:bg-container-inset-hover
- 1x focus-within:border-gray-900 (activity_feed search wrapper)
  -> focus-within:border-primary

Left intentionally:

- bg-gray-300 status indicator dot in show.html.erb (same pattern as
  the settings pilot; no semantic equivalent for "neutral inactive
  indicator" yet).
- bg-gray-700 in _missing_price_tooltip.html.erb (already fixed in
  PR #1626; would conflict on rebase).
- focus-within:ring-gray-100 (subtle effect that works in both modes;
  ring-color tokens are a separate concern).

* chore(design-system): bump $version to 2.1.0 for additive token additions

Per the design tokens semver contract: PR #1626 already bumped to 2.0.0
(major / breaking when fg-* utilities were removed). This PR adds
button-bg-secondary-strong + hover without removing or changing existing
tokens, so the correct bump is minor (2.0.0 → 2.1.0).

Spotted by CodeRabbit on the rebased branch.

* fix(design-system): drop dead focus-within:ring-gray-100 on activity feed search

The focus-within:ring-gray-100 class only sets --tw-ring-color, but the
parent has no ring-width utility, so it produces no visible ring — dead
code from before the focus-within:border-primary swap landed.

Same issue spotted on app/views/accounts/show/_activity.html.erb in the
finalize sweep PR; applying the equivalent fix here for the holdings
activity feed component.

---------

Signed-off-by: Guillem Arias Fauste <gariasf@proton.me>
2026-05-04 21:44:47 +02:00
Guillem Arias Fauste
2bcdf6c554 fix(design-system): replace undefined utility classes and broken /N modifiers (#1660)
* fix(design-system): replace undefined utility classes and broken /N modifiers

Audit of class-name resolution in views surfaced two related silent
failures across ~17 files:

1. Class names that don't exist anywhere in the design system. Tailwind
   silently drops them and the element renders with no CSS for that
   property.
   - bg-primary (and bg-primary/5, /10, /90): never defined as a
     custom utility, no --color-primary in @theme. Used as a CTA bg
     in 8 places, all rendered transparent.
   - text-inverted: typo of text-inverse.
   - text-primary-foreground: shadcn/Radix vocabulary, not in our
     token system.
   - bg-accent / border-accent / text-accent: same shadcn vocabulary;
     not defined.

2. Slash modifier (/N) used on custom @utility blocks. Modifiers only
   resolve on Tailwind theme colors (anything in tokens.json color.*).
   Custom @utility blocks compile to static @apply statements and
   silently drop the /N variant. Affected uses:
   - border-surface-inset/50 across provider account selectors.
   - border-secondary/30, /40 in admin SSO form and simplefin setup.
   - bg-surface-inset/30, /40 in settings preferences and simplefin.

Fixes:

| From                                              | To                                                  |
|---------------------------------------------------|------------------------------------------------------|
| bg-primary text-white (and similar primary CTAs)  | button-bg-primary text-inverse                      |
| bg-primary text-primary-foreground (badges)       | button-bg-primary text-inverse                      |
| bg-primary text-inverted (typo)                   | button-bg-primary text-inverse                      |
| bg-primary text-primary (broken active pill)      | bg-inverse text-inverse                             |
| bg-primary (status dot)                           | bg-inverse                                          |
| bg-primary/5, bg-primary/10 (subtle accent bg)    | bg-gray-tint-5, bg-gray-tint-10                     |
| hover:bg-primary/90                               | hover:button-bg-primary-hover                       |
| border-accent bg-accent/10 text-accent (badges)   | border-secondary bg-surface-inset text-secondary    |
| border-surface-inset/50                           | border-secondary                                     |
| border-secondary/30, /40                          | border-tertiary                                      |
| bg-surface-inset/30                               | bg-surface-inset (full strength)                     |
| bg-surface-inset/40                               | bg-container-inset                                   |

Also documents the alpha-modifier limitation in design/tokens/README.md
under a new "Alpha modifiers in views (/N syntax)" section, with the
opacity-N convention for custom utilities and a note that the
gray-tint-5 / gray-tint-10 family (and similar pre-resolved tints) are
theme colors and accept /N modifiers natively.

The accent-badge mapping uses neutral semantics for now. A dedicated
brand-accent token (text-link-tint-10 etc.) is worth considering as a
follow-up if the "highlighted metadata badge" pattern recurs.

* fix(design-system): replace undefined divide-primary / divide-secondary with alpha tokens

Same class of bug as the rest of this PR: divide-{name} requires the
name to be a theme color (i.e. expose --color-{name}), and our custom
@utility utilities (primary, secondary, etc.) do not. Tailwind silently
drops the unrecognized class and rows render with no separator.

Spotted six instances during the visual audit:

- admin/users/index.html.erb (×2): users table + pending invitations
- admin/sso_providers/index.html.erb (×2): configured + legacy lists
- transactions/categorizes/_transaction_list.html.erb: categorize sidebar
- settings/preferences/show.html.erb: divide-secondary/60 (also broken)

Swapped to the alpha-black/white pattern already used elsewhere in the
codebase (imports/cleans/show, transactions/_summary, etc.):

  divide-y divide-primary
  -> divide-y divide-alpha-black-200 theme-dark:divide-alpha-white-200

  divide-y divide-secondary/60
  -> divide-y divide-alpha-black-100 theme-dark:divide-alpha-white-100

The lighter (-100) variant on the preferences list matches the original
intent of /60 (more subtle).
2026-05-04 21:40:17 +02:00
Guillem Arias Fauste
0fe1e06645 refactor(design-system): migrate fg-* utilities to text-* and remove namespace (#1626)
* refactor(design-system): migrate fg-* utilities to text-* and remove namespace

The design system carried two parallel namespaces for foreground colors:
text-* (canonical, ~2,000 uses) and fg-* (32 uses). Most fg-* tokens
were 1:1 duplicates of a text-* counterpart. fg-gray was nearly
identical to text-secondary, with a one-step shade difference in dark
mode.

This PR migrates all 32 usages to their text-* equivalents and removes
the fg-* block from the design tokens. Closes #1606.

Mapping:
- fg-inverse  -> text-inverse  (20 usages, identical light/dark values)
- fg-gray     -> text-secondary (7 usages; light values match, dark is
                                 one step lighter: gray-300 vs gray-400)
- fg-primary  -> text-primary  (3 usages, identical values)
- fg-subdued  -> text-subdued  (2 usages, identical values)

The four other fg-* tokens (fg-contrast, fg-primary-variant,
fg-secondary, fg-secondary-variant) had zero usages despite being
defined; they are removed without replacement.

JSON / build:
- design/tokens/sure.tokens.json: $version 1.0.0 -> 2.0.0 (breaking
  schema change per the policy added in #1620). 8 fg-* token
  definitions removed.
- button-bg-ghost-hover's dark value still references "fg-inverse"
  internally; rewritten to "bg-gray-800 text-inverse" so the cleanup
  doesn't break that utility.
- _generated.css regenerated. 42 utility blocks now (was 50).

Lookbook tokens preview:
- The Text & foregrounds section dropped its split between text-*
  (canonical) and fg-* (legacy). Now a single section listing the
  five text-* utilities. The "(legacy)" framing is gone since there's
  no legacy left.

README:
- design/tokens/README.md's button-bg-ghost-hover edge-case example
  updated to reflect the new "bg-gray-800 text-inverse" dark value.

Visual review needed in dark mode:
- Anywhere icons use the application_helper#icon helper with
  color: "default" (most icons in the app). The default class moved
  from fg-gray (gray-400 dark) to text-secondary (gray-300 dark), so
  default-color icons render slightly lighter in dark mode.
- DS::Buttonish icons in secondary buttons (same shade shift).
- DS::Link icons (same).
- Time series chart axes (same).
- All tooltips, account add flow, settings hostings buttons,
  invitations, AI consent, family export, danger-zone buttons --
  these used fg-inverse, which is identical to text-inverse, so no
  visual change expected.

* fix(design-system): use inverse pair on tooltips for readable dark mode

* fix(lookbook): use semantic tokens in menu preview header text

* fix(lookbook): set text-primary on layout body so previews inherit theme

* fix(design-system): keep shadows dark-toned in dark mode

Inverting shadows to white|8% on dark surfaces produces a halo
effect rather than an elevation cue, and stacks redundantly with
the alpha-white 1px ring already in shadow-border-*.

Switch dark-mode shadows to black at progressively higher alpha
(25%/30%/35%/40%/50% for xs..xl) so they read as actual cast
shadows on near-black surfaces. Surface-tint differences and the
existing alpha-white border ring continue to handle elevation
hierarchy and edge definition.

Approach matches Material 3, Apple HIG, IBM Carbon, Refactoring UI,
and the dark-mode shadows used in Linear/Vercel/Stripe.

* fix(design-system): set text-primary on DS::Dialog element

Browser UA stylesheets apply color: black directly to <dialog>,
which overrides ancestor inheritance even when a body or html
ancestor sets a theme-aware color. Unstyled child content then
renders black regardless of theme.

Setting text-primary on the dialog element itself defeats the UA
override and lets descendants inherit the semantic token.

* fix(lookbook): use shadow css vars in effects preview so dark theme renders

* Revert "fix(design-system): keep shadows dark-toned in dark mode"

This reverts commit 3e9d76ed0b.

* fix(design-system): use opacity-70 instead of text-inverse/70 in value tooltip

The custom @utility text-inverse expands to @apply text-white and
isn't modifier-aware, so text-inverse/70 produced no CSS at all and
the muted labels fell through to inherited color (invisible on the
white pill in dark mode).

Replace with text-inverse + opacity-70. Same visual effect, works
with the existing utility definition.
2026-05-04 00:50:52 +02:00
Copilot
3199c9b76d Prevent long category labels from overflowing or crowding adjacent controls (#1498)
* Initial plan

* Fix category delete dialog dropdown overflow

Agent-Logs-Url: https://github.com/we-promise/sure/sessions/200da7a4-fd59-4ae4-a709-f631ccf21e8c

Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com>

* Tighten category deletion regression test

Agent-Logs-Url: https://github.com/we-promise/sure/sessions/200da7a4-fd59-4ae4-a709-f631ccf21e8c

Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com>

* Fix deletion button text overflow

Agent-Logs-Url: https://github.com/we-promise/sure/sessions/e802e01f-079e-4322-ba03-b222ab5d4b84

Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com>

* Preserve category menu spacing on mobile

Agent-Logs-Url: https://github.com/we-promise/sure/sessions/74b5dd1e-7935-4356-806a-759bff911930

Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com>

* Prevent account activity label overlap on mobile

Agent-Logs-Url: https://github.com/we-promise/sure/sessions/e94027d6-e230-44c8-99a1-6e5645bec82b

Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com>

* Fix wide account activity category overflow

Agent-Logs-Url: https://github.com/we-promise/sure/sessions/4ad79894-2935-47a3-8d37-037e2bd14376

Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com>

* Linter

* Fix flaky system tests in CI

Agent-Logs-Url: https://github.com/we-promise/sure/sessions/3507447f-363f-4759-807c-c62a2858d270

Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com>

* Reset system test viewport between tests

Agent-Logs-Url: https://github.com/we-promise/sure/sessions/357a43b1-11c5-49be-972d-0592a37d97b1

Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-04-19 18:40:50 +02:00
soky srm
e40811b1ee Add improvements from security providers to FX providers also (#1445)
* FIX prefer provider rate always

- add debugging also

* Move logic from securities over

* FIXes

* Review fixes

* Update provided.rb

---------

Signed-off-by: soky srm <sokysrm@gmail.com>
2026-04-13 00:51:23 +02:00
Pedro J. Aramburu
f699660479 Add exchange rate feature with multi-currency transactions and transfers support (#1099)
Co-authored-by: Pedro J. Aramburu <pedro@joakin.dev>
2026-04-08 21:05:58 +02:00
Tao Chen
2658c36b05 feat(select): improve merchant dropdown behavior and placement controls (#1364)
* feat(select): improve merchant dropdown behavior and placement controls

 - add configurable menu_placement strategy to DS::Select (auto/down/up) with safe normalization
forward menu_placement through StyledFormBuilder#collection_select
 - force Merchant dropdown to open downward in transaction create and editor forms
 - fix select option/search text contrast by applying text-primary in DS select menu
 - prevent form jump on open by scrolling only inside dropdown content instead of using scrollIntoView
 - clamp internal dropdown scroll to valid bounds for stability
- refactor select controller placement logic for readability (placementMode, clamp) without changing behavior

* set menu_placement=auto for metchant selector
2026-04-07 20:52:14 +02:00
Anas Limouri
a90f9b7317 Add CoinStats exchange portfolio sync and normalize linked investment charts (#1308)
* [FEATURE] Add CoinStats exchange portfolios and normalize linked investment charts

* [BUGFIX] Fix CoinStats PR regressions

* [BUGFIX] Fix CoinStats PR review findings

* [BUGFIX] Address follow-up CoinStats PR feedback

* [REFACTO] Extract CoinStats exchange account helpers

* [BUGFIX] Batch linked CoinStats chart normalization

* [BUGFIX] Fix CoinStats processor lint

---------

Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-04-01 20:25:06 +02:00
soky srm
560c9fbff3 Family sharing (#1272)
* Initial account sharing changes

* Update schema.rb

* Update schema.rb

* Change sharing UI to modal

* UX fixes and sharing controls

* Scope include in finances better

* Update totals.rb

* Update totals.rb

* Scope reports to finance account scope

* Update impersonation_sessions_controller_test.rb

* Review fixes

* Update schema.rb

* Update show.html.erb

* FIX db validation

* Refine edit permissions

* Review items

* Review

* Review

* Add application level helper

* Critical review

* Address remaining review items

* Fix modals

* more scoping

* linter

* small UI fix

* Fix: Sync broadcasts push unscoped balance sheet to all users

* Update sync_complete_event.rb

 The fix removes the sidebar broadcasts (which rendered unscoped account groups using family.balance_sheet without user context)
  along with the now-unused sidebar_targets, account_group, and family_balance_sheet private methods.

  The sidebar will still update correctly — when the sync completes, Family::SyncCompleteEvent#broadcast fires family.broadcast_refresh, which triggers a
  morph-based page refresh for each user with their own authenticated session, rendering properly scoped sidebar content.
2026-03-25 10:50:23 +01:00
soky srm
12d2f4e36d Provider merchants enhancement (#1254)
* Add AI merchant enhancement and dedup

* Enhancements

Add error if job is already running
add note that we also merge merchants

* Allow updating provider website

* Review fixes

* Update provider_merchant.rb

* Linter and fixes

* FIX transaction quick menu modal
2026-03-23 12:34:43 +01:00
soky srm
79e8469102 Merge pull request #1055 from ChakibMoMi/feature/privacy-mode
Add privacy mode to blur financial data across the app
2026-03-22 11:06:03 +01:00
sokiee
b6b093c578 Extend privacy headers
Extend privacy mode coverage to remaining financial views

  Transfers, trades, valuations, and holdings detail views were missing
  the privacy-sensitive class, leaving amounts visible when privacy mode
  was enabled. Also adds blur to the summary card partial (used by credit
  cards, loans, etc.), account chart balances, and time series chart
  containers (dashboard net worth and per-account charts).
2026-03-22 10:57:56 +01:00
sokiee
71c0735824 Linter 2026-03-22 10:48:54 +01:00
Yacine Kanzari
62a5255e02 Fix select is hidden inside dialog (#1196)
* Fix Select hidden inside Dialog

* Fix regression in Drawer
2026-03-21 15:14:11 +01:00
Serge L
5aa808e668 Feat: Add default user account and consolidate account actions in menu (#1130)
* feat: Add default account for manual transaction entries (#1061)

Allow users to designate a default account that auto-selects
in the transaction creation form. Also consolidates account list
actions (edit, link/unlink, enable/disable) into a meatball menu.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* - handle context menu width on mobile
- restrict default account to depository types only
- added FR, ES and DE i18n files

* - Add credit card accounts can also be used as default
- Moved logic into controller

* Scope context menu max-width to accounts menu only
- decouples the width constraint from the shared DS::Menu component by introducing an optional max_width param

* fix ci test and address issues raised by coderabbit and codex

* Address CodeRabbit review feedback

- Use .present? for institution_name guards to avoid empty UI artifacts
- Align "Set default" menu visibility with actual preselection eligibility
  (active + unlinked + supports_default?) to prevent drift between UI and model
- Keep disabled star visible when account is already default but now ineligible

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add eligible_for_transaction_default? predicate to Account model

Consolidates active + unlinked + supports_default? checks into a single
shared predicate used by the controller, view, and user model guard,
preventing a direct PATCH from bypassing UI eligibility rules.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Added "Unset default" option
Added negative test for default account
Removed duplicated logic for account.eligible_for_transaction_default

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 21:26:26 +01:00
Ellion Blessan
98ae6782dc feat(transaction): add support for file attachments using Active Storage (#713)
* feat(transaction): add support for file attachments using Active Storage

* feat(attachments): implement transaction attachments with upload, show, and delete functionality

* feat(attachments): enhance attachment upload functionality to support multiple files and improved error handling

* feat(attachments): add attachment upload form and display functionality in transaction views

* feat(attachments): implement attachment validation for count, size, and content type; enhance upload form with validation hints

* fix(attachments): use correct UI components

* feat(attachments): Implement Turbo Stream responses for creating and deleting transaction attachments.

* fix(attachments): include auth in activestorage controller

* test(attachments): add test coverage for turbostream and auth

* feat(attachments): extract strings to i18n

* fix(attachments): ensure only newly added attachments are purged when transaction validation fails.

* fix(attachments): validate attachment params

* refactor(attachments): use stimulus declarative actions

* fix(attachments): add auth for other representations

* refactor(attachments): use Browse component for attachment uploads

* fix(attachments): reject empty values on attachment upload

* fix(attachments): hide the upload form if reached max uploads

* fix(attachments): correctly purge only newly added attachments on upload failure

* fix(attachments): ensure attachment count limit is respected within a transaction lock

* fix(attachments): update attachment parameter handling to avoid `ParameterMissing` errors.

* fix(components): adjust icon_only logic for buttonish

---------

Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-03-14 23:56:27 +01:00
Alessio Cappa
0f78f54f90 New select component (#1071)
* feat: add new UI component to display dropdown select with filter

* feat: use new dropdown componet for category selection in transactions

* feat: improve dropdown controller

* feat: Add checkbox indicator to highlight selected element in list

* feat: add possibility to define dropdown without search

* feat: initial implementation of variants

* feat: Add default color for dropdown menu

* feat: add "icon" variant for dropdown

* refactor: component + controller refactoring

* refactor: view + component

* fix: adjust min width in selection for mobile

* feat: refactor collection_select method to use new filter dropdown component

* fix: compute fixed position for dropdown

* feat: controller improvements

* lint issues

* feat: add dot color if no icon is available

* refactor: controller refactor + update naming for variant from icon to logo

* fix: set width to 100% for select dropdown

* feat: add variant to collection_select in new transaction form

* fix: typo in placeholder value

* fix: add back include_blank property

* refactor: rename component from FilterDropdown to Select

* fix: translate placeholder and keep value_method and text_method

* fix: remove duplicate variable assignment

* fix: translate placeholder

* fix: verify color format

* fix: use right autocomplete value

* fix: selection issue + controller adjustments

* fix: move calls to startAutoUpdate and stopAutoUpdate

* Update app/javascript/controllers/select_controller.js

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Alessio Cappa <104093777+alessiocappa@users.noreply.github.com>

* fix: add aria-labels

* fix: pass html_options to DS::Select

* fix: unnecessary closing tag

* fix: use offsetvalue for position checks

* fix: use right classes for dropdown transitions

* include options[:prompt] in placeholder init

* fix: remove unused locale key

* fix: Emit a native change event after updating the input value.

* fix: Guard against negative maxHeight in constrained layouts.

* fix: Update test

* fix: lint issues

* Update test/system/transfers_test.rb

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Alessio Cappa <104093777+alessiocappa@users.noreply.github.com>

* Update test/system/transfers_test.rb

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Alessio Cappa <104093777+alessiocappa@users.noreply.github.com>

* refactor: move CSS class for button select form in maybe-design-system.css

---------

Signed-off-by: Alessio Cappa <104093777+alessiocappa@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-06 10:16:14 +01:00
Alessio Cappa
862d39dc3b fix: Remove additional padding from JS controller and add directly as a class (#1007) 2026-02-16 23:36:27 +01:00
StalkerSea
4cf25ada63 fix: restore drawer positioning for transaction modals on desktop (#857) (#896)
* feat: Add responsive dialog behavior for transaction modals

Add responsive option to DS::Dialog component that switches between:
- Mobile (< 1024px): Modal style (centered) with inline close button
- Desktop (≥ 1024px): Drawer style (right side panel) with header close button
Update transaction, transfer, holding, trade, and valuation views to use
responsive behavior, maintaining mobile experience while reverting desktop
to drawer style like budget categories.

Changes:
- app/components/DS/dialog.rb: Add responsive parameter and helper methods
- app/components/DS/dialog.html.erb: Apply responsive styling
- app/views/*/show.html.erb: Add responsive: true and hide close icons on mobile

* fix: Enhance close button accessibility in dialog components

* fix: Refactor dialog component to improve close button handling and accessibility
2026-02-11 00:02:15 +01:00
eureka928
329fe9832a Add Reset AI cache button to rules index
Add menu button with confirmation dialog to reset AI cache. Fix menu_item to safely handle non-standard confirm values.
2026-01-26 09:46:31 +01:00
LPW
c504ba9b99 Add security remapping for holdings with sync protection (#692)
* Add security remapping support to holdings

- Introduced `provider_security` tracking for holdings with schema updates.
- Implemented security remap/reset workflows in `Holding` model and UI.
- Updated routes, controllers, and tests to support new functionality.
- Enhanced client-side interaction with Stimulus controller for remapping.

# Conflicts:
#	app/components/UI/account/activity_feed.html.erb
#	db/schema.rb

* Refactor "New transaction" to "New activity" across UI and tests

- Updated localized strings, button labels, and ARIA attributes.
- Improved error handling in holdings' current price display.
- Scoped fallback queries in `provider_import_adapter` to prevent overwrites.
- Added safeguard for offline securities in price fetching logic.

* Update security remapping to merge holdings on collision by deleting duplicates

- Removed error handling for collisions in `remap_security!`.
- Added logic to merge holdings by deleting duplicates on conflicting dates.
- Modified associated test to validate merging behavior.

* Update security remapping to merge holdings on collision by combining qty and amount

- Modified `remap_security!` to merge holdings by summing `qty` and `amount` on conflicting dates.
- Adjusted logic to calculate `price` for merged holdings.
- Updated test to validate new merge behavior.

* Improve DOM handling in Turbo redirect action & enhance holdings merge logic

- Updated Turbo's custom `redirect` action to use the "replace" option for cleaner DOM updates without clearing the cache.
- Enhanced holdings merge logic to calculate weighted average cost basis during security remapping, ensuring more accurate cost_basis updates.

* Track provider_security_id during security updates to support reset workflows

* Fix provider tracking: guard nil ticker lookups and preserve merge attrs

- Guard fallback 1b lookup when security.ticker is blank to avoid matching NULL tickers
- Preserve external_id, provider_security_id, account_provider_id during collision merge

* Fix schema.rb version after merge (includes tax_treatment migration)

* fix: Rename migration to run after schema version

The migration 20260117000001 was skipped in CI because it had a timestamp
earlier than the schema version (2026_01_17_200000). CI loads schema.rb
directly and only runs migrations with versions after the schema version.

Renamed to 20260119000001 so it runs correctly.

* Update schema: remove Coinbase tables, add new fields and indexes

* Update schema: add back `tax_treatment` field with default value "taxable"

* Improve Turbo redirect action: use "replace" to avoid form submission in history

* Lock merged holdings to prevent provider overwrites and fix activity feed template indentation

* Refactor holdings transfer logic: enforce currency checks during collisions and enhance merge handling

---------

Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-01-23 12:54:55 +01:00
Number Eight
0c6d208ef2 feat: implement expandable view for cashflow sankey chart (#739)
* feat: implement expandable view for cashflow sankey chart

* refactor: migrate cashflow dialog sizing to tailwind utilities

* refactor: declarative draggable restore on cashflow dialog close

* refactor: localized title and use Tailwind utilities

* refactor: update dialog interaction especially on mobile

* refactor: add global expand text to localization

* fix: restore draggable immediately after dialog close

* Whitespace noise

---------

Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-01-23 09:52:15 +01:00
LPW
a83f70425f Add SnapTrade brokerage integration with full trade history support (#737)
* Introduce SnapTrade integration with models, migrations, views, and activity processing logic.

* Refactor SnapTrade activities processing: improve activity fetching flow, handle pending states, and update UI elements for enhanced user feedback.

* Update Brakeman ignore file to include intentional redirect for SnapTrade OAuth portal.

* Refactor SnapTrade models, views, and processing logic: add currency extraction helper, improve pending state handling, optimize migration checks, and enhance user feedback in UI.

* Remove encryption for SnapTrade `snaptrade_user_id`, as it is an identifier, not a secret.

* Introduce `SnaptradeConnectionCleanupJob` to asynchronously handle SnapTrade connection cleanup and improve i18n for SnapTrade item status messages.

* Update SnapTrade encryption: make `snaptrade_user_secret` non-deterministic to enhance security.

---------

Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-01-22 20:52:49 +01:00
LPW
dd991fa339 Add Coinbase exchange integration with CDP API support (#704)
* **Add Coinbase integration with item and account management**
- Creates migrations for `coinbase_items` and `coinbase_accounts`.
- Adds models, controllers, views, and background tasks to support account linking, syncing, and transaction handling.
- Implements Coinbase API client and adapter for seamless integration.
- Supports ActiveRecord encryption for secure credential storage.
- Adds UI components for provider setup, account management, and synchronization.

* Localize Coinbase-related UI strings, refine account linking for security, and add timeouts to Coinbase API requests.

* Localize Coinbase account handling to support native currencies (USD, EUR, GBP, etc.) across balances, trades, holdings, and transactions.

* Improve Coinbase processing with timezone-safe parsing, native currency support, and immediate holdings updates.

* Improve trend percentage formatting and enhance race condition handling for Coinbase account linking.

* Fix log message wording for orphan cleanup

* Ensure `selected_accounts` parameter is sanitized by rejecting blank entries.

* Add tests for Coinbase integration: account, item, and controller coverage

- Adds unit tests for `CoinbaseAccount` and `CoinbaseItem` models.
- Adds integration tests for `CoinbaseItemsController`.
- Introduces Stimulus `select-all` controller for UI checkbox handling.
- Localizes UI strings and logging for Coinbase integration.

* Update test fixtures to use consistent placeholder API keys and secrets

* Refine `coinbase_item` tests to ensure deterministic ordering and improve scope assertions.

* Integrate `SyncStats::Collector` into Coinbase syncer to streamline statistics collection and enhance consistency.

* Localize Coinbase sync status messages and improve sync summary test coverage.

* Update `CoinbaseItem` encryption: use deterministic encryption for `api_key` and standard for `api_secret`.

* fix schema drift

* Beta labels to lower expectations

---------

Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-01-21 22:56:39 +01:00
luckyPipewrench
4727a391a7 Refactor Investment Contributions category handling to use a centralized constant and streamline related logic. 2026-01-20 17:18:49 -05:00
luckyPipewrench
196d12466f Handle investment_contribution classification and update related logic. 2026-01-20 16:50:45 -05:00
LPW
f97ff419e8 Allow manual entry on linked accounts (#689)
* Update activity menu to conditionally display options for linked and investment accounts

* Update transaction test to reflect "New activity" menu change

---------

Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
2026-01-18 15:08:27 +01:00
LPW
c391ba2b23 Harden SimpleFIN sync: protect user data, fix stuck syncs, optimize API calls (#671)
* Implement entry protection flags for sync overwrites

- Added `user_modified` and `import_locked` flags to `entries` table to prevent provider sync from overwriting user-edited and imported data.
- Introduced backfill migration to mark existing entries based on conditions.
- Enhanced sync and processing logic to respect protection flags, track skipped entries, and log detailed stats.
- Updated UI to display skipped/protected entries and reasons in sync summaries.

* Localize error details summary text and adjust `sync_account_later` method placement

* Restored schema.rb

---------

Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
2026-01-16 12:34:06 +01:00
Alessio Cappa
fabd60c098 fix: PWA display issues (#653)
* feat: re-apply PWA changes from previous PR

* feat: adjust padding on pages for mobile

* fix: Add position relative to netWorthChart to avoid overflow issues on mobile

* fix: Add safe-area to progress bar

* feat: add missing class on html

* fix: Replace touch-none with overscroll-none
2026-01-15 12:53:35 +01:00
LPW
3658e812a8 Add pending transaction handling and duplicate reconciliation logic (#602)
* Add pending transaction handling and duplicate reconciliation logic

- Implemented logic to exclude pending transactions from budgets and analytics calculations.
- Introduced mechanisms for reconciling pending transactions with posted versions.
- Added duplicate detection with support for merging or dismissing matches.
- Updated transaction search filters to include a `status_filter` for pending/confirmed transactions.
- Introduced UI elements for reviewing and resolving duplicates.
- Enhanced `ProviderSyncSummary` with stats for reconciled and stale pending transactions.

* Refactor translation handling and enhance transaction and sync logic

- Moved hardcoded strings to locale files for improved translation support.
- Refined styling for duplicate transaction indicators and sync summaries.
- Improved logic for excluding stale pending transactions and updating timestamps on batch exclusion.
- Added unique IDs to status filters for better element targeting in UI.
- Optimized database queries to avoid N+1 issues in stale pending calculations.

* Add sync settings and enhance pending transaction handling

- Introduced a new "Sync Settings" section in hosting settings with UI to toggle inclusion of pending transactions.
- Updated handling of pending transactions with improved inference logic for `posted=0` and `transacted_at` in processors.
- Added priority order for pending transaction inclusion: explicit argument > environment variable > runtime configurable setting.
- Refactored settings and controllers to store updated sync preferences.

* Refactor sync settings and pending transaction reconciliation

- Extracted logic for pending transaction reconciliation, stale exclusion, and unmatched tracking into dedicated methods for better maintainability.
- Updated sync settings to infer defaults from multiple provider environment variables (`SIMPLEFIN_INCLUDE_PENDING`, `PLAID_INCLUDE_PENDING`).
- Refined UI and messaging to handle multi-provider configurations in sync settings.

# Conflicts:
#	app/models/simplefin_item/importer.rb

* Debounce transaction reconciliation during imports

- Added per-run reconciliation debouncing to prevent repeated scans for the same account during chunked history imports.
- Trimmed size of reconciliation stats to retain recent details only.
- Introduced error tracking for reconciliation steps to improve UI visibility of issues.

* Apply ABS() in pending transaction queries and improve error handling

- Updated pending transaction logic to use ABS() for consistent handling of negative amounts.
- Adjusted amount bounds calculations to ensure accuracy for both positive and negative values.
- Refined exception handling in `merge_duplicate` to log failures and update user alert.
- Replaced `Date.today` with `Date.current` in tests to ensure timezone consistency.
- Minor optimization to avoid COUNT queries by loading limited records directly.

* Improve error handling in duplicate suggestion and dismissal logic

- Added exception handling for `store_duplicate_suggestion` to log failures and prevent crashes during fuzzy/low-confidence matches.
- Enhanced `dismiss_duplicate` action to handle `ActiveRecord::RecordInvalid` and display appropriate user alerts.

---------

Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com>
2026-01-10 20:11:00 +01:00
LPW
140ea78b0e Add global sync summary component for all providers (#588)
* Add shared sync statistics collection and provider sync summary UI

- Introduced `SyncStats::Collector` concern to centralize sync statistics logic, including account, transaction, holdings, and health stats collection.
- Added collapsible `ProviderSyncSummary` component for displaying sync summaries across providers.
- Updated syncers (e.g., `LunchflowItem::Syncer`) to use the shared collector methods for consistent stats calculation.
- Added rake tasks under `dev:sync_stats` for testing and development purposes, including fake stats generation with optional issues.
- Enhanced provider-specific views to include sync summaries using the new shared component.

* Refactor `ProviderSyncSummary` to improve maintainability

- Extracted `severity_color_class` to simplify severity-to-CSS mapping.
- Replaced `holdings_label` with `holdings_label_key` for streamlined localization.
- Updated locale file to separate `found` and `processed` translations for clarity.

---------

Signed-off-by: Juan José Mata <juanjo.mata@gmail.com>
Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2026-01-09 19:26:37 +01:00
soky srm
ca4fb7995c Implement holdings for lunch flow (#590)
* Implement holdings for lunch flow

* Implement holdings function call
2026-01-09 13:14:14 +01:00
Dylan Corrales
3b1495422a DS::Menu: Prevent scrolling page content (#520) 2026-01-05 22:17:45 +01:00
Alessio Cappa
b3af8bf1ae Transactions & Activities pages improvements (#452)
* feat: Add toggle on mobile to show/hide checkboxes in transaction page

* fix: Add multi-select toggle also in activities page. Make JS controller compatible also in this view.

* feat: Add category in mobile view

* feat: Add mobile layout for transaction categories

* feat: Add margin for pagination on mobile

* fix: Ensure category exists when displaying the name

* fix: Adjust mobile paddings

* fix: Display "uncategorized" label if no category is set

* fix: Expand transaction name/subtitle

* feat: Add merchant name on desktop view

* feat: Move merchant name before account name

* fix: Add class to hide merchant on mobile

* feat: Add merchant logo on mobile

* fix: add pointer-events-none to merchant image on mobile view

* feat: toggle header checkbox in transaction page when button is clicked

* Remove unnecessary CSS class

* Remove duplicate CSS class

* Remove wrong Enable Banking logo URL

* Update app/views/transactions/_transaction.html.erb

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Alessio Cappa <104093777+alessiocappa@users.noreply.github.com>

* Revert "Update app/views/transactions/_transaction.html.erb"

This reverts commit 9766c50a1d.

* Add translation for Loan Payment/Transfer

* Apply review comments

* Add accessible name for toggle based on review comments

* Use border instead of border-1 class

* Apply review comments

* Missing l10n key

---------

Signed-off-by: Alessio Cappa <104093777+alessiocappa@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2025-12-24 01:57:16 +01:00
soky srm
91a91c3834 Improvements (#379)
* Improvements

- Fix button visibility in reports on light theme
- Unify logic for provider syncs
- Add default option is to skip accounts linking ( no op default )

* Stability fixes and UX improvements

* FIX add unlinking when deleting lunch flow connection as well

* Wrap updates in transaction

* Some more improvements

* FIX proper provider setup check

* Make provider section collapsible

* Fix balance calculation

* Restore focus ring

* Use browser default focus

* Fix lunch flow balance for credit cards
2025-11-25 20:21:29 +01:00
Dylan Corrales
b533a9b9b7 PWA: DS::Menu - Place below button and center (#291)
* PWA: Floating Menu - Place below button and center

* PWA: menu_controller.js: null safety checks
2025-11-08 13:50:42 +01:00
Albert Solà
f42e6e373b Added translations for ca - Catalan (#238)
* Add CA locales for models

* Add CA locales for views

* Use translations in activity feed

* Additional CA locales

* Fix typo

---------

Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
2025-10-26 17:50:31 +01:00
Zach Gollwitzer
f7f6ebb091 Use new balance components in activity feed (#2511)
* Balance reconcilations with new components

* Fix materializer and test assumptions

* Fix investment valuation calculations and recon display

* Lint fixes

* Balance series uses new component fields
2025-07-23 18:15:14 -04:00
Zach Gollwitzer
321a343df4 Fix title for activity feed 2025-07-19 13:22:56 -04:00
Zach Gollwitzer
e8eb32d2ae Start and end balance breakdown in activity view (#2466)
* Initial data objects

* Remove trend calculator

* Fill in balance reconciliation for entry group

* Initial tooltip component

* Balance trends in activity view

* Lint fixes

* trade partial alignment fix

* Tweaks to balance calculation to acknowledge holdings value better

* More lint fixes

* Bump brakeman dep

* Test fixes

* Remove unused class
2025-07-18 17:56:25 -04:00
Zach Gollwitzer
ab6fdbbb68 Component namespacing (#2463)
* [claudesquad] update from 'component-namespacing' on 18 Jul 25 07:23 EDT

* [claudesquad] update from 'component-namespacing' on 18 Jul 25 07:30 EDT

* Update stimulus controller references to use namespace

* Fix remaining tests
2025-07-18 08:30:00 -04:00
Zach Gollwitzer
8c97c9d31a Consolidate and simplify account pages (#2462)
* Remove ScrollFocusable

* Consolidate and simplify account pages

* Lint fixes

* Fix tab param initialization

* Remove stale files

* Remove stale route, make accountable routes clearer
2025-07-18 05:52:18 -04:00
Zach Gollwitzer
188126d402 Fix activity view "new" button styles 2025-07-10 15:30:22 -04:00
Zach Gollwitzer
662f2c04ce Multi-step account forms + clearer balance editing (#2427)
* Initial multi-step property form

* Improve form structure, add optional tooltip help icons to form fields

* Add basic inline alert component

* Clean up and improve property form lifecycle

* Implement Account status concept

* Lint fixes

* Remove whitespace

* Balance editing, scope updates for account

* Passing tests

* Fix brakeman warning

* Remove stale columns

* data constraint tweaks

* Redundant property
2025-07-03 09:33:07 -04:00
Zach Gollwitzer
4b50acff2b Replace sync spinners with pulse animation (#2413)
* Replace sync spinners with pulse animation

* Remove dev code
2025-06-25 16:51:30 -04:00
Alex Hatzenbuhler
5c82af0e8c Fix and improve chat title edit (#2285)
* Fix and improve chat title edit

* Put back background color

* use transparent
2025-05-23 15:31:08 -04:00
Alex Hatzenbuhler
443b834b46 Create shared ruler and standardize across views (#2240)
* Create shared ruler view

* Use collection rendering/spacer templates for rules, and new shared_ruler

* Use shared ruler for all the places a ruler is used

* Use shared ruler for imports and balance sheet

* Fix brakeman by using a static partial with a defined collection

* Update balance sheet
2025-05-20 15:13:18 -04:00
Zach Gollwitzer
10dd9e061a Improve account sync performance, handle concurrent market data syncing (#2236)
* PlaidConnectable concern

* Remove bad abstraction

* Put sync implementations in own concerns

* Sync strategies

* Move sync orchestration to Sync class

* Clean up sync class, add state machine

* Basic market data sync cron

* Fix price sync

* Improve sync window column names, add timestamps

* 30 day syncs by default

* Clean up market data methods

* Report high duplicate sync counts to Sentry

* Add sync states throughout app

* account tab session

* Persistent account tab selections

* Remove manual sleep

* Add migration to clear stale syncs on self hosted apps

* Tweak sync states

* Sync completion event broadcasts

* Fix timezones in tests

* Cleanup

* More cleanup

* Plaid item UI broadcasts for sync

* Fix account ID namespace conflict

* Sync broadcasters

* Smoother account sync refreshes

* Remove test sync delay
2025-05-15 10:19:56 -04:00
Alex Hatzenbuhler
c0267d5665 Use icon helper for all-the-things (#2191)
* Use icon helper for all-the-things

* Pass size and color to the icon from buttonish components directly
2025-05-06 12:08:18 -04:00