decidim-department_admin 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE-AGPLv3.txt +661 -0
  3. data/README.md +132 -0
  4. data/Rakefile +9 -0
  5. data/app/controllers/decidim/department_admin/admin/application_controller.rb +15 -0
  6. data/app/controllers/decidim/department_admin/application_controller.rb +13 -0
  7. data/app/decorators/decidim/admin/newsletters_controller_decorator.rb +30 -0
  8. data/app/decorators/decidim/admin/users_controller_decorator.rb +128 -0
  9. data/app/decorators/decidim/area_decorator.rb +44 -0
  10. data/app/decorators/decidim/assemblies/admin/assemblies_controller_decorator.rb +25 -0
  11. data/app/decorators/decidim/assemblies/admin/assemblies_helper_decorator.rb +24 -0
  12. data/app/decorators/decidim/assemblies/create_assembly_decorator.rb +19 -0
  13. data/app/decorators/decidim/assemblies/parent_assemblies_for_select_decorator.rb +38 -0
  14. data/app/decorators/decidim/assemblies/permissions_decorator.rb +22 -0
  15. data/app/decorators/decidim/assemblies/update_assembly_decorator.rb +19 -0
  16. data/app/decorators/decidim/assemblies_decorator.rb +21 -0
  17. data/app/decorators/decidim/assemblies_with_user_role_decorator.rb +27 -0
  18. data/app/decorators/decidim/conference_form_decorator.rb +23 -0
  19. data/app/decorators/decidim/conferences/admin/conferences_controller_decorator.rb +27 -0
  20. data/app/decorators/decidim/conferences/create_conference_decorator.rb +52 -0
  21. data/app/decorators/decidim/conferences/permissions_decorator.rb +24 -0
  22. data/app/decorators/decidim/conferences/update_conference_decorator.rb +21 -0
  23. data/app/decorators/decidim/conferences_decorator.rb +27 -0
  24. data/app/decorators/decidim/conferences_with_user_role_decorator.rb +29 -0
  25. data/app/decorators/decidim/decidim_form_helper_decorator.rb +23 -0
  26. data/app/decorators/decidim/invite_user_decorator.rb +56 -0
  27. data/app/decorators/decidim/invite_user_form_decorator.rb +45 -0
  28. data/app/decorators/decidim/newsletter_decorator.rb +20 -0
  29. data/app/decorators/decidim/newsletters_helper_decorator.rb +44 -0
  30. data/app/decorators/decidim/participatory_process_decorator.rb +21 -0
  31. data/app/decorators/decidim/participatory_process_group_decorator.rb +17 -0
  32. data/app/decorators/decidim/participatory_processes/admin/participatory_processes_controller_decorator.rb +25 -0
  33. data/app/decorators/decidim/participatory_processes/create_participatory_process_decorator.rb +19 -0
  34. data/app/decorators/decidim/participatory_processes/permissions_decorator.rb +22 -0
  35. data/app/decorators/decidim/participatory_processes/update_participatory_process_decorator.rb +19 -0
  36. data/app/decorators/decidim/participatory_processes_with_user_role_decorator.rb +27 -0
  37. data/app/decorators/decidim/user_decorator.rb +59 -0
  38. data/app/decorators/lib/decidim/participatory_space_resourceable_decorator.rb +33 -0
  39. data/app/helpers/decidim/admin/user_roles_helper.rb +25 -0
  40. data/app/helpers/decidim/department_admin/application_helper.rb +54 -0
  41. data/app/models/decidim/participatory_space_role_config/department_admin.rb +8 -0
  42. data/app/overrides/decidim/admin/shared/add_radio_buttons_to_filters.rb +6 -0
  43. data/app/packs/entrypoints/decidim_department_admin.js +4 -0
  44. data/app/packs/entrypoints/decidim_department_admin.scss +1 -0
  45. data/app/packs/images/decidim/department_admin/icon.svg +1 -0
  46. data/app/packs/stylesheets/decidim/admin/department_admin.scss +7 -0
  47. data/app/permissions/decidim/assemblies/participatory_space_permissions.rb +14 -0
  48. data/app/permissions/decidim/conferences/participatory_space_permissions.rb +17 -0
  49. data/app/permissions/decidim/department_admin/permissions.rb +240 -0
  50. data/app/permissions/decidim/participatory_processes/participatory_space_permissions.rb +14 -0
  51. data/app/queries/decidim/admin/user_admin_by_space_name_filter.rb +67 -0
  52. data/app/queries/decidim/admin/user_admin_filter.rb +50 -0
  53. data/app/views/decidim/admin/users/_filters.html.erb +32 -0
  54. data/app/views/decidim/admin/users/_form.html.erb +36 -0
  55. data/app/views/decidim/admin/users/index.html.erb +91 -0
  56. data/app/views/decidim/admin/users/show.html.erb +98 -0
  57. data/app/views/decidim/assemblies/admin/assemblies/index.html.erb +139 -0
  58. data/app/views/decidim/conferences/admin/conferences/_form.html.erb +134 -0
  59. data/app/views/decidim/conferences/admin/conferences/index.html.erb +78 -0
  60. data/app/views/decidim/participatory_processes/admin/participatory_processes/index.html.erb +117 -0
  61. data/config/assets.rb +27 -0
  62. data/config/i18n-tasks.yml +148 -0
  63. data/config/initializers/user_roles.rb +4 -0
  64. data/config/locales/ca.yml +61 -0
  65. data/config/locales/cs.yml +46 -0
  66. data/config/locales/en.yml +61 -0
  67. data/config/locales/es.yml +61 -0
  68. data/db/migrate/20190328130102_create_department_admin_areas.rb +10 -0
  69. data/db/migrate/20210420143021_add_area_to_conferences.rb +7 -0
  70. data/lib/decidim/department_admin/admin.rb +10 -0
  71. data/lib/decidim/department_admin/admin_engine.rb +27 -0
  72. data/lib/decidim/department_admin/engine.rb +136 -0
  73. data/lib/decidim/department_admin/test/factories.rb +17 -0
  74. data/lib/decidim/department_admin/version.rb +11 -0
  75. data/lib/decidim/department_admin.rb +15 -0
  76. metadata +189 -0
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Intercepts the `call` method and forces the Area of the user if it is a
4
+ # department_admin user.
5
+ module Decidim::Conferences::CreateConferenceDecorator
6
+ def self.decorate
7
+ return unless Decidim::DepartmentAdmin.conferences_defined?
8
+
9
+ Decidim::Conferences::Admin::CreateConference.class_eval do
10
+ alias_method :original_call, :call
11
+
12
+ def call
13
+ author = form.current_user
14
+ form.area_id = author.areas.first.id if author.department_admin?
15
+ original_call
16
+ end
17
+
18
+ private
19
+
20
+ def conference
21
+ @conference ||= Decidim.traceability.create(
22
+ Decidim::Conference,
23
+ form.current_user,
24
+ organization: form.current_organization,
25
+ title: form.title,
26
+ slogan: form.slogan,
27
+ slug: form.slug,
28
+ hashtag: form.hashtag,
29
+ weight: form.weight,
30
+ description: form.description,
31
+ short_description: form.short_description,
32
+ objectives: form.objectives,
33
+ location: form.location,
34
+ scopes_enabled: form.scopes_enabled,
35
+ scope: form.scope,
36
+ start_date: form.start_date,
37
+ end_date: form.end_date,
38
+ hero_image: form.hero_image,
39
+ banner_image: form.banner_image,
40
+ promoted: form.promoted,
41
+ show_statistics: form.show_statistics,
42
+ registrations_enabled: form.registrations_enabled,
43
+ available_slots: form.available_slots || 0,
44
+ registration_terms: form.registration_terms,
45
+ area: form.area
46
+ )
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ Decidim::Conferences::CreateConferenceDecorator.decorate
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim::Conferences::PermissionsDecorator
4
+ def self.decorate
5
+ return unless Decidim::DepartmentAdmin.conferences_defined?
6
+
7
+ Decidim::Conferences::Permissions.class_eval do
8
+ # Intercept the `has_manageable_conferences?` method
9
+ # always returns true if the user is a department_admin. Otherwise delegates to the original method.
10
+ # This is a fix to avoid permissions crashing when there are no conferences with the user's area.
11
+ alias_method :original_has_manageable_conferences?, :has_manageable_conferences?
12
+
13
+ # rubocop: disable Lint/UnusedMethodArgument
14
+ def has_manageable_conferences?(role: :any)
15
+ return unless user
16
+
17
+ user.department_admin? || original_has_manageable_conferences?
18
+ end
19
+ # rubocop: enable Lint/UnusedMethodArgument
20
+ end
21
+ end
22
+ end
23
+
24
+ Decidim::Conferences::PermissionsDecorator.decorate
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Intercepts the `call` method and forces the Area of the user if it is a
4
+ # department_admin user.
5
+ module Decidim::Conferences::UpdateConferenceDecorator
6
+ def self.decorate
7
+ return unless Decidim::DepartmentAdmin.conferences_defined?
8
+
9
+ Decidim::Conferences::Admin::UpdateConference.class_eval do
10
+ alias_method :original_call, :call
11
+
12
+ def call
13
+ author = form.current_user
14
+ form.area_id = author.areas.first.id if author.department_admin?
15
+ original_call
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ Decidim::Conferences::UpdateConferenceDecorator.decorate
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim::ConferencesDecorator
4
+ #
5
+ # This decorator adds required associations between Decidim::Conference and Area.
6
+ #
7
+ def self.decorate
8
+ return unless Decidim::DepartmentAdmin.conferences_defined?
9
+
10
+ require_dependency "decidim/conference"
11
+ Decidim::Conference.class_eval do
12
+ belongs_to :area,
13
+ foreign_key: "decidim_area_id",
14
+ class_name: "Decidim::Area",
15
+ optional: true
16
+
17
+ has_and_belongs_to_many :users_with_any_role,
18
+ class_name: "Decidim::User",
19
+ join_table: :decidim_conference_user_roles,
20
+ foreign_key: :decidim_conference_id,
21
+ association_foreign_key: :decidim_user_id,
22
+ validate: false
23
+ end
24
+ end
25
+ end
26
+
27
+ Decidim::ConferencesDecorator.decorate
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim::ConferencesWithUserRoleDecorator
4
+ #
5
+ # This decorator adds the capability to query participatory_processes
6
+ # filtering by User role `department_admin`.
7
+ #
8
+ def self.decorate
9
+ return unless Decidim::DepartmentAdmin.conferences_defined?
10
+
11
+ Decidim::Conferences::ConferencesWithUserRole.class_eval do
12
+ private
13
+
14
+ alias_method :conference_ids_by_conferences_user_table, :conference_ids
15
+
16
+ def conference_ids
17
+ ids = [conference_ids_by_conferences_user_table]
18
+ if user&.department_admin?
19
+ ids << ::Decidim::Conference
20
+ .where("decidim_area_id" => user.areas.pluck(:id)).pluck(:id)
21
+ end
22
+
23
+ ::Decidim::Conference.where(id: ids.flatten.uniq)
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ Decidim::ConferencesWithUserRoleDecorator.decorate
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim::DecidimFormHelperDecorator
4
+ #
5
+ # This decorator override Decidim::DecidimFormHelper methods:
6
+ # - areas_for_select with assigned areas to user.
7
+ #
8
+ def self.decorate
9
+ Decidim::DecidimFormHelper.class_eval do
10
+ alias_method :original_areas_for_select, :areas_for_select
11
+
12
+ def areas_for_select(organization)
13
+ author = current_user
14
+
15
+ return author.areas if author&.department_admin? && controller_path.split("/").include?("admin")
16
+
17
+ original_areas_for_select(organization)
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ Decidim::DecidimFormHelperDecorator.decorate
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim::InviteUserDecorator
4
+ #
5
+ # This decorator overwrites how InviteUser performs the invitation by associating the area to the user.
6
+ #
7
+ def self.decorate
8
+ Decidim::InviteUser.class_eval do
9
+ alias_method :original_update_user, :update_user
10
+
11
+ def update_user
12
+ add_selected_area_to(user)
13
+ clear_department_admin_role if admin_role?
14
+ original_update_user
15
+ end
16
+
17
+ def invite_user
18
+ @user = Decidim::User.new(
19
+ name: form.name,
20
+ email: form.email.downcase,
21
+ nickname: Decidim::UserBaseEntity.nicknamize(form.name, organization: form.organization),
22
+ organization: form.organization,
23
+ admin: admin_role?,
24
+ roles: admin_role? ? [] : [form.role].compact
25
+ )
26
+ add_selected_area_to(@user)
27
+ @user.invite!(
28
+ form.invited_by,
29
+ invitation_instructions: form.invitation_instructions
30
+ )
31
+ end
32
+
33
+ private #---------------------------------------------------------
34
+
35
+ def add_selected_area_to(user)
36
+ if current_user.department_admin?
37
+ user.areas << current_user.areas.first
38
+ elsif form.selected_area.present?
39
+ user.areas.clear
40
+ user.areas << form.selected_area
41
+ end
42
+ end
43
+
44
+ def admin_role?
45
+ form.role == "admin"
46
+ end
47
+
48
+ def clear_department_admin_role
49
+ user.areas.clear
50
+ user.roles.delete("department_admin")
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ Decidim::InviteUserDecorator.decorate
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim::InviteUserFormDecorator
4
+ #
5
+ # This decorator adds the attribute area_id tot the InviteUserForm and
6
+ # extends it with utility methods for the view and command.
7
+ #
8
+ def self.decorate
9
+ Decidim::InviteUserForm.class_eval do
10
+ attribute :area_id, Integer
11
+
12
+ alias_method :original_roles_method, :available_roles_for_select
13
+
14
+ def available_roles_for_select
15
+ if current_user.department_admin?
16
+ Decidim::User::Roles.all.select { |n| n == "department_admin" }.map do |role|
17
+ [
18
+ I18n.t("models.user.fields.roles.#{role}", scope: "decidim.admin"),
19
+ role,
20
+ ]
21
+ end
22
+ else
23
+ original_roles_method
24
+ end
25
+ end
26
+
27
+ # called from the view
28
+ def available_areas_for_select
29
+ if current_user.department_admin?
30
+ current_user.areas.collect { |area| [area.translated_name, area.id] }
31
+ else
32
+ Decidim::Area.all.collect { |area| [area.translated_name, area.id] }
33
+ end
34
+ end
35
+
36
+ # called from the command
37
+ # returns the selected Decidim::Area instance.
38
+ def selected_area
39
+ Decidim::Area.find_by(id: area_id)
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ Decidim::InviteUserFormDecorator.decorate
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_dependency "decidim/newsletter"
4
+
5
+ module Decidim::NewsletterDecorator
6
+ def self.decorate
7
+ Decidim::Newsletter.class_eval do
8
+ # The area of the newsletter is the same
9
+ # than the area of the author of the newsletter.
10
+ # The method name is `area` because the permissions system
11
+ # must verify that the `user` has the same `area` as the `resource`.
12
+ def area
13
+ return unless author.areas.any?
14
+ return author.areas.first if author&.department_admin?
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ Decidim::NewsletterDecorator.decorate
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim::NewslettersHelperDecorator
4
+ # rubocop: disable Metrics/CyclomaticComplexity
5
+ # rubocop: disable Metrics/PerceivedComplexity
6
+ def self.decorate
7
+ Decidim::Admin::NewslettersHelper.class_eval do
8
+ alias_method :original_spaces_user_can_admin, :spaces_user_can_admin
9
+
10
+ def spaces_user_can_admin
11
+ author = current_user
12
+
13
+ if author&.department_admin?
14
+ spaces_department_admin_can_admin
15
+ else
16
+ original_spaces_user_can_admin
17
+ end
18
+ end
19
+
20
+ def spaces_department_admin_can_admin
21
+ @spaces_user_can_admin ||= {}
22
+ Decidim.participatory_space_manifests.each do |manifest|
23
+ organization_participatory_space(manifest.name)&.each do |space|
24
+ next unless space.respond_to?(:decidim_area_id)
25
+ next if space.decidim_area_id.blank?
26
+ next unless current_user.areas.any?
27
+ next unless space.decidim_area_id == current_user.areas.first.id
28
+
29
+ @spaces_user_can_admin[manifest.name] ||= []
30
+ space_as_option_for_select_data = space_as_option_for_select(space)
31
+ @spaces_user_can_admin[manifest.name] << space_as_option_for_select_data unless @spaces_user_can_admin[manifest.name].detect do |x|
32
+ x == space_as_option_for_select_data
33
+ end
34
+ end
35
+ end
36
+ @spaces_user_can_admin
37
+ end
38
+ end
39
+ end
40
+ # rubocop: enable Metrics/CyclomaticComplexity
41
+ # rubocop: enable Metrics/PerceivedComplexity
42
+ end
43
+
44
+ Decidim::NewslettersHelperDecorator.decorate
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim::ParticipatoryProcessDecorator
4
+ #
5
+ # This decorator adds required associations between Decidim::ParticipatoryProcess and Departaments.
6
+ #
7
+ #
8
+ def self.decorate
9
+ require_dependency "decidim/participatory_process"
10
+ Decidim::ParticipatoryProcess.class_eval do
11
+ has_and_belongs_to_many :users_with_any_role,
12
+ class_name: "Decidim::User",
13
+ join_table: :decidim_participatory_process_user_roles,
14
+ foreign_key: :decidim_participatory_process_id,
15
+ association_foreign_key: :decidim_user_id,
16
+ validate: false
17
+ end
18
+ end
19
+ end
20
+
21
+ Decidim::ParticipatoryProcessDecorator.decorate
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim::ParticipatoryProcessGroupDecorator
4
+ #
5
+ # This decorator adds required associations between Decidim::ParticipatoryProcess and Departaments.
6
+ #
7
+ def self.decorate
8
+ require_dependency "decidim/participatory_process_group"
9
+ Decidim::ParticipatoryProcessGroup.class_eval do
10
+ has_many :participatory_process,
11
+ class_name: "ParticipatoryProcess",
12
+ foreign_key: "decidim_participatory_process_group_id"
13
+ end
14
+ end
15
+ end
16
+
17
+ Decidim::ParticipatoryProcessGroupDecorator.decorate
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim::ParticipatoryProcesses::Admin::ParticipatoryProcessesControllerDecorator
4
+ #
5
+ # This decorator adds the capability to the controller to query processes
6
+ # filtering by User role `department_admin`.
7
+ #
8
+ def self.decorate
9
+ Decidim::ParticipatoryProcesses::Admin::ParticipatoryProcessesController.class_eval do
10
+ private
11
+
12
+ alias_method :original_organization_processes, :collection
13
+
14
+ def collection
15
+ @collection ||= if current_user.admin?
16
+ original_organization_processes
17
+ else
18
+ ::Decidim::ParticipatoryProcessesWithUserRole.for(current_user)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ Decidim::ParticipatoryProcesses::Admin::ParticipatoryProcessesControllerDecorator.decorate
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim::ParticipatoryProcesses::CreateParticipatoryProcessDecorator
4
+ # Intercepts the `call` method and forces the Area of the user if it is a
5
+ # department_admin user.
6
+ def self.decorate
7
+ Decidim::ParticipatoryProcesses::Admin::CreateParticipatoryProcess.class_eval do
8
+ alias_method :original_call, :call
9
+
10
+ def call
11
+ author = form.current_user
12
+ form.area_id = author.areas.first.id if author.department_admin?
13
+ original_call
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ Decidim::ParticipatoryProcesses::CreateParticipatoryProcessDecorator.decorate
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim::ParticipatoryProcesses::PermissionsDecorator
4
+ def self.decorate
5
+ Decidim::ParticipatoryProcesses::Permissions.class_eval do
6
+ # Intercept the `has_manageable_processes?` method
7
+ # always returns true if the user is a department_admin. Otherwise delegates to the original method.
8
+ # This is a fix to avoid permissions crashing when there are no processes with the user's area.
9
+ alias_method :original_has_manageable_processes?, :has_manageable_processes?
10
+
11
+ # rubocop: disable Lint/UnusedMethodArgument
12
+ def has_manageable_processes?(role: :any)
13
+ return unless user
14
+
15
+ user.department_admin? || original_has_manageable_processes?
16
+ end
17
+ # rubocop: enable Lint/UnusedMethodArgument
18
+ end
19
+ end
20
+ end
21
+
22
+ Decidim::ParticipatoryProcesses::PermissionsDecorator.decorate
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim::ParticipatoryProcesses::UpdateParticipatoryProcessDecorator
4
+ # Intercepts the `call` method and forces the Area of the user if it is a
5
+ # department_admin user.
6
+ def self.decorate
7
+ Decidim::ParticipatoryProcesses::Admin::UpdateParticipatoryProcess.class_eval do
8
+ alias_method :original_call, :call
9
+
10
+ def call
11
+ author = form.current_user
12
+ form.area_id = author.areas.first.id if author.department_admin?
13
+ original_call
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ Decidim::ParticipatoryProcesses::UpdateParticipatoryProcessDecorator.decorate
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim::ParticipatoryProcessesWithUserRoleDecorator
4
+ #
5
+ # This decorator adds the capability to query participatory_processes
6
+ # filtering by User role `department_admin`.
7
+ #
8
+ def self.decorate
9
+ Decidim::ParticipatoryProcessesWithUserRole.class_eval do
10
+ private
11
+
12
+ alias_method :process_ids_by_process_user_table, :process_ids
13
+
14
+ def process_ids
15
+ ids = [process_ids_by_process_user_table]
16
+ if user&.department_admin?
17
+ ids << ::Decidim::ParticipatoryProcess
18
+ .where("decidim_area_id" => user.areas.pluck(:id))
19
+ end
20
+
21
+ ::Decidim::ParticipatoryProcess.where(id: ids.flatten.uniq)
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ Decidim::ParticipatoryProcessesWithUserRoleDecorator.decorate
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim::UserDecorator
4
+ #
5
+ # This decorator adds required associations between Decidim::User and Area.
6
+ #
7
+ def self.decorate
8
+ require_dependency "decidim/user"
9
+ Decidim::User.class_eval do
10
+ has_and_belongs_to_many :areas,
11
+ join_table: :department_admin_areas,
12
+ foreign_key: :decidim_user_id,
13
+ association_foreign_key: :decidim_area_id,
14
+ validate: false
15
+
16
+ has_and_belongs_to_many :participatory_processes,
17
+ join_table: :decidim_participatory_process_user_roles,
18
+ foreign_key: :decidim_user_id,
19
+ association_foreign_key: :decidim_participatory_process_id,
20
+ validate: false
21
+
22
+ has_and_belongs_to_many :assemblies,
23
+ join_table: :decidim_assembly_user_roles,
24
+ foreign_key: :decidim_user_id,
25
+ association_foreign_key: :decidim_assembly_id,
26
+ validate: false
27
+ if Decidim::DepartmentAdmin.conferences_defined?
28
+ has_and_belongs_to_many :conferences,
29
+ join_table: :decidim_conference_user_roles,
30
+ foreign_key: :decidim_user_id,
31
+ association_foreign_key: :decidim_conference_id,
32
+ validate: false
33
+ end
34
+
35
+ scope :admins, -> { where(admin: true) }
36
+ scope :user_managers, -> { where(roles: ["user_manager"]) }
37
+ scope :department_admins, -> { where(roles: ["department_admin"]) }
38
+
39
+ def department_admin?
40
+ role?("department_admin")
41
+ end
42
+
43
+ def self.space_admins(organization)
44
+ if Decidim::DepartmentAdmin.conferences_defined?
45
+ Decidim::User.where(organization:)
46
+ .where('"decidim_users"."id" in (select "decidim_participatory_process_user_roles"."decidim_user_id" from "decidim_participatory_process_user_roles") ' \
47
+ 'or "decidim_users"."id" in (select "decidim_assembly_user_roles"."decidim_user_id" from "decidim_assembly_user_roles") ' \
48
+ 'or "decidim_users"."id" in (select "decidim_conference_user_roles"."decidim_user_id" from "decidim_conference_user_roles")')
49
+ else
50
+ Decidim::User.where(organization:)
51
+ .where('"decidim_users"."id" in (select "decidim_participatory_process_user_roles"."decidim_user_id" from "decidim_participatory_process_user_roles") ' \
52
+ 'or "decidim_users"."id" in (select "decidim_assembly_user_roles"."decidim_user_id" from "decidim_assembly_user_roles")')
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ Decidim::UserDecorator.decorate
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Lib::Decidim::ParticipatorySpaceResourceableDecorator
4
+ #
5
+ # This decorator overrided method to avoid .to_sym error when logged in user is Department Admin
6
+ # Override affects only line `case role_name&.to_sym`
7
+ # Furthermore added new ParticipatorySpaceRole case for DeparmentAdmin
8
+ #
9
+ def self.decorate
10
+ Decidim::ParticipatorySpaceResourceable.class_eval do
11
+ def user_role_config_for(user, role_name)
12
+ case role_name&.to_sym
13
+ when :organization_admin
14
+ Decidim::ParticipatorySpaceRoleConfig::Admin.new(user)
15
+ when :admin # ParticipatorySpace admin
16
+ Decidim::ParticipatorySpaceRoleConfig::ParticipatorySpaceAdmin.new(user)
17
+ when :department_admin
18
+ Decidim::ParticipatorySpaceRoleConfig::DepartmentAdmin.new(user)
19
+ when :valuator
20
+ Decidim::ParticipatorySpaceRoleConfig::Valuator.new(user)
21
+ when :moderator
22
+ Decidim::ParticipatorySpaceRoleConfig::Moderator.new(user)
23
+ when :collaborator
24
+ Decidim::ParticipatorySpaceRoleConfig::Collaborator.new(user)
25
+ else
26
+ Decidim::ParticipatorySpaceRoleConfig::NullObject.new(user)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ Lib::Decidim::ParticipatorySpaceResourceableDecorator.decorate
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # NOTE: This module is being override to take into account when a user is a department_admin.
4
+
5
+ module Decidim
6
+ module Admin
7
+ module UserRolesHelper
8
+ # rubocop: disable Rails/HelperInstanceVariable
9
+ def user_role_config
10
+ return @user_role_config if @user_role_config
11
+
12
+ space = current_participatory_space
13
+ @user_role_config = if current_user.admin?
14
+ space.user_role_config_for(current_user, :organization_admin)
15
+ elsif current_user.department_admin?
16
+ space.user_role_config_for(current_user, :department_admin)
17
+ else
18
+ role = space.user_roles.find_by(user: current_user)
19
+ space.user_role_config_for(current_user, role&.role)
20
+ end
21
+ end
22
+ # rubocop: enable Rails/HelperInstanceVariable
23
+ end
24
+ end
25
+ end