decidim-admin 0.29.2 → 0.30.0.rc2

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 (236) 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/bulk_action.rb +92 -0
  5. data/app/commands/decidim/admin/bulk_block_users.rb +75 -0
  6. data/app/commands/decidim/admin/bulk_unblock_users.rb +66 -0
  7. data/app/commands/decidim/admin/bulk_unreport_users.rb +69 -0
  8. data/app/commands/decidim/admin/content_blocks/update_content_block.rb +1 -1
  9. data/app/commands/decidim/admin/create_participatory_space_private_user.rb +3 -1
  10. data/app/commands/decidim/admin/create_share_token.rb +39 -0
  11. data/app/commands/decidim/admin/create_taxonomy.rb +23 -0
  12. data/app/commands/decidim/admin/create_taxonomy_filter.rb +24 -0
  13. data/app/commands/decidim/admin/destroy_share_token.rb +22 -0
  14. data/app/commands/decidim/admin/destroy_taxonomy.rb +18 -0
  15. data/app/commands/decidim/admin/destroy_taxonomy_filter.rb +20 -0
  16. data/app/commands/decidim/admin/hide_menu_component.rb +37 -0
  17. data/app/commands/decidim/admin/hide_resource.rb +4 -3
  18. data/app/commands/decidim/admin/publish_all_participatory_space_private_users.rb +50 -0
  19. data/app/commands/decidim/admin/publish_component.rb +3 -0
  20. data/app/commands/decidim/admin/reorder_components.rb +47 -0
  21. data/app/commands/decidim/admin/reorder_taxonomies.rb +76 -0
  22. data/app/commands/decidim/admin/unhide_resource.rb +11 -3
  23. data/app/commands/decidim/admin/unpublish_all_participatory_space_private_users.rb +50 -0
  24. data/app/commands/decidim/admin/unreport_resource.rb +11 -3
  25. data/app/commands/decidim/admin/update_component_permissions.rb +53 -13
  26. data/app/commands/decidim/admin/update_participatory_space_private_user.rb +11 -0
  27. data/app/commands/decidim/admin/update_share_token.rb +24 -0
  28. data/app/commands/decidim/admin/update_taxonomy.rb +20 -0
  29. data/app/commands/decidim/admin/update_taxonomy_filter.rb +28 -0
  30. data/app/controllers/concerns/decidim/admin/component_taxonomies_helper.rb +19 -0
  31. data/app/controllers/concerns/decidim/admin/filterable.rb +15 -18
  32. data/app/controllers/concerns/decidim/admin/has_trashable_resources.rb +170 -0
  33. data/app/controllers/concerns/decidim/admin/needs_admin_tos_accepted.rb +2 -29
  34. data/app/controllers/concerns/decidim/admin/participatory_space_admin_context.rb +12 -2
  35. data/app/controllers/concerns/decidim/admin/taxonomies/filterable.rb +27 -0
  36. data/app/controllers/decidim/admin/application_controller.rb +1 -2
  37. data/app/controllers/decidim/admin/areas_controller.rb +1 -0
  38. data/app/controllers/decidim/admin/block_user_controller.rb +42 -0
  39. data/app/controllers/decidim/admin/component_permissions_controller.rb +2 -4
  40. data/app/controllers/decidim/admin/components_controller.rb +50 -9
  41. data/app/controllers/decidim/admin/concerns/has_private_users.rb +59 -2
  42. data/app/controllers/decidim/admin/global_moderations_controller.rb +4 -0
  43. data/app/controllers/decidim/admin/moderated_users_controller.rb +26 -0
  44. data/app/controllers/decidim/admin/moderations_controller.rb +18 -0
  45. data/app/controllers/decidim/admin/newsletters_controller.rb +50 -7
  46. data/app/controllers/decidim/admin/resource_permissions_controller.rb +1 -1
  47. data/app/controllers/decidim/admin/scopes_controller.rb +1 -0
  48. data/app/controllers/decidim/admin/share_tokens_controller.rb +109 -7
  49. data/app/controllers/decidim/admin/taxonomies_controller.rb +129 -0
  50. data/app/controllers/decidim/admin/taxonomy_filters_controller.rb +112 -0
  51. data/app/controllers/decidim/admin/taxonomy_filters_selector_controller.rb +81 -0
  52. data/app/controllers/decidim/admin/taxonomy_items_controller.rb +91 -0
  53. data/app/forms/concerns/decidim/has_taxonomy_form_attributes.rb +57 -0
  54. data/app/forms/decidim/admin/block_users_form.rb +21 -0
  55. data/app/forms/decidim/admin/import_example_form.rb +1 -1
  56. data/app/forms/decidim/admin/newsletter_form.rb +1 -1
  57. data/app/forms/decidim/admin/participatory_space_private_user_form.rb +5 -0
  58. data/app/forms/decidim/admin/selective_newsletter_form.rb +46 -11
  59. data/app/forms/decidim/admin/share_token_form.rb +55 -0
  60. data/app/forms/decidim/admin/taxonomy_filter_form.rb +85 -0
  61. data/app/forms/decidim/admin/taxonomy_form.rb +20 -0
  62. data/app/forms/decidim/admin/taxonomy_item_form.rb +54 -0
  63. data/app/helpers/decidim/admin/application_helper.rb +0 -1
  64. data/app/helpers/decidim/admin/bulk_actions_helper.rb +0 -31
  65. data/app/helpers/decidim/admin/moderations/reports_helper.rb +1 -1
  66. data/app/helpers/decidim/admin/moderations_helper.rb +1 -1
  67. data/app/helpers/decidim/admin/newsletters_helper.rb +57 -27
  68. data/app/helpers/decidim/admin/scopes_helper.rb +0 -6
  69. data/app/helpers/decidim/admin/search_form_helper.rb +1 -1
  70. data/app/helpers/decidim/admin/settings_helper.rb +85 -11
  71. data/app/jobs/decidim/admin/newsletter_job.rb +3 -1
  72. data/app/packs/entrypoints/decidim_admin.js +4 -0
  73. data/app/packs/src/decidim/admin/application.js +2 -0
  74. data/app/packs/src/decidim/admin/draggable-table.js +33 -0
  75. data/app/packs/src/decidim/admin/form.js +0 -1
  76. data/app/packs/src/decidim/admin/global_moderations.js +186 -0
  77. data/app/packs/src/decidim/admin/managed_moderated_users.js +186 -0
  78. data/app/packs/src/decidim/admin/newsletters.js +164 -82
  79. data/app/packs/src/decidim/admin/proposal_infinite_edit.js +3 -6
  80. data/app/packs/src/decidim/admin/sortable.js +28 -16
  81. data/app/packs/src/decidim/admin/taxonomy_filters.js +93 -0
  82. data/app/packs/stylesheets/decidim/admin/_component-show.scss +66 -5
  83. data/app/packs/stylesheets/decidim/admin/_legacy_foundation.scss +13 -0
  84. data/app/packs/stylesheets/decidim/admin/_select_picker.scss +20 -0
  85. data/app/packs/stylesheets/decidim/admin/_table-list.scss +22 -0
  86. data/app/packs/stylesheets/decidim/admin/_taxonomies.scss +74 -0
  87. data/app/packs/stylesheets/decidim/admin/application.scss +3 -0
  88. data/app/permissions/decidim/admin/permissions.rb +32 -1
  89. data/app/queries/decidim/admin/newsletter_recipients.rb +50 -14
  90. data/app/views/decidim/admin/areas/index.html.erb +3 -0
  91. data/app/views/decidim/admin/block_user/bulk_new.html.erb +45 -0
  92. data/app/views/decidim/admin/components/_actions.html.erb +50 -33
  93. data/app/views/decidim/admin/components/{_component.html.erb → _component_row.html.erb} +10 -5
  94. data/app/views/decidim/admin/components/_components_table.html.erb +18 -0
  95. data/app/views/decidim/admin/components/_form.html.erb +0 -12
  96. data/app/views/decidim/admin/components/_taxonomy_filters_drawer.html.erb +2 -0
  97. data/app/views/decidim/admin/components/_visibility_label.html.erb +9 -0
  98. data/app/views/decidim/admin/components/index.html.erb +12 -14
  99. data/app/views/decidim/admin/components/manage_trash.html.erb +11 -0
  100. data/app/views/decidim/admin/moderated_users/_bulk-actions.html.erb +6 -0
  101. data/app/views/decidim/admin/moderated_users/bulk_actions/_block.html.erb +20 -0
  102. data/app/views/decidim/admin/moderated_users/bulk_actions/_dropdown.html.erb +40 -0
  103. data/app/views/decidim/admin/moderated_users/bulk_actions/_unblock.html.erb +20 -0
  104. data/app/views/decidim/admin/moderated_users/bulk_actions/_unreport.html.erb +20 -0
  105. data/app/views/decidim/admin/moderated_users/index.html.erb +14 -6
  106. data/app/views/decidim/admin/moderations/_bulk-actions.html.erb +7 -0
  107. data/app/views/decidim/admin/moderations/_moderation-tr.html.erb +50 -0
  108. data/app/views/decidim/admin/moderations/_moderations-thead.html.erb +18 -0
  109. data/app/views/decidim/admin/moderations/bulk_actions/_dropdown.html.erb +43 -0
  110. data/app/views/decidim/admin/moderations/bulk_actions/_hide.html.erb +20 -0
  111. data/app/views/decidim/admin/moderations/bulk_actions/_unhide.html.erb +20 -0
  112. data/app/views/decidim/admin/moderations/bulk_actions/_unreport.html.erb +20 -0
  113. data/app/views/decidim/admin/moderations/index.html.erb +13 -81
  114. data/app/views/decidim/admin/newsletters/confirm_recipients.html.erb +64 -0
  115. data/app/views/decidim/admin/newsletters/select_recipients_to_deliver.html.erb +44 -20
  116. data/app/views/decidim/admin/participatory_space_private_users/_form.html.erb +6 -0
  117. data/app/views/decidim/admin/participatory_space_private_users/edit.html.erb +19 -0
  118. data/app/views/decidim/admin/participatory_space_private_users/index.html.erb +15 -1
  119. data/app/views/decidim/admin/resource_permissions/_options_form.html.erb +5 -0
  120. data/app/views/decidim/admin/resource_permissions/edit.html.erb +2 -2
  121. data/app/views/decidim/admin/scope_types/index.html.erb +3 -0
  122. data/app/views/decidim/admin/scopes/index.html.erb +3 -0
  123. data/app/views/decidim/admin/share_tokens/_form.html.erb +52 -0
  124. data/app/views/decidim/admin/share_tokens/edit.html.erb +33 -0
  125. data/app/views/decidim/admin/share_tokens/index.html.erb +47 -0
  126. data/app/views/decidim/admin/share_tokens/new.html.erb +69 -0
  127. data/app/views/decidim/admin/taxonomies/_filters.html.erb +19 -0
  128. data/app/views/decidim/admin/taxonomies/_form.html.erb +5 -0
  129. data/app/views/decidim/admin/taxonomies/_row.html.erb +40 -0
  130. data/app/views/decidim/admin/taxonomies/_row_children.html.erb +8 -0
  131. data/app/views/decidim/admin/taxonomies/_table.html.erb +86 -0
  132. data/app/views/decidim/admin/taxonomies/_taxonomy_actions.html.erb +15 -0
  133. data/app/views/decidim/admin/taxonomies/edit.html.erb +87 -0
  134. data/app/views/decidim/admin/taxonomies/index.html.erb +28 -0
  135. data/app/views/decidim/admin/taxonomies/new.html.erb +16 -0
  136. data/app/views/decidim/admin/taxonomy_filters/_check_boxes.html.erb +10 -0
  137. data/app/views/decidim/admin/taxonomy_filters/_form.html.erb +96 -0
  138. data/app/views/decidim/admin/taxonomy_filters/_table.html.erb +33 -0
  139. data/app/views/decidim/admin/taxonomy_filters/edit.html.erb +22 -0
  140. data/app/views/decidim/admin/taxonomy_filters/index.html.erb +26 -0
  141. data/app/views/decidim/admin/taxonomy_filters/new.html.erb +32 -0
  142. data/app/views/decidim/admin/taxonomy_filters_selector/_check_boxes.html.erb +7 -0
  143. data/app/views/decidim/admin/taxonomy_filters_selector/_component_table.html.erb +25 -0
  144. data/app/views/decidim/admin/taxonomy_filters_selector/_taxonomies_select.html.erb +16 -0
  145. data/app/views/decidim/admin/taxonomy_filters_selector/index.html.erb +1 -0
  146. data/app/views/decidim/admin/taxonomy_filters_selector/new.html.erb +27 -0
  147. data/app/views/decidim/admin/taxonomy_filters_selector/show.html.erb +18 -0
  148. data/app/views/decidim/admin/taxonomy_items/_form.html.erb +8 -0
  149. data/app/views/decidim/admin/taxonomy_items/edit.html.erb +12 -0
  150. data/app/views/decidim/admin/taxonomy_items/new.html.erb +12 -0
  151. data/app/views/layouts/decidim/admin/taxonomy_filters.html.erb +17 -0
  152. data/app/views/layouts/decidim/admin/taxonomy_filters_selector.html.erb +10 -0
  153. data/config/locales/ar.yml +45 -37
  154. data/config/locales/bg.yml +48 -51
  155. data/config/locales/bs-BA.yml +1 -27
  156. data/config/locales/ca.yml +301 -50
  157. data/config/locales/cs.yml +299 -46
  158. data/config/locales/de.yml +301 -50
  159. data/config/locales/el.yml +1 -50
  160. data/config/locales/en.yml +301 -50
  161. data/config/locales/es-MX.yml +298 -47
  162. data/config/locales/es-PY.yml +298 -47
  163. data/config/locales/es.yml +298 -47
  164. data/config/locales/eu.yml +302 -51
  165. data/config/locales/fi-plain.yml +298 -47
  166. data/config/locales/fi.yml +298 -47
  167. data/config/locales/fr-CA.yml +184 -47
  168. data/config/locales/fr.yml +184 -47
  169. data/config/locales/ga-IE.yml +0 -23
  170. data/config/locales/gl.yml +1 -46
  171. data/config/locales/hu.yml +1 -51
  172. data/config/locales/id-ID.yml +0 -24
  173. data/config/locales/is-IS.yml +0 -30
  174. data/config/locales/it.yml +2 -46
  175. data/config/locales/ja.yml +299 -50
  176. data/config/locales/kaa.yml +0 -7
  177. data/config/locales/ko.yml +0 -50
  178. data/config/locales/lb.yml +1 -46
  179. data/config/locales/lt.yml +1 -50
  180. data/config/locales/lv.yml +1 -28
  181. data/config/locales/nl.yml +1 -46
  182. data/config/locales/no.yml +1 -46
  183. data/config/locales/pl.yml +3 -51
  184. data/config/locales/pt-BR.yml +38 -50
  185. data/config/locales/pt.yml +29 -49
  186. data/config/locales/ro-RO.yml +38 -52
  187. data/config/locales/ru.yml +1 -24
  188. data/config/locales/sk.yml +1 -28
  189. data/config/locales/sl.yml +0 -5
  190. data/config/locales/sq-AL.yml +0 -22
  191. data/config/locales/sr-CS.yml +1 -27
  192. data/config/locales/sv.yml +296 -46
  193. data/config/locales/th-TH.yml +0 -10
  194. data/config/locales/tr-TR.yml +1 -44
  195. data/config/locales/uk.yml +0 -23
  196. data/config/locales/zh-CN.yml +0 -38
  197. data/config/locales/zh-TW.yml +1 -50
  198. data/config/routes.rb +13 -12
  199. data/decidim-admin.gemspec +1 -1
  200. data/lib/decidim/admin/engine.rb +2 -1
  201. data/lib/decidim/admin/import/creator.rb +2 -6
  202. data/lib/decidim/admin/import/readers/json.rb +1 -1
  203. data/lib/decidim/admin/menu.rb +9 -1
  204. data/lib/decidim/admin/search_form_builder.rb +1 -1
  205. data/lib/decidim/admin/test/destroy_admin_examples.rb +2 -2
  206. data/lib/decidim/admin/test/filterable_examples.rb +100 -9
  207. data/lib/decidim/admin/test/forms/attachment_collection_form_examples.rb +1 -1
  208. data/lib/decidim/admin/test/forms/attachment_form_examples.rb +1 -1
  209. data/lib/decidim/admin/test/invite_participatory_space_admins_shared_examples.rb +2 -4
  210. data/lib/decidim/admin/test/manage_component_permissions_examples.rb +5 -5
  211. data/lib/decidim/admin/test/manage_hide_content_examples.rb +0 -1
  212. data/lib/decidim/admin/test/manage_moderations_examples.rb +3 -3
  213. data/lib/decidim/admin/test/manage_resource_soft_deletion_examples.rb +113 -0
  214. data/lib/decidim/admin/test/manage_taxonomy_filters_examples.rb +127 -0
  215. data/lib/decidim/admin/test/taxonomy_filters_examples.rb +32 -0
  216. data/lib/decidim/admin/test.rb +3 -1
  217. data/lib/decidim/admin/version.rb +1 -1
  218. metadata +103 -29
  219. data/app/commands/decidim/admin/create_category.rb +0 -15
  220. data/app/commands/decidim/admin/destroy_category.rb +0 -15
  221. data/app/commands/decidim/admin/destroy_component.rb +0 -19
  222. data/app/commands/decidim/admin/update_category.rb +0 -11
  223. data/app/controllers/decidim/admin/categories_controller.rb +0 -98
  224. data/app/forms/decidim/admin/category_form.rb +0 -32
  225. data/app/helpers/decidim/admin/resource_scope_helper.rb +0 -52
  226. data/app/packs/src/decidim/admin/scope_picker_enabler.component.js +0 -12
  227. data/app/views/decidim/admin/categories/_form.html.erb +0 -18
  228. data/app/views/decidim/admin/categories/edit.html.erb +0 -19
  229. data/app/views/decidim/admin/categories/index.html.erb +0 -65
  230. data/app/views/decidim/admin/categories/new.html.erb +0 -19
  231. data/app/views/decidim/admin/share_tokens/_share_tokens.html.erb +0 -45
  232. data/lib/decidim/admin/test/commands/create_category_examples.rb +0 -74
  233. data/lib/decidim/admin/test/commands/destroy_category_examples.rb +0 -83
  234. data/lib/decidim/admin/test/commands/update_category_examples.rb +0 -76
  235. data/lib/decidim/admin/test/forms/category_form_examples.rb +0 -70
  236. 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
 
@@ -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
@@ -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
@@ -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