decidim-admin 0.23.6 → 0.24.0.rc1

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 (177) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/config/decidim_admin_manifest.js +1 -0
  3. data/app/assets/javascripts/decidim/admin/application.js.es6 +2 -0
  4. data/app/assets/javascripts/decidim/admin/budget_rule_toggler.component.js.es6 +23 -20
  5. data/app/assets/javascripts/decidim/admin/bundle.js +10 -17
  6. data/app/assets/javascripts/decidim/admin/bundle.js.map +1 -1
  7. data/app/assets/javascripts/decidim/admin/form.js.es6 +1 -0
  8. data/app/assets/javascripts/decidim/admin/import_guidance.js.es6 +29 -0
  9. data/app/assets/javascripts/decidim/admin/moderations.js.es6 +24 -0
  10. data/app/assets/javascripts/decidim/admin/proposal_infinite_edit.js.es6 +20 -0
  11. data/app/assets/javascripts/decidim/admin/user_moderations.js +2 -0
  12. data/app/assets/stylesheets/decidim/admin/_variables.scss +9 -0
  13. data/app/assets/stylesheets/decidim/admin/components/_dropdown-menu.scss +3 -0
  14. data/app/assets/stylesheets/decidim/admin/extra/_action-icon.scss +13 -0
  15. data/app/assets/stylesheets/decidim/admin/extra/_block_user.scss +5 -0
  16. data/app/assets/stylesheets/decidim/admin/extra/_title_bar.scss +1 -0
  17. data/app/assets/stylesheets/decidim/admin/modules/_moderations.scss +39 -0
  18. data/app/assets/stylesheets/decidim/admin/modules/_modules.scss +2 -0
  19. data/app/assets/stylesheets/decidim/admin/modules/_reveal.scss +5 -0
  20. data/app/assets/stylesheets/decidim/admin/modules/_secondary-nav.scss +6 -3
  21. data/app/assets/stylesheets/decidim/admin/modules/_user-login.scss +2 -2
  22. data/app/assets/stylesheets/decidim/admin/user_moderations.scss +3 -0
  23. data/app/assets/stylesheets/decidim/admin/utils/_settings.scss +1 -0
  24. data/app/cells/decidim/admin/content_block/show.erb +1 -1
  25. data/app/cells/decidim/admin/content_block_cell.rb +4 -0
  26. data/app/commands/decidim/admin/block_user.rb +70 -0
  27. data/app/commands/decidim/admin/create_import.rb +29 -0
  28. data/app/commands/decidim/admin/create_participatory_space_private_user.rb +1 -1
  29. data/app/commands/decidim/admin/create_static_page.rb +2 -1
  30. data/app/commands/decidim/admin/hide_resource.rb +21 -0
  31. data/app/commands/decidim/admin/impersonate_user.rb +17 -1
  32. data/app/commands/decidim/admin/promote_managed_user.rb +10 -0
  33. data/app/commands/decidim/admin/reorder_content_blocks.rb +6 -3
  34. data/app/commands/decidim/admin/transfer_user.rb +78 -0
  35. data/app/commands/decidim/admin/unblock_user.rb +48 -0
  36. data/app/commands/decidim/admin/unreport_user.rb +46 -0
  37. data/app/commands/decidim/admin/update_organization_appearance.rb +12 -4
  38. data/app/commands/decidim/admin/update_static_page.rb +2 -1
  39. data/app/commands/decidim/admin/verify_user_group.rb +1 -1
  40. data/app/controllers/concerns/decidim/admin/filterable.rb +1 -1
  41. data/app/controllers/concerns/decidim/admin/global_moderation_context.rb +51 -0
  42. data/app/controllers/concerns/decidim/admin/landing_page.rb +105 -0
  43. data/app/controllers/concerns/decidim/admin/landing_page_content_blocks.rb +118 -0
  44. data/app/controllers/concerns/decidim/moderations/admin/filterable.rb +54 -0
  45. data/app/controllers/decidim/admin/block_user_controller.rb +60 -0
  46. data/app/controllers/decidim/admin/components/base_controller.rb +1 -0
  47. data/app/controllers/decidim/admin/conflicts_controller.rb +46 -0
  48. data/app/controllers/decidim/admin/exports_controller.rb +1 -2
  49. data/app/controllers/decidim/admin/global_moderations/reports_controller.rb +18 -0
  50. data/app/controllers/decidim/admin/global_moderations_controller.rb +32 -0
  51. data/app/controllers/decidim/admin/impersonations_controller.rb +1 -1
  52. data/app/controllers/decidim/admin/imports_controller.rb +52 -0
  53. data/app/controllers/decidim/admin/moderated_users_controller.rb +44 -0
  54. data/app/controllers/decidim/admin/moderations/reports_controller.rb +39 -0
  55. data/app/controllers/decidim/admin/moderations_controller.rb +31 -7
  56. data/app/controllers/decidim/admin/officializations_controller.rb +3 -3
  57. data/app/controllers/decidim/admin/organization_homepage_controller.rb +6 -2
  58. data/app/controllers/decidim/admin/static_pages_controller.rb +7 -0
  59. data/app/events/decidim/resource_hidden_event.rb +37 -0
  60. data/app/forms/decidim/admin/block_user_form.rb +25 -0
  61. data/app/forms/decidim/admin/import_form.rb +85 -0
  62. data/app/forms/decidim/admin/organization_appearance_form.rb +1 -2
  63. data/app/forms/decidim/admin/static_page_form.rb +6 -1
  64. data/app/forms/decidim/admin/transfer_user_form.rb +19 -0
  65. data/app/helpers/decidim/admin/application_helper.rb +5 -4
  66. data/app/helpers/decidim/admin/exports_helper.rb +2 -2
  67. data/app/helpers/decidim/admin/filterable_helper.rb +3 -2
  68. data/app/helpers/decidim/admin/imports_helper.rb +43 -0
  69. data/app/helpers/decidim/admin/menu_helper.rb +10 -0
  70. data/app/helpers/decidim/admin/moderations/reports_helper.rb +40 -0
  71. data/app/helpers/decidim/admin/moderations_helper.rb +36 -0
  72. data/app/helpers/decidim/admin/newsletters_helper.rb +4 -10
  73. data/app/helpers/decidim/admin/settings_helper.rb +2 -1
  74. data/app/helpers/decidim/admin/sidebar_menu_helper.rb +13 -0
  75. data/app/helpers/decidim/admin/user_moderations_helper.rb +6 -0
  76. data/app/jobs/decidim/admin/import_participatory_space_private_user_csv_job.rb +1 -1
  77. data/app/jobs/decidim/admin/verify_user_group_from_csv_job.rb +1 -1
  78. data/app/permissions/decidim/admin/permissions.rb +7 -6
  79. data/app/presenters/decidim/admin/dashboard_metric_charts_presenter.rb +1 -1
  80. data/app/presenters/decidim/admin/secondary_menu_presenter.rb +26 -0
  81. data/app/queries/decidim/admin/active_users_counter.rb +1 -2
  82. data/app/queries/decidim/admin/user_filter.rb +1 -2
  83. data/app/views/decidim/admin/area_types/index.html.erb +2 -2
  84. data/app/views/decidim/admin/areas/index.html.erb +1 -1
  85. data/app/views/decidim/admin/attachment_collections/index.html.erb +1 -1
  86. data/app/views/decidim/admin/attachments/index.html.erb +1 -1
  87. data/app/views/decidim/admin/block_user/new.html.erb +22 -0
  88. data/app/views/decidim/admin/categories/index.html.erb +1 -1
  89. data/app/views/decidim/admin/components/_component.html.erb +12 -0
  90. data/app/views/decidim/admin/components/_form.html.erb +1 -1
  91. data/app/views/decidim/admin/conflicts/edit.html.erb +46 -0
  92. data/app/views/decidim/admin/conflicts/index.html.erb +34 -0
  93. data/app/views/decidim/admin/dashboard/show.html.erb +1 -0
  94. data/app/views/decidim/admin/exports/_dropdown.html.erb +1 -1
  95. data/app/views/decidim/admin/imports/_dropdown.html.erb +9 -0
  96. data/app/views/decidim/admin/imports/new.html.erb +57 -0
  97. data/app/views/decidim/admin/moderated_users/_report.html.erb +10 -0
  98. data/app/views/decidim/admin/moderated_users/index.html.erb +78 -0
  99. data/app/views/decidim/admin/moderations/_report.html.erb +1 -1
  100. data/app/views/decidim/admin/moderations/index.html.erb +27 -9
  101. data/app/views/decidim/admin/moderations/reports/index.html.erb +102 -0
  102. data/app/views/decidim/admin/moderations/reports/show.html.erb +62 -0
  103. data/app/views/decidim/admin/newsletters/index.html.erb +1 -1
  104. data/app/views/decidim/admin/newsletters/select_recipients_to_deliver.html.erb +3 -3
  105. data/app/views/decidim/admin/newsletters/show.html.erb +1 -1
  106. data/app/views/decidim/admin/officializations/index.html.erb +13 -4
  107. data/app/views/decidim/admin/organization_appearance/_form.html.erb +0 -4
  108. data/app/views/decidim/admin/organization_appearance/form/_colors.html.erb +1 -1
  109. data/app/views/decidim/admin/organization_appearance/form/_images.html.erb +4 -4
  110. data/app/views/decidim/admin/participatory_space_private_users/index.html.erb +1 -1
  111. data/app/views/decidim/admin/scopes/index.html.erb +1 -1
  112. data/app/views/decidim/admin/shared/landing_page/edit.html.erb +47 -0
  113. data/app/views/decidim/admin/shared/landing_page_content_blocks/edit.html.erb +15 -0
  114. data/app/views/decidim/admin/static_pages/_form.html.erb +6 -0
  115. data/app/views/decidim/admin/static_pages/_topic.html.erb +3 -3
  116. data/app/views/decidim/admin/users/index.html.erb +2 -2
  117. data/app/views/layouts/decidim/admin/_application.html.erb +5 -1
  118. data/app/views/layouts/decidim/admin/_title_bar.html.erb +2 -2
  119. data/app/views/layouts/decidim/admin/global_moderations.html.erb +7 -0
  120. data/app/views/layouts/decidim/admin/newsletters.erb +1 -1
  121. data/app/views/layouts/decidim/admin/pages.html.erb +2 -2
  122. data/app/views/layouts/decidim/admin/settings.html.erb +2 -33
  123. data/app/views/layouts/decidim/admin/users.html.erb +11 -0
  124. data/config/locales/ar.yml +0 -5
  125. data/config/locales/bg.yml +0 -1
  126. data/config/locales/ca.yml +33 -7
  127. data/config/locales/cs.yml +154 -9
  128. data/config/locales/de.yml +150 -5
  129. data/config/locales/el.yml +55 -5
  130. data/config/locales/en.yml +150 -5
  131. data/config/locales/es-MX.yml +42 -7
  132. data/config/locales/es-PY.yml +42 -7
  133. data/config/locales/es.yml +42 -7
  134. data/config/locales/eu.yml +0 -3
  135. data/config/locales/fi-plain.yml +148 -3
  136. data/config/locales/fi.yml +148 -3
  137. data/config/locales/fr-CA.yml +139 -4
  138. data/config/locales/fr.yml +139 -4
  139. data/config/locales/gl.yml +83 -12
  140. data/config/locales/hu.yml +13 -5
  141. data/config/locales/id-ID.yml +0 -3
  142. data/config/locales/is-IS.yml +19 -3
  143. data/config/locales/it.yml +59 -5
  144. data/config/locales/ja.yml +38 -5
  145. data/config/locales/lv.yml +0 -5
  146. data/config/locales/nl.yml +110 -4
  147. data/config/locales/no.yml +13 -7
  148. data/config/locales/pl.yml +159 -14
  149. data/config/locales/pt-BR.yml +0 -3
  150. data/config/locales/pt.yml +0 -5
  151. data/config/locales/ro-RO.yml +121 -133
  152. data/config/locales/ru.yml +0 -3
  153. data/config/locales/sk.yml +0 -5
  154. data/config/locales/sl.yml +0 -1
  155. data/config/locales/sr-CS.yml +0 -3
  156. data/config/locales/sv.yml +51 -5
  157. data/config/locales/tr-TR.yml +81 -4
  158. data/config/locales/uk.yml +0 -3
  159. data/config/locales/zh-CN.yml +0 -5
  160. data/config/routes.rb +21 -1
  161. data/lib/decidim/admin/engine.rb +76 -1
  162. data/lib/decidim/admin/import/creator.rb +82 -0
  163. data/lib/decidim/admin/import/importer.rb +82 -0
  164. data/lib/decidim/admin/import/importer_factory.rb +17 -0
  165. data/lib/decidim/admin/import/readers/base.rb +31 -0
  166. data/lib/decidim/admin/import/readers/csv.rb +23 -0
  167. data/lib/decidim/admin/import/readers/json.rb +25 -0
  168. data/lib/decidim/admin/import/readers/xls.rb +25 -0
  169. data/lib/decidim/admin/import/readers.rb +39 -0
  170. data/lib/decidim/admin/import.rb +12 -0
  171. data/lib/decidim/admin/test/commands/create_attachment_collection_examples.rb +6 -6
  172. data/lib/decidim/admin/test/commands/create_category_examples.rb +6 -6
  173. data/lib/decidim/admin/test/filterable_examples.rb +1 -8
  174. data/lib/decidim/admin/test/manage_moderations_examples.rb +49 -4
  175. data/lib/decidim/admin/version.rb +1 -1
  176. data/lib/decidim/admin.rb +6 -0
  177. metadata +72 -16
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ # This controller allows admins to import resources from a file.
6
+ class ImportsController < Decidim::Admin::ApplicationController
7
+ include Decidim::ComponentPathHelper
8
+
9
+ def new
10
+ enforce_permission_to :import, :component_data, component: current_component
11
+ @form = form(Admin::ImportForm).from_params(
12
+ {
13
+ # We need to set "default" creator because form-class doesn't have context / current_component
14
+ # when it sets it's default values.
15
+ creator: current_component.manifest.import_manifests.first.creator
16
+ },
17
+ current_component: current_component
18
+ )
19
+ end
20
+
21
+ def create
22
+ enforce_permission_to :import, :component_data, component: current_component
23
+
24
+ @form = form(Admin::ImportForm).from_params(
25
+ params,
26
+ current_component: current_component,
27
+ current_organization: current_organization
28
+ )
29
+
30
+ CreateImport.call(@form) do
31
+ on(:ok) do |imported_data|
32
+ flash[:notice] = t("decidim.admin.imports.notice",
33
+ number: imported_data.length,
34
+ resource_name: imported_data.first.resource_manifest.name.pluralize)
35
+ redirect_to manage_component_path(current_component)
36
+ end
37
+
38
+ on(:invalid) do
39
+ flash.now[:alert] = t("decidim.admin.imports.error")
40
+ render :new
41
+ end
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def current_component
48
+ @current_component ||= current_participatory_space.components.find(params[:component_id])
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ class ModeratedUsersController < Decidim::Admin::ApplicationController
6
+ include Decidim::Moderations::Admin::Filterable
7
+
8
+ layout "decidim/admin/users"
9
+
10
+ def index
11
+ enforce_permission_to :read, :moderate_users
12
+
13
+ @moderated_users = filtered_collection.page(params[:page]).per(15)
14
+ end
15
+
16
+ def ignore
17
+ enforce_permission_to :unreport, :moderate_users
18
+
19
+ Admin::UnreportUser.call(reportable, current_user) do
20
+ on(:ok) do
21
+ flash[:notice] = I18n.t("reportable.unreport.success", scope: "decidim.moderations.admin")
22
+ redirect_to moderated_users_path
23
+ end
24
+
25
+ on(:invalid) do
26
+ flash.now[:alert] = I18n.t("reportable.unreport.invalid", scope: "decidim.moderations.admin")
27
+ redirect_to moderated_users_path
28
+ end
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def reportable
35
+ @reportable ||= UserModeration.find(params[:id]).user
36
+ end
37
+
38
+ def collection
39
+ target_scope = params[:blocked] && params[:blocked] == "true" ? :blocked : :unblocked
40
+ UserModeration.send(target_scope)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ module Moderations
6
+ # This controller allows admins to manage reports in a moderation.
7
+ class ReportsController < Decidim::Admin::ApplicationController
8
+ helper_method :moderation, :reports, :permission_resource
9
+
10
+ def index
11
+ enforce_permission_to :read, permission_resource
12
+ end
13
+
14
+ def show
15
+ enforce_permission_to :read, permission_resource
16
+ @report = reports.find(params[:id])
17
+ end
18
+
19
+ private
20
+
21
+ def reports
22
+ @reports ||= moderation.reports
23
+ end
24
+
25
+ def moderation
26
+ @moderation ||= participatory_space_moderations.find(params[:moderation_id])
27
+ end
28
+
29
+ def participatory_space_moderations
30
+ @participatory_space_moderations ||= Decidim::Moderation.where(participatory_space: current_participatory_space)
31
+ end
32
+
33
+ def permission_resource
34
+ :moderation
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -4,14 +4,21 @@ module Decidim
4
4
  module Admin
5
5
  # This controller allows admins to manage moderations in a participatory process.
6
6
  class ModerationsController < Decidim::Admin::ApplicationController
7
- helper_method :moderations, :allowed_to?
7
+ include Decidim::Moderations::Admin::Filterable
8
+
9
+ helper_method :moderations, :allowed_to?, :query, :permission_resource
8
10
 
9
11
  def index
10
- enforce_permission_to :read, :moderation
12
+ enforce_permission_to :read, permission_resource
13
+ end
14
+
15
+ def show
16
+ enforce_permission_to :read, permission_resource
17
+ @moderation = collection.find(params[:id])
11
18
  end
12
19
 
13
20
  def unreport
14
- enforce_permission_to :unreport, :moderation
21
+ enforce_permission_to :unreport, permission_resource
15
22
 
16
23
  Admin::UnreportResource.call(reportable, current_user) do
17
24
  on(:ok) do
@@ -27,7 +34,7 @@ module Decidim
27
34
  end
28
35
 
29
36
  def hide
30
- enforce_permission_to :hide, :moderation
37
+ enforce_permission_to :hide, permission_resource
31
38
 
32
39
  Admin::HideResource.call(reportable, current_user) do
33
40
  on(:ok) do
@@ -43,7 +50,7 @@ module Decidim
43
50
  end
44
51
 
45
52
  def unhide
46
- enforce_permission_to :unhide, :moderation
53
+ enforce_permission_to :unhide, permission_resource
47
54
 
48
55
  Admin::UnhideResource.call(reportable, current_user) do
49
56
  on(:ok) do
@@ -60,8 +67,10 @@ module Decidim
60
67
 
61
68
  private
62
69
 
63
- def moderations
64
- @moderations ||= begin
70
+ # Private: This method is used by the `Filterable` concern as the base query
71
+ # without applying filtering and/or sorting options.
72
+ def collection
73
+ @collection ||= begin
65
74
  if params[:hidden]
66
75
  participatory_space_moderations.where.not(hidden_at: nil)
67
76
  else
@@ -70,6 +79,13 @@ module Decidim
70
79
  end
71
80
  end
72
81
 
82
+ # Private: Returns a collection of `Moderation` filtered and/or sorted by
83
+ # some criteria. The `filtered_collection` is provided by the
84
+ # `Filterable` concern.
85
+ def moderations
86
+ @moderations ||= filtered_collection
87
+ end
88
+
73
89
  def reportable
74
90
  @reportable ||= participatory_space_moderations.find(params[:id]).reportable
75
91
  end
@@ -77,6 +93,14 @@ module Decidim
77
93
  def participatory_space_moderations
78
94
  @participatory_space_moderations ||= Decidim::Moderation.where(participatory_space: current_participatory_space)
79
95
  end
96
+
97
+ # Private: Defines the resource that permissions will check. This is
98
+ # added so that the `GlobalModerationController` can overwrite this method
99
+ # and define the custom permission resource, so that the permission system
100
+ # is not overridden.
101
+ def permission_resource
102
+ :moderation
103
+ end
80
104
  end
81
105
  end
82
106
  end
@@ -32,7 +32,7 @@ module Decidim
32
32
  on(:ok) do |user|
33
33
  notice = I18n.t("officializations.create.success", scope: "decidim.admin")
34
34
 
35
- redirect_to officializations_path(q: user.name), notice: notice
35
+ redirect_to officializations_path(q: { name_or_nickname_or_email_cont: user.name }), notice: notice
36
36
  end
37
37
  end
38
38
  end
@@ -44,7 +44,7 @@ module Decidim
44
44
  on(:ok) do
45
45
  notice = I18n.t("officializations.destroy.success", scope: "decidim.admin")
46
46
 
47
- redirect_to officializations_path(q: user.name), notice: notice
47
+ redirect_to officializations_path(q: { name_or_nickname_or_email_cont: user.name }), notice: notice
48
48
  end
49
49
  end
50
50
  end
@@ -60,7 +60,7 @@ module Decidim
60
60
  private
61
61
 
62
62
  def collection
63
- @collection ||= current_organization.users.not_deleted
63
+ @collection ||= current_organization.users.not_deleted.left_outer_joins(:user_moderation)
64
64
  end
65
65
 
66
66
  def user
@@ -31,11 +31,15 @@ module Decidim
31
31
  end
32
32
 
33
33
  def active_blocks
34
- @active_blocks ||= content_blocks.published
34
+ @active_blocks ||= content_blocks.published.where(manifest_name: Decidim.content_blocks.for(:homepage).map(&:name))
35
+ end
36
+
37
+ def unpublished_blocks
38
+ @unpublished_blocks ||= content_blocks.unpublished.where(manifest_name: Decidim.content_blocks.for(:homepage).map(&:name))
35
39
  end
36
40
 
37
41
  def inactive_blocks
38
- @inactive_blocks ||= content_blocks.unpublished + unused_manifests
42
+ @inactive_blocks ||= unpublished_blocks + unused_manifests
39
43
  end
40
44
 
41
45
  def used_manifests
@@ -82,6 +82,13 @@ module Decidim
82
82
  form_params = params.to_unsafe_hash
83
83
  form_params["static_page"] ||= {}
84
84
  form_params["static_page"]["organization"] = current_organization
85
+ form_params["static_page"]["allow_public_access"] ||= begin
86
+ if page
87
+ page.allow_public_access
88
+ else
89
+ false
90
+ end
91
+ end
85
92
 
86
93
  return form_params unless page
87
94
 
@@ -0,0 +1,37 @@
1
+ # frozen-string_literal: true
2
+
3
+ module Decidim
4
+ class ResourceHiddenEvent < Decidim::Events::SimpleEvent
5
+ i18n_attributes :resource_path, :report_reasons, :resource_type, :resource_content
6
+
7
+ def resource_path
8
+ @resource.reported_content_url
9
+ end
10
+
11
+ def resource_url
12
+ @resource.reported_content_url
13
+ end
14
+
15
+ def report_reasons
16
+ extra["report_reasons"].map do |reason|
17
+ I18n.t("decidim.admin.moderations.report.reasons.#{reason}").downcase
18
+ end.join(", ")
19
+ end
20
+
21
+ def resource_title
22
+ nil
23
+ end
24
+
25
+ def resource_content
26
+ translated_attribute(@resource[@resource.reported_attributes.first]).truncate(100, separator: " ")
27
+ end
28
+
29
+ def resource_text
30
+ "<i>#{resource_content}</i>"
31
+ end
32
+
33
+ def resource_type
34
+ @resource.model_name.human.downcase
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ # A form object used to officialize users from the admin dashboard.
6
+ class BlockUserForm < Form
7
+ attribute :user_id, Integer
8
+ attribute :justification, String
9
+
10
+ validates :user, presence: true
11
+ validates :justification, presence: true, length: { minimum: UserBlock::MINIMUM_JUSTIFICATION_LENGTH }
12
+
13
+ def map_model(user)
14
+ self.user_id = user.id
15
+ end
16
+
17
+ def user
18
+ @user ||= Decidim::User.find_by(
19
+ id: user_id,
20
+ organization: current_organization
21
+ )
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ class ImportForm < Form
6
+ ACCEPTED_MIME_TYPES = Decidim::Admin::Import::Readers::ACCEPTED_MIME_TYPES
7
+
8
+ attribute :creator, String, default: ->(form, _attribute) { form.creators.first[:creator].to_s }
9
+ attribute :file
10
+ attribute :user_group_id, Integer
11
+
12
+ validates :file, presence: true
13
+ validates :creator, presence: true
14
+ validate :accepted_mime_type
15
+ validate :check_invalid_lines
16
+
17
+ def check_invalid_lines
18
+ return if file.blank? || !accepted_mime_type
19
+
20
+ importer.prepare
21
+ invalid_lines = importer.invalid_lines
22
+ errors.add(:file, I18n.t("decidim.admin.imports.invalid_lines", invalid_lines: invalid_lines.join(","))) unless invalid_lines.empty?
23
+ end
24
+
25
+ def file_path
26
+ file&.path
27
+ end
28
+
29
+ def mime_type
30
+ file&.content_type
31
+ end
32
+
33
+ def accepted_mime_type
34
+ accepted_mime_types = ACCEPTED_MIME_TYPES.values
35
+ return true if accepted_mime_types.include?(mime_type)
36
+ # Avoid duplicating error messages
37
+ return false if errors[:file].present?
38
+
39
+ errors.add(
40
+ :file,
41
+ I18n.t(
42
+ "activemodel.errors.new_import.attributes.file.invalid_mime_type",
43
+ valid_mime_types: ACCEPTED_MIME_TYPES.keys.map do |m|
44
+ I18n.t("decidim.admin.new_import.accepted_mime_types.#{m}")
45
+ end.join(", ")
46
+ )
47
+ )
48
+ false
49
+ end
50
+
51
+ def creators
52
+ @creators ||= current_component.manifest.import_manifests.map do |manifest|
53
+ { creator: manifest.creator, name: manifest.creator.to_s.split("::").last.downcase }
54
+ end
55
+ end
56
+
57
+ def creator_class
58
+ return creator.constantize if creator.is_a?(String)
59
+
60
+ creator
61
+ end
62
+
63
+ def user_group
64
+ @user_group ||= Decidim::UserGroup.find_by(
65
+ organization: current_organization,
66
+ id: user_group_id.to_i
67
+ )
68
+ end
69
+
70
+ def importer
71
+ @importer ||= importer_for(file_path, mime_type)
72
+ end
73
+
74
+ def importer_for(filepath, mime_type)
75
+ context[:user_group] = user_group
76
+ Import::ImporterFactory.build(
77
+ filepath,
78
+ mime_type,
79
+ context: context,
80
+ creator: creator_class
81
+ )
82
+ end
83
+ end
84
+ end
85
+ end
@@ -20,7 +20,6 @@ module Decidim
20
20
  attribute :official_img_footer
21
21
  attribute :remove_official_img_footer
22
22
  attribute :official_url
23
- attribute :show_statistics, Boolean
24
23
  attribute :header_snippets, String
25
24
  attribute :cta_button_path, String
26
25
  attribute :highlighted_content_banner_enabled, Boolean, default: false
@@ -47,7 +46,7 @@ module Decidim
47
46
  translatable_attribute :omnipresent_banner_title, String
48
47
  translatable_attribute :omnipresent_banner_short_description, String
49
48
 
50
- validates :cta_button_path, format: { with: %r{\A[a-zA-Z]+[a-zA-Z0-9\-\_/]+\z} }, allow_blank: true
49
+ validates :cta_button_path, format: { with: %r{\A[a-zA-Z]+[a-zA-Z0-9\-_/]+\z} }, allow_blank: true
51
50
  validates :official_img_header,
52
51
  :official_img_footer,
53
52
  :logo,
@@ -11,6 +11,7 @@ module Decidim
11
11
  translatable_attribute :content, String
12
12
  attribute :changed_notably, Boolean
13
13
  attribute :show_in_footer, Boolean
14
+ attribute :allow_public_access, Boolean
14
15
  attribute :weight, Integer
15
16
  attribute :topic_id, Integer
16
17
 
@@ -18,7 +19,7 @@ module Decidim
18
19
 
19
20
  validates :slug, presence: true
20
21
  validates :title, :content, translatable_presence: true
21
- validates :slug, format: { with: %r{\A[a-zA-Z]+[a-zA-Z0-9\-\_/]+\z} }, allow_blank: true
22
+ validates :slug, format: { with: %r{\A[a-zA-Z]+[a-zA-Z0-9\-_/]+\z} }, allow_blank: true
22
23
 
23
24
  validate :slug, :slug_uniqueness
24
25
 
@@ -41,6 +42,10 @@ module Decidim
41
42
  )
42
43
  end
43
44
 
45
+ def control_public_access?
46
+ current_organization.force_users_to_authenticate_before_access_organization?
47
+ end
48
+
44
49
  private
45
50
 
46
51
  def slug_uniqueness
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ # A form object used to transfer conflicted users from the admin dashboard.
6
+ #
7
+ # This form will contain a dynamic attribute for the user authorization.
8
+ # This authorization will be selected by the admin user if more than one exists.
9
+ class TransferUserForm < Form
10
+ attribute :email, String
11
+ attribute :reason, String
12
+ attribute :current_user, Decidim::User
13
+ attribute :conflict, Decidim::Verifications::Conflict
14
+
15
+ validates :current_user, presence: true
16
+ validates :conflict, presence: true
17
+ end
18
+ end
19
+ end
@@ -15,10 +15,6 @@ module Decidim
15
15
  include Decidim::Admin::UserRolesHelper
16
16
  include Decidim::Admin::ResourceScopeHelper
17
17
 
18
- def title
19
- current_organization.name
20
- end
21
-
22
18
  # Adds a link to the secondary navigation so admins can easily access the public page of the
23
19
  # element their working on.
24
20
  #
@@ -32,6 +28,11 @@ module Decidim
32
28
  end
33
29
  end
34
30
  end
31
+
32
+ def participatory_space_active_link?(component)
33
+ endpoints = component.manifest.admin_engine.try(:participatory_space_endpoints)
34
+ endpoints && is_active_link?(decidim_admin_participatory_processes.components_path(current_participatory_space), %r{/\d+/manage/(#{endpoints.join("|")})\b})
35
+ end
35
36
  end
36
37
  end
37
38
  end
@@ -10,8 +10,8 @@ module Decidim
10
10
  # current component.
11
11
  #
12
12
  # Returns a rendered dropdown.
13
- def export_dropdown(component = current_component)
14
- render partial: "decidim/admin/exports/dropdown", locals: { component: component }
13
+ def export_dropdown(component = current_component, resource_id = nil)
14
+ render partial: "decidim/admin/exports/dropdown", locals: { component: component, resource_id: resource_id }
15
15
  end
16
16
 
17
17
  # Routes to the correct exporter for a component.
@@ -15,9 +15,10 @@ module Decidim
15
15
 
16
16
  filters_with_values.each_with_object({}) do |(filter, values), hash|
17
17
  link = filter_link_label(filter, i18n_scope)
18
- hash[link] = if values.is_a?(Array)
18
+ hash[link] = case values
19
+ when Array
19
20
  build_submenu_options_tree_from_array(filter, values, i18n_scope)
20
- elsif values.is_a?(Hash)
21
+ when Hash
21
22
  build_submenu_options_tree_from_hash(filter, values, i18n_scope)
22
23
  end
23
24
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ module ImportsHelper
6
+ # Renders an import dropdown for the provided component. Additional dropdown items
7
+ # can be given as block.
8
+ #
9
+ # component - The component to render the export dropdown for. Defaults to the
10
+ # current component.
11
+ #
12
+ # resource_id - The resource id that is passed to route.
13
+ #
14
+ # Returns a rendered dropdown.
15
+ def import_dropdown(component = current_component, resource_id = nil)
16
+ locals = { component: component, resource_id: resource_id }
17
+ locals[:block] = yield if block_given?
18
+ render partial: "decidim/admin/imports/dropdown", locals: locals
19
+ end
20
+
21
+ # Routes to the correct importer for a component.
22
+ #
23
+ # component - The component to be routed.
24
+ # options - Extra options that need to be passed to the route.
25
+ #
26
+ # Returns the path to the component importer.
27
+ def admin_imports_path(component, options)
28
+ EngineRouter.admin_proxy(component.participatory_space).new_component_import_path(options.merge(component_id: component))
29
+ end
30
+
31
+ # Public: A formatted collection of mime_type to be used in forms.
32
+ def mime_types
33
+ accepted_mime_types = Decidim::Admin::Import::Readers::ACCEPTED_MIME_TYPES.keys
34
+ accepted_mime_types.map { |mime_type| t("decidim.admin.imports.new.accepted_mime_types.#{mime_type}") }.join(", ")
35
+ end
36
+
37
+ # Returns verified user groups of current user
38
+ def user_groups
39
+ Decidim::UserGroups::ManageableUserGroups.for(current_user).verified
40
+ end
41
+ end
42
+ end
43
+ end
@@ -4,6 +4,8 @@ module Decidim
4
4
  module Admin
5
5
  # This module includes helpers to manage menus in admin layout
6
6
  module MenuHelper
7
+ include Decidim::Admin::SidebarMenuHelper
8
+
7
9
  # Public: Returns the main menu presenter object
8
10
  def main_menu
9
11
  @main_menu ||= ::Decidim::MenuPresenter.new(
@@ -12,6 +14,14 @@ module Decidim
12
14
  active_class: "is-active"
13
15
  )
14
16
  end
17
+
18
+ def global_moderation_menu
19
+ @global_moderation_menu ||= sidebar_menu(:admin_global_moderation_menu)
20
+ end
21
+
22
+ def organization_settings_menu
23
+ @organization_settings_menu ||= sidebar_menu(:admin_settings_menu)
24
+ end
15
25
  end
16
26
  end
17
27
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ module Moderations
6
+ # This module includes helpers to show moderation reports in admin
7
+ module ReportsHelper
8
+ include Decidim::Messaging::ConversationHelper
9
+
10
+ # Public: Returns the reportable's author names separated by commas.
11
+ def reportable_author_name(reportable)
12
+ reportable_authors = reportable.try(:authors) || [reportable.try(:normalized_author)]
13
+ content_tag :ul, class: "reportable-authors" do
14
+ reportable_authors.select(&:present?).map do |author|
15
+ if author.is_a? User
16
+ content_tag :li do
17
+ link_to current_or_new_conversation_path_with(author), target: "_blank", rel: "noopener" do
18
+ "#{author.name} #{icon "envelope-closed"}".html_safe
19
+ end
20
+ end
21
+ else
22
+ content_tag(:li, author.name)
23
+ end
24
+ end.join("").html_safe
25
+ end
26
+ end
27
+
28
+ # Public: Renders a small preview of the content reported.
29
+ def reported_content_for(reportable, options = {})
30
+ cell "decidim/reported_content", reportable, options
31
+ end
32
+
33
+ # Public: Whether the resource has some translated attribute or not.
34
+ def translatable_resource?(reportable)
35
+ reportable.respond_to?(:content_original_language)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end