decidim-department_admin 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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