decidim-admin 0.29.2 → 0.30.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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 -2
  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 +300 -50
  157. data/config/locales/cs.yml +298 -46
  158. data/config/locales/de.yml +300 -50
  159. data/config/locales/el.yml +1 -50
  160. data/config/locales/en.yml +300 -50
  161. data/config/locales/es-MX.yml +297 -47
  162. data/config/locales/es-PY.yml +297 -47
  163. data/config/locales/es.yml +297 -47
  164. data/config/locales/eu.yml +301 -51
  165. data/config/locales/fi-plain.yml +297 -47
  166. data/config/locales/fi.yml +297 -47
  167. data/config/locales/fr-CA.yml +183 -47
  168. data/config/locales/fr.yml +183 -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 +1 -46
  175. data/config/locales/ja.yml +298 -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 +35 -50
  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
@@ -5,8 +5,6 @@ module Decidim
5
5
  # This class contains helpers needed in order for component settings to
6
6
  # properly render.
7
7
  module SettingsHelper
8
- include Decidim::ScopesHelper
9
-
10
8
  TYPES = {
11
9
  boolean: :check_box,
12
10
  integer: :number_field,
@@ -14,9 +12,10 @@ module Decidim
14
12
  float: :number_field,
15
13
  text: :text_area,
16
14
  select: :select_field,
17
- scope: :scope_field,
18
15
  enum: :collection_radio_buttons,
19
- time: :datetime_field
16
+ time: :datetime_field,
17
+ integer_with_units: :integer_with_units,
18
+ taxonomy_filters: :taxonomy_filters
20
19
  }.freeze
21
20
 
22
21
  # Renders a form field that matches a settings attribute's type.
@@ -52,20 +51,39 @@ module Decidim
52
51
  if attribute.translated?
53
52
  options[:tabs_id] = "#{options.delete(:tabs_prefix)}-#{name}-tabs"
54
53
  form.send(:translated, form_method, name, options)
55
- elsif form_method == :collection_radio_buttons
56
- render_enum_form_field(form, attribute, name, i18n_scope, options)
57
- elsif form_method == :select_field
58
- render_select_form_field(form, attribute, name, i18n_scope, options)
59
- elsif form_method == :scope_field
60
- scopes_select_field(form, name)
61
54
  else
62
- form.send(form_method, name, options)
55
+ render_field_form_method(form_method, form, attribute, name, i18n_scope, options)
63
56
  end
64
57
  end.html_safe
65
58
  end
66
59
 
67
60
  private
68
61
 
62
+ # rubocop:disable Metrics/ParameterLists
63
+ def render_field_form_method(form_method, form, attribute, name, i18n_scope, options)
64
+ case form_method
65
+ when :collection_radio_buttons
66
+ render_enum_form_field(form, attribute, name, i18n_scope, options)
67
+ when :select_field
68
+ render_select_form_field(form, attribute, name, i18n_scope, options)
69
+ when :integer_with_units
70
+ integer_with_units(form, attribute, name, i18n_scope, options)
71
+ when :taxonomy_filters
72
+ if TaxonomyFilter.for(current_organization).blank?
73
+ label_tag(name, t(name, scope: i18n_scope)) +
74
+ content_tag(:p) do
75
+ content_tag(:span, t("no_taxonomy_filters_found", scope: i18n_scope), class: "text-gray mr-2") +
76
+ link_to(t("define_taxonomy_filters", scope: i18n_scope), decidim_admin.taxonomies_path, class: "button button__text-secondary")
77
+ end.html_safe
78
+ else
79
+ taxonomy_filters(form, name, i18n_scope)
80
+ end
81
+ else
82
+ form.send(form_method, name, options)
83
+ end
84
+ end
85
+ # rubocop:enable Metrics/ParameterLists
86
+
69
87
  # Renders a select field collection input for the given attribute
70
88
  #
71
89
  # @param form (see #settings_attribute_input)
@@ -165,6 +183,62 @@ module Decidim
165
183
  [t("#{name}_choices.#{choice}", scope: i18n_scope), choice]
166
184
  end
167
185
  end
186
+
187
+ # Renders a form field that includes an integer input and a select dropdown for units.
188
+ #
189
+ # @param form (see #settings_attribute_input)
190
+ # @param attribute [Decidim::SettingsManifest::Attribute] The attribute to be rendered
191
+ # @param name (see #settings_attribute_input)
192
+ # @param i18n_scope (see #settings_attribute_input)
193
+ # @param options (see #settings_attribute_input)
194
+ # @option options [String] :label The label text for the field
195
+ # @return [ActiveSupport::SafeBuffer] Rendered form field
196
+ def integer_with_units(form, attribute, name, i18n_scope, options)
197
+ value = form.object.send(name)
198
+
199
+ number_value = value[0].to_i
200
+ unit_value = value[1].to_s
201
+
202
+ number_field_html = form.number_field(name, options.merge(label: false,
203
+ value: number_value,
204
+ name: "#{form.field_name(name)}[0]",
205
+ style: "flex: 0 0 25%;"))
206
+ select_field_html = form.select(name,
207
+ attribute.build_units.map { |unit| [t("#{name}_units.#{unit}", scope: i18n_scope), unit] },
208
+ { label: false, value: unit_value },
209
+ { name: "#{form.field_name(name)}[1]", style: "flex: 1 1 75%;" })
210
+
211
+ content_tag(:label, options[:label]) + content_tag(:div, number_field_html + select_field_html, class: "flex space-x-2 items-center")
212
+ end
213
+
214
+ # Renders a form field that includes a taxonomy filters input hidden for each taxonomy filter
215
+ # and a button to open a drawer with all the available taxonomy filters with actions to manage them.
216
+ #
217
+ # @param name (see #settings_attribute_input)
218
+ # @param i18n_scope (see #settings_attribute_input)
219
+ def taxonomy_filters(form, name, i18n_scope)
220
+ current_filters = content_tag(:div, class: "js-current-filters") do
221
+ render partial: "decidim/admin/taxonomy_filters_selector/component_table",
222
+ locals: { field_name: "#{form.object_name}[#{name}][]", component: @component }
223
+ end
224
+ add_button = content_tag(:div, class: "mt-2") do
225
+ content_tag(:button,
226
+ t("#{name}_add", scope: i18n_scope),
227
+ class: "button button__xs button__transparent-secondary js-add-taxonomy-filter",
228
+ data: {
229
+ url: decidim_admin.taxonomy_filters_selector_index_path(component_id: @component.id)
230
+ })
231
+ end
232
+ container = content_tag(:div, class: "js-taxonomy-filters-container", data: { drawer: "#{name}-dialog" }) do
233
+ current_filters + add_button
234
+ end
235
+
236
+ drawer = decidim_drawer id: "#{name}-dialog" do
237
+ render partial: "decidim/admin/components/taxonomy_filters_drawer"
238
+ end
239
+
240
+ label_tag(name, t(name, scope: i18n_scope)) + container + drawer
241
+ end
168
242
  end
169
243
  end
170
244
  end
@@ -33,10 +33,12 @@ module Decidim
33
33
  def extended_data
34
34
  {
35
35
  send_to_all_users: @form["send_to_all_users"],
36
+ send_to_verified_users: @form["send_to_verified_users"],
36
37
  send_to_followers: @form["send_to_followers"],
37
38
  send_to_participants: @form["send_to_participants"],
39
+ send_to_private_members: @form["send_to_private_members"],
38
40
  participatory_space_types: @form["participatory_space_types"],
39
- scope_ids: @form["scope_ids"]
41
+ verification_types: @form["verification_types"]
40
42
  }
41
43
  end
42
44
 
@@ -10,8 +10,11 @@ import "src/decidim/admin/newsletters"
10
10
  import "src/decidim/admin/form"
11
11
  import "src/decidim/admin/external_domain_allowlist"
12
12
  import "src/decidim/admin/draggable-list"
13
+ import "src/decidim/admin/draggable-table"
13
14
  import "src/decidim/admin/sortable"
15
+ import "src/decidim/admin/managed_moderated_users"
14
16
  import "src/decidim/admin/moderations"
17
+ import "src/decidim/admin/global_moderations"
15
18
  import "src/decidim/admin/officializations"
16
19
  import "src/decidim/slug_form"
17
20
  import "src/decidim/admin/admin_autocomplete"
@@ -20,6 +23,7 @@ import "src/decidim/admin/participatory_space_search"
20
23
  import "src/decidim/admin/css_preview"
21
24
  import "src/decidim/admin/sync_radio_buttons"
22
25
  import "src/decidim/admin/text_copy"
26
+ import "src/decidim/admin/taxonomy_filters"
23
27
 
24
28
  // CSS
25
29
  import "entrypoints/decidim_admin.scss";
@@ -7,6 +7,8 @@ import Configuration from "src/decidim/configuration";
7
7
  import InputCharacterCounter from "src/decidim/input_character_counter";
8
8
  import managedUsersForm from "src/decidim/admin/managed_users";
9
9
 
10
+ import "chartkick/chart.js";
11
+
10
12
  window.Decidim = window.Decidim || {};
11
13
  window.Decidim.managedUsersForm = managedUsersForm;
12
14
  window.Decidim.config = new Configuration();
@@ -0,0 +1,33 @@
1
+ import createSortList from "src/decidim/admin/sort_list.component"
2
+
3
+ /**
4
+ * Draggable table
5
+ *
6
+ * This script is used to make a table draggable.
7
+ * It works with two data attributes:
8
+ *
9
+ * - data-draggable-table: The table that will be draggable.
10
+ * - data-sort-url: The URL where the order will be sent.
11
+ */
12
+ $(() => {
13
+ createSortList("[data-draggable-table]", {
14
+ onSortUpdate: ($children) => {
15
+ const children = $children.toArray();
16
+
17
+ if (children.length === 0) {
18
+ return;
19
+ }
20
+
21
+ const parent = children[0].parentNode;
22
+ const sortUrl = parent.dataset.sortUrl;
23
+ const order = children.map((child) => child.dataset.recordId);
24
+
25
+ $.ajax({
26
+ method: "PUT",
27
+ url: sortUrl,
28
+ contentType: "application/json",
29
+ data: JSON.stringify({ order_ids: order }) // eslint-disable-line camelcase
30
+ });
31
+ }
32
+ });
33
+ })
@@ -1,4 +1,3 @@
1
- import "src/decidim/admin/scope_picker_enabler.component"
2
1
  import "src/decidim/admin/proposal_infinite_edit"
3
2
 
4
3
  import BudgetRuleTogglerComponent from "src/decidim/admin/budget_rule_toggler.component"
@@ -0,0 +1,186 @@
1
+ /* eslint-disable no-invalid-this */
2
+ /* eslint no-unused-vars: 0 */
3
+ /* eslint id-length: ["error", { "exceptions": ["e"] }] */
4
+
5
+ document.addEventListener("DOMContentLoaded", () => {
6
+ const selectedModerationsCount = () => {
7
+ return document.querySelectorAll(".table-list .js-check-all-moderations:checked").length;
8
+ };
9
+
10
+ const selectedModerationsCountUpdate = () => {
11
+ const selectedModerations = selectedModerationsCount();
12
+
13
+ const countElement = document.getElementById("js-selected-moderations-count");
14
+ const hideActions = document.getElementById("js-hide-global-moderations-actions");
15
+ const unhideActions = document.getElementById("js-unhide-global-moderations-actions");
16
+ const unreportActions = document.getElementById("js-unreport-global-moderations-actions");
17
+
18
+ if (selectedModerations === 0) {
19
+ countElement.textContent = "";
20
+ hideActions.classList.add("hide");
21
+ unhideActions.classList.add("hide");
22
+ unreportActions.classList.add("hide");
23
+ } else {
24
+ countElement.textContent = selectedModerations;
25
+ }
26
+ };
27
+
28
+ const showBulkActionsButton = () => {
29
+ if (selectedModerationsCount() > 0) {
30
+ document.getElementById("js-bulk-actions-button").classList.remove("hide");
31
+ }
32
+ };
33
+
34
+ const hideBulkActionsButton = (force = false) => {
35
+ const bulkActionsButton = document.getElementById("js-bulk-actions-button");
36
+ const bulkActionsDropdown = document.getElementById("js-bulk-actions-dropdown");
37
+
38
+ if (selectedModerationsCount() === 0 || force === true) {
39
+ bulkActionsButton.classList.add("hide");
40
+ bulkActionsDropdown.classList.remove("is-open");
41
+ }
42
+ }
43
+
44
+ const showOtherActionsButtons = () => {
45
+ document.getElementById("js-other-actions-wrapper").classList.remove("hide");
46
+ };
47
+
48
+ const hideOtherActionsButtons = () => {
49
+ document.getElementById("js-other-actions-wrapper").classList.add("hide");
50
+ };
51
+
52
+ const hideBulkActionForms = () => {
53
+ document.querySelectorAll(".js-bulk-action-form").forEach((form) => {
54
+ form.classList.add("hide");
55
+ });
56
+ }
57
+
58
+ // Expose functions to make them available in .js.erb templates
59
+ window.selectedModerationsCountUpdate = selectedModerationsCountUpdate;
60
+ window.showBulkActionsButton = showBulkActionsButton;
61
+ window.hideBulkActionsButton = hideBulkActionsButton;
62
+ window.showOtherActionsButtons = showOtherActionsButtons;
63
+ window.hideOtherActionsButtons = hideOtherActionsButtons;
64
+ window.hideBulkActionForms = hideBulkActionForms;
65
+
66
+ const bulkActionsButton = document.getElementById("js-bulk-actions-button");
67
+
68
+ if (document.querySelectorAll(".js-bulk-action-form").length) {
69
+ hideBulkActionForms();
70
+ bulkActionsButton.classList.add("hide");
71
+
72
+ document.querySelectorAll("#js-bulk-actions-dropdown ul li button").forEach((button) => {
73
+ button.addEventListener("click", (event) => {
74
+ const bulkActionsDropdown = document.getElementById("js-bulk-actions-dropdown");
75
+ bulkActionsDropdown.classList.remove("is-open");
76
+ hideBulkActionForms();
77
+
78
+ const action = event.target.dataset.action;
79
+ const panelActions = [
80
+ "hide-global-moderations",
81
+ "unreport-global-moderations",
82
+ "unhide-global-moderations"
83
+ ];
84
+
85
+ if (!action) {
86
+ return;
87
+ }
88
+
89
+ const form = document.getElementById(`js-form-${action}`);
90
+ const actionElement = document.getElementById(`js-${action}-actions`);
91
+
92
+ if (panelActions.includes(action)) {
93
+ form.addEventListener("submit", () => {
94
+ document.querySelector(".layout-content > div[data-callout-wrapper]").innerHTML = "";
95
+ });
96
+
97
+ actionElement.classList.remove("hide");
98
+ } else {
99
+ form.addEventListener("submit", () => {
100
+ document.querySelector(".layout-content > div[data-callout-wrapper]").innerHTML = "";
101
+ });
102
+
103
+ actionElement.classList.remove("hide");
104
+ hideBulkActionsButton(true);
105
+ hideOtherActionsButtons();
106
+ }
107
+ });
108
+ });
109
+
110
+ // select all checkboxes
111
+ document.querySelector(".js-check-all").addEventListener("change", function () {
112
+ const isChecked = this.checked;
113
+ const checkboxes = document.querySelectorAll(".js-check-all-moderations");
114
+
115
+ checkboxes.forEach((checkbox) => {
116
+ checkbox.checked = isChecked;
117
+ const row = checkbox.closest("tr");
118
+ if (row) {
119
+ row.classList.toggle("selected", isChecked);
120
+ }
121
+ });
122
+
123
+ if (isChecked) {
124
+ showBulkActionsButton();
125
+ } else {
126
+ hideBulkActionsButton();
127
+ }
128
+
129
+ selectedModerationsCountUpdate();
130
+ });
131
+
132
+ // moderation checkbox change
133
+ document.querySelector(".table-list").addEventListener("change", (event) => {
134
+ if (!event.target.matches(".js-check-all-moderations")) {
135
+ return;
136
+ }
137
+
138
+ const checkbox = event.target;
139
+ const moderationId = checkbox.value;
140
+ const checked = checkbox.checked;
141
+
142
+ // Uncheck "select all" if one of the checkboxes is unchecked
143
+ const selectAllCheckbox = document.querySelector(".js-check-all");
144
+ if (!checked) {
145
+ selectAllCheckbox.checked = false;
146
+ }
147
+
148
+ // check "select all" if all checkbox moderations are checked
149
+ const allCheckboxes = Array.from(document.querySelectorAll(".js-check-all-moderations")).filter((checkboxItem) => checkboxItem.offsetParent !== null);
150
+ const checkedCheckboxes = Array.from(document.querySelectorAll(".js-check-all-moderations:checked")).filter((checkboxItem) => checkboxItem.offsetParent !== null);
151
+
152
+ if (allCheckboxes.length === checkedCheckboxes.length) {
153
+ selectAllCheckbox.checked = true;
154
+ showBulkActionsButton();
155
+ }
156
+
157
+ const row = checkbox.closest("tr");
158
+ if (row) {
159
+ row.classList.toggle("selected", checked);
160
+ }
161
+
162
+ if (checked) {
163
+ showBulkActionsButton();
164
+ } else {
165
+ hideBulkActionsButton();
166
+ }
167
+
168
+ if (checkedCheckboxes.length === 0) {
169
+ hideBulkActionsButton();
170
+ }
171
+
172
+ document.querySelectorAll(`.js-moderation-id-${moderationId}`).forEach((input) => {
173
+ input.checked = checked;
174
+ });
175
+ selectedModerationsCountUpdate();
176
+ });
177
+
178
+ document.querySelectorAll(".js-cancel-bulk-action").forEach((button) => {
179
+ button.addEventListener("click", () => {
180
+ hideBulkActionForms();
181
+ showBulkActionsButton();
182
+ showOtherActionsButtons();
183
+ });
184
+ });
185
+ }
186
+ });
@@ -0,0 +1,186 @@
1
+ /* eslint-disable no-invalid-this */
2
+ /* eslint no-unused-vars: 0 */
3
+ /* eslint id-length: ["error", { "exceptions": ["e"] }] */
4
+
5
+ document.addEventListener("DOMContentLoaded", () => {
6
+ const selectedModeratedUsersCount = () => {
7
+ return document.querySelectorAll(".table-list .js-check-all-moderated_users:checked").length;
8
+ };
9
+
10
+ const selectedModeratedUsersCountUpdate = () => {
11
+ const selectedModeratedUsers = selectedModeratedUsersCount();
12
+
13
+ const countElement = document.getElementById("js-selected-moderated_users-count");
14
+ const blockActions = document.getElementById("js-block-moderated_users-actions");
15
+ const unblockActions = document.getElementById("js-unblock-moderated_users-actions");
16
+ const unreportActions = document.getElementById("js-unreport-moderated_users-actions");
17
+
18
+ if (selectedModeratedUsers === 0) {
19
+ countElement.textContent = "";
20
+ blockActions.classList.add("hide");
21
+ unblockActions.classList.add("hide");
22
+ unreportActions.classList.add("hide");
23
+ } else {
24
+ countElement.textContent = selectedModeratedUsers;
25
+ }
26
+ };
27
+
28
+ const showBulkActionsButton = () => {
29
+ if (selectedModeratedUsersCount() > 0) {
30
+ document.getElementById("js-bulk-actions-button").classList.remove("hide");
31
+ }
32
+ };
33
+
34
+ const hideBulkActionsButton = (force = false) => {
35
+ const bulkActionsButton = document.getElementById("js-bulk-actions-button");
36
+ const bulkActionsDropdown = document.getElementById("js-bulk-actions-dropdown");
37
+
38
+ if (selectedModeratedUsersCount() === 0 || force) {
39
+ bulkActionsButton.classList.add("hide");
40
+ bulkActionsDropdown.classList.remove("is-open");
41
+ }
42
+ };
43
+
44
+ const showOtherActionsButtons = () => {
45
+ document.getElementById("js-other-actions-wrapper").classList.remove("hide");
46
+ };
47
+
48
+ const hideOtherActionsButtons = () => {
49
+ document.getElementById("js-other-actions-wrapper").classList.add("hide");
50
+ };
51
+
52
+ const hideBulkActionForms = () => {
53
+ document.querySelectorAll(".js-bulk-action-form").forEach((form) => {
54
+ form.classList.add("hide");
55
+ });
56
+ };
57
+
58
+ // Expose functions to make them available in .js.erb templates
59
+ window.selectedModeratedUsersCountUpdate = selectedModeratedUsersCountUpdate;
60
+ window.showBulkActionsButton = showBulkActionsButton;
61
+ window.hideBulkActionsButton = hideBulkActionsButton;
62
+ window.showOtherActionsButtons = showOtherActionsButtons;
63
+ window.hideOtherActionsButtons = hideOtherActionsButtons;
64
+ window.hideBulkActionForms = hideBulkActionForms;
65
+
66
+ const bulkActionsButton = document.getElementById("js-bulk-actions-button");
67
+
68
+ if (document.querySelectorAll(".js-bulk-action-form").length) {
69
+ hideBulkActionForms();
70
+ bulkActionsButton.classList.add("hide");
71
+
72
+ document.querySelectorAll("#js-bulk-actions-dropdown ul li button").forEach((button) => {
73
+ button.addEventListener("click", (event) => {
74
+ const bulkActionsDropdown = document.getElementById("js-bulk-actions-dropdown");
75
+ bulkActionsDropdown.classList.remove("is-open");
76
+ hideBulkActionForms();
77
+
78
+ const action = event.target.dataset.action;
79
+ const panelActions = [
80
+ "block-moderated_users",
81
+ "unreport-moderated_users",
82
+ "unblock-moderated_users"
83
+ ];
84
+
85
+ if (!action) {
86
+ return;
87
+ }
88
+
89
+ const form = document.getElementById(`js-form-${action}`);
90
+ const actionElement = document.getElementById(`js-${action}-actions`);
91
+
92
+ if (panelActions.includes(action)) {
93
+ form.addEventListener("submit", () => {
94
+ document.querySelector(".layout-content > div[data-callout-wrapper]").innerHTML = "";
95
+ });
96
+
97
+ actionElement.classList.remove("hide");
98
+ } else {
99
+ form.addEventListener("submit", () => {
100
+ document.querySelector(".layout-content > div[data-callout-wrapper]").innerHTML = "";
101
+ });
102
+
103
+ actionElement.classList.remove("hide");
104
+ hideBulkActionsButton(true);
105
+ hideOtherActionsButtons();
106
+ }
107
+ });
108
+ });
109
+
110
+ // Select all checkboxes
111
+ document.querySelector(".js-check-all").addEventListener("change", function () {
112
+ const isChecked = this.checked;
113
+ const checkboxes = document.querySelectorAll(".js-check-all-moderated_users");
114
+
115
+ checkboxes.forEach((checkbox) => {
116
+ checkbox.checked = isChecked;
117
+ const row = checkbox.closest("tr");
118
+ if (row) {
119
+ row.classList.toggle("selected", isChecked);
120
+ }
121
+ });
122
+
123
+ if (isChecked) {
124
+ showBulkActionsButton();
125
+ } else {
126
+ hideBulkActionsButton();
127
+ }
128
+
129
+ selectedModeratedUsersCountUpdate();
130
+ });
131
+
132
+ // moderated users checkbox change
133
+ document.querySelector(".table-list").addEventListener("change", (event) => {
134
+ if (!event.target.matches(".js-check-all-moderated_users")) {
135
+ return;
136
+ }
137
+
138
+ const checkbox = event.target;
139
+ const moderationId = checkbox.value;
140
+ const checked = checkbox.checked;
141
+
142
+ // Uncheck "select all" if one of the checkboxes is unchecked
143
+ const selectAllCheckbox = document.querySelector(".js-check-all");
144
+ if (!checked) {
145
+ selectAllCheckbox.checked = false;
146
+ }
147
+
148
+ // If all individual checkboxes are checked, check the "select all" checkbox
149
+ const allCheckboxes = Array.from(document.querySelectorAll(".js-check-all-moderated_users")).filter((checkboxItem) => checkboxItem.offsetParent !== null);
150
+ const checkedCheckboxes = Array.from(document.querySelectorAll(".js-check-all-moderated_users:checked")).filter((checkboxItem) => checkboxItem.offsetParent !== null);
151
+
152
+ if (allCheckboxes.length === checkedCheckboxes.length) {
153
+ selectAllCheckbox.checked = true;
154
+ showBulkActionsButton();
155
+ }
156
+
157
+ const row = checkbox.closest("tr");
158
+ if (row) {
159
+ row.classList.toggle("selected", checked);
160
+ }
161
+
162
+ if (checked) {
163
+ showBulkActionsButton();
164
+ } else {
165
+ hideBulkActionsButton();
166
+ }
167
+
168
+ if (checkedCheckboxes.length === 0) {
169
+ hideBulkActionsButton();
170
+ }
171
+
172
+ document.querySelectorAll(`.js-moderated_user-id-${moderationId}`).forEach((input) => {
173
+ input.checked = checked;
174
+ });
175
+ selectedModeratedUsersCountUpdate();
176
+ });
177
+
178
+ document.querySelectorAll(".js-cancel-bulk-action").forEach((button) => {
179
+ button.addEventListener("click", () => {
180
+ hideBulkActionForms();
181
+ showBulkActionsButton();
182
+ showOtherActionsButtons();
183
+ });
184
+ });
185
+ }
186
+ });