# frozen_string_literal: true module Decidim module Admin # This class contains helpers needed in order for component settings to # properly render. module SettingsHelper include Decidim::ScopesHelper TYPES = { boolean: :check_box, integer: :number_field, string: :text_field, text: :text_area, scope: :scope_field, enum: :collection_radio_buttons }.freeze # Public: Renders a form field that matches a settings attribute's # type. # # form - The form in which to render the field. # attribute - The Settings::Attribute instance with the # description of the attribute. # name - The name of the field. # options - Extra options to be passed to the field helper. # # Returns a rendered form field. def settings_attribute_input(form, attribute, name, i18n_scope, options = {}) form_method = form_method_for_attribute(attribute) container_class = "#{name}_container" if options[:readonly] container_class += " readonly_container" help_text = text_for_setting(name, "readonly", i18n_scope) end help_text ||= text_for_setting(name, "help", i18n_scope) help_text_options = help_text ? { help_text: help_text } : {} options = { label: t(name, scope: i18n_scope) } .merge(help_text_options) .merge(extra_options_for_type(form_method)) .merge(options) content_tag(:div, class: container_class) do if attribute.translated? options[:tabs_id] = "#{options.delete(:tabs_prefix)}-#{name}-tabs" form.send(:translated, form_method, name, options) elsif form_method == :collection_radio_buttons render_enum_form_field(form, attribute, name, i18n_scope, options) elsif form_method == :scope_field scopes_picker_field(form, name) else form.send(form_method, name, options) end end.html_safe end private # Returns a radio buttons collection input for the given attribute def render_enum_form_field(form, attribute, name, i18n_scope, options) html = label_tag(name) do concat options[:label] concat tag(:br) concat form.collection_radio_buttons(name, build_enum_choices(name, i18n_scope, attribute.build_choices), :last, :first, { checked: form.object.send(name) }, options) { |b| b.label { b.radio_button + b.text } } end html << content_tag(:p, options[:help_text], class: "help-text") if options[:help_text] html end # Returns a translation or nil. If nil, ZURB Foundation won't add the help_text. def text_for_setting(name, suffix, i18n_scope) key = "#{i18n_scope}.#{name}_#{suffix}" return t(key) if I18n.exists?(key) end # Returns the FormBuilder's method used to render def form_method_for_attribute(attribute) return :editor if attribute.type.to_sym == :text && attribute.editor? TYPES[attribute.type.to_sym] end # Handles special cases. # Returns an empty Hash or a Hash with extra HTML options. def extra_options_for_type(input_type) case input_type when :text_area { rows: 6 } else {} end end # Build options for enum attributes def build_enum_choices(name, i18n_scope, choices) choices.map do |choice| [t("#{name}_choices.#{choice}", scope: i18n_scope), choice] end end end end end