decidim-core 0.31.5 → 0.32.0.rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -13
  3. data/app/cells/decidim/amendable/amend_button_card_cell.rb +1 -1
  4. data/app/cells/decidim/content_blocks/announcement_settings_form/show.erb +5 -0
  5. data/app/cells/decidim/content_blocks/announcement_settings_form_cell.rb +17 -0
  6. data/app/cells/decidim/content_blocks/how_to_participate/show.erb +1 -1
  7. data/app/cells/decidim/content_blocks/participatory_space_announcement_cell.rb +1 -3
  8. data/app/cells/decidim/content_blocks/participatory_space_hero_cell.rb +1 -5
  9. data/app/cells/decidim/{participatory_space_private_user_cell.rb → member_cell.rb} +1 -1
  10. data/app/cells/decidim/onboarding_action_message_cell.rb +1 -0
  11. data/app/cells/decidim/profile/details.erb +1 -1
  12. data/app/cells/decidim/profile_cell.rb +1 -0
  13. data/app/cells/decidim/profile_member_of/show.erb +13 -0
  14. data/app/cells/decidim/profile_member_of_cell.rb +35 -0
  15. data/app/cells/decidim/tags_cell.rb +1 -1
  16. data/app/cells/decidim/versions_list/show.erb +25 -0
  17. data/app/commands/decidim/create_follow.rb +3 -5
  18. data/app/commands/decidim/create_user_report.rb +1 -1
  19. data/app/commands/decidim/destroy_account.rb +3 -3
  20. data/app/commands/decidim/search.rb +5 -5
  21. data/app/controllers/concerns/decidim/ajax_permission_handler.rb +1 -1
  22. data/app/controllers/concerns/decidim/direct_upload.rb +3 -2
  23. data/app/controllers/concerns/decidim/ephemeral_session_checker.rb +1 -1
  24. data/app/controllers/concerns/decidim/force_authentication.rb +10 -1
  25. data/app/controllers/concerns/decidim/impersonate_users.rb +4 -0
  26. data/app/controllers/concerns/decidim/locale_switcher.rb +52 -2
  27. data/app/controllers/concerns/decidim/needs_tos_accepted.rb +1 -1
  28. data/app/controllers/concerns/decidim/participatory_space/has_members_page.rb +27 -0
  29. data/app/controllers/concerns/decidim/participatory_space_context.rb +1 -5
  30. data/app/controllers/decidim/account_controller.rb +1 -1
  31. data/app/controllers/decidim/amendments_controller.rb +5 -4
  32. data/app/controllers/decidim/components/base_controller.rb +20 -3
  33. data/app/controllers/decidim/devise/omniauth_registrations_controller.rb +1 -1
  34. data/app/controllers/decidim/devise/passwords_controller.rb +1 -1
  35. data/app/controllers/decidim/devise/registrations_controller.rb +1 -1
  36. data/app/controllers/decidim/devise/sessions_controller.rb +1 -1
  37. data/app/controllers/decidim/download_your_data_controller.rb +1 -1
  38. data/app/controllers/decidim/editor_images_controller.rb +1 -1
  39. data/app/controllers/decidim/follows_controller.rb +4 -3
  40. data/app/controllers/decidim/geolocation_controller.rb +1 -1
  41. data/app/controllers/decidim/likes_controller.rb +2 -1
  42. data/app/controllers/decidim/locales_controller.rb +3 -11
  43. data/app/controllers/decidim/messaging/conversations_controller.rb +3 -3
  44. data/app/controllers/decidim/newsletters_controller.rb +1 -1
  45. data/app/controllers/decidim/notifications_settings_controller.rb +1 -1
  46. data/app/controllers/decidim/notifications_subscriptions_controller.rb +1 -1
  47. data/app/controllers/decidim/open_data_controller.rb +1 -1
  48. data/app/controllers/decidim/report_users_controller.rb +2 -2
  49. data/app/controllers/decidim/reports_controller.rb +1 -1
  50. data/app/controllers/decidim/user_activities_controller.rb +1 -2
  51. data/app/events/decidim/welcome_notification_event.rb +1 -1
  52. data/app/forms/decidim/upload_validation_form.rb +1 -1
  53. data/app/helpers/concerns/decidim/flash_helper_extensions.rb +1 -0
  54. data/app/helpers/decidim/active_link_to_helper.rb +136 -0
  55. data/app/helpers/decidim/amendments_helper.rb +3 -3
  56. data/app/helpers/decidim/check_boxes_tree_helper.rb +2 -2
  57. data/app/helpers/decidim/component_path_helper.rb +9 -4
  58. data/app/helpers/decidim/filters_helper.rb +0 -2
  59. data/app/helpers/decidim/menu_helper.rb +3 -3
  60. data/app/helpers/decidim/meta_tags_helper.rb +0 -2
  61. data/app/helpers/decidim/paginate_helper.rb +14 -1
  62. data/app/helpers/decidim/sanitize_helper.rb +1 -0
  63. data/app/helpers/decidim/short_link_helper.rb +5 -5
  64. data/app/helpers/decidim/translations_helper.rb +4 -4
  65. data/app/jobs/decidim/delete_inactive_participants_job.rb +2 -2
  66. data/app/mailers/decidim/application_mailer.rb +7 -2
  67. data/app/mailers/decidim/decidim_devise_mailer.rb +1 -0
  68. data/app/mailers/decidim/reported_mailer.rb +4 -1
  69. data/app/models/decidim/action_log.rb +1 -1
  70. data/app/models/decidim/attachment.rb +2 -2
  71. data/app/models/decidim/authorization_transfer.rb +1 -1
  72. data/app/models/decidim/component.rb +6 -9
  73. data/app/models/decidim/content_block.rb +3 -3
  74. data/app/models/decidim/newsletter.rb +2 -2
  75. data/app/models/decidim/participatory_space/member.rb +55 -0
  76. data/app/models/decidim/resource_link.rb +1 -1
  77. data/app/models/decidim/short_link.rb +1 -1
  78. data/app/packs/src/decidim/controllers/assign_role/assign_role.test.js +80 -0
  79. data/app/packs/src/decidim/controllers/assign_role/controller.js +27 -0
  80. data/app/packs/src/decidim/controllers/main_menu/controller.js +115 -0
  81. data/app/packs/src/decidim/controllers/main_menu/main_menu.test.js +185 -0
  82. data/app/packs/src/decidim/datepicker/generate_datepicker.js +1 -13
  83. data/app/packs/src/decidim/editor/common/suggestion.js +1 -1
  84. data/app/packs/src/decidim/editor/extensions/decidim_kit/index.js +4 -1
  85. data/app/packs/src/decidim/editor/extensions/image/index.js +8 -5
  86. data/app/packs/src/decidim/editor/extensions/link/index.js +8 -0
  87. data/app/packs/src/decidim/editor/extensions/mention/index.js +18 -5
  88. data/app/packs/src/decidim/editor/extensions/mention_resource/index.js +16 -7
  89. data/app/packs/src/decidim/editor/test/extensions/decidim_kit.test.js +13 -4
  90. data/app/packs/src/decidim/editor/test/extensions/heading.test.js +1 -1
  91. data/app/packs/src/decidim/editor/test/extensions/image.test.js +26 -28
  92. data/app/packs/src/decidim/editor/test/extensions/mention.test.js +6 -2
  93. data/app/packs/src/decidim/editor/test/extensions/video_embed.test.js +27 -15
  94. data/app/packs/src/decidim/editor/test/helpers.js +8 -10
  95. data/app/packs/src/decidim/editor/test/toolbar/full.test.js +15 -4
  96. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_block.js +8 -4
  97. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_formatting.js +5 -1
  98. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_indent.js +9 -5
  99. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_link.js +5 -1
  100. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_list.js +8 -4
  101. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_styling.js +13 -9
  102. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_content_styling.js +6 -2
  103. data/app/packs/src/decidim/index.js +0 -1
  104. data/app/packs/stylesheets/decidim/_cards.scss +2 -1
  105. data/app/packs/stylesheets/decidim/_datepicker.scss +0 -8
  106. data/app/packs/stylesheets/decidim/_dropdown.scss +21 -31
  107. data/app/packs/stylesheets/decidim/_footer.scss +0 -36
  108. data/app/packs/stylesheets/decidim/_forms.scss +5 -1
  109. data/app/packs/stylesheets/decidim/_header.scss +148 -46
  110. data/app/packs/stylesheets/decidim/_language_chooser.scss +79 -0
  111. data/app/packs/stylesheets/decidim/application.scss +1 -0
  112. data/app/presenters/decidim/admin_log/participatory_space/member_presenter.rb +40 -0
  113. data/app/presenters/decidim/admin_log/static_page_resource_presenter.rb +1 -1
  114. data/app/presenters/decidim/authorization_transfer_presenter.rb +1 -1
  115. data/app/presenters/decidim/breadcrumb_root_menu_item_presenter.rb +3 -3
  116. data/app/presenters/decidim/log/user_presenter.rb +1 -0
  117. data/app/presenters/decidim/log/value_types/access_mode_presenter.rb +45 -0
  118. data/app/presenters/decidim/participatory_space/member_presenter.rb +48 -0
  119. data/app/presenters/decidim/resource_locator_presenter.rb +22 -3
  120. data/app/queries/decidim/last_activity.rb +1 -1
  121. data/app/serializers/decidim/exporters/participatory_space_serializer.rb +15 -1
  122. data/app/services/decidim/email_notification_generator.rb +2 -0
  123. data/app/services/decidim/notification_generator.rb +4 -0
  124. data/app/uploaders/decidim/organization_favicon_uploader.rb +4 -9
  125. data/app/validators/uploader_image_dimensions_validator.rb +13 -11
  126. data/app/views/decidim/homepage/show.html.erb +1 -1
  127. data/app/views/decidim/messaging/conversations/_new_conversation_button.html.erb +1 -1
  128. data/app/views/decidim/messaging/conversations/_reply.html.erb +1 -1
  129. data/app/views/decidim/messaging/conversations/new.html.erb +1 -1
  130. data/app/views/decidim/messaging/conversations/show.html.erb +2 -2
  131. data/app/views/decidim/participatory_space/members/_member.html.erb +1 -0
  132. data/app/views/decidim/shared/_results_per_page.html.erb +1 -1
  133. data/app/views/decidim/shared/filters/_check_boxes_tree.html.erb +1 -1
  134. data/app/views/decidim/shared/filters/_dropdown_label.html.erb +4 -3
  135. data/app/views/devise/mailer/{invite_private_user.html.erb → invite_member.html.erb} +2 -2
  136. data/app/views/devise/mailer/{invite_private_user.text.erb → invite_member.text.erb} +2 -2
  137. data/app/views/layouts/decidim/_head.html.erb +2 -2
  138. data/app/views/layouts/decidim/_wrapper.html.erb +1 -1
  139. data/app/views/layouts/decidim/footer/_focus_mode_main.html.erb +0 -1
  140. data/app/views/layouts/decidim/footer/_main.html.erb +0 -1
  141. data/app/views/layouts/decidim/header/_focus_mode_back_button.html.erb +4 -1
  142. data/app/views/layouts/decidim/header/_main.html.erb +17 -8
  143. data/app/views/layouts/decidim/header/_main_language_chooser.html.erb +24 -0
  144. data/app/views/layouts/decidim/header/_main_links_desktop.html.erb +56 -56
  145. data/app/views/layouts/decidim/header/_main_links_mobile_account.html.erb +2 -2
  146. data/app/views/layouts/decidim/header/_main_links_mobile_item_account.html.erb +3 -1
  147. data/app/views/layouts/decidim/header/_main_menu_mobile.html.erb +18 -5
  148. data/app/views/layouts/decidim/header/_main_search.html.erb +3 -3
  149. data/app/views/layouts/decidim/header/_menu.html.erb +5 -5
  150. data/app/views/layouts/decidim/header/_menu_breadcrumb_desktop.html.erb +13 -12
  151. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile.html.erb +28 -0
  152. data/config/initializers/invisible_captcha.rb +1 -0
  153. data/config/locales/ar.yml +3 -10
  154. data/config/locales/bg.yml +3 -10
  155. data/config/locales/ca-IT.yml +33 -19
  156. data/config/locales/ca.yml +33 -19
  157. data/config/locales/cs.yml +22 -19
  158. data/config/locales/de.yml +13 -18
  159. data/config/locales/el.yml +3 -7
  160. data/config/locales/en.yml +33 -19
  161. data/config/locales/es-MX.yml +33 -19
  162. data/config/locales/es-PY.yml +33 -19
  163. data/config/locales/es.yml +33 -19
  164. data/config/locales/eu.yml +33 -19
  165. data/config/locales/fi-plain.yml +33 -19
  166. data/config/locales/fi.yml +33 -19
  167. data/config/locales/fr-CA.yml +33 -19
  168. data/config/locales/fr.yml +33 -19
  169. data/config/locales/ga-IE.yml +3 -1
  170. data/config/locales/gl.yml +3 -7
  171. data/config/locales/hu.yml +3 -10
  172. data/config/locales/id-ID.yml +3 -7
  173. data/config/locales/it.yml +3 -10
  174. data/config/locales/ja.yml +18 -19
  175. data/config/locales/lb.yml +3 -8
  176. data/config/locales/lt.yml +3 -10
  177. data/config/locales/lv.yml +3 -7
  178. data/config/locales/nl.yml +3 -8
  179. data/config/locales/no.yml +3 -8
  180. data/config/locales/pl.yml +3 -10
  181. data/config/locales/pt-BR.yml +17 -19
  182. data/config/locales/pt.yml +3 -8
  183. data/config/locales/ro-RO.yml +10 -18
  184. data/config/locales/ru.yml +0 -6
  185. data/config/locales/sk.yml +33 -19
  186. data/config/locales/sv.yml +33 -19
  187. data/config/locales/tr-TR.yml +3 -8
  188. data/config/locales/uk.yml +0 -3
  189. data/config/locales/zh-CN.yml +3 -7
  190. data/config/locales/zh-TW.yml +3 -8
  191. data/config/routes.rb +139 -76
  192. data/db/data/20251213075429_rename_members_in_action_log.rb +22 -0
  193. data/db/data/20260319145808_rename_send_to_members_in_newsletter.rb +27 -0
  194. data/db/migrate/20200730142511_add_file_upload_settings_to_decidim_organizations.rb +13 -15
  195. data/db/migrate/20250523104311_move_cta_to_hero_content_block.rb +1 -1
  196. data/db/migrate/20250527122040_move_highlighted_content_banner_settings_to_content_block.rb +1 -1
  197. data/db/migrate/20250819110800_convert_private_exports_id_to_uuid.rb +2 -2
  198. data/db/migrate/20251112132305_remove_legacy_images_from_core_module.rb +27 -0
  199. data/db/migrate/20251205122428_rename_participatory_space_private_users_to_members.rb +9 -0
  200. data/db/migrate/20251216185133_rename_privatable_to_to_participatory_space_in_members.rb +10 -0
  201. data/db/migrate/20260208201405_remove_user_group_core.rb +21 -0
  202. data/db/migrate/20260208201406_remove_user_group_memberships.rb +30 -0
  203. data/db/migrate/20260208201407_remove_user_group_organizations.rb +11 -0
  204. data/db/migrate/20260217152425_remove_enable_participatory_space_filters_from_decidim_organizations.rb +7 -0
  205. data/db/migrate/20260314081619_add_index_on_decidim_members.rb +25 -0
  206. data/decidim-core.gemspec +25 -28
  207. data/lib/decidim/acts_as_tree.rb +12 -12
  208. data/lib/decidim/admin_filters_registry.rb +1 -1
  209. data/lib/decidim/amendable.rb +5 -1
  210. data/lib/decidim/api/functions/category_list.rb +1 -0
  211. data/lib/decidim/api/functions/component_finder_base.rb +1 -1
  212. data/lib/decidim/api/functions/component_list.rb +3 -1
  213. data/lib/decidim/api/functions/component_list_base.rb +1 -0
  214. data/lib/decidim/api/functions/participatory_space_finder_base.rb +1 -1
  215. data/lib/decidim/api/functions/participatory_space_list_base.rb +1 -0
  216. data/lib/decidim/api/functions/user_entity_list.rb +0 -1
  217. data/lib/decidim/api/interfaces/amendable_entity_interface.rb +1 -0
  218. data/lib/decidim/api/interfaces/amendable_interface.rb +1 -0
  219. data/lib/decidim/api/interfaces/attachable_collection_interface.rb +1 -0
  220. data/lib/decidim/api/interfaces/attachable_interface.rb +1 -0
  221. data/lib/decidim/api/interfaces/author_interface.rb +2 -1
  222. data/lib/decidim/api/interfaces/authorable_interface.rb +1 -0
  223. data/lib/decidim/api/interfaces/categories_container_interface.rb +1 -0
  224. data/lib/decidim/api/interfaces/categorizable_interface.rb +1 -0
  225. data/lib/decidim/api/interfaces/coauthorable_interface.rb +1 -0
  226. data/lib/decidim/api/interfaces/component_interface.rb +9 -8
  227. data/lib/decidim/api/interfaces/fingerprint_interface.rb +1 -0
  228. data/lib/decidim/api/interfaces/followable_interface.rb +2 -0
  229. data/lib/decidim/api/interfaces/likeable_interface.rb +2 -2
  230. data/lib/decidim/api/interfaces/localizable_interface.rb +1 -0
  231. data/lib/decidim/api/interfaces/participatory_space_interface.rb +1 -0
  232. data/lib/decidim/api/interfaces/referable_interface.rb +1 -0
  233. data/lib/decidim/api/interfaces/scopable_interface.rb +1 -0
  234. data/lib/decidim/api/interfaces/taxonomizable_interface.rb +1 -0
  235. data/lib/decidim/api/interfaces/timestamps_interface.rb +1 -0
  236. data/lib/decidim/api/interfaces/traceable_interface.rb +1 -0
  237. data/lib/decidim/api/types/attachment_collection_type.rb +5 -3
  238. data/lib/decidim/api/types/attachment_type.rb +11 -4
  239. data/lib/decidim/api/types/badge_score_type.rb +28 -0
  240. data/lib/decidim/api/types/moderation_type.rb +25 -0
  241. data/lib/decidim/api/types/participant_details_type.rb +17 -0
  242. data/lib/decidim/api/types/reportable_type.rb +18 -0
  243. data/lib/decidim/api/types/reportable_user_type.rb +17 -0
  244. data/lib/decidim/api/types/static_page_topic_type.rb +16 -0
  245. data/lib/decidim/api/types/static_page_type.rb +22 -0
  246. data/lib/decidim/api/types/taxonomy_type.rb +2 -0
  247. data/lib/decidim/api/types/user_moderation_type.rb +36 -0
  248. data/lib/decidim/api/types/user_type.rb +13 -0
  249. data/lib/decidim/asset_router/pipeline.rb +1 -1
  250. data/lib/decidim/asset_router/storage.rb +9 -9
  251. data/lib/decidim/assets/tailwind/tailwind.config.js.erb +3 -0
  252. data/lib/decidim/attribute_encryptor.rb +51 -10
  253. data/lib/decidim/attribute_object/model.rb +0 -5
  254. data/lib/decidim/block_registry.rb +1 -1
  255. data/lib/decidim/coauthorable.rb +2 -1
  256. data/lib/decidim/command.rb +1 -0
  257. data/lib/decidim/content_processor.rb +1 -1
  258. data/lib/decidim/core/api.rb +8 -0
  259. data/lib/decidim/core/content_blocks/registry_manager.rb +0 -6
  260. data/lib/decidim/core/engine.rb +2 -34
  261. data/lib/decidim/core/menu.rb +0 -26
  262. data/lib/decidim/core/test/factories.rb +29 -18
  263. data/lib/decidim/core/test/shared_examples/access_mode_restricted_participatory_spaces.rb +172 -0
  264. data/lib/decidim/core/test/shared_examples/access_mode_transparent_participatory_spaces.rb +241 -0
  265. data/lib/decidim/core/test/shared_examples/comments_examples.rb +115 -111
  266. data/lib/decidim/core/test/shared_examples/fingerprint_examples.rb +2 -0
  267. data/lib/decidim/core/test/shared_examples/has_members.rb +63 -0
  268. data/lib/decidim/core/test/shared_examples/manage_share_tokens_examples.rb +1 -1
  269. data/lib/decidim/core/test/shared_examples/map_examples.rb +1 -1
  270. data/lib/decidim/core/test/shared_examples/participant_details_examples.rb +16 -0
  271. data/lib/decidim/core/test/shared_examples/participatory_space_members_page_examples.rb +10 -10
  272. data/lib/decidim/core/test/shared_examples/resource_liked_event_examples.rb +1 -1
  273. data/lib/decidim/core/test/shared_examples/resource_locator_presenter_examples.rb +7 -7
  274. data/lib/decidim/core/test/shared_examples/searchable_participatory_space_examples.rb +3 -3
  275. data/lib/decidim/core/test/shared_examples/searchable_results_examples.rb +2 -2
  276. data/lib/decidim/core/test/shared_examples/simple_event.rb +1 -0
  277. data/lib/decidim/core/test/shared_examples/translated_event_examples.rb +2 -2
  278. data/lib/decidim/core/test/shared_examples/versions_controller_examples.rb +1 -1
  279. data/lib/decidim/core/test.rb +2 -1
  280. data/lib/decidim/core/version.rb +1 -1
  281. data/lib/decidim/core.rb +222 -335
  282. data/lib/decidim/download_your_data_serializers/{download_your_data_participatory_space_private_user_serializer.rb → download_your_data_member_serializer.rb} +6 -6
  283. data/lib/decidim/download_your_data_serializers.rb +2 -2
  284. data/lib/decidim/engine_router.rb +31 -6
  285. data/lib/decidim/exporters/csv.rb +1 -1
  286. data/lib/decidim/filter_form_builder.rb +1 -1
  287. data/{app/controllers/concerns → lib}/decidim/form_factory.rb +11 -1
  288. data/lib/decidim/has_settings.rb +2 -2
  289. data/lib/decidim/legacy_form_builder.rb +1 -0
  290. data/lib/decidim/locale_router_detector.rb +41 -0
  291. data/lib/decidim/maintenance/import_models/scope.rb +1 -1
  292. data/lib/decidim/maintenance/import_models.rb +0 -2
  293. data/lib/decidim/map/frontend.rb +1 -1
  294. data/lib/decidim/map/geocoding.rb +2 -2
  295. data/lib/decidim/map/static_map.rb +10 -22
  296. data/lib/decidim/map/utility.rb +3 -6
  297. data/lib/decidim/map.rb +2 -2
  298. data/lib/decidim/menu.rb +1 -1
  299. data/lib/decidim/menu_item.rb +1 -0
  300. data/lib/decidim/menu_registry.rb +1 -1
  301. data/lib/decidim/moderation_tools.rb +1 -1
  302. data/lib/decidim/newsletter_encryptor.rb +5 -8
  303. data/lib/decidim/organization_settings.rb +2 -2
  304. data/lib/decidim/participable.rb +1 -0
  305. data/lib/decidim/participatory_space/has_members.rb +61 -0
  306. data/lib/decidim/participatory_space_manifest.rb +0 -4
  307. data/lib/decidim/participatory_space_resourceable.rb +10 -1
  308. data/lib/decidim/routes/locale_redirects.rb +47 -0
  309. data/lib/decidim/routes.rb +7 -0
  310. data/lib/decidim/search_resource_fields_mapper.rb +3 -4
  311. data/lib/decidim/seeds.rb +17 -0
  312. data/lib/decidim/shakapacker/runner.rb +4 -4
  313. data/lib/decidim/shakapacker/shakapacker.yml +28 -3
  314. data/lib/decidim/taxonomizable.rb +1 -1
  315. data/lib/decidim/translatable_attributes.rb +9 -3
  316. data/lib/decidim/view_model.rb +4 -0
  317. data/lib/devise/models/decidim_newsletterable.rb +1 -1
  318. data/lib/tasks/decidim_procfile.rake +1 -1
  319. data/lib/tasks/decidim_tasks.rake +0 -1
  320. data/lib/tasks/decidim_taxonomies.rake +1 -1
  321. data/lib/tasks/upgrade/decidim_active_storage_migration_tasks.rake +0 -1
  322. data/lib/tasks/upgrade/decidim_encryption.rake +12 -0
  323. data/lib/tasks/upgrade/decidim_migrate_wysiwyg_content.rake +0 -1
  324. data/lib/tasks/upgrade/decidim_remove_deleted_users_left_data_tasks.rake +1 -1
  325. data/lib/tasks/upgrade/{fix_deleted_private_follows.rake → fix_deleted_members_follows.rake} +5 -5
  326. data/lib/tasks/upgrade/migrations.rake +0 -1
  327. data/lib/tasks/upgrade/user_groups_migration.rake +0 -1
  328. metadata +206 -130
  329. data/app/cells/decidim/content_blocks/global_menu/show.erb +0 -11
  330. data/app/cells/decidim/content_blocks/global_menu_cell.rb +0 -35
  331. data/app/cells/decidim/content_blocks/menu_breadcrumb_last_activity/show.erb +0 -10
  332. data/app/cells/decidim/content_blocks/menu_breadcrumb_last_activity_cell.rb +0 -49
  333. data/app/cells/decidim/participatory_space_dropdown_metadata/links.erb +0 -9
  334. data/app/cells/decidim/participatory_space_dropdown_metadata/metadata.erb +0 -1
  335. data/app/cells/decidim/participatory_space_dropdown_metadata/show.erb +0 -11
  336. data/app/cells/decidim/participatory_space_dropdown_metadata_cell.rb +0 -26
  337. data/app/controllers/concerns/decidim/has_members_page.rb +0 -25
  338. data/app/jobs/decidim/newsletters_opt_in_job.rb +0 -11
  339. data/app/jobs/decidim/user_report_job.rb +0 -11
  340. data/app/models/decidim/participatory_space_private_user.rb +0 -51
  341. data/app/packs/src/decidim/controllers/sticky_header/controller.js +0 -116
  342. data/app/packs/src/decidim/controllers/sticky_header/sticky_header.test.js +0 -320
  343. data/app/packs/src/decidim/dropdown_menu.js +0 -18
  344. data/app/packs/src/decidim/identity_selector_dialog.js +0 -33
  345. data/app/presenters/decidim/admin_log/participatory_space_private_user_presenter.rb +0 -38
  346. data/app/presenters/decidim/participatory_space_private_user_presenter.rb +0 -46
  347. data/app/views/decidim/participatory_space_private_users/_participatory_space_private_user.html.erb +0 -1
  348. data/app/views/layouts/decidim/footer/_main_language_chooser.html.erb +0 -26
  349. data/app/views/layouts/decidim/header/_menu_breadcrumb_items.html.erb +0 -34
  350. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_desktop.html.erb +0 -10
  351. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_mobile.html.erb +0 -17
  352. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_top_left.html.erb +0 -2
  353. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile_tablet.html.erb +0 -33
  354. data/app/views/layouts/decidim/header/_mobile_language_choose.html.erb +0 -25
  355. data/lib/decidim/core/test/shared_examples/has_private_users.rb +0 -63
  356. data/lib/decidim/core/test/shared_examples/participatory_space_dropdown_metadata_cell_examples.rb +0 -81
  357. data/lib/decidim/has_private_users.rb +0 -57
  358. data/lib/decidim/maintenance/import_models/assembly_type.rb +0 -49
  359. data/lib/decidim/maintenance/import_models/participatory_process_type.rb +0 -21
  360. data/lib/decidim/query_extensions.rb +0 -64
  361. /data/app/cells/decidim/{participatory_space_private_user → member}/show.erb +0 -0
@@ -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
@@ -37,7 +37,7 @@ module Decidim
37
37
  DownloadYourDataExportJob.perform_later(current_user)
38
38
 
39
39
  flash[:notice] = t("decidim.account.download_your_data_export.notice")
40
- redirect_back(fallback_location: download_your_data_path)
40
+ redirect_back_or_to(download_your_data_path)
41
41
  end
42
42
 
43
43
  def download_file
@@ -16,7 +16,7 @@ module Decidim
16
16
  end
17
17
 
18
18
  on(:invalid) do |_message|
19
- render json: { message: I18n.t("error", scope: "decidim.editor_images.create") }, status: :unprocessable_entity
19
+ render json: { message: I18n.t("error", scope: "decidim.editor_images.create") }, status: :unprocessable_content
20
20
  end
21
21
  end
22
22
  end
@@ -3,6 +3,7 @@
3
3
  module Decidim
4
4
  class FollowsController < Decidim::ApplicationController
5
5
  include FormFactory
6
+
6
7
  before_action :authenticate_user!
7
8
  helper_method :resource, :button_cell, :button_cell_mobile
8
9
 
@@ -16,7 +17,7 @@ module Decidim
16
17
  end
17
18
 
18
19
  on(:invalid) do
19
- render json: { error: I18n.t("follows.destroy.error", scope: "decidim") }, status: :unprocessable_entity
20
+ render json: { error: I18n.t("follows.destroy.error", scope: "decidim") }, status: :unprocessable_content
20
21
  end
21
22
  end
22
23
  end
@@ -31,7 +32,7 @@ module Decidim
31
32
  end
32
33
 
33
34
  on(:invalid) do
34
- render json: { error: I18n.t("follows.create.error", scope: "decidim") }, status: :unprocessable_entity
35
+ render json: { error: I18n.t("follows.create.error", scope: "decidim") }, status: :unprocessable_content
35
36
  end
36
37
  end
37
38
  end
@@ -43,7 +44,7 @@ module Decidim
43
44
  end
44
45
 
45
46
  def button_options
46
- params.require(:follow).permit(:button_classes).to_h.symbolize_keys
47
+ params.expect(follow: [:button_classes]).to_h.symbolize_keys
47
48
  end
48
49
 
49
50
  def button_cell_mobile
@@ -8,7 +8,7 @@ module Decidim
8
8
  enforce_permission_to :locate, :geolocation
9
9
 
10
10
  unless Decidim::Map.configured?
11
- return render(json: { message: I18n.t("not_configured", scope: "decidim.application.geocoding"), found: false }, status: :unprocessable_entity)
11
+ return render(json: { message: I18n.t("not_configured", scope: "decidim.application.geocoding"), found: false }, status: :unprocessable_content)
12
12
  end
13
13
 
14
14
  geocoder = Decidim::Map.utility(:geocoding, organization: current_organization)
@@ -5,6 +5,7 @@ module Decidim
5
5
  class LikesController < Decidim::Components::BaseController
6
6
  # we need to +include+ to be able to call :like_button from the view
7
7
  include Decidim::LikeableHelper
8
+
8
9
  helper_method :like_button
9
10
  # we need to declare with +helper+ to be able to call :render_like_identity from the views
10
11
  helper Decidim::LikeableHelper
@@ -22,7 +23,7 @@ module Decidim
22
23
  end
23
24
 
24
25
  on(:invalid) do
25
- render json: { error: I18n.t("resource_likes.create.error", scope: "decidim") }, status: :unprocessable_entity
26
+ render json: { error: I18n.t("resource_likes.create.error", scope: "decidim") }, status: :unprocessable_content
26
27
  end
27
28
  end
28
29
  end
@@ -7,20 +7,12 @@ module Decidim
7
7
 
8
8
  def create
9
9
  enforce_permission_to :create, :locales
10
- current_user.update!(locale: params["locale"]) if current_user && params["locale"] && available_locales.include?(params["locale"])
11
-
12
- redirect_to referer_with_new_locale
13
- end
14
10
 
15
- private
11
+ desired_locale = params["locale"] if params["locale"] && available_locales.include?(params["locale"])
16
12
 
17
- def referer_with_new_locale
18
- uri = URI(request.referer || "/")
19
- query = uri.query.to_s.gsub(/locale=[a-zA-Z-]{2,5}/, "")
20
- params = URI.decode_www_form(query) << ["locale", current_locale]
21
- uri.query = URI.encode_www_form(params)
13
+ current_user.update!(locale: params["locale"]) if current_user && params["locale"] && available_locales.include?(params["locale"])
22
14
 
23
- uri.to_s
15
+ redirect_to canonical_url(request.referer || "/", desired_locale || default_locale)
24
16
  end
25
17
  end
26
18
  end
@@ -30,7 +30,7 @@ module Decidim
30
30
  conversation = conversation_between(current_user, @form.recipient)
31
31
  end
32
32
 
33
- return redirect_back(fallback_location: profile_path(current_user.nickname)) if @form.recipient.empty?
33
+ return redirect_back_or_to(profile_path(current_user.nickname)) if @form.recipient.empty?
34
34
 
35
35
  return redirect_to conversation_path(conversation) if conversation
36
36
 
@@ -53,7 +53,7 @@ module Decidim
53
53
  render action: :error, locals: {
54
54
  error: I18n.t("messaging.conversations.create.error", scope: "decidim"),
55
55
  messages:
56
- }, status: :unprocessable_entity
56
+ }, status: :unprocessable_content
57
57
  end
58
58
  end
59
59
  end
@@ -89,7 +89,7 @@ module Decidim
89
89
  render action: :error, locals: {
90
90
  error: I18n.t("messaging.conversations.update.error", scope: "decidim"),
91
91
  messages:
92
- }, status: :unprocessable_entity
92
+ }, status: :unprocessable_content
93
93
  end
94
94
  end
95
95
  end
@@ -34,7 +34,7 @@ module Decidim
34
34
 
35
35
  on(:invalid) do
36
36
  flash.now[:alert] = t("newsletters.unsubscribe.error", scope: "decidim")
37
- render action: :unsubscribe, status: :unprocessable_entity
37
+ render action: :unsubscribe, status: :unprocessable_content
38
38
  end
39
39
  end
40
40
  else
@@ -22,7 +22,7 @@ module Decidim
22
22
 
23
23
  on(:invalid) do
24
24
  flash.now[:alert] = t("notifications_settings.update.error", scope: "decidim")
25
- render action: :show, status: :unprocessable_entity
25
+ render action: :show, status: :unprocessable_content
26
26
  end
27
27
  end
28
28
  end
@@ -18,7 +18,7 @@ module Decidim
18
18
  private
19
19
 
20
20
  def unsupported_browser
21
- render json: { error: I18n.t("notifications_settings.show.push_notifications_unsupported_browser", scope: "decidim") }, status: :unprocessable_entity
21
+ render json: { error: I18n.t("notifications_settings.show.push_notifications_unsupported_browser", scope: "decidim") }, status: :unprocessable_content
22
22
  end
23
23
  end
24
24
  end
@@ -15,7 +15,7 @@ module Decidim
15
15
  else
16
16
  schedule_open_data_generation(resource)
17
17
  flash[:alert] = t("decidim.open_data.not_available_yet")
18
- redirect_back fallback_location: open_data_path
18
+ redirect_back_or_to(open_data_path)
19
19
  end
20
20
  end
21
21
 
@@ -18,13 +18,13 @@ module Decidim
18
18
  if @form.block?
19
19
  redirect_to decidim_admin.new_user_block_path(user_id: reportable.id, hide: form.hide?)
20
20
  else
21
- redirect_back fallback_location: root_path
21
+ redirect_back_or_to(root_path)
22
22
  end
23
23
  end
24
24
 
25
25
  on(:invalid) do
26
26
  flash[:alert] = I18n.t("decidim.reports.create.error")
27
- redirect_back fallback_location: root_path
27
+ redirect_back_or_to(root_path)
28
28
  end
29
29
  end
30
30
  end
@@ -26,7 +26,7 @@ module Decidim
26
26
 
27
27
  on(:invalid) do
28
28
  flash[:alert] = I18n.t("decidim.reports.create.error")
29
- redirect_back fallback_location: root_path
29
+ redirect_back_or_to(root_path)
30
30
  end
31
31
  end
32
32
  end
@@ -56,8 +56,7 @@ module Decidim
56
56
 
57
57
  def resource_types
58
58
  @resource_types = begin
59
- array = %w(Decidim::Proposals::CollaborativeDraft
60
- Decidim::Comments::Comment
59
+ array = %w(Decidim::Comments::Comment
61
60
  Decidim::Debates::Debate
62
61
  Decidim::Initiative
63
62
  Decidim::Meetings::Meeting
@@ -45,7 +45,7 @@ module Decidim
45
45
  template
46
46
  .gsub("{{name}}", user.presenter.name)
47
47
  .gsub("{{organization}}", organization_name(organization))
48
- .gsub("{{help_url}}", url_helpers.pages_url(host: organization.host))
48
+ .gsub("{{help_url}}", url_helpers.pages_url(host: organization.host, locale: I18n.locale))
49
49
  .gsub("{{badges_url}}", url_helpers.gamification_badges_url(host: organization.host))
50
50
  .html_safe
51
51
  end
@@ -54,7 +54,7 @@ module Decidim
54
54
 
55
55
  def form_object_class
56
56
  @form_object_class ||= begin
57
- form_class.constantize if form_class.present?
57
+ form_class.presence&.constantize
58
58
  rescue NameError
59
59
  nil
60
60
  end
@@ -57,6 +57,7 @@ module Decidim
57
57
  # @param closable [Boolean] - Whether the close icon is added.
58
58
  #
59
59
  # @return [String] the HTML with the alert box
60
+ # @param [Hash{Symbol => Object}] opts
60
61
  def alert_box(value, alert_class, closable, opts = {})
61
62
  options = {
62
63
  class: "flash #{alert_class}",
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # Overrides {ActiveLinkTo#is_active_link?} to handle locale-prefixed URLs.
5
+ #
6
+ # Decidim adds the locale as a URL path segment (e.g. `/en/processes`), so
7
+ # the URL passed to the helper and `request.original_fullpath` both carry a
8
+ # locale prefix. This module normalizes the URL argument to always carry the
9
+ # current locale prefix before delegating to the gem, so active-state
10
+ # detection works correctly regardless of whether the caller already included
11
+ # the locale in the URL or not.
12
+ #
13
+ # When the locale is part of the Rails script name rather than the path
14
+ # (i.e. the application is mounted at a locale-prefixed mount point), no
15
+ # normalization is performed and the original gem behaviour is preserved.
16
+ #
17
+ # Include this module *after* {ActiveLinkTo} so that this override takes
18
+ # precedence.
19
+ module ActiveLinkToHelper
20
+ # Overrides {ActiveLinkTo#is_active_link?} to normalise locale-prefixed
21
+ # URLs before comparison.
22
+ #
23
+ # @param url [String] the URL to check
24
+ # @param condition [Boolean, Symbol, Regexp, Array, Hash, nil] the active
25
+ # condition, same as accepted by the `active_link_to` gem
26
+ #
27
+ # @return [Boolean] whether the link is considered active
28
+ def is_active_link?(url, condition = nil) # rubocop:disable Naming/PredicatePrefix
29
+ super(locale_prefixed_url(url), condition)
30
+ end
31
+
32
+ private
33
+
34
+ # Normalizes a URL so its path carries the current locale prefix, but only
35
+ # when the current request path itself has a locale prefix. This preserves
36
+ # correct behaviour in engines mounted without a locale segment (e.g. the
37
+ # admin engine at +/admin+) where neither the request path nor the
38
+ # generated paths contain a locale segment.
39
+ #
40
+ # When normalization does apply, any existing locale prefix is stripped
41
+ # first to avoid double-prefixing.
42
+ #
43
+ # Returns the URL unchanged for non-String values, when no locale segments
44
+ # are configured, when the locale lives in the script name, or when the
45
+ # current request path has no locale prefix.
46
+ #
47
+ # @param url [String] the URL to normalize
48
+ #
49
+ # @return [String] the normalized URL
50
+ def locale_prefixed_url(url)
51
+ locale_pattern = locale_prefix_pattern
52
+ return url unless normalizable_url?(url, locale_pattern)
53
+
54
+ current = try(:current_locale) || I18n.locale.to_s
55
+ return url if current.blank?
56
+
57
+ rewrite_url_with_locale(url, locale_pattern, current)
58
+ end
59
+
60
+ # Determines whether a URL string should be normalized with a locale prefix.
61
+ #
62
+ # Returns +false+ when any of the following conditions are true:
63
+ # - +url+ is not a +String+
64
+ # - the locale lives in the script name (via +locale_in_script_name?+)
65
+ # - +locale_pattern+ is +nil+ (no locales are configured)
66
+ # - the current request path does not begin with a locale segment
67
+ #
68
+ # @param url [String] the URL candidate for normalization
69
+ # @param locale_pattern [Regexp, nil] the pattern built by {#locale_prefix_pattern},
70
+ # or +nil+ when no locales are available
71
+ #
72
+ # @return [Boolean] +true+ when the URL should be rewritten with a locale prefix
73
+ def normalizable_url?(url, locale_pattern)
74
+ return false unless url.is_a?(String)
75
+ return false if try(:locale_in_script_name?)
76
+ return false if locale_pattern.nil?
77
+
78
+ current_path = try(:request)&.original_fullpath.to_s
79
+ current_path.match?(locale_pattern)
80
+ end
81
+
82
+ # Builds a +Regexp+ that matches any available locale code at the start of a
83
+ # URL path segment (e.g. +/en+, +/zh-TW+).
84
+ #
85
+ # Locales are sorted longest-first so that longer codes such as +zh-TW+ are
86
+ # tried before shorter ones like +zh+, preventing partial matches.
87
+ #
88
+ # @return [Regexp, nil] the locale-matching pattern, or +nil+ when no locales
89
+ # are configured
90
+ def locale_prefix_pattern
91
+ locales = available_locale_segments
92
+ return if locales.empty?
93
+
94
+ %r{\A/(#{Regexp.union(locales)})(?=/|\z)}
95
+ end
96
+
97
+ # Rewrites the path component of +url+ so it begins with the +current+ locale
98
+ # prefix. Any preexisting locale prefix is stripped first to prevent
99
+ # double-prefixing (e.g. +/en/en/foo+ would never be produced).
100
+ #
101
+ # Returns +url+ unchanged when the URI cannot be parsed.
102
+ #
103
+ # @param url [String] the URL whose path should be rewritten
104
+ # @param locale_pattern [Regexp] the pattern used to strip an existing locale prefix
105
+ # @param current [String] the locale code to prepend (e.g. +"en"+ or +"zh-TW"+)
106
+ #
107
+ # @return [String] the URL with its path rewritten to carry +current+ as the
108
+ # leading segment, or the original +url+ if parsing fails
109
+ def rewrite_url_with_locale(url, locale_pattern, current)
110
+ uri = Addressable::URI.parse(url)
111
+ return url if uri.nil?
112
+
113
+ stripped_path = uri.path.to_s.sub(locale_pattern, "")
114
+ stripped_path = "/" if stripped_path.empty?
115
+
116
+ uri.path = "/#{current}#{stripped_path}"
117
+ uri.to_s
118
+ rescue Addressable::URI::InvalidURIError
119
+ url
120
+ end
121
+
122
+ # Returns the list of available locale codes sorted longest-first.
123
+ #
124
+ # Sorting longest-first ensures that longer locale codes (e.g. +zh-TW+) are
125
+ # matched before shorter ones (e.g. +zh+) when building a {#locale_prefix_pattern}.
126
+ #
127
+ # Falls back to {Decidim.available_locales} when +available_locales+ is not
128
+ # defined on the including context (e.g. outside a controller).
129
+ #
130
+ # @return [Array<String>] locale code strings sorted by descending length
131
+ def available_locale_segments
132
+ locales = try(:available_locales) || Decidim.available_locales
133
+ locales.map(&:to_s).sort_by(&:length).reverse
134
+ end
135
+ end
136
+ end
@@ -17,9 +17,9 @@ module Decidim
17
17
  end
18
18
 
19
19
  # Checks if the user can participate in a participatory space
20
- # based on its settings related with Decidim::HasPrivateUsers.
21
- def can_participate_in_private_space?
22
- return true unless current_participatory_space.class.included_modules.include?(HasPrivateUsers)
20
+ # based on its settings related with Decidim::ParticipatorySpace::HasMembers.
21
+ def can_participate_in_restricted_space?
22
+ return true unless current_participatory_space.class.included_modules.include?(Decidim::ParticipatorySpace::HasMembers)
23
23
 
24
24
  current_participatory_space.can_participate?(current_user)
25
25
  end
@@ -18,12 +18,12 @@ module Decidim
18
18
  label_options: {
19
19
  "data-children-checkbox": parent_id,
20
20
  value:,
21
- for: "#{options[:namespace]}_#{options[:id]}"
21
+ for: options[:id]
22
22
  }
23
23
  }
24
24
  options.merge!(checkbox_options)
25
25
  # as taxonomies work with a nested array of values, we need to manually check if the value is checked
26
- matches = options[:id]&.match(/^with_any_taxonomies_([0-9]+)__taxonomy-([0-9_]+)/)
26
+ matches = options[:id]&.match(/^with_any_taxonomies_taxonomy-([0-9]+)_([0-9_]+)/)
27
27
  if matches.present? && object.respond_to?(:with_any_taxonomies) && object.with_any_taxonomies&.dig(matches[1]).is_a?(Array)
28
28
  options[:checked] = object.with_any_taxonomies[matches[1]].include?(value.to_s)
29
29
  end
@@ -8,8 +8,11 @@ module Decidim
8
8
  # component - the Component we want to find the root path for.
9
9
  #
10
10
  # Returns a relative url.
11
- def main_component_path(component)
11
+ def main_component_path(component, desired_params = {})
12
12
  current_params = try(:params) || {}
13
+ current_params = current_params.merge(locale: I18n.locale)
14
+ .merge(desired_params)
15
+
13
16
  EngineRouter.main_proxy(component).root_path(locale: current_params[:locale])
14
17
  end
15
18
 
@@ -18,8 +21,11 @@ module Decidim
18
21
  # component - the Component we want to find the root path for.
19
22
  #
20
23
  # Returns an absolute url.
21
- def main_component_url(component)
24
+ def main_component_url(component, desired_params = {})
22
25
  current_params = try(:params) || {}
26
+ current_params = current_params.merge(locale: I18n.locale)
27
+ .merge(desired_params)
28
+
23
29
  EngineRouter.main_proxy(component).root_url(locale: current_params[:locale])
24
30
  end
25
31
 
@@ -29,8 +35,7 @@ module Decidim
29
35
  #
30
36
  # Returns a relative url.
31
37
  def manage_component_path(component)
32
- current_params = try(:params) || {}
33
- EngineRouter.admin_proxy(component).root_path(locale: current_params[:locale])
38
+ EngineRouter.admin_proxy(component).root_path
34
39
  end
35
40
 
36
41
  # Returns whether the component can be managed or not by checking if it has
@@ -44,8 +44,6 @@ module Decidim
44
44
  I18n.t("decidim/meetings/meeting.other", scope: "activerecord.models")
45
45
  when "debates"
46
46
  I18n.t("decidim/debates/debate.other", scope: "activerecord.models")
47
- when "sortitions"
48
- I18n.t("decidim/sortitions/sortition.other", scope: "activerecord.models")
49
47
  when "surveys"
50
48
  I18n.t("decidim/surveys/survey.other", scope: "activerecord.models")
51
49
  when "projects"
@@ -70,11 +70,11 @@ module Decidim
70
70
  # The queries already include the order by weight
71
71
  Decidim::ParticipatoryProcesses::OrganizationParticipatoryProcesses.new(current_organization) |
72
72
  Decidim::ParticipatoryProcesses::PromotedParticipatoryProcesses.new
73
- ).select(&:published?).map { |process| remove_private_space_if_not_private_user(process) }&.compact&.first
73
+ ).select(&:published?).map { |process| remove_restricted_space_if_not_member(process) }&.compact&.first
74
74
  end
75
75
 
76
- def remove_private_space_if_not_private_user(process)
77
- return nil if process.private_space == true && !process.can_participate?(current_user)
76
+ def remove_restricted_space_if_not_member(process)
77
+ return nil if process.restricted? && !process.can_participate?(current_user)
78
78
 
79
79
  process
80
80
  end
@@ -8,8 +8,6 @@ module Decidim
8
8
  # the other methods to see how they work.
9
9
  #
10
10
  # @param [Hash] tags - A Hash containing the meta tag name as keys and its content as values.
11
- # @param [Object, nil] resource - The resource object that may contain the image.
12
- #
13
11
  # @return [nil]
14
12
  def add_decidim_meta_tags(tags)
15
13
  add_decidim_page_title(tags[:title])
@@ -16,9 +16,22 @@ module Decidim
16
16
  content_tag :div, class: "flex flex-col-reverse md:flex-row items-center justify-between gap-1 py-8 md:py-16 md:flex-wrap", data: { pagination: "" } do
17
17
  template = ""
18
18
  template += render(partial: "decidim/shared/results_per_page", locals: { per_page: }, formats: [:html]) if collection.total_pages.positive?
19
- template += paginate collection, window: 2, outer_window: 1, theme: "decidim", params: paginate_params
19
+ template += paginate collection, window: 2, outer_window: 1, theme: "decidim", params: pagination_params(paginate_params)
20
20
  template.html_safe
21
21
  end
22
22
  end
23
+
24
+ private
25
+
26
+ def pagination_params(paginate_params)
27
+ request_params = params.to_unsafe_h.except("locale", :locale)
28
+ request_params["q"] = request_params["q"].except("locale", :locale) if request_params["q"].is_a?(Hash)
29
+ request_params[:locale] = nil if admin_controller_with_locale_prefix?
30
+ request_params.merge(paginate_params)
31
+ end
32
+
33
+ def admin_controller_with_locale_prefix?
34
+ request.path_parameters[:locale].present? && controller_path.to_s.include?("/admin/")
35
+ end
23
36
  end
24
37
  end
@@ -131,6 +131,7 @@ module Decidim
131
131
  # @param method [Symbol] Method name
132
132
  #
133
133
  # @return ActiveSupport::SafeBuffer
134
+ # @param [Object, nil] presenter_class
134
135
  def render_sanitized_content(resource, method, presenter_class: nil)
135
136
  content = present(resource, presenter_class:).send(method, links: true, strip_tags: !try(:safe_content?))
136
137
 
@@ -10,11 +10,11 @@ module Decidim
10
10
  # also resolves the current mounted route name to make it possible to refer
11
11
  # to the same context when redirecting the short URL to correct full URL.
12
12
  #
13
- # @option kwargs [Boolean] :route_name the route name to which the short
14
- # link should link to
15
- # @option kwargs [Float] :params the URL query parameters that should be
16
- # included in the URL where the short link redirects to
17
- # @return [String] The short URL
13
+ # Accepts keyword arguments such as:
14
+ # - `route_name`: the route name to link to
15
+ # - `params`: query parameters for the redirect
16
+ #
17
+ # @return [String] The short URL.
18
18
  def short_url(**)
19
19
  target = respond_to?(:current_component) && current_component
20
20
  target ||= respond_to?(:current_participatory_space) && current_participatory_space
@@ -30,8 +30,8 @@ module Decidim
30
30
  #
31
31
  # Returns a Hash with the locales as keys and the empty strings as values.
32
32
  def empty_translatable(locales = Decidim.available_locales)
33
- locales.each_with_object({}) do |locale, result|
34
- result[locale.to_s] = ""
33
+ locales.to_h do |locale|
34
+ [locale.to_s, ""]
35
35
  end
36
36
  end
37
37
 
@@ -49,8 +49,8 @@ module Decidim
49
49
  def ensure_translatable(value, locales = Decidim.available_locales)
50
50
  return empty_translatable(locales) unless value.is_a?(Hash)
51
51
 
52
- locales.each_with_object({}) do |locale, result|
53
- result[locale.to_s] = value[locale.to_s] || value[locale] || ""
52
+ locales.to_h do |locale|
53
+ [locale.to_s, value[locale.to_s] || value[locale] || ""]
54
54
  end
55
55
  end
56
56
 
@@ -14,9 +14,9 @@ module Decidim
14
14
 
15
15
  private
16
16
 
17
- def enqueue_jobs(users, action, *args)
17
+ def enqueue_jobs(users, action, *)
18
18
  users.find_each do |user|
19
- ProcessInactiveParticipantJob.perform_later(user.id, action, *args)
19
+ ProcessInactiveParticipantJob.perform_later(user.id, action, *)
20
20
  end
21
21
  end
22
22
 
@@ -9,10 +9,11 @@ module Decidim
9
9
  include Decidim::SanitizeHelper
10
10
  include Decidim::MailerHelper
11
11
  include Decidim::OrganizationHelper
12
- helper_method :organization_name, :decidim_escape_translated, :decidim_sanitize_translated, :translated_attribute, :decidim_sanitize, :decidim_sanitize_newsletter
13
12
 
14
13
  helper Decidim::SanitizeHelper
15
14
  helper Decidim::MailerHelper
15
+ helper_method :organization_name, :current_locale, :decidim_escape_translated, :decidim_sanitize_translated, :translated_attribute, :decidim_sanitize,
16
+ :decidim_sanitize_newsletter
16
17
 
17
18
  after_action :set_smtp
18
19
  after_action :set_from
@@ -24,10 +25,14 @@ module Decidim
24
25
 
25
26
  attr_reader :organization
26
27
 
28
+ def current_locale
29
+ I18n.locale || I18n.default_locale
30
+ end
31
+
27
32
  def set_smtp
28
33
  return if organization.nil? || organization.smtp_settings.blank? || organization.smtp_settings.except("from", "from_label", "from_email").all?(&:blank?)
29
34
 
30
- mail.reply_to = mail.reply_to || Decidim.config.mailer_reply
35
+ mail.reply_to = mail.reply_to || Decidim.config.mailer_sender
31
36
  mail.delivery_method.settings.merge!(
32
37
  address: organization.smtp_settings["address"],
33
38
  port: organization.smtp_settings["port"],
@@ -6,6 +6,7 @@ module Decidim
6
6
  class DecidimDeviseMailer < ::Devise::Mailer
7
7
  include LocalisedMailer
8
8
  include Decidim::SanitizeHelper
9
+
9
10
  helper_method :decidim_escape_translated, :decidim_sanitize_translated, :translated_attribute
10
11
 
11
12
  layout "decidim/mailer"