decidim-core 0.31.2 → 0.32.1

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 (516) 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 +0 -4
  6. data/app/cells/decidim/card_metadata_cell.rb +1 -1
  7. data/app/cells/decidim/comments_button_cell.rb +9 -1
  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 +1 -1
  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_elements_with_cell_for_list_cell.rb +5 -1
  15. data/app/cells/decidim/content_blocks/highlighted_participatory_spaces_cell.rb +1 -1
  16. data/app/cells/decidim/content_blocks/how_to_participate/show.erb +1 -1
  17. data/app/cells/decidim/content_blocks/html_cell.rb +1 -1
  18. data/app/cells/decidim/content_blocks/participatory_space_announcement_cell.rb +1 -3
  19. data/app/cells/decidim/content_blocks/participatory_space_hero_cell.rb +1 -5
  20. data/app/cells/decidim/content_blocks/participatory_space_hero_settings_form/show.erb +1 -1
  21. data/app/cells/decidim/content_blocks/static_page/section_cell.rb +1 -1
  22. data/app/cells/decidim/content_blocks/static_page/section_settings_form/show.erb +3 -1
  23. data/app/cells/decidim/content_blocks/static_page/summary_cell.rb +1 -1
  24. data/app/cells/decidim/content_blocks/static_page/summary_settings_form/show.erb +3 -1
  25. data/app/cells/decidim/content_blocks/static_page/two_pane_section_cell.rb +2 -2
  26. data/app/cells/decidim/content_blocks/static_page/two_pane_section_settings_form/show.erb +4 -2
  27. data/app/cells/decidim/data_consent/category.erb +25 -38
  28. data/app/cells/decidim/footer_topics/show.erb +5 -8
  29. data/app/cells/decidim/{participatory_space_private_user → member}/show.erb +6 -6
  30. data/app/cells/decidim/{participatory_space_private_user_cell.rb → member_cell.rb} +1 -5
  31. data/app/cells/decidim/nav_links/show.erb +3 -3
  32. data/app/cells/decidim/onboarding_action_message_cell.rb +1 -0
  33. data/app/cells/decidim/profile/details.erb +1 -1
  34. data/app/cells/decidim/profile_cell.rb +1 -0
  35. data/app/cells/decidim/profile_member_of/show.erb +13 -0
  36. data/app/cells/decidim/profile_member_of_cell.rb +35 -0
  37. data/app/cells/decidim/report_button/already_reported_modal.erb +1 -1
  38. data/app/cells/decidim/report_button/flag_modal.erb +1 -1
  39. data/app/cells/decidim/report_user_button/already_reported_modal.erb +1 -1
  40. data/app/cells/decidim/report_user_button/flag_modal.erb +1 -1
  41. data/app/cells/decidim/resource_types_filter/show.erb +2 -2
  42. data/app/cells/decidim/share_text_widget/modal.erb +1 -1
  43. data/app/cells/decidim/share_widget/qr_code_modal.erb +1 -1
  44. data/app/cells/decidim/tags_cell.rb +1 -1
  45. data/app/cells/decidim/upload_modal/files.erb +5 -1
  46. data/app/cells/decidim/upload_modal_cell.rb +15 -1
  47. data/app/cells/decidim/versions_list/show.erb +25 -0
  48. data/app/commands/decidim/create_follow.rb +3 -5
  49. data/app/commands/decidim/create_user_report.rb +1 -1
  50. data/app/commands/decidim/destroy_account.rb +15 -4
  51. data/app/commands/decidim/multiple_attachments_methods.rb +42 -24
  52. data/app/commands/decidim/search.rb +5 -5
  53. data/app/controllers/concerns/decidim/ajax_permission_handler.rb +1 -1
  54. data/app/controllers/concerns/decidim/devise_controllers.rb +9 -0
  55. data/app/controllers/concerns/decidim/direct_upload.rb +3 -2
  56. data/app/controllers/concerns/decidim/ephemeral_session_checker.rb +1 -1
  57. data/app/controllers/concerns/decidim/force_authentication.rb +10 -1
  58. data/app/controllers/concerns/decidim/impersonate_users.rb +4 -0
  59. data/app/controllers/concerns/decidim/locale_switcher.rb +52 -2
  60. data/app/controllers/concerns/decidim/needs_tos_accepted.rb +1 -1
  61. data/app/controllers/concerns/decidim/participatory_space/has_members_page.rb +27 -0
  62. data/app/controllers/concerns/decidim/participatory_space_context.rb +1 -5
  63. data/app/controllers/decidim/account_controller.rb +1 -1
  64. data/app/controllers/decidim/amendments_controller.rb +5 -4
  65. data/app/controllers/decidim/components/base_controller.rb +20 -3
  66. data/app/controllers/decidim/devise/omniauth_registrations_controller.rb +1 -1
  67. data/app/controllers/decidim/devise/passwords_controller.rb +1 -1
  68. data/app/controllers/decidim/devise/registrations_controller.rb +1 -1
  69. data/app/controllers/decidim/devise/sessions_controller.rb +1 -1
  70. data/app/controllers/decidim/download_your_data_controller.rb +2 -2
  71. data/app/controllers/decidim/editor_images_controller.rb +1 -1
  72. data/app/controllers/decidim/follows_controller.rb +4 -3
  73. data/app/controllers/decidim/geolocation_controller.rb +1 -1
  74. data/app/controllers/decidim/likes_controller.rb +2 -1
  75. data/app/controllers/decidim/locales_controller.rb +3 -11
  76. data/app/controllers/decidim/messaging/conversations_controller.rb +3 -3
  77. data/app/controllers/decidim/newsletters_controller.rb +1 -1
  78. data/app/controllers/decidim/notifications_settings_controller.rb +1 -1
  79. data/app/controllers/decidim/notifications_subscriptions_controller.rb +8 -0
  80. data/app/controllers/decidim/open_data_controller.rb +1 -1
  81. data/app/controllers/decidim/private_downloads_controller.rb +29 -0
  82. data/app/controllers/decidim/report_users_controller.rb +2 -2
  83. data/app/controllers/decidim/reports_controller.rb +1 -1
  84. data/app/controllers/decidim/user_activities_controller.rb +1 -2
  85. data/app/events/decidim/amendable/amendment_base_event.rb +7 -1
  86. data/app/events/decidim/welcome_notification_event.rb +1 -1
  87. data/app/forms/decidim/upload_validation_form.rb +1 -1
  88. data/app/helpers/concerns/decidim/flash_helper_extensions.rb +1 -0
  89. data/app/helpers/decidim/active_link_to_helper.rb +136 -0
  90. data/app/helpers/decidim/amendments_helper.rb +3 -3
  91. data/app/helpers/decidim/check_boxes_tree_helper.rb +2 -2
  92. data/app/helpers/decidim/component_path_helper.rb +9 -4
  93. data/app/helpers/decidim/filters_helper.rb +0 -2
  94. data/app/helpers/decidim/mailer_helper.rb +36 -0
  95. data/app/helpers/decidim/menu_helper.rb +4 -5
  96. data/app/helpers/decidim/meta_tags_helper.rb +0 -2
  97. data/app/helpers/decidim/newsletters_helper.rb +4 -22
  98. data/app/helpers/decidim/paginate_helper.rb +14 -1
  99. data/app/helpers/decidim/sanitize_helper.rb +1 -0
  100. data/app/helpers/decidim/short_link_helper.rb +5 -5
  101. data/app/helpers/decidim/translations_helper.rb +4 -4
  102. data/app/jobs/decidim/delete_inactive_participants_job.rb +2 -2
  103. data/app/jobs/decidim/find_and_update_descendants_job.rb +8 -2
  104. data/app/jobs/decidim/process_inactive_participant_job.rb +0 -7
  105. data/app/jobs/decidim/update_search_indexes_job.rb +2 -2
  106. data/app/mailers/decidim/application_mailer.rb +11 -2
  107. data/app/mailers/decidim/decidim_devise_mailer.rb +1 -0
  108. data/app/mailers/decidim/delete_user_mailer.rb +14 -0
  109. data/app/mailers/decidim/participants_account_mailer.rb +0 -16
  110. data/app/mailers/decidim/reported_mailer.rb +4 -1
  111. data/app/models/decidim/action_log.rb +1 -1
  112. data/app/models/decidim/attachment.rb +20 -2
  113. data/app/models/decidim/authorization.rb +7 -0
  114. data/app/models/decidim/authorization_transfer.rb +1 -1
  115. data/app/models/decidim/component.rb +6 -9
  116. data/app/models/decidim/content_block.rb +3 -3
  117. data/app/models/decidim/moderation.rb +1 -1
  118. data/app/models/decidim/newsletter.rb +2 -2
  119. data/app/models/decidim/participatory_space/member.rb +55 -0
  120. data/app/models/decidim/private_download.rb +61 -0
  121. data/app/models/decidim/private_export.rb +6 -0
  122. data/app/models/decidim/resource_link.rb +1 -1
  123. data/app/models/decidim/short_link.rb +1 -1
  124. data/app/models/decidim/user.rb +2 -2
  125. data/app/models/decidim/user_base_entity.rb +17 -2
  126. data/app/models/decidim/user_moderation.rb +1 -1
  127. data/app/packs/src/decidim/a11y.js +29 -0
  128. data/app/packs/src/decidim/a11y.test.js +81 -0
  129. data/app/packs/src/decidim/confirm.js +8 -1
  130. data/app/packs/src/decidim/confirm.test.js +225 -0
  131. data/app/packs/src/decidim/controllers/accordion/accordion.test.js +272 -0
  132. data/app/packs/src/decidim/controllers/accordion/controller.js +117 -17
  133. data/app/packs/src/decidim/controllers/assign_role/assign_role.test.js +80 -0
  134. data/app/packs/src/decidim/controllers/assign_role/controller.js +27 -0
  135. data/app/packs/src/decidim/controllers/breadcrumb_truncate/breadcrumb_truncate.test.js +230 -0
  136. data/app/packs/src/decidim/controllers/breadcrumb_truncate/controller.js +172 -0
  137. data/app/packs/src/decidim/controllers/dropdown/controller.js +32 -0
  138. data/app/packs/src/decidim/controllers/dropdown/dropdown.test.js +215 -0
  139. data/app/packs/src/decidim/controllers/form_validator/form_validator.js +9 -8
  140. data/app/packs/src/decidim/controllers/form_validator/form_validator.test.js +28 -1
  141. data/app/packs/src/decidim/controllers/language_change/controller.js +1 -0
  142. data/app/packs/src/decidim/controllers/language_change/language_change.test.js +13 -0
  143. data/app/packs/src/decidim/controllers/main_menu/controller.js +152 -0
  144. data/app/packs/src/decidim/controllers/main_menu/main_menu.test.js +285 -0
  145. data/app/packs/src/decidim/controllers/mention/controller.js +296 -140
  146. data/app/packs/src/decidim/controllers/mention/input_mentions.test.js +120 -457
  147. data/app/packs/src/decidim/controllers/multiple_mentions/controller.js +68 -32
  148. data/app/packs/src/decidim/controllers/multiple_mentions/input_multiple_mentions.test.js +30 -23
  149. data/app/packs/src/decidim/controllers/password_toggler/controller.js +22 -1
  150. data/app/packs/src/decidim/controllers/password_toggler/password_toggler.test.js +11 -20
  151. data/app/packs/src/decidim/datepicker/datepicker_functions.js +26 -0
  152. data/app/packs/src/decidim/datepicker/generate_datepicker.js +3 -14
  153. data/app/packs/src/decidim/datepicker/generate_timepicker.js +3 -2
  154. data/app/packs/src/decidim/datepicker/test/datepicker_functions_adjust_picker_position.test.js +234 -0
  155. data/app/packs/src/decidim/direct_uploads/upload_field.js +4 -4
  156. data/app/packs/src/decidim/direct_uploads/upload_modal.js +12 -7
  157. data/app/packs/src/decidim/editor/common/suggestion.js +4 -2
  158. data/app/packs/src/decidim/editor/extensions/decidim_kit/index.js +4 -1
  159. data/app/packs/src/decidim/editor/extensions/image/index.js +57 -16
  160. data/app/packs/src/decidim/editor/extensions/image/node_view.js +9 -1
  161. data/app/packs/src/decidim/editor/extensions/indent/index.js +9 -0
  162. data/app/packs/src/decidim/editor/extensions/link/bubble_menu.js +34 -6
  163. data/app/packs/src/decidim/editor/extensions/link/index.js +53 -12
  164. data/app/packs/src/decidim/editor/extensions/mention/index.js +18 -5
  165. data/app/packs/src/decidim/editor/extensions/mention_resource/index.js +16 -7
  166. data/app/packs/src/decidim/editor/test/extensions/decidim_kit.test.js +13 -4
  167. data/app/packs/src/decidim/editor/test/extensions/heading.test.js +1 -1
  168. data/app/packs/src/decidim/editor/test/extensions/image.test.js +26 -28
  169. data/app/packs/src/decidim/editor/test/extensions/image_links.test.js +161 -0
  170. data/app/packs/src/decidim/editor/test/extensions/mention.test.js +6 -2
  171. data/app/packs/src/decidim/editor/test/extensions/video_embed.test.js +27 -15
  172. data/app/packs/src/decidim/editor/test/helpers.js +8 -10
  173. data/app/packs/src/decidim/editor/test/toolbar/full.test.js +15 -4
  174. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_block.js +8 -4
  175. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_formatting.js +5 -1
  176. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_indent.js +9 -5
  177. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_link.js +5 -1
  178. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_list.js +8 -4
  179. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_styling.js +13 -9
  180. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_content_styling.js +6 -2
  181. data/app/packs/src/decidim/geocoding/reverse_geocoding.js +15 -5
  182. data/app/packs/src/decidim/geocoding/reverse_geocoding.test.js +197 -0
  183. data/app/packs/src/decidim/index.js +4 -4
  184. data/app/packs/src/decidim/map/controller.js +10 -1
  185. data/app/packs/src/decidim/refactor/moved/focus_guard.js +16 -16
  186. data/app/packs/src/decidim/refactor/moved/focus_guard.test.js +136 -0
  187. data/app/packs/src/decidim/sw/push-permissions.js +48 -13
  188. data/app/packs/src/decidim/sw/sw.js +1 -1
  189. data/app/packs/src/decidim/utilities/text.js +6 -6
  190. data/app/packs/stylesheets/decidim/_cards.scss +15 -6
  191. data/app/packs/stylesheets/decidim/_conversations.scss +14 -0
  192. data/app/packs/stylesheets/decidim/_cookies.scss +13 -5
  193. data/app/packs/stylesheets/decidim/_datepicker.scss +0 -8
  194. data/app/packs/stylesheets/decidim/_documents.scss +1 -1
  195. data/app/packs/stylesheets/decidim/_dropdown.scss +22 -32
  196. data/app/packs/stylesheets/decidim/_editor_suggestions.scss +49 -0
  197. data/app/packs/stylesheets/decidim/_flash.scss +1 -1
  198. data/app/packs/stylesheets/decidim/_floating_help.scss +1 -1
  199. data/app/packs/stylesheets/decidim/_footer.scss +27 -31
  200. data/app/packs/stylesheets/decidim/_forms.scss +5 -1
  201. data/app/packs/stylesheets/decidim/_header.scss +183 -48
  202. data/app/packs/stylesheets/decidim/_language_chooser.scss +79 -0
  203. data/app/packs/stylesheets/decidim/_participatory_spaces.scss +1 -1
  204. data/app/packs/stylesheets/decidim/_rich_text.scss +17 -0
  205. data/app/packs/stylesheets/decidim/_tom_select.scss +23 -0
  206. data/app/packs/stylesheets/decidim/application.scss +3 -0
  207. data/app/packs/stylesheets/decidim/editor.scss +12 -33
  208. data/app/packs/stylesheets/decidim/geocoding_addons.scss +10 -2
  209. data/app/presenters/decidim/admin_log/participatory_space/member_presenter.rb +40 -0
  210. data/app/presenters/decidim/admin_log/static_page_resource_presenter.rb +1 -1
  211. data/app/presenters/decidim/authorization_transfer_presenter.rb +1 -1
  212. data/app/presenters/decidim/breadcrumb_root_menu_item_presenter.rb +3 -3
  213. data/app/presenters/decidim/footer_menu_presenter.rb +2 -4
  214. data/app/presenters/decidim/log/user_presenter.rb +1 -0
  215. data/app/presenters/decidim/log/value_types/access_mode_presenter.rb +45 -0
  216. data/app/presenters/decidim/menu_item_presenter.rb +15 -3
  217. data/app/presenters/decidim/participatory_space/member_presenter.rb +48 -0
  218. data/app/presenters/decidim/resource_locator_presenter.rb +22 -3
  219. data/app/presenters/decidim/stats_presenter.rb +1 -1
  220. data/app/queries/decidim/last_activity.rb +1 -1
  221. data/app/resolvers/decidim/meta_image_url_resolver.rb +7 -0
  222. data/app/serializers/decidim/exporters/participatory_space_serializer.rb +15 -1
  223. data/app/services/decidim/email_notification_generator.rb +2 -0
  224. data/app/services/decidim/notification_generator.rb +4 -0
  225. data/app/services/decidim/notifications_subscriptions_persistor.rb +6 -0
  226. data/app/services/decidim/push_subscription_endpoint_validator.rb +34 -0
  227. data/app/services/decidim/send_push_notification.rb +5 -1
  228. data/app/uploaders/decidim/image_uploader.rb +1 -1
  229. data/app/uploaders/decidim/organization_favicon_uploader.rb +4 -9
  230. data/app/validators/uploader_image_dimensions_validator.rb +13 -11
  231. data/app/views/decidim/delete_user_mailer/delete.html.erb +6 -0
  232. data/app/views/decidim/devise/invitations/edit.html.erb +3 -3
  233. data/app/views/decidim/devise/registrations/new.html.erb +1 -0
  234. data/app/views/decidim/devise/shared/_tos_fields.html.erb +3 -3
  235. data/app/views/decidim/gamification/badges/index.html.erb +1 -1
  236. data/app/views/decidim/homepage/show.html.erb +2 -2
  237. data/app/views/decidim/last_activities/index.html.erb +1 -1
  238. data/app/views/decidim/messaging/conversations/_error_modal.html.erb +11 -19
  239. data/app/views/decidim/messaging/conversations/_new_conversation_button.html.erb +1 -1
  240. data/app/views/decidim/messaging/conversations/_reply.html.erb +1 -1
  241. data/app/views/decidim/messaging/conversations/error.js.erb +12 -7
  242. data/app/views/decidim/messaging/conversations/new.html.erb +1 -1
  243. data/app/views/decidim/messaging/conversations/show.html.erb +2 -2
  244. data/app/views/decidim/newsletters/unsubscribe.html.erb +1 -1
  245. data/app/views/decidim/notification_mailer/event_received.html.erb +3 -3
  246. data/app/views/decidim/notifications_settings/show.html.erb +5 -5
  247. data/app/views/decidim/offline/show.html.erb +1 -1
  248. data/app/views/decidim/pages/_tabbed.html.erb +3 -3
  249. data/app/views/decidim/pages/index.html.erb +1 -1
  250. data/app/views/decidim/participatory_space/members/_member.html.erb +1 -0
  251. data/app/views/decidim/profiles/show.html.erb +1 -1
  252. data/app/views/decidim/searches/_filters.html.erb +1 -1
  253. data/app/views/decidim/shared/_filters.html.erb +5 -5
  254. data/app/views/decidim/shared/_resource_actions.html.erb +4 -4
  255. data/app/views/decidim/shared/_results_per_page.html.erb +1 -1
  256. data/app/views/decidim/shared/filters/_check_boxes_tree.html.erb +2 -2
  257. data/app/views/decidim/shared/filters/_collection.html.erb +1 -1
  258. data/app/views/decidim/shared/filters/_dropdown_label.html.erb +4 -3
  259. data/app/views/decidim/user_activities/index.html.erb +1 -1
  260. data/app/views/devise/mailer/{invite_private_user.html.erb → invite_member.html.erb} +2 -2
  261. data/app/views/devise/mailer/{invite_private_user.text.erb → invite_member.text.erb} +2 -2
  262. data/app/views/layouts/decidim/_head.html.erb +2 -2
  263. data/app/views/layouts/decidim/_wrapper.html.erb +3 -3
  264. data/app/views/layouts/decidim/footer/_focus_mode_main.html.erb +0 -1
  265. data/app/views/layouts/decidim/footer/_main.html.erb +1 -2
  266. data/app/views/layouts/decidim/footer/_main_links.html.erb +56 -28
  267. data/app/views/layouts/decidim/header/_focus_mode_back_button.html.erb +4 -1
  268. data/app/views/layouts/decidim/header/_main.html.erb +17 -8
  269. data/app/views/layouts/decidim/header/_main_language_chooser.html.erb +24 -0
  270. data/app/views/layouts/decidim/header/_main_links_desktop.html.erb +56 -56
  271. data/app/views/layouts/decidim/header/_main_links_mobile_account.html.erb +2 -2
  272. data/app/views/layouts/decidim/header/_main_links_mobile_item_account.html.erb +3 -1
  273. data/app/views/layouts/decidim/header/_main_menu_mobile.html.erb +18 -5
  274. data/app/views/layouts/decidim/header/_main_search.html.erb +3 -3
  275. data/app/views/layouts/decidim/header/_menu.html.erb +5 -5
  276. data/app/views/layouts/decidim/header/_menu_breadcrumb_desktop.html.erb +40 -12
  277. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile.html.erb +33 -0
  278. data/app/views/layouts/decidim/shared/_layout_center.html.erb +1 -1
  279. data/app/views/layouts/decidim/shared/_layout_item.html.erb +1 -1
  280. data/app/views/layouts/decidim/shared/_layout_two_col.html.erb +1 -1
  281. data/config/initializers/decidim_locale_aware_named_route_helper.rb +16 -0
  282. data/config/initializers/devise.rb +6 -0
  283. data/config/initializers/invisible_captcha.rb +1 -0
  284. data/config/locales/ar.yml +6 -38
  285. data/config/locales/bg.yml +3 -39
  286. data/config/locales/ca-IT.yml +91 -58
  287. data/config/locales/ca.yml +91 -58
  288. data/config/locales/cs.yml +54 -58
  289. data/config/locales/de.yml +45 -68
  290. data/config/locales/el.yml +3 -31
  291. data/config/locales/en.yml +88 -55
  292. data/config/locales/es-MX.yml +93 -60
  293. data/config/locales/es-PY.yml +93 -60
  294. data/config/locales/es.yml +95 -62
  295. data/config/locales/eu.yml +124 -92
  296. data/config/locales/fi-plain.yml +93 -55
  297. data/config/locales/fi.yml +96 -58
  298. data/config/locales/fr-CA.yml +70 -52
  299. data/config/locales/fr.yml +71 -54
  300. data/config/locales/ga-IE.yml +3 -1
  301. data/config/locales/gl.yml +3 -31
  302. data/config/locales/hu.yml +7 -40
  303. data/config/locales/id-ID.yml +3 -30
  304. data/config/locales/is-IS.yml +0 -6
  305. data/config/locales/it.yml +15 -33
  306. data/config/locales/ja.yml +105 -71
  307. data/config/locales/lb.yml +3 -33
  308. data/config/locales/lt.yml +4 -37
  309. data/config/locales/lv.yml +3 -30
  310. data/config/locales/nl.yml +3 -33
  311. data/config/locales/no.yml +3 -33
  312. data/config/locales/pl.yml +7 -41
  313. data/config/locales/pt-BR.yml +24 -65
  314. data/config/locales/pt.yml +3 -33
  315. data/config/locales/ro-RO.yml +12 -55
  316. data/config/locales/ru.yml +0 -16
  317. data/config/locales/sk.yml +1417 -32
  318. data/config/locales/sv.yml +44 -62
  319. data/config/locales/tr-TR.yml +20 -37
  320. data/config/locales/uk.yml +0 -9
  321. data/config/locales/zh-CN.yml +3 -30
  322. data/config/locales/zh-TW.yml +4 -35
  323. data/config/routes.rb +140 -76
  324. data/db/data/20251213075429_rename_members_in_action_log.rb +22 -0
  325. data/db/data/20260319145808_rename_send_to_members_in_newsletter.rb +27 -0
  326. data/db/migrate/20200730142511_add_file_upload_settings_to_decidim_organizations.rb +13 -15
  327. data/db/migrate/20250217192438_convert_user_groups_into_users.rb +3 -2
  328. data/db/migrate/20250523104311_move_cta_to_hero_content_block.rb +1 -1
  329. data/db/migrate/20250527122040_move_highlighted_content_banner_settings_to_content_block.rb +1 -1
  330. data/db/migrate/20250819110800_convert_private_exports_id_to_uuid.rb +2 -2
  331. data/db/migrate/20251112132305_remove_legacy_images_from_core_module.rb +27 -0
  332. data/db/migrate/20251205122428_rename_participatory_space_private_users_to_members.rb +9 -0
  333. data/db/migrate/20251216185133_rename_privatable_to_to_participatory_space_in_members.rb +10 -0
  334. data/db/migrate/20260208201405_remove_user_group_core.rb +21 -0
  335. data/db/migrate/20260208201406_remove_user_group_memberships.rb +30 -0
  336. data/db/migrate/20260208201407_remove_user_group_organizations.rb +11 -0
  337. data/db/migrate/20260217152425_remove_enable_participatory_space_filters_from_decidim_organizations.rb +7 -0
  338. data/db/migrate/20260314081619_add_index_on_decidim_members.rb +25 -0
  339. data/decidim-core.gemspec +28 -28
  340. data/lib/decidim/acts_as_tree.rb +12 -12
  341. data/lib/decidim/admin_filters_registry.rb +1 -1
  342. data/lib/decidim/amendable.rb +5 -1
  343. data/lib/decidim/api/functions/category_list.rb +1 -0
  344. data/lib/decidim/api/functions/component_finder_base.rb +1 -1
  345. data/lib/decidim/api/functions/component_list.rb +3 -1
  346. data/lib/decidim/api/functions/component_list_base.rb +1 -0
  347. data/lib/decidim/api/functions/participatory_space_finder_base.rb +1 -1
  348. data/lib/decidim/api/functions/participatory_space_list_base.rb +1 -0
  349. data/lib/decidim/api/functions/user_entity_list.rb +2 -1
  350. data/lib/decidim/api/interfaces/amendable_entity_interface.rb +1 -0
  351. data/lib/decidim/api/interfaces/amendable_interface.rb +1 -0
  352. data/lib/decidim/api/interfaces/attachable_collection_interface.rb +1 -0
  353. data/lib/decidim/api/interfaces/attachable_interface.rb +1 -0
  354. data/lib/decidim/api/interfaces/author_interface.rb +2 -1
  355. data/lib/decidim/api/interfaces/authorable_interface.rb +1 -0
  356. data/lib/decidim/api/interfaces/categories_container_interface.rb +1 -0
  357. data/lib/decidim/api/interfaces/categorizable_interface.rb +1 -0
  358. data/lib/decidim/api/interfaces/coauthorable_interface.rb +1 -0
  359. data/lib/decidim/api/interfaces/component_interface.rb +9 -8
  360. data/lib/decidim/api/interfaces/fingerprint_interface.rb +1 -0
  361. data/lib/decidim/api/interfaces/followable_interface.rb +2 -0
  362. data/lib/decidim/api/interfaces/likeable_interface.rb +2 -2
  363. data/lib/decidim/api/interfaces/localizable_interface.rb +1 -0
  364. data/lib/decidim/api/interfaces/participatory_space_interface.rb +1 -0
  365. data/lib/decidim/api/interfaces/referable_interface.rb +1 -0
  366. data/lib/decidim/api/interfaces/scopable_interface.rb +1 -0
  367. data/lib/decidim/api/interfaces/taxonomizable_interface.rb +1 -0
  368. data/lib/decidim/api/interfaces/timestamps_interface.rb +1 -0
  369. data/lib/decidim/api/interfaces/traceable_interface.rb +1 -0
  370. data/lib/decidim/api/types/attachment_collection_type.rb +5 -3
  371. data/lib/decidim/api/types/attachment_type.rb +11 -4
  372. data/lib/decidim/api/types/badge_score_type.rb +28 -0
  373. data/lib/decidim/api/types/moderation_type.rb +25 -0
  374. data/lib/decidim/api/types/participant_details_type.rb +17 -0
  375. data/lib/decidim/api/types/reportable_type.rb +18 -0
  376. data/lib/decidim/api/types/reportable_user_type.rb +17 -0
  377. data/lib/decidim/api/types/static_page_topic_type.rb +16 -0
  378. data/lib/decidim/api/types/static_page_type.rb +22 -0
  379. data/lib/decidim/api/types/taxonomy_type.rb +2 -0
  380. data/lib/decidim/api/types/user_moderation_type.rb +36 -0
  381. data/lib/decidim/api/types/user_type.rb +13 -0
  382. data/lib/decidim/asset_router/pipeline.rb +1 -1
  383. data/lib/decidim/asset_router/storage.rb +9 -9
  384. data/lib/decidim/assets/tailwind/tailwind.config.js.erb +4 -1
  385. data/lib/decidim/attachment_attributes.rb +58 -9
  386. data/lib/decidim/attribute_encryptor.rb +51 -10
  387. data/lib/decidim/attribute_object/model.rb +0 -5
  388. data/lib/decidim/block_registry.rb +1 -1
  389. data/lib/decidim/coauthorable.rb +2 -1
  390. data/lib/decidim/command.rb +2 -1
  391. data/lib/decidim/content_parsers/blob_parser.rb +3 -3
  392. data/lib/decidim/content_processor.rb +1 -1
  393. data/lib/decidim/content_renderers/base_renderer.rb +112 -0
  394. data/lib/decidim/content_renderers/blob_renderer.rb +6 -9
  395. data/lib/decidim/content_renderers/mention_resource_renderer.rb +10 -6
  396. data/lib/decidim/content_renderers/resource_renderer.rb +16 -7
  397. data/lib/decidim/content_renderers/user_renderer.rb +11 -9
  398. data/lib/decidim/core/api.rb +8 -0
  399. data/lib/decidim/core/content_blocks/registry_manager.rb +4 -10
  400. data/lib/decidim/core/engine.rb +10 -34
  401. data/lib/decidim/core/menu.rb +0 -26
  402. data/lib/decidim/core/test/factories.rb +32 -18
  403. data/lib/decidim/core/test/shared_examples/access_mode_restricted_participatory_spaces.rb +175 -0
  404. data/lib/decidim/core/test/shared_examples/access_mode_transparent_participatory_spaces.rb +244 -0
  405. data/lib/decidim/core/test/shared_examples/admin_resource_gallery_examples.rb +10 -10
  406. data/lib/decidim/core/test/shared_examples/amendable/amendment_event_examples.rb +2 -2
  407. data/lib/decidim/core/test/shared_examples/amendable/amendment_promoted_event_examples.rb +3 -3
  408. data/lib/decidim/core/test/shared_examples/comments_examples.rb +147 -117
  409. data/lib/decidim/core/test/shared_examples/fingerprint_examples.rb +2 -0
  410. data/lib/decidim/core/test/shared_examples/has_members.rb +63 -0
  411. data/lib/decidim/core/test/shared_examples/has_space_in_mcell_examples.rb +2 -1
  412. data/lib/decidim/core/test/shared_examples/manage_share_tokens_examples.rb +1 -1
  413. data/lib/decidim/core/test/shared_examples/map_examples.rb +1 -1
  414. data/lib/decidim/core/test/shared_examples/participant_details_examples.rb +16 -0
  415. data/lib/decidim/core/test/shared_examples/participatory_space_members_page_examples.rb +10 -10
  416. data/lib/decidim/core/test/shared_examples/participatory_space_members_shared_examples.rb +121 -0
  417. data/lib/decidim/core/test/shared_examples/resource_liked_event_examples.rb +3 -3
  418. data/lib/decidim/core/test/shared_examples/resource_locator_presenter_examples.rb +7 -7
  419. data/lib/decidim/core/test/shared_examples/searchable_participatory_space_examples.rb +3 -3
  420. data/lib/decidim/core/test/shared_examples/searchable_results_examples.rb +2 -2
  421. data/lib/decidim/core/test/shared_examples/simple_event.rb +1 -0
  422. data/lib/decidim/core/test/shared_examples/translated_event_examples.rb +2 -2
  423. data/lib/decidim/core/test/shared_examples/versions_controller_examples.rb +1 -1
  424. data/lib/decidim/core/test.rb +2 -1
  425. data/lib/decidim/core/version.rb +1 -1
  426. data/lib/decidim/core.rb +222 -335
  427. data/lib/decidim/download_your_data_serializers/{download_your_data_participatory_space_private_user_serializer.rb → download_your_data_member_serializer.rb} +6 -6
  428. data/lib/decidim/download_your_data_serializers.rb +2 -2
  429. data/lib/decidim/engine_router.rb +31 -6
  430. data/lib/decidim/exporters/csv.rb +1 -1
  431. data/lib/decidim/filter_form_builder.rb +1 -1
  432. data/lib/decidim/form_builder.rb +58 -36
  433. data/{app/controllers/concerns → lib}/decidim/form_factory.rb +11 -1
  434. data/lib/decidim/has_settings.rb +2 -2
  435. data/lib/decidim/legacy_form_builder.rb +1 -0
  436. data/lib/decidim/locale_router_detector.rb +41 -0
  437. data/lib/decidim/maintenance/import_models/scope.rb +1 -1
  438. data/lib/decidim/maintenance/import_models.rb +0 -2
  439. data/lib/decidim/maintenance/taxonomy_importer.rb +1 -1
  440. data/lib/decidim/map/autocomplete.rb +4 -3
  441. data/lib/decidim/map/dynamic_map.rb +3 -1
  442. data/lib/decidim/map/frontend.rb +1 -1
  443. data/lib/decidim/map/geocoding.rb +2 -2
  444. data/lib/decidim/map/static_map.rb +10 -22
  445. data/lib/decidim/map/utility.rb +3 -6
  446. data/lib/decidim/map.rb +2 -2
  447. data/lib/decidim/menu.rb +1 -1
  448. data/lib/decidim/menu_item.rb +1 -0
  449. data/lib/decidim/menu_registry.rb +1 -1
  450. data/lib/decidim/moderation_tools.rb +1 -1
  451. data/lib/decidim/newsletter_encryptor.rb +5 -8
  452. data/lib/decidim/organization_settings.rb +2 -2
  453. data/lib/decidim/participable.rb +1 -0
  454. data/lib/decidim/participatory_space/has_members.rb +61 -0
  455. data/lib/decidim/participatory_space_manifest.rb +0 -4
  456. data/lib/decidim/participatory_space_resourceable.rb +10 -1
  457. data/lib/decidim/participatory_space_user.rb +1 -1
  458. data/lib/decidim/routes/locale_redirects.rb +47 -0
  459. data/lib/decidim/routes.rb +7 -0
  460. data/lib/decidim/search_resource_fields_mapper.rb +3 -4
  461. data/lib/decidim/searchable.rb +9 -4
  462. data/lib/decidim/seeds.rb +17 -0
  463. data/lib/decidim/shakapacker/runner.rb +4 -4
  464. data/lib/decidim/shakapacker/shakapacker.yml +28 -3
  465. data/lib/decidim/taxonomizable.rb +1 -1
  466. data/lib/decidim/translatable_attributes.rb +9 -3
  467. data/lib/decidim/view_model.rb +5 -1
  468. data/lib/devise/models/decidim_newsletterable.rb +1 -1
  469. data/lib/tasks/decidim_mailers_tasks.rake +31 -9
  470. data/lib/tasks/decidim_procfile.rake +1 -1
  471. data/lib/tasks/decidim_tasks.rake +0 -1
  472. data/lib/tasks/decidim_taxonomies.rake +1 -1
  473. data/lib/tasks/upgrade/decidim_active_storage_migration_tasks.rake +0 -1
  474. data/lib/tasks/upgrade/decidim_encryption.rake +12 -0
  475. data/lib/tasks/upgrade/decidim_migrate_wysiwyg_content.rake +0 -1
  476. data/lib/tasks/upgrade/decidim_remove_deleted_users_left_data_tasks.rake +1 -1
  477. data/lib/tasks/upgrade/{fix_deleted_private_follows.rake → fix_deleted_members_follows.rake} +5 -5
  478. data/lib/tasks/upgrade/migrations.rake +0 -1
  479. data/lib/tasks/upgrade/user_groups_migration.rake +0 -1
  480. metadata +244 -132
  481. data/app/cells/decidim/content_blocks/global_menu/show.erb +0 -11
  482. data/app/cells/decidim/content_blocks/global_menu_cell.rb +0 -35
  483. data/app/cells/decidim/content_blocks/menu_breadcrumb_last_activity/show.erb +0 -10
  484. data/app/cells/decidim/content_blocks/menu_breadcrumb_last_activity_cell.rb +0 -49
  485. data/app/cells/decidim/participatory_space_dropdown_metadata/links.erb +0 -9
  486. data/app/cells/decidim/participatory_space_dropdown_metadata/metadata.erb +0 -1
  487. data/app/cells/decidim/participatory_space_dropdown_metadata/show.erb +0 -11
  488. data/app/cells/decidim/participatory_space_dropdown_metadata_cell.rb +0 -26
  489. data/app/commands/decidim/gallery_methods.rb +0 -107
  490. data/app/controllers/concerns/decidim/has_members_page.rb +0 -25
  491. data/app/jobs/decidim/newsletters_opt_in_job.rb +0 -11
  492. data/app/jobs/decidim/user_report_job.rb +0 -11
  493. data/app/models/decidim/participatory_space_private_user.rb +0 -51
  494. data/app/packs/src/decidim/controllers/sticky_header/controller.js +0 -116
  495. data/app/packs/src/decidim/controllers/sticky_header/sticky_header.test.js +0 -320
  496. data/app/packs/src/decidim/dropdown_menu.js +0 -18
  497. data/app/packs/src/decidim/identity_selector_dialog.js +0 -33
  498. data/app/packs/src/decidim/vendor/tribute.js +0 -1890
  499. data/app/packs/stylesheets/decidim/_tribute.scss +0 -36
  500. data/app/presenters/decidim/admin_log/participatory_space_private_user_presenter.rb +0 -38
  501. data/app/presenters/decidim/participatory_space_private_user_presenter.rb +0 -46
  502. data/app/views/decidim/participants_account_mailer/removal_notification.html.erb +0 -11
  503. data/app/views/decidim/participatory_space_private_users/_participatory_space_private_user.html.erb +0 -1
  504. data/app/views/layouts/decidim/footer/_main_language_chooser.html.erb +0 -26
  505. data/app/views/layouts/decidim/header/_menu_breadcrumb_items.html.erb +0 -34
  506. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_desktop.html.erb +0 -10
  507. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_mobile.html.erb +0 -17
  508. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_top_left.html.erb +0 -2
  509. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile_tablet.html.erb +0 -33
  510. data/app/views/layouts/decidim/header/_mobile_language_choose.html.erb +0 -25
  511. data/lib/decidim/core/test/shared_examples/has_private_users.rb +0 -63
  512. data/lib/decidim/core/test/shared_examples/participatory_space_dropdown_metadata_cell_examples.rb +0 -81
  513. data/lib/decidim/has_private_users.rb +0 -57
  514. data/lib/decidim/maintenance/import_models/assembly_type.rb +0 -49
  515. data/lib/decidim/maintenance/import_models/participatory_process_type.rb +0 -21
  516. data/lib/decidim/query_extensions.rb +0 -64
@@ -3,18 +3,18 @@
3
3
  module Decidim
4
4
  # This class serializes a User so can be exported to CSV
5
5
  module DownloadYourDataSerializers
6
- class DownloadYourDataParticipatorySpacePrivateUserSerializer < Decidim::Exporters::Serializer
6
+ class DownloadYourDataMemberSerializer < Decidim::Exporters::Serializer
7
7
  include Decidim::ResourceHelper
8
8
 
9
9
  # Public: Exports a hash with the serialized data for this user.
10
10
  def serialize
11
11
  {
12
12
  id: resource.id,
13
- privatable_to: {
14
- id: resource.privatable_to_id,
15
- type: resource.privatable_to_type,
16
- title: resource.privatable_to.title,
17
- slug: resource.privatable_to.slug
13
+ participatory_space: {
14
+ id: resource.participatory_space_id,
15
+ type: resource.participatory_space_type,
16
+ title: resource.participatory_space.title,
17
+ slug: resource.participatory_space.slug
18
18
  },
19
19
  created_at: resource.created_at,
20
20
  updated_at: resource.updated_at,
@@ -8,12 +8,12 @@ module Decidim
8
8
  autoload :DownloadYourDataFollowSerializer, "decidim/download_your_data_serializers/download_your_data_follow_serializer"
9
9
  autoload :DownloadYourDataNotificationSerializer, "decidim/download_your_data_serializers/download_your_data_notification_serializer"
10
10
  autoload :DownloadYourDataIdentitySerializer, "decidim/download_your_data_serializers/download_your_data_identity_serializer"
11
- autoload :DownloadYourDataParticipatorySpacePrivateUserSerializer, "decidim/download_your_data_serializers/download_your_data_participatory_space_private_user_serializer"
11
+ autoload :DownloadYourDataMemberSerializer, "decidim/download_your_data_serializers/download_your_data_member_serializer"
12
12
 
13
13
  def self.data_entities
14
14
  ["Decidim::Follow", "Decidim::Identity",
15
15
  "Decidim::Messaging::Conversation", "Decidim::Notification",
16
- "Decidim::ParticipatorySpacePrivateUser", "Decidim::Report", "Decidim::User"] |
16
+ "Decidim::ParticipatorySpace::Member", "Decidim::Report", "Decidim::User"] |
17
17
  Decidim.component_manifests.map(&:data_portable_entities).flatten |
18
18
  Decidim.participatory_space_manifests.map(&:data_portable_entities).flatten |
19
19
  (Decidim::Comments.data_portable_entities.flatten if defined?(Decidim::Comments))
@@ -25,13 +25,14 @@ module Decidim
25
25
  #
26
26
  # @return [EngineRouter] The new engine router
27
27
  def self.admin_proxy(target)
28
- new(target.mounted_admin_engine, target.mounted_params, target)
28
+ new(target.mounted_admin_engine, target.mounted_params.except(:locale), target, admin: true)
29
29
  end
30
30
 
31
- def initialize(engine, default_url_options, target = nil)
31
+ def initialize(engine, default_url_options, target = nil, options = {})
32
32
  @engine = engine
33
33
  @default_url_options = default_url_options
34
34
  @target = target
35
+ @admin = options.fetch(:admin, false)
35
36
  end
36
37
 
37
38
  def default_url_options
@@ -47,13 +48,35 @@ module Decidim
47
48
 
48
49
  filter_slug_params!(method_name)
49
50
 
50
- send(engine).send(method_name, *)
51
+ result = send(engine).send(method_name, *)
52
+ admin? ? rewrite_locale_in_admin_path(result, method_name) : result
51
53
  end
52
54
 
53
55
  private
54
56
 
55
57
  attr_reader :engine, :target
56
58
 
59
+ def admin?
60
+ @admin
61
+ end
62
+
63
+ # Rewrites the locale segment in an admin path or URL to match the current
64
+ # I18n.locale. The admin engine routes are mounted under /:locale/admin but
65
+ # sub-engines mounted inside the admin engine do not have direct access to
66
+ # the locale segment, so they fall back to Decidim.default_locale. This
67
+ # method corrects the generated path/URL after the fact.
68
+ #
69
+ # For paths: /en/admin/... -> /ca/admin/...
70
+ # For URLs: http://host/en/admin/... -> http://host/ca/admin/...
71
+ def rewrite_locale_in_admin_path(result, method_name)
72
+ locale = I18n.locale.to_s
73
+ if method_name.to_s.end_with?("_url")
74
+ result.sub(%r{(https?://[^/]+)/[^/]+/}, "\\1/#{locale}/")
75
+ else
76
+ result.sub(%r{\A/[^/]+/}, "/#{locale}/")
77
+ end
78
+ end
79
+
57
80
  def filter_slug_params!(method_name)
58
81
  return if target.nil?
59
82
  return unless target.respond_to?(:mounted_params)
@@ -67,9 +90,11 @@ module Decidim
67
90
  end
68
91
 
69
92
  def configured_default_url_options
70
- @configured_default_url_options ||=
71
- ActionMailer::Base.default_url_options.presence ||
72
- UrlOptionResolver.new.options
93
+ @configured_default_url_options ||= begin
94
+ opts = ActionMailer::Base.default_url_options.presence ||
95
+ UrlOptionResolver.new.options
96
+ opts
97
+ end
73
98
  end
74
99
  end
75
100
  end
@@ -66,7 +66,7 @@ module Decidim
66
66
  result.merge(flatten(value, new_key))
67
67
  end
68
68
  when Array
69
- { key.to_s => object.compact.map(&:to_s).join(", ") }
69
+ { key.to_s => object.compact.join(", ") }
70
70
  else
71
71
  { key.to_s => object }
72
72
  end
@@ -50,7 +50,7 @@ module Decidim
50
50
  private
51
51
 
52
52
  def check_boxes_tree_id(*args)
53
- args.map(&:to_s).join("_")
53
+ args.join("_")
54
54
  end
55
55
 
56
56
  def default_form_type_for_collection(collection)
@@ -45,14 +45,6 @@ module Decidim
45
45
  end
46
46
  # rubocop:enable Metrics/ParameterLists
47
47
 
48
- def create_language_selector(locales, tabs_id, name)
49
- if locales.count > 4
50
- language_selector_select(locales, tabs_id, name)
51
- else
52
- language_tabs(locales, tabs_id, name)
53
- end
54
- end
55
-
56
48
  # Public: Generates a form field for each locale.
57
49
  #
58
50
  # type - The form field's type, like `text_area` or `text_field`
@@ -65,23 +57,11 @@ module Decidim
65
57
 
66
58
  tabs_id = sanitize_tabs_selector(options[:tabs_id] || "#{object_name}-#{name}-tabs")
67
59
 
68
- label_tabs = content_tag(:div, class: "label--tabs") do
69
- field_label = label_i18n(name, options[:label] || label_for(name), required: options[:required])
60
+ error_on_locale = locales.find { |locale| error?(name_with_locale(name, locale)) }
70
61
 
71
- language_selector = "".html_safe
72
- language_selector = create_language_selector(locales, tabs_id, name) if options[:label] != false
62
+ label_tabs = translated_labels(name, options, tabs_id, error_on_locale)
73
63
 
74
- safe_join [field_label, language_selector]
75
- end
76
-
77
- tabs_content = content_tag(:div, class: "tabs-content", data: { tabs_content: tabs_id }) do
78
- locales.each_with_index.inject("".html_safe) do |string, (locale, index)|
79
- tab_content_id = "#{tabs_id}-#{name}-panel-#{index}"
80
- string + content_tag(:div, class: tab_element_class_for("panel", index), id: tab_content_id, "aria-hidden": tab_attr_aria_hidden_for(index)) do
81
- send(type, name_with_locale(name, locale), options.merge(label: false))
82
- end
83
- end
84
- end
64
+ tabs_content = translated_tabs(type, name, options, tabs_id, error_on_locale)
85
65
 
86
66
  safe_join [label_tabs, tabs_content]
87
67
  end
@@ -452,6 +432,44 @@ module Decidim
452
432
 
453
433
  private
454
434
 
435
+ def translated_tabs(type, name, options, tabs_id, error_on_locale = nil)
436
+ content_tag(:div, class: "tabs-content", data: { tabs_content: tabs_id }) do
437
+ locales.each_with_index.inject("".html_safe) do |string, (locale, index)|
438
+ tab_content_id = sanitize_tabs_selector "#{tabs_id}-#{name}-panel-#{index}"
439
+
440
+ aria_hidden = (error_on_locale.present? ? !locale.eql?(error_on_locale) : index.positive?).to_s
441
+ css_class = if error_on_locale.present?
442
+ tab_element_class_for("panel", locale.eql?(error_on_locale) ? 0 : 1)
443
+ else
444
+ tab_element_class_for("panel", index)
445
+ end
446
+
447
+ string + content_tag(:div, class: css_class, id: tab_content_id, "aria-hidden": aria_hidden) do
448
+ send(type, name_with_locale(name, locale), options.merge(label: false))
449
+ end
450
+ end
451
+ end
452
+ end
453
+
454
+ def create_language_selector(locales, tabs_id, name, error_on_locale = nil)
455
+ if locales.count > 4
456
+ language_selector_select(locales, tabs_id, name, error_on_locale)
457
+ else
458
+ language_tabs(locales, tabs_id, name, error_on_locale)
459
+ end
460
+ end
461
+
462
+ def translated_labels(name, options, tabs_id, error_on_locale = nil)
463
+ content_tag(:div, class: "label--tabs") do
464
+ field_label = label_i18n(name, options[:label] || label_for(name), required: options[:required])
465
+
466
+ language_selector = "".html_safe
467
+ language_selector = create_language_selector(locales, tabs_id, name, error_on_locale) if options[:label] != false
468
+
469
+ safe_join [field_label, language_selector]
470
+ end
471
+ end
472
+
455
473
  def editor_hidden_options(name, options)
456
474
  hidden_options = extract_validations(name, options).merge(options)
457
475
  if hidden_options[:minlength] || hidden_options[:maxlength]
@@ -682,9 +700,7 @@ module Decidim
682
700
  end
683
701
 
684
702
  def tab_attr_aria_hidden_for(index)
685
- return "false" if index.zero?
686
-
687
- "true"
703
+ index.positive?.to_s
688
704
  end
689
705
 
690
706
  def locales
@@ -799,29 +815,35 @@ module Decidim
799
815
  class: "columns")
800
816
  end
801
817
 
802
- def language_selector_select(locales, tabs_id, name)
818
+ # i18n-tasks-use t('locale.name_with_error')
819
+ # i18n-tasks-use t('locale.name')
820
+ def language_selector_select(locales, tabs_id, name, error_on_locale = nil)
803
821
  content_tag(:div) do
804
822
  content_tag(:select, id: tabs_id, class: "language-change", data: { controller: "language-change" }) do
805
823
  locales.each_with_index.inject("".html_safe) do |string, (locale, index)|
806
- title = if error?(name_with_locale(name, locale))
807
- I18n.with_locale(locale) { I18n.t("name_with_error", scope: "locale") }
808
- else
809
- I18n.with_locale(locale) { I18n.t("name", scope: "locale") }
810
- end
824
+ title = locale.eql?(error_on_locale) ? "name_with_error" : "name"
825
+ title = I18n.with_locale(locale) { I18n.t(title, scope: "locale") }
811
826
  tab_content_id = sanitize_tabs_selector "#{tabs_id}-#{name}-panel-#{index}"
812
- string + content_tag(:option, title, value: "##{tab_content_id}")
827
+ string + content_tag(:option, title, value: "##{tab_content_id}", selected: locale.eql?(error_on_locale))
813
828
  end
814
829
  end
815
830
  end
816
831
  end
817
832
 
818
- def language_tabs(locales, tabs_id, name)
833
+ def language_tabs(locales, tabs_id, name, error_on_locale = nil)
819
834
  content_tag(:ul, class: "tabs tabs--lang", id: tabs_id, data: { tabs: true }) do
820
835
  locales.each_with_index.inject("".html_safe) do |string, (locale, index)|
821
- string + content_tag(:li, class: tab_element_class_for("title", index)) do
836
+ display = if error_on_locale.nil?
837
+ index
838
+ else
839
+ locale.eql?(error_on_locale) ? 0 : 1
840
+ end
841
+
842
+ css_class = tab_element_class_for("title", display)
843
+ string + content_tag(:li, class: css_class) do
822
844
  title = I18n.with_locale(locale) { I18n.t("name", scope: "locale") }
823
845
  element_class = nil
824
- element_class = "is-tab-error" if error?(name_with_locale(name, locale))
846
+ element_class = "is-tab-error" if locale.eql?(error_on_locale)
825
847
  tab_content_id = sanitize_tabs_selector "#{tabs_id}-#{name}-panel-#{index}"
826
848
  content_tag(:a, title, href: "##{tab_content_id}", class: element_class)
827
849
  end
@@ -75,10 +75,20 @@ module Decidim
75
75
  current_component: @controller.try(:current_component),
76
76
  current_user: @controller.try(:current_user),
77
77
  current_participatory_space: @controller.try(:current_participatory_space)
78
- }
78
+ }.merge(@controller.form_context)
79
79
  end
80
80
  end.new(klass, self)
81
81
  end
82
+
83
+ # Provides additional context values for forms built through this factory.
84
+ # Controllers (and extension gems) can override this method to inject
85
+ # extra context into form objects, which will be merged into the base
86
+ # context defined in `context`.
87
+ #
88
+ # This method must always return a Hash, typically with symbol keys.
89
+ def form_context
90
+ {}
91
+ end
82
92
  end
83
93
  end
84
94
  end
@@ -45,8 +45,8 @@ module Decidim
45
45
  def step_settings
46
46
  return {} unless participatory_space.allows_steps?
47
47
 
48
- participatory_space.steps.each_with_object({}) do |step, result|
49
- result[step.id.to_s] = new_settings_schema(:step, self[:settings].dig("steps", step.id.to_s))
48
+ participatory_space.steps.to_h do |step|
49
+ [step.id.to_s, new_settings_schema(:step, self[:settings].dig("steps", step.id.to_s))]
50
50
  end
51
51
  end
52
52
 
@@ -10,6 +10,7 @@ module Decidim
10
10
  class LegacyFormBuilder < ActionView::Helpers::FormBuilder
11
11
  include ActionView::Helpers::TagHelper
12
12
  include ActionView::Helpers::OutputSafetyHelper
13
+
13
14
  %w(file_field email_field text_field url_field
14
15
  number_field search_field color_field)
15
16
  .each do |method_name|
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Handle the locale redirects in the route files
4
+ # It tries to detect a place where the locale is being present, either as a GET parameter,
5
+ # or a session, or if there is nothing it will return the default locale of the organization.
6
+ module Decidim
7
+ class LocaleRouterDetector
8
+ def initialize(request, params)
9
+ @request = request
10
+ @input_params = params
11
+ end
12
+
13
+ def locale
14
+ available_locales.map(&:to_sym).include?(extracted_locale.to_sym) ? extracted_locale : default_locale
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :request, :input_params
20
+
21
+ def extracted_locale
22
+ input_params[:locale].presence || request.parameters[:locale].presence || current_user_locale || request.session[:user_locale].presence || I18n.locale
23
+ end
24
+
25
+ def current_user_locale
26
+ request.env["warden"]&.user("user")&.locale.presence
27
+ end
28
+
29
+ def available_locales
30
+ (organization || Decidim).available_locales
31
+ end
32
+
33
+ def default_locale
34
+ (organization || Decidim).default_locale
35
+ end
36
+
37
+ def organization
38
+ request.env["decidim.current_organization"]
39
+ end
40
+ end
41
+ end
@@ -11,7 +11,7 @@ module Decidim
11
11
  "Decidim::Budgets::Budget", "Decidim::Budgets::Project",
12
12
  "Decidim::Debates::Debate",
13
13
  "Decidim::Meetings::Meeting",
14
- "Decidim::Proposals::CollaborativeDraft", "Decidim::Proposals::Proposal"
14
+ "Decidim::Proposals::Proposal"
15
15
  ]
16
16
  participatory_space_models ["Decidim::Assembly", "Decidim::ParticipatoryProcess", "Decidim::Conference", "Decidim::Initiative"]
17
17
 
@@ -7,8 +7,6 @@ module Decidim
7
7
  module Maintenance
8
8
  module ImportModels
9
9
  autoload :ApplicationRecord, "decidim/maintenance/import_models/application_record"
10
- autoload :ParticipatoryProcessType, "decidim/maintenance/import_models/participatory_process_type"
11
- autoload :AssemblyType, "decidim/maintenance/import_models/assembly_type"
12
10
  autoload :Scope, "decidim/maintenance/import_models/scope"
13
11
  autoload :Area, "decidim/maintenance/import_models/area"
14
12
  autoload :AreaType, "decidim/maintenance/import_models/area_type"
@@ -85,7 +85,7 @@ module Decidim
85
85
  component = GlobalID::Locator.locate(component_id)
86
86
  if component
87
87
  begin
88
- component.update!(settings: { taxonomy_filters: [filter.id.to_s] })
88
+ component.update!(settings: component.settings.to_h.merge(taxonomy_filters: [filter.id.to_s]))
89
89
  result[:components_assigned][filter.internal_name[organization.default_locale]] ||= []
90
90
  result[:components_assigned][filter.internal_name[organization.default_locale]] << component_id
91
91
  rescue ActiveRecord::RecordInvalid
@@ -37,19 +37,20 @@ module Decidim
37
37
  template.snippets.add(:decidim_geocoding_scripts, template.append_javascript_pack_tag("decidim_geocoding"))
38
38
  template.snippets.add(:decidim_geocoding_styles, template.append_stylesheet_pack_tag("decidim_geocoding"))
39
39
 
40
- template.content_tag(:div, class: "geocoding-container") do
40
+ template.content_tag(:div, class: "geocoding") do
41
41
  template.text_field(
42
42
  object_name,
43
43
  method,
44
44
  options.merge("data-decidim-geocoding" => view_options.to_json)
45
45
  ) +
46
- template.content_tag(:div, class: "input-group-button user-device-location") do
47
- template.content_tag(:button, class: "button button__sm md:button__sm button__text-secondary", type: "button", data: {
46
+ template.content_tag(:div, class: "input-group-button geocoding__locate") do
47
+ template.content_tag(:button, class: "button button__sm md:button__sm button__text-secondary geocoding__button", type: "button", data: {
48
48
  input: "#{object_name}_#{method}",
49
49
  latitude: "#{object_name}_latitude",
50
50
  longitude: "#{object_name}_longitude",
51
51
  error_no_location: I18n.t("errors.no_device_location", scope: "decidim.proposals.forms"),
52
52
  error_unsupported: I18n.t("errors.device_not_supported", scope: "decidim.proposals.forms"),
53
+ locating_text: I18n.t("locating", scope: "decidim.proposals.forms"),
53
54
  url: Decidim::Core::Engine.routes.url_helpers.locate_path
54
55
  }) do
55
56
  icon("map-pin-line", role: "img", "aria-hidden": true) + " #{I18n.t("use_my_location", scope: "decidim.proposals.forms")}"
@@ -30,7 +30,9 @@ module Decidim
30
30
  def builder_options
31
31
  {
32
32
  marker_color: organization.colors.fetch("primary", "#e02d2d"),
33
- tile_layer: tile_layer_configuration
33
+ tile_layer: tile_layer_configuration,
34
+ zoom_in_text: I18n.t("zoom_in", scope: "decidim.map.dynamic"),
35
+ zoom_out_text: I18n.t("zoom_out", scope: "decidim.map.dynamic")
34
36
  }
35
37
  end
36
38
 
@@ -68,7 +68,7 @@ module Decidim
68
68
  # Converts a hash with Ruby-style key names (snake_case) to JS-style key
69
69
  # names (camelCase).
70
70
  #
71
- # @param [Hash] The original hash with Ruby-style hash keys in
71
+ # @param hash [Hash] The original hash with Ruby-style hash keys in
72
72
  # snake_case format.
73
73
  #
74
74
  # @return [Hash] The resulting hash with JS-style hash keys in camelCase
@@ -22,7 +22,7 @@ module Decidim
22
22
  # A common search method to lookup information about an address or
23
23
  # coordinates from the geocoder.
24
24
  #
25
- # @param query [String, Array(<Float, String>, <Float, String>)] The
25
+ # @param query [Array(Array<Float, String>, Array<Float, String>)] The
26
26
  # search query to be passed to the geocoder
27
27
  # @param options [Hash] Extra options to be provided for the geocoder
28
28
  # search
@@ -55,7 +55,7 @@ module Decidim
55
55
  # (latitude/longitude) coordinates and returns a clear text address for
56
56
  # the closest result.
57
57
  #
58
- # @param coordinates [Array(<Float, String>, <Float, String>)] An array of
58
+ # @param coordinates [Array(Array<Float, String>, Array<Float, String>)] An array of
59
59
  # the coordinates where the first element is the latitude and the second
60
60
  # element is the longitude
61
61
  # @param options [Hash] Extra options to be provided for the geocoder
@@ -11,14 +11,10 @@ module Decidim
11
11
  # Creates a link for the static maps. This will point to an external map
12
12
  # service where the user can further explore the given location.
13
13
  #
14
- # @param params [Hash] The parameters for the static map URL
15
- # @option params [Float, String] :latitude The latitude of the map
16
- # position to be linked to
17
- # @option params [Float, String] :longitude The longitude of the map
18
- # position to be linked to
19
- # @option params [Hash] :options Extra options that can be provided to the
20
- # map URL containing the following keys:
21
- # * zoom: A number to represent the zoom value of the map (default 17)
14
+ # @param latitude [Float, String] The latitude of the map position to be linked to
15
+ # @param longitude [Float, String] The longitude of the map position to be linked to
16
+ # @param options [Hash{Symbol => Object}] The parameters for the static map URL
17
+ # @option options [Integer] :zoom A number to represent the zoom value of the map (default 17)
22
18
  #
23
19
  # @return [String] The link where the static map images link to.
24
20
  def link(latitude:, longitude:, options: {})
@@ -40,20 +36,12 @@ module Decidim
40
36
  # Creates a URL that generates a static map image for the given map
41
37
  # location with the given options.
42
38
  #
43
- # @param params [Hash] The parameters for the static map URL
44
- # @option params [Float, String] :latitude The latitude of the map
45
- # position
46
- # @option params [Float, String] :longitude The longitude of the map
47
- # position
48
- # @option params [Hash] :options Extra options that can be provided to
49
- # the underlying map service to generate the image with containing the
50
- # following keys:
51
- # * zoom: A number to represent the zoom value of the map image (default
52
- # 15)
53
- # * width: A number to represent the pixel width of the map image
54
- # (default 300)
55
- # * height: A number to represent the pixel height of the map image
56
- # (default 300)
39
+ # @param latitude [Float, String] :latitude The latitude of the map position
40
+ # @param longitude [Float, String] The longitude of the map position
41
+ # @param options [Hash] Extra options for the static map URL
42
+ # @option options [Integer] :zoom Zoom level of the map image (default 15)
43
+ # @option options [Integer] :width Pixel width of the map image (default 300)
44
+ # @option options [Integer] :height Pixel height of the map image (default 300)
57
45
  #
58
46
  # @return [String] The URL to request for the static map image.
59
47
  def url(latitude:, longitude:, options: {})
@@ -11,12 +11,9 @@ module Decidim
11
11
 
12
12
  # Initializes the map utility.
13
13
  #
14
- # @param options [Hash] The options for the map utility
15
- # @option options [Decidim::Organization] :organization The organization
16
- # where the map functionality is used
17
- # @option options [String] :config The configuration hash specific to the
18
- # utility
19
- # @option options [String] :locale The locale to use for the queries
14
+ # @param organization [Decidim::Organization] The organization where the map functionality is used
15
+ # @param config [String] The configuration hash specific to the utility
16
+ # @param locale [String] The locale to use for the queries
20
17
  def initialize(organization:, config:, locale: I18n.locale.to_s)
21
18
  @organization = organization
22
19
  @locale = locale
data/lib/decidim/map.rb CHANGED
@@ -24,7 +24,7 @@ module Decidim
24
24
  # Public: Returns a boolean indicating if the category of mapping services
25
25
  # is available for this instance that the provided key represents.
26
26
  #
27
- # @param *categories [Symbol] The utility category key to check the
27
+ # @param categories [Array<Symbol>] The utility category key to check the
28
28
  # availability for.
29
29
  # @return [Boolean] A boolean indicating if the category of mapping services
30
30
  # is available.
@@ -58,7 +58,7 @@ module Decidim
58
58
  # map utilities. The configured utility class (through Decidim.maps) is
59
59
  # should be under these namespaces.
60
60
  #
61
- # @return [Hash<Symbol, Module>] The modules within which the utility
61
+ # @return [Hash{Symbol => Module}] The modules within which the utility
62
62
  # classes should be defined in.
63
63
  def self.utility_modules
64
64
  @utility_modules ||= {}
data/lib/decidim/menu.rb CHANGED
@@ -90,7 +90,7 @@ module Decidim
90
90
 
91
91
  # Public: Registers a new item for the menu
92
92
  #
93
- # @param identifier [String, Symbol] A compulsory label for the menu item
93
+ # @param item [String, Symbol] A compulsory label for the menu item
94
94
  #
95
95
  # @example
96
96
  #
@@ -11,6 +11,7 @@ module Decidim
11
11
  # @param url [String, Symbol] The URL this item will link to
12
12
  # @param options [Hash] The options for the menu item
13
13
  #
14
+ # @param [Object] identifier
14
15
  def initialize(label, url, identifier, options = {})
15
16
  @label = label
16
17
  @url = url
@@ -11,7 +11,7 @@ module Decidim
11
11
  # registers a MenuItem DSL block for the menu.
12
12
  #
13
13
  # @param name [Symbol] Name of the menu
14
- # @param &block [Menu] Registration body of the menu. It is stored to be
14
+ # @param block [Menu] Registration body of the menu. It is stored to be
15
15
  # evaluated at rendering time
16
16
  #
17
17
  def register(name, &block)
@@ -111,7 +111,7 @@ module Decidim
111
111
  private
112
112
 
113
113
  def affected_users
114
- @affected_users ||= (@reportable.try(:authors) || [@reportable.try(:author)]).select { |author| author.is_a?(Decidim::User) }
114
+ @affected_users ||= (@reportable.try(:authors) || [@reportable.try(:author)]).grep(Decidim::User)
115
115
  end
116
116
 
117
117
  def report_reasons
@@ -1,22 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Decidim
4
- class NewsletterEncryptor
4
+ class NewsletterEncryptor < AttributeEncryptor
5
5
  # Method to create string encrypt using sent_at time to unsubscribe's user
6
6
  def self.sent_at_encrypted(user_id, sent_at)
7
- crypt_data.encrypt_and_sign("#{user_id}-#{sent_at.to_i}")
7
+ cryptor.encrypt("#{user_id}-#{sent_at.to_i}")
8
8
  end
9
9
 
10
10
  # Method to decrypt sent_at newsletter.
11
11
  def self.sent_at_decrypted(string_encrypted)
12
- crypt_data.decrypt_and_verify(string_encrypted)
12
+ cryptor.decrypt(string_encrypted)
13
13
  end
14
14
 
15
- def self.crypt_data
16
- key = ActiveSupport::KeyGenerator.new("sent_at", hash_digest_class: OpenSSL::Digest::SHA1).generate_key(
17
- Rails.application.secret_key_base, ActiveSupport::MessageEncryptor.key_len
18
- )
19
- ActiveSupport::MessageEncryptor.new(key)
15
+ def self.cryptor
16
+ @cryptor ||= new(secret: "sent_at")
20
17
  end
21
18
  end
22
19
  end
@@ -48,7 +48,7 @@ module Decidim
48
48
  # Note: this cannot fetch the default settings from the class instance
49
49
  # variable "defaults" because that would cause an infinite loop.
50
50
  #
51
- # @param *chain [Symbol, String] The configuration key(s) to dig into
51
+ # @param chain [Array<Symbol, String>] The configuration key(s) to dig into
52
52
  # inside the default configurations hash.
53
53
  # @return The value found from the default configurations hash.
54
54
  def default(*chain)
@@ -203,7 +203,7 @@ module Decidim
203
203
  # Turns the stars into wildcard regular expression matches in the matching
204
204
  # strings.
205
205
  #
206
- # @param [Array<String>] An array of glob strings to match against.
206
+ # @param types [Array<String>] An array of glob strings to match against.
207
207
  # @return [Array<Regexp>] An array of regular expressions to match against.
208
208
  def content_type_array(types)
209
209
  types.map do |match_string|
@@ -32,6 +32,7 @@ module Decidim
32
32
  def mounted_params
33
33
  {
34
34
  :host => organization.host,
35
+ :locale => I18n.locale,
35
36
  :"#{underscored_name}_slug" => slug
36
37
  }
37
38
  end