decidim-core 0.28.5 → 0.29.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (714) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/app/cells/decidim/activities_cell.rb +0 -1
  4. data/app/cells/decidim/activity_cell.rb +7 -6
  5. data/app/cells/decidim/address/online.erb +2 -2
  6. data/app/cells/decidim/address_cell.rb +3 -9
  7. data/app/cells/decidim/amendable/amend_button_card_cell.rb +0 -2
  8. data/app/cells/decidim/amendable/amendments_cell.rb +0 -2
  9. data/app/cells/decidim/amendable/announcement_cell.rb +10 -14
  10. data/app/cells/decidim/amendable/emendation_actions_cell.rb +0 -2
  11. data/app/cells/decidim/amendable/promote_button_card_cell.rb +0 -2
  12. data/app/cells/decidim/amendable/wizard_step_form_cell.rb +6 -19
  13. data/app/cells/decidim/announcement/show.erb +1 -1
  14. data/app/cells/decidim/announcement_cell.rb +6 -2
  15. data/app/cells/decidim/attachments_file_tab/show.erb +3 -0
  16. data/app/cells/decidim/attachments_file_tab_cell.rb +11 -0
  17. data/app/cells/decidim/attachments_link_tab/show.erb +12 -0
  18. data/app/cells/decidim/attachments_link_tab_cell.rb +21 -0
  19. data/app/cells/decidim/author/flag.erb +2 -2
  20. data/app/cells/decidim/author/show.erb +4 -5
  21. data/app/cells/decidim/author_cell.rb +0 -28
  22. data/app/cells/decidim/authorization_modal_cell.rb +0 -3
  23. data/app/cells/decidim/badge_cell.rb +0 -4
  24. data/app/cells/decidim/badges_cell.rb +0 -2
  25. data/app/cells/decidim/button_cell.rb +0 -3
  26. data/app/cells/decidim/card_cell.rb +1 -5
  27. data/app/cells/decidim/card_g/show.erb +1 -1
  28. data/app/cells/decidim/card_g_cell.rb +4 -7
  29. data/app/cells/decidim/card_l/image.erb +2 -2
  30. data/app/cells/decidim/card_l/space.erb +1 -1
  31. data/app/cells/decidim/card_l_cell.rb +3 -8
  32. data/app/cells/decidim/card_metadata_cell.rb +1 -5
  33. data/app/cells/decidim/card_s/show.erb +3 -5
  34. data/app/cells/decidim/card_s_cell.rb +1 -4
  35. data/app/cells/decidim/coauthorships_cell.rb +0 -2
  36. data/app/cells/decidim/comments_button_cell.rb +0 -2
  37. data/app/cells/decidim/content_blocks/footer_sub_hero/show.erb +1 -1
  38. data/app/cells/decidim/content_blocks/footer_sub_hero_cell.rb +0 -3
  39. data/app/cells/decidim/content_blocks/hero/show.erb +1 -1
  40. data/app/cells/decidim/content_blocks/hero_cell.rb +1 -2
  41. data/app/cells/decidim/content_blocks/highlighted_content_banner/show.erb +1 -1
  42. data/app/cells/decidim/content_blocks/highlighted_content_banner_cell.rb +0 -2
  43. data/app/cells/decidim/content_blocks/how_to_participate/show.erb +1 -1
  44. data/app/cells/decidim/content_blocks/how_to_participate_cell.rb +0 -1
  45. data/app/cells/decidim/content_blocks/participatory_space_documents/content.erb +1 -1
  46. data/app/cells/decidim/content_blocks/participatory_space_documents_cell.rb +17 -1
  47. data/app/cells/decidim/content_blocks/participatory_space_hero_cell.rb +2 -4
  48. data/app/cells/decidim/content_blocks/participatory_space_last_activity_cell.rb +1 -3
  49. data/app/cells/decidim/content_blocks/stats/show.erb +1 -1
  50. data/app/cells/decidim/content_blocks/stats_cell.rb +1 -1
  51. data/app/cells/decidim/content_blocks/sub_hero_cell.rb +0 -3
  52. data/app/cells/decidim/date_range/show.erb +10 -10
  53. data/app/cells/decidim/date_range_cell.rb +0 -2
  54. data/app/cells/decidim/diff_cell.rb +0 -5
  55. data/app/cells/decidim/documents_panel/show.erb +4 -0
  56. data/app/cells/decidim/documents_panel_cell.rb +9 -1
  57. data/app/cells/decidim/endorsement_buttons_cell.rb +6 -14
  58. data/app/cells/decidim/flag_modal/flag_user.erb +3 -3
  59. data/app/cells/decidim/followers_cell.rb +0 -1
  60. data/app/cells/decidim/following_cell.rb +0 -1
  61. data/app/cells/decidim/footer_topics/show.erb +8 -0
  62. data/app/cells/decidim/footer_topics_cell.rb +39 -0
  63. data/app/cells/decidim/groups_cell.rb +0 -3
  64. data/app/cells/decidim/linked_resources_for_cell.rb +0 -3
  65. data/app/cells/decidim/members_cell.rb +0 -1
  66. data/app/cells/decidim/nav_links/show.erb +3 -3
  67. data/app/cells/decidim/navbar_admin_link_cell.rb +0 -2
  68. data/app/cells/decidim/newsletter_templates/base_cell.rb +0 -1
  69. data/app/cells/decidim/newsletter_templates/basic_only_text/show.erb +2 -2
  70. data/app/cells/decidim/newsletter_templates/image_text_cta/show.erb +2 -2
  71. data/app/cells/decidim/newsletter_templates/image_text_cta_cell.rb +1 -1
  72. data/app/cells/decidim/notification/show.erb +5 -0
  73. data/app/cells/decidim/notification_actions/base_cell.rb +13 -0
  74. data/app/cells/decidim/notification_actions/buttons/show.erb +5 -0
  75. data/app/cells/decidim/notification_actions/buttons_cell.rb +41 -0
  76. data/app/cells/decidim/notification_cell.rb +9 -3
  77. data/app/cells/decidim/notifications_cell.rb +0 -1
  78. data/app/cells/decidim/pad_iframe/show.erb +2 -2
  79. data/app/cells/decidim/pad_iframe_cell.rb +0 -1
  80. data/app/cells/decidim/participatory_space_dropdown_metadata_cell.rb +1 -2
  81. data/app/cells/decidim/photo_cell.rb +1 -5
  82. data/app/cells/decidim/photos_list_cell.rb +0 -2
  83. data/app/cells/decidim/profile_cell.rb +0 -2
  84. data/app/cells/decidim/profile_sidebar/show.erb +20 -20
  85. data/app/cells/decidim/profile_sidebar_cell.rb +1 -10
  86. data/app/cells/decidim/progress_bar/show.erb +8 -6
  87. data/app/cells/decidim/public_participation/show.erb +1 -1
  88. data/app/cells/decidim/report_button/flag_modal.erb +1 -1
  89. data/app/cells/decidim/resource_types_filter/show.erb +12 -11
  90. data/app/cells/decidim/resource_types_filter_cell.rb +0 -2
  91. data/app/cells/decidim/scopes_picker/show.erb +1 -1
  92. data/app/cells/decidim/scopes_picker_cell.rb +0 -1
  93. data/app/cells/decidim/search_results_cell.rb +1 -1
  94. data/app/cells/decidim/statistic_cell.rb +0 -2
  95. data/app/cells/decidim/tab_panels/show.erb +1 -1
  96. data/app/cells/decidim/tab_panels_cell.rb +12 -2
  97. data/app/cells/decidim/tags_cell.rb +0 -2
  98. data/app/cells/decidim/tos_page_cell.rb +0 -3
  99. data/app/cells/decidim/translation_bar/show.erb +2 -2
  100. data/app/cells/decidim/translation_bar_cell.rb +1 -3
  101. data/app/cells/decidim/upload_modal/files.erb +1 -1
  102. data/app/cells/decidim/upload_modal_cell.rb +1 -3
  103. data/app/cells/decidim/user_conversation/new.erb +1 -1
  104. data/app/cells/decidim/user_conversation/show.erb +1 -1
  105. data/app/cells/decidim/user_conversation_cell.rb +0 -1
  106. data/app/cells/decidim/user_conversations/show.erb +1 -1
  107. data/app/cells/decidim/user_conversations_cell.rb +0 -1
  108. data/app/cells/decidim/user_group_pending_invitations_list_cell.rb +0 -1
  109. data/app/cells/decidim/user_group_pending_requests_list_cell.rb +0 -1
  110. data/app/cells/decidim/user_timeline/show.erb +1 -1
  111. data/app/cells/decidim/version_cell.rb +3 -5
  112. data/app/cells/decidim/versions_list_cell.rb +1 -3
  113. data/app/cells/decidim/versions_list_item_cell.rb +2 -4
  114. data/app/cells/decidim/wizard_step_form/wizard_aside.erb +2 -2
  115. data/app/cells/decidim/wizard_step_form/wizard_header.erb +2 -3
  116. data/app/cells/decidim/wizard_step_form_cell.rb +0 -8
  117. data/app/commands/decidim/amendable/create_draft.rb +4 -4
  118. data/app/commands/decidim/amendable/promote.rb +3 -2
  119. data/app/commands/decidim/amendable/publish_draft.rb +3 -2
  120. data/app/commands/decidim/amendable/update_draft.rb +4 -3
  121. data/app/commands/decidim/amendable/withdraw.rb +1 -1
  122. data/app/commands/decidim/create_follow.rb +4 -4
  123. data/app/commands/decidim/create_omniauth_registration.rb +4 -10
  124. data/app/commands/decidim/create_report.rb +3 -3
  125. data/app/commands/decidim/create_user_report.rb +5 -5
  126. data/app/commands/decidim/delete_follow.rb +4 -4
  127. data/app/commands/decidim/demote_membership.rb +2 -2
  128. data/app/commands/decidim/destroy_account.rb +21 -22
  129. data/app/commands/decidim/endorse_resource.rb +1 -1
  130. data/app/commands/decidim/invite_user_to_group.rb +5 -4
  131. data/app/commands/decidim/update_account.rb +24 -22
  132. data/app/commands/decidim/update_notifications_settings.rb +13 -11
  133. data/app/commands/decidim/update_password.rb +7 -7
  134. data/app/commands/decidim/update_user_interests.rb +9 -7
  135. data/app/controllers/concerns/decidim/devise_authentication_methods.rb +1 -1
  136. data/app/controllers/concerns/decidim/devise_controllers.rb +2 -1
  137. data/app/controllers/concerns/decidim/filter_resource.rb +1 -1
  138. data/app/controllers/concerns/decidim/needs_rtl_direction.rb +23 -0
  139. data/app/controllers/concerns/decidim/paginable.rb +1 -1
  140. data/app/controllers/concerns/decidim/participatory_space_context.rb +1 -23
  141. data/app/controllers/concerns/decidim/payload_info.rb +2 -1
  142. data/app/controllers/concerns/decidim/registers_permissions.rb +4 -4
  143. data/app/controllers/concerns/decidim/use_organization_time_zone.rb +1 -1
  144. data/app/controllers/concerns/decidim/withdrawable.rb +1 -1
  145. data/app/controllers/decidim/account_controller.rb +2 -2
  146. data/app/controllers/{concerns/decidim → decidim}/amendments_controller.rb +3 -16
  147. data/app/controllers/decidim/application_controller.rb +1 -1
  148. data/app/controllers/decidim/components/base_controller.rb +1 -1
  149. data/app/controllers/decidim/devise/invitations_controller.rb +1 -1
  150. data/app/controllers/decidim/devise/passwords_controller.rb +2 -2
  151. data/app/controllers/decidim/doorkeeper/credentials_controller.rb +1 -1
  152. data/app/controllers/decidim/endorsements_controller.rb +1 -1
  153. data/app/controllers/decidim/favicon_controller.rb +1 -1
  154. data/app/controllers/decidim/follows_controller.rb +2 -2
  155. data/app/controllers/decidim/group_invites_controller.rb +36 -9
  156. data/app/controllers/decidim/links_controller.rb +1 -1
  157. data/app/controllers/decidim/newsletters_opt_in_controller.rb +1 -1
  158. data/app/controllers/decidim/notifications_settings_controller.rb +1 -1
  159. data/app/controllers/decidim/profiles_controller.rb +0 -4
  160. data/app/controllers/decidim/report_users_controller.rb +1 -1
  161. data/app/controllers/decidim/reports_controller.rb +1 -1
  162. data/app/controllers/decidim/user_interests_controller.rb +1 -1
  163. data/app/events/decidim/change_nickname_event.rb +0 -1
  164. data/app/events/decidim/invited_to_group_event.rb +29 -0
  165. data/app/events/decidim/welcome_notification_event.rb +2 -4
  166. data/app/forms/decidim/form.rb +4 -0
  167. data/app/forms/decidim/omniauth_registration_form.rb +1 -1
  168. data/app/forms/decidim/upload_validation_form.rb +2 -2
  169. data/app/helpers/concerns/decidim/flash_helper_extensions.rb +1 -1
  170. data/app/helpers/decidim/amendments_helper.rb +4 -14
  171. data/app/helpers/decidim/application_helper.rb +8 -0
  172. data/app/helpers/decidim/authorization_form_helper.rb +2 -2
  173. data/app/helpers/decidim/breadcrumb_helper.rb +1 -1
  174. data/app/helpers/decidim/cells_helper.rb +1 -1
  175. data/app/helpers/decidim/check_boxes_tree_helper.rb +1 -1
  176. data/app/helpers/decidim/cta_button_helper.rb +1 -1
  177. data/app/helpers/decidim/datalist_select_helper.rb +1 -1
  178. data/app/helpers/decidim/decidim_form_helper.rb +3 -3
  179. data/app/helpers/decidim/filters_helper.rb +1 -1
  180. data/app/helpers/decidim/layout_helper.rb +1 -64
  181. data/app/helpers/decidim/localized_locales_helper.rb +1 -1
  182. data/app/helpers/decidim/map_helper.rb +1 -6
  183. data/app/helpers/decidim/menu_helper.rb +9 -1
  184. data/app/helpers/decidim/meta_tags_helper.rb +26 -23
  185. data/app/helpers/decidim/modal_helper.rb +1 -1
  186. data/app/helpers/decidim/orders_helper.rb +1 -1
  187. data/app/helpers/decidim/organization_helper.rb +55 -0
  188. data/app/helpers/decidim/paginate_helper.rb +5 -3
  189. data/app/helpers/decidim/resource_helper.rb +0 -7
  190. data/app/helpers/decidim/sanitize_helper.rb +2 -11
  191. data/app/helpers/decidim/scopes_helper.rb +3 -4
  192. data/app/helpers/decidim/searches_helper.rb +1 -1
  193. data/app/helpers/decidim/short_link_helper.rb +2 -2
  194. data/app/helpers/decidim/translations_helper.rb +2 -2
  195. data/app/helpers/decidim/twitter_search_helper.rb +1 -1
  196. data/app/helpers/decidim/user_profile_helper.rb +0 -1
  197. data/app/jobs/decidim/email_notifications_digest_generator_job.rb +2 -2
  198. data/app/mailers/decidim/application_mailer.rb +6 -2
  199. data/app/mailers/decidim/block_user_mailer.rb +1 -1
  200. data/app/mailers/decidim/decidim_devise_mailer.rb +7 -1
  201. data/app/mailers/decidim/newsletter_mailer.rb +1 -4
  202. data/app/mailers/decidim/newsletters_opt_in_mailer.rb +2 -2
  203. data/app/mailers/decidim/notification_mailer.rb +0 -1
  204. data/app/mailers/decidim/notifications_digest_mailer.rb +0 -1
  205. data/app/mailers/decidim/reported_mailer.rb +6 -3
  206. data/app/mailers/decidim/user_report_mailer.rb +1 -1
  207. data/app/models/decidim/action_log.rb +2 -12
  208. data/app/models/decidim/area_type.rb +1 -1
  209. data/app/models/decidim/attachment.rb +28 -4
  210. data/app/models/decidim/authorization.rb +1 -1
  211. data/app/models/decidim/authorization_transfer.rb +1 -0
  212. data/app/models/decidim/component.rb +3 -6
  213. data/app/models/decidim/content_block.rb +3 -3
  214. data/app/models/decidim/messaging/message.rb +2 -2
  215. data/app/models/decidim/newsletter.rb +9 -9
  216. data/app/models/decidim/notification.rb +2 -2
  217. data/app/models/decidim/organization.rb +23 -2
  218. data/app/models/decidim/push_notification_message.rb +1 -1
  219. data/app/models/decidim/resource_link.rb +1 -1
  220. data/app/models/decidim/user.rb +14 -14
  221. data/app/models/decidim/user_group.rb +2 -2
  222. data/app/packs/src/decidim/a11y.js +61 -11
  223. data/app/packs/src/decidim/append_redirect_url_to_modals.js +14 -24
  224. data/app/packs/src/decidim/attachments/file_or_link_tabs.js +55 -0
  225. data/app/packs/src/decidim/attachments/index.js +1 -0
  226. data/app/packs/src/decidim/back_to_list.js +1 -1
  227. data/app/packs/src/decidim/check_boxes_tree.js +1 -1
  228. data/app/packs/src/decidim/data_consent/consent_manager.js +1 -1
  229. data/app/packs/src/decidim/data_consent/consent_manager.test.js +6 -6
  230. data/app/packs/src/decidim/data_consent/index.js +1 -1
  231. data/app/packs/src/decidim/datepicker/datepicker_functions.js +243 -0
  232. data/app/packs/src/decidim/datepicker/datepicker_listeners.js +78 -0
  233. data/app/packs/src/decidim/datepicker/form_datepicker.js +91 -0
  234. data/app/packs/src/decidim/datepicker/generate_datepicker.js +148 -0
  235. data/app/packs/src/decidim/datepicker/generate_timepicker.js +298 -0
  236. data/app/packs/src/decidim/datepicker/test/date.test.js +118 -0
  237. data/app/packs/src/decidim/datepicker/test/time.test.js +227 -0
  238. data/app/packs/src/decidim/direct_uploads/upload_field.js +8 -21
  239. data/app/packs/src/decidim/direct_uploads/upload_modal.js +0 -3
  240. data/app/packs/src/decidim/editor/extensions/indent/index.js +1 -1
  241. data/app/packs/src/decidim/editor/extensions/video_embed/index.js +4 -4
  242. data/app/packs/src/decidim/editor/test/extensions/decidim_kit.test.js +0 -15
  243. data/app/packs/src/decidim/editor/test/extensions/indent.test.js +1 -1
  244. data/app/packs/src/decidim/editor/test/fixtures/upload_templates.js +1 -1
  245. data/app/packs/src/decidim/editor/test/helpers.js +1 -14
  246. data/app/packs/src/decidim/editor/utilities/paste_transform.js +2 -2
  247. data/app/packs/src/decidim/external_domain_warning.js +2 -2
  248. data/app/packs/src/decidim/external_domain_warning.test.js +4 -4
  249. data/app/packs/src/decidim/form_filter.js +4 -4
  250. data/app/packs/src/decidim/impersonation.js +1 -1
  251. data/app/packs/src/decidim/index.js +11 -8
  252. data/app/packs/src/decidim/input_character_counter.js +2 -2
  253. data/app/packs/src/decidim/input_emoji.js +171 -72
  254. data/app/packs/src/decidim/input_hashtags.js +1 -1
  255. data/app/packs/src/decidim/input_mentions.js +1 -1
  256. data/app/packs/src/decidim/notifications_actions.js +40 -0
  257. data/app/packs/src/decidim/sticky_header.js +87 -0
  258. data/app/packs/src/decidim/sw/sw.js +8 -6
  259. data/app/packs/src/decidim/toggle.js +1 -1
  260. data/app/packs/src/decidim/tooltips.js +23 -43
  261. data/app/packs/stylesheets/decidim/_buttons.scss +1 -1
  262. data/app/packs/stylesheets/decidim/_datepicker.scss +193 -0
  263. data/app/packs/stylesheets/decidim/_dropdown.scss +45 -9
  264. data/app/packs/stylesheets/decidim/_emoji.scss +36 -0
  265. data/app/packs/stylesheets/decidim/_filters.scss +4 -2
  266. data/app/packs/stylesheets/decidim/_flash.scss +2 -2
  267. data/app/packs/stylesheets/decidim/_footer.scss +1 -3
  268. data/app/packs/stylesheets/decidim/_forms.scss +13 -5
  269. data/app/packs/stylesheets/decidim/_header.scss +70 -50
  270. data/app/packs/stylesheets/decidim/_home.scss +1 -1
  271. data/app/packs/stylesheets/decidim/_layout.scss +13 -0
  272. data/app/packs/stylesheets/decidim/_modal.scss +1 -1
  273. data/app/packs/stylesheets/decidim/_modal_update.scss +1 -5
  274. data/app/packs/stylesheets/decidim/_notifications.scss +4 -0
  275. data/app/packs/stylesheets/decidim/_profile.scss +1 -1
  276. data/app/packs/stylesheets/decidim/_progress-bar.scss +1 -1
  277. data/app/packs/stylesheets/decidim/_tabs_x.scss +5 -1
  278. data/app/packs/stylesheets/decidim/_tooltip.scss +10 -10
  279. data/app/packs/stylesheets/decidim/application.scss +4 -0
  280. data/app/packs/stylesheets/decidim/editor.scss +1 -1
  281. data/app/packs/stylesheets/decidim/legacy/conference-diploma.scss +1 -2
  282. data/app/packs/stylesheets/decidim/legacy/leaflet.scss +1 -1
  283. data/app/packs/stylesheets/decidim/vendor/_datepicker_light.scss +228 -0
  284. data/app/permissions/decidim/default_permissions.rb +2 -2
  285. data/app/presenters/decidim/admin_log/organization_presenter.rb +1 -1
  286. data/app/presenters/decidim/admin_log/static_page_presenter.rb +1 -1
  287. data/app/presenters/decidim/attachment_presenter.rb +1 -1
  288. data/app/presenters/decidim/authorization_transfer_presenter.rb +1 -1
  289. data/app/presenters/decidim/component_attachment_collection_presenter.rb +81 -0
  290. data/app/presenters/decidim/footer_menu_presenter.rb +1 -1
  291. data/app/presenters/decidim/home_stats_presenter.rb +1 -1
  292. data/app/presenters/decidim/menu_item_presenter.rb +1 -1
  293. data/app/presenters/decidim/organization_presenter.rb +1 -1
  294. data/app/queries/decidim/last_activity.rb +5 -16
  295. data/app/queries/decidim/metric_measure.rb +1 -1
  296. data/app/queries/decidim/public_activities.rb +1 -1
  297. data/app/queries/decidim/user_groups/admin_memberships.rb +1 -1
  298. data/app/queries/decidim/user_groups/member_memberships.rb +1 -1
  299. data/app/services/decidim/action_logger.rb +3 -3
  300. data/app/services/decidim/base_diff_renderer.rb +2 -26
  301. data/app/services/decidim/download_your_data_exporter.rb +25 -36
  302. data/app/services/decidim/email_notification_generator.rb +5 -14
  303. data/app/services/decidim/log/diff_changeset_calculator.rb +2 -2
  304. data/app/services/decidim/notifications_digest_sending_decider.rb +1 -1
  305. data/app/services/decidim/open_data_exporter.rb +7 -8
  306. data/app/services/decidim/zip_stream/writer.rb +39 -0
  307. data/app/uploaders/decidim/organization_favicon_uploader.rb +1 -1
  308. data/app/uploaders/decidim/record_image_uploader.rb +2 -2
  309. data/app/validators/organization_present_validator.rb +1 -1
  310. data/app/validators/passthru_validator.rb +1 -1
  311. data/app/validators/uploader_image_dimensions_validator.rb +2 -2
  312. data/app/views/decidim/account/show.html.erb +1 -1
  313. data/app/views/decidim/amendments/_wizard_header.html.erb +1 -2
  314. data/app/views/decidim/application/_collection.html.erb +3 -1
  315. data/app/views/decidim/application/_component_documents.html.erb +4 -0
  316. data/app/views/decidim/application/_document.html.erb +23 -9
  317. data/app/views/decidim/block_user_mailer/notify.html.erb +2 -2
  318. data/app/views/decidim/devise/invitations/edit.html.erb +2 -2
  319. data/app/views/decidim/devise/omniauth_registrations/new.html.erb +2 -2
  320. data/app/views/decidim/devise/registrations/new.html.erb +1 -1
  321. data/app/views/decidim/devise/shared/_login_boxes.html.erb +1 -1
  322. data/app/views/decidim/doorkeeper/authorizations/new.html.erb +1 -1
  323. data/app/views/decidim/endorsements/_identity.html.erb +1 -1
  324. data/app/views/decidim/gamification/badges/index.html.erb +1 -1
  325. data/app/views/decidim/manifests/show.json.erb +4 -4
  326. data/app/views/decidim/messaging/conversations/_add_conversation_users.html.erb +2 -2
  327. data/app/views/decidim/messaging/conversations/_error_modal.html.erb +5 -5
  328. data/app/views/decidim/newsletter_mailer/newsletter.html.erb +1 -1
  329. data/app/views/decidim/newsletters/show.html.erb +1 -1
  330. data/app/views/decidim/newsletters_opt_in_mailer/notify.html.erb +2 -2
  331. data/app/views/decidim/offline/show.html.erb +1 -1
  332. data/app/views/decidim/pages/_tabbed.html.erb +5 -5
  333. data/app/views/decidim/pages/index.html.erb +1 -2
  334. data/app/views/decidim/reported_mailer/report.html.erb +4 -2
  335. data/app/views/decidim/scopes/picker.html.erb +5 -5
  336. data/app/views/decidim/searches/_resources_filter_block.html.erb +6 -6
  337. data/app/views/decidim/shared/_extended_navigation_bar.html.erb +8 -8
  338. data/app/views/decidim/shared/_filters.html.erb +5 -5
  339. data/app/views/decidim/shared/_login_modal.html.erb +1 -1
  340. data/app/views/decidim/shared/_orders.html.erb +2 -3
  341. data/app/views/decidim/shared/filters/_check_boxes_tree.html.erb +1 -1
  342. data/app/views/decidim/shared/filters/_collection.html.erb +1 -1
  343. data/app/views/decidim/user_interests/_areas.html.erb +2 -2
  344. data/app/views/decidim/user_report_mailer/notify.html.erb +2 -2
  345. data/app/views/decidim/user_update_mailer/notify.html.erb +1 -1
  346. data/app/views/decidim/widgets/_data_picker.html.erb +1 -1
  347. data/app/views/devise/mailer/invitation_instructions.html.erb +1 -1
  348. data/app/views/devise/mailer/invitation_instructions.text.erb +1 -1
  349. data/app/views/devise/mailer/invite_admin.html.erb +2 -2
  350. data/app/views/devise/mailer/invite_admin.text.erb +2 -2
  351. data/app/views/devise/mailer/invite_collaborator.html.erb +2 -2
  352. data/app/views/devise/mailer/invite_collaborator.text.erb +2 -2
  353. data/app/views/devise/mailer/invite_private_user.html.erb +2 -2
  354. data/app/views/devise/mailer/invite_private_user.text.erb +2 -2
  355. data/app/views/devise/mailer/organization_admin_invitation_instructions.html.erb +1 -1
  356. data/app/views/devise/mailer/organization_admin_invitation_instructions.text.erb +1 -1
  357. data/app/views/layouts/decidim/_application.html.erb +3 -6
  358. data/app/views/layouts/decidim/_data_consent_warning.html.erb +2 -2
  359. data/app/views/layouts/decidim/_decidim_javascript.html.erb +1 -1
  360. data/app/views/layouts/decidim/_head.html.erb +1 -1
  361. data/app/views/layouts/decidim/_head_extra.html.erb +2 -2
  362. data/app/views/layouts/decidim/_impersonation_warning.html.erb +1 -1
  363. data/app/views/layouts/decidim/_js_configuration.html.erb +7 -2
  364. data/app/views/layouts/decidim/_logo.html.erb +2 -2
  365. data/app/views/layouts/decidim/_logo_mobile.html.erb +11 -0
  366. data/app/views/layouts/decidim/_mailer_logo.html.erb +2 -2
  367. data/app/views/layouts/decidim/_meta_tags_config.html.erb +1 -1
  368. data/app/views/layouts/decidim/_wrapper.html.erb +16 -9
  369. data/app/views/layouts/decidim/footer/_main.html.erb +2 -3
  370. data/app/views/layouts/decidim/footer/_main_intro.html.erb +2 -2
  371. data/app/views/layouts/decidim/footer/_main_legal.html.erb +2 -3
  372. data/app/views/layouts/decidim/footer/_main_links.html.erb +13 -11
  373. data/app/views/layouts/decidim/footer/_main_social_media_links.html.erb +8 -8
  374. data/app/views/layouts/decidim/header/_main.html.erb +9 -22
  375. data/app/views/layouts/decidim/header/_main_links_desktop.html.erb +4 -5
  376. data/app/views/layouts/decidim/header/_main_links_mobile_account.html.erb +11 -4
  377. data/app/views/layouts/decidim/header/_main_links_mobile_item_account.html.erb +24 -0
  378. data/app/views/layouts/decidim/header/_main_links_mobile_search.html.erb +0 -21
  379. data/app/views/layouts/decidim/header/_main_menu_mobile.html.erb +12 -0
  380. data/app/views/layouts/decidim/header/_menu_breadcrumb_desktop.html.erb +1 -1
  381. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_mobile.html.erb +17 -0
  382. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_top_left.html.erb +1 -1
  383. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile_tablet.html.erb +1 -1
  384. data/app/views/layouts/decidim/header/_menu_form_search_mobile.html.erb +16 -0
  385. data/app/views/layouts/decidim/header/_mobile_language_choose.html.erb +25 -0
  386. data/app/views/layouts/decidim/mailer.html.erb +2 -2
  387. data/app/views/layouts/decidim/shared/_layout_center.html.erb +1 -1
  388. data/app/views/layouts/decidim/shared/_layout_item.html.erb +0 -14
  389. data/app/views/layouts/decidim/shared/_layout_user_profile.html.erb +2 -2
  390. data/config/initializers/active_storage.rb +3 -0
  391. data/config/initializers/devise.rb +1 -1
  392. data/config/initializers/new_framework_defaults_7_0.rb +145 -0
  393. data/config/locales/ar.yml +3 -54
  394. data/config/locales/bg.yml +56 -57
  395. data/config/locales/ca.yml +78 -71
  396. data/config/locales/cs.yml +54 -63
  397. data/config/locales/de.yml +77 -70
  398. data/config/locales/el.yml +1 -32
  399. data/config/locales/en.yml +69 -62
  400. data/config/locales/es-MX.yml +69 -62
  401. data/config/locales/es-PY.yml +69 -62
  402. data/config/locales/es.yml +74 -67
  403. data/config/locales/eu.yml +251 -257
  404. data/config/locales/fi-plain.yml +70 -63
  405. data/config/locales/fi.yml +128 -121
  406. data/config/locales/fr-CA.yml +62 -61
  407. data/config/locales/fr.yml +56 -55
  408. data/config/locales/ga-IE.yml +0 -16
  409. data/config/locales/gl.yml +1 -22
  410. data/config/locales/hu.yml +38 -57
  411. data/config/locales/id-ID.yml +0 -18
  412. data/config/locales/is-IS.yml +1 -17
  413. data/config/locales/it.yml +0 -65
  414. data/config/locales/ja.yml +83 -74
  415. data/config/locales/lb.yml +0 -30
  416. data/config/locales/lt.yml +2 -49
  417. data/config/locales/lv.yml +0 -25
  418. data/config/locales/nl.yml +1 -30
  419. data/config/locales/no.yml +0 -30
  420. data/config/locales/pl.yml +69 -57
  421. data/config/locales/pt-BR.yml +5 -250
  422. data/config/locales/pt.yml +0 -36
  423. data/config/locales/ro-RO.yml +180 -329
  424. data/config/locales/ru.yml +0 -19
  425. data/config/locales/sk.yml +1 -26
  426. data/config/locales/sl.yml +0 -8
  427. data/config/locales/sv.yml +164 -605
  428. data/config/locales/tr-TR.yml +5 -33
  429. data/config/locales/uk.yml +1 -14
  430. data/config/locales/zh-CN.yml +0 -27
  431. data/config/locales/zh-TW.yml +1 -51
  432. data/config/routes.rb +0 -2
  433. data/db/migrate/20170128112958_change_user_groups_verified_to_timestamp.rb +1 -1
  434. data/db/migrate/20181025082245_add_timestamps_to_components.rb +1 -5
  435. data/db/migrate/20240110150230_rename_external_domain_whitelist_to_external_domain_allowlist.rb +7 -0
  436. data/db/migrate/20240326104215_remove_show_in_footer_in_static_pages.rb +7 -0
  437. data/db/migrate/20240401192628_change_name_on_decidim_organizations.rb +31 -0
  438. data/db/seeds/avatars/001.jpg +0 -0
  439. data/db/seeds/avatars/002.jpg +0 -0
  440. data/db/seeds/avatars/003.jpg +0 -0
  441. data/db/seeds/avatars/004.jpg +0 -0
  442. data/db/seeds/avatars/005.jpg +0 -0
  443. data/db/seeds/avatars/006.jpg +0 -0
  444. data/db/seeds/avatars/007.jpg +0 -0
  445. data/db/seeds/avatars/008.jpg +0 -0
  446. data/db/seeds/avatars/009.jpg +0 -0
  447. data/db/seeds/avatars/010.jpg +0 -0
  448. data/db/seeds/avatars/011.jpg +0 -0
  449. data/db/seeds/avatars/012.jpg +0 -0
  450. data/db/seeds/avatars/013.jpg +0 -0
  451. data/db/seeds/avatars/014.jpg +0 -0
  452. data/db/seeds/avatars/015.jpg +0 -0
  453. data/db/seeds/avatars/016.jpg +0 -0
  454. data/db/seeds/avatars/017.jpg +0 -0
  455. data/db/seeds/avatars/018.jpg +0 -0
  456. data/db/seeds/avatars/019.jpg +0 -0
  457. data/db/seeds/avatars/020.jpg +0 -0
  458. data/db/seeds/avatars/021.jpg +0 -0
  459. data/db/seeds/avatars/022.jpg +0 -0
  460. data/db/seeds/avatars/023.jpg +0 -0
  461. data/db/seeds/avatars/024.jpg +0 -0
  462. data/db/seeds/avatars/025.jpg +0 -0
  463. data/db/seeds/avatars/026.jpg +0 -0
  464. data/db/seeds/avatars/027.jpg +0 -0
  465. data/db/seeds/avatars/028.jpg +0 -0
  466. data/db/seeds/avatars/029.jpg +0 -0
  467. data/db/seeds/avatars/030.jpg +0 -0
  468. data/db/seeds/avatars/031.jpg +0 -0
  469. data/db/seeds/avatars/032.jpg +0 -0
  470. data/db/seeds/avatars/033.jpg +0 -0
  471. data/db/seeds/avatars/034.jpg +0 -0
  472. data/db/seeds/avatars/035.jpg +0 -0
  473. data/db/seeds/avatars/036.jpg +0 -0
  474. data/db/seeds/avatars/037.jpg +0 -0
  475. data/db/seeds/avatars/038.jpg +0 -0
  476. data/db/seeds/avatars/039.jpg +0 -0
  477. data/db/seeds/avatars/040.jpg +0 -0
  478. data/db/seeds/avatars/041.jpg +0 -0
  479. data/db/seeds/avatars/042.jpg +0 -0
  480. data/db/seeds/avatars/043.jpg +0 -0
  481. data/db/seeds/avatars/044.jpg +0 -0
  482. data/db/seeds/avatars/045.jpg +0 -0
  483. data/db/seeds/avatars/046.jpg +0 -0
  484. data/db/seeds/avatars/047.jpg +0 -0
  485. data/db/seeds/avatars/048.jpg +0 -0
  486. data/db/seeds/avatars/049.jpg +0 -0
  487. data/db/seeds/avatars/050.jpg +0 -0
  488. data/db/seeds/avatars/051.jpg +0 -0
  489. data/db/seeds/avatars/052.jpg +0 -0
  490. data/db/seeds/avatars/053.jpg +0 -0
  491. data/db/seeds/avatars/054.jpg +0 -0
  492. data/db/seeds/avatars/055.jpg +0 -0
  493. data/db/seeds/avatars/056.jpg +0 -0
  494. data/db/seeds/avatars/057.jpg +0 -0
  495. data/db/seeds/avatars/058.jpg +0 -0
  496. data/db/seeds/avatars/059.jpg +0 -0
  497. data/db/seeds/avatars/060.jpg +0 -0
  498. data/db/seeds/avatars/061.jpg +0 -0
  499. data/db/seeds/avatars/062.jpg +0 -0
  500. data/db/seeds/avatars/063.jpg +0 -0
  501. data/db/seeds/avatars/064.jpg +0 -0
  502. data/db/seeds/avatars/065.jpg +0 -0
  503. data/db/seeds/avatars/066.jpg +0 -0
  504. data/db/seeds/avatars/067.jpg +0 -0
  505. data/db/seeds/avatars/068.jpg +0 -0
  506. data/db/seeds/avatars/069.jpg +0 -0
  507. data/db/seeds/avatars/070.jpg +0 -0
  508. data/db/seeds/avatars/071.jpg +0 -0
  509. data/db/seeds/avatars/072.jpg +0 -0
  510. data/db/seeds/avatars/073.jpg +0 -0
  511. data/db/seeds/avatars/074.jpg +0 -0
  512. data/db/seeds/avatars/075.jpg +0 -0
  513. data/db/seeds/avatars/076.jpg +0 -0
  514. data/db/seeds/avatars/077.jpg +0 -0
  515. data/db/seeds/avatars/078.jpg +0 -0
  516. data/db/seeds/avatars/079.jpg +0 -0
  517. data/db/seeds/avatars/080.jpg +0 -0
  518. data/db/seeds/avatars/081.jpg +0 -0
  519. data/db/seeds/avatars/082.jpg +0 -0
  520. data/db/seeds/avatars/083.jpg +0 -0
  521. data/db/seeds/avatars/084.jpg +0 -0
  522. data/db/seeds/avatars/085.jpg +0 -0
  523. data/db/seeds/avatars/086.jpg +0 -0
  524. data/db/seeds/avatars/087.jpg +0 -0
  525. data/db/seeds/avatars/088.jpg +0 -0
  526. data/db/seeds/avatars/089.jpg +0 -0
  527. data/db/seeds/avatars/090.jpg +0 -0
  528. data/db/seeds/avatars/091.jpg +0 -0
  529. data/db/seeds/avatars/092.jpg +0 -0
  530. data/db/seeds/avatars/093.jpg +0 -0
  531. data/db/seeds/avatars/094.jpg +0 -0
  532. data/db/seeds/avatars/095.jpg +0 -0
  533. data/db/seeds/avatars/096.jpg +0 -0
  534. data/db/seeds/avatars/097.jpg +0 -0
  535. data/db/seeds/avatars/098.jpg +0 -0
  536. data/db/seeds/avatars/099.jpg +0 -0
  537. data/db/seeds/avatars/100.jpg +0 -0
  538. data/db/seeds/avatars/CREDITS.md +114 -0
  539. data/db/seeds/avatars/README.md +25 -0
  540. data/decidim-core.gemspec +8 -9
  541. data/lib/decidim/acts_as_author.rb +1 -1
  542. data/lib/decidim/admin_filter.rb +44 -0
  543. data/lib/decidim/admin_filters_registry.rb +55 -0
  544. data/lib/decidim/amendable.rb +1 -2
  545. data/lib/decidim/api/functions/component_finder_base.rb +1 -1
  546. data/lib/decidim/api/functions/component_list.rb +1 -1
  547. data/lib/decidim/api/functions/needs_api_filter_and_order.rb +3 -3
  548. data/lib/decidim/api/functions/participatory_space_finder_base.rb +2 -12
  549. data/lib/decidim/api/functions/participatory_space_list_base.rb +1 -1
  550. data/lib/decidim/api/input_filters/user_entity_input_filter.rb +3 -3
  551. data/lib/decidim/api/interfaces/author_interface.rb +1 -1
  552. data/lib/decidim/api/interfaces/participatory_space_interface.rb +1 -1
  553. data/lib/decidim/api/types/component_type.rb +0 -7
  554. data/lib/decidim/api/types/organization_type.rb +1 -1
  555. data/lib/decidim/api/types/user_group_type.rb +1 -5
  556. data/lib/decidim/api/types/user_type.rb +1 -5
  557. data/lib/decidim/asset_router/pipeline.rb +2 -2
  558. data/lib/decidim/asset_router/storage.rb +11 -214
  559. data/lib/decidim/assets/tailwind/instance.rb +1 -1
  560. data/lib/decidim/assets/tailwind/tailwind.config.js.erb +8 -3
  561. data/lib/decidim/attribute_object/model.rb +2 -2
  562. data/lib/decidim/attribute_object/type_resolver.rb +1 -3
  563. data/lib/decidim/attribute_object.rb +2 -2
  564. data/lib/decidim/attributes/time_with_zone.rb +1 -11
  565. data/lib/decidim/attributes.rb +0 -6
  566. data/lib/decidim/authorable.rb +5 -0
  567. data/lib/decidim/command.rb +2 -2
  568. data/lib/decidim/commands/create_resource.rb +63 -0
  569. data/lib/decidim/commands/destroy_resource.rb +74 -0
  570. data/lib/decidim/commands/hook_error.rb +8 -0
  571. data/lib/decidim/commands/resource_handler.rb +85 -0
  572. data/lib/decidim/commands/update_resource.rb +64 -0
  573. data/lib/decidim/component_manifest.rb +3 -1
  574. data/lib/decidim/component_validator.rb +1 -1
  575. data/lib/decidim/content_blocks/has_related_components.rb +1 -1
  576. data/lib/decidim/content_parsers/resource_parser.rb +2 -2
  577. data/lib/decidim/content_parsers.rb +0 -1
  578. data/lib/decidim/content_processor.rb +1 -1
  579. data/lib/decidim/content_renderers.rb +0 -1
  580. data/lib/decidim/content_security_policy.rb +1 -1
  581. data/lib/decidim/core/engine.rb +13 -58
  582. data/lib/decidim/core/menu.rb +13 -3
  583. data/lib/decidim/core/seeds.rb +120 -147
  584. data/lib/decidim/core/test/factories.rb +24 -31
  585. data/lib/decidim/core/test/shared_examples/acts_as_author_examples.rb +1 -1
  586. data/lib/decidim/core/test/shared_examples/amendable/withdraw_amendment_examples.rb +2 -2
  587. data/lib/decidim/core/test/shared_examples/announcements_examples.rb +3 -3
  588. data/lib/decidim/core/test/shared_examples/assembly_announcements_examples.rb +4 -4
  589. data/lib/decidim/core/test/shared_examples/attachable_interface_examples.rb +1 -1
  590. data/lib/decidim/core/test/shared_examples/authorable_interface_examples.rb +1 -1
  591. data/lib/decidim/core/test/shared_examples/comments_examples.rb +90 -107
  592. data/lib/decidim/core/test/shared_examples/comments_reports_examples.rb +4 -4
  593. data/lib/decidim/core/test/shared_examples/digest_mail_examples.rb +1 -1
  594. data/lib/decidim/core/test/shared_examples/edit_link_shared_examples.rb +1 -1
  595. data/lib/decidim/core/test/shared_examples/editor_shared_examples.rb +7 -7
  596. data/lib/decidim/core/test/shared_examples/fingerprint_examples.rb +1 -1
  597. data/lib/decidim/core/test/shared_examples/follows_examples.rb +6 -11
  598. data/lib/decidim/core/test/shared_examples/has_attachment_collections.rb +4 -2
  599. data/lib/decidim/core/test/shared_examples/has_attachments.rb +3 -2
  600. data/lib/decidim/core/test/shared_examples/has_contextual_help.rb +4 -4
  601. data/lib/decidim/core/test/shared_examples/has_reference.rb +1 -1
  602. data/lib/decidim/core/test/shared_examples/logo_email.rb +1 -1
  603. data/lib/decidim/core/test/shared_examples/manage_component_share_tokens.rb +9 -9
  604. data/lib/decidim/core/test/shared_examples/map_examples.rb +5 -5
  605. data/lib/decidim/core/test/shared_examples/paginated_resource_examples.rb +7 -7
  606. data/lib/decidim/core/test/shared_examples/participatory_space_dropdown_metadata_cell_examples.rb +3 -3
  607. data/lib/decidim/core/test/shared_examples/preview_component_with_share_token_examples.rb +3 -3
  608. data/lib/decidim/core/test/shared_examples/process_announcements_examples.rb +4 -4
  609. data/lib/decidim/core/test/shared_examples/reports_examples.rb +5 -5
  610. data/lib/decidim/core/test/shared_examples/rich_text_editor_examples.rb +10 -10
  611. data/lib/decidim/core/test/shared_examples/searchable_participatory_space_examples.rb +1 -1
  612. data/lib/decidim/core/test/shared_examples/searchable_results_examples.rb +8 -8
  613. data/lib/decidim/core/test/shared_examples/share_link_examples.rb +2 -2
  614. data/lib/decidim/core/test/shared_examples/simple_event.rb +1 -1
  615. data/lib/decidim/core/test/shared_examples/space_cell_changes_button_text_cta.rb +3 -3
  616. data/lib/decidim/core/test/shared_examples/system_endorse_resource_examples.rb +15 -113
  617. data/lib/decidim/core/test/shared_examples/translated_event_examples.rb +2 -2
  618. data/lib/decidim/core/test/shared_examples/uncommentable_component_examples.rb +2 -2
  619. data/lib/decidim/core/test/shared_examples/with_endorsable_permissions_examples.rb +1 -1
  620. data/lib/decidim/core/version.rb +1 -1
  621. data/lib/decidim/core.rb +24 -17
  622. data/lib/decidim/dependency_resolver.rb +3 -3
  623. data/lib/decidim/diffy_extension.rb +1 -19
  624. data/lib/decidim/download_your_data_serializers/download_your_data_user_serializer.rb +2 -1
  625. data/lib/decidim/engine_router.rb +2 -2
  626. data/lib/decidim/events/base_event.rb +19 -0
  627. data/lib/decidim/events/simple_event.rb +1 -0
  628. data/lib/decidim/exporters/export_manifest.rb +1 -1
  629. data/lib/decidim/faker/localized.rb +3 -3
  630. data/lib/decidim/form_builder.rb +5 -5
  631. data/lib/decidim/hashtag.rb +1 -1
  632. data/lib/decidim/jsonb_attributes.rb +4 -4
  633. data/lib/decidim/manifest_messages.rb +2 -2
  634. data/lib/decidim/map/autocomplete.rb +0 -1
  635. data/lib/decidim/organization_settings.rb +5 -8
  636. data/lib/decidim/paddable.rb +1 -1
  637. data/lib/decidim/participable.rb +1 -1
  638. data/lib/decidim/participatory_space_manifest.rb +1 -1
  639. data/lib/decidim/participatory_space_user.rb +0 -4
  640. data/lib/decidim/query_extensions.rb +26 -0
  641. data/lib/decidim/resourceable.rb +1 -1
  642. data/lib/decidim/search_resource_fields_mapper.rb +2 -2
  643. data/lib/decidim/searchable.rb +3 -3
  644. data/lib/decidim/seeds.rb +62 -0
  645. data/lib/decidim/settings_manifest.rb +0 -2
  646. data/lib/decidim/stats_registry.rb +2 -2
  647. data/lib/decidim/translatable_attributes.rb +4 -9
  648. data/lib/decidim/translatable_resource.rb +1 -1
  649. data/lib/decidim/view_hooks.rb +1 -1
  650. data/lib/decidim/view_model.rb +5 -1
  651. data/lib/decidim/webpacker/esbuild.config.js +14 -0
  652. data/lib/decidim/webpacker/shakapacker.yml +2 -2
  653. data/lib/decidim/webpacker/tsconfig.json +11 -0
  654. data/lib/decidim/webpacker/webpack/custom.js +13 -35
  655. data/lib/devise/models/decidim_newsletterable.rb +1 -1
  656. data/lib/tasks/decidim_download_your_data_tasks.rake +2 -2
  657. data/lib/tasks/decidim_locales_tasks.rake +1 -1
  658. data/lib/tasks/decidim_mailers_tasks.rake +2 -2
  659. data/lib/tasks/decidim_metrics_tasks.rake +6 -6
  660. data/lib/tasks/decidim_procfile.rake +9 -3
  661. data/lib/tasks/decidim_tasks.rake +5 -4
  662. data/lib/tasks/decidim_webpacker_tasks.rake +126 -117
  663. data/lib/tasks/upgrade/decidim_active_storage_migration_tasks.rake +80 -0
  664. data/lib/tasks/upgrade/decidim_content_blocks_tasks.rake +50 -0
  665. data/lib/tasks/upgrade/decidim_deduplicate_endorsements.rake +1 -1
  666. data/lib/tasks/upgrade/decidim_fix_categorization.rake +6 -132
  667. data/lib/tasks/upgrade/decidim_fix_nickname_uniqueness.rake +1 -1
  668. data/lib/tasks/upgrade/decidim_fix_short_url_resolver.rake +1 -1
  669. data/lib/tasks/upgrade/decidim_moderation_tasks.rake +1 -1
  670. data/lib/tasks/upgrade/decidim_user_moderation.rake +1 -1
  671. metadata +219 -101
  672. data/app/cells/decidim/content_blocks/cta/show.erb +0 -12
  673. data/app/cells/decidim/content_blocks/cta_cell.rb +0 -31
  674. data/app/cells/decidim/footer_pages/pages.erb +0 -3
  675. data/app/cells/decidim/footer_pages/topics.erb +0 -12
  676. data/app/cells/decidim/footer_pages_cell.rb +0 -68
  677. data/app/controllers/concerns/decidim/direct_upload.rb +0 -82
  678. data/app/helpers/concerns/decidim/user_role_checker.rb +0 -46
  679. data/app/packs/src/decidim/remote_tooltips.js +0 -38
  680. data/app/packs/src/decidim/vendor/modernizr.js +0 -5
  681. data/app/queries/decidim/similar_emendations.rb +0 -56
  682. data/app/uploaders/decidim/cw/application_uploader.rb +0 -77
  683. data/app/uploaders/decidim/cw/attachment_uploader.rb +0 -56
  684. data/app/uploaders/decidim/cw/avatar_uploader.rb +0 -24
  685. data/app/uploaders/decidim/cw/banner_image_uploader.rb +0 -7
  686. data/app/uploaders/decidim/cw/download_your_data_uploader.rb +0 -15
  687. data/app/uploaders/decidim/cw/downloader.rb +0 -9
  688. data/app/uploaders/decidim/cw/hero_image_uploader.rb +0 -10
  689. data/app/uploaders/decidim/cw/homepage_image_uploader.rb +0 -14
  690. data/app/uploaders/decidim/cw/image_uploader.rb +0 -78
  691. data/app/uploaders/decidim/cw/newsletter_template_image_uploader.rb +0 -38
  692. data/app/uploaders/decidim/cw/oauth_application_logo_uploader.rb +0 -10
  693. data/app/uploaders/decidim/cw/official_image_footer_uploader.rb +0 -10
  694. data/app/uploaders/decidim/cw/official_image_header_uploader.rb +0 -10
  695. data/app/uploaders/decidim/cw/open_data_uploader.rb +0 -23
  696. data/app/uploaders/decidim/cw/organization_favicon_uploader.rb +0 -18
  697. data/app/uploaders/decidim/cw/organization_logo_uploader.rb +0 -10
  698. data/app/uploaders/decidim/cw/record_image_uploader.rb +0 -15
  699. data/app/uploaders/decidim/downloader.rb +0 -9
  700. data/app/views/decidim/amendments/compare_draft.html.erb +0 -18
  701. data/app/views/layouts/decidim/_edit_link.html.erb +0 -0
  702. data/app/views/layouts/decidim/header/_main_links_mobile.html.erb +0 -36
  703. data/config/initializers/carrierwave.rb +0 -15
  704. data/config/locales/bn-BD.yml +0 -1
  705. data/config/locales/bs-BA.yml +0 -98
  706. data/lib/decidim/attributes/rich_text.rb +0 -38
  707. data/lib/decidim/carrier_wave_migrator_service.rb +0 -287
  708. data/lib/decidim/content_parsers/blob_parser.rb +0 -93
  709. data/lib/decidim/content_renderers/blob_renderer.rb +0 -90
  710. data/lib/decidim/seven_zip_wrapper.rb +0 -29
  711. data/lib/tasks/decidim_active_storage_migration_tasks.rake +0 -114
  712. data/lib/tasks/decidim_content_blocks_tasks.rake +0 -48
  713. data/lib/tasks/upgrade/decidim_attachments.rake +0 -14
  714. /data/app/views/layouts/decidim/header/{_menu_breadcrumb_main_dropdown.html.erb → _menu_breadcrumb_main_dropdown_desktop.html.erb} +0 -0
@@ -2,16 +2,13 @@
2
2
 
3
3
  module Decidim
4
4
  class NewsletterMailer < ApplicationMailer
5
- helper Decidim::SanitizeHelper
6
- helper Decidim::TranslationsHelper
7
-
8
5
  include Decidim::NewslettersHelper
9
6
 
10
7
  layout "decidim/newsletter_base"
11
8
 
12
9
  helper_method :cell
13
10
 
14
- def newsletter(user, newsletter, preview: false)
11
+ def newsletter(user, newsletter, preview = nil)
15
12
  return if user.email.blank?
16
13
 
17
14
  @organization = user.organization
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Decidim
4
4
  # A custom mailer for Decidim so we can notify users to verify
5
- # their own newsletter notifications settings. GDPR releated
5
+ # their own newsletter notifications settings. GDPR related
6
6
  class NewslettersOptInMailer < ApplicationMailer
7
7
  def notify(user, token)
8
8
  with_user(user) do
@@ -10,7 +10,7 @@ module Decidim
10
10
  @organization = user.organization
11
11
  @token = token
12
12
 
13
- mail(to: user.email, subject: I18n.t("decidim.newsletters_opt_in_mailer.notify.subject", organization_name: @organization.name))
13
+ mail(to: user.email, subject: I18n.t("decidim.newsletters_opt_in_mailer.notify.subject", organization_name: organization_name(@organization)))
14
14
  end
15
15
  end
16
16
  end
@@ -5,7 +5,6 @@ module Decidim
5
5
  # a events are received.
6
6
  class NotificationMailer < Decidim::ApplicationMailer
7
7
  helper Decidim::ResourceHelper
8
- helper Decidim::SanitizeHelper
9
8
 
10
9
  def event_received(event, event_class_name, resource, user, user_role, extra) # rubocop:disable Metrics/ParameterLists
11
10
  with_user(user) do
@@ -5,7 +5,6 @@ module Decidim
5
5
  # a events are received.
6
6
  class NotificationsDigestMailer < Decidim::ApplicationMailer
7
7
  helper Decidim::ResourceHelper
8
- helper Decidim::SanitizeHelper
9
8
  SIZE_LIMIT = 10
10
9
 
11
10
  def digest_mail(user, notification_ids)
@@ -1,10 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Decidim
4
- # A custom mailer for sending notifications to an admin when a report is created..
4
+ # A custom mailer for sending notifications to an admin when a report is created.
5
5
  class ReportedMailer < Decidim::ApplicationMailer
6
6
  helper Decidim::ResourceHelper
7
- helper Decidim::TranslationsHelper
8
7
 
9
8
  helper_method :reported_content_url, :report_url, :manage_moderations_url, :author_profile_url, :reported_content_cell
10
9
 
@@ -38,6 +37,10 @@ module Decidim
38
37
  @organization
39
38
  end
40
39
 
40
+ def current_user
41
+ @user
42
+ end
43
+
41
44
  private
42
45
 
43
46
  def reported_content_url
@@ -63,7 +66,7 @@ module Decidim
63
66
  end
64
67
 
65
68
  # This is needed to be able to use a cell in an ActionMailer, which is not supported out of the box by cells-rails.
66
- # We are are passing the current object as if it was a controller.
69
+ # We are passing the current object as if it was a controller.
67
70
  # We also need to define a 'current_organization' method, which is expected by Decidim::ViewModel.
68
71
  # A similar approach is used in Decidim::NewsletterMailer
69
72
  def reported_content_cell
@@ -11,7 +11,7 @@ module Decidim
11
11
  with_user(admin) do
12
12
  mail(to: admin.email, subject: I18n.t(
13
13
  "decidim.user_report_mailer.notify.subject",
14
- organization_name: report.moderation.user.organization.name,
14
+ organization_name: organization_name(report.moderation.user.organization),
15
15
  reason: @report.reason
16
16
  ))
17
17
  end
@@ -138,7 +138,6 @@ module Decidim
138
138
  Decidim::Proposals::Proposal
139
139
  Decidim::Surveys::Survey
140
140
  Decidim::Assembly
141
- Decidim::Conference
142
141
  Decidim::Initiative
143
142
  Decidim::ParticipatoryProcess
144
143
  ).select do |klass|
@@ -155,16 +154,7 @@ module Decidim
155
154
  end
156
155
 
157
156
  def self.publicable_public_resource_types
158
- @publicable_public_resource_types ||= public_resource_types
159
- .select { |klass| klass.constantize.column_names.include?("published_at") } - publicable_exceptions
160
- end
161
-
162
- def self.publicable_exceptions
163
- @publicable_exceptions = %w(
164
- Decidim::Blogs::Post
165
- ).select do |klass|
166
- klass.safe_constantize.present?
167
- end
157
+ @publicable_public_resource_types ||= public_resource_types.select { |klass| klass.constantize.column_names.include?("published_at") }
168
158
  end
169
159
 
170
160
  def self.ransackable_scopes(auth_object = nil)
@@ -204,7 +194,7 @@ module Decidim
204
194
  # as a regular object.
205
195
  def participatory_space_lazy(cache: true)
206
196
  return if participatory_space_id.blank? || participatory_space_type.blank?
207
- return resouce_lazy if participatory_space_id == resource_id && participatory_space_type == resource_type
197
+ return resource_lazy if participatory_space_id == resource_id && participatory_space_type == resource_type
208
198
 
209
199
  self.class.lazy_relation(participatory_space_id, participatory_space_type, cache)
210
200
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Decidim
4
4
  # Area types allows to use different types of areas in participatory space
5
- # (terriotrial, sectorial, etc.)
5
+ # (territorial, sectorial, etc.)
6
6
  class AreaType < ApplicationRecord
7
7
  include Decidim::TranslatableResource
8
8
  include Decidim::Traceable
@@ -9,6 +9,7 @@ module Decidim
9
9
  include Traceable
10
10
 
11
11
  before_save :set_content_type_and_size, if: :attached?
12
+ before_validation :set_link_content_type_and_size, if: :link?
12
13
 
13
14
  translatable_fields :title, :description
14
15
  belongs_to :attachment_collection, class_name: "Decidim::AttachmentCollection", optional: true
@@ -61,15 +62,33 @@ module Decidim
61
62
  !photo?
62
63
  end
63
64
 
65
+ # Whether this attachment is a link or not.
66
+ #
67
+ # Returns Boolean.
68
+ def link?
69
+ link.present?
70
+ end
71
+
64
72
  # Which kind of file this is.
65
73
  #
66
74
  # Returns String.
67
75
  def file_type
68
- url&.split(".")&.last&.split("&")&.first&.downcase
76
+ if file?
77
+ url&.split(".")&.last&.downcase
78
+ elsif link?
79
+ "link"
80
+ end
69
81
  end
70
82
 
83
+ # The URL that points to the attachment
84
+ #
85
+ # Returns String.
71
86
  def url
72
- attached_uploader(:file).url
87
+ if file?
88
+ attached_uploader(:file).path
89
+ elsif link?
90
+ link
91
+ end
73
92
  end
74
93
 
75
94
  # The URL to download the thumbnail of the file. Only works with images.
@@ -78,7 +97,7 @@ module Decidim
78
97
  def thumbnail_url
79
98
  return unless photo?
80
99
 
81
- @thumbnail_url ||= attached_uploader(:file).variant_url(:thumbnail)
100
+ attached_uploader(:file).path(variant: :thumbnail)
82
101
  end
83
102
 
84
103
  # The URL to download the a big version of the file. Only works with images.
@@ -87,7 +106,7 @@ module Decidim
87
106
  def big_url
88
107
  return unless photo?
89
108
 
90
- @big_url ||= attached_uploader(:file).variant_url(:big)
109
+ attached_uploader(:file).path(variant: :big)
91
110
  end
92
111
 
93
112
  def set_content_type_and_size
@@ -95,6 +114,11 @@ module Decidim
95
114
  self.file_size = file.byte_size
96
115
  end
97
116
 
117
+ def set_link_content_type_and_size
118
+ self.content_type = "text/uri-list"
119
+ self.file_size = 0
120
+ end
121
+
98
122
  def self.log_presenter_class_for(_log)
99
123
  Decidim::AdminLog::AttachmentPresenter
100
124
  end
@@ -101,7 +101,7 @@ module Decidim
101
101
  @workflow_manifest ||= Decidim::Verifications.find_workflow_manifest(name)
102
102
  end
103
103
 
104
- # Calculates when this authorization can be reseted, if desired.
104
+ # Calculates when this authorization can be reset, if desired.
105
105
  #
106
106
  # **time_between_renewals** is defined in `workflow_manifest.time_between_renewals`
107
107
  # defaults to 1 day
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # rubocop:disable Rails/HelperInstanceVariable
3
4
  module Decidim
4
5
  # An authorization transfer object is created when the user authorizes
5
6
  # themselves with the same unique ID as some other user had used in the past.
@@ -14,10 +14,7 @@ module Decidim
14
14
 
15
15
  belongs_to :participatory_space, polymorphic: true
16
16
 
17
- scope :registered_component_manifests, -> { where(manifest_name: Decidim.component_registry.manifests.collect(&:name)) }
18
- scope :registered_space_manifests, -> { where(participatory_space_type: Decidim.participatory_space_registry.manifests.collect(&:model_class_name)) }
19
-
20
- default_scope { registered_component_manifests.registered_space_manifests.order(arel_table[:weight].asc, arel_table[:manifest_name].asc) }
17
+ default_scope { order(arel_table[:weight].asc, arel_table[:manifest_name].asc) }
21
18
 
22
19
  delegate :organization, :categories, to: :participatory_space
23
20
 
@@ -59,8 +56,8 @@ module Decidim
59
56
  # Public: The hash of contextual params when the component is mounted.
60
57
  def mounted_params
61
58
  {
62
- host: organization.host,
63
- component_id: id,
59
+ :host => organization.host,
60
+ :component_id => id,
64
61
  "#{participatory_space.underscored_name}_slug".to_sym => participatory_space.slug
65
62
  }
66
63
  end
@@ -60,8 +60,8 @@ module Decidim
60
60
  #
61
61
  # # This is how you can access the image data, just like with any other
62
62
  # # uploader field. You can use the uploader variants too.
63
- # content_block.images_container.attached_uploader(:my_image).url
64
- # content_block.images_container.attached_uploader(:my_image).variant_url(:big)
63
+ # content_block.images_container.attached_uploader(:my_image).path
64
+ # content_block.images_container.attached_uploader(:my_image).path(variant: :big)
65
65
  #
66
66
  # # This will delete the attached image
67
67
  # content_block.images_container.my_image = nil
@@ -134,7 +134,7 @@ module Decidim
134
134
  images_container.save
135
135
  end
136
136
 
137
- # On instance reloading we need to remove the `images_cointainer` cached
137
+ # On instance reloading we need to remove the `images_container` cached
138
138
  # class so it gets regenerated with the new values.
139
139
  def reload_images
140
140
  @images_container = nil
@@ -34,7 +34,7 @@ module Decidim
34
34
 
35
35
  #
36
36
  # Associates receipts for this message for each of the given users,
37
- # including also a receipt for the remitent (sender) of the message.
37
+ # including also a receipt for the remittant (sender) of the message.
38
38
  # Receipts are unread by default, except for the sender's receipt.
39
39
  #
40
40
  # If the sender is a UserGroup then receipts will be created for its managers
@@ -64,7 +64,7 @@ module Decidim
64
64
 
65
65
  private
66
66
 
67
- # returns all posible recipients from a list of users or groups
67
+ # returns all possible recipients from a list of users or groups
68
68
  def all_recipients(recipients)
69
69
  users = recipients.flat_map do |recipient|
70
70
  recipient.is_a?(UserGroup) ? recipient.managers : recipient
@@ -46,7 +46,7 @@ module Decidim
46
46
  extended_data["send_to_participants"]
47
47
  end
48
48
 
49
- def sended_to_partipatory_spaces
49
+ def sent_to_participatory_spaces
50
50
  extended_data["participatory_space_types"]
51
51
  end
52
52
 
@@ -56,16 +56,16 @@ module Decidim
56
56
  .find_by(scoped_resource_id: id)
57
57
  end
58
58
 
59
- def url(**kwargs)
60
- proxy_url(:newsletter_url, id:, **kwargs)
59
+ def url(**)
60
+ proxy_url(:newsletter_url, id:, **)
61
61
  end
62
62
 
63
- def notifications_settings_url(**kwargs)
64
- proxy_url(__method__, **kwargs)
63
+ def notifications_settings_url(**)
64
+ proxy_url(__method__, **)
65
65
  end
66
66
 
67
- def unsubscribe_newsletters_url(**kwargs)
68
- proxy_url(__method__, **kwargs)
67
+ def unsubscribe_newsletters_url(**)
68
+ proxy_url(__method__, **)
69
69
  end
70
70
 
71
71
  def organization_official_url
@@ -82,10 +82,10 @@ module Decidim
82
82
  errors.add(:author, :invalid) unless author.organization == organization
83
83
  end
84
84
 
85
- def proxy_url(method, **kwargs)
85
+ def proxy_url(method, **)
86
86
  return "#" unless sent?
87
87
 
88
- router.public_send(method, host: organization.host, **kwargs)
88
+ router.public_send(method, host: organization.host, **)
89
89
  end
90
90
 
91
91
  def router
@@ -9,12 +9,12 @@ module Decidim
9
9
 
10
10
  # Daily notifications should contain all notifications within the previous
11
11
  # day from the given day.
12
- scope :daily, ->(time: Time.now.utc) { where(created_at: (time - 1.day).all_day) }
12
+ scope :daily, ->(time = Time.now.utc) { where(created_at: (time - 1.day).all_day) }
13
13
 
14
14
  # Weekly notifications should contain all notifications within the previous
15
15
  # week counting from the end of the previous day until the start of the day
16
16
  # 1 week ago from the previous day.
17
- scope :weekly, lambda { |time: Time.now.utc|
17
+ scope :weekly, lambda { |time = Time.now.utc|
18
18
  end_of_previous_day = (time - 1.day).end_of_day
19
19
  where(created_at: (end_of_previous_day - 7.days).beginning_of_day..end_of_previous_day)
20
20
  }
@@ -15,7 +15,7 @@ module Decidim
15
15
  SOCIAL_HANDLERS = [:twitter, :facebook, :instagram, :youtube, :github].freeze
16
16
  AVAILABLE_MACHINE_TRANSLATION_DISPLAY_PRIORITIES = %w(original translation).freeze
17
17
 
18
- translatable_fields :description, :cta_button_text, :omnipresent_banner_title, :omnipresent_banner_short_description,
18
+ translatable_fields :name, :description, :cta_button_text, :omnipresent_banner_title, :omnipresent_banner_short_description,
19
19
  :highlighted_content_banner_title, :highlighted_content_banner_short_description, :highlighted_content_banner_action_title,
20
20
  :highlighted_content_banner_action_subtitle, :welcome_notification_subject, :welcome_notification_body, :id_documents_explanation_text,
21
21
  :admin_terms_of_service_body
@@ -41,7 +41,7 @@ module Decidim
41
41
  # disable: Users cannot register or sign in.
42
42
  enum users_registration_mode: [:enabled, :existing, :disabled], _prefix: true
43
43
 
44
- validates :name, :host, uniqueness: true
44
+ validates :host, uniqueness: true
45
45
  validates :reference_prefix, presence: true
46
46
  validates :time_zone, presence: true, time_zone: true
47
47
  validates :default_locale, inclusion: { in: :available_locales }
@@ -60,6 +60,27 @@ module Decidim
60
60
 
61
61
  has_one_attached :open_data_file
62
62
 
63
+ validate :unique_name
64
+
65
+ def unique_name
66
+ base_query = new_record? ? Decidim::Organization.all : Decidim::Organization.where.not(id:).all
67
+
68
+ organization_names = []
69
+
70
+ base_query.pluck(:name).each do |value|
71
+ organization_names += value.except("machine_translations").values
72
+ organization_names += value.fetch("machine_translations", {}).values
73
+ end
74
+
75
+ organization_names = organization_names.map(&:downcase).compact_blank
76
+
77
+ name.each do |language, value|
78
+ next if value.is_a?(Hash)
79
+
80
+ errors.add("name_#{language}", :taken) if organization_names.include?(value.downcase)
81
+ end
82
+ end
83
+
63
84
  def self.log_presenter_class_for(_log)
64
85
  Decidim::AdminLog::OrganizationPresenter
65
86
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Decidim
4
- # A messsage from a conversation that will be sent as a push notification
4
+ # A message from a conversation that will be sent as a push notification
5
5
  class PushNotificationMessage
6
6
  class InvalidActionError < StandardError; end
7
7
 
@@ -7,7 +7,7 @@ module Decidim
7
7
  # In order to group the relations between resources you need to specify a name.
8
8
  #
9
9
  # Some examples could be: proposals that have been created in a meeting or
10
- # projects that are a result of merging diffrent proposals.
10
+ # projects that are a result of merging different proposals.
11
11
  class ResourceLink < ApplicationRecord
12
12
  belongs_to :from, polymorphic: true
13
13
  belongs_to :to, polymorphic: true
@@ -278,18 +278,6 @@ module Decidim
278
278
  false
279
279
  end
280
280
 
281
- def after_confirmation
282
- return unless organization.send_welcome_notification?
283
-
284
- Decidim::EventsManager.publish(
285
- event: "decidim.events.core.welcome_notification",
286
- event_class: WelcomeNotificationEvent,
287
- resource: self,
288
- affected_users: [self],
289
- extra: { force_email: true }
290
- )
291
- end
292
-
293
281
  protected
294
282
 
295
283
  # Overrides devise email required validation.
@@ -308,11 +296,23 @@ module Decidim
308
296
  super
309
297
  end
310
298
 
299
+ def after_confirmation
300
+ return unless organization.send_welcome_notification?
301
+
302
+ Decidim::EventsManager.publish(
303
+ event: "decidim.events.core.welcome_notification",
304
+ event_class: WelcomeNotificationEvent,
305
+ resource: self,
306
+ affected_users: [self],
307
+ extra: { force_email: true }
308
+ )
309
+ end
310
+
311
311
  private
312
312
 
313
313
  # Changes default Devise behaviour to use ActiveJob to send async emails.
314
- def send_devise_notification(notification, *args)
315
- devise_mailer.send(notification, self, *args).deliver_later
314
+ def send_devise_notification(notification, *)
315
+ devise_mailer.send(notification, self, *).deliver_later
316
316
  end
317
317
 
318
318
  def all_roles_are_valid
@@ -202,13 +202,13 @@ module Decidim
202
202
  document_number.present?
203
203
  end
204
204
 
205
- # Overwites method in `Decidim::Validatable`, as user groups do not have a
205
+ # Overrides method in `Decidim::Validatable`, as user groups do not have a
206
206
  # password.
207
207
  def password_required?
208
208
  false
209
209
  end
210
210
 
211
- # Overwites method in `Decidim::Validatable`, as user groups do not have a
211
+ # Overrides method in `Decidim::Validatable`, as user groups do not have a
212
212
  # password.
213
213
  def password
214
214
  nil
@@ -59,6 +59,7 @@ const createDropdown = (component) => {
59
59
  const dropdownOptions = {};
60
60
  dropdownOptions.dropdown = component.dataset.target;
61
61
  dropdownOptions.hover = component.dataset.hover === "true";
62
+ dropdownOptions.isOpen = component.dataset.open === "true";
62
63
  dropdownOptions.autoClose = component.dataset.autoClose === "true";
63
64
 
64
65
  // This snippet allows to disable the dropdown based on the current viewport
@@ -77,17 +78,6 @@ const createDropdown = (component) => {
77
78
  return
78
79
  }
79
80
 
80
- dropdownOptions.isOpen = component.dataset.open === "true";
81
-
82
- const isOpen = Object.keys(screens).some((key) => {
83
- if (!isScreenSize(key)) {
84
- return false;
85
- }
86
- return Boolean(component.dataset[`open-${key}`.replace(/-([a-z])/g, (str) => str[1].toUpperCase())]);
87
- });
88
-
89
- dropdownOptions.isOpen = dropdownOptions.isOpen || isOpen;
90
-
91
81
  if (!component.id) {
92
82
  // when component has no id, we enforce to have it one
93
83
  component.id = `dropdown-${Math.random().toString(36).substring(7)}`
@@ -114,6 +104,20 @@ const createDropdown = (component) => {
114
104
  });
115
105
  }
116
106
 
107
+ // Disable focus on children elements so we can pass the AXE accessibility tests
108
+ const dropdownMenu = document.getElementById(dropdownOptions.dropdown);
109
+ if (dropdownMenu.getAttribute("aria-hidden") === "true") {
110
+ dropdownMenu.
111
+ querySelectorAll("a, input, button").
112
+ forEach((element) => { element.tabIndex = -1 })
113
+ }
114
+
115
+ component.addEventListener("click", () => {
116
+ dropdownMenu.
117
+ querySelectorAll("a, input, button").
118
+ forEach((element) => { element.tabIndex = 0 })
119
+ })
120
+
117
121
  Dropdowns.render(component.id, dropdownOptions);
118
122
  }
119
123
 
@@ -186,10 +190,56 @@ const createDialog = (component) => {
186
190
  })
187
191
  }
188
192
 
193
+ /**
194
+ * Announces a message to the screen reader dynamically.
195
+ *
196
+ * This should not be called consecutively multiple times because the screen
197
+ * reader may not read all the messages if the content is changed quickly.
198
+ *
199
+ * @param {String} message The message to be announced
200
+ * @param {String} mode The mode for the announcement, either "assertive"
201
+ * (default) or "polite".
202
+ * @return {void}
203
+ */
204
+ const announceForScreenReader = (message, mode = "assertive") => {
205
+ if (!message || typeof message !== "string" || message.length < 1) {
206
+ return;
207
+ }
208
+
209
+ let element = document.getElementById("screen-reader-announcement");
210
+ if (!element) {
211
+ element = document.createElement("div");
212
+ element.setAttribute("id", "screen-reader-announcement");
213
+ element.classList.add("sr-only");
214
+ element.setAttribute("aria-atomic", true);
215
+ document.body.append(element);
216
+ }
217
+ if (mode === "polite") {
218
+ element.setAttribute("aria-live", mode);
219
+ } else {
220
+ element.setAttribute("aria-live", "assertive");
221
+ }
222
+
223
+ element.innerHTML = "";
224
+
225
+ setTimeout(() => {
226
+ // Wrap the text in a span with a random attribute value that changes every
227
+ // time to try to indicate to the screen reader the content has changed. This
228
+ // helps reading the message aloud if the message is exactly the same as the
229
+ // last time.
230
+ const randomIdentifier = `announcement-${new Date().getUTCMilliseconds()}-${Math.floor(Math.random() * 10000000)}`;
231
+ const announce = document.createElement("span")
232
+ announce.setAttribute("data-random", randomIdentifier);
233
+ announce.textContent = message;
234
+ element.append(announce);
235
+ }, 100);
236
+ };
237
+
189
238
  export {
190
239
  createAccordion,
191
240
  createDialog,
192
241
  createDropdown,
242
+ announceForScreenReader,
193
243
  Accordions,
194
244
  Dialogs,
195
245
  Dropdowns
@@ -53,31 +53,21 @@ $(() => {
53
53
  }
54
54
 
55
55
  $(document).on("click.zf.trigger", (event) => {
56
- // Try to get the <a> directly or find the closest parent <a>
57
- const $target = $(event.target).closest("a");
58
-
59
- // Check if an <a> was found
60
- if (!$target) {
61
- return;
62
- }
63
-
64
- const dialogTarget = `#${$target.data("dialog-open")}`;
65
- const redirectUrl = $target.data("redirectUrl");
66
-
67
- if (!dialogTarget || !redirectUrl) {
68
- return;
56
+ const target = `#${$(event.target).data("open")}`;
57
+ const redirectUrl = $(event.target).data("redirectUrl");
58
+
59
+ if (target && redirectUrl) {
60
+ $("<input type='hidden' />").
61
+ attr("id", "redirect_url").
62
+ attr("name", "redirect_url").
63
+ attr("value", redirectUrl).
64
+ appendTo(`${target} form`);
65
+
66
+ $(`${target} a`).attr("href", (index, href) => {
67
+ const querystring = jQuery.param({"redirect_url": redirectUrl});
68
+ return href + (href.match(/\?/) ? "&" : "?") + querystring;
69
+ });
69
70
  }
70
-
71
- $("<input type='hidden' />").
72
- attr("id", "redirect_url").
73
- attr("name", "redirect_url").
74
- attr("value", redirectUrl).
75
- appendTo(`${dialogTarget} form`);
76
-
77
- $(`${dialogTarget} a`).attr("href", (index, href) => {
78
- const querystring = jQuery.param({"redirect_url": redirectUrl});
79
- return href + (href.match(/\?/) ? "&" : "?") + querystring;
80
- });
81
71
  });
82
72
 
83
73
  $(document).on("closed.zf.reveal", (event) => {