diff --git a/app/controllers/concerns/setting_concern.rb b/app/controllers/concerns/setting_concern.rb index 6cf5d77..b59acdc 100644 --- a/app/controllers/concerns/setting_concern.rb +++ b/app/controllers/concerns/setting_concern.rb @@ -10,6 +10,8 @@ module SettingConcern def show @setting = target_class.new(initial_params) + @_used_param = {} + @_used_section = {} render "shared/settings/show" end @@ -32,7 +34,7 @@ module SettingConcern private def setting_params - params.require(target_class.to_s.underscore.gsub("/", "_")).permit(*target_class.const_get(:KEYS)) + params.require(target_class.to_s.underscore.gsub("/", "_")).permit(*target_plugin_params) end def initial_params @@ -40,10 +42,46 @@ module SettingConcern end def target_plugin_name - target_class.to_s.split("::").last.underscore + prefix = case target_class.plugin_type + when "input" + "in" + when "output" + "out" + else + target_class.plugin_type + end + "#{prefix}_#{target_class.plugin_name}" end def plugin_setting_form_action_url(*args) send("finish_daemon_setting_#{target_plugin_name}_path", *args) end + + def target_plugin_params + keys = [] + target_class.config_definition.each do |name, definition| + if definition[:section] + keys.concat(parse_section_definition(definition)) + else + keys.concat(definition.keys) + end + end + keys + end + + def parse_section_definition(definition) + keys = [] + definition.except(:section, :argument, :required, :multi, :alias).each do |name, _definition| + _keys = [] + _definition.each do |key, __definition| + if __definition[:section] + _keys.push({ name => parse_section_definition(__definition) }) + else + _keys.push(key) + end + end + keys.push({ name => _keys }) + end + keys + end end diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb index dfee00b..f1af4d4 100644 --- a/app/helpers/settings_helper.rb +++ b/app/helpers/settings_helper.rb @@ -2,26 +2,62 @@ module SettingsHelper def field(form, key, opts = {}) html = '
' - field_resolver(form.object.column_type(key), html, form, key, opts) + field_resolver(html, form, key, opts) html << "
" html.html_safe end private - def field_resolver(type, html, form, key, opts) - case type - when :hidden - html << form.hidden_field(key) - when :boolean, :flag - boolean_field(html, form, key, opts) - when :choice - choice_field(html, form, key, opts) - when :nested - nested_field(html, form, key, opts) - else - other_field(html, form, key, opts) + + def field_resolver(html, form, key, opts) + plugin_class = form.object.class + type = plugin_class.column_type(key) + if type && !@_used_param.key?(key) + case type + when :enum + enum_field(html, form, key, opts) + when :bool + bool_field(html, form, key, opts) + else + other_field(html, form, key, opts) + end + @_used_param[key] = true end + if plugin_class._sections[key] && !@_used_section.key?(key) + section_field(html, form, key, opts) + @_used_section[key] = true + end + end + + def section_field(html, form, key, opts = {}) + klass = form.object.class._sections[key] + children = form.object.__send__(key) || { "0" => {} } + + children.each do |index, child| + open_section_div(html, klass.multi) do |_html| + _html << append_and_remove_links if klass.multi + _html << h(form.label(key)) + _html << section_fields(form, key, index, klass, child) + end + end + end + + def open_section_div(html, multi) + html << %Q!
! + yield html + html << "
" + end + + def section_fields(form, key, index, klass, child) + html = "" + object = klass.new(child) + form.fields_for("#{key}[#{index}]", object) do |ff| + klass._types.keys.each do |kk| + html << field(ff, kk) + end + end + html end def nested_field(html, form, key, opts = {}) @@ -54,27 +90,28 @@ module SettingsHelper end def append_and_remove_links - %Q!#{icon('fa-plus')} ! + - %Q! ! + %Q!#{icon('fa-plus')} ! + + %Q! ! end def child_data(form, key) form.object.class.children[key] end - def choice_field(html, form, key, opts = {}) + def enum_field(html, form, key, opts = {}) html << h(form.label(key)) html << " " # NOTE: Adding space for padding - html << form.select(key, form.object.values_of(key), opts) + html << form.select(key, form.object.list_of(key), opts) end - def boolean_field(html, form, key, opts = {}) + def bool_field(html, form, key, opts = {}) html << form.check_box(key, {}, "true", "false") html << " " # NOTE: Adding space for padding html << h(form.label(key)) end def other_field(html, form, key, opts = {}) + return unless form.object.respond_to?(key) html << h(form.label(key)) html << form.text_field(key, class: "form-control") end