decidim-core 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/app/assets/config/decidim_core_manifest.js +1 -0
  4. data/app/assets/javascripts/decidim.js.es6 +3 -2
  5. data/app/assets/javascripts/decidim/append_elements.js.es6 +8 -0
  6. data/app/assets/javascripts/decidim/filters.js.es6 +22 -0
  7. data/app/assets/javascripts/decidim/form_filter.component.js.es6 +176 -0
  8. data/app/assets/javascripts/decidim/form_filter.component.test.js +151 -0
  9. data/app/assets/javascripts/decidim/inline_svg.js.es6 +12 -0
  10. data/app/assets/javascripts/decidim/user_registrations.js.es6 +22 -0
  11. data/app/assets/stylesheets/decidim/_variables.scss +1 -1
  12. data/app/assets/stylesheets/decidim/modules/_comments.scss +3 -6
  13. data/app/assets/stylesheets/decidim/modules/_cookie-bar.scss +22 -0
  14. data/app/assets/stylesheets/decidim/modules/_layout.scss +9 -1
  15. data/app/assets/stylesheets/decidim/modules/_navbar.scss +8 -5
  16. data/app/assets/stylesheets/decidim/modules/_order-by.scss +0 -1
  17. data/app/assets/stylesheets/decidim/modules/_process-phase.scss +4 -0
  18. data/app/assets/stylesheets/decidim/modules/_timeline.scss +62 -80
  19. data/app/assets/stylesheets/decidim/modules/_typography.scss +20 -31
  20. data/app/assets/stylesheets/decidim/utils/_fontface.scss +4 -16
  21. data/app/assets/stylesheets/decidim/utils/_settings.scss +29 -26
  22. data/app/assets/stylesheets/decidim/utils/_variables.scss +22 -0
  23. data/app/commands/decidim/authorize_user.rb +17 -1
  24. data/app/commands/decidim/create_omniauth_registration.rb +92 -0
  25. data/app/commands/decidim/create_registration.rb +50 -0
  26. data/app/commands/decidim/invite_user.rb +50 -0
  27. data/app/commands/decidim/invite_user_again.rb +25 -0
  28. data/app/commands/decidim/remove_user_role.rb +26 -0
  29. data/app/controllers/concerns/decidim/feature_settings.rb +27 -0
  30. data/app/controllers/concerns/decidim/filter_resource.rb +71 -0
  31. data/app/controllers/concerns/decidim/form_factory.rb +21 -18
  32. data/app/controllers/concerns/decidim/needs_participatory_process.rb +2 -3
  33. data/app/controllers/decidim/devise/confirmations_controller.rb +2 -0
  34. data/app/controllers/decidim/devise/invitations_controller.rb +4 -0
  35. data/app/controllers/decidim/devise/omniauth_registrations_controller.rb +96 -0
  36. data/app/controllers/decidim/devise/passwords_controller.rb +2 -0
  37. data/app/controllers/decidim/devise/registrations_controller.rb +34 -0
  38. data/app/controllers/decidim/devise/sessions_controller.rb +1 -0
  39. data/app/controllers/decidim/pages_controller.rb +10 -2
  40. data/app/controllers/decidim/participatory_process_steps_controller.rb +16 -0
  41. data/app/controllers/decidim/participatory_processes_controller.rb +6 -11
  42. data/app/forms/decidim/form.rb +6 -6
  43. data/app/forms/decidim/invite_admin_form.rb +37 -0
  44. data/app/forms/decidim/omniauth_registration_form.rb +24 -0
  45. data/app/forms/decidim/registration_form.rb +41 -0
  46. data/app/helpers/decidim/filters_helper.rb +21 -0
  47. data/app/helpers/decidim/layout_helper.rb +17 -1
  48. data/app/helpers/decidim/omniauth_helper.rb +23 -0
  49. data/app/helpers/decidim/paginate_helper.rb +21 -0
  50. data/app/helpers/decidim/participatory_process_helper.rb +14 -0
  51. data/app/helpers/decidim/participatory_process_steps_helper.rb +17 -0
  52. data/app/mailers/decidim/decidim_devise_mailer.rb +2 -2
  53. data/app/models/decidim/feature.rb +40 -0
  54. data/app/models/decidim/identity.rb +12 -0
  55. data/app/models/decidim/organization.rb +3 -10
  56. data/app/models/decidim/user.rb +3 -1
  57. data/app/models/decidim/user_group.rb +18 -0
  58. data/app/models/decidim/user_group_membership.rb +9 -0
  59. data/app/services/decidim/authorization_handler.rb +13 -13
  60. data/app/services/decidim/resource_search.rb +52 -0
  61. data/app/uploaders/decidim/organization_logo_uploader.rb +1 -1
  62. data/app/views/decidim/authorizations/new.html.erb +3 -1
  63. data/app/views/decidim/devise/omniauth_registrations/new.html.erb +40 -0
  64. data/app/views/decidim/devise/registrations/new.html.erb +21 -1
  65. data/app/views/decidim/devise/sessions/new.html.erb +1 -0
  66. data/app/views/decidim/devise/shared/_links.html.erb +0 -8
  67. data/app/views/decidim/devise/shared/_omniauth_buttons.html.erb +21 -0
  68. data/app/views/decidim/participatory_process_steps/_participatory_process_step.html.erb +16 -0
  69. data/app/views/decidim/participatory_process_steps/_timeline.html.erb +7 -0
  70. data/app/views/decidim/participatory_process_steps/index.html.erb +12 -0
  71. data/app/views/decidim/participatory_processes/show.html.erb +5 -5
  72. data/app/views/decidim/shared/_login_modal.html.erb +30 -0
  73. data/app/views/devise/mailer/invite_admin.html.erb +17 -0
  74. data/app/views/devise/mailer/invite_admin.text.erb +15 -0
  75. data/app/views/devise/mailer/organization_admin_invitation_instructions.html.erb +1 -1
  76. data/app/views/devise/mailer/organization_admin_invitation_instructions.text.erb +1 -1
  77. data/app/views/layouts/decidim/_application.html.erb +1 -0
  78. data/app/views/layouts/decidim/_header.html.erb +1 -1
  79. data/app/views/layouts/decidim/_meta.html.erb +1 -0
  80. data/app/views/layouts/decidim/_process_header.html.erb +12 -1
  81. data/app/views/layouts/decidim/_process_header_steps.html.erb +1 -0
  82. data/app/views/layouts/decidim/_social_meta.html.erb +11 -0
  83. data/app/views/layouts/decidim/participatory_process.html.erb +4 -0
  84. data/app/views/pages/home.html.erb +29 -2
  85. data/config/i18n-tasks.yml +1 -0
  86. data/config/initializers/devise.rb +10 -1
  87. data/config/locales/ca.yml +45 -3
  88. data/config/locales/en.yml +45 -3
  89. data/config/locales/es.yml +45 -3
  90. data/config/routes.rb +9 -2
  91. data/config/secrets.yml +36 -0
  92. data/db/migrate/20170110133113_add_configuration_to_features.rb +7 -0
  93. data/db/migrate/20170110153807_add_handler_to_organization.rb +5 -0
  94. data/db/migrate/20170116110851_create_identities.rb +11 -0
  95. data/db/migrate/20170116135237_loosen_step_requirements.rb +6 -0
  96. data/db/migrate/20170117142904_add_uniqueness_field_to_authorizations.rb +7 -0
  97. data/db/migrate/20170119145359_create_user_groups.rb +11 -0
  98. data/db/migrate/20170119150255_create_user_group_memberships.rb +12 -0
  99. data/db/migrate/20170119150649_add_show_statistics_to_organization.rb +5 -0
  100. data/db/migrate/20170120120733_add_user_groups_verified.rb +5 -0
  101. data/db/seeds.rb +45 -79
  102. data/lib/decidim/core.rb +8 -0
  103. data/lib/decidim/core/engine.rb +8 -0
  104. data/lib/decidim/core/test/factories.rb +188 -0
  105. data/lib/decidim/core/version.rb +1 -1
  106. data/lib/decidim/devise_failure_app.rb +1 -0
  107. data/lib/decidim/feature_manifest.rb +27 -0
  108. data/lib/decidim/features/base_controller.rb +8 -3
  109. data/lib/decidim/features/settings_manifest.rb +94 -0
  110. data/lib/decidim/filter_form_builder.rb +56 -0
  111. data/lib/decidim/form_builder.rb +4 -7
  112. data/vendor/assets/javascripts/svg-injector.js +464 -0
  113. metadata +142 -26
  114. data/app/assets/stylesheets/decidim/modules/_owl-carousel.scss +0 -72
  115. data/app/assets/stylesheets/decidim/modules/_phase-nav.scss +0 -177
  116. data/app/assets/stylesheets/decidim/utils/_helpers.sass +0 -21
  117. data/app/assets/stylesheets/decidim/utils/_keyframes.sass +0 -13
  118. data/app/assets/stylesheets/decidim/utils/_mixins.sass +0 -33
@@ -7,6 +7,7 @@ module Decidim
7
7
  autoload :TranslatableAttributes, "decidim/translatable_attributes"
8
8
  autoload :FormBuilder, "decidim/form_builder"
9
9
  autoload :AuthorizationFormBuilder, "decidim/authorization_form_builder"
10
+ autoload :FilterFormBuilder, "decidim/filter_form_builder"
10
11
  autoload :DeviseFailureApp, "decidim/devise_failure_app"
11
12
  autoload :FeatureManifest, "decidim/feature_manifest"
12
13
  autoload :Features, "decidim/features"
@@ -15,6 +16,11 @@ module Decidim
15
16
 
16
17
  # Loads seeds from all engines.
17
18
  def self.seed!
19
+ # Faker needs to have the `:en` locale in order to work properly, so we
20
+ # must enforce it during the seeds.
21
+ original_locale = I18n.available_locales
22
+ I18n.available_locales = original_locale + [:en] unless original_locale.include?(:en)
23
+
18
24
  railties = Rails.application.railties.to_a.uniq.select do |railtie|
19
25
  railtie.respond_to?(:load_seed) && railtie.class.name.include?("Decidim::")
20
26
  end
@@ -28,6 +34,8 @@ module Decidim
28
34
  puts "Creating Feature (#{feature.name}) seeds..."
29
35
  feature.seed!
30
36
  end
37
+
38
+ I18n.available_locales = original_locale
31
39
  end
32
40
 
33
41
  # Exposes a configuration option: The application name String.
@@ -24,6 +24,10 @@ require "sprockets/es6"
24
24
  require "cancancan"
25
25
  require "truncato"
26
26
  require "file_validators"
27
+ require "omniauth"
28
+ require "omniauth-facebook"
29
+ require "omniauth-twitter"
30
+ require "omniauth-google-oauth2"
27
31
 
28
32
  require "decidim/api"
29
33
 
@@ -48,6 +52,10 @@ module Decidim
48
52
 
49
53
  initializer "decidim.assets" do |app|
50
54
  app.config.assets.precompile += %w(decidim_core_manifest.js)
55
+
56
+ Decidim.feature_manifests.each do |feature|
57
+ app.config.assets.precompile += [feature.icon]
58
+ end
51
59
  end
52
60
 
53
61
  initializer "decidim.high_voltage" do |_app|
@@ -0,0 +1,188 @@
1
+ # frozen_string_literal: true
2
+ require "decidim/faker/localized"
3
+ require "decidim/dev"
4
+
5
+ FactoryGirl.define do
6
+ sequence :name do |n|
7
+ "#{Faker::Name.name} #{n}"
8
+ end
9
+
10
+ sequence(:email) do |n|
11
+ "user#{n}@decidim.org"
12
+ end
13
+
14
+ sequence(:slug) do |n|
15
+ "#{Faker::Internet.slug(nil, "-")}-#{n}"
16
+ end
17
+
18
+ factory :category, class: Decidim::Category do
19
+ name { Decidim::Faker::Localized.sentence(3) }
20
+ description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { Decidim::Faker::Localized.sentence(2) } }
21
+ participatory_process
22
+ end
23
+
24
+ factory :subcategory, parent: :category do
25
+ parent { build(:category) }
26
+
27
+ before(:create) do |object|
28
+ object.parent.save unless object.parent.persisted?
29
+ end
30
+ end
31
+
32
+ factory :organization, class: Decidim::Organization do
33
+ name { Faker::Company.name }
34
+ twitter_handler { Faker::Hipster.word }
35
+ sequence(:host) { |n| "#{n}.lvh.me" }
36
+ description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { Decidim::Faker::Localized.sentence(2) } }
37
+ welcome_text { Decidim::Faker::Localized.wrapped("<p>", "</p>") { Decidim::Faker::Localized.sentence(2) } }
38
+ homepage_image { test_file("city.jpeg", "image/jpeg") }
39
+ default_locale I18n.default_locale
40
+ available_locales Decidim.available_locales
41
+ end
42
+
43
+ factory :participatory_process, class: Decidim::ParticipatoryProcess do
44
+ title { Decidim::Faker::Localized.sentence(3) }
45
+ slug { generate(:slug) }
46
+ subtitle { Decidim::Faker::Localized.sentence(1) }
47
+ short_description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { Decidim::Faker::Localized.sentence(2) } }
48
+ description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { Decidim::Faker::Localized.sentence(4) } }
49
+ hero_image { test_file("city.jpeg", "image/jpeg") }
50
+ banner_image { test_file("city2.jpeg", "image/jpeg") }
51
+ published_at { Time.current }
52
+ organization
53
+
54
+ trait :promoted do
55
+ promoted true
56
+ end
57
+
58
+ trait :unpublished do
59
+ published_at nil
60
+ end
61
+
62
+ trait :published do
63
+ published_at { Time.current }
64
+ end
65
+
66
+ trait :with_steps do
67
+ after(:create) do |participatory_process, _evaluator|
68
+ create(:participatory_process_step,
69
+ active: true,
70
+ participatory_process: participatory_process)
71
+ end
72
+ end
73
+ end
74
+
75
+ factory :participatory_process_step, class: Decidim::ParticipatoryProcessStep do
76
+ title { Decidim::Faker::Localized.sentence(3) }
77
+ short_description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { Decidim::Faker::Localized.sentence(2) } }
78
+ description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { Decidim::Faker::Localized.sentence(4) } }
79
+ start_date 1.month.ago.at_midnight
80
+ end_date 2.month.from_now.at_midnight
81
+ position nil
82
+ participatory_process
83
+
84
+ trait :active do
85
+ active true
86
+ end
87
+ end
88
+
89
+ factory :user, class: Decidim::User do
90
+ email { generate(:email) }
91
+ password "password1234"
92
+ password_confirmation "password1234"
93
+ name { generate(:name) }
94
+ organization
95
+ locale { organization.default_locale }
96
+ tos_agreement "1"
97
+ avatar { test_file("avatar.svg", "image/svg+xml") }
98
+
99
+ trait :confirmed do
100
+ confirmed_at { Time.current }
101
+ end
102
+
103
+ trait :admin do
104
+ roles ["admin"]
105
+ end
106
+
107
+ trait :moderator do
108
+ roles ["moderator"]
109
+ end
110
+
111
+ trait :official do
112
+ roles ["official"]
113
+ end
114
+ end
115
+
116
+ factory :user_group, class: Decidim::UserGroup do
117
+ name { Faker::Educator.course }
118
+ document_number { Faker::Number.number(8) + "X" }
119
+ phone { Faker::PhoneNumber.phone_number }
120
+ end
121
+
122
+ factory :user_group_membership, class: Decidim::UserGroupMembership do
123
+ user
124
+ user_group
125
+ end
126
+
127
+ factory :identity, class: Decidim::Identity do
128
+ provider "facebook"
129
+ sequence(:uid)
130
+ user
131
+ end
132
+
133
+ factory :authorization, class: Decidim::Authorization do
134
+ name "decidim/dummy_authorization_handler"
135
+ user
136
+ metadata { {} }
137
+ end
138
+
139
+ factory :static_page, class: Decidim::StaticPage do
140
+ slug { generate(:slug) }
141
+ title { Decidim::Faker::Localized.sentence(3) }
142
+ content { Decidim::Faker::Localized.wrapped("<p>", "</p>") { Decidim::Faker::Localized.sentence(4) } }
143
+ organization
144
+
145
+ trait :default do
146
+ slug { Decidim::StaticPage::DEFAULT_PAGES.sample }
147
+ end
148
+ end
149
+
150
+ factory :participatory_process_attachment, class: Decidim::ParticipatoryProcessAttachment do
151
+ title { Decidim::Faker::Localized.sentence(3) }
152
+ description { Decidim::Faker::Localized.wrapped("<p>", "</p>") { Decidim::Faker::Localized.sentence(4) } }
153
+ file { test_file("city.jpeg", "image/jpeg") }
154
+ participatory_process
155
+
156
+ trait :with_image do
157
+ file { test_file("city.jpeg", "image/jpeg") }
158
+ end
159
+
160
+ trait :with_pdf do
161
+ file { test_file("Exampledocument.pdf", "application/pdf") }
162
+ end
163
+
164
+ trait :with_doc do
165
+ file { test_file("Exampledocument.doc", "application/msword") }
166
+ end
167
+
168
+ trait :with_odt do
169
+ file { test_file("Exampledocument.odt", "application/vnd.oasis.opendocument") }
170
+ end
171
+ end
172
+
173
+ factory :feature, class: Decidim::Feature do
174
+ name { Decidim::Faker::Localized.sentence(3) }
175
+ participatory_process
176
+ manifest_name "dummy"
177
+ end
178
+
179
+ factory :scope, class: Decidim::Scope do
180
+ name { generate(:name) }
181
+ organization
182
+ end
183
+ end
184
+
185
+ def test_file(filename, content_type)
186
+ asset = Decidim::Dev.asset(filename)
187
+ Rack::Test::UploadedFile.new(asset, content_type)
188
+ end
@@ -2,7 +2,7 @@
2
2
  # This holds Decidim's version and the Rails version on which it depends.
3
3
  module Decidim
4
4
  def self.version
5
- "0.0.1"
5
+ "0.0.2"
6
6
  end
7
7
 
8
8
  def self.rails_version
@@ -17,6 +17,7 @@ module Decidim
17
17
 
18
18
  route = route(scope)
19
19
 
20
+ opts[:locale] = params[:locale] if params[:locale]
20
21
  opts[:format] = request_format unless skip_format?
21
22
 
22
23
  opts[:script_name] = relative_url_root if relative_url_root?
@@ -1,3 +1,5 @@
1
+ require_dependency "decidim/features/settings_manifest"
2
+
1
3
  # frozen_string_literal: true
2
4
  module Decidim
3
5
  # This class handles all the logic associated to configuring a feature
@@ -15,6 +17,10 @@ module Decidim
15
17
  attribute :name, Symbol
16
18
  attribute :hooks, Hash[Symbol => Array[Proc]], default: {}
17
19
 
20
+ # A String with the feature's icon. The icon must be stored in the
21
+ # engine's assets path.
22
+ attribute :icon, String
23
+
18
24
  validates :name, presence: true
19
25
 
20
26
  # Public: Registers a hook to this manifest. Hooks get fired when some
@@ -67,5 +73,26 @@ module Decidim
67
73
  def seed!
68
74
  @seeds&.call
69
75
  end
76
+
77
+ # Public: Adds configurable attributes for this feature, scoped to a name. It
78
+ # uses the DSL specified under `Decidim::FeatureSettingsManifest`.
79
+ #
80
+ # name - Either `global` or `step`
81
+ # &block - The DSL present on `Decidim::FeatureSettingsManifest`
82
+ #
83
+ # Examples:
84
+ #
85
+ # feature.settings(:global) do |settings|
86
+ # settings.attribute :voting_enabled, type: :boolean, default: true
87
+ # end
88
+ #
89
+ # Returns nothing.
90
+ def settings(name = :global, &block)
91
+ @settings ||= {}
92
+ name = name.to_sym
93
+ settings = (@settings[name] ||= FeatureSettingsManifest.new)
94
+ yield(settings) if block
95
+ settings
96
+ end
70
97
  end
71
98
  end
@@ -8,9 +8,12 @@ module Decidim
8
8
  class BaseController < Decidim::ApplicationController
9
9
  layout "layouts/decidim/participatory_process"
10
10
  include NeedsParticipatoryProcess
11
+ include FeatureSettings
11
12
  helper Decidim::TranslationsHelper
12
13
  helper Decidim::ParticipatoryProcessHelper
13
- helper_method :current_feature
14
+
15
+ helper_method :current_feature,
16
+ :current_manifest
14
17
 
15
18
  skip_authorize_resource
16
19
 
@@ -18,12 +21,14 @@ module Decidim
18
21
  authorize! :read, current_participatory_process
19
22
  end
20
23
 
21
- private
22
-
23
24
  def current_feature
24
25
  request.env["decidim.current_feature"]
25
26
  end
26
27
 
28
+ def current_manifest
29
+ current_feature.manifest
30
+ end
31
+
27
32
  def current_participatory_process
28
33
  request.env["decidim.current_participatory_process"]
29
34
  end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+ module Decidim
3
+ # This class serves as a DSL that enables specifying an arbitrary settings
4
+ # to a feature, so the admin panel can show a standarized UI to configure them.
5
+ #
6
+ class FeatureSettingsManifest
7
+ attr_reader :attributes
8
+
9
+ # Initializes a FeatureSettingsManifest.
10
+ def initialize
11
+ @attributes = {}
12
+ end
13
+
14
+ # Public: Adds a new attribute field to the FeatureSettingsManifest.
15
+ #
16
+ # name - The name of the attribute to inject.
17
+ # options - A set of options to configure the attribute.
18
+ # :type - The type of the attribute as found in Attribute::TYPES
19
+ # :default - The default value of this settings field.
20
+ #
21
+ # Returns nothing.
22
+ def attribute(name, options = {})
23
+ attribute = Attribute.new(options)
24
+ attribute.validate!
25
+ @attributes[name.to_sym] = attribute
26
+
27
+ @schema = nil
28
+ end
29
+
30
+ # Public: Creates a model Class that sanitizes, coerces and filters data to
31
+ # the right types given a hash of serialized information.
32
+ #
33
+ # Returns a Class.
34
+ def schema
35
+ return @schema if @schema
36
+
37
+ manifest = self
38
+
39
+ @schema = Class.new do
40
+ include Virtus.model
41
+ include ActiveModel::Validations
42
+
43
+ cattr_accessor :manifest
44
+
45
+ def self.model_name
46
+ ActiveModel::Name.new(self, nil, "FeatureSettings")
47
+ end
48
+
49
+ def manifest
50
+ self.class.manifest
51
+ end
52
+
53
+ def ==(other)
54
+ other.attributes == attributes
55
+ end
56
+
57
+ manifest.attributes.each do |name, attribute|
58
+ attribute name, attribute.type_class, default: attribute.default_value
59
+ validates name, presence: true
60
+ end
61
+ end
62
+
63
+ @schema.manifest = self
64
+ @schema
65
+ end
66
+
67
+ # Semi-private: Attributes are an abstraction used by FeatureSettingsManifest
68
+ # to encapsulate behavior related to each individual settings field. Shouldn't
69
+ # be used from the outside.
70
+ class Attribute
71
+ include Virtus.model
72
+ include ActiveModel::Validations
73
+
74
+ TYPES = {
75
+ boolean: { klass: Boolean, default: false },
76
+ string: { klass: String, default: nil },
77
+ text: { klass: String, default: nil }
78
+ }.freeze
79
+
80
+ attribute :type, Symbol, default: :boolean
81
+ attribute :default
82
+
83
+ validates :type, inclusion: { in: TYPES.keys }
84
+
85
+ def type_class
86
+ TYPES[type][:klass]
87
+ end
88
+
89
+ def default_value
90
+ default || TYPES[type][:default]
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+ # rubocop:disable Metrics/ParameterLists
3
+ require "decidim/form_builder"
4
+
5
+ module Decidim
6
+ # This custom FormBuilder is used to create resource filter forms
7
+ class FilterFormBuilder < FormBuilder
8
+ # Wrap the radio buttons collection in a custom fieldset.
9
+ # It also renders the inputs inside its labels.
10
+ def collection_radio_buttons(method, collection, value_method, label_method, options = {}, html_options = {})
11
+ fieldset_wrapper options[:legend_title] do
12
+ super(method, collection, value_method, label_method, options, html_options) do |builder|
13
+ if block_given?
14
+ yield builder
15
+ else
16
+ builder.label { builder.radio_button + builder.text }
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ # Wrap the check_boxes collection in a custom fieldset.
23
+ # It also renders the inputs inside its labels.
24
+ def collection_check_boxes(method, collection, value_method, label_method, options = {}, html_options = {})
25
+ fieldset_wrapper options[:legend_title] do
26
+ super(method, collection, value_method, label_method, options, html_options) do |builder|
27
+ if block_given?
28
+ yield builder
29
+ else
30
+ builder.label { builder.check_box + builder.text }
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ # Wrap the category select in a custom fieldset.
37
+ def categories_select(method, collection, options = {})
38
+ fieldset_wrapper options[:legend_title] do
39
+ super(method, collection, options)
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ # Private: Renders a custom fieldset and execute the given block.
46
+ def fieldset_wrapper(legend_title)
47
+ @template.content_tag(:div, "", class: "filters__section") do
48
+ @template.content_tag(:fieldset) do
49
+ @template.content_tag(:legend) do
50
+ @template.content_tag(:h6, legend_title, class: "heading6")
51
+ end + yield
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end