From cdce00c71ea160a4843adab7c90fd68a3674c9b7 Mon Sep 17 00:00:00 2001
From: Guillem Arias Fauste
Date: Wed, 20 May 2026 18:15:15 +0200
Subject: [PATCH] =?UTF-8?q?refactor(design-system):=20migrate=2038=20hand-?=
=?UTF-8?q?rolled=20provider=20buttons=20to=20DS::Button=20/=20DS::Link=20?=
=?UTF-8?q?(#1715=20=C2=A75=20part=20B)=20(#1860)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* refactor(design-system): migrate 9 hand-rolled buttons with orphan btn-- classes to DS::Button / DS::Link
Part of #1715 §5. The `btn`, `btn--primary`, `btn--outline`, `btn--ghost`,
`btn--sm` CSS classes have no backing styles anywhere in the codebase
(no .btn definition in app/assets/, no Bootstrap dependency). These
callsites have been rendering unstyled buttons / links since the
underlying CSS was last removed.
Migrate the 9 broken callsites:
- `app/views/transactions/show.html.erb` — duplicate-merge action
buttons (×2): `button_to ... class: "btn btn--primary btn--sm"` /
`class: "btn btn--outline btn--sm"` → DS::Button with href +
variant + size + `data: { turbo_method: :post }`.
- `app/views/snaptrade_items/select_existing_account.html.erb` —
"Go to Provider Settings" link → DS::Link primary sm.
- `app/views/indexa_capital_items/select_existing_account.html.erb` —
same pattern → DS::Link primary sm.
- `app/views/import/confirms/show.html.erb` — Publish button +
Cancel link → DS::Button primary full-width + DS::Link ghost
full-width.
- `app/views/simplefin_items/new.html.erb` — Cancel link
(`class: "btn"` only) + Connect submit → DS::Link secondary +
bare `f.submit` (already routes to DS::Button via
StyledFormBuilder).
- `app/views/settings/providers/_ibkr_panel.html.erb`,
`_snaptrade_panel.html.erb`,
`_indexa_capital_panel.html.erb` — strip the orphan
`class: "btn btn--primary"` from `f.submit` callers; the submit
is already a styled DS::Button via the form builder.
The next PR in this chain (Phase B) will tackle the larger inline-
button cluster (~29 files, 38 instances) — provider panels and
provider-item flows hand-rolling the same
`inline-flex items-center justify-center rounded-lg px-4 py-2
text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover
focus:outline-none focus:ring-2 focus:ring-primary transition-colors`
string.
* refactor(design-system): migrate 38 hand-rolled provider buttons to DS::Button / DS::Link (#1715 §5 part B)
Bulk sweep of the second cluster from §5. 29 files, 38 button
instances — each one hand-rolled the same long Tailwind string for
the primary action button:
inline-flex items-center justify-center rounded-lg px-4 py-2
text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover
focus:outline-none focus:ring-2 focus:ring-primary transition-colors
(some variations used `button-bg-primary hover:button-bg-primary-hover`
instead of `bg-inverse hover:bg-inverse-hover` — same intent).
Every instance is now a DS::Button / DS::Link with `variant: :primary`,
which:
- Picks up the new focus-ring + touch-target work from #1840 once
that merges.
- Stops duplicating the long Tailwind string across 29 files —
single source of truth in `DS::Buttonish::VARIANTS[:primary]`.
- Picks up consistent `aria-label` derivation for icon-only forms.
- Removes the misnamed `focus:ring-primary` (no token) — the new
ring comes from `base.css` automatically.
Migration patterns applied:
- `f.submit text, class: "inline-flex …"` inside `styled_form_with`
→ bare `<%= f.submit text %>`. StyledFormBuilder routes through
DS::Button.
- `link_to text, path, class: "inline-flex …"` → DS::Link primary.
- `button_to text, path, method: :X, class: "inline-flex …"` →
DS::Button with `href: path` and `data: { turbo_method: :X }`.
- `submit_tag text, class: "inline-flex …"` inside raw `form_with`
→ DS::Button with `type: :submit`.
Notable adjustments:
- `holdings/show.html.erb` — the form was `form_with` (not styled).
Switched to `styled_form_with` so `f.submit` routes through
DS::Button. `f.combobox` (hotwire_combobox) still works through
the styled builder.
- Two `link_to settings_providers_path` callsites in
`coinstats_items/new.html.erb` + `enable_banking_items/new.html.erb`
had `w-full inline-flex … hidden md:inline-flex` — the responsive
pair conflicted (both `inline-flex` and `hidden md:inline-flex`
on the same element). Migrated to `full_width: true` without the
responsive split; the buttons now render at all breakpoints
consistently. (Pre-existing copy-paste bug, fixed in passing.)
- `enable_banking_panel` add-connection button gained
`icon: "plus"` via the DS::Button API; the explicit `gap-2 …
icon "plus"` markup is now redundant.
Sibling buttons that don't match the primary spec (destructive
trash, secondary outline-bordered, button-bg-secondary-strong on
holdings/show.html.erb, etc.) are intentionally left alone — they
need their own audit pass once #1840 lands and the focus-ring
behavior on those variants is stable.
* fix(review): restore SimpleFIN submit styling + i18n provider_form label
- SimpleFIN new modal: switch form_with -> styled_form_with so f.submit
picks up the DS::Button render via styled builder (Codex #1860).
- _provider_form: replace hardcoded "Save and connect" with t(".save_and_connect")
and add scoped key under settings.providers.provider_form (CodeRabbit).
---
app/views/brex_items/_api_error.html.erb | 11 +++---
app/views/brex_items/_setup_required.html.erb | 11 +++---
app/views/brex_items/select_accounts.html.erb | 9 +++--
.../select_existing_account.html.erb | 9 +++--
app/views/coinstats_items/new.html.erb | 18 ++++-----
app/views/enable_banking_items/new.html.erb | 38 ++++++++++---------
app/views/holdings/show.html.erb | 6 +--
app/views/import/confirms/show.html.erb | 16 +++++++-
.../select_existing_account.html.erb | 8 +++-
app/views/lunchflow_items/_api_error.html.erb | 11 +++---
.../lunchflow_items/_setup_required.html.erb | 11 +++---
.../lunchflow_items/select_accounts.html.erb | 7 +++-
.../select_existing_account.html.erb | 7 +++-
app/views/mercury_items/_api_error.html.erb | 11 +++---
.../mercury_items/_setup_required.html.erb | 11 +++---
.../mercury_items/select_accounts.html.erb | 7 +++-
.../select_existing_account.html.erb | 7 +++-
app/views/pages/intro.html.erb | 6 ++-
.../select_existing_account.html.erb | 7 +++-
.../providers/_binance_panel.html.erb | 3 +-
.../settings/providers/_brex_panel.html.erb | 6 +--
.../providers/_coinbase_panel.html.erb | 3 +-
.../providers/_coinstats_panel.html.erb | 3 +-
.../providers/_enable_banking_panel.html.erb | 29 +++++++-------
.../settings/providers/_ibkr_panel.html.erb | 2 +-
.../providers/_indexa_capital_panel.html.erb | 2 +-
.../settings/providers/_kraken_panel.html.erb | 6 +--
.../providers/_lunchflow_panel.html.erb | 3 +-
.../providers/_mercury_panel.html.erb | 6 +--
.../providers/_provider_form.html.erb | 3 +-
.../providers/_simplefin_panel.html.erb | 3 +-
.../providers/_snaptrade_panel.html.erb | 3 +-
.../providers/_sophtron_panel.html.erb | 3 +-
.../_replacement_prompt.html.erb | 17 +++++----
app/views/simplefin_items/new.html.erb | 11 ++++--
.../select_existing_account.html.erb | 8 +++-
app/views/transactions/show.html.erb | 24 +++++++-----
config/locales/views/settings/en.yml | 2 +
38 files changed, 203 insertions(+), 145 deletions(-)
diff --git a/app/views/brex_items/_api_error.html.erb b/app/views/brex_items/_api_error.html.erb
index 8f05f813b..0cf49d068 100644
--- a/app/views/brex_items/_api_error.html.erb
+++ b/app/views/brex_items/_api_error.html.erb
@@ -24,11 +24,12 @@
- <%= link_to return_path.presence || settings_providers_path,
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 transition-colors",
- data: { turbo: false } do %>
- <%= t(".settings_link") %>
- <% end %>
+ <%= render DS::Link.new(
+ text: t(".settings_link"),
+ href: return_path.presence || settings_providers_path,
+ variant: :primary,
+ data: { turbo: false }
+ ) %>
<% end %>
diff --git a/app/views/brex_items/_setup_required.html.erb b/app/views/brex_items/_setup_required.html.erb
index cce66fce2..e6347142e 100644
--- a/app/views/brex_items/_setup_required.html.erb
+++ b/app/views/brex_items/_setup_required.html.erb
@@ -22,11 +22,12 @@
- <%= link_to settings_providers_path,
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 transition-colors",
- data: { turbo: false } do %>
- <%= t(".settings_link") %>
- <% end %>
+ <%= render DS::Link.new(
+ text: t(".settings_link"),
+ href: settings_providers_path,
+ variant: :primary,
+ data: { turbo: false }
+ ) %>
<% end %>
diff --git a/app/views/brex_items/select_accounts.html.erb b/app/views/brex_items/select_accounts.html.erb
index fdc3e25f9..7ca056eb0 100644
--- a/app/views/brex_items/select_accounts.html.erb
+++ b/app/views/brex_items/select_accounts.html.erb
@@ -48,9 +48,12 @@
<%= link_to t(".cancel"), @return_to || new_account_path,
class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-primary button-bg-secondary hover:button-bg-secondary-hover",
data: { turbo_frame: "_top" } %>
- <%= submit_tag t(".link_accounts"),
- disabled: !has_selectable,
- class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-inverse bg-inverse hover:bg-inverse-hover disabled:button-bg-disabled disabled:cursor-not-allowed" %>
+ <%= render DS::Button.new(
+ text: t(".link_accounts"),
+ variant: :primary,
+ type: :submit,
+ disabled: !has_selectable
+ ) %>
<% end %>
diff --git a/app/views/brex_items/select_existing_account.html.erb b/app/views/brex_items/select_existing_account.html.erb
index 734db5a1f..ddb681e7a 100644
--- a/app/views/brex_items/select_existing_account.html.erb
+++ b/app/views/brex_items/select_existing_account.html.erb
@@ -48,9 +48,12 @@
<%= link_to t(".cancel"), @return_to || accounts_path,
class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-primary button-bg-secondary hover:button-bg-secondary-hover",
data: { turbo_frame: "_top" } %>
- <%= submit_tag t(".link_account"),
- disabled: !has_selectable,
- class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-inverse bg-inverse hover:bg-inverse-hover disabled:button-bg-disabled disabled:cursor-not-allowed" %>
+ <%= render DS::Button.new(
+ text: t(".link_account"),
+ variant: :primary,
+ type: :submit,
+ disabled: !has_selectable
+ ) %>
<% end %>
diff --git a/app/views/coinstats_items/new.html.erb b/app/views/coinstats_items/new.html.erb
index 40b90570b..5d163f86e 100644
--- a/app/views/coinstats_items/new.html.erb
+++ b/app/views/coinstats_items/new.html.erb
@@ -53,8 +53,7 @@
<% end %>
- <%= form.submit t(".link_wallet_submit"),
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors" %>
+ <%= form.submit t(".link_wallet_submit") %>
<% end %>
@@ -90,8 +89,7 @@
- <%= form.submit t(".link_exchange_submit"),
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors" %>
+ <%= form.submit t(".link_exchange_submit") %>
<% end %>
@@ -115,11 +113,13 @@
- <%= link_to settings_providers_path,
- class: "w-full inline-flex items-center justify-center rounded-lg font-medium whitespace-nowrap rounded-lg hidden md:inline-flex px-3 py-2 text-sm text-inverse bg-inverse hover:bg-inverse-hover disabled:bg-gray-500 theme-dark:disabled:bg-gray-400",
- data: { turbo: false } do %>
- <%= t(".go_to_settings") %>
- <% end %>
+ <%= render DS::Link.new(
+ text: t(".go_to_settings"),
+ href: settings_providers_path,
+ variant: :primary,
+ full_width: true,
+ data: { turbo: false }
+ ) %>
<% end %>
diff --git a/app/views/enable_banking_items/new.html.erb b/app/views/enable_banking_items/new.html.erb
index 625579939..2f7b481e9 100644
--- a/app/views/enable_banking_items/new.html.erb
+++ b/app/views/enable_banking_items/new.html.erb
@@ -53,11 +53,13 @@
<%= t(".reconnect") %>
<% end %>
<% else %>
- <%= link_to select_bank_enable_banking_item_path(item),
- class: "inline-flex items-center justify-center rounded-lg px-3 py-1.5 text-xs font-medium text-inverse button-bg-primary hover:button-bg-primary-hover transition-colors",
- data: { turbo_frame: "modal" } do %>
- <%= t(".connect_bank") %>
- <% end %>
+ <%= render DS::Link.new(
+ text: t(".connect_bank"),
+ href: select_bank_enable_banking_item_path(item),
+ variant: :primary,
+ size: :sm,
+ data: { turbo_frame: "modal" }
+ ) %>
<% end %>
<%= button_to enable_banking_item_path(item),
@@ -73,13 +75,13 @@
<%# Add Connection button below the list - only show if we have a valid session to copy credentials from %>
<% if item_for_new_connection %>
- <%= button_to new_connection_enable_banking_item_path(item_for_new_connection),
- method: :post,
- class: "inline-flex items-center gap-2 justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover transition-colors",
- data: { turbo_frame: "modal" } do %>
- <%= icon "plus", size: "sm" %>
- <%= t(".add_connection") %>
- <% end %>
+ <%= render DS::Button.new(
+ text: t(".add_connection"),
+ icon: "plus",
+ href: new_connection_enable_banking_item_path(item_for_new_connection),
+ variant: :primary,
+ data: { turbo_method: :post, turbo_frame: "modal" }
+ ) %>
<% end %>
@@ -104,11 +106,13 @@
- <%= link_to settings_providers_path,
- class: "w-full inline-flex items-center justify-center rounded-lg font-medium whitespace-nowrap rounded-lg hidden md:inline-flex px-3 py-2 text-sm text-inverse bg-inverse hover:bg-inverse-hover disabled:bg-gray-500 theme-dark:disabled:bg-gray-400",
- data: { turbo: false } do %>
- <%= t(".go_to_provider_settings") %>
- <% end %>
+ <%= render DS::Link.new(
+ text: t(".go_to_provider_settings"),
+ href: settings_providers_path,
+ variant: :primary,
+ full_width: true,
+ data: { turbo: false }
+ ) %>
<% end %>
diff --git a/app/views/holdings/show.html.erb b/app/views/holdings/show.html.erb
index 153166c2d..e382fda31 100644
--- a/app/views/holdings/show.html.erb
+++ b/app/views/holdings/show.html.erb
@@ -58,7 +58,7 @@
<% if Security.providers.any? %>
- <%= form_with url: remap_security_holding_path(@holding), method: :patch, class: "space-y-3" do |f| %>
+ <%= styled_form_with url: remap_security_holding_path(@holding), method: :patch, class: "space-y-3" do |f| %>
<%= f.combobox :security_id,
securities_path(country_code: Current.family.country),
@@ -72,7 +72,7 @@
data-action="click->holding-security-remap#toggle">
<%= t(".cancel") %>
- <%= f.submit t(".remap_security"), class: "inline-flex items-center gap-1 px-3 py-2 rounded-lg text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover" %>
+ <%= f.submit t(".remap_security") %>
<% end %>
<% else %>
@@ -185,7 +185,7 @@
data-action="click->drawer-cost-basis#toggle">
<%= t("holdings.cost_basis_cell.cancel") %>
- <%= f.submit t("holdings.cost_basis_cell.save"), class: "inline-flex items-center gap-1 px-3 py-2 rounded-lg text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover" %>
+ <%= f.submit t("holdings.cost_basis_cell.save") %>
<% end %>
diff --git a/app/views/import/confirms/show.html.erb b/app/views/import/confirms/show.html.erb
index 1c89375be..8560b761d 100644
--- a/app/views/import/confirms/show.html.erb
+++ b/app/views/import/confirms/show.html.erb
@@ -31,8 +31,20 @@
- <%= button_to t("import.confirms.sure_import.publish_button"), publish_import_path(@import), method: :post, class: "btn btn--primary w-full", disabled: !@import.publishable? %>
- <%= link_to t("import.confirms.sure_import.cancel"), imports_path, class: "btn btn--ghost w-full text-center" %>
+ <%= render DS::Button.new(
+ text: t("import.confirms.sure_import.publish_button"),
+ href: publish_import_path(@import),
+ variant: :primary,
+ full_width: true,
+ disabled: !@import.publishable?,
+ data: { turbo_method: :post }
+ ) %>
+ <%= render DS::Link.new(
+ text: t("import.confirms.sure_import.cancel"),
+ href: imports_path,
+ variant: :ghost,
+ full_width: true
+ ) %>
<% else %>
diff --git a/app/views/indexa_capital_items/select_existing_account.html.erb b/app/views/indexa_capital_items/select_existing_account.html.erb
index 7b0f46764..bb6535672 100644
--- a/app/views/indexa_capital_items/select_existing_account.html.erb
+++ b/app/views/indexa_capital_items/select_existing_account.html.erb
@@ -14,7 +14,13 @@
<%= icon "alert-circle", class: "text-warning mx-auto mb-4", size: "lg" %>
<%= t("indexa_capital_items.select_existing_account.no_accounts") %>
<%= t("indexa_capital_items.select_existing_account.connect_hint") %>
- <%= link_to t("indexa_capital_items.select_existing_account.settings_link"), settings_providers_path, class: "btn btn--primary btn--sm mt-4" %>
+ <%= render DS::Link.new(
+ text: t("indexa_capital_items.select_existing_account.settings_link"),
+ href: settings_providers_path,
+ variant: :primary,
+ size: :sm,
+ class: "mt-4"
+ ) %>
<% else %>
diff --git a/app/views/lunchflow_items/_api_error.html.erb b/app/views/lunchflow_items/_api_error.html.erb
index 50050e35a..7a1e2c352 100644
--- a/app/views/lunchflow_items/_api_error.html.erb
+++ b/app/views/lunchflow_items/_api_error.html.erb
@@ -21,11 +21,12 @@
- <%= link_to settings_providers_path,
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors",
- data: { turbo: false } do %>
- <%= t(".check_provider_settings") %>
- <% end %>
+ <%= render DS::Link.new(
+ text: t(".check_provider_settings"),
+ href: settings_providers_path,
+ variant: :primary,
+ data: { turbo: false }
+ ) %>
<% end %>
diff --git a/app/views/lunchflow_items/_setup_required.html.erb b/app/views/lunchflow_items/_setup_required.html.erb
index 1773e81ef..f53dce376 100644
--- a/app/views/lunchflow_items/_setup_required.html.erb
+++ b/app/views/lunchflow_items/_setup_required.html.erb
@@ -20,11 +20,12 @@
- <%= link_to settings_providers_path,
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors",
- data: { turbo: false } do %>
- <%= t(".go_to_provider_settings") %>
- <% end %>
+ <%= render DS::Link.new(
+ text: t(".go_to_provider_settings"),
+ href: settings_providers_path,
+ variant: :primary,
+ data: { turbo: false }
+ ) %>
<% end %>
diff --git a/app/views/lunchflow_items/select_accounts.html.erb b/app/views/lunchflow_items/select_accounts.html.erb
index 9399bef0f..dc9f5aba5 100644
--- a/app/views/lunchflow_items/select_accounts.html.erb
+++ b/app/views/lunchflow_items/select_accounts.html.erb
@@ -46,8 +46,11 @@
<%= link_to t(".cancel"), @return_to || new_account_path,
class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-primary button-bg-secondary hover:button-bg-secondary-hover",
data: { turbo_frame: "_top", action: "DS--dialog#close" } %>
- <%= submit_tag t(".link_accounts"),
- class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-inverse bg-inverse hover:bg-inverse-hover disabled:button-bg-disabled" %>
+ <%= render DS::Button.new(
+ text: t(".link_accounts"),
+ variant: :primary,
+ type: :submit
+ ) %>
diff --git a/app/views/lunchflow_items/select_existing_account.html.erb b/app/views/lunchflow_items/select_existing_account.html.erb
index 3dc778517..07f8227eb 100644
--- a/app/views/lunchflow_items/select_existing_account.html.erb
+++ b/app/views/lunchflow_items/select_existing_account.html.erb
@@ -46,8 +46,11 @@
<%= link_to t(".cancel"), @return_to || accounts_path,
class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-primary button-bg-secondary hover:button-bg-secondary-hover",
data: { turbo_frame: "_top", action: "DS--dialog#close" } %>
- <%= submit_tag t(".link_account"),
- class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-inverse bg-inverse hover:bg-inverse-hover disabled:button-bg-disabled" %>
+ <%= render DS::Button.new(
+ text: t(".link_account"),
+ variant: :primary,
+ type: :submit
+ ) %>
diff --git a/app/views/mercury_items/_api_error.html.erb b/app/views/mercury_items/_api_error.html.erb
index 0f5696b14..7b736eab6 100644
--- a/app/views/mercury_items/_api_error.html.erb
+++ b/app/views/mercury_items/_api_error.html.erb
@@ -24,11 +24,12 @@
- <%= link_to settings_providers_path,
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors",
- data: { turbo: false } do %>
- <%= t(".check_provider_settings") %>
- <% end %>
+ <%= render DS::Link.new(
+ text: t(".check_provider_settings"),
+ href: settings_providers_path,
+ variant: :primary,
+ data: { turbo: false }
+ ) %>
<% end %>
diff --git a/app/views/mercury_items/_setup_required.html.erb b/app/views/mercury_items/_setup_required.html.erb
index 5711d968d..3738a1fce 100644
--- a/app/views/mercury_items/_setup_required.html.erb
+++ b/app/views/mercury_items/_setup_required.html.erb
@@ -22,11 +22,12 @@
- <%= link_to settings_providers_path,
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors",
- data: { turbo: false } do %>
- <%= t(".go_to_provider_settings") %>
- <% end %>
+ <%= render DS::Link.new(
+ text: t(".go_to_provider_settings"),
+ href: settings_providers_path,
+ variant: :primary,
+ data: { turbo: false }
+ ) %>
<% end %>
diff --git a/app/views/mercury_items/select_accounts.html.erb b/app/views/mercury_items/select_accounts.html.erb
index 5e80783c6..4b48c7720 100644
--- a/app/views/mercury_items/select_accounts.html.erb
+++ b/app/views/mercury_items/select_accounts.html.erb
@@ -48,8 +48,11 @@
<%= link_to t(".cancel"), @return_to || new_account_path,
class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-primary button-bg-secondary hover:button-bg-secondary-hover",
data: { turbo_frame: "_top", action: "DS--dialog#close" } %>
- <%= submit_tag t(".link_accounts"),
- class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-inverse bg-inverse hover:bg-inverse-hover disabled:button-bg-disabled" %>
+ <%= render DS::Button.new(
+ text: t(".link_accounts"),
+ variant: :primary,
+ type: :submit
+ ) %>
diff --git a/app/views/mercury_items/select_existing_account.html.erb b/app/views/mercury_items/select_existing_account.html.erb
index e66266e61..2641de1a5 100644
--- a/app/views/mercury_items/select_existing_account.html.erb
+++ b/app/views/mercury_items/select_existing_account.html.erb
@@ -48,8 +48,11 @@
<%= link_to t(".cancel"), @return_to || accounts_path,
class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-primary button-bg-secondary hover:button-bg-secondary-hover",
data: { turbo_frame: "_top", action: "DS--dialog#close" } %>
- <%= submit_tag t(".link_account"),
- class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-inverse bg-inverse hover:bg-inverse-hover disabled:button-bg-disabled" %>
+ <%= render DS::Button.new(
+ text: t(".link_account"),
+ variant: :primary,
+ type: :submit
+ ) %>
diff --git a/app/views/pages/intro.html.erb b/app/views/pages/intro.html.erb
index 7378ccdeb..7c014008e 100644
--- a/app/views/pages/intro.html.erb
+++ b/app/views/pages/intro.html.erb
@@ -15,7 +15,11 @@
<%= t(".description") %>
- <%= link_to t(".start_chatting"), chats_path, class: "inline-flex items-center gap-2 px-4 py-2 rounded-lg button-bg-primary text-inverse font-medium" %>
+ <%= render DS::Link.new(
+ text: t(".start_chatting"),
+ href: chats_path,
+ variant: :primary
+ ) %>
diff --git a/app/views/plaid_items/select_existing_account.html.erb b/app/views/plaid_items/select_existing_account.html.erb
index 8b0cde2bc..088d5bf11 100644
--- a/app/views/plaid_items/select_existing_account.html.erb
+++ b/app/views/plaid_items/select_existing_account.html.erb
@@ -35,8 +35,11 @@
<%= link_to t(".cancel"), accounts_path,
class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-primary button-bg-secondary hover:button-bg-secondary-hover",
data: { turbo_frame: "_top", action: "DS--dialog#close" } %>
- <%= submit_tag t(".link_account"),
- class: "inline-flex items-center gap-1 px-3 py-2 text-sm font-medium rounded-lg text-inverse bg-inverse hover:bg-inverse-hover disabled:button-bg-disabled" %>
+ <%= render DS::Button.new(
+ text: t(".link_account"),
+ variant: :primary,
+ type: :submit
+ ) %>
diff --git a/app/views/settings/providers/_binance_panel.html.erb b/app/views/settings/providers/_binance_panel.html.erb
index 49b8cd0d4..578573188 100644
--- a/app/views/settings/providers/_binance_panel.html.erb
+++ b/app/views/settings/providers/_binance_panel.html.erb
@@ -93,8 +93,7 @@
type: :password %>
- <%= form.submit t("settings.providers.binance_panel.connect_button"),
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-gray-900 focus:ring-offset-2 transition-colors" %>
+ <%= form.submit t("settings.providers.binance_panel.connect_button") %>
<% end %>
<% end %>
diff --git a/app/views/settings/providers/_brex_panel.html.erb b/app/views/settings/providers/_brex_panel.html.erb
index 3954c60f3..5b87ad38e 100644
--- a/app/views/settings/providers/_brex_panel.html.erb
+++ b/app/views/settings/providers/_brex_panel.html.erb
@@ -98,8 +98,7 @@
href: setup_accounts_brex_item_path(item),
frame: :modal
) %>
- <%= form.submit t("brex_items.provider_panel.update_connection"),
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-primary transition-colors" %>
+ <%= form.submit t("brex_items.provider_panel.update_connection") %>
<% end %>
@@ -136,8 +135,7 @@
placeholder: t("brex_items.provider_panel.base_url_placeholder") %>
- <%= form.submit t("brex_items.provider_panel.add_connection"),
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-primary transition-colors" %>
+ <%= form.submit t("brex_items.provider_panel.add_connection") %>
<% end %>
diff --git a/app/views/settings/providers/_coinbase_panel.html.erb b/app/views/settings/providers/_coinbase_panel.html.erb
index 546d32626..82cb7d473 100644
--- a/app/views/settings/providers/_coinbase_panel.html.erb
+++ b/app/views/settings/providers/_coinbase_panel.html.erb
@@ -72,8 +72,7 @@
type: :password %>
- <%= form.submit t("settings.providers.coinbase_panel.connect_button"),
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-gray-900 focus:ring-offset-2 transition-colors" %>
+ <%= form.submit t("settings.providers.coinbase_panel.connect_button") %>
<% end %>
<% end %>
diff --git a/app/views/settings/providers/_coinstats_panel.html.erb b/app/views/settings/providers/_coinstats_panel.html.erb
index b9e62b071..d545c9952 100644
--- a/app/views/settings/providers/_coinstats_panel.html.erb
+++ b/app/views/settings/providers/_coinstats_panel.html.erb
@@ -32,8 +32,7 @@
type: :password %>
- <%= form.submit is_new_record ? t("coinstats_items.new.configure") : t("coinstats_items.new.update_configuration"),
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-gray-900 focus:ring-offset-2 transition-colors" %>
+ <%= form.submit is_new_record ? t("coinstats_items.new.configure") : t("coinstats_items.new.update_configuration") %>
<% end %>
diff --git a/app/views/settings/providers/_enable_banking_panel.html.erb b/app/views/settings/providers/_enable_banking_panel.html.erb
index b73009f96..9b2fb2381 100644
--- a/app/views/settings/providers/_enable_banking_panel.html.erb
+++ b/app/views/settings/providers/_enable_banking_panel.html.erb
@@ -90,8 +90,7 @@
disabled: has_authenticated_connections && !is_new_record %>
- <%= form.submit is_new_record ? t("settings.providers.enable_banking_panel.save_and_connect") : t("settings.providers.enable_banking_panel.update_connection"),
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors" %>
+ <%= form.submit is_new_record ? t("settings.providers.enable_banking_panel.save_and_connect") : t("settings.providers.enable_banking_panel.update_connection") %>
<% end %>
@@ -158,11 +157,13 @@
<%= t("settings.providers.enable_banking_panel.reconnect") %>
<% end %>
<% else %>
- <%= link_to select_bank_enable_banking_item_path(item),
- class: "inline-flex items-center justify-center rounded-lg px-3 py-1.5 text-xs font-medium text-inverse button-bg-primary hover:button-bg-primary-hover transition-colors",
- data: { turbo_frame: "modal" } do %>
- <%= t("settings.providers.enable_banking_panel.connect_bank") %>
- <% end %>
+ <%= render DS::Link.new(
+ text: t("settings.providers.enable_banking_panel.connect_bank"),
+ href: select_bank_enable_banking_item_path(item),
+ variant: :primary,
+ size: :sm,
+ data: { turbo_frame: "modal" }
+ ) %>
<% end %>
<%= button_to enable_banking_item_path(item),
@@ -178,13 +179,13 @@
<%# Add Connection button below the list - only show if we have a valid session to copy credentials from %>
<% if item_for_new_connection %>
- <%= button_to new_connection_enable_banking_item_path(item_for_new_connection),
- method: :post,
- class: "inline-flex items-center gap-2 justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover transition-colors",
- data: { turbo_frame: "modal" } do %>
- <%= icon "plus", size: "sm" %>
- <%= t("settings.providers.enable_banking_panel.add_connection") %>
- <% end %>
+ <%= render DS::Button.new(
+ text: t("settings.providers.enable_banking_panel.add_connection"),
+ icon: "plus",
+ href: new_connection_enable_banking_item_path(item_for_new_connection),
+ variant: :primary,
+ data: { turbo_method: :post, turbo_frame: "modal" }
+ ) %>
<% end %>
diff --git a/app/views/settings/providers/_ibkr_panel.html.erb b/app/views/settings/providers/_ibkr_panel.html.erb
index d20d03f31..578c6af34 100644
--- a/app/views/settings/providers/_ibkr_panel.html.erb
+++ b/app/views/settings/providers/_ibkr_panel.html.erb
@@ -132,7 +132,7 @@
type: :password %>
- <%= form.submit(is_new_record ? t(".save_configuration") : t(".update_configuration"), class: "btn btn--primary") %>
+ <%= form.submit(is_new_record ? t(".save_configuration") : t(".update_configuration")) %>
<% end %>
diff --git a/app/views/settings/providers/_indexa_capital_panel.html.erb b/app/views/settings/providers/_indexa_capital_panel.html.erb
index c0fbdcaf1..c751e0feb 100644
--- a/app/views/settings/providers/_indexa_capital_panel.html.erb
+++ b/app/views/settings/providers/_indexa_capital_panel.html.erb
@@ -53,7 +53,7 @@
<%= form.submit is_new_record ? t("indexa_capital_items.panel.save_button") : t("indexa_capital_items.panel.update_button"),
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium btn btn--primary" %>
+ class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium" %>
<% end %>
diff --git a/app/views/settings/providers/_kraken_panel.html.erb b/app/views/settings/providers/_kraken_panel.html.erb
index 7de8e7831..8490b1c49 100644
--- a/app/views/settings/providers/_kraken_panel.html.erb
+++ b/app/views/settings/providers/_kraken_panel.html.erb
@@ -93,8 +93,7 @@
value: nil %>
- <%= form.submit t("settings.providers.kraken_panel.update_connection"),
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-primary transition-colors" %>
+ <%= form.submit t("settings.providers.kraken_panel.update_connection") %>
<% end %>
@@ -134,8 +133,7 @@
value: nil %>
- <%= form.submit t("settings.providers.kraken_panel.add_connection"),
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-primary transition-colors" %>
+ <%= form.submit t("settings.providers.kraken_panel.add_connection") %>
<% end %>
diff --git a/app/views/settings/providers/_lunchflow_panel.html.erb b/app/views/settings/providers/_lunchflow_panel.html.erb
index 9b128f8dd..d6aef9530 100644
--- a/app/views/settings/providers/_lunchflow_panel.html.erb
+++ b/app/views/settings/providers/_lunchflow_panel.html.erb
@@ -37,8 +37,7 @@
value: lunchflow_item.base_url %>
- <%= form.submit is_new_record ? t("settings.providers.lunchflow_panel.save_and_connect") : t("settings.providers.lunchflow_panel.update_connection"),
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors" %>
+ <%= form.submit is_new_record ? t("settings.providers.lunchflow_panel.save_and_connect") : t("settings.providers.lunchflow_panel.update_connection") %>
<% end %>
diff --git a/app/views/settings/providers/_mercury_panel.html.erb b/app/views/settings/providers/_mercury_panel.html.erb
index 47a7f8b20..4e711b4c7 100644
--- a/app/views/settings/providers/_mercury_panel.html.erb
+++ b/app/views/settings/providers/_mercury_panel.html.erb
@@ -78,8 +78,7 @@
href: setup_accounts_mercury_item_path(item),
frame: :modal
) %>
- <%= form.submit t("mercury_items.provider_panel.update_connection"),
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-primary transition-colors" %>
+ <%= form.submit t("mercury_items.provider_panel.update_connection") %>
<% end %>
@@ -117,8 +116,7 @@
<%= t("mercury_items.provider_panel.sandbox_note_html").html_safe %>
- <%= form.submit t("mercury_items.provider_panel.add_connection"),
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-primary transition-colors" %>
+ <%= form.submit t("mercury_items.provider_panel.add_connection") %>
<% end %>
diff --git a/app/views/settings/providers/_provider_form.html.erb b/app/views/settings/providers/_provider_form.html.erb
index 4a7294a65..a16a15675 100644
--- a/app/views/settings/providers/_provider_form.html.erb
+++ b/app/views/settings/providers/_provider_form.html.erb
@@ -63,8 +63,7 @@
<% end %>
- <%= form.submit "Save and connect",
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors" %>
+ <%= form.submit t(".save_and_connect") %>
<% end %>
diff --git a/app/views/settings/providers/_simplefin_panel.html.erb b/app/views/settings/providers/_simplefin_panel.html.erb
index b169c5cd9..f5125a2a1 100644
--- a/app/views/settings/providers/_simplefin_panel.html.erb
+++ b/app/views/settings/providers/_simplefin_panel.html.erb
@@ -25,8 +25,7 @@
type: :password %>
- <%= form.submit t("settings.providers.simplefin_panel.save_and_connect"),
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse button-bg-primary hover:button-bg-primary-hover focus:outline-none focus:ring-2 focus:ring-gray-900 theme-dark:focus:ring-white focus:ring-offset-2 transition-colors" %>
+ <%= form.submit t("settings.providers.simplefin_panel.save_and_connect") %>
<% end %>
diff --git a/app/views/settings/providers/_snaptrade_panel.html.erb b/app/views/settings/providers/_snaptrade_panel.html.erb
index b99bace2b..ec877bdcd 100644
--- a/app/views/settings/providers/_snaptrade_panel.html.erb
+++ b/app/views/settings/providers/_snaptrade_panel.html.erb
@@ -38,8 +38,7 @@
type: :password %>
- <%= form.submit is_new_record ? t("providers.snaptrade.save_button") : t("providers.snaptrade.update_button"),
- class: "btn btn--primary" %>
+ <%= form.submit is_new_record ? t("providers.snaptrade.save_button") : t("providers.snaptrade.update_button") %>
<% end %>
diff --git a/app/views/settings/providers/_sophtron_panel.html.erb b/app/views/settings/providers/_sophtron_panel.html.erb
index e17c8a816..4511d01dc 100644
--- a/app/views/settings/providers/_sophtron_panel.html.erb
+++ b/app/views/settings/providers/_sophtron_panel.html.erb
@@ -40,8 +40,7 @@
value: sophtron_item.base_url %>
- <%= form.submit is_new_record ? t("sophtron_items.sophtron_panel.save") : t("sophtron_items.sophtron_panel.update"),
- class: "inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium text-inverse bg-inverse hover:bg-inverse-hover focus:outline-none focus:ring-2 focus:ring-primary transition-colors" %>
+ <%= form.submit is_new_record ? t("sophtron_items.sophtron_panel.save") : t("sophtron_items.sophtron_panel.update") %>
<% end %>
diff --git a/app/views/simplefin_items/_replacement_prompt.html.erb b/app/views/simplefin_items/_replacement_prompt.html.erb
index f17e5dc41..4337a8f69 100644
--- a/app/views/simplefin_items/_replacement_prompt.html.erb
+++ b/app/views/simplefin_items/_replacement_prompt.html.erb
@@ -52,14 +52,15 @@
new_name: new_sfa.name),
btn_text: t("simplefin_items.replacement_prompt.relink")
) %>
- <%= button_to t("simplefin_items.replacement_prompt.relink"),
- link_existing_account_simplefin_items_path(
- account_id: sure_account.id,
- simplefin_account_id: new_sfa.id
- ),
- method: :post,
- data: { turbo_confirm: confirm.to_data_attribute },
- class: "inline-flex items-center gap-1.5 text-sm font-medium px-3 py-2 rounded-lg text-inverse bg-inverse hover:bg-inverse-hover" %>
+ <%= render DS::Button.new(
+ text: t("simplefin_items.replacement_prompt.relink"),
+ href: link_existing_account_simplefin_items_path(
+ account_id: sure_account.id,
+ simplefin_account_id: new_sfa.id
+ ),
+ variant: :primary,
+ data: { turbo_method: :post, turbo_confirm: confirm.to_data_attribute }
+ ) %>
diff --git a/app/views/simplefin_items/new.html.erb b/app/views/simplefin_items/new.html.erb
index ade7c448c..4979ed5c5 100644
--- a/app/views/simplefin_items/new.html.erb
+++ b/app/views/simplefin_items/new.html.erb
@@ -9,15 +9,20 @@
<% end %>
- <%= form_with model: @simplefin_item, url: simplefin_items_path, method: :post, data: { turbo: true, turbo_frame: "_top" } do |f| %>
+ <%= styled_form_with model: @simplefin_item, url: simplefin_items_path, method: :post, data: { turbo: true, turbo_frame: "_top" } do |f| %>
<%= f.label :setup_token, t(".setup_token"), class: "text-sm text-secondary block mb-1" %>
<%= f.text_field :setup_token, class: "input", placeholder: t(".setup_token_placeholder") %>
- <%= link_to t(".cancel"), accounts_path, class: "btn", data: { turbo_frame: "_top", action: "DS--dialog#close" } %>
- <%= f.submit t(".connect"), class: "btn btn--primary" %>
+ <%= render DS::Link.new(
+ text: t(".cancel"),
+ href: accounts_path,
+ variant: :secondary,
+ data: { turbo_frame: "_top", action: "DS--dialog#close" }
+ ) %>
+ <%= f.submit t(".connect") %>
<% end %>
diff --git a/app/views/snaptrade_items/select_existing_account.html.erb b/app/views/snaptrade_items/select_existing_account.html.erb
index ab4d49ff2..bf817c98d 100644
--- a/app/views/snaptrade_items/select_existing_account.html.erb
+++ b/app/views/snaptrade_items/select_existing_account.html.erb
@@ -14,7 +14,13 @@
<%= icon "alert-circle", class: "text-warning mx-auto mb-4", size: "lg" %>
<%= t("snaptrade_items.select_existing_account.no_accounts", default: "No unlinked SnapTrade accounts available.") %>
<%= t("snaptrade_items.select_existing_account.connect_hint", default: "You may need to connect a brokerage first.") %>
- <%= link_to t("snaptrade_items.select_existing_account.settings_link", default: "Go to Provider Settings"), settings_providers_path, class: "btn btn--primary btn--sm mt-4" %>
+ <%= render DS::Link.new(
+ text: t("snaptrade_items.select_existing_account.settings_link", default: "Go to Provider Settings"),
+ href: settings_providers_path,
+ variant: :primary,
+ size: :sm,
+ class: "mt-4"
+ ) %>
<% else %>
diff --git a/app/views/transactions/show.html.erb b/app/views/transactions/show.html.erb
index 701844a9c..342670518 100644
--- a/app/views/transactions/show.html.erb
+++ b/app/views/transactions/show.html.erb
@@ -28,16 +28,20 @@
- <%= button_to t("transactions.show.merge_duplicate"),
- merge_duplicate_transaction_path(@entry.transaction),
- method: :post,
- class: "btn btn--primary btn--sm",
- data: { turbo_frame: "_top" } %>
- <%= button_to t("transactions.show.keep_both"),
- dismiss_duplicate_transaction_path(@entry.transaction),
- method: :post,
- class: "btn btn--outline btn--sm",
- data: { turbo_frame: "_top" } %>
+ <%= render DS::Button.new(
+ text: t("transactions.show.merge_duplicate"),
+ href: merge_duplicate_transaction_path(@entry.transaction),
+ variant: :primary,
+ size: :sm,
+ data: { turbo_method: :post, turbo_frame: "_top" }
+ ) %>
+ <%= render DS::Button.new(
+ text: t("transactions.show.keep_both"),
+ href: dismiss_duplicate_transaction_path(@entry.transaction),
+ variant: :outline,
+ size: :sm,
+ data: { turbo_method: :post, turbo_frame: "_top" }
+ ) %>
diff --git a/config/locales/views/settings/en.yml b/config/locales/views/settings/en.yml
index 9a7968fe9..e7abc768f 100644
--- a/config/locales/views/settings/en.yml
+++ b/config/locales/views/settings/en.yml
@@ -342,6 +342,8 @@ en:
encryption_error:
title: Encryption keys missing
message: "Bank sync needs Active Record encryption configured. Set primary_key, deterministic_key and key_derivation_salt in your Rails credentials or environment variables."
+ provider_form:
+ save_and_connect: "Save and connect"
coinbase_panel:
setup_instructions: "To connect Coinbase:"
step1_html: Go to Coinbase API Settings