diff --git a/app/javascript/controllers/currency_preferences_controller.js b/app/javascript/controllers/currency_preferences_controller.js index 04cf31b71..4908d2f9e 100644 --- a/app/javascript/controllers/currency_preferences_controller.js +++ b/app/javascript/controllers/currency_preferences_controller.js @@ -1,12 +1,19 @@ import { Controller } from "@hotwired/stimulus"; export default class extends Controller { - static targets = ["dialog", "checkbox"]; + static targets = ["dialog", "checkbox", "selectedCount"]; static values = { baseCurrency: String, + locale: String, + selectedCountTranslations: Object, }; + connect() { + this.updateSelectedCount(); + } + open() { + this.updateSelectedCount(); this.dialogTarget.showModal(); } @@ -14,12 +21,31 @@ export default class extends Controller { this.checkboxTargets.forEach((checkbox) => { checkbox.checked = true; }); + + this.updateSelectedCount(); } selectBaseOnly() { this.checkboxTargets.forEach((checkbox) => { checkbox.checked = checkbox.value === this.baseCurrencyValue; }); + + this.updateSelectedCount(); + } + + updateSelectedCount() { + if (!this.hasSelectedCountTarget) return; + + const selectedCount = this.checkboxTargets.filter((checkbox) => checkbox.checked).length; + const pluralRules = new Intl.PluralRules(this.localeValue || undefined); + const pluralCategory = pluralRules.select(selectedCount); + const labelTemplate = + this.selectedCountTranslationsValue[pluralCategory] || + this.selectedCountTranslationsValue.other || + "%{count}"; + const label = labelTemplate.replace("%{count}", selectedCount); + + this.selectedCountTarget.textContent = label; } handleSubmitEnd(event) { diff --git a/app/views/settings/preferences/show.html.erb b/app/views/settings/preferences/show.html.erb index 199ad36e0..8dd2c5053 100644 --- a/app/views/settings/preferences/show.html.erb +++ b/app/views/settings/preferences/show.html.erb @@ -44,39 +44,52 @@ <% end %> <% if Current.user.admin? %> <%= settings_section title: t(".currencies_title", moniker: family_moniker), subtitle: t(".currencies_subtitle", moniker: family_moniker_downcase) do %> + <% selected_count_translations = t(".selected_currencies_count") %>
- <% preview_currencies = @user.family.enabled_currency_objects.first(6) %> -
-
+ data-currency-preferences-base-currency-value="<%= @user.family.primary_currency_code %>" + data-currency-preferences-locale-value="<%= I18n.locale %>" + data-currency-preferences-selected-count-translations-value="<%= selected_count_translations.to_json %>"> + <% additional_preview_currencies = @user.family.secondary_enabled_currency_objects.first(6) %> + <% additional_currency_count = @user.family.secondary_enabled_currency_objects.count %> +
+
-

<%= @user.family.primary_currency_code %>

-

<%= currency_label(@user.family.primary_currency_code) %>

+

<%= t(".base_currency_label") %>

+
+

<%= @user.family.primary_currency_code %>

+

<%= currency_label(@user.family.primary_currency_code) %>

+
+
+
+

<%= t(".additional_currencies_label") %>

+ <% if additional_preview_currencies.any? %> +
+ <% additional_preview_currencies.each do |currency| %> + + <%= currency.iso_code %> + + <% end %> + <% if additional_currency_count > additional_preview_currencies.count %> + + <%= t(".currencies_more", count: additional_currency_count - additional_preview_currencies.count) %> + + <% end %> +
+ <% else %> +

<%= t(".no_additional_currencies") %>

+ <% end %>
- - <%= t(".base_currency_badge") %> - -
-
- <% preview_currencies.each do |currency| %> - - <%= currency.iso_code %> - - <% end %> - <% if @user.family.enabled_currency_codes.count > preview_currencies.count %> - - <%= t(".currencies_more", count: @user.family.enabled_currency_codes.count - preview_currencies.count) %> - - <% end %>
- <%= render DS::Button.new( - text: t(".manage_currencies"), - type: :button, - class: "md:w-auto w-full justify-center", - data: { action: "currency-preferences#open" } - ) %> +
+ <%= render DS::Button.new( + text: t(".manage_currencies"), + type: :button, + class: "md:w-auto w-full justify-center", + data: { action: "currency-preferences#open" } + ) %> +
<%= render DS::Dialog.new( id: "currency-preferences-dialog", auto_open: false, @@ -86,23 +99,36 @@ ) do |dialog| %> <% dialog.with_header(title: t(".manage_currencies"), subtitle: t(".manage_currencies_subtitle")) %> <% dialog.with_body do %> + <% primary_currency_code = @user.family.primary_currency_code %> + <% selected_currency_codes = @user.family.enabled_currency_codes %> + <% base_currency_rows, other_currency_rows = Money::Currency.as_options.partition { |currency| currency.iso_code == primary_currency_code } %> + <% currency_rows = base_currency_rows + other_currency_rows %> <%= styled_form_with model: @user, url: user_path(@user), class: "space-y-4", data: { action: "turbo:submit-end->currency-preferences#handleSubmitEnd" } do |form| %> <%= form.hidden_field :redirect_to, value: "preferences" %> <%= hidden_field_tag "user[family_attributes][id]", @user.family.id %> - <%= hidden_field_tag "user[family_attributes][enabled_currencies][]", @user.family.primary_currency_code, id: nil %> -
- <%= render DS::Button.new( - text: t(".select_all_currencies"), - type: :button, - variant: :ghost, - data: { action: "currency-preferences#selectAll" } - ) %> - <%= render DS::Button.new( - text: t(".select_base_only"), - type: :button, - variant: :ghost, - data: { action: "currency-preferences#selectBaseOnly" } - ) %> + <%= hidden_field_tag "user[family_attributes][enabled_currencies][]", primary_currency_code, id: nil %> +
+
+ <%= render DS::Button.new( + text: t(".select_all_currencies"), + type: :button, + variant: :ghost, + size: :sm, + data: { action: "currency-preferences#selectAll" } + ) %> + <%= render DS::Button.new( + text: t(".select_base_only"), + type: :button, + variant: :ghost, + size: :sm, + data: { action: "currency-preferences#selectBaseOnly" } + ) %> +
+

@@ -112,33 +138,47 @@ aria-label="<%= t(".currency_search_placeholder") %>" data-list-filter-target="input" data-action="input->list-filter#filter" - class="block w-full border border-secondary rounded-md py-2 pl-10 pr-3 bg-container focus:ring-gray-500 sm:text-sm"> + class="block w-full border border-secondary rounded-md py-2.5 pl-10 pr-3 bg-container focus:ring-gray-500 sm:text-sm">
<%= icon("search", class: "text-secondary") %>
-
- <% Money::Currency.as_options.each do |currency| %> - <% checked = @user.family.enabled_currency_codes.include?(currency.iso_code) %> - <% base_currency = currency.iso_code == @user.family.primary_currency_code %> -