decidim-core 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 (517) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/activity_cell.rb +0 -3
  3. data/app/cells/decidim/amendable/amend_button_card/show.erb +6 -4
  4. data/app/cells/decidim/amendable/amend_button_card_cell.rb +8 -0
  5. data/app/cells/decidim/amendable/amendments/show.erb +1 -1
  6. data/app/cells/decidim/amendable/promote_button_card/show.erb +2 -0
  7. data/app/cells/decidim/author/show.erb +5 -4
  8. data/app/cells/decidim/author_cell.rb +27 -1
  9. data/app/cells/decidim/card_l/extra_data.erb +1 -0
  10. data/app/cells/decidim/card_metadata_cell.rb +9 -16
  11. data/app/cells/decidim/card_s/show.erb +5 -3
  12. data/app/cells/decidim/comments_button_cell.rb +14 -2
  13. data/app/cells/decidim/content_blocks/highlighted_elements_cell.rb +2 -0
  14. data/app/cells/decidim/content_blocks/highlighted_elements_with_cell_for_list_cell.rb +1 -1
  15. data/app/cells/decidim/diff_cell.rb +4 -0
  16. data/app/cells/decidim/endorsement_block/show.erb +0 -1
  17. data/app/cells/decidim/endorsement_block_cell.rb +6 -0
  18. data/app/cells/decidim/endorsement_buttons/button_content.erb +1 -1
  19. data/app/cells/decidim/endorsement_buttons/select_identity_button.erb +1 -1
  20. data/app/cells/decidim/endorsement_buttons/show.erb +7 -7
  21. data/app/cells/decidim/endorsement_buttons/verification_modal.erb +4 -2
  22. data/app/cells/decidim/endorsers_list/empty.erb +3 -0
  23. data/app/cells/decidim/endorsers_list/full.erb +17 -5
  24. data/app/cells/decidim/endorsers_list/show.erb +19 -10
  25. data/app/cells/decidim/endorsers_list_cell.rb +19 -6
  26. data/app/cells/decidim/follow_button/show.erb +1 -2
  27. data/app/cells/decidim/follow_button_cell.rb +5 -0
  28. data/app/cells/decidim/map/show.erb +3 -0
  29. data/app/cells/decidim/map/template.erb +14 -0
  30. data/app/cells/decidim/map_cell.rb +39 -0
  31. data/app/cells/decidim/newsletter_templates/image_text_cta_cell.rb +1 -1
  32. data/app/cells/decidim/notification_actions/buttons_cell.rb +1 -1
  33. data/app/cells/decidim/onboarding_action_message/show.erb +15 -0
  34. data/app/cells/decidim/onboarding_action_message_cell.rb +81 -0
  35. data/app/cells/decidim/participatory_space_private_user/show.erb +23 -0
  36. data/app/cells/decidim/participatory_space_private_user_cell.rb +21 -0
  37. data/app/cells/decidim/progress_bar/show.erb +2 -2
  38. data/app/cells/decidim/report_button_cell.rb +1 -0
  39. data/app/cells/decidim/resource_history/show.erb +20 -0
  40. data/app/cells/decidim/resource_history_cell.rb +66 -0
  41. data/app/cells/decidim/share_button_cell.rb +0 -4
  42. data/app/cells/decidim/share_widget/modal.erb +26 -0
  43. data/app/cells/decidim/share_widget/show.erb +2 -0
  44. data/app/cells/decidim/share_widget_cell.rb +20 -0
  45. data/app/cells/decidim/tags/show.erb +7 -4
  46. data/app/cells/decidim/tags_cell.rb +11 -72
  47. data/app/cells/decidim/translation_bar/show.erb +2 -2
  48. data/app/cells/decidim/translation_bar_cell.rb +1 -1
  49. data/app/commands/decidim/amendable/create_draft.rb +2 -2
  50. data/app/commands/decidim/create_ephemeral_user.rb +52 -0
  51. data/app/commands/decidim/create_omniauth_registration.rb +13 -3
  52. data/app/commands/decidim/create_report.rb +1 -5
  53. data/app/commands/decidim/create_user_group.rb +6 -2
  54. data/app/commands/decidim/destroy_account.rb +3 -0
  55. data/app/commands/decidim/destroy_ephemeral_user.rb +47 -0
  56. data/app/commands/decidim/update_account.rb +11 -3
  57. data/app/commands/decidim/update_notifications_settings.rb +1 -0
  58. data/app/commands/decidim/update_resources_taxonomies.rb +67 -0
  59. data/app/commands/decidim/update_user_group.rb +7 -1
  60. data/app/constraints/decidim/current_component.rb +1 -1
  61. data/app/controllers/concerns/decidim/ajax_permission_handler.rb +21 -0
  62. data/app/controllers/concerns/decidim/devise_authentication_methods.rb +3 -6
  63. data/app/controllers/concerns/decidim/devise_controllers.rb +2 -0
  64. data/app/controllers/concerns/decidim/disable_redirection_to_external_host.rb +1 -1
  65. data/app/controllers/concerns/decidim/ephemeral_session_checker.rb +87 -0
  66. data/app/controllers/concerns/decidim/filter_resource.rb +4 -2
  67. data/app/controllers/concerns/decidim/has_members_page.rb +25 -0
  68. data/app/controllers/concerns/decidim/headers/browser_feature_permissions.rb +50 -0
  69. data/app/controllers/concerns/decidim/locale_switcher.rb +2 -2
  70. data/app/controllers/concerns/decidim/needs_password_change.rb +0 -1
  71. data/app/controllers/concerns/decidim/needs_permission.rb +2 -1
  72. data/app/controllers/concerns/decidim/needs_tos_accepted.rb +4 -5
  73. data/app/controllers/concerns/decidim/onboarding_action_methods.rb +52 -0
  74. data/app/controllers/decidim/application_controller.rb +10 -0
  75. data/app/controllers/decidim/authorization_modals_controller.rb +8 -2
  76. data/app/controllers/decidim/components/base_controller.rb +3 -7
  77. data/app/controllers/decidim/devise/confirmations_controller.rb +4 -0
  78. data/app/controllers/decidim/devise/omniauth_registrations_controller.rb +8 -1
  79. data/app/controllers/decidim/devise/registrations_controller.rb +1 -1
  80. data/app/controllers/decidim/devise/sessions_controller.rb +2 -0
  81. data/app/controllers/decidim/doorkeeper/credentials_controller.rb +1 -1
  82. data/app/controllers/decidim/download_your_data_controller.rb +33 -2
  83. data/app/controllers/decidim/editor_images_controller.rb +1 -11
  84. data/app/controllers/decidim/follows_controller.rb +1 -1
  85. data/app/controllers/decidim/geolocation_controller.rb +19 -0
  86. data/app/controllers/decidim/homepage_controller.rb +0 -1
  87. data/app/controllers/decidim/links_controller.rb +1 -1
  88. data/app/controllers/decidim/open_data_controller.rb +33 -8
  89. data/app/controllers/decidim/profiles_controller.rb +4 -0
  90. data/app/controllers/decidim/user_conversations_controller.rb +1 -11
  91. data/app/events/decidim/soft_delete_resource_event.rb +15 -0
  92. data/app/forms/decidim/amendable/form.rb +4 -2
  93. data/app/forms/decidim/ephemeral_user_form.rb +22 -0
  94. data/app/forms/decidim/notifications_settings_form.rb +1 -0
  95. data/app/forms/decidim/omniauth_registration_form.rb +14 -1
  96. data/app/helpers/concerns/decidim/flash_helper_extensions.rb +17 -2
  97. data/app/helpers/concerns/decidim/user_role_checker.rb +46 -0
  98. data/app/helpers/decidim/action_authorization_helper.rb +75 -14
  99. data/app/helpers/decidim/amendments_helper.rb +0 -9
  100. data/app/helpers/decidim/application_helper.rb +6 -2
  101. data/app/helpers/decidim/breadcrumb_helper.rb +6 -0
  102. data/app/helpers/decidim/cache_helper.rb +1 -1
  103. data/app/helpers/decidim/check_boxes_tree_helper.rb +25 -53
  104. data/app/helpers/decidim/cta_button_helper.rb +1 -1
  105. data/app/helpers/decidim/decidim_form_helper.rb +0 -44
  106. data/app/helpers/decidim/endorsable_helper.rb +0 -10
  107. data/app/helpers/decidim/layout_helper.rb +6 -0
  108. data/app/helpers/decidim/map_helper.rb +6 -1
  109. data/app/helpers/decidim/messaging/conversation_helper.rb +2 -3
  110. data/app/helpers/decidim/meta_tags_helper.rb +32 -23
  111. data/app/helpers/decidim/modal_helper.rb +23 -0
  112. data/app/helpers/decidim/omniauth_helper.rb +5 -5
  113. data/app/helpers/decidim/onboarding_action_helper.rb +13 -0
  114. data/app/helpers/decidim/passwords_helper.rb +2 -2
  115. data/app/helpers/decidim/sanitize_helper.rb +11 -2
  116. data/app/helpers/decidim/taxonomies_helper.rb +40 -0
  117. data/app/jobs/decidim/download_your_data_export_job.rb +2 -19
  118. data/app/jobs/decidim/event_publisher_job.rb +18 -9
  119. data/app/jobs/decidim/export_job.rb +5 -1
  120. data/app/jobs/decidim/export_participatory_space_job.rb +4 -1
  121. data/app/jobs/decidim/open_data_job.rb +4 -4
  122. data/app/mailers/decidim/export_mailer.rb +7 -12
  123. data/app/models/decidim/action_log.rb +11 -0
  124. data/app/models/decidim/attachment.rb +1 -1
  125. data/app/models/decidim/category.rb +4 -0
  126. data/app/models/decidim/component.rb +25 -3
  127. data/app/models/decidim/metric.rb +2 -1
  128. data/app/models/decidim/moderation.rb +16 -0
  129. data/app/models/decidim/newsletter.rb +12 -8
  130. data/app/models/decidim/organization.rb +7 -3
  131. data/app/models/decidim/participatory_space_private_user.rb +20 -0
  132. data/app/models/decidim/private_export.rb +24 -0
  133. data/app/models/decidim/push_notification_message.rb +1 -1
  134. data/app/models/decidim/scope.rb +4 -0
  135. data/app/models/decidim/share_token.rb +36 -10
  136. data/app/models/decidim/taxonomization.rb +23 -0
  137. data/app/models/decidim/taxonomy.rb +139 -0
  138. data/app/models/decidim/taxonomy_filter.rb +130 -0
  139. data/app/models/decidim/taxonomy_filter_item.rb +33 -0
  140. data/app/models/decidim/user.rb +9 -23
  141. data/app/models/decidim/user_base_entity.rb +12 -0
  142. data/app/models/decidim/user_moderation.rb +9 -0
  143. data/app/models/decidim/user_report.rb +4 -0
  144. data/app/packs/entrypoints/decidim_core.js +1 -0
  145. data/app/packs/entrypoints/decidim_geocoding.js +2 -0
  146. data/app/packs/images/decidim/brands/facebook.svg +10 -0
  147. data/app/packs/images/decidim/brands/google.svg +7 -1
  148. data/app/packs/images/decidim/brands/twitter-x.svg +3 -0
  149. data/app/packs/src/decidim/append_redirect_url_to_modals.js +14 -6
  150. data/app/packs/src/decidim/check_boxes_tree.js +0 -1
  151. data/app/packs/src/decidim/clipboard.js +18 -9
  152. data/app/packs/src/decidim/confirm.js +79 -59
  153. data/app/packs/src/decidim/decidim_application.js +1 -0
  154. data/app/packs/src/decidim/direct_uploads/upload_field.js +21 -8
  155. data/app/packs/src/decidim/form_remote.js +1 -1
  156. data/app/packs/src/decidim/geocoding/reverse_geocoding.js +60 -0
  157. data/app/packs/src/decidim/impersonation.js +1 -1
  158. data/app/packs/src/decidim/index.js +14 -1
  159. data/app/packs/src/decidim/onboarding_pending_action.js +24 -0
  160. data/app/packs/src/decidim/remote_tooltips.js +38 -0
  161. data/app/packs/src/decidim/session_timeouter.js +1 -1
  162. data/app/packs/src/decidim/sticky_footer.js +29 -0
  163. data/app/packs/src/decidim/sticky_header.js +6 -31
  164. data/app/packs/src/decidim/toggle.js +1 -1
  165. data/app/packs/src/decidim/tooltips.js +42 -22
  166. data/app/packs/src/decidim/user_registrations.js +13 -0
  167. data/app/packs/src/decidim/utilities/dom.js +148 -0
  168. data/app/packs/stylesheets/decidim/_accordion.scss +30 -0
  169. data/app/packs/stylesheets/decidim/_buttons.scss +19 -0
  170. data/app/packs/stylesheets/decidim/_dropdown.scss +1 -1
  171. data/app/packs/stylesheets/decidim/_endorsers_list.scss +26 -20
  172. data/app/packs/stylesheets/decidim/_forms.scss +2 -2
  173. data/app/packs/stylesheets/decidim/_header.scss +5 -3
  174. data/app/packs/stylesheets/decidim/_labels.scss +1 -1
  175. data/app/packs/stylesheets/decidim/_layout.scss +32 -2
  176. data/app/packs/stylesheets/decidim/_login.scss +53 -6
  177. data/app/packs/stylesheets/decidim/_modal.scss +42 -0
  178. data/app/packs/stylesheets/decidim/_modal_tos_refuse.scss +4 -0
  179. data/app/packs/stylesheets/decidim/_participatory_spaces.scss +46 -0
  180. data/app/packs/stylesheets/decidim/_profile.scss +2 -2
  181. data/app/packs/stylesheets/decidim/_progress-bar.scss +1 -1
  182. data/app/packs/stylesheets/decidim/_success_image.scss +64 -0
  183. data/app/packs/stylesheets/decidim/_tribute.scss +36 -0
  184. data/app/packs/stylesheets/decidim/application.scss +1 -0
  185. data/app/packs/stylesheets/decidim/geocoding_addons.scss +5 -0
  186. data/app/packs/stylesheets/decidim/legacy/conference-diploma.scss +2 -1
  187. data/app/packs/stylesheets/decidim/map.scss +7 -10
  188. data/app/packs/stylesheets/decidim/resource_history.scss +31 -0
  189. data/app/permissions/decidim/permissions.rb +8 -2
  190. data/app/presenters/decidim/admin_log/base_user_presenter.rb +67 -0
  191. data/app/presenters/decidim/admin_log/component_presenter.rb +32 -3
  192. data/app/presenters/decidim/admin_log/moderation_presenter.rb +30 -3
  193. data/app/presenters/decidim/admin_log/share_token_presenter.rb +39 -0
  194. data/app/presenters/decidim/admin_log/taxonomy_filter_presenter.rb +57 -0
  195. data/app/presenters/decidim/admin_log/taxonomy_presenter.rb +48 -0
  196. data/app/presenters/decidim/admin_log/user_group_presenter.rb +6 -6
  197. data/app/presenters/decidim/admin_log/user_presenter.rb +4 -18
  198. data/app/presenters/decidim/attachment_presenter.rb +1 -1
  199. data/app/presenters/decidim/log/value_types/date_presenter.rb +1 -0
  200. data/app/presenters/decidim/log/value_types/taxonomy_presenter.rb +29 -0
  201. data/app/presenters/decidim/participatory_space_private_user_presenter.rb +50 -0
  202. data/app/presenters/decidim/taxonomy_filter_presenter.rb +19 -0
  203. data/app/presenters/decidim/taxonomy_presenter.rb +14 -0
  204. data/app/queries/decidim/metrics/blocked_users_metric_manage.rb +2 -2
  205. data/app/queries/decidim/metrics/users_metric_manage.rb +2 -2
  206. data/app/queries/decidim/public_activities.rb +1 -12
  207. data/app/queries/decidim/stats_users_count.rb +2 -2
  208. data/app/resolvers/decidim/meta_image_url_resolver.rb +128 -0
  209. data/app/serializers/decidim/exporters/open_data_blocked_user_serializer.rb +25 -0
  210. data/app/serializers/decidim/exporters/open_data_metric_serializer.rb +22 -0
  211. data/app/serializers/decidim/exporters/open_data_moderation_serializer.rb +30 -0
  212. data/app/serializers/decidim/exporters/open_data_taxonomy_serializer.rb +30 -0
  213. data/app/serializers/decidim/exporters/open_data_user_group_serializer.rb +38 -0
  214. data/app/serializers/decidim/exporters/open_data_user_serializer.rb +39 -0
  215. data/app/serializers/decidim/exporters/participatory_space_serializer.rb +104 -0
  216. data/app/serializers/decidim/exporters/serializer.rb +25 -0
  217. data/app/serializers/decidim/schema_org_breadcrumb_list_serializer.rb +52 -0
  218. data/app/services/decidim/action_authorizer.rb +32 -3
  219. data/app/services/decidim/base_diff_renderer.rb +27 -3
  220. data/app/services/decidim/download_your_data_exporter.rb +58 -24
  221. data/app/services/decidim/email_notification_generator.rb +14 -5
  222. data/app/services/decidim/onboarding_manager.rb +272 -0
  223. data/app/services/decidim/open_data_exporter.rb +139 -13
  224. data/app/services/decidim/traceability.rb +13 -0
  225. data/app/uploaders/decidim/application_uploader.rb +1 -1
  226. data/app/validators/etiquette_validator.rb +9 -2
  227. data/app/validators/passthru_validator.rb +1 -1
  228. data/app/validators/translated_etiquette_validator.rb +32 -0
  229. data/app/views/decidim/account/_password_fields.html.erb +2 -2
  230. data/app/views/decidim/application/_accordion_section.html.erb +14 -0
  231. data/app/views/decidim/application/_collection.html.erb +30 -18
  232. data/app/views/decidim/devise/omniauth_registrations/new.html.erb +5 -1
  233. data/app/views/decidim/devise/omniauth_registrations/new_tos_fields.html.erb +29 -0
  234. data/app/views/decidim/devise/registrations/new.html.erb +10 -22
  235. data/app/views/decidim/devise/sessions/new.html.erb +24 -29
  236. data/app/views/decidim/devise/shared/_omniauth_buttons.html.erb +2 -4
  237. data/app/views/decidim/devise/shared/_tos_fields.html.erb +16 -0
  238. data/app/views/decidim/download_your_data/_export.html.erb +15 -0
  239. data/app/views/decidim/download_your_data/show.html.erb +51 -5
  240. data/app/views/decidim/endorsements/update_buttons_and_counters.js.erb +16 -19
  241. data/app/views/decidim/export_mailer/download_your_data_export.html.erb +2 -2
  242. data/app/views/decidim/export_mailer/export.html.erb +5 -1
  243. data/app/views/decidim/notifications_settings/show.html.erb +22 -0
  244. data/app/views/decidim/open_data/_how_to_open_accordion_section.html.erb +15 -0
  245. data/app/views/decidim/open_data/index.html.erb +108 -0
  246. data/app/views/decidim/pages/_tabbed.html.erb +2 -2
  247. data/app/views/decidim/pages/show.html.erb +2 -1
  248. data/app/views/decidim/participatory_space_private_users/_participatory_space_private_user.html.erb +1 -0
  249. data/app/views/decidim/shared/_login_modal.html.erb +26 -20
  250. data/app/views/decidim/shared/_resource_actions.html.erb +21 -0
  251. data/app/views/decidim/shared/filters/_check_boxes_tree.html.erb +1 -2
  252. data/app/views/decidim/shared/filters/_collection.html.erb +1 -1
  253. data/app/views/decidim/shared/filters/_dropdown_label.html.erb +7 -4
  254. data/app/views/layouts/decidim/_application.html.erb +0 -1
  255. data/app/views/layouts/decidim/_js_configuration.html.erb +1 -0
  256. data/app/views/layouts/decidim/_logo.html.erb +1 -1
  257. data/app/views/layouts/decidim/_logo_mobile.html.erb +1 -1
  258. data/app/views/layouts/decidim/_meta_tags_config.html.erb +6 -11
  259. data/app/views/layouts/decidim/_schema_org_breadcrumb_list.html.erb +3 -0
  260. data/app/views/layouts/decidim/_wrapper.html.erb +15 -9
  261. data/app/views/layouts/decidim/footer/_main_links.html.erb +1 -1
  262. data/app/views/layouts/decidim/header/_close_ephemeral_session.html.erb +25 -0
  263. data/app/views/layouts/decidim/header/_main.html.erb +14 -10
  264. data/app/views/layouts/decidim/header/_menu_breadcrumb_items.html.erb +2 -0
  265. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile_tablet.html.erb +1 -1
  266. data/app/views/layouts/decidim/shared/_layout_item.html.erb +1 -1
  267. data/config/assets.rb +2 -1
  268. data/config/locales/ar.yml +38 -54
  269. data/config/locales/bg.yml +3 -64
  270. data/config/locales/bn-BD.yml +1 -0
  271. data/config/locales/bs-BA.yml +98 -0
  272. data/config/locales/ca.yml +380 -69
  273. data/config/locales/cs.yml +369 -55
  274. data/config/locales/de.yml +371 -67
  275. data/config/locales/el.yml +5 -45
  276. data/config/locales/en.yml +365 -54
  277. data/config/locales/eo.yml +0 -2
  278. data/config/locales/es-MX.yml +366 -58
  279. data/config/locales/es-PY.yml +366 -58
  280. data/config/locales/es.yml +375 -64
  281. data/config/locales/eu.yml +547 -223
  282. data/config/locales/fi-plain.yml +361 -57
  283. data/config/locales/fi.yml +400 -93
  284. data/config/locales/fr-CA.yml +181 -55
  285. data/config/locales/fr.yml +182 -53
  286. data/config/locales/ga-IE.yml +4 -16
  287. data/config/locales/gl.yml +5 -30
  288. data/config/locales/hu.yml +3 -55
  289. data/config/locales/id-ID.yml +5 -30
  290. data/config/locales/is-IS.yml +4 -13
  291. data/config/locales/it.yml +10 -46
  292. data/config/locales/ja.yml +230 -69
  293. data/config/locales/lb.yml +5 -47
  294. data/config/locales/lt.yml +5 -59
  295. data/config/locales/lv.yml +5 -36
  296. data/config/locales/nl.yml +5 -48
  297. data/config/locales/no.yml +6 -47
  298. data/config/locales/pl.yml +4 -66
  299. data/config/locales/pt-BR.yml +12 -52
  300. data/config/locales/pt.yml +11 -47
  301. data/config/locales/ro-RO.yml +448 -247
  302. data/config/locales/ru.yml +4 -16
  303. data/config/locales/sk.yml +5 -37
  304. data/config/locales/sv.yml +108 -64
  305. data/config/locales/tr-TR.yml +5 -45
  306. data/config/locales/uk.yml +4 -15
  307. data/config/locales/zh-CN.yml +5 -45
  308. data/config/locales/zh-TW.yml +5 -50
  309. data/config/routes.rb +5 -10
  310. data/db/migrate/20181025082245_add_timestamps_to_components.rb +2 -0
  311. data/db/migrate/20240628111905_add_visible_to_components.rb +7 -0
  312. data/db/migrate/20240704115429_create_decidim_taxonomies.rb +23 -0
  313. data/db/migrate/20240717093514_add_registered_only_to_decidim_share_tokens.rb +7 -0
  314. data/db/migrate/20240722215500_change_object_changes_on_versions.rb +39 -0
  315. data/db/migrate/20240806065417_create_decidim_taxonomy_filters.rb +23 -0
  316. data/db/migrate/20240822161348_add_deleted_at_to_decidim_components.rb +8 -0
  317. data/db/migrate/20240906162524_add_part_of_to_taxonomies.rb +26 -0
  318. data/db/migrate/20241001135825_add_role_to_participatory_space_private_users.rb +7 -0
  319. data/db/migrate/20241001140408_add_published_to_participatory_space_private_users.rb +7 -0
  320. data/db/migrate/20241022002600_create_private_exports.rb +18 -0
  321. data/db/migrate/20241028114430_add_component_counter_to_taxonomy_filters.rb +7 -0
  322. data/db/migrate/20241111104357_add_names_and_space_boolean_to_taxonomy_filters.rb +9 -0
  323. data/db/migrate/20241127093708_add_taxonomy_to_metrics.rb +7 -0
  324. data/db/migrate/20241204121445_add_participatory_space_manifests_from_taxonomy_filters.rb +9 -0
  325. data/decidim-core.gemspec +18 -18
  326. data/lib/decidim/action_authorization.rb +3 -2
  327. data/lib/decidim/amendable.rb +1 -1
  328. data/lib/decidim/api/functions/component_list.rb +1 -1
  329. data/lib/decidim/api/functions/participatory_space_finder_base.rb +11 -1
  330. data/lib/decidim/api/input_filters/category_input_filter.rb +5 -3
  331. data/lib/decidim/api/input_filters/component_input_filter.rb +33 -20
  332. data/lib/decidim/api/input_filters/user_entity_input_filter.rb +53 -44
  333. data/lib/decidim/api/input_sorts/component_input_sort.rb +15 -13
  334. data/lib/decidim/api/input_sorts/user_entity_input_sort.rb +4 -4
  335. data/lib/decidim/api/interfaces/author_interface.rb +3 -2
  336. data/lib/decidim/api/interfaces/coauthorable_interface.rb +5 -5
  337. data/lib/decidim/api/interfaces/endorsable_interface.rb +2 -2
  338. data/lib/decidim/api/interfaces/participatory_space_interface.rb +5 -10
  339. data/lib/decidim/api/interfaces/taxonomizable_interface.rb +13 -0
  340. data/lib/decidim/api/types/amendment_type.rb +5 -7
  341. data/lib/decidim/api/types/area_api_type.rb +3 -3
  342. data/lib/decidim/api/types/attachment_type.rb +3 -3
  343. data/lib/decidim/api/types/category_type.rb +2 -2
  344. data/lib/decidim/api/types/component_type.rb +7 -0
  345. data/lib/decidim/api/types/decidim_type.rb +5 -1
  346. data/lib/decidim/api/types/fingerprint_type.rb +1 -1
  347. data/lib/decidim/api/types/localized_string_type.rb +1 -1
  348. data/lib/decidim/api/types/metric_history_type.rb +2 -0
  349. data/lib/decidim/api/types/metric_type.rb +1 -1
  350. data/lib/decidim/api/types/organization_type.rb +5 -0
  351. data/lib/decidim/api/types/participatory_space_link_type.rb +2 -2
  352. data/lib/decidim/api/types/participatory_space_manifest_type.rb +1 -1
  353. data/lib/decidim/api/types/quantifiable_translated_field_type.rb +1 -1
  354. data/lib/decidim/api/types/scope_api_type.rb +2 -3
  355. data/lib/decidim/api/types/session_type.rb +1 -2
  356. data/lib/decidim/api/types/taxonomy_type.rb +15 -0
  357. data/lib/decidim/api/types/trace_version_type.rb +2 -2
  358. data/lib/decidim/api/types/translated_field_type.rb +3 -5
  359. data/lib/decidim/api/types/user_group_type.rb +11 -20
  360. data/lib/decidim/api/types/user_type.rb +9 -18
  361. data/lib/decidim/asset_router/storage.rb +4 -4
  362. data/lib/decidim/assets/tailwind/tailwind.config.js.erb +2 -1
  363. data/lib/decidim/attachment_attributes.rb +1 -1
  364. data/lib/decidim/attribute_encryptor.rb +1 -1
  365. data/lib/decidim/attribute_object/nested_validator.rb +1 -1
  366. data/lib/decidim/attributes/integer_with_units.rb +27 -0
  367. data/lib/decidim/attributes/rich_text.rb +38 -0
  368. data/lib/decidim/attributes/time_with_zone.rb +11 -1
  369. data/lib/decidim/attributes.rb +4 -0
  370. data/lib/decidim/authorization_form_builder.rb +0 -7
  371. data/lib/decidim/coauthorable.rb +1 -1
  372. data/lib/decidim/command.rb +3 -3
  373. data/lib/decidim/commands/destroy_resource.rb +5 -1
  374. data/lib/decidim/commands/resource_handler.rb +2 -2
  375. data/lib/decidim/commands/restore_resource.rb +45 -0
  376. data/lib/decidim/commands/soft_delete_resource.rb +63 -0
  377. data/lib/decidim/component_manifest.rb +7 -0
  378. data/lib/decidim/content_parsers/blob_parser.rb +93 -0
  379. data/lib/decidim/content_parsers.rb +1 -0
  380. data/lib/decidim/content_renderers/blob_renderer.rb +90 -0
  381. data/lib/decidim/content_renderers.rb +1 -0
  382. data/lib/decidim/core/api.rb +2 -0
  383. data/lib/decidim/core/engine.rb +50 -8
  384. data/lib/decidim/core/menu.rb +0 -5
  385. data/lib/decidim/core/seeds.rb +42 -2
  386. data/lib/decidim/core/test/factories.rb +133 -2
  387. data/lib/decidim/core/test/shared_examples/admin_resource_gallery_examples.rb +85 -0
  388. data/lib/decidim/core/test/shared_examples/authorable_interface_examples.rb +1 -1
  389. data/lib/decidim/core/test/shared_examples/comments_examples.rb +408 -40
  390. data/lib/decidim/core/test/shared_examples/components_controller_hide_shared_examples.rb +11 -0
  391. data/lib/decidim/core/test/shared_examples/components_controller_reorder_shared_examples.rb +21 -0
  392. data/lib/decidim/core/test/shared_examples/download_open_data_shared_context.rb +36 -0
  393. data/lib/decidim/core/test/shared_examples/download_open_data_shared_examples.rb +45 -0
  394. data/lib/decidim/core/test/shared_examples/download_your_data_shared_examples.rb +17 -0
  395. data/lib/decidim/core/test/shared_examples/etiquette_validator_examples.rb +25 -0
  396. data/lib/decidim/core/test/shared_examples/follows_examples.rb +43 -0
  397. data/lib/decidim/core/test/shared_examples/has_taxonomies.rb +94 -0
  398. data/lib/decidim/core/test/shared_examples/manage_share_tokens_examples.rb +237 -0
  399. data/lib/decidim/core/test/shared_examples/map_examples.rb +2 -0
  400. data/lib/decidim/core/test/shared_examples/open_data_exporter_examples.rb +102 -0
  401. data/lib/decidim/core/test/shared_examples/participatory_space_members_page_examples.rb +46 -0
  402. data/lib/decidim/core/test/shared_examples/participatory_space_search_examples.rb +98 -0
  403. data/lib/decidim/core/test/shared_examples/permissions.rb +7 -7
  404. data/lib/decidim/core/test/shared_examples/preview_with_share_token_examples.rb +94 -0
  405. data/lib/decidim/core/test/shared_examples/reports_examples.rb +9 -5
  406. data/lib/decidim/core/test/shared_examples/resource_endorsed_event_examples.rb +2 -2
  407. data/lib/decidim/core/test/shared_examples/resource_search_examples.rb +75 -69
  408. data/lib/decidim/core/test/shared_examples/searchable_resources_shared_context.rb +1 -1
  409. data/lib/decidim/core/test/shared_examples/simple_event.rb +33 -19
  410. data/lib/decidim/core/test/shared_examples/social_share_examples.rb +25 -0
  411. data/lib/decidim/core/test/shared_examples/softdeleteable_components_examples.rb +173 -0
  412. data/lib/decidim/core/test/shared_examples/system_endorse_resource_examples.rb +54 -8
  413. data/lib/decidim/core/test/shared_examples/taxonomizable_interface_examples.rb +20 -0
  414. data/lib/decidim/core/test/shared_examples/taxonomizable_resource_examples.rb +37 -0
  415. data/lib/decidim/core/test/shared_examples/taxonomy_settings.rb +49 -0
  416. data/lib/decidim/core/test/shared_examples/translated_event_examples.rb +1 -1
  417. data/lib/decidim/core/test/shared_examples/versions_controller_examples.rb +2 -2
  418. data/lib/decidim/core/test/shared_examples/with_endorsable_permissions_examples.rb +1 -1
  419. data/lib/decidim/core/test.rb +9 -5
  420. data/lib/decidim/core/version.rb +1 -1
  421. data/lib/decidim/core.rb +58 -0
  422. data/lib/decidim/diffy_extension.rb +18 -0
  423. data/lib/decidim/download_your_data_serializers/download_your_data_identity_serializer.rb +0 -4
  424. data/lib/decidim/download_your_data_serializers/download_your_data_participatory_space_private_user_serializer.rb +3 -1
  425. data/lib/decidim/download_your_data_serializers/download_your_data_report_serializer.rb +2 -1
  426. data/lib/decidim/download_your_data_serializers/download_your_data_user_serializer.rb +6 -7
  427. data/lib/decidim/download_your_data_serializers.rb +19 -0
  428. data/lib/decidim/exporters/csv.rb +6 -0
  429. data/lib/decidim/exporters/export_manifest.rb +14 -0
  430. data/lib/decidim/exporters/pdf.rb +26 -22
  431. data/lib/decidim/filter_form_builder.rb +12 -15
  432. data/lib/decidim/form_builder.rb +7 -130
  433. data/lib/decidim/has_category.rb +5 -1
  434. data/lib/decidim/has_private_users.rb +4 -0
  435. data/lib/decidim/has_taxonomy_settings.rb +47 -0
  436. data/lib/decidim/has_upload_validations.rb +1 -1
  437. data/lib/decidim/legacy_form_builder.rb +118 -0
  438. data/lib/decidim/maintenance/import_models/application_record.rb +93 -0
  439. data/lib/decidim/maintenance/import_models/area.rb +82 -0
  440. data/lib/decidim/maintenance/import_models/area_type.rb +12 -0
  441. data/lib/decidim/maintenance/import_models/assembly_type.rb +49 -0
  442. data/lib/decidim/maintenance/import_models/categorization.rb +14 -0
  443. data/lib/decidim/maintenance/import_models/category.rb +107 -0
  444. data/lib/decidim/maintenance/import_models/participatory_process_type.rb +21 -0
  445. data/lib/decidim/maintenance/import_models/scope.rb +163 -0
  446. data/lib/decidim/maintenance/import_models.rb +19 -0
  447. data/lib/decidim/maintenance/taxonomy_importer.rb +132 -0
  448. data/lib/decidim/maintenance/taxonomy_plan.rb +78 -0
  449. data/lib/decidim/maintenance.rb +12 -0
  450. data/lib/decidim/map/autocomplete.rb +53 -8
  451. data/lib/decidim/map/dynamic_map.rb +1 -1
  452. data/lib/decidim/map/provider/geocoding/here.rb +9 -3
  453. data/lib/decidim/map.rb +3 -6
  454. data/lib/decidim/moderation_tools.rb +14 -3
  455. data/lib/decidim/newsletter_encryptor.rb +1 -1
  456. data/lib/decidim/paddable.rb +1 -1
  457. data/lib/decidim/participable.rb +10 -10
  458. data/lib/decidim/participatory_space_user.rb +14 -0
  459. data/lib/decidim/private_download_helper.rb +15 -0
  460. data/lib/decidim/query_extensions.rb +0 -26
  461. data/lib/decidim/record_encryptor.rb +51 -46
  462. data/lib/decidim/resourceable.rb +16 -0
  463. data/lib/decidim/seeds.rb +18 -20
  464. data/lib/decidim/settings_manifest.rb +36 -1
  465. data/lib/decidim/soft_deletable.rb +17 -0
  466. data/lib/decidim/taxonomizable.rb +72 -0
  467. data/lib/decidim/translatable_attributes.rb +6 -1
  468. data/lib/decidim/view_model.rb +0 -1
  469. data/lib/tasks/decidim_download_your_data_tasks.rake +2 -4
  470. data/lib/tasks/decidim_procfile.rake +6 -0
  471. data/lib/tasks/decidim_tasks.rake +1 -0
  472. data/lib/tasks/decidim_taxonomies.rake +155 -0
  473. data/lib/tasks/upgrade/{decidim_fix_categorization.rake → clean.rake} +52 -19
  474. data/lib/tasks/upgrade/decidim_active_storage_migration_tasks.rake +1 -1
  475. data/lib/tasks/upgrade/migrations.rake +91 -0
  476. metadata +217 -103
  477. data/app/cells/decidim/amendable/amenders_list/show.erb +0 -0
  478. data/app/cells/decidim/content_blocks/base/content.erb +0 -0
  479. data/app/cells/decidim/endorsers_list/full_endorsers_list.erb +0 -3
  480. data/app/cells/decidim/endorsers_list_button/content.erb +0 -1
  481. data/app/cells/decidim/endorsers_list_button_cell.rb +0 -15
  482. data/app/cells/decidim/scopes_picker/scope_picker_prompt.erb +0 -3
  483. data/app/cells/decidim/scopes_picker/scope_picker_values.erb +0 -5
  484. data/app/cells/decidim/scopes_picker/show.erb +0 -14
  485. data/app/cells/decidim/scopes_picker_cell.rb +0 -92
  486. data/app/commands/decidim/update_user_interests.rb +0 -41
  487. data/app/controllers/decidim/scopes_controller.rb +0 -84
  488. data/app/controllers/decidim/user_interests_controller.rb +0 -30
  489. data/app/forms/decidim/user_interest_scope_form.rb +0 -25
  490. data/app/forms/decidim/user_interests_form.rb +0 -17
  491. data/app/helpers/decidim/categories_helper.rb +0 -26
  492. data/app/helpers/decidim/scopes_helper.rb +0 -105
  493. data/app/packs/images/decidim/vendor/leaflet/layers-2x.png +0 -0
  494. data/app/packs/images/decidim/vendor/leaflet/layers.png +0 -0
  495. data/app/packs/images/decidim/vendor/leaflet/marker-icon-2x.png +0 -0
  496. data/app/packs/images/decidim/vendor/leaflet/marker-icon.png +0 -0
  497. data/app/packs/images/decidim/vendor/leaflet/marker-shadow.png +0 -0
  498. data/app/packs/stylesheets/decidim/legacy/MarkerCluster.Default.scss +0 -67
  499. data/app/packs/stylesheets/decidim/legacy/MarkerCluster.scss +0 -18
  500. data/app/packs/stylesheets/decidim/legacy/leaflet.scss +0 -705
  501. data/app/validators/scope_belongs_to_component_validator.rb +0 -16
  502. data/app/views/decidim/account/_user_groups.html.erb +0 -0
  503. data/app/views/decidim/scopes/_scopes_picker_input.html.erb +0 -19
  504. data/app/views/decidim/scopes/picker.html.erb +0 -53
  505. data/app/views/decidim/shared/_comments.html.erb +0 -0
  506. data/app/views/decidim/shared/_share_modal.html.erb +0 -26
  507. data/app/views/decidim/shared/_tags.html.erb +0 -1
  508. data/app/views/decidim/user_interests/_areas.html.erb +0 -14
  509. data/app/views/decidim/user_interests/_scopes.html.erb +0 -22
  510. data/app/views/decidim/user_interests/show.html.erb +0 -22
  511. data/config/initializers/foundation_rails_helper.rb +0 -4
  512. data/lib/decidim/core/test/shared_examples/has_category.rb +0 -38
  513. data/lib/decidim/core/test/shared_examples/has_scope.rb +0 -11
  514. data/lib/decidim/core/test/shared_examples/manage_component_share_tokens.rb +0 -83
  515. data/lib/decidim/core/test/shared_examples/preview_component_with_share_token_examples.rb +0 -49
  516. data/lib/decidim/core/test/shared_examples/scope_helper_examples.rb +0 -93
  517. data/lib/decidim/seven_zip_wrapper.rb +0 -29
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # Represents the association between a taxonomy and a filterable entity within the system.
5
+ class TaxonomyFilter < ApplicationRecord
6
+ include Decidim::TranslatableResource
7
+ include Decidim::Traceable
8
+
9
+ translatable_fields :name, :internal_name
10
+
11
+ belongs_to :root_taxonomy,
12
+ class_name: "Decidim::Taxonomy",
13
+ counter_cache: :filters_count,
14
+ inverse_of: :taxonomy_filters
15
+
16
+ has_many :filter_items,
17
+ class_name: "Decidim::TaxonomyFilterItem",
18
+ inverse_of: :taxonomy_filter,
19
+ dependent: :destroy
20
+
21
+ validate :root_taxonomy_is_root
22
+ validate :space_manifest_is_registered
23
+
24
+ scope :for_manifest, ->(space_manifest) { where("? = ANY(participatory_space_manifests)", space_manifest) }
25
+ scope :space_filters, -> { where.not(participatory_space_manifests: []) }
26
+ # filters for the organization
27
+ scope :for, ->(organization) { joins(:root_taxonomy).where(decidim_taxonomies: { decidim_organization_id: organization.id }) }
28
+
29
+ delegate :organization, to: :root_taxonomy
30
+ delegate :translated_name, :translated_internal_name, to: :presenter
31
+
32
+ def presenter
33
+ Decidim::TaxonomyFilterPresenter.new(self)
34
+ end
35
+
36
+ # Returns the presenter class for this log.
37
+ #
38
+ # log - A Decidim::Log instance.
39
+ #
40
+ # Returns a Decidim::AdminLog::TaxonomyFilterPresenter class
41
+ def self.log_presenter_class_for(_log)
42
+ Decidim::AdminLog::TaxonomyFilterPresenter
43
+ end
44
+
45
+ # Public name for this filter, defaults to the root taxonomy name.
46
+ def name
47
+ return root_taxonomy&.name if super&.compact_blank.blank?
48
+
49
+ super
50
+ end
51
+
52
+ # Internal name for this filter, defaults to the root taxonomy name.
53
+ def internal_name
54
+ return root_taxonomy&.name if super&.compact_blank.blank?
55
+
56
+ super
57
+ end
58
+
59
+ # Components that have this taxonomy filter enabled.
60
+ def components
61
+ @components ||= Decidim::Component.where("(settings->'global'->'taxonomy_filters') @> ?", "\"#{id}\"")
62
+ end
63
+
64
+ def filter_taxonomy_ids
65
+ @filter_taxonomy_ids ||= filter_items.map(&:taxonomy_item_id)
66
+ end
67
+
68
+ # A memoized taxonomy tree hash filtered according to the filter_items
69
+
70
+ # that respects the order given by the taxonomies table.
71
+ # The returned hash structure is:
72
+ # {
73
+ # _object_id_ => {
74
+ # taxonomy: _object_,
75
+ # children: {
76
+ # _sub_object_id_: {
77
+ # taxonomy: _sub_object_,
78
+ # children: {
79
+ # ...
80
+ # }
81
+ # @returns [Hash] a hash with the taxonomy tree structure.
82
+ def taxonomies
83
+ @taxonomies ||= root_taxonomy
84
+ .all_children
85
+ .where(id: filter_taxonomy_ids)
86
+ .each_with_object({}) do |taxonomy, tree|
87
+ insert_child(taxonomy, tree)
88
+ end
89
+ end
90
+
91
+ def update_components_count
92
+ update(components_count: components.count)
93
+ end
94
+
95
+ def reset_all_counters
96
+ Decidim::TaxonomyFilter.reset_counters(id, :filter_items_count)
97
+ update_components_count
98
+ end
99
+
100
+ private
101
+
102
+ def insert_child(taxonomy, tree)
103
+ return if tree[taxonomy.id]
104
+
105
+ if (parent = find_parent(taxonomy, tree))
106
+ insert_child(taxonomy, parent[:children])
107
+ else
108
+ tree[taxonomy.id] = { taxonomy:, children: {} }
109
+ end
110
+ end
111
+
112
+ def find_parent(taxonomy, tree)
113
+ tree[taxonomy.parent_id].presence ||
114
+ tree.values.detect { |v| find_parent(taxonomy, v[:children]) }
115
+ end
116
+
117
+ def root_taxonomy_is_root
118
+ return if root_taxonomy&.root?
119
+
120
+ errors.add(:root_taxonomy, :invalid)
121
+ end
122
+
123
+ def space_manifest_is_registered
124
+ available_manifests = Decidim.participatory_space_manifests.map(&:name)
125
+ return if (participatory_space_manifests.map(&:to_sym) - available_manifests).empty?
126
+
127
+ errors.add(:participatory_space_manifests, :invalid)
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # Represents the association between a taxonomy and a filterable entity within the system.
5
+ class TaxonomyFilterItem < ApplicationRecord
6
+ belongs_to :taxonomy_filter,
7
+ class_name: "Decidim::TaxonomyFilter",
8
+ counter_cache: :filter_items_count,
9
+ inverse_of: :filter_items
10
+
11
+ belongs_to :taxonomy_item,
12
+ class_name: "Decidim::Taxonomy",
13
+ counter_cache: :filter_items_count,
14
+ inverse_of: :taxonomy_filter_items
15
+
16
+ validate :taxonomy_item_is_not_root
17
+ validate :taxonomy_item_is_child_of_taxonomy_filter_root
18
+
19
+ private
20
+
21
+ def taxonomy_item_is_not_root
22
+ return unless taxonomy_item&.root?
23
+
24
+ errors.add(:taxonomy_item, :invalid)
25
+ end
26
+
27
+ def taxonomy_item_is_child_of_taxonomy_filter_root
28
+ return if taxonomy_item&.root_taxonomy == taxonomy_filter&.root_taxonomy
29
+
30
+ errors.add(:taxonomy_item, :invalid)
31
+ end
32
+ end
33
+ end
@@ -35,6 +35,7 @@ module Decidim
35
35
  has_many :access_grants, class_name: "Doorkeeper::AccessGrant", foreign_key: :resource_owner_id, dependent: :destroy
36
36
  has_many :access_tokens, class_name: "Doorkeeper::AccessToken", foreign_key: :resource_owner_id, dependent: :destroy
37
37
  has_many :reminders, foreign_key: "decidim_user_id", class_name: "Decidim::Reminder", dependent: :destroy
38
+ has_many :private_exports, class_name: "Decidim::PrivateExport", dependent: :destroy, inverse_of: :attached_to, as: :attached_to
38
39
 
39
40
  validates :name, presence: true, unless: -> { deleted? }
40
41
  validates :nickname,
@@ -45,6 +46,7 @@ module Decidim
45
46
  validates :locale, inclusion: { in: :available_locales }, allow_blank: true
46
47
  validates :tos_agreement, acceptance: true, allow_nil: false, on: :create
47
48
  validates :tos_agreement, acceptance: true, if: :user_invited?
49
+ validates :tos_agreement, acceptance: true, if: :ephemeral?
48
50
  validates :email, :nickname, uniqueness: { scope: :organization }, unless: -> { deleted? || managed? || nickname.blank? }
49
51
 
50
52
  validate :all_roles_are_valid
@@ -59,25 +61,13 @@ module Decidim
59
61
  scope :officialized, -> { where.not(officialized_at: nil) }
60
62
  scope :not_officialized, -> { where(officialized_at: nil) }
61
63
 
62
- scope :interested_in_scopes, lambda { |scope_ids|
63
- actual_ids = scope_ids.select(&:presence)
64
- if actual_ids.count.positive?
65
- ids = actual_ids.map(&:to_i).join(",")
66
- where(Arel.sql("extended_data->'interested_scopes' @> ANY('{#{ids}}')").to_s)
67
- else
68
- # Do not apply the scope filter when there are scope ids available. Note
69
- # that the active record scope must always return an active record
70
- # collection.
71
- self
72
- end
73
- }
74
-
75
64
  scope :org_admins_except_me, ->(user) { where(organization: user.organization, admin: true).where.not(id: user.id) }
76
65
 
66
+ scope :ephemeral, -> { where("extended_data @> ?", Arel.sql({ ephemeral: true }.to_json)) }
67
+
77
68
  attr_accessor :newsletter_notifications
78
69
 
79
70
  searchable_fields({
80
- # scope_id: :decidim_scope_id,
81
71
  organization_id: :decidim_organization_id,
82
72
  A: :name,
83
73
  B: :nickname,
@@ -195,7 +185,7 @@ module Decidim
195
185
  end
196
186
 
197
187
  def tos_accepted?
198
- return true if managed
188
+ return true if managed && !ephemeral?
199
189
  return false if accepted_tos_version.nil?
200
190
 
201
191
  # For some reason, if we do not use `#to_i` here we get some
@@ -217,14 +207,6 @@ module Decidim
217
207
  ImpersonationLog.active.exists?(user: self)
218
208
  end
219
209
 
220
- def interested_scopes_ids
221
- extended_data["interested_scopes"] || []
222
- end
223
-
224
- def interested_scopes
225
- @interested_scopes ||= organization.scopes.where(id: interested_scopes_ids)
226
- end
227
-
228
210
  def user_name
229
211
  extended_data["user_name"] || name
230
212
  end
@@ -278,6 +260,10 @@ module Decidim
278
260
  false
279
261
  end
280
262
 
263
+ def ephemeral?
264
+ extended_data["ephemeral"]
265
+ end
266
+
281
267
  def after_confirmation
282
268
  return unless organization.send_welcome_notification?
283
269
 
@@ -65,6 +65,18 @@ module Decidim
65
65
  Decidim::UserBaseEntity.joins(:follows).where(decidim_follows: { user: self }).blocked.exists?
66
66
  end
67
67
 
68
+ def self.ransackable_attributes(auth_object = nil)
69
+ base = %w(name email nickname last_sign_in_at)
70
+
71
+ return base unless auth_object&.admin?
72
+
73
+ base + %w(invitation_sent_at invitation_accepted_at officialized_at)
74
+ end
75
+
76
+ def self.ransackable_associations(_auth_object = nil)
77
+ []
78
+ end
79
+
68
80
  private
69
81
 
70
82
  def only_public(klass, ids)
@@ -6,6 +6,7 @@ module Decidim
6
6
  include Loggable
7
7
 
8
8
  belongs_to :user, foreign_key: :decidim_user_id, class_name: "Decidim::UserBaseEntity"
9
+ has_one :blocking, through: :user
9
10
  has_many :reports, class_name: "Decidim::UserReport", dependent: :destroy
10
11
 
11
12
  scope :blocked, -> { joins(:user).where(decidim_users: { blocked: true }) }
@@ -16,5 +17,13 @@ module Decidim
16
17
  def self.log_presenter_class_for(_log)
17
18
  Decidim::AdminLog::UserModerationPresenter
18
19
  end
20
+
21
+ def self.ransackable_attributes(_auth_object = nil)
22
+ []
23
+ end
24
+
25
+ def self.ransackable_associations(_auth_object = nil)
26
+ %w(reports user)
27
+ end
19
28
  end
20
29
  end
@@ -19,6 +19,10 @@ module Decidim
19
19
  # Decidim::DownloadYourDataSerializers::DownloadYourDataReportSerializer
20
20
  end
21
21
 
22
+ def self.ransackable_attributes(_auth_object = nil)
23
+ %w(reason)
24
+ end
25
+
22
26
  private
23
27
 
24
28
  # Private: check if the moderation and the user have the same organization
@@ -6,6 +6,7 @@ import "src/decidim/decidim_application"
6
6
 
7
7
  // CSS
8
8
  import "entrypoints/decidim_core.scss"
9
+ import "stylesheets/decidim/resource_history.scss"
9
10
 
10
11
  // Images
11
12
  require.context("../images", true)
@@ -0,0 +1,2 @@
1
+ import "src/decidim/geocoding/reverse_geocoding.js"
2
+ import "stylesheets/decidim/geocoding_addons.scss";
@@ -0,0 +1,10 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g clip-path="url(#clip0_29214_25190)">
3
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M24 12.0707C24 5.40424 18.6274 0 12 0C5.37258 0 0 5.40424 0 12.0707C0 18.0956 4.38823 23.0893 10.125 23.9948V15.5599H7.07812V12.0707H10.125V9.41139C10.125 6.38617 11.9165 4.71513 14.6576 4.71513C15.9705 4.71513 17.3438 4.95088 17.3438 4.95088V7.92141H15.8306C14.3399 7.92141 13.875 8.85187 13.875 9.80645V12.0707H17.2031L16.6711 15.5599H13.875V23.9948C19.6118 23.0893 24 18.0956 24 12.0707Z" fill="white"/>
4
+ </g>
5
+ <defs>
6
+ <clipPath id="clip0_29214_25190">
7
+ <rect width="24" height="24" fill="white"/>
8
+ </clipPath>
9
+ </defs>
10
+ </svg>
@@ -1 +1,7 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="42" height="42" viewBox="2 -2 42 42"><defs><filter id="b" width="2" height="2" x="-.5" y="-.5" filterUnits="objectBoundingBox"><feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1"/><feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation=".5"/><feColorMatrix in="shadowBlurOuter1" result="shadowMatrixOuter1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.168 0"/><feOffset in="SourceAlpha" result="shadowOffsetOuter2"/><feGaussianBlur in="shadowOffsetOuter2" result="shadowBlurOuter2" stdDeviation=".5"/><feColorMatrix in="shadowBlurOuter2" result="shadowMatrixOuter2" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.084 0"/><feMerge><feMergeNode in="shadowMatrixOuter1"/><feMergeNode in="shadowMatrixOuter2"/><feMergeNode in="SourceGraphic"/></feMerge></filter><rect id="a" width="40" height="40" x="0" y="0" rx="2"/></defs><use width="100%" height="100%" fill="#fff" fill-rule="evenodd" filter="url(#b)" transform="translate(3 -1)" xlink:href="#a"/><use width="100%" height="100%" fill="none" fill-rule="evenodd" filter="url(#b)" transform="translate(3 -1)" xlink:href="#a"/><use width="100%" height="100%" fill="none" fill-rule="evenodd" filter="url(#b)" transform="translate(3 -1)" xlink:href="#a"/><use width="100%" height="100%" fill="none" fill-rule="evenodd" filter="url(#b)" transform="translate(3 -1)" xlink:href="#a"/><path fill="#4285f4" fill-rule="evenodd" d="M31.64 19.205c0-.639-.057-1.252-.164-1.841H23v3.481h4.844a4.14 4.14 0 01-1.796 2.716v2.259h2.908c1.702-1.567 2.684-3.875 2.684-6.615z"/><path fill="#34a853" fill-rule="evenodd" d="M23 28c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711h-3.007v2.332A8.997 8.997 0 0023 28z"/><path fill="#fbbc05" fill-rule="evenodd" d="M17.964 20.71a5.41 5.41 0 01-.282-1.71c0-.593.102-1.17.282-1.71v-2.332h-3.007A8.996 8.996 0 0014 19c0 1.452.348 2.827.957 4.042z"/><path fill="#ea4335" fill-rule="evenodd" d="M23 13.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C27.463 10.891 25.426 10 23 10a8.997 8.997 0 00-8.043 4.958l3.007 2.332c.708-2.127 2.692-3.71 5.036-3.71z"/><path fill="none" d="M14 10h18v18H14z"/></svg>
1
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" xmlns:xlink="http://www.w3.org/1999/xlink" style="display: block;">
2
+ <path fill="#EA4335" d="M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z"></path>
3
+ <path fill="#4285F4" d="M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z"></path>
4
+ <path fill="#FBBC05" d="M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z"></path>
5
+ <path fill="#34A853" d="M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z"></path>
6
+ <path fill="none" d="M0 0h48v48H0z"></path>
7
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-twitter-x" viewBox="0 0 16 16">
2
+ <path d="M12.6.75h2.454l-5.36 6.142L16 15.25h-4.937l-3.867-5.07-4.425 5.07H.316l5.733-6.57L0 .75h5.063l3.495 4.633L12.601.75Zm-.86 13.028h1.36L4.323 2.145H2.865z"/>
3
+ </svg>
@@ -53,10 +53,18 @@ $(() => {
53
53
  }
54
54
 
55
55
  $(document).on("click.zf.trigger", (event) => {
56
- const target = `#${$(event.target).data("dialogOpen")}`;
57
- const redirectUrl = $(event.target).data("redirectUrl");
56
+ // Try to get the <a> directly or find the closest parent <a>
57
+ const $target = $(event.target).closest("a");
58
58
 
59
- if (!target || !redirectUrl) {
59
+ // Check if an <a> was found
60
+ if (!$target) {
61
+ return;
62
+ }
63
+
64
+ const dialogTarget = `#${$target.data("dialog-open")}`;
65
+ const redirectUrl = $target.data("redirectUrl");
66
+
67
+ if (!dialogTarget || !redirectUrl) {
60
68
  return;
61
69
  }
62
70
 
@@ -64,10 +72,10 @@ $(() => {
64
72
  attr("id", "redirect_url").
65
73
  attr("name", "redirect_url").
66
74
  attr("value", redirectUrl).
67
- appendTo(`${target} form`);
75
+ appendTo(`${dialogTarget} form`);
68
76
 
69
- $(`${target} a`).attr("href", (index, href) => {
70
- const querystring = jQuery.param({ "redirect_url": redirectUrl });
77
+ $(`${dialogTarget} a`).attr("href", (index, href) => {
78
+ const querystring = jQuery.param({"redirect_url": redirectUrl});
71
79
  return href + (href.match(/\?/) ? "&" : "?") + querystring;
72
80
  });
73
81
  });
@@ -101,7 +101,6 @@ export default class CheckBoxesTree {
101
101
  const indeterminateSiblings = totalCheckSiblings.filter((checkbox) => checkbox.indeterminate)
102
102
 
103
103
  if (checkedSiblings.length === 0 && indeterminateSiblings.length === 0) {
104
- parentCheck.checked = false;
105
104
  parentCheck.indeterminate = false;
106
105
  } else if (checkedSiblings.length === totalCheckSiblings.length && indeterminateSiblings.length === 0) {
107
106
  parentCheck.checked = true;
@@ -21,7 +21,9 @@ import select from "select";
21
21
  *
22
22
  * Options through data attributes:
23
23
  * - `data-clipboard-copy` = The jQuery selector for the target input element
24
- * where text will be copied from.
24
+ * where text will be copied from. If this element does not contain any visible text (for instance is an image),
25
+ * the selector indicated in here will be used to place the confirmation message.
26
+ * - `data-clipboard-content` = The text that will be copied. If empty or not present, the target input element will be used.
25
27
  * - `data-clipboard-copy-label` = The label that will be shown in the button
26
28
  * after a succesful copy.
27
29
  * - `data-clipboard-copy-message` = The text that will be announced to screen
@@ -40,12 +42,17 @@ $(() => {
40
42
  }
41
43
 
42
44
  const $input = $($el.data("clipboard-copy"));
43
- if ($input.length < 1 || !$input.is("input, textarea, select")) {
44
- return;
45
+
46
+ let selectedText = $el.data("clipboard-content") || "";
47
+ if (selectedText === "" && $input.is("input, textarea, select")) {
48
+ selectedText = select($input[0]);
45
49
  }
46
50
 
51
+ let $msgEl = $el;
52
+ if ($msgEl.text() === "") {
53
+ $msgEl = $input;
54
+ }
47
55
  // Get the available text to clipboard.
48
- const selectedText = select($input[0]);
49
56
  if (!selectedText || selectedText.length < 1) {
50
57
  return;
51
58
  }
@@ -83,16 +90,18 @@ $(() => {
83
90
  }
84
91
 
85
92
  if (!$el.data("clipboard-copy-label-original")) {
86
- $el.data("clipboard-copy-label-original", $el.html());
93
+ $el.data("clipboard-copy-label-original", $msgEl.html());
87
94
  }
88
95
 
89
- $el.html(label);
96
+ $msgEl.html(label);
97
+
90
98
  to = setTimeout(() => {
91
- $el.html($el.data("clipboard-copy-label-original"));
99
+ $msgEl.html($el.data("clipboard-copy-label-original"));
92
100
  $el.removeData("clipboard-copy-label-original");
93
101
  $el.removeData("clipboard-copy-label-timeout");
94
102
  }, CLIPBOARD_COPY_TIMEOUT);
95
- $el.data("clipboard-copy-label-timeout", to)
103
+
104
+ $el.data("clipboard-copy-label-timeout", to);
96
105
  }
97
106
 
98
107
  // Alert the screen reader what just happened (the link was copied).
@@ -107,7 +116,7 @@ $(() => {
107
116
  }
108
117
  } else {
109
118
  $msg = $('<div aria-role="alert" aria-live="assertive" aria-atomic="true" class="sr-only"></div>');
110
- $el.after($msg);
119
+ $msgEl.append($msg);
111
120
  $el.data("clipboard-message-element", $msg);
112
121
  }
113
122
 
@@ -5,12 +5,14 @@
5
5
  * it to gain control over the confirm events BEFORE rails-ujs is loaded.
6
6
  */
7
7
 
8
- import Rails from "@rails/ujs"
8
+ const { Rails } = window;
9
9
 
10
10
  class ConfirmDialog {
11
11
  constructor(sourceElement) {
12
12
  this.$modal = $("#confirm-modal");
13
- this.$source = sourceElement;
13
+ if (sourceElement) {
14
+ this.$source = $(sourceElement);
15
+ }
14
16
  this.$content = $("[data-confirm-modal-content]", this.$modal);
15
17
  this.$buttonConfirm = $("[data-confirm-ok]", this.$modal);
16
18
  this.$buttonCancel = $("[data-confirm-cancel]", this.$modal);
@@ -29,22 +31,37 @@ class ConfirmDialog {
29
31
  this.$buttonConfirm.on("click", (ev) => {
30
32
  ev.preventDefault();
31
33
 
32
- window.Decidim.currentDialogs["confirm-modal"].close()
33
- resolve(true);
34
- this.$source.focus();
34
+ this.close(() => resolve(true));
35
35
  });
36
36
 
37
37
  this.$buttonCancel.on("click", (ev) => {
38
38
  ev.preventDefault();
39
39
 
40
- window.Decidim.currentDialogs["confirm-modal"].close()
41
- resolve(false);
42
- this.$source.focus();
40
+ this.close(() => resolve(false));
43
41
  });
44
42
  });
45
43
  }
44
+
45
+ close(afterClose) {
46
+ window.Decidim.currentDialogs["confirm-modal"].close()
47
+ afterClose();
48
+ if (this.$source) {
49
+ this.$source.focus();
50
+ }
51
+ }
46
52
  }
47
53
 
54
+ const runConfirm = (message, sourceElement = null) => new Promise((resolve) => {
55
+ const dialog = new ConfirmDialog(sourceElement);
56
+ dialog.confirm(message).then((answer) => {
57
+ let completed = true;
58
+ if (sourceElement) {
59
+ completed = Rails.fire(sourceElement, "confirm:complete", [answer]);
60
+ }
61
+ resolve(answer && completed);
62
+ });
63
+ });
64
+
48
65
  // Override the default confirm dialog by Rails
49
66
  // See:
50
67
  // https://github.com/rails/rails/blob/fba1064153d8e2f4654df7762a7d3664b93e9fc8/actionview/app/assets/javascripts/rails-ujs/features/confirm.coffee
@@ -64,37 +81,35 @@ const allowAction = (ev, element) => {
64
81
  return false;
65
82
  }
66
83
 
67
- const dialog = new ConfirmDialog(
68
- $(element)
69
- );
70
- dialog.confirm(message).then((answer) => {
71
- const completed = Rails.fire(element, "confirm:complete", [answer]);
72
- if (answer && completed) {
73
- // Allow the event to propagate normally and re-dispatch it without
74
- // the confirm data attribute which the Rails internal method is
75
- // checking.
76
- $(element).data("confirm", null);
77
- $(element).removeAttr("data-confirm");
78
-
79
- // The submit button click events will not do anything if they are
80
- // dispatched as is. In these cases, just submit the underlying form.
81
- if (ev.type === "click" &&
82
- (
83
- $(element).is('button[type="submit"]') ||
84
- $(element).is('input[type="submit"]')
85
- )
86
- ) {
87
- $(element).parents("form").submit();
88
- } else {
89
- let origEv = ev.originalEvent || ev;
90
- let newEv = origEv;
91
- if (typeof Event === "function") {
92
- // Clone the event because otherwise some click events may not
93
- // work properly when re-dispatched.
94
- newEv = new origEv.constructor(origEv.type, origEv);
95
- }
96
- ev.target.dispatchEvent(newEv);
84
+ runConfirm(message, element).then((answer) => {
85
+ if (!answer) {
86
+ return;
87
+ }
88
+
89
+ // Allow the event to propagate normally and re-dispatch it without
90
+ // the confirm data attribute which the Rails internal method is
91
+ // checking.
92
+ $(element).data("confirm", null);
93
+ $(element).removeAttr("data-confirm");
94
+
95
+ // The submit button click events will not do anything if they are
96
+ // dispatched as is. In these cases, just submit the underlying form.
97
+ if (ev.type === "click" &&
98
+ (
99
+ $(element).is('button[type="submit"]') ||
100
+ $(element).is('input[type="submit"]')
101
+ )
102
+ ) {
103
+ $(element).parents("form").submit();
104
+ } else {
105
+ let origEv = ev.originalEvent || ev;
106
+ let newEv = origEv;
107
+ if (typeof Event === "function") {
108
+ // Clone the event because otherwise some click events may not
109
+ // work properly when re-dispatched.
110
+ newEv = new origEv.constructor(origEv.type, origEv);
97
111
  }
112
+ ev.target.dispatchEvent(newEv);
98
113
  }
99
114
  });
100
115
 
@@ -129,26 +144,31 @@ const handleDocumentEvent = (ev, matchSelectors) => {
129
144
  });
130
145
  };
131
146
 
132
- document.addEventListener("click", (ev) => {
133
- return handleDocumentEvent(ev, [
134
- Rails.linkClickSelector,
135
- Rails.buttonClickSelector,
136
- Rails.formInputClickSelector
137
- ]);
138
- });
139
- document.addEventListener("change", (ev) => {
140
- return handleDocumentEvent(ev, [Rails.inputChangeSelector]);
141
- });
142
- document.addEventListener("submit", (ev) => {
143
- return handleDocumentEvent(ev, [Rails.formSubmitSelector]);
144
- });
147
+ // Note that this needs to be run **before** Rails.start()
148
+ export const initializeConfirm = () => {
149
+ document.addEventListener("click", (ev) => {
150
+ return handleDocumentEvent(ev, [
151
+ Rails.linkClickSelector,
152
+ Rails.buttonClickSelector,
153
+ Rails.formInputClickSelector
154
+ ]);
155
+ });
156
+ document.addEventListener("change", (ev) => {
157
+ return handleDocumentEvent(ev, [Rails.inputChangeSelector]);
158
+ });
159
+ document.addEventListener("submit", (ev) => {
160
+ return handleDocumentEvent(ev, [Rails.formSubmitSelector]);
161
+ });
145
162
 
146
- // This is needed for the confirm dialog to work with Foundation Abide.
147
- // Abide registers its own submit click listeners since Foundation 5.6.x
148
- // which will be handled before the document listeners above. This would
149
- // break the custom confirm functionality when used with Foundation Abide.
150
- document.addEventListener("DOMContentLoaded", function() {
151
- $(Rails.formInputClickSelector).on("click.confirm", (ev) => {
152
- handleConfirm(ev, getMatchingEventTarget(ev, Rails.formInputClickSelector));
163
+ // This is needed for the confirm dialog to work with Foundation Abide.
164
+ // Abide registers its own submit click listeners since Foundation 5.6.x
165
+ // which will be handled before the document listeners above. This would
166
+ // break the custom confirm functionality when used with Foundation Abide.
167
+ document.addEventListener("DOMContentLoaded", function() {
168
+ $(Rails.formInputClickSelector).on("click.confirm", (ev) => {
169
+ handleConfirm(ev, getMatchingEventTarget(ev, Rails.formInputClickSelector));
170
+ });
153
171
  });
154
- });
172
+ };
173
+
174
+ export default runConfirm;
@@ -0,0 +1 @@
1
+ // This file is intentionally empty, because is the place for the defidim applications will add their JavaScript code.