decidim-core 0.31.7 → 0.32.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (488) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -13
  3. data/app/cells/decidim/amendable/amend_button_card/show.erb +2 -2
  4. data/app/cells/decidim/amendable/amend_button_card_cell.rb +1 -1
  5. data/app/cells/decidim/author_cell.rb +4 -0
  6. data/app/cells/decidim/card_metadata_cell.rb +1 -1
  7. data/app/cells/decidim/comments_button_cell.rb +1 -9
  8. data/app/cells/decidim/content_blocks/announcement_settings_form/show.erb +5 -0
  9. data/app/cells/decidim/content_blocks/announcement_settings_form_cell.rb +17 -0
  10. data/app/cells/decidim/content_blocks/cta_settings_form/show.erb +1 -1
  11. data/app/cells/decidim/content_blocks/hero_settings_form/show.erb +2 -2
  12. data/app/cells/decidim/content_blocks/highlighted_content_banner_cell.rb +1 -1
  13. data/app/cells/decidim/content_blocks/highlighted_content_banner_settings_form/show.erb +1 -1
  14. data/app/cells/decidim/content_blocks/highlighted_participatory_spaces_cell.rb +1 -1
  15. data/app/cells/decidim/content_blocks/how_to_participate/show.erb +1 -1
  16. data/app/cells/decidim/content_blocks/html_cell.rb +1 -1
  17. data/app/cells/decidim/content_blocks/participatory_space_announcement_cell.rb +1 -3
  18. data/app/cells/decidim/content_blocks/participatory_space_hero_cell.rb +1 -5
  19. data/app/cells/decidim/content_blocks/participatory_space_hero_settings_form/show.erb +1 -1
  20. data/app/cells/decidim/content_blocks/static_page/section_cell.rb +1 -1
  21. data/app/cells/decidim/content_blocks/static_page/section_settings_form/show.erb +1 -3
  22. data/app/cells/decidim/content_blocks/static_page/summary_cell.rb +1 -1
  23. data/app/cells/decidim/content_blocks/static_page/summary_settings_form/show.erb +1 -3
  24. data/app/cells/decidim/content_blocks/static_page/two_pane_section_cell.rb +2 -2
  25. data/app/cells/decidim/content_blocks/static_page/two_pane_section_settings_form/show.erb +2 -4
  26. data/app/cells/decidim/data_consent/category.erb +38 -25
  27. data/app/cells/decidim/footer_topics/show.erb +8 -5
  28. data/app/cells/decidim/{participatory_space_private_user_cell.rb → member_cell.rb} +1 -1
  29. data/app/cells/decidim/onboarding_action_message_cell.rb +1 -0
  30. data/app/cells/decidim/profile/details.erb +1 -1
  31. data/app/cells/decidim/profile_cell.rb +1 -0
  32. data/app/cells/decidim/profile_member_of/show.erb +13 -0
  33. data/app/cells/decidim/profile_member_of_cell.rb +35 -0
  34. data/app/cells/decidim/resource_types_filter/show.erb +2 -2
  35. data/app/cells/decidim/share_widget/qr_code_modal.erb +1 -1
  36. data/app/cells/decidim/tags_cell.rb +1 -1
  37. data/app/cells/decidim/upload_modal_cell.rb +0 -5
  38. data/app/cells/decidim/versions_list/show.erb +25 -0
  39. data/app/commands/decidim/create_follow.rb +3 -5
  40. data/app/commands/decidim/create_user_report.rb +1 -1
  41. data/app/commands/decidim/destroy_account.rb +4 -15
  42. data/app/commands/decidim/gallery_methods.rb +107 -0
  43. data/app/commands/decidim/multiple_attachments_methods.rb +27 -28
  44. data/app/commands/decidim/search.rb +5 -5
  45. data/app/controllers/concerns/decidim/ajax_permission_handler.rb +1 -1
  46. data/app/controllers/concerns/decidim/devise_controllers.rb +0 -10
  47. data/app/controllers/concerns/decidim/direct_upload.rb +3 -2
  48. data/app/controllers/concerns/decidim/ephemeral_session_checker.rb +1 -1
  49. data/app/controllers/concerns/decidim/force_authentication.rb +10 -1
  50. data/app/controllers/concerns/decidim/impersonate_users.rb +4 -0
  51. data/app/controllers/concerns/decidim/locale_switcher.rb +52 -2
  52. data/app/controllers/concerns/decidim/needs_tos_accepted.rb +1 -1
  53. data/app/controllers/concerns/decidim/participatory_space/has_members_page.rb +27 -0
  54. data/app/controllers/concerns/decidim/participatory_space_context.rb +1 -5
  55. data/app/controllers/decidim/account_controller.rb +1 -1
  56. data/app/controllers/decidim/amendments_controller.rb +5 -4
  57. data/app/controllers/decidim/components/base_controller.rb +20 -3
  58. data/app/controllers/decidim/devise/omniauth_registrations_controller.rb +1 -1
  59. data/app/controllers/decidim/devise/passwords_controller.rb +1 -1
  60. data/app/controllers/decidim/devise/registrations_controller.rb +1 -1
  61. data/app/controllers/decidim/devise/sessions_controller.rb +1 -1
  62. data/app/controllers/decidim/download_your_data_controller.rb +2 -2
  63. data/app/controllers/decidim/editor_images_controller.rb +1 -1
  64. data/app/controllers/decidim/follows_controller.rb +4 -3
  65. data/app/controllers/decidim/geolocation_controller.rb +1 -1
  66. data/app/controllers/decidim/likes_controller.rb +2 -1
  67. data/app/controllers/decidim/locales_controller.rb +3 -11
  68. data/app/controllers/decidim/messaging/conversations_controller.rb +3 -3
  69. data/app/controllers/decidim/newsletters_controller.rb +1 -1
  70. data/app/controllers/decidim/notifications_settings_controller.rb +1 -1
  71. data/app/controllers/decidim/notifications_subscriptions_controller.rb +0 -8
  72. data/app/controllers/decidim/open_data_controller.rb +1 -1
  73. data/app/controllers/decidim/report_users_controller.rb +2 -2
  74. data/app/controllers/decidim/reports_controller.rb +1 -1
  75. data/app/controllers/decidim/user_activities_controller.rb +1 -2
  76. data/app/events/decidim/amendable/amendment_base_event.rb +1 -7
  77. data/app/events/decidim/welcome_notification_event.rb +1 -1
  78. data/app/forms/decidim/upload_validation_form.rb +1 -1
  79. data/app/helpers/concerns/decidim/flash_helper_extensions.rb +1 -0
  80. data/app/helpers/decidim/active_link_to_helper.rb +136 -0
  81. data/app/helpers/decidim/amendments_helper.rb +3 -3
  82. data/app/helpers/decidim/check_boxes_tree_helper.rb +2 -2
  83. data/app/helpers/decidim/component_path_helper.rb +9 -4
  84. data/app/helpers/decidim/filters_helper.rb +0 -2
  85. data/app/helpers/decidim/menu_helper.rb +5 -3
  86. data/app/helpers/decidim/meta_tags_helper.rb +0 -2
  87. data/app/helpers/decidim/paginate_helper.rb +14 -1
  88. data/app/helpers/decidim/sanitize_helper.rb +1 -0
  89. data/app/helpers/decidim/short_link_helper.rb +5 -5
  90. data/app/helpers/decidim/translations_helper.rb +4 -4
  91. data/app/jobs/decidim/delete_inactive_participants_job.rb +2 -2
  92. data/app/jobs/decidim/process_inactive_participant_job.rb +7 -0
  93. data/app/mailers/decidim/application_mailer.rb +7 -2
  94. data/app/mailers/decidim/decidim_devise_mailer.rb +1 -0
  95. data/app/mailers/decidim/participants_account_mailer.rb +16 -0
  96. data/app/mailers/decidim/reported_mailer.rb +4 -1
  97. data/app/models/decidim/action_log.rb +1 -1
  98. data/app/models/decidim/attachment.rb +2 -20
  99. data/app/models/decidim/authorization.rb +0 -7
  100. data/app/models/decidim/authorization_transfer.rb +1 -1
  101. data/app/models/decidim/component.rb +6 -9
  102. data/app/models/decidim/content_block.rb +3 -3
  103. data/app/models/decidim/moderation.rb +1 -1
  104. data/app/models/decidim/newsletter.rb +2 -2
  105. data/app/models/decidim/participatory_space/member.rb +55 -0
  106. data/app/models/decidim/private_export.rb +0 -6
  107. data/app/models/decidim/resource_link.rb +1 -1
  108. data/app/models/decidim/short_link.rb +1 -1
  109. data/app/models/decidim/user.rb +2 -2
  110. data/app/models/decidim/user_base_entity.rb +2 -17
  111. data/app/models/decidim/user_moderation.rb +1 -1
  112. data/app/packs/src/decidim/controllers/accordion/accordion.test.js +42 -196
  113. data/app/packs/src/decidim/controllers/accordion/controller.js +17 -93
  114. data/app/packs/src/decidim/controllers/assign_role/assign_role.test.js +80 -0
  115. data/app/packs/src/decidim/controllers/assign_role/controller.js +27 -0
  116. data/app/packs/src/decidim/controllers/dropdown/controller.js +0 -6
  117. data/app/packs/src/decidim/controllers/dropdown/dropdown.test.js +0 -28
  118. data/app/packs/src/decidim/controllers/form_validator/form_validator.js +6 -6
  119. data/app/packs/src/decidim/controllers/form_validator/form_validator.test.js +1 -23
  120. data/app/packs/src/decidim/controllers/main_menu/controller.js +115 -0
  121. data/app/packs/src/decidim/controllers/main_menu/main_menu.test.js +185 -0
  122. data/app/packs/src/decidim/controllers/mention/controller.js +140 -296
  123. data/app/packs/src/decidim/controllers/mention/input_mentions.test.js +457 -120
  124. data/app/packs/src/decidim/controllers/multiple_mentions/controller.js +32 -68
  125. data/app/packs/src/decidim/controllers/multiple_mentions/input_multiple_mentions.test.js +23 -30
  126. data/app/packs/src/decidim/controllers/password_toggler/controller.js +1 -22
  127. data/app/packs/src/decidim/controllers/password_toggler/password_toggler.test.js +20 -11
  128. data/app/packs/src/decidim/datepicker/generate_datepicker.js +1 -13
  129. data/app/packs/src/decidim/direct_uploads/upload_field.js +4 -4
  130. data/app/packs/src/decidim/direct_uploads/upload_modal.js +7 -12
  131. data/app/packs/src/decidim/editor/common/suggestion.js +1 -1
  132. data/app/packs/src/decidim/editor/extensions/decidim_kit/index.js +4 -1
  133. data/app/packs/src/decidim/editor/extensions/image/index.js +8 -5
  134. data/app/packs/src/decidim/editor/extensions/link/index.js +8 -0
  135. data/app/packs/src/decidim/editor/extensions/mention/index.js +18 -5
  136. data/app/packs/src/decidim/editor/extensions/mention_resource/index.js +16 -7
  137. data/app/packs/src/decidim/editor/test/extensions/decidim_kit.test.js +13 -4
  138. data/app/packs/src/decidim/editor/test/extensions/heading.test.js +1 -1
  139. data/app/packs/src/decidim/editor/test/extensions/image.test.js +26 -28
  140. data/app/packs/src/decidim/editor/test/extensions/mention.test.js +6 -2
  141. data/app/packs/src/decidim/editor/test/extensions/video_embed.test.js +27 -15
  142. data/app/packs/src/decidim/editor/test/helpers.js +8 -10
  143. data/app/packs/src/decidim/editor/test/toolbar/full.test.js +15 -4
  144. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_block.js +8 -4
  145. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_formatting.js +5 -1
  146. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_indent.js +9 -5
  147. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_link.js +5 -1
  148. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_list.js +8 -4
  149. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_styling.js +13 -9
  150. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_content_styling.js +6 -2
  151. data/app/packs/src/decidim/geocoding/reverse_geocoding.js +5 -15
  152. data/app/packs/src/decidim/index.js +3 -5
  153. data/app/packs/src/decidim/map/controller.js +1 -10
  154. data/app/packs/src/decidim/refactor/moved/focus_guard.js +12 -12
  155. data/app/packs/src/decidim/sw/push-permissions.js +13 -48
  156. data/app/packs/src/decidim/sw/sw.js +1 -1
  157. data/app/packs/src/decidim/utilities/text.js +6 -6
  158. data/app/packs/src/decidim/vendor/tribute.js +1890 -0
  159. data/app/packs/stylesheets/decidim/_cards.scss +3 -2
  160. data/app/packs/stylesheets/decidim/_conversations.scss +0 -14
  161. data/app/packs/stylesheets/decidim/_cookies.scss +5 -13
  162. data/app/packs/stylesheets/decidim/_datepicker.scss +0 -8
  163. data/app/packs/stylesheets/decidim/_documents.scss +1 -1
  164. data/app/packs/stylesheets/decidim/_dropdown.scss +21 -31
  165. data/app/packs/stylesheets/decidim/_floating_help.scss +1 -1
  166. data/app/packs/stylesheets/decidim/_footer.scss +1 -69
  167. data/app/packs/stylesheets/decidim/_forms.scss +5 -1
  168. data/app/packs/stylesheets/decidim/_header.scss +148 -46
  169. data/app/packs/stylesheets/decidim/_language_chooser.scss +79 -0
  170. data/app/packs/stylesheets/decidim/_participatory_spaces.scss +1 -1
  171. data/app/packs/stylesheets/decidim/_tribute.scss +36 -0
  172. data/app/packs/stylesheets/decidim/application.scss +1 -2
  173. data/app/packs/stylesheets/decidim/editor.scss +33 -2
  174. data/app/packs/stylesheets/decidim/geocoding_addons.scss +2 -10
  175. data/app/presenters/decidim/admin_log/participatory_space/member_presenter.rb +40 -0
  176. data/app/presenters/decidim/admin_log/static_page_resource_presenter.rb +1 -1
  177. data/app/presenters/decidim/authorization_transfer_presenter.rb +1 -1
  178. data/app/presenters/decidim/breadcrumb_root_menu_item_presenter.rb +3 -3
  179. data/app/presenters/decidim/footer_menu_presenter.rb +4 -2
  180. data/app/presenters/decidim/log/user_presenter.rb +1 -0
  181. data/app/presenters/decidim/log/value_types/access_mode_presenter.rb +45 -0
  182. data/app/presenters/decidim/menu_item_presenter.rb +3 -9
  183. data/app/presenters/decidim/participatory_space/member_presenter.rb +48 -0
  184. data/app/presenters/decidim/resource_locator_presenter.rb +22 -3
  185. data/app/presenters/decidim/stats_presenter.rb +1 -1
  186. data/app/queries/decidim/last_activity.rb +1 -1
  187. data/app/resolvers/decidim/meta_image_url_resolver.rb +0 -7
  188. data/app/serializers/decidim/exporters/participatory_space_serializer.rb +15 -1
  189. data/app/services/decidim/email_notification_generator.rb +2 -0
  190. data/app/services/decidim/notification_generator.rb +4 -0
  191. data/app/services/decidim/notifications_subscriptions_persistor.rb +0 -6
  192. data/app/services/decidim/send_push_notification.rb +1 -5
  193. data/app/uploaders/decidim/image_uploader.rb +1 -1
  194. data/app/uploaders/decidim/organization_favicon_uploader.rb +4 -9
  195. data/app/validators/uploader_image_dimensions_validator.rb +13 -11
  196. data/app/views/decidim/gamification/badges/index.html.erb +1 -1
  197. data/app/views/decidim/homepage/show.html.erb +2 -2
  198. data/app/views/decidim/last_activities/index.html.erb +1 -1
  199. data/app/views/decidim/messaging/conversations/_error_modal.html.erb +19 -11
  200. data/app/views/decidim/messaging/conversations/_new_conversation_button.html.erb +1 -1
  201. data/app/views/decidim/messaging/conversations/_reply.html.erb +1 -1
  202. data/app/views/decidim/messaging/conversations/error.js.erb +7 -12
  203. data/app/views/decidim/messaging/conversations/new.html.erb +1 -1
  204. data/app/views/decidim/messaging/conversations/show.html.erb +2 -2
  205. data/app/views/decidim/newsletters/unsubscribe.html.erb +1 -1
  206. data/app/views/decidim/notifications_settings/show.html.erb +5 -5
  207. data/app/views/decidim/offline/show.html.erb +1 -1
  208. data/app/views/decidim/pages/index.html.erb +1 -1
  209. data/app/views/decidim/participants_account_mailer/removal_notification.html.erb +11 -0
  210. data/app/views/decidim/participatory_space/members/_member.html.erb +1 -0
  211. data/app/views/decidim/profiles/show.html.erb +1 -1
  212. data/app/views/decidim/searches/_filters.html.erb +1 -1
  213. data/app/views/decidim/shared/_resource_actions.html.erb +4 -4
  214. data/app/views/decidim/shared/_results_per_page.html.erb +1 -1
  215. data/app/views/decidim/shared/filters/_check_boxes_tree.html.erb +1 -1
  216. data/app/views/decidim/shared/filters/_dropdown_label.html.erb +4 -3
  217. data/app/views/decidim/user_activities/index.html.erb +1 -1
  218. data/app/views/devise/mailer/{invite_private_user.html.erb → invite_member.html.erb} +2 -2
  219. data/app/views/devise/mailer/{invite_private_user.text.erb → invite_member.text.erb} +2 -2
  220. data/app/views/layouts/decidim/_head.html.erb +2 -2
  221. data/app/views/layouts/decidim/_wrapper.html.erb +3 -3
  222. data/app/views/layouts/decidim/footer/_focus_mode_main.html.erb +0 -1
  223. data/app/views/layouts/decidim/footer/_main.html.erb +1 -2
  224. data/app/views/layouts/decidim/footer/_main_links.html.erb +28 -56
  225. data/app/views/layouts/decidim/header/_focus_mode_back_button.html.erb +4 -1
  226. data/app/views/layouts/decidim/header/_main.html.erb +17 -8
  227. data/app/views/layouts/decidim/header/_main_language_chooser.html.erb +24 -0
  228. data/app/views/layouts/decidim/header/_main_links_desktop.html.erb +56 -56
  229. data/app/views/layouts/decidim/header/_main_links_mobile_account.html.erb +2 -2
  230. data/app/views/layouts/decidim/header/_main_links_mobile_item_account.html.erb +3 -1
  231. data/app/views/layouts/decidim/header/_main_menu_mobile.html.erb +18 -5
  232. data/app/views/layouts/decidim/header/_main_search.html.erb +3 -3
  233. data/app/views/layouts/decidim/header/_menu.html.erb +5 -5
  234. data/app/views/layouts/decidim/header/_menu_breadcrumb_desktop.html.erb +13 -12
  235. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile.html.erb +28 -0
  236. data/app/views/layouts/decidim/shared/_layout_center.html.erb +1 -1
  237. data/app/views/layouts/decidim/shared/_layout_item.html.erb +1 -1
  238. data/app/views/layouts/decidim/shared/_layout_two_col.html.erb +1 -1
  239. data/config/initializers/invisible_captcha.rb +1 -0
  240. data/config/locales/ar.yml +29 -12
  241. data/config/locales/bg.yml +31 -14
  242. data/config/locales/bs-BA.yml +0 -1
  243. data/config/locales/ca-IT.yml +68 -60
  244. data/config/locales/ca.yml +68 -60
  245. data/config/locales/cs.yml +56 -37
  246. data/config/locales/da.yml +0 -1
  247. data/config/locales/de.yml +58 -27
  248. data/config/locales/el.yml +26 -9
  249. data/config/locales/en.yml +64 -55
  250. data/config/locales/eo.yml +0 -1
  251. data/config/locales/es-MX.yml +67 -59
  252. data/config/locales/es-PY.yml +67 -59
  253. data/config/locales/es.yml +67 -59
  254. data/config/locales/et.yml +0 -1
  255. data/config/locales/eu.yml +104 -94
  256. data/config/locales/fa-IR.yml +0 -1
  257. data/config/locales/fi-plain.yml +63 -60
  258. data/config/locales/fi.yml +65 -62
  259. data/config/locales/fr-CA.yml +63 -39
  260. data/config/locales/fr.yml +63 -39
  261. data/config/locales/ga-IE.yml +3 -2
  262. data/config/locales/gl.yml +26 -9
  263. data/config/locales/gn-PY.yml +0 -1
  264. data/config/locales/hr.yml +0 -1
  265. data/config/locales/hu.yml +26 -12
  266. data/config/locales/id-ID.yml +25 -9
  267. data/config/locales/is-IS.yml +7 -2
  268. data/config/locales/it.yml +24 -23
  269. data/config/locales/ja.yml +65 -75
  270. data/config/locales/ka-GE.yml +0 -1
  271. data/config/locales/kaa.yml +0 -1
  272. data/config/locales/ko.yml +0 -1
  273. data/config/locales/lb.yml +27 -10
  274. data/config/locales/lt.yml +28 -12
  275. data/config/locales/lv.yml +25 -9
  276. data/config/locales/mt.yml +0 -1
  277. data/config/locales/nl.yml +27 -10
  278. data/config/locales/no.yml +27 -10
  279. data/config/locales/oc-FR.yml +0 -1
  280. data/config/locales/pl.yml +33 -18
  281. data/config/locales/pt-BR.yml +61 -26
  282. data/config/locales/pt.yml +27 -10
  283. data/config/locales/ro-RO.yml +43 -21
  284. data/config/locales/ru.yml +8 -7
  285. data/config/locales/sk.yml +25 -1409
  286. data/config/locales/sl.yml +0 -1
  287. data/config/locales/sr-CS.yml +0 -1
  288. data/config/locales/sv.yml +72 -30
  289. data/config/locales/tr-TR.yml +28 -10
  290. data/config/locales/uk.yml +6 -4
  291. data/config/locales/vi.yml +0 -1
  292. data/config/locales/zh-CN.yml +25 -9
  293. data/config/locales/zh-TW.yml +28 -10
  294. data/config/routes.rb +138 -77
  295. data/db/data/20251213075429_rename_members_in_action_log.rb +22 -0
  296. data/db/data/20260319145808_rename_send_to_members_in_newsletter.rb +27 -0
  297. data/db/migrate/20200730142511_add_file_upload_settings_to_decidim_organizations.rb +13 -15
  298. data/db/migrate/20250217192438_convert_user_groups_into_users.rb +2 -3
  299. data/db/migrate/20250523104311_move_cta_to_hero_content_block.rb +1 -1
  300. data/db/migrate/20250527122040_move_highlighted_content_banner_settings_to_content_block.rb +1 -1
  301. data/db/migrate/20250819110800_convert_private_exports_id_to_uuid.rb +2 -2
  302. data/db/migrate/20251112132305_remove_legacy_images_from_core_module.rb +27 -0
  303. data/db/migrate/20251205122428_rename_participatory_space_private_users_to_members.rb +9 -0
  304. data/db/migrate/20251216185133_rename_privatable_to_to_participatory_space_in_members.rb +10 -0
  305. data/db/migrate/20260208201405_remove_user_group_core.rb +21 -0
  306. data/db/migrate/20260208201406_remove_user_group_memberships.rb +30 -0
  307. data/db/migrate/20260208201407_remove_user_group_organizations.rb +11 -0
  308. data/db/migrate/20260217152425_remove_enable_participatory_space_filters_from_decidim_organizations.rb +7 -0
  309. data/db/migrate/20260314081619_add_index_on_decidim_members.rb +25 -0
  310. data/decidim-core.gemspec +25 -31
  311. data/lib/decidim/acts_as_tree.rb +12 -12
  312. data/lib/decidim/admin_filters_registry.rb +1 -1
  313. data/lib/decidim/amendable.rb +5 -1
  314. data/lib/decidim/api/functions/category_list.rb +1 -0
  315. data/lib/decidim/api/functions/component_finder_base.rb +1 -1
  316. data/lib/decidim/api/functions/component_list.rb +3 -1
  317. data/lib/decidim/api/functions/component_list_base.rb +1 -0
  318. data/lib/decidim/api/functions/participatory_space_finder_base.rb +1 -1
  319. data/lib/decidim/api/functions/participatory_space_list_base.rb +1 -0
  320. data/lib/decidim/api/functions/user_entity_list.rb +0 -3
  321. data/lib/decidim/api/interfaces/amendable_entity_interface.rb +1 -0
  322. data/lib/decidim/api/interfaces/amendable_interface.rb +1 -0
  323. data/lib/decidim/api/interfaces/attachable_collection_interface.rb +1 -0
  324. data/lib/decidim/api/interfaces/attachable_interface.rb +1 -0
  325. data/lib/decidim/api/interfaces/author_interface.rb +2 -1
  326. data/lib/decidim/api/interfaces/authorable_interface.rb +1 -0
  327. data/lib/decidim/api/interfaces/categories_container_interface.rb +1 -0
  328. data/lib/decidim/api/interfaces/categorizable_interface.rb +1 -0
  329. data/lib/decidim/api/interfaces/coauthorable_interface.rb +1 -0
  330. data/lib/decidim/api/interfaces/component_interface.rb +9 -8
  331. data/lib/decidim/api/interfaces/fingerprint_interface.rb +1 -0
  332. data/lib/decidim/api/interfaces/followable_interface.rb +2 -0
  333. data/lib/decidim/api/interfaces/likeable_interface.rb +2 -2
  334. data/lib/decidim/api/interfaces/localizable_interface.rb +1 -0
  335. data/lib/decidim/api/interfaces/participatory_space_interface.rb +1 -0
  336. data/lib/decidim/api/interfaces/referable_interface.rb +1 -0
  337. data/lib/decidim/api/interfaces/scopable_interface.rb +1 -0
  338. data/lib/decidim/api/interfaces/taxonomizable_interface.rb +1 -0
  339. data/lib/decidim/api/interfaces/timestamps_interface.rb +1 -0
  340. data/lib/decidim/api/interfaces/traceable_interface.rb +1 -0
  341. data/lib/decidim/api/types/attachment_collection_type.rb +5 -3
  342. data/lib/decidim/api/types/attachment_type.rb +11 -4
  343. data/lib/decidim/api/types/badge_score_type.rb +28 -0
  344. data/lib/decidim/api/types/moderation_type.rb +25 -0
  345. data/lib/decidim/api/types/participant_details_type.rb +17 -0
  346. data/lib/decidim/api/types/reportable_type.rb +18 -0
  347. data/lib/decidim/api/types/reportable_user_type.rb +17 -0
  348. data/lib/decidim/api/types/static_page_topic_type.rb +16 -0
  349. data/lib/decidim/api/types/static_page_type.rb +22 -0
  350. data/lib/decidim/api/types/taxonomy_type.rb +2 -0
  351. data/lib/decidim/api/types/user_moderation_type.rb +36 -0
  352. data/lib/decidim/api/types/user_type.rb +13 -0
  353. data/lib/decidim/asset_router/pipeline.rb +1 -1
  354. data/lib/decidim/asset_router/storage.rb +9 -9
  355. data/lib/decidim/assets/tailwind/tailwind.config.js.erb +3 -0
  356. data/lib/decidim/attachment_attributes.rb +9 -58
  357. data/lib/decidim/attribute_encryptor.rb +51 -10
  358. data/lib/decidim/attribute_object/model.rb +0 -5
  359. data/lib/decidim/block_registry.rb +1 -1
  360. data/lib/decidim/coauthorable.rb +2 -1
  361. data/lib/decidim/command.rb +2 -1
  362. data/lib/decidim/content_processor.rb +1 -1
  363. data/lib/decidim/content_renderers/base_renderer.rb +0 -112
  364. data/lib/decidim/content_renderers/blob_renderer.rb +7 -4
  365. data/lib/decidim/content_renderers/mention_resource_renderer.rb +6 -10
  366. data/lib/decidim/content_renderers/resource_renderer.rb +7 -16
  367. data/lib/decidim/content_renderers/user_renderer.rb +9 -11
  368. data/lib/decidim/core/api.rb +8 -0
  369. data/lib/decidim/core/content_blocks/registry_manager.rb +4 -10
  370. data/lib/decidim/core/engine.rb +2 -42
  371. data/lib/decidim/core/menu.rb +0 -26
  372. data/lib/decidim/core/test/factories.rb +29 -21
  373. data/lib/decidim/core/test/shared_examples/access_mode_restricted_participatory_spaces.rb +172 -0
  374. data/lib/decidim/core/test/shared_examples/access_mode_transparent_participatory_spaces.rb +241 -0
  375. data/lib/decidim/core/test/shared_examples/admin_resource_gallery_examples.rb +10 -10
  376. data/lib/decidim/core/test/shared_examples/amendable/amendment_event_examples.rb +2 -2
  377. data/lib/decidim/core/test/shared_examples/amendable/amendment_promoted_event_examples.rb +3 -3
  378. data/lib/decidim/core/test/shared_examples/comments_examples.rb +121 -143
  379. data/lib/decidim/core/test/shared_examples/fingerprint_examples.rb +2 -0
  380. data/lib/decidim/core/test/shared_examples/has_members.rb +63 -0
  381. data/lib/decidim/core/test/shared_examples/has_space_in_mcell_examples.rb +1 -2
  382. data/lib/decidim/core/test/shared_examples/manage_share_tokens_examples.rb +1 -1
  383. data/lib/decidim/core/test/shared_examples/map_examples.rb +1 -1
  384. data/lib/decidim/core/test/shared_examples/participant_details_examples.rb +16 -0
  385. data/lib/decidim/core/test/shared_examples/participatory_space_members_page_examples.rb +10 -10
  386. data/lib/decidim/core/test/shared_examples/resource_liked_event_examples.rb +3 -3
  387. data/lib/decidim/core/test/shared_examples/resource_locator_presenter_examples.rb +7 -7
  388. data/lib/decidim/core/test/shared_examples/searchable_participatory_space_examples.rb +3 -3
  389. data/lib/decidim/core/test/shared_examples/searchable_results_examples.rb +2 -2
  390. data/lib/decidim/core/test/shared_examples/simple_event.rb +1 -0
  391. data/lib/decidim/core/test/shared_examples/translated_event_examples.rb +2 -2
  392. data/lib/decidim/core/test/shared_examples/versions_controller_examples.rb +1 -1
  393. data/lib/decidim/core/test.rb +2 -1
  394. data/lib/decidim/core/version.rb +1 -1
  395. data/lib/decidim/core.rb +222 -335
  396. data/lib/decidim/download_your_data_serializers/{download_your_data_participatory_space_private_user_serializer.rb → download_your_data_member_serializer.rb} +6 -6
  397. data/lib/decidim/download_your_data_serializers.rb +2 -2
  398. data/lib/decidim/engine_router.rb +31 -6
  399. data/lib/decidim/exporters/csv.rb +1 -1
  400. data/lib/decidim/filter_form_builder.rb +1 -1
  401. data/{app/controllers/concerns → lib}/decidim/form_factory.rb +11 -1
  402. data/lib/decidim/has_settings.rb +2 -2
  403. data/lib/decidim/legacy_form_builder.rb +1 -0
  404. data/lib/decidim/locale_router_detector.rb +41 -0
  405. data/lib/decidim/maintenance/import_models/scope.rb +1 -1
  406. data/lib/decidim/maintenance/import_models.rb +0 -2
  407. data/lib/decidim/map/autocomplete.rb +3 -4
  408. data/lib/decidim/map/dynamic_map.rb +1 -3
  409. data/lib/decidim/map/frontend.rb +1 -1
  410. data/lib/decidim/map/geocoding.rb +2 -2
  411. data/lib/decidim/map/static_map.rb +10 -22
  412. data/lib/decidim/map/utility.rb +3 -6
  413. data/lib/decidim/map.rb +2 -2
  414. data/lib/decidim/menu.rb +1 -1
  415. data/lib/decidim/menu_item.rb +1 -0
  416. data/lib/decidim/menu_registry.rb +1 -1
  417. data/lib/decidim/moderation_tools.rb +1 -1
  418. data/lib/decidim/newsletter_encryptor.rb +5 -8
  419. data/lib/decidim/organization_settings.rb +2 -2
  420. data/lib/decidim/participable.rb +1 -0
  421. data/lib/decidim/participatory_space/has_members.rb +61 -0
  422. data/lib/decidim/participatory_space_manifest.rb +0 -4
  423. data/lib/decidim/participatory_space_resourceable.rb +10 -1
  424. data/lib/decidim/routes/locale_redirects.rb +47 -0
  425. data/lib/decidim/routes.rb +7 -0
  426. data/lib/decidim/search_resource_fields_mapper.rb +3 -4
  427. data/lib/decidim/searchable.rb +0 -5
  428. data/lib/decidim/seeds.rb +17 -0
  429. data/lib/decidim/shakapacker/runner.rb +4 -4
  430. data/lib/decidim/shakapacker/shakapacker.yml +28 -3
  431. data/lib/decidim/taxonomizable.rb +1 -1
  432. data/lib/decidim/translatable_attributes.rb +9 -3
  433. data/lib/decidim/view_model.rb +5 -1
  434. data/lib/devise/models/decidim_newsletterable.rb +1 -1
  435. data/lib/tasks/decidim_mailers_tasks.rake +9 -31
  436. data/lib/tasks/decidim_procfile.rake +1 -1
  437. data/lib/tasks/decidim_tasks.rake +0 -1
  438. data/lib/tasks/decidim_taxonomies.rake +1 -1
  439. data/lib/tasks/upgrade/decidim_active_storage_migration_tasks.rake +0 -1
  440. data/lib/tasks/upgrade/decidim_encryption.rake +12 -0
  441. data/lib/tasks/upgrade/decidim_migrate_wysiwyg_content.rake +0 -1
  442. data/lib/tasks/upgrade/decidim_remove_deleted_users_left_data_tasks.rake +1 -1
  443. data/lib/tasks/upgrade/{fix_deleted_private_follows.rake → fix_deleted_members_follows.rake} +5 -5
  444. data/lib/tasks/upgrade/migrations.rake +0 -1
  445. data/lib/tasks/upgrade/user_groups_migration.rake +0 -1
  446. metadata +206 -155
  447. data/app/cells/decidim/content_blocks/global_menu/show.erb +0 -11
  448. data/app/cells/decidim/content_blocks/global_menu_cell.rb +0 -35
  449. data/app/cells/decidim/content_blocks/menu_breadcrumb_last_activity/show.erb +0 -10
  450. data/app/cells/decidim/content_blocks/menu_breadcrumb_last_activity_cell.rb +0 -49
  451. data/app/cells/decidim/participatory_space_dropdown_metadata/links.erb +0 -9
  452. data/app/cells/decidim/participatory_space_dropdown_metadata/metadata.erb +0 -1
  453. data/app/cells/decidim/participatory_space_dropdown_metadata/show.erb +0 -11
  454. data/app/cells/decidim/participatory_space_dropdown_metadata_cell.rb +0 -26
  455. data/app/controllers/concerns/decidim/has_members_page.rb +0 -25
  456. data/app/controllers/decidim/private_downloads_controller.rb +0 -29
  457. data/app/jobs/decidim/newsletters_opt_in_job.rb +0 -11
  458. data/app/jobs/decidim/user_report_job.rb +0 -11
  459. data/app/mailers/decidim/delete_user_mailer.rb +0 -14
  460. data/app/models/decidim/participatory_space_private_user.rb +0 -51
  461. data/app/models/decidim/private_download.rb +0 -61
  462. data/app/packs/src/decidim/controllers/sticky_header/controller.js +0 -116
  463. data/app/packs/src/decidim/controllers/sticky_header/sticky_header.test.js +0 -320
  464. data/app/packs/src/decidim/dropdown_menu.js +0 -18
  465. data/app/packs/src/decidim/geocoding/reverse_geocoding.test.js +0 -197
  466. data/app/packs/src/decidim/identity_selector_dialog.js +0 -33
  467. data/app/packs/src/decidim/refactor/moved/focus_guard.test.js +0 -136
  468. data/app/packs/stylesheets/decidim/_editor_suggestions.scss +0 -49
  469. data/app/packs/stylesheets/decidim/_tom_select.scss +0 -23
  470. data/app/presenters/decidim/admin_log/participatory_space_private_user_presenter.rb +0 -38
  471. data/app/presenters/decidim/participatory_space_private_user_presenter.rb +0 -46
  472. data/app/services/decidim/push_subscription_endpoint_validator.rb +0 -34
  473. data/app/views/decidim/delete_user_mailer/delete.html.erb +0 -6
  474. data/app/views/decidim/participatory_space_private_users/_participatory_space_private_user.html.erb +0 -1
  475. data/app/views/layouts/decidim/footer/_main_language_chooser.html.erb +0 -26
  476. data/app/views/layouts/decidim/header/_menu_breadcrumb_items.html.erb +0 -34
  477. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_desktop.html.erb +0 -10
  478. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_mobile.html.erb +0 -17
  479. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_top_left.html.erb +0 -2
  480. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile_tablet.html.erb +0 -33
  481. data/app/views/layouts/decidim/header/_mobile_language_choose.html.erb +0 -25
  482. data/lib/decidim/core/test/shared_examples/has_private_users.rb +0 -63
  483. data/lib/decidim/core/test/shared_examples/participatory_space_dropdown_metadata_cell_examples.rb +0 -81
  484. data/lib/decidim/has_private_users.rb +0 -57
  485. data/lib/decidim/maintenance/import_models/assembly_type.rb +0 -49
  486. data/lib/decidim/maintenance/import_models/participatory_process_type.rb +0 -21
  487. data/lib/decidim/query_extensions.rb +0 -64
  488. /data/app/cells/decidim/{participatory_space_private_user → member}/show.erb +0 -0
@@ -15,7 +15,7 @@ module Decidim
15
15
  def call
16
16
  return broadcast(:invalid) unless @form.valid?
17
17
 
18
- with_events(with_transaction: true) do
18
+ Decidim::User.transaction do
19
19
  destroy_user_account!
20
20
  destroy_user_identities
21
21
  destroy_follows
@@ -28,7 +28,7 @@ module Decidim
28
28
  destroy_user_badges
29
29
  destroy_user_likes
30
30
  destroy_user_reports
31
- destroy_participatory_space_private_user
31
+ destroy_member
32
32
  delegate_destroy_to_participatory_spaces
33
33
  end
34
34
 
@@ -101,8 +101,8 @@ module Decidim
101
101
  Decidim::Follow.where(user: current_user).find_each(&:destroy)
102
102
  end
103
103
 
104
- def destroy_participatory_space_private_user
105
- Decidim::ParticipatorySpacePrivateUser.where(user: current_user).find_each(&:destroy)
104
+ def destroy_member
105
+ Decidim::ParticipatorySpace::Member.where(user: current_user).find_each(&:destroy)
106
106
  end
107
107
 
108
108
  def delegate_destroy_to_participatory_spaces
@@ -110,16 +110,5 @@ module Decidim
110
110
  space_manifest.invoke_on_destroy_account(current_user)
111
111
  end
112
112
  end
113
-
114
- # We use memoization in this particular email, as we want to have the data available before the actual anonymization
115
- def event_arguments
116
- @event_arguments ||= {
117
- user_id: current_user.id,
118
- user_email: current_user.email,
119
- user_name: current_user.name,
120
- locale: current_user.locale,
121
- organization: current_user.organization
122
- }
123
- end
124
113
  end
125
114
  end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # A module with all the gallery common methods
5
+ # Allows to create several image attachments at once
6
+ module GalleryMethods
7
+ private
8
+
9
+ def build_gallery(attached_to = nil)
10
+ @gallery = []
11
+ @form.add_photos.compact_blank.each do |photo|
12
+ if photo.is_a?(Hash) && photo.has_key?(:id)
13
+ update_attachment_title_for(photo)
14
+ next
15
+ end
16
+
17
+ @gallery << Attachment.new(
18
+ title: photos_title(photo),
19
+ attached_to: attached_to || gallery_attached_to,
20
+ file: photos_signed_id(photo), # Define attached_to before this
21
+ content_type: photos_content_type(photo)
22
+ )
23
+ end
24
+ end
25
+
26
+ def update_attachment_title_for(photo)
27
+ Decidim::Attachment.find(photo[:id]).update(title: photos_title(photo))
28
+ end
29
+
30
+ def image?(signed_id)
31
+ blob(signed_id).content_type.start_with? "image"
32
+ end
33
+
34
+ def gallery_invalid?
35
+ @gallery.each do |photo|
36
+ if photo.invalid? && photo.errors.has_key?(:file)
37
+ @form.errors.add(:add_photos, photo.errors[:file])
38
+ return true
39
+ end
40
+ end
41
+ false
42
+ end
43
+
44
+ def create_gallery(first_weight: 0)
45
+ weight = first_weight
46
+ # Add the weights first to the old photos
47
+ @form.photos.each do |photo|
48
+ photo.update!(weight:)
49
+ weight += 1
50
+ end
51
+ @gallery.map! do |photo|
52
+ photo.weight = weight
53
+ photo.attached_to = gallery_attached_to
54
+ photo.save!
55
+ weight += 1
56
+ @form.photos << photo
57
+ end
58
+ end
59
+
60
+ def photo_cleanup!
61
+ gallery_attached_to.photos.each do |photo|
62
+ next unless @form.photos.map(&:id).exclude?(photo.id)
63
+
64
+ photo.destroy! if (@form.respond_to?(:documents) && @form.documents.map(&:id).exclude?(photo.id)) || !@form.respond_to?(:documents)
65
+ end
66
+ # manually reset cached photos
67
+ gallery_attached_to.reload
68
+ gallery_attached_to.instance_variable_set(:@photos, nil)
69
+ end
70
+
71
+ # maybe a custom settings options would be nice
72
+ def gallery_allowed?
73
+ true
74
+ end
75
+
76
+ def process_gallery?
77
+ gallery_allowed? && @form.add_photos.any?
78
+ end
79
+
80
+ def gallery_attached_to
81
+ return @attached_to if @attached_to.present?
82
+ return form.current_organization if form.respond_to?(:current_organization)
83
+
84
+ form.current_component.organization if form.respond_to?(:current_component)
85
+ end
86
+
87
+ def photos_signed_id(photo)
88
+ return photo[:file] if photo.is_a?(Hash)
89
+
90
+ photo
91
+ end
92
+
93
+ def photos_title(photo)
94
+ return { I18n.locale => photo[:title] } if photo.is_a?(Hash) && photo.has_key?(:title)
95
+
96
+ { I18n.locale => "" }
97
+ end
98
+
99
+ def photos_content_type(photo)
100
+ blob(photos_signed_id(photo)).content_type
101
+ end
102
+
103
+ def blob(signed_id)
104
+ ActiveStorage::Blob.find_signed(signed_id)
105
+ end
106
+ end
107
+ end
@@ -5,16 +5,16 @@ module Decidim
5
5
  private
6
6
 
7
7
  def build_attachments
8
- @attachments = []
9
- @form.add_attachments.compact_blank.each do |attachment|
8
+ @documents = []
9
+ @form.add_documents.compact_blank.each do |attachment|
10
10
  if attachment.is_a?(Hash) && attachment.has_key?(:id)
11
11
  update_attachment_title_for(attachment)
12
12
  next
13
13
  end
14
14
 
15
- @attachments << Attachment.new(
15
+ @documents << Attachment.new(
16
16
  title: title_for(attachment),
17
- attached_to: @attached_to || attachments_attached_to,
17
+ attached_to: @attached_to || documents_attached_to,
18
18
  file: signed_id_for(attachment),
19
19
  content_type: content_type_for(attachment)
20
20
  )
@@ -26,11 +26,11 @@ module Decidim
26
26
  end
27
27
 
28
28
  def attachments_invalid?
29
- @attachments.each do |attachment|
30
- next if attachment.valid? || !attachment.errors.has_key?(:file)
29
+ @documents.each do |document|
30
+ next if document.valid? || !document.errors.has_key?(:file)
31
31
 
32
- attachment.errors[:file].each do |error|
33
- @form.errors.add(:add_attachments, error)
32
+ document.errors[:file].each do |error|
33
+ @form.errors.add(:add_documents, error)
34
34
  end
35
35
 
36
36
  return true
@@ -41,38 +41,37 @@ module Decidim
41
41
 
42
42
  def create_attachments(first_weight: 0)
43
43
  weight = first_weight
44
- # Add the weights first to the old attachments
45
- attachment_ids = keep_ids
46
- Decidim::Attachment.where(id: attachment_ids).each do |attachment|
47
- attachment.update!(weight:)
44
+ # Add the weights first to the old documents
45
+ document_ids = keep_ids
46
+ Decidim::Attachment.where(id: document_ids).each do |document|
47
+ document.update!(weight:)
48
48
  weight += 1
49
49
  end
50
- @attachments.map! do |attachment|
51
- attachment.weight = weight
52
- attachment.attached_to = attachments_attached_to
53
- attachment.save!
50
+ @documents.map! do |document|
51
+ document.weight = weight
52
+ document.attached_to = documents_attached_to
53
+ document.save!
54
54
  weight += 1
55
- @form.attachments << attachment
55
+ @form.documents << document
56
56
  end
57
57
  end
58
58
 
59
- def attachment_cleanup!(include_all_attachments: false)
60
- attachments = include_all_attachments ? attachments_attached_to.attachments.with_attached_file : attachments_attached_to.attachments
59
+ def document_cleanup!(include_all_attachments: false)
60
+ documents = include_all_attachments ? documents_attached_to.attachments.with_attached_file : documents_attached_to.documents
61
61
 
62
- attachments.each do |attachment|
63
- attachment.destroy! unless keep_ids.include?(attachment.id)
62
+ documents.each do |document|
63
+ document.destroy! unless keep_ids.include?(document.id)
64
64
  end
65
65
 
66
- attachments_attached_to.reload
67
- attachments_attached_to.instance_variable_set(:@attachments, nil)
68
- attachments_attached_to.instance_variable_set(:@photos, nil)
66
+ documents_attached_to.reload
67
+ documents_attached_to.instance_variable_set(:@documents, nil)
69
68
  end
70
69
 
71
70
  def process_attachments?
72
- @form.add_attachments.any?
71
+ @form.add_documents.any?
73
72
  end
74
73
 
75
- def attachments_attached_to
74
+ def documents_attached_to
76
75
  return @attached_to if @attached_to.present?
77
76
  return form.current_organization if form.respond_to?(:current_organization)
78
77
 
@@ -102,8 +101,8 @@ module Decidim
102
101
  end
103
102
 
104
103
  def keep_ids
105
- attachments_array = Array(@form.attachments)
106
- attachments_array.map do |doc|
104
+ documents_array = Array(@form.documents)
105
+ documents_array.map do |doc|
107
106
  case doc
108
107
  when Decidim::Attachment
109
108
  doc.id
@@ -7,10 +7,10 @@ module Decidim
7
7
 
8
8
  # Public: Initializes the command.
9
9
  #
10
- # @param term: The term to search for.
11
- # @param organization: The Organization to which the results are constrained.
12
- # @param filters: (optional) A Hash of SearchableResource attributes to filter for.
13
- # @param page_params: (optional) A Hash with `page` and `per_page` options to paginate.
10
+ # @param term [String] - The term to search for.
11
+ # @param organization [Decidim::Organization] - The Organization to which the results are constrained.
12
+ # @param filters [Hash] - (optional) A Hash of SearchableResource attributes to filter for.
13
+ # @param page_params [Hash] - (optional) A Hash with `page` and `per_page` options to paginate.
14
14
  def initialize(term, organization, filters = {}, page_params = {})
15
15
  @term = term
16
16
  @organization = organization
@@ -91,7 +91,7 @@ module Decidim
91
91
  query = query.where(decidim_participatory_space: spaces)
92
92
  end
93
93
 
94
- query = query.order("datetime DESC")
94
+ query = query.order(datetime: :desc)
95
95
  query = query.global_search(I18n.transliterate(term)) if term.present?
96
96
  query
97
97
  end
@@ -15,7 +15,7 @@ module Decidim
15
15
  def ajax_user_has_no_permission
16
16
  return user_has_no_permission unless request.xhr?
17
17
 
18
- render json: { message: I18n.t("actions.unauthorized", scope: "decidim.core") }, status: :unprocessable_entity
18
+ render json: { message: I18n.t("actions.unauthorized", scope: "decidim.core") }, status: :unprocessable_content
19
19
  end
20
20
  end
21
21
  end
@@ -41,10 +41,6 @@ module Decidim
41
41
 
42
42
  layout "layouts/decidim/application"
43
43
 
44
- # Ensure locale is set before Devise's own prepended callbacks and reset
45
- # after the request finishes.
46
- prepend_around_action :set_current_locale
47
-
48
44
  # Saves the location before loading each page so we can return to the
49
45
  # right page.
50
46
  before_action :store_current_location
@@ -62,12 +58,6 @@ module Decidim
62
58
 
63
59
  store_location_for(:user, redirect_url)
64
60
  end
65
-
66
- def set_current_locale(&)
67
- locale = detect_locale
68
- locale = default_locale unless available_locales.include?(locale)
69
- I18n.with_locale(locale, &)
70
- end
71
61
  end
72
62
  end
73
63
  end
@@ -6,6 +6,7 @@ module Decidim
6
6
 
7
7
  included do
8
8
  include Decidim::NeedsOrganization
9
+
9
10
  skip_before_action :verify_organization
10
11
 
11
12
  before_action :check_organization!,
@@ -18,14 +19,14 @@ module Decidim
18
19
  # We skip the validation if we are in system panel. `current_admin` refers to the main system admin user.
19
20
  return if current_admin.present?
20
21
 
21
- head :unprocessable_entity unless [
22
+ head :unprocessable_content unless [
22
23
  maximum_allowed_size.try(:to_i) >= blob_args[:byte_size].try(:to_i),
23
24
  content_types.any? { |pattern| pattern.match?(blob_args[:content_type]) },
24
25
  content_types.any? { |pattern| pattern.match?(MiniMime.lookup_by_extension(extension)&.content_type) },
25
26
  allowed_extensions.any? { |pattern| pattern.match?(extension) }
26
27
  ].all?
27
28
  rescue NoMethodError
28
- head :unprocessable_entity
29
+ head :unprocessable_content
29
30
  end
30
31
 
31
32
  def extension
@@ -78,7 +78,7 @@ module Decidim
78
78
  end
79
79
  paths_list.prepend(
80
80
  pending_authorizations_path,
81
- decidim.page_path(terms_of_service_page)
81
+ decidim.page_path(terms_of_service_page, locale: current_locale)
82
82
  )
83
83
 
84
84
  paths_list.find { |el| /\A#{URI.parse(el).path}/.match?(request.path) }
@@ -38,12 +38,21 @@ module Decidim
38
38
  default_unauthorized_paths + Decidim::StaticPage.where(
39
39
  organization: current_organization,
40
40
  allow_public_access: true
41
- ).pluck(Arel.sql("CONCAT('/pages/', slug)"))
41
+ ).pluck(
42
+ Arel::Nodes::Concat.new(
43
+ Arel::Nodes.build_quoted("/#{current_locale}/pages/"),
44
+ Arel::Table.new(Decidim::StaticPage.table_name)[:slug]
45
+ )
46
+ )
42
47
  end
43
48
 
44
49
  def default_unauthorized_paths
45
50
  # /locale is for changing the locale and /manifest.webmanifest to request PWA manifest
46
51
  %w(/locale /manifest.webmanifest)
47
52
  end
53
+
54
+ def current_locale
55
+ @current_locale ||= I18n.locale.to_s
56
+ end
48
57
  end
49
58
  end
@@ -71,6 +71,10 @@ module Decidim
71
71
  # Prevent redirect on non-HTML responses, because we want redirect AFTER impersonation.js inits a reload.
72
72
  return if request && request.negotiate_mime([Mime[:html]]).blank?
73
73
  return unless can_impersonate_users?
74
+
75
+ # Keep the expiration check in sync with the active impersonation log so
76
+ # the redirect happens in the same request when the session just expired.
77
+ impersonation_log&.ensure_not_expired!
74
78
  return unless expired_log
75
79
 
76
80
  expired_log.update!(ended_at: Time.current)
@@ -9,7 +9,7 @@ module Decidim
9
9
 
10
10
  included do
11
11
  around_action :switch_locale
12
- helper_method :current_locale, :available_locales, :default_locale
12
+ helper_method :current_locale, :available_locales, :default_locale, :canonical_url
13
13
 
14
14
  # Sets the locale for the current session.
15
15
  # Saves current locale in a session variable in case some links are locale-orphaned
@@ -21,6 +21,7 @@ module Decidim
21
21
  else
22
22
  locale = default_locale
23
23
  end
24
+
24
25
  I18n.with_locale(locale, &)
25
26
  end
26
27
 
@@ -29,7 +30,7 @@ module Decidim
29
30
  #
30
31
  # Returns a Hash.
31
32
  def default_url_options
32
- return {} if current_locale == default_locale.to_s
33
+ return {} if locale_in_script_name?
33
34
 
34
35
  { locale: current_locale }
35
36
  end
@@ -99,6 +100,55 @@ module Decidim
99
100
  end
100
101
  lang == "*" ? nil : lang
101
102
  end
103
+
104
+ def canonical_url(desired_url, target_locale = default_locale)
105
+ uri = URI(desired_url)
106
+ desired_locale = available_locales.include?(target_locale) ? target_locale : default_locale
107
+
108
+ path_segments = uri.path.split("/").compact_blank
109
+ locale_segment = path_segments.first
110
+
111
+ query = uri.query.to_s.gsub(/locale=[a-zA-Z-]{2,5}/, "")
112
+
113
+ if available_locales.include?(locale_segment)
114
+ path_segments[0] = desired_locale
115
+
116
+ uri.path = "/#{path_segments.join("/")}"
117
+
118
+ if query.present?
119
+ params = URI.decode_www_form(query)
120
+ uri.query = URI.encode_www_form(params)
121
+ else
122
+ uri.query = nil
123
+ end
124
+ elsif uri.host.blank? || uri.host == request.host
125
+ uri.path = if uri.path == "/"
126
+ "/#{desired_locale}"
127
+ else
128
+ "/#{desired_locale}#{uri.path}"
129
+ end
130
+
131
+ if query.present?
132
+ params = URI.decode_www_form(query)
133
+ uri.query = URI.encode_www_form(params)
134
+ else
135
+ uri.query = nil
136
+ end
137
+ else
138
+ params = URI.decode_www_form(query) << ["locale", desired_locale]
139
+ uri.query = URI.encode_www_form(params)
140
+ end
141
+
142
+ uri.to_s
143
+ end
144
+
145
+ def locale_in_script_name?
146
+ script_name = request&.script_name.to_s
147
+ return false if script_name.blank?
148
+
149
+ locale_segment = script_name.split("/").compact_blank.first
150
+ available_locales.include?(locale_segment)
151
+ end
102
152
  # rubocop: enable Metrics/CyclomaticComplexity
103
153
  # rubocop: enable Metrics/PerceivedComplexity
104
154
  end
@@ -43,7 +43,7 @@ module Decidim
43
43
  end
44
44
 
45
45
  def tos_path
46
- decidim.page_path terms_of_service_page
46
+ decidim.page_path terms_of_service_page, locale: current_locale
47
47
  end
48
48
 
49
49
  def redirect_to_tos
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ module ParticipatorySpace
7
+ module HasMembersPage
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ helper_method :collection
12
+
13
+ private
14
+
15
+ def can_visit_index?
16
+ current_user_can_visit_space? && current_participatory_space.members_public_page?
17
+ end
18
+
19
+ def members
20
+ @members ||= current_participatory_space.members.published
21
+ end
22
+
23
+ alias_method :collection, :members
24
+ end
25
+ end
26
+ end
27
+ end
@@ -36,8 +36,6 @@ module Decidim
36
36
  # title of the space (mandatory).
37
37
  # * url - The url of the resource (optional).
38
38
  # * active - Whether the item is active (optional).
39
- # * dropdown_cell - When this value is present is used to generate a dropdown
40
- # associated to the item (optional).
41
39
  # * resource - The resource of the item. This value is passed to the
42
40
  # dropdown cell, so it is mandatory if the dropdown cell is
43
41
  # present.
@@ -48,7 +46,6 @@ module Decidim
48
46
  label: current_participatory_space.title,
49
47
  url: Decidim::ResourceLocatorPresenter.new(current_participatory_space).path,
50
48
  active: true,
51
- dropdown_cell: current_participatory_space_manifest.breadcrumb_cell,
52
49
  resource: current_participatory_space
53
50
  }
54
51
  end
@@ -79,8 +76,7 @@ module Decidim
79
76
 
80
77
  # Method for current user can visit the space (assembly or process)
81
78
  def current_user_can_visit_space?
82
- return true unless current_participatory_space.try(:private_space?) &&
83
- !current_participatory_space.try(:is_transparent?)
79
+ return true unless current_participatory_space.respond_to?(:restricted?) && current_participatory_space.restricted?
84
80
  return false unless current_user
85
81
  return true if current_user.admin?
86
82
  return true if user_has_any_role?(current_user, current_participatory_space, broad_check: true)
@@ -31,7 +31,7 @@ module Decidim
31
31
  on(:invalid) do |password|
32
32
  fetch_entered_password(password)
33
33
  flash[:alert] = t("account.update.error", scope: "decidim")
34
- render action: :show, status: :unprocessable_entity
34
+ render action: :show, status: :unprocessable_content
35
35
  end
36
36
  end
37
37
  end
@@ -5,6 +5,7 @@ module Decidim
5
5
  include Decidim::ApplicationHelper
6
6
  include FormFactory
7
7
  include HasSpecificBreadcrumb
8
+
8
9
  helper Decidim::ResourceReferenceHelper
9
10
 
10
11
  before_action :authenticate_user!
@@ -38,7 +39,7 @@ module Decidim
38
39
 
39
40
  on(:invalid) do
40
41
  flash.now[:alert] = t("created.error", scope: "decidim.amendments")
41
- render :new, status: :unprocessable_entity
42
+ render :new, status: :unprocessable_content
42
43
  end
43
44
  end
44
45
  end
@@ -62,7 +63,7 @@ module Decidim
62
63
 
63
64
  on(:invalid) do
64
65
  flash.now[:alert] = t("error", scope: "decidim.amendments.update_draft")
65
- render :edit_draft, status: :unprocessable_entity
66
+ render :edit_draft, status: :unprocessable_content
66
67
  end
67
68
  end
68
69
  end
@@ -100,7 +101,7 @@ module Decidim
100
101
 
101
102
  on(:invalid) do
102
103
  flash.now[:alert] = t("error", scope: "decidim.amendments.publish_draft")
103
- render :edit_draft, status: :unprocessable_entity
104
+ render :edit_draft, status: :unprocessable_content
104
105
  end
105
106
  end
106
107
  end
@@ -160,7 +161,7 @@ module Decidim
160
161
 
161
162
  on(:invalid) do
162
163
  flash.now[:alert] = t("accepted.error", scope: "decidim.amendments")
163
- render :review, status: :unprocessable_entity
164
+ render :review, status: :unprocessable_content
164
165
  end
165
166
  end
166
167
  end
@@ -10,6 +10,7 @@ module Decidim
10
10
  include Decidim::NeedsPermission
11
11
 
12
12
  include ParticipatorySpaceContext
13
+
13
14
  before_action :authorize_participatory_space
14
15
 
15
16
  helper Decidim::FiltersHelper
@@ -35,7 +36,7 @@ module Decidim
35
36
 
36
37
  before_action :redirect_unless_feature_private
37
38
 
38
- before_action :set_component_breadcrumb_item
39
+ before_action :set_breadcrumb_items
39
40
 
40
41
  def current_participatory_space
41
42
  request.env["decidim.current_participatory_space"]
@@ -66,14 +67,30 @@ module Decidim
66
67
  raise ActionController::RoutingError, "Not Found" unless current_user_can_visit_space?
67
68
  end
68
69
 
69
- def set_component_breadcrumb_item
70
- context_breadcrumb_items << {
70
+ def set_breadcrumb_items
71
+ context_breadcrumb_items << add_current_component
72
+ context_breadcrumb_items << add_parent_breadcrumb_item
73
+ context_breadcrumb_items << add_breadcrumb_item
74
+ end
75
+
76
+ private
77
+
78
+ def add_current_component
79
+ {
71
80
  label: current_component.name,
72
81
  url: Decidim::EngineRouter.main_proxy(current_component).root_path,
73
82
  active: false,
74
83
  resource: current_component
75
84
  }
76
85
  end
86
+
87
+ def add_parent_breadcrumb_item
88
+ {}
89
+ end
90
+
91
+ def add_breadcrumb_item
92
+ {}
93
+ end
77
94
  end
78
95
  end
79
96
  end
@@ -34,7 +34,7 @@ module Decidim
34
34
 
35
35
  on(:invalid) do
36
36
  set_flash_message :notice, :success, kind: @form.provider.capitalize
37
- render :new, status: :unprocessable_entity
37
+ render :new, status: :unprocessable_content
38
38
  end
39
39
 
40
40
  on(:add_tos_errors) do
@@ -36,7 +36,7 @@ module Decidim
36
36
  on(:invalid) do
37
37
  flash.now[:alert] = t("passwords.update.error", scope: "decidim")
38
38
  resource.errors.errors.concat(@form.errors.errors)
39
- render action: "edit", status: :unprocessable_entity
39
+ render action: "edit", status: :unprocessable_content
40
40
  end
41
41
  end
42
42
  end
@@ -40,7 +40,7 @@ module Decidim
40
40
 
41
41
  on(:invalid) do
42
42
  flash.now[:alert] = t("error", scope: "decidim.devise.registrations.create")
43
- render :new, status: :unprocessable_entity
43
+ render :new, status: :unprocessable_content
44
44
  end
45
45
  end
46
46
  end
@@ -48,7 +48,7 @@ module Decidim
48
48
 
49
49
  def redirect_to_referer_or_path
50
50
  set_flash_message(:alert, "csrf_token", scope: "devise.failure")
51
- redirect_back(fallback_location: root_path) && return
51
+ redirect_back_or_to(root_path) && return
52
52
  end
53
53
 
54
54
  def check_sign_in_enabled