Files
sure/app/views/rules/confirm.html.erb
Guillem Arias Fauste ea51612ac7 refactor(views): migrate 6 residual inline alerts to DS::Alert (#1933)
* refactor(views): migrate 6 residual inline alerts to DS::Alert

PR #1731 extended DS::Alert and migrated 9 inline alert blocks. Six
hand-rolled alert blocks slipped through that sweep and stayed on raw
palette tokens with no `theme-dark:` variants:

- `app/views/settings/llm_usages/show.html.erb` — "About Cost Estimates"
  blue info block. Most visible offender: `bg-blue-50 border border-blue-200`
  + `text-blue-900 / text-blue-700 / text-blue-600` rendered as a bright
  white-blue island in dark mode (the bug spotted on the LLM usage page).
- `app/views/accounts/confirm_unlink.html.erb` — yellow warning with
  bullet list.
- `app/views/oidc_accounts/new_user.html.erb` — blue info heading.
- `app/views/oidc_accounts/link.html.erb` — two blocks (yellow verify
  warning + blue create info). Also flips the file's pre-existing
  `text-gray-600` hint paragraph to `text-secondary` (caught by the
  `DeprecatedClasses` erb_lint rule on save).
- `app/views/rules/confirm.html.erb` — AI cost notice.
- `app/views/rules/confirm_all.html.erb` — AI cost notice.

All six migrate to `DS::Alert.new(title:, variant:)` (with a block content
slot for the rich/conditional bodies). DS::Alert resolves `bg-info/10`,
`border-info/20`, etc. from the `@theme` semantic tokens, so dark mode
now renders a subtle blue/yellow tint over the page surface instead of
a hardcoded light-mode pill.

Out of scope (left as-is, not alert-shaped):

- `app/views/assistant_messages/_tool_calls.html.erb` — a tool-call
  display panel (not an alert; needs its own token sweep).
- `app/views/import/rows/_form.html.erb` — inline cell-error tooltip
  (`bg-red-50 border border-red-200`) — also not alert-shaped; a future
  PR can swap it to `bg-destructive/10 border-destructive-subtle` once
  #1932 lands.

Surfaced while scanning DS drift for the LLM usage page bug. Tracking
issue: #1715 (closed but conceptually relevant) / #1911 (active drift
patrol).

* fix(oidc): keep alert description in <p>, retarget tests for DS::Alert title

CI on #1933 caught three test failures introduced by migrating the
two OIDC link alerts and the verify-redirect copy from hand-rolled
`<h3>` / `<p>` markup to `DS::Alert`:

1. `OidcAccountsControllerTest#test_should_show_create_account_option_for_new_user`
2. `OidcAccountsControllerTest#test_does_not_show_create_account_button_when_JIT_link-only_mode`
3. `SessionsControllerTest#test_redirects_to_account_linking_when_no_OIDC_identity_exists`

DS::Alert renders its `title:` slot as a `<p>` (semantically the alert
heading lives on the container's `aria-labelledby`, not on a heading
tag) and renders block / message content directly inside a `<div>`,
not a `<p>`. The pre-migration markup used `<h3>` for the heading and
`<p class="...text-blue-700">` for the description, so the tests
above asserted those specific tags.

Two fixes:

- `app/views/oidc_accounts/link.html.erb` — wrap the html_safe
  description bodies in explicit `<p>` tags inside the DS::Alert
  block. Restores the `<p>` element the session-redirect test asserts
  on, and keeps the description as a semantic paragraph rather than
  a bare text node inside the alert container.
- `test/controllers/oidc_accounts_controller_test.rb` — flip the two
  `assert_select "h3", text: "Create New Account"` calls to match the
  DS::Alert title `<p>`. The test was asserting an implementation
  detail of the pre-migration markup; switching to the new tag keeps
  the assertion meaningful (the heading text still has to render)
  without re-introducing an `<h3>` outside of DS::Alert.

* fix(test): match Create New Account title with regex (sr-only "Info:" prefix)

DS::Alert prepends `<span class="sr-only">Info:</span>` inside the
title `<p>`, so the full text content is "Info: Create New Account",
not "Create New Account". `assert_select "p", text: "Create New Account"`
requires an exact text match and rejected the prefixed string. Switch
to a regex match — keeps the heading-text assertion meaningful without
coupling to the screen-reader prefix.
2026-05-23 09:23:30 +02:00

48 lines
1.7 KiB
Plaintext

<%= render DS::Dialog.new(reload_on_close: params[:reload_on_close].present?) do |dialog| %>
<%
title = if @rule.name.present?
t(".title_with_name", name: @rule.name)
else
t(".title")
end
%>
<% dialog.with_header(title: title) %>
<% dialog.with_body do %>
<p class="text-secondary text-sm mb-4">
<%= t(".apply_notice_html", count: @rule.affected_resource_count, resource: @rule.resource_type.pluralize) %>
</p>
<% if @rule.actions.any? { |a| a.action_type == "auto_categorize" } %>
<% affected_count = @rule.affected_resource_count %>
<div class="mb-4">
<%= render DS::Alert.new(title: t(".ai_cost_title"), variant: :info) do %>
<% if @estimated_cost.present? %>
<p><%= t(".ai_cost_with_estimate_html", count: affected_count, cost: sprintf("%.4f", @estimated_cost)) %></p>
<% else %>
<p>
<%= t(".ai_cost_no_estimate_html", count: affected_count) %>
<% if @selected_model.present? %>
<span class="font-semibold"><%= t(".cost_unavailable_model", model: @selected_model) %></span>
<% else %>
<span class="font-semibold"><%= t(".cost_unavailable_no_provider") %></span>
<% end %>
<%= t(".cost_warning") %>
</p>
<% end %>
<p>
<%= link_to t(".view_usage_history"), settings_llm_usage_path, class: "text-link underline" %>
</p>
<% end %>
</div>
<% end %>
<%= render DS::Button.new(
text: t(".confirm_changes"),
href: apply_rule_path(@rule),
method: :post,
full_width: true,
data: { turbo_frame: "_top" }) %>
<% end %>
<% end %>