From ee798aed9ea39043b3075f92336e900ce5342d0a Mon Sep 17 00:00:00 2001 From: Guillem Arias Date: Sat, 9 May 2026 13:18:51 +0200 Subject: [PATCH] refactor(settings/providers): align with DS conventions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two consistency wins from the screenshot/DS audit pass. Sync icon button now renders DS::Button (variant: icon, size: sm) instead of a hand-rolled `button_to`. Same component used by other icon-only actions across the app (settings/profiles, layouts/imports). Visual delta: 28×28 → 32×32 (DS sm size). Accept the +4px for consistency. `event.stopPropagation()` still wired via the form opt so the row's
doesn't toggle when the user clicks the button. Group heading now follows the established Sure section-label style (`text-xs font-medium text-secondary uppercase`) used by `_settings_nav` and the imports/categories surfaces. The previous sentence-case `text-sm text-primary` was a one-off that didn't match the rest of the app. Locale strings stay sentence-case; uppercase comes from CSS `text-transform`. Tests updated to case-insensitively match the rendered heading text. --- .../providers/_group_heading.html.erb | 4 ++-- .../settings/providers/_sync_button.html.erb | 21 +++++++++++-------- test/system/settings/providers_test.rb | 16 +++++++------- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/app/views/settings/providers/_group_heading.html.erb b/app/views/settings/providers/_group_heading.html.erb index 73efb6fbb..970be0443 100644 --- a/app/views/settings/providers/_group_heading.html.erb +++ b/app/views/settings/providers/_group_heading.html.erb @@ -1,9 +1,9 @@ <%# locals: (title:, count: nil, description: nil, anchor: nil) %> <%= tag.div id: anchor.presence, class: "flex items-baseline justify-between gap-3 mt-5 mb-1.5 px-1" do %> -

+

<%= title %> <% if count %> - · <%= count %> + · <%= count %> <% end %>

<% if description.present? %> diff --git a/app/views/settings/providers/_sync_button.html.erb b/app/views/settings/providers/_sync_button.html.erb index 6655480ab..6e3df16ae 100644 --- a/app/views/settings/providers/_sync_button.html.erb +++ b/app/views/settings/providers/_sync_button.html.erb @@ -1,12 +1,15 @@ <%# locals: (provider_key:, last_synced_at: nil) %> <% recently_synced = last_synced_at.present? && last_synced_at > 60.seconds.ago %> <% button_label = recently_synced ? t("settings.providers.recently_synced") : t("settings.providers.sync_provider") %> -<%= button_to sync_provider_settings_providers_path(provider_key: provider_key), - method: :post, - disabled: recently_synced, - title: button_label, - aria: { label: button_label }, - class: "inline-flex items-center justify-center w-7 h-7 rounded-md text-secondary hover:text-primary hover:bg-alpha-black-50 transition-colors disabled:opacity-40 disabled:cursor-not-allowed", - form: { onclick: "event.stopPropagation()", class: "inline-flex" } do %> - <%= icon "refresh-cw", size: "sm", class: "!w-3.5 !h-3.5" %> -<% end %> +<%= render DS::Button.new( + variant: "icon", + size: "sm", + icon: "refresh-cw", + href: sync_provider_settings_providers_path(provider_key: provider_key), + method: :post, + disabled: recently_synced, + title: button_label, + aria: { label: button_label }, + class: "disabled:opacity-40 disabled:cursor-not-allowed", + form: { onclick: "event.stopPropagation()", class: "inline-flex" } + ) %> diff --git a/test/system/settings/providers_test.rb b/test/system/settings/providers_test.rb index 10148e4d5..135b9bef3 100644 --- a/test/system/settings/providers_test.rb +++ b/test/system/settings/providers_test.rb @@ -36,8 +36,8 @@ class Settings::ProvidersTest < ApplicationSystemTestCase titles = all("details").map { |d| d.find("summary h3", match: :first).text.squish } assert_equal titles.sort_by(&:downcase), titles, "Connection panels should render alphabetically by title" - connections_heading = page.find(:xpath, "//h2[contains(normalize-space(), 'Your connections')]") - available_heading = page.find(:xpath, "//h2[contains(normalize-space(), 'Available')]") + connections_heading = page.find(:xpath, "//h2[contains(translate(normalize-space(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'your connections')]") + available_heading = page.find(:xpath, "//h2[contains(translate(normalize-space(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'available')]") connections_y = connections_heading.native.location.y available_y = available_heading.native.location.y @@ -65,12 +65,12 @@ class Settings::ProvidersTest < ApplicationSystemTestCase visit settings_providers_path - connections_heading = find(:xpath, "//h2[contains(., 'Your connections')]") + connections_heading = find(:xpath, "//h2[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'your connections')]") normalized = connections_heading.text.squish - assert_match(/Your connections .*· \d+/, normalized) + assert_match(/Your connections .*· \d+/i, normalized) connections_y = connections_heading.native.location.y - available_heading = find(:xpath, "//h2[contains(., 'Available')]") + available_heading = find(:xpath, "//h2[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'available')]") available_y = available_heading.native.location.y simplefin_y = find("details", text: "SimpleFIN").native.location.y @@ -86,8 +86,8 @@ class Settings::ProvidersTest < ApplicationSystemTestCase visit settings_providers_path - assert_selector "h2", text: /\AYour connections/ - assert_no_selector "h2", text: /\AAction needed/ + assert_selector "h2", text: /\AYour connections/i + assert_no_selector "h2", text: /\AAction needed/i end test "enable banking with expiring session appears in your connections and auto-opens" do @@ -104,7 +104,7 @@ class Settings::ProvidersTest < ApplicationSystemTestCase visit settings_providers_path - assert_selector "h2", text: /\AYour connections/ + assert_selector "h2", text: /\AYour connections/i # Auto-expanded warning sections hide compact meta behind `group-open:hidden`; # collapse once so the re-consent copy is visible again.