decidim-admin 0.29.1 → 0.30.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (249) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/admin/multi_select_picker/show.erb +10 -0
  3. data/app/cells/decidim/admin/multi_select_picker_cell.rb +38 -0
  4. data/app/commands/decidim/admin/block_user.rb +1 -0
  5. data/app/commands/decidim/admin/bulk_action.rb +92 -0
  6. data/app/commands/decidim/admin/bulk_block_users.rb +75 -0
  7. data/app/commands/decidim/admin/bulk_unblock_users.rb +66 -0
  8. data/app/commands/decidim/admin/bulk_unreport_users.rb +69 -0
  9. data/app/commands/decidim/admin/content_blocks/update_content_block.rb +1 -1
  10. data/app/commands/decidim/admin/create_participatory_space_private_user.rb +3 -1
  11. data/app/commands/decidim/admin/create_share_token.rb +39 -0
  12. data/app/commands/decidim/admin/create_taxonomy.rb +23 -0
  13. data/app/commands/decidim/admin/create_taxonomy_filter.rb +24 -0
  14. data/app/commands/decidim/admin/destroy_share_token.rb +22 -0
  15. data/app/commands/decidim/admin/destroy_taxonomy.rb +18 -0
  16. data/app/commands/decidim/admin/destroy_taxonomy_filter.rb +20 -0
  17. data/app/commands/decidim/admin/hide_menu_component.rb +37 -0
  18. data/app/commands/decidim/admin/hide_resource.rb +4 -2
  19. data/app/commands/decidim/admin/publish_all_participatory_space_private_users.rb +50 -0
  20. data/app/commands/decidim/admin/publish_component.rb +3 -0
  21. data/app/commands/decidim/admin/reorder_components.rb +47 -0
  22. data/app/commands/decidim/admin/reorder_taxonomies.rb +76 -0
  23. data/app/commands/decidim/admin/unhide_resource.rb +11 -3
  24. data/app/commands/decidim/admin/unpublish_all_participatory_space_private_users.rb +50 -0
  25. data/app/commands/decidim/admin/unreport_resource.rb +11 -3
  26. data/app/commands/decidim/admin/update_component_permissions.rb +53 -13
  27. data/app/commands/decidim/admin/update_participatory_space_private_user.rb +11 -0
  28. data/app/commands/decidim/admin/update_share_token.rb +24 -0
  29. data/app/commands/decidim/admin/update_taxonomy.rb +20 -0
  30. data/app/commands/decidim/admin/update_taxonomy_filter.rb +28 -0
  31. data/app/controllers/concerns/decidim/admin/component_taxonomies_helper.rb +19 -0
  32. data/app/controllers/concerns/decidim/admin/filterable.rb +15 -18
  33. data/app/controllers/concerns/decidim/admin/has_trashable_resources.rb +170 -0
  34. data/app/controllers/concerns/decidim/admin/needs_admin_tos_accepted.rb +2 -29
  35. data/app/controllers/concerns/decidim/admin/participatory_space_admin_context.rb +12 -2
  36. data/app/controllers/concerns/decidim/admin/taxonomies/filterable.rb +27 -0
  37. data/app/controllers/decidim/admin/application_controller.rb +1 -2
  38. data/app/controllers/decidim/admin/areas_controller.rb +1 -0
  39. data/app/controllers/decidim/admin/block_user_controller.rb +43 -1
  40. data/app/controllers/decidim/admin/component_permissions_controller.rb +2 -4
  41. data/app/controllers/decidim/admin/components_controller.rb +50 -9
  42. data/app/controllers/decidim/admin/concerns/has_private_users.rb +59 -2
  43. data/app/controllers/decidim/admin/conflicts_controller.rb +1 -1
  44. data/app/controllers/decidim/admin/global_moderations_controller.rb +4 -0
  45. data/app/controllers/decidim/admin/impersonations_controller.rb +1 -0
  46. data/app/controllers/decidim/admin/moderated_users_controller.rb +26 -0
  47. data/app/controllers/decidim/admin/moderations_controller.rb +18 -0
  48. data/app/controllers/decidim/admin/newsletters_controller.rb +50 -6
  49. data/app/controllers/decidim/admin/resource_permissions_controller.rb +1 -1
  50. data/app/controllers/decidim/admin/scopes_controller.rb +1 -0
  51. data/app/controllers/decidim/admin/share_tokens_controller.rb +109 -7
  52. data/app/controllers/decidim/admin/taxonomies_controller.rb +129 -0
  53. data/app/controllers/decidim/admin/taxonomy_filters_controller.rb +112 -0
  54. data/app/controllers/decidim/admin/taxonomy_filters_selector_controller.rb +81 -0
  55. data/app/controllers/decidim/admin/taxonomy_items_controller.rb +91 -0
  56. data/app/forms/concerns/decidim/has_taxonomy_form_attributes.rb +57 -0
  57. data/app/forms/decidim/admin/block_users_form.rb +21 -0
  58. data/app/forms/decidim/admin/help_section_form.rb +1 -1
  59. data/app/forms/decidim/admin/impersonate_user_form.rb +5 -0
  60. data/app/forms/decidim/admin/import_example_form.rb +1 -1
  61. data/app/forms/decidim/admin/newsletter_form.rb +1 -1
  62. data/app/forms/decidim/admin/organization_appearance_form.rb +2 -2
  63. data/app/forms/decidim/admin/organization_form.rb +2 -2
  64. data/app/forms/decidim/admin/participatory_space_private_user_form.rb +5 -0
  65. data/app/forms/decidim/admin/selective_newsletter_form.rb +46 -11
  66. data/app/forms/decidim/admin/share_token_form.rb +55 -0
  67. data/app/forms/decidim/admin/static_page_form.rb +1 -1
  68. data/app/forms/decidim/admin/taxonomy_filter_form.rb +85 -0
  69. data/app/forms/decidim/admin/taxonomy_form.rb +20 -0
  70. data/app/forms/decidim/admin/taxonomy_item_form.rb +54 -0
  71. data/app/forms/decidim/admin/transfer_user_form.rb +15 -0
  72. data/app/helpers/decidim/admin/application_helper.rb +0 -1
  73. data/app/helpers/decidim/admin/bulk_actions_helper.rb +0 -31
  74. data/app/helpers/decidim/admin/moderations/reports_helper.rb +1 -1
  75. data/app/helpers/decidim/admin/moderations_helper.rb +1 -1
  76. data/app/helpers/decidim/admin/newsletters_helper.rb +57 -27
  77. data/app/helpers/decidim/admin/scopes_helper.rb +0 -6
  78. data/app/helpers/decidim/admin/search_form_helper.rb +1 -1
  79. data/app/helpers/decidim/admin/settings_helper.rb +85 -11
  80. data/app/jobs/decidim/admin/newsletter_job.rb +3 -1
  81. data/app/packs/entrypoints/decidim_admin.js +4 -0
  82. data/app/packs/src/decidim/admin/application.js +2 -0
  83. data/app/packs/src/decidim/admin/draggable-table.js +33 -0
  84. data/app/packs/src/decidim/admin/form.js +0 -1
  85. data/app/packs/src/decidim/admin/global_moderations.js +186 -0
  86. data/app/packs/src/decidim/admin/managed_moderated_users.js +186 -0
  87. data/app/packs/src/decidim/admin/newsletters.js +164 -73
  88. data/app/packs/src/decidim/admin/proposal_infinite_edit.js +3 -6
  89. data/app/packs/src/decidim/admin/sortable.js +28 -16
  90. data/app/packs/src/decidim/admin/taxonomy_filters.js +93 -0
  91. data/app/packs/stylesheets/decidim/admin/_component-show.scss +66 -5
  92. data/app/packs/stylesheets/decidim/admin/_legacy_foundation.scss +13 -0
  93. data/app/packs/stylesheets/decidim/admin/_moderations.scss +8 -0
  94. data/app/packs/stylesheets/decidim/admin/_select_picker.scss +20 -0
  95. data/app/packs/stylesheets/decidim/admin/_table-list.scss +22 -0
  96. data/app/packs/stylesheets/decidim/admin/_taxonomies.scss +74 -0
  97. data/app/packs/stylesheets/decidim/admin/application.scss +3 -0
  98. data/app/permissions/decidim/admin/permissions.rb +32 -1
  99. data/app/queries/decidim/admin/newsletter_recipients.rb +59 -19
  100. data/app/views/decidim/admin/areas/index.html.erb +3 -0
  101. data/app/views/decidim/admin/block_user/bulk_new.html.erb +45 -0
  102. data/app/views/decidim/admin/components/_actions.html.erb +50 -33
  103. data/app/views/decidim/admin/components/{_component.html.erb → _component_row.html.erb} +10 -5
  104. data/app/views/decidim/admin/components/_components_table.html.erb +18 -0
  105. data/app/views/decidim/admin/components/_form.html.erb +0 -12
  106. data/app/views/decidim/admin/components/_taxonomy_filters_drawer.html.erb +2 -0
  107. data/app/views/decidim/admin/components/_visibility_label.html.erb +9 -0
  108. data/app/views/decidim/admin/components/index.html.erb +12 -14
  109. data/app/views/decidim/admin/components/manage_trash.html.erb +11 -0
  110. data/app/views/decidim/admin/conflicts/edit.html.erb +21 -11
  111. data/app/views/decidim/admin/moderated_users/_bulk-actions.html.erb +6 -0
  112. data/app/views/decidim/admin/moderated_users/bulk_actions/_block.html.erb +20 -0
  113. data/app/views/decidim/admin/moderated_users/bulk_actions/_dropdown.html.erb +40 -0
  114. data/app/views/decidim/admin/moderated_users/bulk_actions/_unblock.html.erb +20 -0
  115. data/app/views/decidim/admin/moderated_users/bulk_actions/_unreport.html.erb +20 -0
  116. data/app/views/decidim/admin/moderated_users/index.html.erb +15 -7
  117. data/app/views/decidim/admin/moderations/_bulk-actions.html.erb +7 -0
  118. data/app/views/decidim/admin/moderations/_moderation-tr.html.erb +50 -0
  119. data/app/views/decidim/admin/moderations/_moderations-thead.html.erb +18 -0
  120. data/app/views/decidim/admin/moderations/bulk_actions/_dropdown.html.erb +43 -0
  121. data/app/views/decidim/admin/moderations/bulk_actions/_hide.html.erb +20 -0
  122. data/app/views/decidim/admin/moderations/bulk_actions/_unhide.html.erb +20 -0
  123. data/app/views/decidim/admin/moderations/bulk_actions/_unreport.html.erb +20 -0
  124. data/app/views/decidim/admin/moderations/index.html.erb +13 -81
  125. data/app/views/decidim/admin/newsletter_templates/index.html.erb +0 -1
  126. data/app/views/decidim/admin/newsletters/confirm_recipients.html.erb +64 -0
  127. data/app/views/decidim/admin/newsletters/select_recipients_to_deliver.html.erb +44 -20
  128. data/app/views/decidim/admin/participatory_space_private_users/_form.html.erb +6 -0
  129. data/app/views/decidim/admin/participatory_space_private_users/edit.html.erb +19 -0
  130. data/app/views/decidim/admin/participatory_space_private_users/index.html.erb +15 -1
  131. data/app/views/decidim/admin/resource_permissions/_options_form.html.erb +5 -0
  132. data/app/views/decidim/admin/resource_permissions/edit.html.erb +2 -2
  133. data/app/views/decidim/admin/scope_types/index.html.erb +3 -0
  134. data/app/views/decidim/admin/scopes/index.html.erb +3 -0
  135. data/app/views/decidim/admin/share_tokens/_form.html.erb +52 -0
  136. data/app/views/decidim/admin/share_tokens/edit.html.erb +33 -0
  137. data/app/views/decidim/admin/share_tokens/index.html.erb +47 -0
  138. data/app/views/decidim/admin/share_tokens/new.html.erb +69 -0
  139. data/app/views/decidim/admin/shared/landing_page_content_blocks/edit.html.erb +1 -1
  140. data/app/views/decidim/admin/taxonomies/_filters.html.erb +19 -0
  141. data/app/views/decidim/admin/taxonomies/_form.html.erb +5 -0
  142. data/app/views/decidim/admin/taxonomies/_row.html.erb +40 -0
  143. data/app/views/decidim/admin/taxonomies/_row_children.html.erb +8 -0
  144. data/app/views/decidim/admin/taxonomies/_table.html.erb +86 -0
  145. data/app/views/decidim/admin/taxonomies/_taxonomy_actions.html.erb +15 -0
  146. data/app/views/decidim/admin/taxonomies/edit.html.erb +87 -0
  147. data/app/views/decidim/admin/taxonomies/index.html.erb +28 -0
  148. data/app/views/decidim/admin/taxonomies/new.html.erb +16 -0
  149. data/app/views/decidim/admin/taxonomy_filters/_check_boxes.html.erb +10 -0
  150. data/app/views/decidim/admin/taxonomy_filters/_form.html.erb +96 -0
  151. data/app/views/decidim/admin/taxonomy_filters/_table.html.erb +33 -0
  152. data/app/views/decidim/admin/taxonomy_filters/edit.html.erb +22 -0
  153. data/app/views/decidim/admin/taxonomy_filters/index.html.erb +26 -0
  154. data/app/views/decidim/admin/taxonomy_filters/new.html.erb +32 -0
  155. data/app/views/decidim/admin/taxonomy_filters_selector/_check_boxes.html.erb +7 -0
  156. data/app/views/decidim/admin/taxonomy_filters_selector/_component_table.html.erb +25 -0
  157. data/app/views/decidim/admin/taxonomy_filters_selector/_taxonomies_select.html.erb +16 -0
  158. data/app/views/decidim/admin/taxonomy_filters_selector/index.html.erb +1 -0
  159. data/app/views/decidim/admin/taxonomy_filters_selector/new.html.erb +27 -0
  160. data/app/views/decidim/admin/taxonomy_filters_selector/show.html.erb +18 -0
  161. data/app/views/decidim/admin/taxonomy_items/_form.html.erb +8 -0
  162. data/app/views/decidim/admin/taxonomy_items/edit.html.erb +12 -0
  163. data/app/views/decidim/admin/taxonomy_items/new.html.erb +12 -0
  164. data/app/views/layouts/decidim/admin/taxonomy_filters.html.erb +17 -0
  165. data/app/views/layouts/decidim/admin/taxonomy_filters_selector.html.erb +10 -0
  166. data/config/locales/ar.yml +91 -36
  167. data/config/locales/bg.yml +48 -51
  168. data/config/locales/bn-BD.yml +1 -0
  169. data/config/locales/bs-BA.yml +499 -0
  170. data/config/locales/ca.yml +300 -50
  171. data/config/locales/cs.yml +298 -46
  172. data/config/locales/de.yml +300 -50
  173. data/config/locales/el.yml +1 -50
  174. data/config/locales/en.yml +300 -50
  175. data/config/locales/es-MX.yml +298 -48
  176. data/config/locales/es-PY.yml +298 -48
  177. data/config/locales/es.yml +298 -48
  178. data/config/locales/eu.yml +433 -171
  179. data/config/locales/fi-plain.yml +298 -48
  180. data/config/locales/fi.yml +315 -65
  181. data/config/locales/fr-CA.yml +183 -47
  182. data/config/locales/fr.yml +183 -47
  183. data/config/locales/ga-IE.yml +0 -23
  184. data/config/locales/gl.yml +1 -46
  185. data/config/locales/hu.yml +1 -51
  186. data/config/locales/id-ID.yml +0 -20
  187. data/config/locales/is-IS.yml +0 -18
  188. data/config/locales/it.yml +1 -46
  189. data/config/locales/ja.yml +303 -55
  190. data/config/locales/kaa.yml +0 -10
  191. data/config/locales/ko.yml +0 -50
  192. data/config/locales/lb.yml +1 -46
  193. data/config/locales/lt.yml +1 -50
  194. data/config/locales/lv.yml +1 -27
  195. data/config/locales/nl.yml +1 -46
  196. data/config/locales/no.yml +1 -46
  197. data/config/locales/pl.yml +3 -51
  198. data/config/locales/pt-BR.yml +38 -50
  199. data/config/locales/pt.yml +30 -46
  200. data/config/locales/ro-RO.yml +35 -50
  201. data/config/locales/ru.yml +1 -22
  202. data/config/locales/sk.yml +1 -27
  203. data/config/locales/sl.yml +0 -7
  204. data/config/locales/sq-AL.yml +0 -25
  205. data/config/locales/sr-CS.yml +1 -27
  206. data/config/locales/sv.yml +297 -47
  207. data/config/locales/tr-TR.yml +1 -44
  208. data/config/locales/uk.yml +0 -20
  209. data/config/locales/zh-CN.yml +0 -44
  210. data/config/locales/zh-TW.yml +1 -50
  211. data/config/routes.rb +14 -13
  212. data/decidim-admin.gemspec +2 -2
  213. data/lib/decidim/admin/engine.rb +3 -1
  214. data/lib/decidim/admin/import/creator.rb +2 -6
  215. data/lib/decidim/admin/import/readers/json.rb +1 -1
  216. data/lib/decidim/admin/menu.rb +9 -1
  217. data/lib/decidim/admin/search_form_builder.rb +1 -1
  218. data/lib/decidim/admin/test/destroy_admin_examples.rb +2 -2
  219. data/lib/decidim/admin/test/filterable_examples.rb +100 -9
  220. data/lib/decidim/admin/test/forms/attachment_collection_form_examples.rb +1 -1
  221. data/lib/decidim/admin/test/forms/attachment_form_examples.rb +1 -1
  222. data/lib/decidim/admin/test/invite_participatory_space_admins_shared_examples.rb +2 -4
  223. data/lib/decidim/admin/test/manage_component_permissions_examples.rb +5 -5
  224. data/lib/decidim/admin/test/manage_hide_content_examples.rb +0 -1
  225. data/lib/decidim/admin/test/manage_moderations_examples.rb +3 -3
  226. data/lib/decidim/admin/test/manage_resource_soft_deletion_examples.rb +113 -0
  227. data/lib/decidim/admin/test/manage_taxonomy_filters_examples.rb +127 -0
  228. data/lib/decidim/admin/test/taxonomy_filters_examples.rb +32 -0
  229. data/lib/decidim/admin/test.rb +3 -1
  230. data/lib/decidim/admin/version.rb +1 -1
  231. metadata +106 -30
  232. data/app/commands/decidim/admin/create_category.rb +0 -15
  233. data/app/commands/decidim/admin/destroy_category.rb +0 -15
  234. data/app/commands/decidim/admin/destroy_component.rb +0 -19
  235. data/app/commands/decidim/admin/update_category.rb +0 -11
  236. data/app/controllers/decidim/admin/categories_controller.rb +0 -98
  237. data/app/forms/decidim/admin/category_form.rb +0 -32
  238. data/app/helpers/decidim/admin/resource_scope_helper.rb +0 -52
  239. data/app/packs/src/decidim/admin/scope_picker_enabler.component.js +0 -12
  240. data/app/views/decidim/admin/categories/_form.html.erb +0 -18
  241. data/app/views/decidim/admin/categories/edit.html.erb +0 -19
  242. data/app/views/decidim/admin/categories/index.html.erb +0 -65
  243. data/app/views/decidim/admin/categories/new.html.erb +0 -19
  244. data/app/views/decidim/admin/share_tokens/_share_tokens.html.erb +0 -45
  245. data/lib/decidim/admin/test/commands/create_category_examples.rb +0 -74
  246. data/lib/decidim/admin/test/commands/destroy_category_examples.rb +0 -83
  247. data/lib/decidim/admin/test/commands/update_category_examples.rb +0 -76
  248. data/lib/decidim/admin/test/forms/category_form_examples.rb +0 -70
  249. data/lib/decidim/admin/test/manage_categories_examples.rb +0 -128
@@ -0,0 +1,170 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Admin
5
+ # Concern to handle warnings for deleted (trashed) resources
6
+ #
7
+ # # i18n-tasks-use t('decidim.admin.trash_management.restore.invalid')
8
+ # # i18n-tasks-use t('decidim.admin.trash_management.restore.success')
9
+ # # i18n-tasks-use t('decidim.admin.trash_management.soft_delete.invalid')
10
+ # # i18n-tasks-use t('decidim.admin.trash_management.soft_delete.success')
11
+ module HasTrashableResources
12
+ extend ActiveSupport::Concern
13
+
14
+ included do
15
+ helper_method :trashable_deleted_collection
16
+
17
+ before_action :trashable_set_deleted_warning, if: :trash_zone?
18
+
19
+ # i18n-tasks-use t('decidim.admin.trash_management.soft_delete.invalid')
20
+ # i18n-tasks-use t('decidim.admin.trash_management.soft_delete.success')
21
+ def soft_delete
22
+ enforce_permission_to(:soft_delete, trashable_deleted_resource_type, trashable_deleted_resource:)
23
+
24
+ Decidim::Commands::SoftDeleteResource.call(trashable_deleted_resource, current_user) do
25
+ on(:ok) do
26
+ flash[:notice] = I18n.t("soft_delete.success", scope: trashable_i18n_scope, resource_name: human_readable_resource_name.capitalize)
27
+ redirect_to_resource_index
28
+ end
29
+
30
+ on(:invalid) do
31
+ flash[:alert] = I18n.t("soft_delete.invalid", scope: trashable_i18n_scope, resource_name: human_readable_resource_name)
32
+ redirect_to_resource_index
33
+ end
34
+ end
35
+ end
36
+
37
+ # i18n-tasks-use t('decidim.admin.trash_management.restore.invalid')
38
+ # i18n-tasks-use t('decidim.admin.trash_management.restore.success')
39
+ def restore
40
+ enforce_permission_to(:restore, trashable_deleted_resource_type, trashable_deleted_resource:)
41
+
42
+ Decidim::Commands::RestoreResource.call(trashable_deleted_resource, current_user) do
43
+ on(:ok) do
44
+ flash[:notice] = I18n.t("restore.success", scope: trashable_i18n_scope, resource_name: human_readable_resource_name.capitalize)
45
+ redirect_to_resource_trash
46
+ end
47
+
48
+ on(:invalid) do
49
+ flash[:alert] = I18n.t("restore.invalid", scope: trashable_i18n_scope, resource_name: human_readable_resource_name)
50
+ redirect_to_resource_trash
51
+ end
52
+ end
53
+ end
54
+
55
+ def manage_trash
56
+ enforce_permission_to :manage_trash, trashable_deleted_resource_type
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def trashable_deleted_resource_type
63
+ raise NotImplementedError, "Return the type of the deleted resource (symbol)"
64
+ end
65
+
66
+ def trashable_deleted_resource
67
+ raise NotImplementedError, "Return the deleted resource or nil"
68
+ end
69
+
70
+ def trashable_deleted_collection
71
+ raise NotImplementedError, "Return the collection of deleted resources"
72
+ end
73
+
74
+ # override to customize flash messages
75
+ def trashable_i18n_scope
76
+ "decidim.admin.trash_management"
77
+ end
78
+
79
+ def find_parent_resource
80
+ respond_to?(:parent_resource_finder, true) ? find_parent_resource : nil
81
+ end
82
+
83
+ # defaults to the resource name pluralized, but you can override on complex cases
84
+ def redirect_to_resource_index
85
+ redirect_to build_redirect_path
86
+ end
87
+
88
+ def redirect_to_resource_trash
89
+ redirect_to build_redirect_path(trash: true)
90
+ end
91
+
92
+ def trashable_set_deleted_warning
93
+ flash.now[:warning] = I18n.t("deleted_warning", scope: trashable_i18n_scope, default: t("decidim.admin.manage_trash.deleted_items_warning"))
94
+ end
95
+
96
+ def build_redirect_path(trash: false)
97
+ parent_resource = find_parent_resource
98
+
99
+ if parent_resource.present?
100
+ parent_resource_name = parent_resource.class.name.demodulize.underscore
101
+ action_prefix = trash ? "manage_trash_" : ""
102
+ route_name = "#{action_prefix}#{parent_resource_name}_#{trashable_deleted_resource_type.to_s.pluralize}_path"
103
+ if respond_to?(:current_component)
104
+ Decidim::EngineRouter.admin_proxy(current_component).send(route_name, parent_resource)
105
+ else
106
+ send(route_name, parent_resource)
107
+ end
108
+ else
109
+ action_prefix = trash ? "manage_trash_" : ""
110
+ route_name = "#{action_prefix}#{trashable_deleted_resource_type.to_s.pluralize}_path"
111
+ if respond_to?(:current_component)
112
+ Decidim::EngineRouter.admin_proxy(current_component).send(route_name)
113
+ else
114
+ send(route_name)
115
+ end
116
+ end
117
+ end
118
+
119
+ def trash_zone?
120
+ case action_name
121
+ when "manage_trash"
122
+ true
123
+ when "index", "show", "new", "edit"
124
+ resource_or_parents_trashed?
125
+ else
126
+ false
127
+ end
128
+ end
129
+
130
+ def parent_resource
131
+ trashable_deleted_resource&.try(:parent)
132
+ end
133
+
134
+ def component_trashed?
135
+ respond_to?(:current_component) && current_component&.deleted?
136
+ end
137
+
138
+ def participatory_space_trashed?
139
+ current_participatory_space.respond_to?(:deleted?) && current_participatory_space&.deleted?
140
+ end
141
+
142
+ def resource_trashed?
143
+ trashable_deleted_resource&.deleted?
144
+ end
145
+
146
+ def parent_trashed?
147
+ parent_resource&.deleted?
148
+ end
149
+
150
+ def parent_id_trashed?
151
+ parent_resource = find_parent_resource
152
+ parent_resource&.deleted? || false
153
+ end
154
+
155
+ def human_readable_resource_name
156
+ trashable_deleted_resource_type.to_s.humanize
157
+ end
158
+
159
+ def resource_or_parents_trashed?
160
+ return true if component_trashed?
161
+ return true if participatory_space_trashed?
162
+ return true if resource_trashed?
163
+ return true if parent_trashed?
164
+ return true if parent_id_trashed?
165
+
166
+ false
167
+ end
168
+ end
169
+ end
170
+ end
@@ -5,6 +5,7 @@ module Decidim
5
5
  # Shared behaviour for signed_in admins that require the latest TOS accepted
6
6
  module NeedsAdminTosAccepted
7
7
  extend ActiveSupport::Concern
8
+ include UserRoleChecker
8
9
 
9
10
  included do
10
11
  before_action :tos_accepted_by_admin
@@ -15,7 +16,7 @@ module Decidim
15
16
  def tos_accepted_by_admin
16
17
  return unless request.format.html?
17
18
  return unless current_user
18
- return unless user_has_any_role?
19
+ return unless user_has_any_role?(current_user, broad_check: true)
19
20
  return if current_user.admin_terms_accepted?
20
21
  return if permitted_paths?
21
22
 
@@ -38,34 +39,6 @@ module Decidim
38
39
  def admin_tos_path
39
40
  decidim_admin.admin_terms_show_path
40
41
  end
41
-
42
- def user_has_any_role?
43
- return true if current_user.admin
44
- return true if current_user.roles.any?
45
- return true if participatory_process_user_role?
46
- return true if assembly_user_role?
47
- return true if conference_user_role?
48
-
49
- false
50
- end
51
-
52
- def participatory_process_user_role?
53
- return false unless Decidim.module_installed?(:participatory_processes)
54
-
55
- true if Decidim::ParticipatoryProcessUserRole.exists?(user: current_user)
56
- end
57
-
58
- def assembly_user_role?
59
- return false unless Decidim.module_installed?(:assemblies)
60
-
61
- true if Decidim::AssemblyUserRole.exists?(user: current_user)
62
- end
63
-
64
- def conference_user_role?
65
- return false unless Decidim.module_installed?(:conferences)
66
-
67
- true if Decidim::ConferenceUserRole.exists?(user: current_user)
68
- end
69
42
  end
70
43
  end
71
44
  end
@@ -30,8 +30,6 @@ module Decidim
30
30
  helper_method :current_participatory_space
31
31
  helper_method :current_participatory_space_manifest
32
32
  helper_method :current_participatory_space_context
33
-
34
- delegate :manifest, to: :current_participatory_space, prefix: true
35
33
  end
36
34
 
37
35
  private
@@ -44,6 +42,18 @@ module Decidim
44
42
  raise NotImplementedError
45
43
  end
46
44
 
45
+ def current_participatory_space_manifest
46
+ return current_participatory_space.manifest if current_participatory_space
47
+
48
+ manifest = Decidim.find_participatory_space_manifest(
49
+ self.class.name.demodulize.underscore.gsub("_controller", "")
50
+ )
51
+
52
+ raise NotImplementedError unless manifest
53
+
54
+ manifest
55
+ end
56
+
47
57
  def authorize_participatory_space
48
58
  enforce_permission_to :read, :participatory_space, current_participatory_space:
49
59
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ module Admin
7
+ module Taxonomies
8
+ module Filterable
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ include Decidim::Admin::Filterable
13
+
14
+ private
15
+
16
+ def base_query
17
+ collection
18
+ end
19
+
20
+ def search_field_predicate
21
+ :name_or_children_name_cont
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -26,10 +26,9 @@ module Decidim
26
26
  helper Decidim::Admin::IconLinkHelper
27
27
  helper Decidim::Admin::IconWithTooltipHelper
28
28
  helper Decidim::Admin::MenuHelper
29
- helper Decidim::Admin::ScopesHelper
30
29
  helper Decidim::DecidimFormHelper
31
30
  helper Decidim::ReplaceButtonsHelper
32
- helper Decidim::ScopesHelper
31
+ helper Decidim::TaxonomiesHelper
33
32
  helper Decidim::TranslationsHelper
34
33
  helper Decidim::LanguageChooserHelper
35
34
  helper Decidim::ComponentPathHelper
@@ -6,6 +6,7 @@ module Decidim
6
6
  #
7
7
  class AreasController < Decidim::Admin::ApplicationController
8
8
  include Decidim::Admin::Concerns::HasTabbedMenu
9
+ helper Decidim::Admin::AreasHelper
9
10
 
10
11
  layout "decidim/admin/settings"
11
12
 
@@ -22,7 +22,7 @@ module Decidim
22
22
  BlockUser.call(@form) do
23
23
  on(:ok) do
24
24
  flash[:notice] = I18n.t("officializations.block.success", scope: "decidim.admin")
25
- redirect_to moderated_users_path(blocked: true), notice:
25
+ redirect_to moderated_users_path, notice:
26
26
  end
27
27
 
28
28
  on(:invalid) do
@@ -48,6 +48,41 @@ module Decidim
48
48
  redirect_to moderated_users_path, notice:
49
49
  end
50
50
 
51
+ def bulk_new
52
+ enforce_permission_to :block, :admin_user
53
+
54
+ @form = form(BlockUsersForm).from_params(params)
55
+ end
56
+
57
+ def bulk_create
58
+ @form = form(BlockUsersForm).from_params(params)
59
+
60
+ Admin::BulkBlockUsers.call(@form) do
61
+ on(:ok) do
62
+ flash[:notice] = I18n.t("officializations.bulk_action.block.success", scope: "decidim.admin")
63
+ redirect_to moderated_users_path
64
+ end
65
+
66
+ on(:invalid) do
67
+ flash.now[:alert] = I18n.t("officializations.bulk_action.block.invalid", scope: "decidim.admin")
68
+ render :bulk_new
69
+ end
70
+ end
71
+ end
72
+
73
+ def bulk_destroy
74
+ Admin::BulkUnblockUsers.call(blocked_users, current_user) do
75
+ on(:ok) do
76
+ flash[:notice] = I18n.t("officializations.bulk_action.unblock.success", scope: "decidim.admin")
77
+ end
78
+
79
+ on(:invalid) do
80
+ flash.now[:alert] = I18n.t("officializations.bulk_action.unblock.invalid", scope: "decidim.admin")
81
+ end
82
+ end
83
+ redirect_to moderated_users_path
84
+ end
85
+
51
86
  private
52
87
 
53
88
  def user
@@ -56,6 +91,13 @@ module Decidim
56
91
  organization: current_organization
57
92
  )
58
93
  end
94
+
95
+ def blocked_users
96
+ @blocked_users ||= Decidim::UserBaseEntity.where(
97
+ id: params[:user_ids],
98
+ organization: current_organization
99
+ )
100
+ end
59
101
  end
60
102
  end
61
103
  end
@@ -9,16 +9,14 @@ module Decidim
9
9
 
10
10
  def edit
11
11
  enforce_permission_to(:update, :component, component:)
12
- @permissions_form = PermissionsForm.new(
13
- permissions: permission_forms
14
- )
12
+ @permissions_form = form(PermissionsForm).from_params(permissions: permission_forms)
15
13
 
16
14
  render template: "decidim/admin/resource_permissions/edit"
17
15
  end
18
16
 
19
17
  def update
20
18
  enforce_permission_to(:update, :component, component:)
21
- @permissions_form = PermissionsForm.from_params(params)
19
+ @permissions_form = form(PermissionsForm).from_params(params)
22
20
 
23
21
  UpdateComponentPermissions.call(@permissions_form, component, resource) do
24
22
  on(:ok) do
@@ -6,7 +6,8 @@ module Decidim
6
6
  # admin panel.
7
7
  #
8
8
  class ComponentsController < Decidim::Admin::ApplicationController
9
- helper_method :manifest, :current_participatory_space
9
+ include Decidim::Admin::HasTrashableResources
10
+ helper_method :manifest
10
11
 
11
12
  def index
12
13
  enforce_permission_to :read, :component
@@ -78,19 +79,21 @@ module Decidim
78
79
  end
79
80
  end
80
81
 
81
- def destroy
82
- @component = query_scope.find(params[:id])
83
- enforce_permission_to :destroy, :component, component: @component
82
+ # i18n-tasks-use t('decidim.admin.trash_management.soft_delete.invalid')
83
+ # i18n-tasks-use t('decidim.admin.trash_management.soft_delete.success')
84
+ def soft_delete
85
+ enforce_permission_to(:soft_delete, trashable_deleted_resource_type, trashable_deleted_resource:)
84
86
 
85
- DestroyComponent.call(@component, current_user) do
87
+ Decidim::Commands::SoftDeleteResource.call(trashable_deleted_resource, current_user) do
86
88
  on(:ok) do
87
- flash[:notice] = I18n.t("components.destroy.success", scope: "decidim.admin")
88
- redirect_to action: :index
89
+ Decidim::Reminder.where(component: resource).destroy_all
90
+ flash[:notice] = I18n.t("soft_delete.success", scope: trashable_i18n_scope, resource_name: human_readable_resource_name.capitalize)
91
+ redirect_to_resource_index
89
92
  end
90
93
 
91
94
  on(:invalid) do
92
- flash[:alert] = I18n.t("components.destroy.error", scope: "decidim.admin")
93
- redirect_to action: :index
95
+ flash[:alert] = I18n.t("soft_delete.invalid", scope: trashable_i18n_scope, resource_name: human_readable_resource_name)
96
+ redirect_to_resource_index
94
97
  end
95
98
  end
96
99
  end
@@ -119,6 +122,18 @@ module Decidim
119
122
  end
120
123
  end
121
124
 
125
+ def hide
126
+ @component = query_scope.find(params[:id])
127
+ enforce_permission_to :publish, :component, component: @component
128
+
129
+ HideMenuComponent.call(@component, current_user) do
130
+ on(:ok) do
131
+ flash[:notice] = I18n.t("components.hide.success", scope: "decidim.admin")
132
+ redirect_to action: :index
133
+ end
134
+ end
135
+ end
136
+
122
137
  def share
123
138
  @component = query_scope.find(params[:id])
124
139
  share_token = @component.share_tokens.create!(user: current_user, organization: current_organization)
@@ -126,8 +141,34 @@ module Decidim
126
141
  redirect_to share_token.url
127
142
  end
128
143
 
144
+ def reorder
145
+ enforce_permission_to :reorder, :component
146
+
147
+ ReorderComponents.call(current_participatory_space.components, params[:order_ids]) do
148
+ on(:ok) do
149
+ head :ok
150
+ end
151
+
152
+ on(:invalid) do
153
+ head :bad_request
154
+ end
155
+ end
156
+ end
157
+
129
158
  private
130
159
 
160
+ def trashable_deleted_resource_type
161
+ :component
162
+ end
163
+
164
+ def trashable_deleted_resource
165
+ @trashable_deleted_resource = query_scope.with_deleted.find_by(id: params[:id])
166
+ end
167
+
168
+ def trashable_deleted_collection
169
+ @trashable_deleted_collection ||= current_participatory_space.components.only_deleted.deleted_at_desc
170
+ end
171
+
131
172
  # Processes the component params so the form object defined in the manifest (component_form_class_name)
132
173
  # can assign and validate the attributes when using #from_params.
133
174
  def component_params
@@ -17,6 +17,10 @@ module Decidim
17
17
  helper PaginateHelper
18
18
  helper_method :privatable_to, :participatory_space_private_users
19
19
 
20
+ # rubocop:disable Rails/LexicallyScopedActionFilter
21
+ before_action :set_private_user, only: [:edit, :update, :destroy, :resend_invitation]
22
+ # rubocop:enable Rails/LexicallyScopedActionFilter
23
+
20
24
  def index
21
25
  enforce_permission_to :read, :space_private_user
22
26
 
@@ -29,6 +33,29 @@ module Decidim
29
33
  render template: "decidim/admin/participatory_space_private_users/new"
30
34
  end
31
35
 
36
+ def edit
37
+ enforce_permission_to :update, :space_private_user, private_user: @private_user
38
+ @form = form(ParticipatorySpacePrivateUserForm).from_model(@private_user)
39
+ render template: "decidim/admin/participatory_space_private_users/edit"
40
+ end
41
+
42
+ def update
43
+ enforce_permission_to :update, :space_private_user, private_user: @private_user
44
+ @form = form(ParticipatorySpacePrivateUserForm).from_params(params, privatable_to:)
45
+
46
+ UpdateParticipatorySpacePrivateUser.call(@form, @private_user) do
47
+ on(:ok) do
48
+ flash[:notice] = I18n.t("participatory_space_private_users.update.success", scope: "decidim.admin")
49
+ redirect_to action: :index
50
+ end
51
+
52
+ on(:invalid) do
53
+ flash.now[:alert] = I18n.t("participatory_space_private_users.update.error", scope: "decidim.admin")
54
+ render template: "decidim/admin/participatory_space_private_users/edit"
55
+ end
56
+ end
57
+ end
58
+
32
59
  def create
33
60
  enforce_permission_to :create, :space_private_user
34
61
  @form = form(ParticipatorySpacePrivateUserForm).from_params(params, privatable_to:)
@@ -47,7 +74,6 @@ module Decidim
47
74
  end
48
75
 
49
76
  def destroy
50
- @private_user = collection.find(params[:id])
51
77
  enforce_permission_to :destroy, :space_private_user, private_user: @private_user
52
78
 
53
79
  DestroyParticipatorySpacePrivateUser.call(@private_user, current_user) do
@@ -64,7 +90,6 @@ module Decidim
64
90
  end
65
91
 
66
92
  def resend_invitation
67
- @private_user = collection.find(params[:id])
68
93
  enforce_permission_to :invite, :space_private_user, private_user: @private_user
69
94
  InviteUserAgain.call(@private_user.user, "invite_private_user") do
70
95
  on(:ok) do
@@ -79,6 +104,34 @@ module Decidim
79
104
  redirect_to after_destroy_path
80
105
  end
81
106
 
107
+ def publish_all
108
+ PublishAllParticipatorySpacePrivateUsers.call(current_participatory_space, current_user) do
109
+ on(:ok) do
110
+ flash[:notice] = I18n.t("participatory_space_private_users.publish_all.success", scope: "decidim.admin")
111
+ redirect_to action: :index
112
+ end
113
+
114
+ on(:invalid) do
115
+ flash[:alert] = I18n.t("participatory_space_private_users.publish_all.error", scope: "decidim.admin")
116
+ redirect_to action: :index
117
+ end
118
+ end
119
+ end
120
+
121
+ def unpublish_all
122
+ UnpublishAllParticipatorySpacePrivateUsers.call(current_participatory_space, current_user) do
123
+ on(:ok) do
124
+ flash[:notice] = I18n.t("participatory_space_private_users.unpublish_all.success", scope: "decidim.admin")
125
+ redirect_to action: :index
126
+ end
127
+
128
+ on(:invalid) do
129
+ flash[:alert] = I18n.t("participatory_space_private_users.unpublish_all.error", scope: "decidim.admin")
130
+ redirect_to action: :index
131
+ end
132
+ end
133
+ end
134
+
82
135
  # Public: Returns a String or Object that will be passed to `redirect_to` after
83
136
  # destroying a private user. By default it redirects to the privatable_to.
84
137
  #
@@ -105,6 +158,10 @@ module Decidim
105
158
  def participatory_space_private_users
106
159
  filtered_collection
107
160
  end
161
+
162
+ def set_private_user
163
+ @private_user = collection.find(params[:id])
164
+ end
108
165
  end
109
166
  end
110
167
  end
@@ -47,7 +47,7 @@ module Decidim
47
47
 
48
48
  on(:invalid) do
49
49
  flash.now[:alert] = I18n.t("error", scope: "decidim.admin.conflicts.transfer")
50
- redirect_to decidim.root_path
50
+ render action: "edit"
51
51
  end
52
52
  end
53
53
  end
@@ -27,6 +27,10 @@ module Decidim
27
27
  def reportable
28
28
  @reportable ||= moderations_for_user.find(params[:id]).reportable
29
29
  end
30
+
31
+ def selected_moderations
32
+ @selected_moderations ||= moderations_for_user.where(id: params[:moderation_ids])
33
+ end
30
34
  end
31
35
  end
32
36
  end
@@ -29,6 +29,7 @@ module Decidim
29
29
 
30
30
  @form = form(ImpersonateUserForm).from_params(
31
31
  user:,
32
+ name: params[:impersonate_user][:name],
32
33
  handler_name:,
33
34
  reason: params[:impersonate_user][:reason],
34
35
  authorization: Decidim::AuthorizationHandler.handler_for(
@@ -5,6 +5,8 @@ module Decidim
5
5
  class ModeratedUsersController < Decidim::Admin::ApplicationController
6
6
  include Decidim::ModeratedUsers::Admin::Filterable
7
7
 
8
+ helper_method :moderated_users
9
+
8
10
  layout "decidim/admin/global_moderations"
9
11
 
10
12
  before_action :set_moderation_breadcrumb_item
@@ -31,12 +33,36 @@ module Decidim
31
33
  end
32
34
  end
33
35
 
36
+ def bulk_unreport
37
+ Admin::BulkUnreportUsers.call(current_user, reportables) do
38
+ on(:ok) do
39
+ flash[:notice] = I18n.t("reportable.bulk_action.ignore.success", scope: "decidim.moderations.admin")
40
+ end
41
+
42
+ on(:invalid) do
43
+ flash.now[:alert] = I18n.t("reportable.bulk_action.ignore.invalid", scope: "decidim.moderations.admin")
44
+ end
45
+ end
46
+ redirect_to moderated_users_path
47
+ end
48
+
34
49
  private
35
50
 
51
+ def moderated_users
52
+ @moderated_users ||= filtered_collection
53
+ end
54
+
36
55
  def reportable
37
56
  @reportable ||= base_query_finder.find(params[:id]).user
38
57
  end
39
58
 
59
+ def reportables
60
+ @reportables ||= Decidim::UserBaseEntity.where(
61
+ id: params[:user_ids],
62
+ organization: current_organization
63
+ )
64
+ end
65
+
40
66
  def base_query_finder
41
67
  Decidim::Admin::ModerationStats.new(current_user).user_reports
42
68
  end
@@ -67,6 +67,20 @@ module Decidim
67
67
  end
68
68
  end
69
69
 
70
+ def bulk_action
71
+ Admin::BulkAction.call(current_user, params[:bulk_action], selected_moderations) do
72
+ on(:ok) do |ok, ko|
73
+ flash[:notice] = I18n.t("reportable.bulk_action.#{params[:bulk_action]}.success", scope: "decidim.moderations.admin", count_ok: ok.count) if ok.count.positive?
74
+ flash[:alert] = I18n.t("reportable.bulk_action.#{params[:bulk_action]}.failed", scope: "decidim.moderations.admin", errored: ko.join(", ")) if ko.present? && ko.any?
75
+ end
76
+
77
+ on(:invalid) do
78
+ flash.now[:alert] = I18n.t("reportable.bulk_action.#{params[:bulk_action]}.invalid", scope: "decidim.moderations.admin")
79
+ end
80
+ end
81
+ redirect_to moderations_path
82
+ end
83
+
70
84
  private
71
85
 
72
86
  def ransack_params
@@ -94,6 +108,10 @@ module Decidim
94
108
  @reportable ||= participatory_space_moderations.find(params[:id]).reportable
95
109
  end
96
110
 
111
+ def selected_moderations
112
+ @selected_moderations ||= participatory_space_moderations.where(id: params[:moderation_ids])
113
+ end
114
+
97
115
  def participatory_space_moderations
98
116
  @participatory_space_moderations ||= Decidim::Moderation.where(participatory_space: current_participatory_space)
99
117
  end