decidim-assemblies 0.21.0 → 0.23.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) 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 +4 -0
  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_assembly_admin.rb +2 -1
  10. data/app/commands/decidim/assemblies/admin/create_assembly_member.rb +12 -3
  11. data/app/commands/decidim/assemblies/admin/import_assembly.rb +72 -0
  12. data/app/commands/decidim/assemblies/admin/notify_role_assigned_to_assembly.rb +22 -0
  13. data/app/commands/decidim/assemblies/admin/update_assemblies_setting.rb +46 -0
  14. data/app/commands/decidim/assemblies/admin/update_assembly.rb +10 -5
  15. data/app/commands/decidim/assemblies/admin/update_assembly_admin.rb +2 -1
  16. data/app/controllers/decidim/assemblies/admin/assemblies_settings_controller.rb +49 -0
  17. data/app/controllers/decidim/assemblies/admin/assembly_exports_controller.rb +24 -0
  18. data/app/controllers/decidim/assemblies/admin/assembly_imports_controller.rb +31 -0
  19. data/app/controllers/decidim/assemblies/admin/assembly_user_roles_controller.rb +2 -1
  20. data/app/controllers/decidim/assemblies/assemblies_controller.rb +5 -1
  21. data/app/controllers/decidim/assemblies/{assembly_widgets_controller.rb → widgets_controller.rb} +2 -2
  22. data/app/events/decidim/assemblies/create_assembly_member_event.rb +17 -0
  23. data/app/events/decidim/role_assigned_to_assembly_event.rb +28 -0
  24. data/app/forms/decidim/assemblies/admin/assemblies_setting_form.rb +14 -0
  25. data/app/forms/decidim/assemblies/admin/assembly_form.rb +19 -10
  26. data/app/forms/decidim/assemblies/admin/assembly_import_form.rb +83 -0
  27. data/app/forms/decidim/assemblies/admin/assembly_user_role_form.rb +3 -2
  28. data/app/helpers/decidim/assemblies/assemblies_helper.rb +6 -3
  29. data/app/models/decidim/assemblies_setting.rb +17 -0
  30. data/app/models/decidim/assemblies_type.rb +3 -0
  31. data/app/models/decidim/assembly.rb +14 -1
  32. data/app/permissions/decidim/assemblies/permissions.rb +35 -2
  33. data/app/presenters/decidim/assemblies/admin_log/assemblies_setting_presenter.rb +27 -0
  34. data/app/presenters/decidim/assemblies/admin_log/assemblies_type_presenter.rb +2 -2
  35. data/app/presenters/decidim/assemblies/admin_log/assembly_member_presenter.rb +2 -2
  36. data/app/presenters/decidim/assemblies/admin_log/assembly_presenter.rb +2 -2
  37. data/app/presenters/decidim/assemblies/admin_log/assembly_user_role_presenter.rb +2 -2
  38. data/app/presenters/decidim/assemblies/assembly_presenter.rb +29 -0
  39. data/app/presenters/decidim/assemblies/assembly_stats_presenter.rb +1 -1
  40. data/app/queries/decidim/assemblies/parent_assemblies_for_select.rb +20 -1
  41. data/app/serializers/decidim/assemblies/assembly_importer.rb +172 -0
  42. data/app/serializers/decidim/assemblies/assembly_serializer.rb +147 -0
  43. data/app/views/decidim/assemblies/_filter_by_type.html.erb +11 -9
  44. data/app/views/decidim/assemblies/admin/assemblies/index.html.erb +13 -2
  45. data/app/views/decidim/assemblies/admin/assemblies_settings/_form.html.erb +10 -0
  46. data/app/views/decidim/assemblies/admin/assemblies_settings/edit.html.erb +6 -0
  47. data/app/views/decidim/assemblies/admin/assembly_imports/_form.html.erb +46 -0
  48. data/app/views/decidim/assemblies/admin/assembly_imports/new.html.erb +7 -0
  49. data/app/views/decidim/assemblies/admin/assembly_members/index.html.erb +2 -2
  50. data/app/views/decidim/assemblies/assemblies/_parent_assemblies.html.erb +2 -2
  51. data/app/views/decidim/assemblies/assemblies/_promoted_assembly.html.erb +3 -3
  52. data/app/views/decidim/assemblies/assemblies/index.html.erb +11 -8
  53. data/app/views/decidim/assemblies/assemblies/show.html.erb +10 -9
  54. data/app/views/decidim/assemblies/assembly_members/index.html.erb +1 -1
  55. data/app/views/layouts/decidim/admin/assemblies.html.erb +5 -0
  56. data/app/views/layouts/decidim/assembly.html.erb +1 -0
  57. data/config/locales/am-ET.yml +1 -0
  58. data/config/locales/bg-BG.yml +7 -0
  59. data/config/locales/bg.yml +7 -0
  60. data/config/locales/ca.yml +72 -1
  61. data/config/locales/cs.yml +118 -47
  62. data/config/locales/da-DK.yml +1 -0
  63. data/config/locales/da.yml +1 -0
  64. data/config/locales/de.yml +133 -39
  65. data/config/locales/el.yml +474 -0
  66. data/config/locales/en.yml +71 -0
  67. data/config/locales/eo.yml +1 -0
  68. data/config/locales/es-MX.yml +71 -0
  69. data/config/locales/es-PY.yml +71 -0
  70. data/config/locales/es.yml +71 -0
  71. data/config/locales/et-EE.yml +1 -0
  72. data/config/locales/et.yml +1 -0
  73. data/config/locales/fi-plain.yml +72 -1
  74. data/config/locales/fi.yml +79 -8
  75. data/config/locales/fr-CA.yml +481 -0
  76. data/config/locales/fr.yml +93 -1
  77. data/config/locales/ga-IE.yml +1 -0
  78. data/config/locales/gl.yml +37 -16
  79. data/config/locales/hr-HR.yml +1 -0
  80. data/config/locales/hr.yml +1 -0
  81. data/config/locales/hu.yml +53 -2
  82. data/config/locales/is.yml +263 -0
  83. data/config/locales/it.yml +159 -76
  84. data/config/locales/ja-JP.yml +471 -0
  85. data/config/locales/ja.yml +477 -0
  86. data/config/locales/ko-KR.yml +1 -0
  87. data/config/locales/ko.yml +1 -0
  88. data/config/locales/lt-LT.yml +1 -0
  89. data/config/locales/lt.yml +1 -0
  90. data/config/locales/lv.yml +454 -0
  91. data/config/locales/mt-MT.yml +1 -0
  92. data/config/locales/mt.yml +1 -0
  93. data/config/locales/nl.yml +77 -0
  94. data/config/locales/no.yml +79 -10
  95. data/config/locales/om-ET.yml +1 -0
  96. data/config/locales/pl.yml +240 -152
  97. data/config/locales/pt-BR.yml +1 -1
  98. data/config/locales/pt.yml +207 -119
  99. data/config/locales/ro-RO.yml +441 -0
  100. data/config/locales/si-LK.yml +1 -0
  101. data/config/locales/sk-SK.yml +168 -0
  102. data/config/locales/sk.yml +172 -0
  103. data/config/locales/sl.yml +283 -0
  104. data/config/locales/so-SO.yml +1 -0
  105. data/config/locales/sr-CS.yml +73 -0
  106. data/config/locales/sv.yml +178 -89
  107. data/config/locales/sw-KE.yml +1 -0
  108. data/config/locales/ti-ER.yml +1 -0
  109. data/config/locales/tr-TR.yml +237 -144
  110. data/config/locales/vi-VN.yml +1 -0
  111. data/config/locales/vi.yml +1 -0
  112. data/config/locales/zh-CN.yml +471 -0
  113. data/config/locales/zh-TW.yml +1 -0
  114. data/db/migrate/20200320105906_index_foreign_keys_in_decidim_assemblies.rb +7 -0
  115. data/db/migrate/20200320105907_index_foreign_keys_in_decidim_assembly_user_roles.rb +7 -0
  116. data/db/migrate/20200416132109_remove_legacy_decidim_assembly_type.rb +8 -0
  117. data/db/migrate/20200430202456_create_decidim_assemblies_settings.rb +10 -0
  118. data/db/seeds/city.jpeg +0 -0
  119. data/db/seeds/city2.jpeg +0 -0
  120. data/lib/decidim/assemblies/admin_engine.rb +8 -0
  121. data/lib/decidim/assemblies/engine.rb +1 -1
  122. data/lib/decidim/assemblies/participatory_space.rb +26 -13
  123. data/lib/decidim/assemblies/test/factories.rb +8 -3
  124. data/lib/decidim/assemblies/version.rb +1 -1
  125. metadata +74 -14
@@ -25,12 +25,13 @@ module Decidim
25
25
  CreateAssemblyAdmin.call(@form, current_user, current_assembly) do
26
26
  on(:ok) do
27
27
  flash[:notice] = I18n.t("assembly_user_roles.create.success", scope: "decidim.admin")
28
+ redirect_to assembly_user_roles_path(current_assembly)
28
29
  end
29
30
 
30
31
  on(:invalid) do
31
32
  flash[:alert] = I18n.t("assembly_user_roles.create.error", scope: "decidim.admin")
33
+ render :new
32
34
  end
33
- redirect_to assembly_user_roles_path(current_assembly)
34
35
  end
35
36
  end
36
37
 
@@ -8,7 +8,7 @@ module Decidim
8
8
  participatory_space_layout only: :show
9
9
  include FilterResource
10
10
 
11
- helper_method :parent_assemblies, :promoted_assemblies, :stats, :assembly_participatory_processes
11
+ helper_method :parent_assemblies, :promoted_assemblies, :stats, :assembly_participatory_processes, :current_assemblies_settings
12
12
 
13
13
  def index
14
14
  enforce_permission_to :list, :assembly
@@ -87,6 +87,10 @@ module Decidim
87
87
  def assembly_participatory_processes
88
88
  @assembly_participatory_processes ||= @current_participatory_space.linked_participatory_space_resources(:participatory_processes, "included_participatory_processes")
89
89
  end
90
+
91
+ def current_assemblies_settings
92
+ @current_assemblies_settings ||= Decidim::AssembliesSetting.find_or_create_by(decidim_organization_id: current_organization.id)
93
+ end
90
94
  end
91
95
  end
92
96
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Decidim
4
4
  module Assemblies
5
- class AssemblyWidgetsController < Decidim::WidgetsController
5
+ class WidgetsController < Decidim::WidgetsController
6
6
  helper Decidim::SanitizeHelper
7
7
 
8
8
  private
@@ -16,7 +16,7 @@ module Decidim
16
16
  end
17
17
 
18
18
  def iframe_url
19
- @iframe_url ||= assembly_assembly_widget_url(model)
19
+ @iframe_url ||= assembly_widget_url(model)
20
20
  end
21
21
  end
22
22
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Assemblies
5
+ class CreateAssemblyMemberEvent < Decidim::Events::SimpleEvent
6
+ i18n_attributes :resource_name
7
+
8
+ def resource_name
9
+ @resource_name ||= translated_attribute(assembly.title)
10
+ end
11
+
12
+ def assembly
13
+ @assembly ||= resource
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,28 @@
1
+ # frozen-string_literal: true
2
+
3
+ module Decidim
4
+ class RoleAssignedToAssemblyEvent < Decidim::Events::SimpleEvent
5
+ include Decidim::Events::NotificationEvent
6
+ include Decidim::Events::AuthorEvent
7
+
8
+ def notification_title
9
+ I18n.t("notification_title", i18n_options).html_safe
10
+ end
11
+
12
+ def i18n_role
13
+ I18n.t(extra["role"], "decidim.admin.models.assembly_user_role.roles", default: extra["role"])
14
+ end
15
+
16
+ def i18n_options
17
+ {
18
+ resource_path: resource_path,
19
+ resource_title: resource_title,
20
+ resource_url: resource_url,
21
+ scope: event_name,
22
+ participatory_space_title: participatory_space_title,
23
+ participatory_space_url: participatory_space_url,
24
+ role: i18n_role
25
+ }
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Assemblies
5
+ module Admin
6
+ # A form object used to create assembly setting from the admin dashboard.
7
+ class AssembliesSettingForm < Form
8
+ mimic :assemblies_setting
9
+
10
+ attribute :enable_organization_chart, Boolean
11
+ end
12
+ end
13
+ end
14
+ end
@@ -8,6 +8,7 @@ module Decidim
8
8
  #
9
9
  class AssemblyForm < Form
10
10
  include TranslatableAttributes
11
+ include Decidim::HasUploadValidations
11
12
 
12
13
  CREATED_BY = %w(city_council public others).freeze
13
14
 
@@ -62,7 +63,10 @@ module Decidim
62
63
  attribute :remove_hero_image
63
64
 
64
65
  validates :area, presence: true, if: proc { |object| object.area_id.present? }
65
- validates :parent, presence: true, if: ->(form) { form.parent_id.present? }
66
+
67
+ validates :parent, presence: true, if: ->(form) { form.parent.present? }
68
+ validate :ensure_parent_cannot_be_child, if: ->(form) { form.parent.present? }
69
+
66
70
  validates :scope, presence: true, if: proc { |object| object.scope_id.present? }
67
71
  validates :slug, presence: true, format: { with: Decidim::Assembly.slug_format }
68
72
 
@@ -72,12 +76,17 @@ module Decidim
72
76
  validates :created_by_other, translatable_presence: true, if: ->(form) { form.created_by == "others" }
73
77
  validates :title, :subtitle, :description, :short_description, translatable_presence: true
74
78
 
75
- validates :banner_image,
76
- file_size: { less_than_or_equal_to: ->(_record) { Decidim.maximum_attachment_size } },
77
- file_content_type: { allow: ["image/jpeg", "image/png"] }
78
- validates :hero_image,
79
- file_size: { less_than_or_equal_to: ->(_record) { Decidim.maximum_attachment_size } },
80
- file_content_type: { allow: ["image/jpeg", "image/png"] }
79
+ validates :banner_image, passthru: { to: Decidim::Assembly }
80
+ validates :hero_image, passthru: { to: Decidim::Assembly }
81
+
82
+ alias organization current_organization
83
+
84
+ def ensure_parent_cannot_be_child
85
+ return if id.blank?
86
+
87
+ available_assemblies = Decidim::Assemblies::ParentAssembliesForSelect.for(current_organization, Assembly.find(id))
88
+ errors.add(:parent, :invalid) unless available_assemblies.include? parent
89
+ end
81
90
 
82
91
  def map_model(model)
83
92
  self.scope_id = model.decidim_scope_id
@@ -93,7 +102,7 @@ module Decidim
93
102
 
94
103
  def assembly_types_for_select
95
104
  @assembly_types_for_select ||= organization_assembly_types
96
- &.map { |type| [translated_attribute(type.title), type.id] }
105
+ &.map { |type| [translated_attribute(type.title), type.id] }
97
106
  end
98
107
 
99
108
  def created_by_for_select
@@ -111,8 +120,8 @@ module Decidim
111
120
 
112
121
  def processes_for_select
113
122
  @processes_for_select ||= organization_participatory_processes
114
- &.map { |pp| [translated_attribute(pp.title), pp.id] }
115
- &.sort_by { |arr| arr[0] }
123
+ &.map { |pp| [translated_attribute(pp.title), pp.id] }
124
+ &.sort_by { |arr| arr[0] }
116
125
  end
117
126
 
118
127
  def assembly_type
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Assemblies
5
+ module Admin
6
+ # A form object used to import an assembly from the admin
7
+ # dashboard.
8
+ #
9
+ class AssemblyImportForm < Form
10
+ include TranslatableAttributes
11
+
12
+ JSON_MIME_TYPE = "application/json"
13
+ # Accepted mime types
14
+ # keys: are used for dynamic help text on admin form.
15
+ # values: are used to validate the file format of imported document.
16
+ #
17
+ # WARNING: consider adding/removing the relative translation key at
18
+ # decidim.assemblies.admin.new_import.accepted_types when modifying this hash
19
+ ACCEPTED_TYPES = {
20
+ json: JSON_MIME_TYPE
21
+ }.freeze
22
+
23
+ translatable_attribute :title, String
24
+
25
+ mimic :assembly
26
+
27
+ attribute :slug, String
28
+ attribute :import_steps, Boolean, default: false
29
+ attribute :import_categories, Boolean, default: true
30
+ attribute :import_attachments, Boolean, default: true
31
+ attribute :import_components, Boolean, default: true
32
+ attribute :document
33
+
34
+ validates :document, presence: true
35
+
36
+ validates :slug, presence: true, format: { with: Decidim::Assembly.slug_format }
37
+ validates :title, translatable_presence: true
38
+ validate :slug_uniqueness
39
+
40
+ validate :document_type_must_be_valid, if: :document
41
+
42
+ def document_text
43
+ @document_text ||= document&.read
44
+ end
45
+
46
+ def document_type_must_be_valid
47
+ return if valid_mime_types.include?(document_type)
48
+
49
+ errors.add(:document, i18n_invalid_document_type_text)
50
+ end
51
+
52
+ # Return ACCEPTED_MIME_TYPES plus `text/plain` for better markdown support
53
+ def valid_mime_types
54
+ ACCEPTED_TYPES.values
55
+ end
56
+
57
+ def document_type
58
+ document.content_type
59
+ end
60
+
61
+ def i18n_invalid_document_type_text
62
+ I18n.t("invalid_document_type",
63
+ scope: "activemodel.errors.models.assembly.attributes.document",
64
+ valid_mime_types: i18n_valid_mime_types_text)
65
+ end
66
+
67
+ def i18n_valid_mime_types_text
68
+ ACCEPTED_TYPES.keys.map do |mime_type|
69
+ I18n.t(mime_type, scope: "decidim.assemblies.admin.new_import.accepted_types")
70
+ end.join(", ")
71
+ end
72
+
73
+ private
74
+
75
+ def slug_uniqueness
76
+ return unless OrganizationAssemblies.new(current_organization).query.where(slug: slug).where.not(id: id).any?
77
+
78
+ errors.add(:slug, :taken)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -12,10 +12,11 @@ module Decidim
12
12
  attribute :email, String
13
13
  attribute :role, String
14
14
 
15
- validates :email, :role, presence: true
16
- validates :name, presence: true
15
+ validates :name, :email, :role, presence: true
17
16
  validates :role, inclusion: { in: Decidim::AssemblyUserRole::ROLES }
18
17
 
18
+ validates :name, format: { with: UserBaseEntity::REGEXP_NAME }
19
+
19
20
  def roles
20
21
  Decidim::AssemblyUserRole::ROLES.map do |role|
21
22
  [
@@ -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
@@ -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
@@ -5,6 +5,9 @@ module Decidim
5
5
  class AssembliesType < ApplicationRecord
6
6
  include Decidim::Traceable
7
7
  include Decidim::Loggable
8
+ include Decidim::TranslatableResource
9
+
10
+ translatable_fields :title
8
11
 
9
12
  belongs_to :organization,
10
13
  foreign_key: "decidim_organization_id",
@@ -24,7 +24,7 @@ module Decidim
24
24
  include Decidim::HasAttachmentCollections
25
25
  include Decidim::Participable
26
26
  include Decidim::Publicable
27
- include Decidim::Scopable
27
+ include Decidim::ScopableParticipatorySpace
28
28
  include Decidim::Followable
29
29
  include Decidim::HasReference
30
30
  include Decidim::Traceable
@@ -32,10 +32,16 @@ module Decidim
32
32
  include Decidim::ParticipatorySpaceResourceable
33
33
  include Decidim::HasPrivateUsers
34
34
  include Decidim::Searchable
35
+ include Decidim::HasUploadValidations
36
+ include Decidim::TranslatableResource
35
37
 
36
38
  SOCIAL_HANDLERS = [:twitter, :facebook, :instagram, :youtube, :github].freeze
37
39
  CREATED_BY = %w(city_council public others).freeze
38
40
 
41
+ translatable_fields :title, :subtitle, :short_description, :description, :developer_group, :meta_scope, :local_area,
42
+ :target, :participatory_scope, :participatory_structure, :purpose_of_action, :composition, :created_by_other,
43
+ :closing_date_reason, :internal_organisation, :special_features
44
+
39
45
  belongs_to :organization,
40
46
  foreign_key: "decidim_organization_id",
41
47
  class_name: "Decidim::Organization"
@@ -63,7 +69,10 @@ module Decidim
63
69
  has_many :children, foreign_key: "parent_id", class_name: "Decidim::Assembly", inverse_of: :parent, dependent: :destroy
64
70
  belongs_to :parent, foreign_key: "parent_id", class_name: "Decidim::Assembly", inverse_of: :children, optional: true, counter_cache: :children_count
65
71
 
72
+ validates_upload :hero_image
66
73
  mount_uploader :hero_image, Decidim::HeroImageUploader
74
+
75
+ validates_upload :banner_image
67
76
  mount_uploader :banner_image, Decidim::BannerImageUploader
68
77
 
69
78
  validates :slug, uniqueness: { scope: :organization }
@@ -158,6 +167,10 @@ module Decidim
158
167
  roles.where(role: role_name)
159
168
  end
160
169
 
170
+ def attachment_context
171
+ :admin
172
+ end
173
+
161
174
  private
162
175
 
163
176
  # When an assembly changes their parent, we need to update the parents_path attribute
@@ -30,8 +30,10 @@ 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?
@@ -165,6 +167,13 @@ module Decidim
165
167
  toggle_allow(user.admin?)
166
168
  end
167
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
+
168
177
  # Everyone can read the assembly list
169
178
  def user_can_read_assembly_list?
170
179
  return unless read_assembly_list_permission_action?
@@ -172,6 +181,25 @@ module Decidim
172
181
  toggle_allow(user.admin? || has_manageable_assemblies?)
173
182
  end
174
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
+
175
203
  def user_can_read_current_assembly?
176
204
  return unless read_assembly_list_permission_action?
177
205
  return if permission_action.subject == :assembly_list
@@ -221,7 +249,9 @@ module Decidim
221
249
  :assembly,
222
250
  :assembly_user_role,
223
251
  :assembly_member,
224
- :space_private_user
252
+ :space_private_user,
253
+ :export_space,
254
+ :import
225
255
  ].include?(permission_action.subject)
226
256
  allow! if is_allowed
227
257
  end
@@ -239,7 +269,10 @@ module Decidim
239
269
  :assembly,
240
270
  :assembly_user_role,
241
271
  :assembly_member,
242
- :space_private_user
272
+ :space_private_user,
273
+ :export_space,
274
+ :import,
275
+ :assemblies_setting
243
276
  ].include?(permission_action.subject)
244
277
  allow! if is_allowed
245
278
  end