diff --git a/.rubocop.yml b/.rubocop.yml index eef2eaac0..96d7572b5 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -574,6 +574,7 @@ RSpec/InstanceVariable: Enabled: true Exclude: - spec/controllers/concerns/has_orders_spec.rb + - spec/form_builders/translatable_form_builder_spec.rb RSpec/LetBeforeExamples: Enabled: true diff --git a/app/assets/stylesheets/admin/locales/form.scss b/app/assets/stylesheets/admin/locales/form.scss new file mode 100644 index 000000000..c834ee28b --- /dev/null +++ b/app/assets/stylesheets/admin/locales/form.scss @@ -0,0 +1,43 @@ +.admin .locales-form { + label { + display: table; + } + + select { + width: auto; + } + + .help-text { + display: block; + } + + > select + fieldset, + > fieldset + fieldset { + margin-top: $line-height / 2; + } + + > [type="hidden"] + fieldset, + > fieldset + fieldset { + @include admin-fieldset-separator; + padding-top: calc(#{$line-height} / 4); + } + + .collection-radio-buttons, + .collection-check-boxes { + column-gap: rem-calc(map-get($grid-column-gutter, medium)); + column-width: 13rem; + max-width: max-content; + + @each $elements in 10, 15, 20, 25, 30 { + &:has(label:nth-of-type(#{$elements})) { + column-count: calc(#{$elements} / 5); + } + } + } + + [type="submit"] { + @include regular-button; + display: block; + margin-top: $line-height; + } +} diff --git a/app/components/admin/locales/form_component.html.erb b/app/components/admin/locales/form_component.html.erb new file mode 100644 index 000000000..6c8bbb291 --- /dev/null +++ b/app/components/admin/locales/form_component.html.erb @@ -0,0 +1,39 @@ +<%= form_for locales_settings, url: admin_locales_path, html: { class: "locales-form" } do |f| %> + <% if many_available_locales? %> + <%= f.select :default, locales_options, hint: sanitize(t("admin.locales.default_help_text")) %> + <% else %> +
+ <%= attribute_name(:default) %> +

<%= sanitize(t("admin.locales.default_help_text")) %>

+ +
+ <%= f.collection_radio_buttons( + :default, + available_locales, + :to_sym, + ->(locale) { name_for_locale(locale) } + ) do |b| %> + <%= b.label { b.radio_button + b.text } %> + <% end %> +
+
+ <% end %> + +
+ <%= attribute_name(:enabled) %> +

<%= t("admin.locales.enabled_help_text") %>

+ +
+ <%= f.collection_check_boxes( + :enabled, + available_locales, + :to_sym, + ->(locale) { name_for_locale(locale) } + ) do |b| %> + <%= b.label { b.check_box + b.text } %> + <% end %> +
+
+ + <%= submit_tag %> +<% end %> diff --git a/app/components/admin/locales/form_component.rb b/app/components/admin/locales/form_component.rb new file mode 100644 index 000000000..4cd16bc85 --- /dev/null +++ b/app/components/admin/locales/form_component.rb @@ -0,0 +1,30 @@ +class Admin::Locales::FormComponent < ApplicationComponent + attr_reader :locales_settings + use_helpers :name_for_locale + + def initialize(locales_settings) + @locales_settings = locales_settings + end + + private + + def available_locales + I18n.available_locales + end + + def many_available_locales? + available_locales.count > select_field_threshold + end + + def locales_options + available_locales.map { |locale| [name_for_locale(locale), locale] } + end + + def select_field_threshold + 10 + end + + def attribute_name(...) + locales_settings.class.human_attribute_name(...) + end +end diff --git a/app/components/admin/locales/show_component.html.erb b/app/components/admin/locales/show_component.html.erb new file mode 100644 index 000000000..6a1463f3e --- /dev/null +++ b/app/components/admin/locales/show_component.html.erb @@ -0,0 +1,4 @@ +<%= header %> +<% provide :main_class, "admin-locales-show" %> + +<%= render Admin::Locales::FormComponent.new(locales_settings) %> diff --git a/app/components/admin/locales/show_component.rb b/app/components/admin/locales/show_component.rb new file mode 100644 index 000000000..e33e66b51 --- /dev/null +++ b/app/components/admin/locales/show_component.rb @@ -0,0 +1,12 @@ +class Admin::Locales::ShowComponent < ApplicationComponent + include Header + attr_reader :locales_settings + + def initialize(locales_settings) + @locales_settings = locales_settings + end + + def title + t("admin.menu.locales") + end +end diff --git a/app/components/admin/menu_component.rb b/app/components/admin/menu_component.rb index 480be1b89..2fb97d858 100644 --- a/app/components/admin/menu_component.rb +++ b/app/components/admin/menu_component.rb @@ -54,7 +54,7 @@ class Admin::MenuComponent < ApplicationComponent end def settings? - controllers_names = ["settings", "tenants", "tags", "geozones", "local_census_records", "imports"] + controllers_names = %w[settings tenants tags locales geozones local_census_records imports] controllers_names.include?(controller_name) end @@ -462,6 +462,7 @@ class Admin::MenuComponent < ApplicationComponent settings_link, tenants_link, tags_link, + locales_link, geozones_link, local_census_records_link ) @@ -494,6 +495,14 @@ class Admin::MenuComponent < ApplicationComponent ] end + def locales_link + [ + t("admin.menu.locales"), + admin_locales_path, + controller_name == "locales" + ] + end + def geozones_link [ t("admin.menu.geozones"), diff --git a/app/views/admin/site_customization/content_blocks/_form_content_block.html.erb b/app/components/admin/site_customization/content_blocks/form_content_block_component.html.erb similarity index 52% rename from app/views/admin/site_customization/content_blocks/_form_content_block.html.erb rename to app/components/admin/site_customization/content_blocks/form_content_block_component.html.erb index 01f61438e..55ea3f573 100644 --- a/app/views/admin/site_customization/content_blocks/_form_content_block.html.erb +++ b/app/components/admin/site_customization/content_blocks/form_content_block_component.html.erb @@ -1,12 +1,12 @@ -<%= form_for [:admin, @content_block], html: { class: "edit_page" } do |f| %> +<%= form_for [:admin, content_block], html: { class: "edit_page" } do |f| %> - <%= render "shared/errors", resource: @content_block %> + <%= render "shared/errors", resource: content_block %>
- <%= f.select :name, options_for_select(valid_blocks, @selected_content_block) %> + <%= f.select :name, options_for_select(valid_blocks, selected_content_block) %>
- <%= f.select :locale, I18n.available_locales %> + <%= f.select :locale, Setting.enabled_locales %>
diff --git a/app/components/admin/site_customization/content_blocks/form_content_block_component.rb b/app/components/admin/site_customization/content_blocks/form_content_block_component.rb new file mode 100644 index 000000000..59218499c --- /dev/null +++ b/app/components/admin/site_customization/content_blocks/form_content_block_component.rb @@ -0,0 +1,14 @@ +class Admin::SiteCustomization::ContentBlocks::FormContentBlockComponent < ApplicationComponent + attr_reader :content_block + use_helpers :valid_blocks + + def initialize(content_block) + @content_block = content_block + end + + private + + def selected_content_block + content_block.name + end +end diff --git a/app/views/admin/site_customization/content_blocks/_form_heading_content_block.html.erb b/app/components/admin/site_customization/content_blocks/form_heading_content_block_component.html.erb similarity index 56% rename from app/views/admin/site_customization/content_blocks/_form_heading_content_block.html.erb rename to app/components/admin/site_customization/content_blocks/form_heading_content_block_component.html.erb index d3415c053..486b9b4cd 100644 --- a/app/views/admin/site_customization/content_blocks/_form_heading_content_block.html.erb +++ b/app/components/admin/site_customization/content_blocks/form_heading_content_block_component.html.erb @@ -1,17 +1,17 @@ -<%= form_tag(admin_site_customization_update_heading_content_block_path(@content_block.id), method: "put") do %> - <%= render "shared/errors", resource: @content_block %> +<%= form_tag(admin_site_customization_update_heading_content_block_path(content_block.id), method: "put") do %> + <%= render "shared/errors", resource: content_block %>
<%= label_tag :name %> - <%= select_tag :name, options_for_select(valid_blocks, @selected_content_block) %> + <%= select_tag :name, options_for_select(valid_blocks, selected_content_block) %>
<%= label_tag :locale %> - <%= select_tag :locale, options_for_select(I18n.available_locales, @content_block.locale.to_sym) %> + <%= select_tag :locale, options_for_select(Setting.enabled_locales, content_block.locale.to_sym) %>
<%= label_tag :body %> - <%= text_area_tag :body, @content_block.body, rows: 10 %> + <%= text_area_tag :body, content_block.body, rows: 10 %>
<%= button_tag t("admin.menu.site_customization.buttons.content_block.update"), class: "button success expanded" %>
diff --git a/app/components/admin/site_customization/content_blocks/form_heading_content_block_component.rb b/app/components/admin/site_customization/content_blocks/form_heading_content_block_component.rb new file mode 100644 index 000000000..6c13a9656 --- /dev/null +++ b/app/components/admin/site_customization/content_blocks/form_heading_content_block_component.rb @@ -0,0 +1,14 @@ +class Admin::SiteCustomization::ContentBlocks::FormHeadingContentBlockComponent < ApplicationComponent + attr_reader :content_block + use_helpers :valid_blocks + + def initialize(content_block) + @content_block = content_block + end + + private + + def selected_content_block + "hcb_#{content_block.heading_id}" + end +end diff --git a/app/views/admin/site_customization/information_texts/_form.html.erb b/app/components/admin/site_customization/information_texts/form_component.html.erb similarity index 74% rename from app/views/admin/site_customization/information_texts/_form.html.erb rename to app/components/admin/site_customization/information_texts/form_component.html.erb index b7b4adf5b..b8f8b6444 100644 --- a/app/views/admin/site_customization/information_texts/_form.html.erb +++ b/app/components/admin/site_customization/information_texts/form_component.html.erb @@ -1,13 +1,13 @@ -<%= render "globalize_locales" %> +<%= render Shared::GlobalizeLocalesComponent.new %> <%= form_tag admin_site_customization_information_texts_path do %> - <% I18n.available_locales.each do |l| %> + <% enabled_locales.each do |l| %> <%= translation_enabled_tag l, site_customization_enable_translation?(l) %> <% end %> <% contents.each do |group| %> <% group.each do |content| %> <%= content.key %> - <% content.globalize_locales.each do |locale| %> + <% (content.globalize_locales & enabled_locales.map(&:to_sym)).each do |locale| %> <%= render Admin::SiteCustomization::InformationTexts::FormFieldComponent.new(content, locale: locale) %> <% end %> <% end %> diff --git a/app/components/admin/site_customization/information_texts/form_component.rb b/app/components/admin/site_customization/information_texts/form_component.rb new file mode 100644 index 000000000..862e5a759 --- /dev/null +++ b/app/components/admin/site_customization/information_texts/form_component.rb @@ -0,0 +1,18 @@ +class Admin::SiteCustomization::InformationTexts::FormComponent < ApplicationComponent + attr_reader :contents + use_helpers :site_customization_enable_translation? + + def initialize(contents) + @contents = contents + end + + private + + def translation_enabled_tag(locale, enabled) + hidden_field_tag("enabled_translations[#{locale}]", (enabled ? 1 : 0)) + end + + def enabled_locales + Setting.enabled_locales + end +end diff --git a/app/components/admin/site_customization/information_texts/form_field_component.html.erb b/app/components/admin/site_customization/information_texts/form_field_component.html.erb index 2bda944d7..1852afba0 100644 --- a/app/components/admin/site_customization/information_texts/form_field_component.html.erb +++ b/app/components/admin/site_customization/information_texts/form_field_component.html.erb @@ -4,6 +4,6 @@ text, rows: 5, class: "js-globalize-attribute", - style: site_customization_display_translation_style(locale), + style: site_customization_display_translation_style, data: { locale: locale } %> <% end %> diff --git a/app/components/admin/site_customization/information_texts/form_field_component.rb b/app/components/admin/site_customization/information_texts/form_field_component.rb index f85c1c2ca..69ce896ef 100644 --- a/app/components/admin/site_customization/information_texts/form_field_component.rb +++ b/app/components/admin/site_customization/information_texts/form_field_component.rb @@ -1,6 +1,6 @@ class Admin::SiteCustomization::InformationTexts::FormFieldComponent < ApplicationComponent attr_reader :i18n_content, :locale - use_helpers :globalize, :site_customization_display_translation_style + use_helpers :globalize, :site_customization_enable_translation? def initialize(i18n_content, locale:) @i18n_content = i18n_content @@ -22,4 +22,8 @@ class Admin::SiteCustomization::InformationTexts::FormFieldComponent < Applicati def i18n_text I18n.translate(i18n_content.key, locale: locale) end + + def site_customization_display_translation_style + site_customization_enable_translation?(locale) ? "" : "display: none;" + end end diff --git a/app/components/layout/locale_switcher_component.rb b/app/components/layout/locale_switcher_component.rb index 304bfd119..bce22d522 100644 --- a/app/components/layout/locale_switcher_component.rb +++ b/app/components/layout/locale_switcher_component.rb @@ -12,7 +12,7 @@ class Layout::LocaleSwitcherComponent < ApplicationComponent end def locales - I18n.available_locales + Setting.enabled_locales end def label diff --git a/app/views/shared/_common_globalize_locales.html.erb b/app/components/shared/globalize_locales_component.html.erb similarity index 79% rename from app/views/shared/_common_globalize_locales.html.erb rename to app/components/shared/globalize_locales_component.html.erb index 2ead5fd8c..664d298db 100644 --- a/app/views/shared/_common_globalize_locales.html.erb +++ b/app/components/shared/globalize_locales_component.html.erb @@ -3,19 +3,19 @@ "> - <%= selected_languages_description(resource) %> + <%= selected_languages_description %> <%= select_tag :select_language, - options_for_select_language(resource), + options_for_select_language, prompt: t("shared.translations.select_language_prompt"), class: "js-select-language" %> - <%= select_language_error(resource) %> + <%= select_language_error %>
<% if manage_languages %> - <% I18n.available_locales.each do |locale| %> + <% Setting.enabled_locales.each do |locale| %> <%= link_to t("shared.translations.remove_language"), "#", - style: display_destroy_locale_style(resource, locale), + style: display_destroy_locale_style(locale), class: "delete js-delete-language js-delete-#{locale}", data: { locale: locale } %> <% end %> diff --git a/app/components/shared/globalize_locales_component.rb b/app/components/shared/globalize_locales_component.rb new file mode 100644 index 000000000..8bc2696ce --- /dev/null +++ b/app/components/shared/globalize_locales_component.rb @@ -0,0 +1,95 @@ +class Shared::GlobalizeLocalesComponent < ApplicationComponent + attr_reader :resource, :manage_languages + use_helpers :first_translation, :first_marked_for_destruction_translation, + :enabled_locale?, :name_for_locale, :highlight_translation_html_class + + def initialize(resource = nil, manage_languages: true) + @resource = resource + @manage_languages = manage_languages + end + + private + + def options_for_select_language + options_for_select(available_locales, selected_locale) + end + + def available_locales + Setting.enabled_locales.select { |locale| enabled_locale?(resource, locale) }.map do |locale| + [name_for_locale(locale), locale, { data: { locale: locale }}] + end + end + + def selected_locale + return first_i18n_content_locale if resource.blank? + + if resource.locales_not_marked_for_destruction.any? + first_translation(resource) + elsif resource.locales_persisted_and_marked_for_destruction.any? + first_marked_for_destruction_translation(resource) + else + I18n.locale + end + end + + def first_i18n_content_locale + if i18n_content_locales.empty? || i18n_content_locales.include?(I18n.locale) + I18n.locale + else + i18n_content_locales.first + end + end + + def selected_languages_description + sanitize(t("shared.translations.languages_in_use", count: active_locales_count)) + end + + def select_language_error + return if resource.blank? + + current_translation = resource.translation_for(selected_locale) + if current_translation.errors.added? :base, :translations_too_short + tag.div class: "small error" do + current_translation.errors[:base].join(", ") + end + end + end + + def active_locales_count + if active_locales.size > 0 + active_locales.size + else + 1 + end + end + + def active_locales + if resource.present? + resource.locales_not_marked_for_destruction + else + i18n_content_locales + end + end + + def display_destroy_locale_style(locale) + "display: none;" unless display_destroy_locale_link?(locale) + end + + def display_destroy_locale_link?(locale) + selected_locale == locale + end + + def options_for_add_language + options_for_select(all_language_options, nil) + end + + def all_language_options + Setting.enabled_locales.map do |locale| + [name_for_locale(locale), locale] + end + end + + def i18n_content_locales + I18nContentTranslation.existing_locales + end +end diff --git a/app/controllers/admin/locales_controller.rb b/app/controllers/admin/locales_controller.rb new file mode 100644 index 000000000..df822a29b --- /dev/null +++ b/app/controllers/admin/locales_controller.rb @@ -0,0 +1,27 @@ +class Admin::LocalesController < Admin::BaseController + before_action :set_locales_settings + authorize_resource :locales_settings + + def show + end + + def update + @locales_settings.update!(locales_settings_params) + + redirect_to admin_locales_path, notice: t("admin.locales.update.notice") + end + + private + + def locales_settings_params + params.require(:setting_locales_settings).permit(allowed_params) + end + + def allowed_params + [:default, enabled: []] + end + + def set_locales_settings + @locales_settings = Setting::LocalesSettings.new + end +end diff --git a/app/controllers/admin/site_customization/content_blocks_controller.rb b/app/controllers/admin/site_customization/content_blocks_controller.rb index 7384551f9..0b124cf6f 100644 --- a/app/controllers/admin/site_customization/content_blocks_controller.rb +++ b/app/controllers/admin/site_customization/content_blocks_controller.rb @@ -11,6 +11,9 @@ class Admin::SiteCustomization::ContentBlocksController < Admin::SiteCustomizati @headings_content_blocks = Budget::ContentBlock.all end + def new + end + def create if is_heading_content_block?(@content_block.name) heading_content_block = new_heading_content_block @@ -31,11 +34,6 @@ class Admin::SiteCustomization::ContentBlocksController < Admin::SiteCustomizati end def edit - if @content_block.is_a? SiteCustomization::ContentBlock - @selected_content_block = @content_block.name - else - @selected_content_block = "hcb_#{@content_block.heading_id}" - end end def update @@ -72,11 +70,6 @@ class Admin::SiteCustomization::ContentBlocksController < Admin::SiteCustomizati def edit_heading_content_block @content_block = Budget::ContentBlock.find(params[:id]) - if @content_block.is_a? Budget::ContentBlock - @selected_content_block = "hcb_#{@content_block.heading_id}" - else - @selected_content_block = @content_block.name - end @is_heading_content_block = true render :edit end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 082c74754..6a70a9d5e 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -46,17 +46,17 @@ class ApplicationController < ActionController::Base current_user.update(locale: locale) end - session[:locale] = locale + session[:locale] = locale.to_s I18n.with_locale(locale, &action) end def current_locale - if I18n.available_locales.include?(params[:locale]&.to_sym) + if Setting.enabled_locales.include?(params[:locale]&.to_sym) params[:locale] - elsif I18n.available_locales.include?(session[:locale]&.to_sym) + elsif Setting.enabled_locales.include?(session[:locale]&.to_sym) session[:locale] else - I18n.default_locale + Setting.default_locale end end diff --git a/app/controllers/management/base_controller.rb b/app/controllers/management/base_controller.rb index b408d01fa..745688743 100644 --- a/app/controllers/management/base_controller.rb +++ b/app/controllers/management/base_controller.rb @@ -40,11 +40,11 @@ class Management::BaseController < ActionController::Base end def switch_locale(&action) - if params[:locale] && I18n.available_locales.include?(params[:locale].to_sym) - session[:locale] = params[:locale] + if params[:locale] && Setting.enabled_locales.include?(params[:locale].to_sym) + session[:locale] = params[:locale].to_s end - session[:locale] ||= I18n.default_locale + session[:locale] ||= Setting.default_locale.to_s I18n.with_locale(session[:locale], &action) end diff --git a/app/controllers/subscriptions_controller.rb b/app/controllers/subscriptions_controller.rb index 163b913b8..e1a50316a 100644 --- a/app/controllers/subscriptions_controller.rb +++ b/app/controllers/subscriptions_controller.rb @@ -32,8 +32,12 @@ class SubscriptionsController < ApplicationController def set_user_locale(&action) if params[:locale].blank? - session[:locale] = I18n.available_locales.find { |locale| locale == @user.locale&.to_sym } + session[:locale] = find_locale.to_s end I18n.with_locale(session[:locale], &action) end + + def find_locale + Setting.enabled_locales.find { |locale| locale == @user.locale&.to_sym } || I18n.locale + end end diff --git a/app/lib/consul_form_builder.rb b/app/form_builders/consul_form_builder.rb similarity index 100% rename from app/lib/consul_form_builder.rb rename to app/form_builders/consul_form_builder.rb diff --git a/app/form_builders/custom/.keep b/app/form_builders/custom/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/app/form_builders/translatable_form_builder.rb b/app/form_builders/translatable_form_builder.rb new file mode 100644 index 000000000..cc1700ca1 --- /dev/null +++ b/app/form_builders/translatable_form_builder.rb @@ -0,0 +1,71 @@ +class TranslatableFormBuilder < ConsulFormBuilder + attr_accessor :translations + + def translatable_fields(&) + @translations = {} + visible_locales.map do |locale| + @translations[locale] = translation_for(locale) + end + safe_join(visible_locales.map do |locale| + Globalize.with_locale(locale) { fields_for_locale(locale, &) } + end) + end + + private + + def fields_for_locale(locale) + fields_for_translation(@translations[locale]) do |translations_form| + @template.tag.div(**translations_options(translations_form.object, locale)) do + @template.concat translations_form.hidden_field( + :_destroy, + value: !@template.enabled_locale?(translations_form.object.globalized_model, locale), + data: { locale: locale } + ) + + @template.concat translations_form.hidden_field(:locale, value: locale) + + yield translations_form + end + end + end + + def fields_for_translation(translation, &) + fields_for(:translations, translation, builder: TranslationsFieldsFormBuilder, &) + end + + def translation_for(locale) + existing_translation_for(locale) || new_translation_for(locale) + end + + def existing_translation_for(locale) + @object.translations.find { |translation| translation.locale == locale } + end + + def new_translation_for(locale) + @object.translations.new(locale: locale).tap(&:mark_for_destruction) + end + + def highlight_translation_html_class + @template.highlight_translation_html_class + end + + def translations_options(resource, locale) + { + class: "translatable-fields js-globalize-attribute #{highlight_translation_html_class}", + style: @template.display_translation_style(resource.globalized_model, locale), + data: { locale: locale } + } + end + + def no_other_translations?(translation) + (@object.translations - [translation]).reject(&:_destroy).empty? + end + + def visible_locales + if @template.translations_interface_enabled? + Setting.enabled_locales & @object.globalize_locales + else + [I18n.locale] + end + end +end diff --git a/app/form_builders/translations_fields_form_builder.rb b/app/form_builders/translations_fields_form_builder.rb new file mode 100644 index 000000000..e33d8f15f --- /dev/null +++ b/app/form_builders/translations_fields_form_builder.rb @@ -0,0 +1,5 @@ +class TranslationsFieldsFormBuilder < ConsulFormBuilder + def locale + @object.locale + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index eeaf6a7ff..801bb8e16 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -46,8 +46,8 @@ module ApplicationHelper end end - def content_block(name, locale = I18n.locale) - SiteCustomization::ContentBlock.block_for(name, locale) + def content_block(...) + SiteCustomization::ContentBlock.block_for(...) end def self.asset_data_base64(path) diff --git a/app/helpers/globalize_helper.rb b/app/helpers/globalize_helper.rb index b18762550..bb6cebb11 100644 --- a/app/helpers/globalize_helper.rb +++ b/app/helpers/globalize_helper.rb @@ -1,14 +1,4 @@ module GlobalizeHelper - def options_for_select_language(resource) - options_for_select(available_locales(resource), selected_locale(resource)) - end - - def available_locales(resource) - I18n.available_locales.select { |locale| enabled_locale?(resource, locale) }.map do |locale| - [name_for_locale(locale), locale, { data: { locale: locale }}] - end - end - def enabled_locale?(resource, locale) return site_customization_enable_translation?(locale) if resource.blank? @@ -21,27 +11,6 @@ module GlobalizeHelper end end - def selected_locale(resource) - return first_i18n_content_translation_locale if resource.blank? - - if resource.locales_not_marked_for_destruction.any? - first_translation(resource) - elsif resource.locales_persisted_and_marked_for_destruction.any? - first_marked_for_destruction_translation(resource) - else - I18n.locale - end - end - - def first_i18n_content_translation_locale - if I18nContentTranslation.existing_languages.count == 0 || - I18nContentTranslation.existing_languages.include?(I18n.locale) - I18n.locale - else - I18nContentTranslation.existing_languages.first - end - end - def first_translation(resource) if resource.locales_not_marked_for_destruction.include? I18n.locale I18n.locale @@ -58,40 +27,6 @@ module GlobalizeHelper end end - def translations_for_locale?(resource) - resource.locales_not_marked_for_destruction.any? - end - - def selected_languages_description(resource) - sanitize(t("shared.translations.languages_in_use", count: active_languages_count(resource))) - end - - def select_language_error(resource) - return if resource.blank? - - current_translation = resource.translation_for(selected_locale(resource)) - if current_translation.errors.added? :base, :translations_too_short - tag.div class: "small error" do - current_translation.errors[:base].join(", ") - end - end - end - - def active_languages_count(resource) - if resource.blank? - no_resource_languages_count - elsif resource.locales_not_marked_for_destruction.size > 0 - resource.locales_not_marked_for_destruction.size - else - 1 - end - end - - def no_resource_languages_count - count = I18nContentTranslation.existing_languages.count - count > 0 ? count : 1 - end - def display_translation_style(resource, locale) "display: none;" unless display_translation?(resource, locale) end @@ -108,28 +43,6 @@ module GlobalizeHelper end end - def display_destroy_locale_style(resource, locale) - "display: none;" unless display_destroy_locale_link?(resource, locale) - end - - def display_destroy_locale_link?(resource, locale) - selected_locale(resource) == locale - end - - def options_for_add_language - options_for_select(all_language_options, nil) - end - - def all_language_options - I18n.available_locales.map do |locale| - [name_for_locale(locale), locale] - end - end - - def translation_enabled_tag(locale, enabled) - hidden_field_tag("enabled_translations[#{locale}]", (enabled ? 1 : 0)) - end - def globalize(locale, &) Globalize.with_locale(locale, &) end diff --git a/app/helpers/site_customization_helper.rb b/app/helpers/site_customization_helper.rb index 72f00951f..61dd678e9 100644 --- a/app/helpers/site_customization_helper.rb +++ b/app/helpers/site_customization_helper.rb @@ -1,10 +1,6 @@ module SiteCustomizationHelper def site_customization_enable_translation?(locale) - I18nContentTranslation.existing_languages.include?(locale) || locale == I18n.locale - end - - def site_customization_display_translation_style(locale) - site_customization_enable_translation?(locale) ? "" : "display: none;" + I18nContentTranslation.existing_locales.include?(locale) || locale == I18n.locale end def information_texts_tabs diff --git a/app/helpers/translatable_form_helper.rb b/app/helpers/translatable_form_helper.rb index f77ca0b00..d67b5fe95 100644 --- a/app/helpers/translatable_form_helper.rb +++ b/app/helpers/translatable_form_helper.rb @@ -14,82 +14,4 @@ module TranslatableFormHelper def highlight_translation_html_class "highlight" if translations_interface_enabled? end - - class TranslatableFormBuilder < ConsulFormBuilder - attr_accessor :translations - - def translatable_fields(&) - @translations = {} - visible_locales.map do |locale| - @translations[locale] = translation_for(locale) - end - safe_join(visible_locales.map do |locale| - Globalize.with_locale(locale) { fields_for_locale(locale, &) } - end) - end - - private - - def fields_for_locale(locale) - fields_for_translation(@translations[locale]) do |translations_form| - @template.tag.div **translations_options(translations_form.object, locale) do - @template.concat translations_form.hidden_field( - :_destroy, - value: !@template.enabled_locale?(translations_form.object.globalized_model, locale), - data: { locale: locale } - ) - - @template.concat translations_form.hidden_field(:locale, value: locale) - - yield translations_form - end - end - end - - def fields_for_translation(translation, &) - fields_for(:translations, translation, builder: TranslationsFieldsBuilder, &) - end - - def translation_for(locale) - existing_translation_for(locale) || new_translation_for(locale) - end - - def existing_translation_for(locale) - @object.translations.find { |translation| translation.locale == locale } - end - - def new_translation_for(locale) - @object.translations.new(locale: locale).tap(&:mark_for_destruction) - end - - def highlight_translation_html_class - @template.highlight_translation_html_class - end - - def translations_options(resource, locale) - { - class: "translatable-fields js-globalize-attribute #{highlight_translation_html_class}", - style: @template.display_translation_style(resource.globalized_model, locale), - data: { locale: locale } - } - end - - def no_other_translations?(translation) - (@object.translations - [translation]).reject(&:_destroy).empty? - end - - def visible_locales - if @template.translations_interface_enabled? - @object.globalize_locales - else - [I18n.locale] - end - end - end - - class TranslationsFieldsBuilder < ConsulFormBuilder - def locale - @object.locale - end - end end diff --git a/app/lib/search_dictionary_selector.rb b/app/lib/search_dictionary_selector.rb index cc6168317..358204489 100644 --- a/app/lib/search_dictionary_selector.rb +++ b/app/lib/search_dictionary_selector.rb @@ -37,7 +37,7 @@ module SearchDictionarySelector private def find_from_i18n_default - key_to_lookup = I18n.default_locale.to_s.split("-").first.to_sym + key_to_lookup = Setting.default_locale.to_s.split("-").first.to_sym dictionary = I18N_TO_DICTIONARY[key_to_lookup] dictionary ||= "simple" diff --git a/app/mailers/mailer.rb b/app/mailers/mailer.rb index 8398bbf6b..7fcc3d98c 100644 --- a/app/mailers/mailer.rb +++ b/app/mailers/mailer.rb @@ -76,7 +76,7 @@ class Mailer < ApplicationMailer def user_invite(email) @email_to = email - I18n.with_locale(I18n.default_locale) do + I18n.with_locale(Setting.default_locale) do mail(to: @email_to, subject: t("mailers.user_invite.subject", org_name: Setting["org_name"])) end end diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index cd5e4d3f0..c6abe703c 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -134,6 +134,8 @@ module Abilities can [:deliver], Newsletter, hidden_at: nil can [:manage], Dashboard::AdministratorTask + can :manage, Setting::LocalesSettings + can :manage, LocalCensusRecord can [:create, :read], LocalCensusRecords::Import diff --git a/app/models/budget/content_block.rb b/app/models/budget/content_block.rb index fef73dc9a..95608f30d 100644 --- a/app/models/budget/content_block.rb +++ b/app/models/budget/content_block.rb @@ -1,6 +1,6 @@ class Budget class ContentBlock < ApplicationRecord - validates :locale, presence: true, inclusion: { in: I18n.available_locales.map(&:to_s) } + validates :locale, presence: true, inclusion: { in: ->(*) { Setting.enabled_locales.map(&:to_s) }} validates :heading, presence: true, uniqueness: { scope: :locale } belongs_to :heading diff --git a/app/models/concerns/globalizable.rb b/app/models/concerns/globalizable.rb index 8b9ea9527..5578c37db 100644 --- a/app/models/concerns/globalizable.rb +++ b/app/models/concerns/globalizable.rb @@ -13,10 +13,6 @@ module Globalizable translations.reject(&:marked_for_destruction?).map(&:locale) end - def locales_marked_for_destruction - I18n.available_locales - locales_not_marked_for_destruction - end - def locales_persisted_and_marked_for_destruction translations.select { |t| t.persisted? && t.marked_for_destruction? }.map(&:locale) end @@ -86,7 +82,7 @@ module Globalizable translation_class.instance_eval do validates method, length: options[:length], - if: lambda { |translation| translation.locale == I18n.default_locale } + if: lambda { |translation| translation.locale == Setting.default_locale } end if options.count > 1 translation_class.instance_eval do diff --git a/app/models/i18n_content.rb b/app/models/i18n_content.rb index c17a7dee2..72c656c95 100644 --- a/app/models/i18n_content.rb +++ b/app/models/i18n_content.rb @@ -119,7 +119,7 @@ class I18nContent < ApplicationRecord end end - def self.update(contents, enabled_translations = I18n.available_locales) + def self.update(contents, enabled_translations = Setting.enabled_locales) contents.each do |content| values = content[:values].slice(*translation_params(enabled_translations)) diff --git a/app/models/i18n_content_translation.rb b/app/models/i18n_content_translation.rb index 4e754a3a5..165dd8a60 100644 --- a/app/models/i18n_content_translation.rb +++ b/app/models/i18n_content_translation.rb @@ -1,5 +1,5 @@ class I18nContentTranslation < ApplicationRecord - def self.existing_languages - self.select(:locale).distinct.map { |l| l.locale.to_sym }.to_a + def self.existing_locales + distinct.pluck(:locale).map(&:to_sym) end end diff --git a/app/models/setting.rb b/app/models/setting.rb index 5427afccf..7a69b569d 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -95,6 +95,8 @@ class Setting < ApplicationRecord "html.per_page_code_body": "", # Code to be included at the top (inside ) of every page (useful for tracking) "html.per_page_code_head": "", + "locales.enabled": nil, + "locales.default": nil, "map.latitude": 51.48, "map.longitude": 0.0, "map.zoom": 10, @@ -219,5 +221,20 @@ class Setting < ApplicationRecord def archived_proposals_date_limit Setting["months_to_archive_proposals"].to_i.months.ago end + + def enabled_locales + locales = Setting["locales.enabled"].to_s.split.map(&:to_sym) + + [ + default_locale, + *((locales & I18n.available_locales).presence || I18n.available_locales) + ].uniq + end + + def default_locale + locale = Setting["locales.default"].to_s.strip.to_sym + + ([locale] & I18n.available_locales).first || I18n.default_locale + end end end diff --git a/app/models/setting/locales_settings.rb b/app/models/setting/locales_settings.rb new file mode 100644 index 000000000..26db131a9 --- /dev/null +++ b/app/models/setting/locales_settings.rb @@ -0,0 +1,23 @@ +class Setting + class LocalesSettings + include ActiveModel::Model + include ActiveModel::Attributes + + attribute :enabled, array: true, default: -> { Setting.enabled_locales } + attribute :default, default: -> { Setting.default_locale } + + def persisted? + true + end + + def update(attributes) + assign_attributes(attributes) + + Setting.transaction do + Setting["locales.default"] = default + Setting["locales.enabled"] = [default, *enabled].join(" ") + end + end + alias_method :update!, :update + end +end diff --git a/app/models/site_customization/content_block.rb b/app/models/site_customization/content_block.rb index 7d42817e6..6009505b7 100644 --- a/app/models/site_customization/content_block.rb +++ b/app/models/site_customization/content_block.rb @@ -1,11 +1,10 @@ class SiteCustomization::ContentBlock < ApplicationRecord VALID_BLOCKS = %w[top_links footer footer_legal subnavigation_left subnavigation_right].freeze - validates :locale, presence: true, inclusion: { in: I18n.available_locales.map(&:to_s) } + validates :locale, presence: true, inclusion: { in: ->(*) { Setting.enabled_locales.map(&:to_s) }} validates :name, presence: true, uniqueness: { scope: :locale }, inclusion: { in: ->(*) { VALID_BLOCKS }} - def self.block_for(name, locale) - locale ||= I18n.default_locale + def self.block_for(name, locale = I18n.locale) find_by(name: name, locale: locale)&.body end end diff --git a/app/models/user.rb b/app/models/user.rb index d13c27b2f..2fbfd9fed 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -339,7 +339,7 @@ class User < ApplicationRecord end def locale - self[:locale] || I18n.default_locale.to_s + self[:locale] || Setting.default_locale.to_s end def confirmation_required? diff --git a/app/views/admin/legislation/homepages/_form.html.erb b/app/views/admin/legislation/homepages/_form.html.erb index 4a752569c..b2a3e42e5 100644 --- a/app/views/admin/legislation/homepages/_form.html.erb +++ b/app/views/admin/legislation/homepages/_form.html.erb @@ -1,7 +1,4 @@ -<%= render "shared/globalize_locales", - resource: @process, - display_style: lambda { |locale| enable_translation_style(@process, locale) }, - manage_languages: false %> +<%= render "shared/globalize_locales", resource: @process, manage_languages: false %> <%= translatable_form_for [:admin, @process], url: url do |f| %> diff --git a/app/views/admin/legislation/milestones/_summary_form.html.erb b/app/views/admin/legislation/milestones/_summary_form.html.erb index 27442d377..1e6b0b4a9 100644 --- a/app/views/admin/legislation/milestones/_summary_form.html.erb +++ b/app/views/admin/legislation/milestones/_summary_form.html.erb @@ -1,7 +1,4 @@ -<%= render "shared/globalize_locales", - resource: @process, - display_style: lambda { |locale| enable_translation_style(@process, locale) }, - manage_languages: false %> +<%= render "shared/globalize_locales", resource: @process, manage_languages: false %> <%= translatable_form_for [:admin, @process] do |f| %>
diff --git a/app/views/admin/locales/show.html.erb b/app/views/admin/locales/show.html.erb new file mode 100644 index 000000000..994174d9f --- /dev/null +++ b/app/views/admin/locales/show.html.erb @@ -0,0 +1 @@ +<%= render Admin::Locales::ShowComponent.new(@locales_settings) %> diff --git a/app/views/admin/site_customization/content_blocks/_form.html.erb b/app/views/admin/site_customization/content_blocks/_form.html.erb index 6f2b99a18..7879c6195 100644 --- a/app/views/admin/site_customization/content_blocks/_form.html.erb +++ b/app/views/admin/site_customization/content_blocks/_form.html.erb @@ -1,5 +1,5 @@ <% if @is_heading_content_block %> - <%= render "form_heading_content_block" %> + <%= render Admin::SiteCustomization::ContentBlocks::FormHeadingContentBlockComponent.new(@content_block) %> <% else %> - <%= render "form_content_block" %> + <%= render Admin::SiteCustomization::ContentBlocks::FormContentBlockComponent.new(@content_block) %> <% end %> diff --git a/app/views/admin/site_customization/information_texts/_globalize_locales.html.erb b/app/views/admin/site_customization/information_texts/_globalize_locales.html.erb deleted file mode 100644 index da4297ad1..000000000 --- a/app/views/admin/site_customization/information_texts/_globalize_locales.html.erb +++ /dev/null @@ -1,4 +0,0 @@ -<%= render "shared/common_globalize_locales", - resource: nil, - display_style: lambda { |locale| site_customization_display_translation_style(locale) }, - manage_languages: defined?(manage_languages) ? manage_languages : true %> diff --git a/app/views/admin/site_customization/information_texts/index.html.erb b/app/views/admin/site_customization/information_texts/index.html.erb index 16d3d7f32..c6a2fea43 100644 --- a/app/views/admin/site_customization/information_texts/index.html.erb +++ b/app/views/admin/site_customization/information_texts/index.html.erb @@ -4,7 +4,6 @@ <%= render "tabs" %> -
diff --git a/app/views/shared/_globalize_locales.html.erb b/app/views/shared/_globalize_locales.html.erb index 88aa4064b..e35125c6f 100644 --- a/app/views/shared/_globalize_locales.html.erb +++ b/app/views/shared/_globalize_locales.html.erb @@ -1,6 +1,6 @@ <% if translations_interface_enabled? %> - <%= render "shared/common_globalize_locales", - resource: resource, - display_style: lambda { |locale| enable_translation_style(resource, locale) }, - manage_languages: defined?(manage_languages) ? manage_languages : true %> + <%= render Shared::GlobalizeLocalesComponent.new( + resource, + manage_languages: defined?(manage_languages) ? manage_languages : true + ) %> <% end %> diff --git a/config/application.rb b/config/application.rb index deaf238f6..ca6317e38 100644 --- a/config/application.rb +++ b/config/application.rb @@ -136,6 +136,7 @@ module Consul [ "app/components/custom", "app/controllers/custom", + "app/form_builders/custom", "app/graphql/custom", "app/lib/custom", "app/mailers/custom", diff --git a/config/locales/en/activemodel.yml b/config/locales/en/activemodel.yml index ea83bed5e..346b0e3d5 100644 --- a/config/locales/en/activemodel.yml +++ b/config/locales/en/activemodel.yml @@ -38,6 +38,9 @@ en: year_of_birth: "Year born" local_census_records/import: file: File + setting/locales_settings: + default: Default language + enabled: Enabled languages errors: models: local_census_records/import: diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 66ff65ea1..3b70a864d 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -710,6 +710,11 @@ en: milestones: index: title: Following + locales: + default_help_text: "This is the default language of the application, and changing it will affect every user visiting the website for the first time." + enabled_help_text: The default language, selected above, will be included automatically. + update: + notice: Languages updated successfully managers: index: title: Managers @@ -727,11 +732,12 @@ en: menu: activity: Moderator activity admin: Admin menu - banner: Manage banners + banner: Banners proposals: Proposals proposals_topics: Proposals topics budgets: Participatory budgets - geozones: Manage geozones + geozones: Geozones + locales: Languages hidden_comments: Hidden comments hidden_debates: Hidden debates hidden_proposals: Hidden proposals @@ -752,7 +758,7 @@ en: polls: Polls poll_booths: Booths location poll_booth_assignments: Booths Assignments - poll_shifts: Manage shifts + poll_shifts: Shifts Assignments officials: Officials organizations: Organisations settings: Global settings @@ -794,7 +800,7 @@ en: dashboard_actions: Resources and actions debates: "Debates" comments: "Comments" - local_census_records: Manage local census + local_census_records: Local census machine_learning: "AI / Machine learning" multitenancy: Multitenancy administrators: @@ -1232,7 +1238,7 @@ en: show: location: "Location" booth: - shifts: "Manage shifts" + shifts: "Shifts Assignments" officials: edit: destroy: Remove "Official" status @@ -1713,7 +1719,7 @@ en: empty: "There are no changes logged" local_census_records: index: - title: Manage local census + title: Local census create: Create new local census record no_local_census_records: There are no local census records. document_type: Document type @@ -1738,7 +1744,7 @@ en: create: notice: Local census records import process executed successfully! show: - title: Manage local census + title: Local census subtitle: Import process results import: Import again errored: Errored rows diff --git a/config/locales/es/activemodel.yml b/config/locales/es/activemodel.yml index e303303d7..eaf66fc74 100644 --- a/config/locales/es/activemodel.yml +++ b/config/locales/es/activemodel.yml @@ -38,6 +38,9 @@ es: year_of_birth: "Año de nacimiento" local_census_records/import: file: Archivo + setting/locales_settings: + default: Idioma por defecto + enabled: Idiomas habilitados errors: models: local_census_records/import: diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 81297a548..513ae0306 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -710,6 +710,11 @@ es: milestones: index: title: Seguimiento + locales: + default_help_text: "Cambiar el idioma por defecto afectará a todos los usuarios que visiten la página por primera vez." + enabled_help_text: El idioma por defecto, seleccionado con anterioridad, se habilitará automáticamente. + update: + notice: Idiomas actualizados con éxito managers: index: title: Gestores @@ -727,11 +732,12 @@ es: menu: activity: Actividad de moderadores admin: Menú de administración - banner: Gestionar banners + banner: Banners proposals: Propuestas proposals_topics: Temas de propuestas budgets: Presupuestos participativos - geozones: Gestionar zonas + geozones: Zonas + locales: Idiomas hidden_comments: Comentarios ocultos hidden_debates: Debates ocultos hidden_proposals: Propuestas ocultas @@ -794,7 +800,7 @@ es: dashboard_actions: Recursos y acciones debates: "Debates" comments: "Comentarios" - local_census_records: Gestionar censo local + local_census_records: Censo local machine_learning: "IA / Machine learning" multitenancy: Multientidad administrators: @@ -1713,7 +1719,7 @@ es: empty: "No hay cambios registrados" local_census_records: index: - title: Gestionar censo local + title: Censo local create: Crear nuevo registro en el censo local no_local_census_records: No hay registros de censo local document_type: Tipo de documento @@ -1738,7 +1744,7 @@ es: create: notice: ¡Proceso de import de registros del censo local ejecutado correctamente! show: - title: Gestionar censo local + title: Censo local subtitle: Resultados del proceso de importación import: Importar otro fichero errored: Filas erróneas diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 4e72dae01..c38eaf672 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -242,6 +242,7 @@ namespace :admin do end resources :geozones, only: [:index, :new, :create, :edit, :update, :destroy] + resource :locales, only: [:show, :update] namespace :site_customization do resources :pages, except: [:show] do diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index 00f102f22..4623cdac1 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -23,7 +23,11 @@ def log(msg) end def random_locales - [I18n.default_locale, *(I18n.available_locales & %i[en es]), *I18n.available_locales.sample(4)].uniq.take(5) + [ + Setting.default_locale, + *(Setting.enabled_locales & %i[en es]), + *Setting.enabled_locales.sample(4) + ].uniq.take(5) end def random_locales_attributes(**attribute_names_with_values) diff --git a/db/dev_seeds/banners.rb b/db/dev_seeds/banners.rb index 345ae4e90..9716978ae 100644 --- a/db/dev_seeds/banners.rb +++ b/db/dev_seeds/banners.rb @@ -9,7 +9,7 @@ section "Creating banners" do post_started_at: rand((1.week.ago)..(1.day.ago)), post_ended_at: rand((1.day.ago)..(1.week.from_now)), created_at: rand((1.week.ago)..Time.current)) - I18n.available_locales.map do |locale| + Setting.enabled_locales.map do |locale| Globalize.with_locale(locale) do banner.description = "Description for locale #{locale}" banner.title = "Title for locale #{locale}" diff --git a/db/dev_seeds/polls.rb b/db/dev_seeds/polls.rb index e0b62a899..44021a782 100644 --- a/db/dev_seeds/polls.rb +++ b/db/dev_seeds/polls.rb @@ -41,7 +41,7 @@ section "Creating polls" do Poll.find_each do |poll| name = poll.name - I18n.available_locales.map do |locale| + Setting.enabled_locales.map do |locale| Globalize.with_locale(locale) do poll.name = "#{name} (#{locale})" poll.summary = "Summary for locale #{locale}" @@ -59,7 +59,7 @@ section "Creating Poll Questions & Answers" do question = Poll::Question.new(author: User.sample, title: question_title, poll: poll) - I18n.available_locales.map do |locale| + Setting.enabled_locales.map do |locale| Globalize.with_locale(locale) do question.title = "#{question_title} (#{locale})" end @@ -71,7 +71,7 @@ section "Creating Poll Questions & Answers" do title: title.capitalize, description: description, given_order: index + 1) - I18n.available_locales.map do |locale| + Setting.enabled_locales.map do |locale| Globalize.with_locale(locale) do answer.title = "#{title} (#{locale})" answer.description = "#{description} (#{locale})" @@ -235,7 +235,7 @@ section "Creating Poll Questions from Proposals" do question = Poll::Question.new(poll: poll) question.copy_attributes_from_proposal(proposal) question_title = question.title - I18n.available_locales.map do |locale| + Setting.enabled_locales.map do |locale| Globalize.with_locale(locale) do question.title = "#{question_title} (#{locale})" end @@ -247,7 +247,7 @@ section "Creating Poll Questions from Proposals" do title: title.capitalize, description: description, given_order: index + 1) - I18n.available_locales.map do |locale| + Setting.enabled_locales.map do |locale| Globalize.with_locale(locale) do answer.title = "#{title} (#{locale})" answer.description = "#{description} (#{locale})" @@ -265,7 +265,7 @@ section "Creating Successful Proposals" do question = Poll::Question.new(poll: poll) question.copy_attributes_from_proposal(proposal) question_title = question.title - I18n.available_locales.map do |locale| + Setting.enabled_locales.map do |locale| Globalize.with_locale(locale) do question.title = "#{question_title} (#{locale})" end @@ -277,7 +277,7 @@ section "Creating Successful Proposals" do title: title.capitalize, description: description, given_order: index + 1) - I18n.available_locales.map do |locale| + Setting.enabled_locales.map do |locale| Globalize.with_locale(locale) do answer.title = "#{title} (#{locale})" answer.description = "#{description} (#{locale})" diff --git a/db/pages/accessibility.rb b/db/pages/accessibility.rb index c499199ca..8d2e2d824 100644 --- a/db/pages/accessibility.rb +++ b/db/pages/accessibility.rb @@ -104,7 +104,7 @@ end if SiteCustomization::Page.find_by(slug: "accessibility").nil? page = SiteCustomization::Page.new(slug: "accessibility", status: "published") - I18n.available_locales.each do |locale| + Setting.enabled_locales.each do |locale| I18n.with_locale(locale) { generate_content(page) } end end diff --git a/db/pages/census_terms.rb b/db/pages/census_terms.rb index b5c3a43c3..27ac3fc45 100644 --- a/db/pages/census_terms.rb +++ b/db/pages/census_terms.rb @@ -7,7 +7,7 @@ end if SiteCustomization::Page.find_by(slug: "census_terms").nil? page = SiteCustomization::Page.new(slug: "census_terms", status: "published") page.print_content_flag = true - I18n.available_locales.each do |locale| + Setting.enabled_locales.each do |locale| I18n.with_locale(locale) { generate_content(page) } end end diff --git a/db/pages/conditions.rb b/db/pages/conditions.rb index 539fc6afe..314d0db61 100644 --- a/db/pages/conditions.rb +++ b/db/pages/conditions.rb @@ -8,7 +8,7 @@ end if SiteCustomization::Page.find_by(slug: "conditions").nil? page = SiteCustomization::Page.new(slug: "conditions", status: "published") page.print_content_flag = true - I18n.available_locales.each do |locale| + Setting.enabled_locales.each do |locale| I18n.with_locale(locale) { generate_content(page) } end end diff --git a/db/pages/faq.rb b/db/pages/faq.rb index 362801a2e..983b78665 100644 --- a/db/pages/faq.rb +++ b/db/pages/faq.rb @@ -5,7 +5,7 @@ def generate_content(page) end if SiteCustomization::Page.find_by(slug: "faq").nil? page = SiteCustomization::Page.new(slug: "faq", status: "published") - I18n.available_locales.each do |locale| + Setting.enabled_locales.each do |locale| I18n.with_locale(locale) { generate_content(page) } end end diff --git a/db/pages/privacy.rb b/db/pages/privacy.rb index 5f215810d..dfa82b492 100644 --- a/db/pages/privacy.rb +++ b/db/pages/privacy.rb @@ -7,7 +7,7 @@ end if SiteCustomization::Page.find_by(slug: "privacy").nil? page = SiteCustomization::Page.new(slug: "privacy", status: "published") page.print_content_flag = true - I18n.available_locales.each do |locale| + Setting.enabled_locales.each do |locale| I18n.with_locale(locale) { generate_content(page) } end end diff --git a/db/pages/welcome_level_three_verified.rb b/db/pages/welcome_level_three_verified.rb index 5467f5917..0fd6a6eac 100644 --- a/db/pages/welcome_level_three_verified.rb +++ b/db/pages/welcome_level_three_verified.rb @@ -17,7 +17,7 @@ end if SiteCustomization::Page.find_by(slug: "welcome_level_three_verified").nil? page = SiteCustomization::Page.new(slug: "welcome_level_three_verified", status: "published") - I18n.available_locales.each do |locale| + Setting.enabled_locales.each do |locale| I18n.with_locale(locale) { generate_content(page) } end end diff --git a/db/pages/welcome_level_two_verified.rb b/db/pages/welcome_level_two_verified.rb index 251fc6b04..27d2fba32 100644 --- a/db/pages/welcome_level_two_verified.rb +++ b/db/pages/welcome_level_two_verified.rb @@ -22,7 +22,7 @@ def generate_content(page) end if SiteCustomization::Page.find_by(slug: "welcome_level_two_verified").nil? page = SiteCustomization::Page.new(slug: "welcome_level_two_verified", status: "published") - I18n.available_locales.each do |locale| + Setting.enabled_locales.each do |locale| I18n.with_locale(locale) { generate_content(page) } end end diff --git a/db/pages/welcome_not_verified.rb b/db/pages/welcome_not_verified.rb index 4263130f0..946570101 100644 --- a/db/pages/welcome_not_verified.rb +++ b/db/pages/welcome_not_verified.rb @@ -22,7 +22,7 @@ def generate_content(page) end if SiteCustomization::Page.find_by(slug: "welcome_not_verified").nil? page = SiteCustomization::Page.new(slug: "welcome_not_verified", status: "published") - I18n.available_locales.each do |locale| + Setting.enabled_locales.each do |locale| I18n.with_locale(locale) { generate_content(page) } end end diff --git a/spec/components/admin/locales/form_component_spec.rb b/spec/components/admin/locales/form_component_spec.rb new file mode 100644 index 000000000..ea2398f01 --- /dev/null +++ b/spec/components/admin/locales/form_component_spec.rb @@ -0,0 +1,37 @@ +require "rails_helper" + +describe Admin::Locales::FormComponent do + let(:default_locale) { :nl } + let(:enabled_locales) { %i[en nl] } + let(:locales_settings) { Setting::LocalesSettings.new(default: default_locale, enabled: enabled_locales) } + let(:component) { Admin::Locales::FormComponent.new(locales_settings) } + + describe "default language selector" do + before { allow(I18n).to receive(:available_locales).and_return(%i[de en es nl]) } + + it "renders radio buttons when there are only a few locales" do + render_inline component + + page.find(:fieldset, "Default language") do |fieldset| + expect(fieldset).to have_checked_field "Nederlands", type: :radio + expect(fieldset).to have_unchecked_field "English", type: :radio + expect(fieldset).to have_unchecked_field "Español", type: :radio + expect(fieldset).to have_unchecked_field "Deutsch", type: :radio + end + + expect(page).not_to have_select + end + + it "renders a select when there are many locales" do + allow(component).to receive(:select_field_threshold).and_return(3) + + render_inline component + + expect(page).not_to have_field type: :radio + + expect(page).to have_select "Default language", + options: %w[English Español Deutsch Nederlands], + selected: "Nederlands" + end + end +end diff --git a/spec/components/admin/site_customization/content_blocks/form_content_block_component_spec.rb b/spec/components/admin/site_customization/content_blocks/form_content_block_component_spec.rb new file mode 100644 index 000000000..f025bd3a5 --- /dev/null +++ b/spec/components/admin/site_customization/content_blocks/form_content_block_component_spec.rb @@ -0,0 +1,19 @@ +require "rails_helper" + +describe Admin::SiteCustomization::ContentBlocks::FormContentBlockComponent do + describe "locale selector" do + let(:content_block) { create(:site_customization_content_block, locale: "de") } + let(:component) do + Admin::SiteCustomization::ContentBlocks::FormContentBlockComponent.new(content_block) + end + + it "only includes enabled settings" do + Setting["locales.default"] = "de" + Setting["locales.enabled"] = "de fr" + + render_inline component + + expect(page).to have_select "locale", options: ["de", "fr"] + end + end +end diff --git a/spec/components/admin/site_customization/content_blocks/form_heading_content_block_component_spec.rb b/spec/components/admin/site_customization/content_blocks/form_heading_content_block_component_spec.rb new file mode 100644 index 000000000..09fe4469d --- /dev/null +++ b/spec/components/admin/site_customization/content_blocks/form_heading_content_block_component_spec.rb @@ -0,0 +1,19 @@ +require "rails_helper" + +describe Admin::SiteCustomization::ContentBlocks::FormHeadingContentBlockComponent do + describe "locale selector" do + let(:content_block) { create(:heading_content_block, locale: "de") } + let(:component) do + Admin::SiteCustomization::ContentBlocks::FormHeadingContentBlockComponent.new(content_block) + end + + it "only includes enabled settings" do + Setting["locales.default"] = "de" + Setting["locales.enabled"] = "de fr" + + render_inline component + + expect(page).to have_select "locale", options: ["de", "fr"] + end + end +end diff --git a/spec/components/admin/site_customization/information_texts/form_component_spec.rb b/spec/components/admin/site_customization/information_texts/form_component_spec.rb new file mode 100644 index 000000000..614ef28f9 --- /dev/null +++ b/spec/components/admin/site_customization/information_texts/form_component_spec.rb @@ -0,0 +1,29 @@ +require "rails_helper" + +describe Admin::SiteCustomization::InformationTexts::FormComponent do + describe "enabled_translations fields" do + it "renders fields for enabled locales" do + Setting["locales.enabled"] = "en es" + content = create(:i18n_content) + + render_inline Admin::SiteCustomization::InformationTexts::FormComponent.new([[content]]) + + expect(page).to have_css "input[name^='enabled_translations']", count: 2, visible: :all + expect(page).to have_css "input[name='enabled_translations[en]']", visible: :hidden + expect(page).to have_css "input[name='enabled_translations[es]']", visible: :hidden + end + end + + describe "text fields" do + it "renders fields for enabled locales" do + Setting["locales.enabled"] = "en es" + content = create(:i18n_content, key: "system.failure") + + render_inline Admin::SiteCustomization::InformationTexts::FormComponent.new([[content]]) + + expect(page).to have_css "textarea[name^='contents[content_system.failure]']", count: 2, visible: :all + expect(page).to have_field "contents[content_system.failure]values[value_en]" + expect(page).to have_field "contents[content_system.failure]values[value_es]" + end + end +end diff --git a/spec/components/layout/locale_switcher_component_spec.rb b/spec/components/layout/locale_switcher_component_spec.rb index 1063ede2f..8678ef566 100644 --- a/spec/components/layout/locale_switcher_component_spec.rb +++ b/spec/components/layout/locale_switcher_component_spec.rb @@ -97,4 +97,21 @@ describe Layout::LocaleSwitcherComponent do expect(page).to have_css "[href='/?locale=en'][data-turbolinks=true]" end end + + context "when not all available locales are enabled" do + before do + allow(I18n).to receive(:available_locales).and_return(%i[en es fr]) + Setting["locales.default"] = "es" + Setting["locales.enabled"] = "es fr" + end + + it "displays the enabled locales" do + render_inline component + + expect(page).to have_link count: 2 + expect(page).to have_link "Español" + expect(page).to have_link "Français" + expect(page).not_to have_link "English" + end + end end diff --git a/spec/components/shared/globalize_locales_component_spec.rb b/spec/components/shared/globalize_locales_component_spec.rb new file mode 100644 index 000000000..da2dae47f --- /dev/null +++ b/spec/components/shared/globalize_locales_component_spec.rb @@ -0,0 +1,49 @@ +require "rails_helper" + +describe Shared::GlobalizeLocalesComponent do + describe "Language selector" do + it "only includes enabled locales" do + Setting["locales.enabled"] = "en nl" + + I18n.with_locale(:en) do + render_inline Shared::GlobalizeLocalesComponent.new + + expect(page).to have_select options: ["Choose language", "English"] + end + + I18n.with_locale(:es) do + render_inline Shared::GlobalizeLocalesComponent.new + + expect(page).to have_select options: ["Seleccionar idioma"] + end + end + end + + describe "links to destroy languages" do + it "only includes enabled locales" do + Setting["locales.enabled"] = "en nl" + + I18n.with_locale(:en) do + render_inline Shared::GlobalizeLocalesComponent.new + + expect(page).to have_css "a[data-locale]", count: 1 + end + + I18n.with_locale(:es) do + render_inline Shared::GlobalizeLocalesComponent.new + + expect(page).not_to have_css "a[data-locale]" + end + end + end + + describe "Add language selector" do + it "only includes enabled locales" do + Setting["locales.enabled"] = "en nl" + + render_inline Shared::GlobalizeLocalesComponent.new + + expect(page).to have_select options: ["Add language", "English", "Nederlands"] + end + end +end diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index c6d77bfe4..921a3256e 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -1,6 +1,14 @@ require "rails_helper" describe ApplicationController do + controller do + skip_authorization_check + + def index + render plain: I18n.locale + end + end + describe "#current_budget" do it "returns the last budget that is not in draft phase" do create(:budget, :finished, created_at: 2.years.ago, name: "Old") @@ -12,4 +20,68 @@ describe ApplicationController do expect(budget.name).to eq("Current") end end + + describe "#switch_locale" do + it "uses the default locale by default" do + Setting["locales.default"] = "pt-BR" + + get :index + + expect(response.body).to eq "pt-BR" + end + + it "uses the locale in the parameters when it's there" do + get :index, params: { locale: :es } + + expect(response.body).to eq "es" + end + + it "uses the locale in the session if there are no parameters" do + get :index, params: { locale: :es } + + expect(response.body).to eq "es" + + get :index + + expect(response.body).to eq "es" + end + + it "uses the locale in the parameters even when it's in the session" do + get :index + + expect(response.body).to eq "en" + + get :index, params: { locale: :es } + + expect(response.body).to eq "es" + end + + it "only accepts enabled locales" do + Setting["locales.enabled"] = "en es fr" + + get :index, params: { locale: :es } + + expect(response.body).to eq "es" + + get :index, params: { locale: :de } + + expect(response.body).to eq "es" + + get :index, params: { locale: :fr } + + expect(response.body).to eq "fr" + end + + context "authenticated user" do + let(:user) { create(:user) } + before { sign_in(user) } + + it "updates the prefered locale when it's in the parameters" do + get :index, params: { locale: :es } + + expect(user.reload.locale).to eq "es" + expect(response.body).to eq "es" + end + end + end end diff --git a/spec/controllers/management/base_controller_spec.rb b/spec/controllers/management/base_controller_spec.rb index da0a15cbb..35385f73d 100644 --- a/spec/controllers/management/base_controller_spec.rb +++ b/spec/controllers/management/base_controller_spec.rb @@ -1,6 +1,16 @@ require "rails_helper" describe Management::BaseController do + before { session[:manager] = double } + + controller do + skip_authorization_check + + def index + render plain: I18n.locale + end + end + describe "managed_user" do it "returns existent user with session document info if present" do session[:document_type] = "1" @@ -21,4 +31,56 @@ describe Management::BaseController do expect(managed_user.document_number).to eq "333333333E" end end + + describe "#switch_locale" do + it "uses the default locale by default" do + Setting["locales.default"] = "pt-BR" + + get :index + + expect(response.body).to eq "pt-BR" + end + + it "uses the locale in the parameters when it's there" do + get :index, params: { locale: :es } + + expect(response.body).to eq "es" + end + + it "uses the locale in the session if there are no parameters" do + get :index, params: { locale: :es } + + expect(response.body).to eq "es" + + get :index + + expect(response.body).to eq "es" + end + + it "uses the locale in the parameters even when it's in the session" do + get :index + + expect(response.body).to eq "en" + + get :index, params: { locale: :es } + + expect(response.body).to eq "es" + end + + it "only accepts enabled locales" do + Setting["locales.enabled"] = "en es fr" + + get :index, params: { locale: :es } + + expect(response.body).to eq "es" + + get :index, params: { locale: :de } + + expect(response.body).to eq "es" + + get :index, params: { locale: :fr } + + expect(response.body).to eq "fr" + end + end end diff --git a/spec/controllers/subscriptions_controller_spec.rb b/spec/controllers/subscriptions_controller_spec.rb index 3c1d39414..11a96fd8d 100644 --- a/spec/controllers/subscriptions_controller_spec.rb +++ b/spec/controllers/subscriptions_controller_spec.rb @@ -19,5 +19,24 @@ describe SubscriptionsController do expect(response).to redirect_to "/" expect(flash[:alert]).to eq "No tienes permiso para acceder a esta página." end + + it "uses the user locale where there's no locale in the parameters" do + create(:user, locale: "es", subscriptions_token: "mytoken") + + get :edit, params: { token: "mytoken" } + + expect(session[:locale]).to eq "es" + end + + it "only accepts enabled locales" do + Setting["locales.default"] = "fr" + Setting["locales.enabled"] = "fr nl" + + create(:user, locale: "es", subscriptions_token: "mytoken") + + get :edit, params: { token: "mytoken" } + + expect(session[:locale]).to eq "fr" + end end end diff --git a/spec/lib/consul_form_builder_spec.rb b/spec/form_builders/consul_form_builder_spec.rb similarity index 100% rename from spec/lib/consul_form_builder_spec.rb rename to spec/form_builders/consul_form_builder_spec.rb diff --git a/spec/form_builders/translatable_form_builder_spec.rb b/spec/form_builders/translatable_form_builder_spec.rb new file mode 100644 index 000000000..fd8747f3f --- /dev/null +++ b/spec/form_builders/translatable_form_builder_spec.rb @@ -0,0 +1,46 @@ +require "rails_helper" + +describe TranslatableFormBuilder do + before do + dummy_banner = Class.new(ApplicationRecord) do + def self.name + "DummyBanner" + end + self.table_name = "banners" + + translates :title, touch: true + include Globalizable + has_many :translations, class_name: "DummyBanner::Translation", foreign_key: "banner_id" + end + + stub_const("DummyBanner", dummy_banner) + end + + let(:builder) do + TranslatableFormBuilder.new(:dummy, DummyBanner.new, ApplicationController.new.view_context, {}) + end + + describe "#translatable_fields" do + it "renders fields for the enabled locales when the translation interface is enabled" do + Setting["feature.translation_interface"] = true + Setting["locales.enabled"] = "en fr" + + builder.translatable_fields do |translations_builder| + render translations_builder.text_field :title + end + + expect(page).to have_field "Title", count: 2 + end + end + + attr_reader :content + + def render(content) + @content ||= "" + @content << content + end + + def page + Capybara::Node::Simple.new(content) + end +end diff --git a/spec/lib/search_dictionary_selector_spec.rb b/spec/lib/search_dictionary_selector_spec.rb index d9a618b25..b0f2cbc29 100644 --- a/spec/lib/search_dictionary_selector_spec.rb +++ b/spec/lib/search_dictionary_selector_spec.rb @@ -3,27 +3,23 @@ require "rails_helper" describe SearchDictionarySelector do context "from I18n default locale" do before { allow(subject).to receive(:call).and_call_original } - around do |example| - original_i18n_default = I18n.default_locale - begin - example.run - ensure - I18n.default_locale = original_i18n_default - end - end it "returns correct dictionary for simple locale" do - I18n.default_locale = :es + Setting["locales.default"] = "es" + expect(subject.call).to eq("spanish") end it "returns correct dictionary for compound locale" do - I18n.default_locale = :"pt-BR" + Setting["locales.default"] = "pt-BR" + expect(subject.call).to eq("portuguese") end it "returns simple for unsupported locale" do - expect(I18n).to receive(:default_locale).and_return(:pl) # avoiding I18n::InvalidLocale + allow(I18n).to receive(:available_locales).and_return(%i[en pl]) + Setting["locales.default"] = "pl" + expect(subject.call).to eq("simple") end end diff --git a/spec/mailers/mailer_spec.rb b/spec/mailers/mailer_spec.rb index af991075c..aed829ae2 100644 --- a/spec/mailers/mailer_spec.rb +++ b/spec/mailers/mailer_spec.rb @@ -30,6 +30,16 @@ describe Mailer do end end + describe "#user_invite" do + it "uses the default locale setting" do + Setting["locales.default"] = "es" + + Mailer.user_invite("invited@consul.dev").deliver_now + + expect(ActionMailer::Base.deliveries.last.body.to_s).to match " "Oh, yeah" }}]) + + expect(I18nContent.all).to be_empty + end + + it "uses different enabled translations when given a parameter" do + Setting["locales.enabled"] = "en es" + I18nContent.update([{ id: "shared.yes", values: { "value_en" => "Oh, yeah" }}], [:es]) expect(I18nContent.all).to be_empty diff --git a/spec/models/setting/locales_settings_spec.rb b/spec/models/setting/locales_settings_spec.rb new file mode 100644 index 000000000..1b21ec582 --- /dev/null +++ b/spec/models/setting/locales_settings_spec.rb @@ -0,0 +1,13 @@ +require "rails_helper" + +describe Setting::LocalesSettings do + describe "#update!" do + it "saves the default locale in the enabled ones when nothing is enabled" do + Setting::LocalesSettings.new.update!(default: "es", enabled: %w[]) + updated_locales_settings = Setting::LocalesSettings.new + + expect(updated_locales_settings.default).to eq :es + expect(updated_locales_settings.enabled).to match_array [:es] + end + end +end diff --git a/spec/models/setting_spec.rb b/spec/models/setting_spec.rb index d31c4ef3c..f3a87ce22 100644 --- a/spec/models/setting_spec.rb +++ b/spec/models/setting_spec.rb @@ -258,4 +258,96 @@ describe Setting do expect(Setting.force_presence_postal_code?).to be true end end + + describe ".available_locales" do + before { allow(I18n).to receive_messages(default_locale: :de, available_locales: %i[de en es pt-BR]) } + + it "uses I18n available locales by default" do + Setting["locales.enabled"] = "" + + expect(Setting.enabled_locales).to eq %i[de en es pt-BR] + end + + it "defines available locales with a space-separated list" do + Setting["locales.enabled"] = "de es" + + expect(Setting.enabled_locales).to eq %i[de es] + end + + it "handles locales which include a dash" do + Setting["locales.enabled"] = "de en pt-BR" + + expect(Setting.enabled_locales).to eq %i[de en pt-BR] + end + + it "adds the default locale to the list of available locales" do + Setting["locales.enabled"] = "en es" + + expect(Setting.enabled_locales).to eq %i[de en es] + end + + it "ignores extra whitespace between locales" do + Setting["locales.enabled"] = " de en pt-BR " + + expect(Setting.enabled_locales).to eq %i[de en pt-BR] + end + + it "ignores locales which aren't available" do + Setting["locales.enabled"] = "de es en-US fr zh-CN" + + expect(Setting.enabled_locales).to eq %i[de es] + end + + it "ignores words that don't make sense in this context" do + Setting["locales.enabled"] = "yes de 1234 en SuperCool" + + expect(Setting.enabled_locales).to eq %i[de en] + end + + it "uses I18n available locales when no locale is available" do + Setting["locales.enabled"] = "nl fr zh-CN" + + expect(Setting.enabled_locales).to eq %i[de en es pt-BR] + end + end + + describe ".default_locale" do + before { allow(I18n).to receive_messages(default_locale: :en, available_locales: %i[de en es pt-BR]) } + + it "uses I18n default locale by default" do + Setting["locales.default"] = "" + + expect(Setting.default_locale).to eq :en + end + + it "allows defining the default locale" do + Setting["locales.default"] = "de" + + expect(Setting.default_locale).to eq :de + end + + it "handles locales which include a dash" do + Setting["locales.default"] = "pt-BR" + + expect(Setting.default_locale).to eq :"pt-BR" + end + + it "ignores extra whitespace in the locale name" do + Setting["locales.default"] = " es " + + expect(Setting.default_locale).to eq :es + end + + it "ignores locales which aren't available" do + Setting["locales.default"] = "fr" + + expect(Setting.default_locale).to eq :en + end + + it "ignores an array of several locales" do + Setting["locales.default"] = "de es" + + expect(Setting.default_locale).to eq :en + end + end end diff --git a/spec/models/site_customization/content_block_spec.rb b/spec/models/site_customization/content_block_spec.rb index a61753f12..d0b5d276b 100644 --- a/spec/models/site_customization/content_block_spec.rb +++ b/spec/models/site_customization/content_block_spec.rb @@ -27,4 +27,13 @@ RSpec.describe SiteCustomization::ContentBlock do block.name = "top_links" expect(block).not_to be_valid end + + it "is not valid with a disabled locale" do + Setting["locales.default"] = "nl" + Setting["locales.enabled"] = "nl pt-BR" + + block.locale = "en" + + expect(block).not_to be_valid + end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 62a0663be..0e9d4fe22 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -81,6 +81,16 @@ describe User do end end + describe "#locale" do + it "defaults to the default locale setting" do + Setting["locales.default"] = "nl" + + user = build(:user, locale: nil) + + expect(user.locale).to eq "nl" + end + end + describe "preferences" do describe "email_on_comment" do it "is false by default" do diff --git a/spec/system/admin/banners_spec.rb b/spec/system/admin/banners_spec.rb index c604f6d6e..33d67c405 100644 --- a/spec/system/admin/banners_spec.rb +++ b/spec/system/admin/banners_spec.rb @@ -65,7 +65,7 @@ describe "Admin banners magement", :admin do within("#side_menu") do click_button "Site content" - click_link "Manage banners" + click_link "Banners" end click_link "Create banner" @@ -134,7 +134,7 @@ describe "Admin banners magement", :admin do within("#side_menu") do click_button "Site content" - click_link "Manage banners" + click_link "Banners" end click_link "Edit" diff --git a/spec/system/admin/geozones_spec.rb b/spec/system/admin/geozones_spec.rb index 384cccc73..3ece9f6f4 100644 --- a/spec/system/admin/geozones_spec.rb +++ b/spec/system/admin/geozones_spec.rb @@ -16,7 +16,7 @@ describe "Admin geozones", :admin do within("#side_menu") do click_button "Settings" - click_link "Manage geozones" + click_link "Geozones" end click_link "Create geozone" diff --git a/spec/system/admin/locales_spec.rb b/spec/system/admin/locales_spec.rb new file mode 100644 index 000000000..46b5ee2a2 --- /dev/null +++ b/spec/system/admin/locales_spec.rb @@ -0,0 +1,54 @@ +require "rails_helper" + +describe "Locales management", :admin do + scenario "Navigate to languages page and update them" do + allow(I18n).to receive(:available_locales).and_return(%i[de en es fr]) + Setting["locales.default"] = "en" + Setting["locales.enabled"] = "en de" + + visit admin_root_path + + within ".locale" do + expect(page).to have_css "[aria-current]", exact_text: "English" + + expect(page).to have_link "English" + expect(page).to have_link "Deutsch" + expect(page).not_to have_link "Français" + expect(page).not_to have_link "Español" + end + + within "#admin_menu" do + expect(page).not_to have_link "Languages" + + click_button "Settings" + click_link "Languages" + + expect(page).to have_css "[aria-current]", exact_text: "Languages" + expect(page).to have_link "Languages" + end + + within_fieldset "Default language" do + expect(page).to have_checked_field "English" + + choose "Español" + end + + within_fieldset "Enabled languages" do + uncheck "English" + check "Français" + end + + click_button "Save changes" + + expect(page).to have_content "Languages updated successfully" + + within ".locale" do + expect(page).to have_css "[aria-current]", exact_text: "Español" + + expect(page).to have_link "Français" + expect(page).to have_link "Español" + expect(page).to have_link "Deutsch" + expect(page).not_to have_link "English" + end + end +end diff --git a/spec/system/admin/poll/booths_spec.rb b/spec/system/admin/poll/booths_spec.rb index 392f01b62..9462358df 100644 --- a/spec/system/admin/poll/booths_spec.rb +++ b/spec/system/admin/poll/booths_spec.rb @@ -39,7 +39,7 @@ describe "Admin booths", :admin do within("#side_menu") do click_button "Voting booths" - click_link "Manage shifts" + click_link "Shifts Assignments" end expect(page).to have_css(".booth", count: 1) @@ -80,7 +80,7 @@ describe "Admin booths", :admin do visit admin_booths_path within("#booth_#{booth.id}") do - expect(page).not_to have_link "Manage shifts" + expect(page).not_to have_link "Shifts Assignments" click_link "Edit" end @@ -105,7 +105,7 @@ describe "Admin booths", :admin do visit available_admin_booths_path within("#booth_#{booth.id}") do - click_link "Manage shifts" + click_link "Shifts Assignments" end click_link "Go back" diff --git a/spec/system/admin/poll/shifts_spec.rb b/spec/system/admin/poll/shifts_spec.rb index a5e25a554..ad55359f8 100644 --- a/spec/system/admin/poll/shifts_spec.rb +++ b/spec/system/admin/poll/shifts_spec.rb @@ -44,7 +44,7 @@ describe "Admin shifts", :admin do visit available_admin_booths_path within("#booth_#{booth.id}") do - click_link "Manage shifts" + click_link "Shifts Assignments" end expect(page).to have_content "This booth has no shifts" @@ -71,7 +71,7 @@ describe "Admin shifts", :admin do visit available_admin_booths_path within("#booth_#{booth.id}") do - click_link "Manage shifts" + click_link "Shifts Assignments" end expect(page).to have_css(".shift", count: 1) @@ -117,7 +117,7 @@ describe "Admin shifts", :admin do visit available_admin_booths_path within("#booth_#{booth.id}") do - click_link "Manage shifts" + click_link "Shifts Assignments" end expect(page).to have_css(".shift", count: 2) @@ -159,7 +159,7 @@ describe "Admin shifts", :admin do visit available_admin_booths_path within("#booth_#{booth.id}") do - click_link "Manage shifts" + click_link "Shifts Assignments" end expect(page).to have_content "This booth has no shifts" @@ -182,7 +182,7 @@ describe "Admin shifts", :admin do visit available_admin_booths_path within("#booth_#{booth.id}") do - click_link "Manage shifts" + click_link "Shifts Assignments" end expect(page).to have_css(".shift", count: 1) @@ -208,7 +208,7 @@ describe "Admin shifts", :admin do visit available_admin_booths_path within("#booth_#{booth.id}") do - click_link "Manage shifts" + click_link "Shifts Assignments" end expect(page).to have_css(".shift", count: 1) @@ -237,7 +237,7 @@ describe "Admin shifts", :admin do visit available_admin_booths_path within("#booth_#{booth.id}") do - click_link "Manage shifts" + click_link "Shifts Assignments" end expect(page).to have_css(".shift", count: 1)