decidim-assemblies 0.19.0 → 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/decidim/assemblies/assembly.svg +1 -3
  3. data/app/assets/javascripts/decidim/assemblies/orgchart.js.es6 +698 -0
  4. data/app/cells/decidim/assemblies/assembly_m/footer.erb +2 -2
  5. data/app/cells/decidim/assemblies/assembly_m_cell.rb +5 -5
  6. data/app/cells/decidim/assemblies/assembly_member/show.erb +4 -4
  7. data/app/cells/decidim/assemblies/content_blocks/highlighted_assemblies/show.erb +10 -11
  8. data/app/cells/decidim/assemblies/content_blocks/highlighted_assemblies_cell.rb +1 -0
  9. data/app/commands/decidim/assemblies/admin/create_assemblies_type.rb +45 -0
  10. data/app/commands/decidim/assemblies/admin/create_assembly.rb +1 -2
  11. data/app/commands/decidim/assemblies/admin/create_assembly_admin.rb +2 -1
  12. data/app/commands/decidim/assemblies/admin/create_assembly_member.rb +12 -3
  13. data/app/commands/decidim/assemblies/admin/destroy_assemblies_type.rb +45 -0
  14. data/app/commands/decidim/assemblies/admin/notify_role_assigned_to_assembly.rb +22 -0
  15. data/app/commands/decidim/assemblies/admin/update_assemblies_setting.rb +46 -0
  16. data/app/commands/decidim/assemblies/admin/update_assemblies_type.rb +46 -0
  17. data/app/commands/decidim/assemblies/admin/update_assembly.rb +1 -2
  18. data/app/commands/decidim/assemblies/admin/update_assembly_admin.rb +2 -1
  19. data/app/controllers/concerns/decidim/assemblies/admin/filterable.rb +30 -0
  20. data/app/controllers/decidim/assemblies/admin/assemblies_controller.rb +8 -29
  21. data/app/controllers/decidim/assemblies/admin/assemblies_settings_controller.rb +49 -0
  22. data/app/controllers/decidim/assemblies/admin/assemblies_types_controller.rb +107 -0
  23. data/app/controllers/decidim/assemblies/assemblies_controller.rb +6 -2
  24. data/app/events/decidim/assemblies/create_assembly_member_event.rb +17 -0
  25. data/app/events/decidim/role_assigned_to_assembly_event.rb +28 -0
  26. data/app/forms/decidim/assemblies/admin/assemblies_setting_form.rb +14 -0
  27. data/app/forms/decidim/assemblies/admin/assemblies_type_form.rb +17 -0
  28. data/app/forms/decidim/assemblies/admin/assembly_form.rb +32 -13
  29. data/app/helpers/decidim/assemblies/admin/assemblies_helper.rb +6 -0
  30. data/app/helpers/decidim/assemblies/assemblies_helper.rb +6 -3
  31. data/app/helpers/decidim/assemblies/filter_assemblies_helper.rb +10 -7
  32. data/app/models/decidim/assemblies_setting.rb +17 -0
  33. data/app/models/decidim/assemblies_type.rb +24 -0
  34. data/app/models/decidim/assembly.rb +25 -2
  35. data/app/models/decidim/assembly_user_role.rb +1 -1
  36. data/app/permissions/decidim/assemblies/permissions.rb +55 -1
  37. data/app/presenters/decidim/assemblies/admin_log/assemblies_setting_presenter.rb +27 -0
  38. data/app/presenters/decidim/assemblies/admin_log/assemblies_type_presenter.rb +43 -0
  39. data/app/presenters/decidim/assemblies/admin_log/assembly_presenter.rb +1 -2
  40. data/app/presenters/decidim/assemblies/assembly_stats_presenter.rb +1 -1
  41. data/app/presenters/decidim/log/value_types/assembly_type_presenter.rb +29 -0
  42. data/app/queries/decidim/assemblies/filtered_assemblies.rb +2 -2
  43. data/app/queries/decidim/assemblies/parent_assemblies_for_select.rb +42 -0
  44. data/app/services/decidim/assemblies/assembly_search.rb +3 -3
  45. data/app/types/decidim/assemblies/assemblies_type_type.rb +17 -0
  46. data/app/types/decidim/assemblies/assembly_member_type.rb +29 -0
  47. data/app/types/decidim/assemblies/assembly_type.rb +67 -0
  48. data/app/views/decidim/assemblies/_filter_by_type.html.erb +11 -7
  49. data/app/views/decidim/assemblies/admin/assemblies/_form.html.erb +2 -6
  50. data/app/views/decidim/assemblies/admin/assemblies/index.html.erb +8 -4
  51. data/app/views/decidim/assemblies/admin/assemblies_settings/_form.html.erb +10 -0
  52. data/app/views/decidim/assemblies/admin/assemblies_settings/edit.html.erb +6 -0
  53. data/app/views/decidim/assemblies/admin/assemblies_types/_form.html.erb +11 -0
  54. data/app/views/decidim/assemblies/admin/assemblies_types/edit.html.erb +6 -0
  55. data/app/views/decidim/assemblies/admin/assemblies_types/index.html.erb +43 -0
  56. data/app/views/decidim/assemblies/admin/assemblies_types/new.html.erb +7 -0
  57. data/app/views/decidim/assemblies/admin/assembly_members/index.html.erb +30 -30
  58. data/app/views/decidim/assemblies/assemblies/_parent_assemblies.html.erb +2 -2
  59. data/app/views/decidim/assemblies/assemblies/_promoted_assembly.html.erb +3 -3
  60. data/app/views/decidim/assemblies/assemblies/index.html.erb +11 -8
  61. data/app/views/decidim/assemblies/assemblies/show.html.erb +10 -13
  62. data/app/views/decidim/assemblies/assembly_members/index.html.erb +1 -1
  63. data/app/views/layouts/decidim/admin/assemblies.html.erb +22 -0
  64. data/app/views/layouts/decidim/admin/assembly.html.erb +2 -2
  65. data/config/locales/ar.yml +60 -27
  66. data/config/locales/bg-BG.yml +7 -0
  67. data/config/locales/ca.yml +79 -1
  68. data/config/locales/cs.yml +125 -47
  69. data/config/locales/da-DK.yml +1 -0
  70. data/config/locales/de.yml +80 -0
  71. data/config/locales/el-GR.yml +1 -0
  72. data/config/locales/el.yml +456 -0
  73. data/config/locales/en.yml +78 -0
  74. data/config/locales/es-MX.yml +79 -0
  75. data/config/locales/es-PY.yml +79 -0
  76. data/config/locales/es.yml +78 -0
  77. data/config/locales/et-EE.yml +1 -0
  78. data/config/locales/eu.yml +11 -0
  79. data/config/locales/fi-plain.yml +78 -0
  80. data/config/locales/fi.yml +81 -3
  81. data/config/locales/fr-CA.yml +456 -0
  82. data/config/locales/fr.yml +78 -0
  83. data/config/locales/ga-IE.yml +1 -0
  84. data/config/locales/gl.yml +11 -0
  85. data/config/locales/hr-HR.yml +1 -0
  86. data/config/locales/hu.yml +67 -2
  87. data/config/locales/id-ID.yml +11 -0
  88. data/config/locales/is-IS.yml +263 -0
  89. data/config/locales/it.yml +181 -102
  90. data/config/locales/ja-JP.yml +452 -0
  91. data/config/locales/lt-LT.yml +1 -0
  92. data/config/locales/lv-LV.yml +454 -0
  93. data/config/locales/mt-MT.yml +1 -0
  94. data/config/locales/nl.yml +86 -8
  95. data/config/locales/no.yml +451 -0
  96. data/config/locales/pl.yml +222 -142
  97. data/config/locales/pt-BR.yml +12 -1
  98. data/config/locales/pt.yml +198 -118
  99. data/config/locales/ro-RO.yml +422 -0
  100. data/config/locales/ru.yml +11 -0
  101. data/config/locales/sk-SK.yml +168 -0
  102. data/config/locales/sk.yml +172 -0
  103. data/config/locales/sl.yml +132 -0
  104. data/config/locales/sr-CS.yml +73 -0
  105. data/config/locales/sv.yml +167 -88
  106. data/config/locales/tr-TR.yml +11 -0
  107. data/config/locales/uk.yml +11 -0
  108. data/db/migrate/20200108113855_create_decidim_assembly_types.rb +19 -0
  109. data/db/migrate/20200108123050_migrate_decidim_assembly_types.rb +83 -0
  110. data/db/migrate/20200320105906_index_foreign_keys_in_decidim_assemblies.rb +7 -0
  111. data/db/migrate/20200320105907_index_foreign_keys_in_decidim_assembly_user_roles.rb +7 -0
  112. data/db/migrate/20200416132109_remove_legacy_decidim_assembly_type.rb +8 -0
  113. data/db/migrate/20200430202456_create_decidim_assemblies_settings.rb +10 -0
  114. data/db/seeds/city.jpeg +0 -0
  115. data/db/seeds/city2.jpeg +0 -0
  116. data/lib/decidim/assemblies/admin_engine.rb +3 -0
  117. data/lib/decidim/assemblies/engine.rb +7 -0
  118. data/lib/decidim/assemblies/participatory_space.rb +11 -3
  119. data/lib/decidim/assemblies/query_extensions.rb +40 -0
  120. data/lib/decidim/assemblies/test/factories.rb +29 -2
  121. data/lib/decidim/assemblies/version.rb +1 -1
  122. metadata +62 -10
  123. data/app/views/decidim/assemblies/assembly_widgets/show.html.erb +0 -11
@@ -14,6 +14,12 @@ module Decidim
14
14
  @processes_selected ||= current_assembly.linked_participatory_space_resources(:participatory_processes, "included_participatory_processes").pluck(:id)
15
15
  end
16
16
  end
17
+
18
+ # Public: A collection of Assemblies that can be selected as parent
19
+ # assemblies for another assembly; to be used in forms.
20
+ def parent_assemblies_for_select
21
+ @parent_assemblies_for_select ||= ParentAssembliesForSelect.for(current_organization, current_assembly)
22
+ end
17
23
  end
18
24
  end
19
25
  end
@@ -45,9 +45,12 @@ module Decidim
45
45
  html += "<span class='definition-data__title'>#{t("assemblies.show.social_networks", scope: "decidim")}</span>".html_safe
46
46
  Decidim::Assembly::SOCIAL_HANDLERS.each do |handler|
47
47
  handler_name = "#{handler}_handler"
48
- if assembly.send(handler_name).present?
49
- html += link_to handler.capitalize, "https://#{handler}.com/#{assembly.send(handler_name)}", target: "_blank", class: "", title: handler.capitalize, rel: "noopener"
50
- end
48
+ next if assembly.send(handler_name).blank?
49
+
50
+ html += link_to handler.capitalize, "https://#{handler}.com/#{assembly.send(handler_name)}",
51
+ target: "_blank",
52
+ class: "",
53
+ title: t("assemblies.show.social_networks_title", scope: "decidim") << " " << handler.capitalize.to_s, rel: "noopener"
51
54
  end
52
55
  html += "</div>".html_safe
53
56
  end
@@ -7,10 +7,10 @@ module Decidim
7
7
  # `filter` returns a Filter object from Decidim::FilterResource
8
8
  module FilterAssembliesHelper
9
9
  def available_filters
10
- %w(all) + Assembly::ASSEMBLY_TYPES
10
+ @available_filters ||= [t("all", scope: "decidim.assemblies.filter")] + organization_assembly_types
11
11
  end
12
12
 
13
- def filter_link(filter_name)
13
+ def filter_link(type_id)
14
14
  Decidim::Assemblies::Engine
15
15
  .routes
16
16
  .url_helpers
@@ -18,7 +18,7 @@ module Decidim
18
18
  filter: {
19
19
  scope_id: filter.scope_id,
20
20
  area_id: filter.area_id,
21
- assembly_type: filter_name
21
+ type_id: type_id
22
22
  }
23
23
  )
24
24
  end
@@ -27,12 +27,15 @@ module Decidim
27
27
  t("help", scope: "decidim.assemblies.filter")
28
28
  end
29
29
 
30
- def filter_name(filter_key)
31
- t(filter_key, scope: "decidim.assemblies.filter")
30
+ def current_filter_name
31
+ type = AssembliesType.find_by(id: filter.type_id)
32
+ return translated_attribute type.title if type
33
+
34
+ t("all", scope: "decidim.assemblies.filter")
32
35
  end
33
36
 
34
- def current_filter_name
35
- filter_name(filter.assembly_type)
37
+ def organization_assembly_types
38
+ AssembliesType.where(organization: current_organization)&.map { |type| [translated_attribute(type.title), type.id] }
36
39
  end
37
40
  end
38
41
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # Assemblies setting.
5
+ class AssembliesSetting < ApplicationRecord
6
+ include Decidim::Traceable
7
+ include Decidim::Loggable
8
+
9
+ belongs_to :organization,
10
+ foreign_key: "decidim_organization_id",
11
+ class_name: "Decidim::Organization"
12
+
13
+ def self.log_presenter_class_for(_log)
14
+ Decidim::Assemblies::AdminLog::AssembliesSettingPresenter
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # Assembly type.
5
+ class AssembliesType < ApplicationRecord
6
+ include Decidim::Traceable
7
+ include Decidim::Loggable
8
+
9
+ belongs_to :organization,
10
+ foreign_key: "decidim_organization_id",
11
+ class_name: "Decidim::Organization"
12
+
13
+ has_many :assemblies,
14
+ foreign_key: "decidim_assemblies_type_id",
15
+ class_name: "Decidim::Assembly",
16
+ dependent: :nullify
17
+
18
+ validates :title, presence: true
19
+
20
+ def self.log_presenter_class_for(_log)
21
+ Decidim::Assemblies::AdminLog::AssembliesTypePresenter
22
+ end
23
+ end
24
+ end
@@ -31,9 +31,9 @@ module Decidim
31
31
  include Decidim::Loggable
32
32
  include Decidim::ParticipatorySpaceResourceable
33
33
  include Decidim::HasPrivateUsers
34
+ include Decidim::Searchable
34
35
 
35
36
  SOCIAL_HANDLERS = [:twitter, :facebook, :instagram, :youtube, :github].freeze
36
- ASSEMBLY_TYPES = %w(government executive consultative_advisory participatory working_group commission others).freeze
37
37
  CREATED_BY = %w(city_council public others).freeze
38
38
 
39
39
  belongs_to :organization,
@@ -43,6 +43,10 @@ module Decidim
43
43
  foreign_key: "decidim_area_id",
44
44
  class_name: "Decidim::Area",
45
45
  optional: true
46
+ belongs_to :assembly_type,
47
+ foreign_key: "decidim_assemblies_type_id",
48
+ class_name: "Decidim::AssembliesType",
49
+ optional: true
46
50
  has_many :categories,
47
51
  foreign_key: "decidim_participatory_space_id",
48
52
  foreign_type: "decidim_participatory_space_type",
@@ -68,6 +72,18 @@ module Decidim
68
72
  after_create :set_parents_path
69
73
  after_update :set_parents_path, :update_children_paths, if: :saved_change_to_parent_id?
70
74
 
75
+ searchable_fields({
76
+ scope_id: :decidim_scope_id,
77
+ participatory_space: :itself,
78
+ A: :title,
79
+ B: :subtitle,
80
+ C: :short_description,
81
+ D: :description,
82
+ datetime: :published_at
83
+ },
84
+ index_on_create: ->(_assembly) { false },
85
+ index_on_update: ->(assembly) { assembly.visible? })
86
+
71
87
  # Overwriting existing method Decidim::HasPrivateUsers.visible_for
72
88
  def self.visible_for(user)
73
89
  if user
@@ -135,6 +151,13 @@ module Decidim
135
151
  closing_date < Date.current
136
152
  end
137
153
 
154
+ def user_roles(role_name = nil)
155
+ roles = Decidim::AssemblyUserRole.where(assembly: self)
156
+ return roles if role_name.blank?
157
+
158
+ roles.where(role: role_name)
159
+ end
160
+
138
161
  private
139
162
 
140
163
  # When an assembly changes their parent, we need to update the parents_path attribute
@@ -188,7 +211,7 @@ module Decidim
188
211
 
189
212
  # Allow ransacker to search for a key in a hstore column (`title`.`en`)
190
213
  ransacker :title do |parent|
191
- Arel::Nodes::InfixOperation.new("->", parent.table[:title], Arel::Nodes.build_quoted(I18n.locale.to_s))
214
+ Arel::Nodes::InfixOperation.new("->>", parent.table[:title], Arel::Nodes.build_quoted(I18n.locale.to_s))
192
215
  end
193
216
  end
194
217
  end
@@ -11,7 +11,7 @@ module Decidim
11
11
  belongs_to :assembly, foreign_key: "decidim_assembly_id", class_name: "Decidim::Assembly", optional: true
12
12
  alias participatory_space assembly
13
13
 
14
- ROLES = %w(admin collaborator moderator).freeze
14
+ ROLES = %w(admin collaborator moderator valuator).freeze
15
15
  validates :role, inclusion: { in: ROLES }, uniqueness: { scope: [:user, :assembly] }
16
16
  validate :user_and_assembly_same_organization
17
17
 
@@ -30,16 +30,20 @@ module Decidim
30
30
  return permission_action unless permission_action.scope == :admin
31
31
 
32
32
  user_can_read_assembly_list?
33
+ user_can_list_assembly_list?
33
34
  user_can_read_current_assembly?
34
35
  user_can_create_assembly?
36
+ user_can_read_assemblies_setting?
35
37
 
36
38
  # org admins and space admins can do everything in the admin section
37
39
  org_admin_action?
40
+ assemblies_type_action?
38
41
 
39
42
  return permission_action unless assembly
40
43
 
41
44
  moderator_action?
42
45
  collaborator_action?
46
+ valuator_action?
43
47
  assembly_admin_action?
44
48
 
45
49
  permission_action
@@ -47,6 +51,21 @@ module Decidim
47
51
 
48
52
  private
49
53
 
54
+ def assemblies_type_action?
55
+ return unless [:assembly_type, :assemblies_type].include? permission_action.subject
56
+ return disallow! unless user.admin?
57
+
58
+ assembly_type = context.fetch(:assembly_type, nil)
59
+ case permission_action.action
60
+ when :destroy
61
+ assemblies_is_empty = assembly_type && assembly_type.assemblies.empty?
62
+
63
+ toggle_allow(assemblies_is_empty)
64
+ else
65
+ allow!
66
+ end
67
+ end
68
+
50
69
  # It's an admin user if it's an organization admin or is a space admin
51
70
  # for the current `assembly`.
52
71
  def admin_user?
@@ -148,6 +167,13 @@ module Decidim
148
167
  toggle_allow(user.admin?)
149
168
  end
150
169
 
170
+ def user_can_read_assemblies_setting?
171
+ return unless permission_action.action == :read &&
172
+ permission_action.subject == :assemblies_setting
173
+
174
+ toggle_allow(user.admin?)
175
+ end
176
+
151
177
  # Everyone can read the assembly list
152
178
  def user_can_read_assembly_list?
153
179
  return unless read_assembly_list_permission_action?
@@ -155,6 +181,25 @@ module Decidim
155
181
  toggle_allow(user.admin? || has_manageable_assemblies?)
156
182
  end
157
183
 
184
+ # Checks whether the user can list the current given assembly or not.
185
+ #
186
+ # In case of user being admin of child assembly even parent assembly
187
+ # should be listed to be able to navigate to child assembly
188
+ def user_can_list_assembly_list?
189
+ return unless permission_action.action == :list &&
190
+ permission_action.subject == :assembly
191
+
192
+ toggle_allow(user.admin? || allowed_list_of_assemblies?)
193
+ end
194
+
195
+ def allowed_list_of_assemblies?
196
+ assemblies = AssembliesWithUserRole.for(user)
197
+ parent_assemblies = assemblies.flat_map { |assembly| [assembly.id] + assembly.ancestors.pluck(:id) }
198
+
199
+ allowed_list_of_assemblies = Decidim::Assembly.where(id: assemblies + parent_assemblies)
200
+ allowed_list_of_assemblies.uniq.member?(assembly)
201
+ end
202
+
158
203
  def user_can_read_current_assembly?
159
204
  return unless read_assembly_list_permission_action?
160
205
  return if permission_action.subject == :assembly_list
@@ -177,6 +222,14 @@ module Decidim
177
222
  allow! if permission_action.action == :read || permission_action.action == :preview
178
223
  end
179
224
 
225
+ # Valuators can only read the assembly components
226
+ def valuator_action?
227
+ return unless can_manage_assembly?(role: :valuator)
228
+
229
+ allow! if permission_action.action == :read && permission_action.subject == :component
230
+ allow! if permission_action.action == :export && permission_action.subject == :component_data
231
+ end
232
+
180
233
  # Process admins can perform everything *inside* that assembly. They cannot
181
234
  # create a assembly or perform actions on assembly groups or other
182
235
  # assemblies.
@@ -214,7 +267,8 @@ module Decidim
214
267
  :assembly,
215
268
  :assembly_user_role,
216
269
  :assembly_member,
217
- :space_private_user
270
+ :space_private_user,
271
+ :assemblies_setting
218
272
  ].include?(permission_action.subject)
219
273
  allow! if is_allowed
220
274
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Assemblies
5
+ module AdminLog
6
+ # This class holds the logic to present a `Decidim::AssembliesSetting`
7
+ # for the `AdminLog` log.
8
+ #
9
+ # Usage should be automatic and you shouldn't need to call this class
10
+ # directly, but here's an example:
11
+ #
12
+ # action_log = Decidim::ActionLog.last
13
+ # view_helpers # => this comes from the views
14
+ # AssembliesSettingPresenter.new(action_log, view_helpers).present
15
+ class AssembliesSettingPresenter < Decidim::Log::BasePresenter
16
+ private
17
+
18
+ def action_string
19
+ case action
20
+ when "update"
21
+ "decidim.admin_log.assembly_setting.#{action}"
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Assemblies
5
+ module AdminLog
6
+ # This class holds the logic to present a `Decidim::AssembliesType`
7
+ # for the `AdminLog` log.
8
+ #
9
+ # Usage should be automatic and you shouldn't need to call this class
10
+ # directly, but here's an example:
11
+ #
12
+ # action_log = Decidim::ActionLog.last
13
+ # view_helpers # => this comes from the views
14
+ # AssembliesTypePresenter.new(action_log, view_helpers).present
15
+ class AssembliesTypePresenter < Decidim::Log::BasePresenter
16
+ private
17
+
18
+ def diff_fields_mapping
19
+ {
20
+ title: :i18n
21
+ }
22
+ end
23
+
24
+ def i18n_labels_scope
25
+ "activemodel.attributes.assemblies_type"
26
+ end
27
+
28
+ def action_string
29
+ case action
30
+ when "create", "delete", "update"
31
+ "decidim.admin_log.assembly_type.#{action}"
32
+ else
33
+ super
34
+ end
35
+ end
36
+
37
+ def has_diff?
38
+ action == "delete" || super
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -37,8 +37,7 @@ module Decidim
37
37
  target: :i18n,
38
38
  title: :i18n,
39
39
  purpose_of_action: :i18n,
40
- assembly_type: :string,
41
- assembly_type_other: :i8n,
40
+ decidim_assemblies_type_id: :assembly_type,
42
41
  creation_date: :date,
43
42
  created_by: :string,
44
43
  created_by_other: :i18n,
@@ -38,7 +38,7 @@ module Decidim
38
38
 
39
39
  def render_stats_data(component_manifest, name, data, index)
40
40
  safe_join([
41
- index.zero? ? manifest_icon(component_manifest) : " /&nbsp".html_safe,
41
+ index.zero? ? manifest_icon(component_manifest, role: "img", "aria-hidden": true) : " /&nbsp".html_safe,
42
42
  content_tag(:span, "#{number_with_delimiter(data)} " + I18n.t(name, scope: "decidim.assemblies.statistics"),
43
43
  class: "#{name} process_stats-text")
44
44
  ])
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Log
5
+ module ValueTypes
6
+ # This class presents the given value as a Decidim::AssembliesType. Check
7
+ # the `DefaultPresenter` for more info on how value
8
+ # presenters work.
9
+ class AssemblyTypePresenter < DefaultPresenter
10
+ # Public: Presents the value as a Decidim::AssembliesType. If the type can
11
+ # be found, it shows its title. Otherwise it shows its ID.
12
+ #
13
+ # Returns an HTML-safe String.
14
+ def present
15
+ return unless value
16
+ return h.translated_attribute(type.title) if type
17
+
18
+ I18n.t("not_found", id: value, scope: "decidim.log.value_types.assembly_type_presenter")
19
+ end
20
+
21
+ private
22
+
23
+ def type
24
+ @type ||= Decidim::AssembliesType.find_by(id: value)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -13,9 +13,9 @@ module Decidim
13
13
  end
14
14
 
15
15
  def query
16
- return assemblies.all if @filter == "all"
16
+ return assemblies.all if @filter.blank?
17
17
 
18
- assemblies.where(assembly_type: @filter)
18
+ assemblies.where(decidim_assemblies_type_id: @filter)
19
19
  end
20
20
  end
21
21
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Assemblies
5
+ # This query filters assemblies that can be assigned as parents for an assembly.
6
+ class ParentAssembliesForSelect < Rectify::Query
7
+ # Syntactic sugar to initialize the class and return the queried objects.
8
+ def self.for(organization, assembly)
9
+ new(organization, assembly).query
10
+ end
11
+
12
+ # Initializes the class.
13
+ def initialize(organization, assembly)
14
+ @organization = organization
15
+ @assembly = assembly
16
+ end
17
+
18
+ # Finds the available assemblies
19
+ #
20
+ # Returns an ActiveRecord::Relation.
21
+ def query
22
+ available_assemblies = Assembly.where(organization: @organization).where.not(id: @assembly)
23
+
24
+ return available_assemblies if @assembly.blank?
25
+
26
+ available_assemblies.where.not(id: descendant_ids)
27
+ end
28
+
29
+ private
30
+
31
+ def descendant_ids
32
+ recursive_children(@assembly).flatten
33
+ end
34
+
35
+ def recursive_children(model)
36
+ model.children.map do |child|
37
+ [recursive_children(child), child.id]
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end