decidim-core 0.28.6 → 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 (739) 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/show.erb +3 -5
  81. data/app/cells/decidim/participatory_space_dropdown_metadata_cell.rb +1 -2
  82. data/app/cells/decidim/photo_cell.rb +1 -5
  83. data/app/cells/decidim/photos_list_cell.rb +0 -2
  84. data/app/cells/decidim/profile_cell.rb +0 -2
  85. data/app/cells/decidim/profile_sidebar/show.erb +20 -20
  86. data/app/cells/decidim/profile_sidebar_cell.rb +1 -10
  87. data/app/cells/decidim/progress_bar/show.erb +8 -6
  88. data/app/cells/decidim/public_participation/show.erb +1 -1
  89. data/app/cells/decidim/report_button/flag_modal.erb +1 -1
  90. data/app/cells/decidim/resource_types_filter/show.erb +12 -11
  91. data/app/cells/decidim/resource_types_filter_cell.rb +6 -8
  92. data/app/cells/decidim/scopes_picker/show.erb +1 -1
  93. data/app/cells/decidim/scopes_picker_cell.rb +0 -1
  94. data/app/cells/decidim/search_results_cell.rb +1 -1
  95. data/app/cells/decidim/statistic_cell.rb +0 -2
  96. data/app/cells/decidim/tab_panels/show.erb +1 -1
  97. data/app/cells/decidim/tab_panels_cell.rb +12 -2
  98. data/app/cells/decidim/tags_cell.rb +0 -2
  99. data/app/cells/decidim/tos_page_cell.rb +0 -3
  100. data/app/cells/decidim/translation_bar/show.erb +2 -2
  101. data/app/cells/decidim/translation_bar_cell.rb +1 -3
  102. data/app/cells/decidim/upload_modal/files.erb +1 -1
  103. data/app/cells/decidim/upload_modal_cell.rb +1 -3
  104. data/app/cells/decidim/user_activity/show.erb +1 -1
  105. data/app/cells/decidim/user_conversation/new.erb +1 -1
  106. data/app/cells/decidim/user_conversation/show.erb +1 -1
  107. data/app/cells/decidim/user_conversation_cell.rb +0 -1
  108. data/app/cells/decidim/user_conversations/show.erb +1 -1
  109. data/app/cells/decidim/user_conversations_cell.rb +0 -1
  110. data/app/cells/decidim/user_group_pending_invitations_list_cell.rb +0 -1
  111. data/app/cells/decidim/user_group_pending_requests_list_cell.rb +0 -1
  112. data/app/cells/decidim/user_timeline/show.erb +1 -1
  113. data/app/cells/decidim/version_cell.rb +3 -5
  114. data/app/cells/decidim/versions_list_cell.rb +1 -3
  115. data/app/cells/decidim/versions_list_item_cell.rb +2 -4
  116. data/app/cells/decidim/wizard_step_form/wizard_aside.erb +2 -2
  117. data/app/cells/decidim/wizard_step_form/wizard_header.erb +2 -3
  118. data/app/cells/decidim/wizard_step_form_cell.rb +0 -8
  119. data/app/commands/decidim/amendable/create_draft.rb +4 -4
  120. data/app/commands/decidim/amendable/promote.rb +3 -2
  121. data/app/commands/decidim/amendable/publish_draft.rb +3 -2
  122. data/app/commands/decidim/amendable/update_draft.rb +4 -3
  123. data/app/commands/decidim/amendable/withdraw.rb +1 -1
  124. data/app/commands/decidim/create_follow.rb +4 -4
  125. data/app/commands/decidim/create_omniauth_registration.rb +11 -23
  126. data/app/commands/decidim/create_report.rb +3 -3
  127. data/app/commands/decidim/create_user_report.rb +5 -5
  128. data/app/commands/decidim/delete_follow.rb +4 -4
  129. data/app/commands/decidim/demote_membership.rb +2 -2
  130. data/app/commands/decidim/destroy_account.rb +21 -22
  131. data/app/commands/decidim/endorse_resource.rb +1 -1
  132. data/app/commands/decidim/invite_user_to_group.rb +5 -4
  133. data/app/commands/decidim/search.rb +0 -14
  134. data/app/commands/decidim/update_account.rb +24 -22
  135. data/app/commands/decidim/update_notifications_settings.rb +13 -11
  136. data/app/commands/decidim/update_password.rb +7 -7
  137. data/app/commands/decidim/update_user_interests.rb +9 -7
  138. data/app/controllers/concerns/decidim/devise_authentication_methods.rb +1 -1
  139. data/app/controllers/concerns/decidim/devise_controllers.rb +2 -1
  140. data/app/controllers/concerns/decidim/filter_resource.rb +1 -1
  141. data/app/controllers/concerns/decidim/needs_rtl_direction.rb +23 -0
  142. data/app/controllers/concerns/decidim/paginable.rb +1 -1
  143. data/app/controllers/concerns/decidim/participatory_space_context.rb +1 -23
  144. data/app/controllers/concerns/decidim/payload_info.rb +2 -1
  145. data/app/controllers/concerns/decidim/registers_permissions.rb +4 -4
  146. data/app/controllers/concerns/decidim/use_organization_time_zone.rb +1 -1
  147. data/app/controllers/concerns/decidim/withdrawable.rb +1 -1
  148. data/app/controllers/decidim/account_controller.rb +2 -2
  149. data/app/controllers/{concerns/decidim → decidim}/amendments_controller.rb +3 -16
  150. data/app/controllers/decidim/application_controller.rb +1 -1
  151. data/app/controllers/decidim/components/base_controller.rb +1 -1
  152. data/app/controllers/decidim/devise/invitations_controller.rb +1 -1
  153. data/app/controllers/decidim/devise/passwords_controller.rb +2 -2
  154. data/app/controllers/decidim/doorkeeper/credentials_controller.rb +1 -1
  155. data/app/controllers/decidim/endorsements_controller.rb +1 -1
  156. data/app/controllers/decidim/favicon_controller.rb +1 -1
  157. data/app/controllers/decidim/follows_controller.rb +2 -2
  158. data/app/controllers/decidim/group_invites_controller.rb +36 -9
  159. data/app/controllers/decidim/links_controller.rb +1 -1
  160. data/app/controllers/decidim/newsletters_opt_in_controller.rb +1 -1
  161. data/app/controllers/decidim/notifications_settings_controller.rb +1 -1
  162. data/app/controllers/decidim/profiles_controller.rb +2 -6
  163. data/app/controllers/decidim/report_users_controller.rb +1 -1
  164. data/app/controllers/decidim/reports_controller.rb +2 -2
  165. data/app/controllers/decidim/user_activities_controller.rb +1 -1
  166. data/app/controllers/decidim/user_interests_controller.rb +1 -1
  167. data/app/events/decidim/change_nickname_event.rb +0 -1
  168. data/app/events/decidim/invited_to_group_event.rb +29 -0
  169. data/app/events/decidim/welcome_notification_event.rb +2 -4
  170. data/app/forms/decidim/account_form.rb +2 -5
  171. data/app/forms/decidim/form.rb +4 -0
  172. data/app/forms/decidim/omniauth_registration_form.rb +1 -1
  173. data/app/forms/decidim/upload_validation_form.rb +2 -2
  174. data/app/helpers/concerns/decidim/flash_helper_extensions.rb +1 -1
  175. data/app/helpers/decidim/amendments_helper.rb +4 -14
  176. data/app/helpers/decidim/application_helper.rb +8 -0
  177. data/app/helpers/decidim/authorization_form_helper.rb +2 -2
  178. data/app/helpers/decidim/breadcrumb_helper.rb +1 -1
  179. data/app/helpers/decidim/cells_helper.rb +1 -1
  180. data/app/helpers/decidim/check_boxes_tree_helper.rb +1 -1
  181. data/app/helpers/decidim/cta_button_helper.rb +1 -1
  182. data/app/helpers/decidim/datalist_select_helper.rb +1 -1
  183. data/app/helpers/decidim/decidim_form_helper.rb +3 -3
  184. data/app/helpers/decidim/filters_helper.rb +1 -1
  185. data/app/helpers/decidim/layout_helper.rb +1 -64
  186. data/app/helpers/decidim/localized_locales_helper.rb +1 -1
  187. data/app/helpers/decidim/map_helper.rb +1 -6
  188. data/app/helpers/decidim/menu_helper.rb +9 -1
  189. data/app/helpers/decidim/meta_tags_helper.rb +26 -23
  190. data/app/helpers/decidim/modal_helper.rb +1 -1
  191. data/app/helpers/decidim/orders_helper.rb +2 -3
  192. data/app/helpers/decidim/organization_helper.rb +55 -0
  193. data/app/helpers/decidim/paginate_helper.rb +5 -3
  194. data/app/helpers/decidim/participatory_space_helpers.rb +1 -1
  195. data/app/helpers/decidim/resource_helper.rb +0 -7
  196. data/app/helpers/decidim/sanitize_helper.rb +2 -11
  197. data/app/helpers/decidim/scopes_helper.rb +3 -4
  198. data/app/helpers/decidim/searches_helper.rb +1 -1
  199. data/app/helpers/decidim/short_link_helper.rb +2 -2
  200. data/app/helpers/decidim/translations_helper.rb +2 -2
  201. data/app/helpers/decidim/twitter_search_helper.rb +1 -1
  202. data/app/helpers/decidim/user_profile_helper.rb +0 -1
  203. data/app/jobs/decidim/email_notifications_digest_generator_job.rb +2 -2
  204. data/app/mailers/decidim/application_mailer.rb +6 -2
  205. data/app/mailers/decidim/block_user_mailer.rb +1 -1
  206. data/app/mailers/decidim/decidim_devise_mailer.rb +7 -1
  207. data/app/mailers/decidim/newsletter_mailer.rb +1 -4
  208. data/app/mailers/decidim/newsletters_opt_in_mailer.rb +2 -2
  209. data/app/mailers/decidim/notification_mailer.rb +0 -1
  210. data/app/mailers/decidim/notifications_digest_mailer.rb +0 -1
  211. data/app/mailers/decidim/reported_mailer.rb +6 -3
  212. data/app/mailers/decidim/user_report_mailer.rb +1 -1
  213. data/app/models/decidim/action_log.rb +2 -12
  214. data/app/models/decidim/area_type.rb +1 -1
  215. data/app/models/decidim/attachment.rb +28 -4
  216. data/app/models/decidim/authorization.rb +1 -1
  217. data/app/models/decidim/authorization_transfer.rb +1 -0
  218. data/app/models/decidim/component.rb +3 -6
  219. data/app/models/decidim/content_block.rb +3 -3
  220. data/app/models/decidim/messaging/message.rb +2 -2
  221. data/app/models/decidim/newsletter.rb +9 -9
  222. data/app/models/decidim/notification.rb +2 -2
  223. data/app/models/decidim/organization.rb +23 -2
  224. data/app/models/decidim/push_notification_message.rb +1 -1
  225. data/app/models/decidim/resource_link.rb +1 -1
  226. data/app/models/decidim/user.rb +18 -14
  227. data/app/models/decidim/user_base_entity.rb +0 -4
  228. data/app/models/decidim/user_group.rb +2 -2
  229. data/app/packs/src/decidim/a11y.js +61 -11
  230. data/app/packs/src/decidim/append_redirect_url_to_modals.js +14 -24
  231. data/app/packs/src/decidim/attachments/file_or_link_tabs.js +55 -0
  232. data/app/packs/src/decidim/attachments/index.js +1 -0
  233. data/app/packs/src/decidim/back_to_list.js +1 -1
  234. data/app/packs/src/decidim/check_boxes_tree.js +1 -1
  235. data/app/packs/src/decidim/data_consent/consent_manager.js +1 -1
  236. data/app/packs/src/decidim/data_consent/consent_manager.test.js +6 -6
  237. data/app/packs/src/decidim/data_consent/index.js +1 -1
  238. data/app/packs/src/decidim/datepicker/datepicker_functions.js +243 -0
  239. data/app/packs/src/decidim/datepicker/datepicker_listeners.js +78 -0
  240. data/app/packs/src/decidim/datepicker/form_datepicker.js +91 -0
  241. data/app/packs/src/decidim/datepicker/generate_datepicker.js +148 -0
  242. data/app/packs/src/decidim/datepicker/generate_timepicker.js +298 -0
  243. data/app/packs/src/decidim/datepicker/test/date.test.js +118 -0
  244. data/app/packs/src/decidim/datepicker/test/time.test.js +227 -0
  245. data/app/packs/src/decidim/direct_uploads/upload_field.js +8 -21
  246. data/app/packs/src/decidim/direct_uploads/upload_modal.js +0 -3
  247. data/app/packs/src/decidim/editor/extensions/indent/index.js +1 -1
  248. data/app/packs/src/decidim/editor/extensions/video_embed/index.js +4 -4
  249. data/app/packs/src/decidim/editor/test/extensions/decidim_kit.test.js +0 -15
  250. data/app/packs/src/decidim/editor/test/extensions/indent.test.js +1 -1
  251. data/app/packs/src/decidim/editor/test/fixtures/upload_templates.js +1 -1
  252. data/app/packs/src/decidim/editor/test/helpers.js +1 -14
  253. data/app/packs/src/decidim/editor/utilities/paste_transform.js +2 -2
  254. data/app/packs/src/decidim/external_domain_warning.js +2 -2
  255. data/app/packs/src/decidim/external_domain_warning.test.js +4 -4
  256. data/app/packs/src/decidim/form_filter.js +4 -4
  257. data/app/packs/src/decidim/impersonation.js +1 -1
  258. data/app/packs/src/decidim/index.js +11 -10
  259. data/app/packs/src/decidim/input_character_counter.js +2 -2
  260. data/app/packs/src/decidim/input_emoji.js +171 -72
  261. data/app/packs/src/decidim/input_hashtags.js +1 -1
  262. data/app/packs/src/decidim/input_mentions.js +1 -1
  263. data/app/packs/src/decidim/map/provider/here.js +1 -1
  264. data/app/packs/src/decidim/notifications_actions.js +40 -0
  265. data/app/packs/src/decidim/sticky_header.js +87 -0
  266. data/app/packs/src/decidim/sw/sw.js +8 -6
  267. data/app/packs/src/decidim/toggle.js +1 -1
  268. data/app/packs/src/decidim/tooltips.js +23 -43
  269. data/app/packs/src/decidim/vendor/leaflet-tilelayer-here.js +212 -0
  270. data/app/packs/stylesheets/decidim/_buttons.scss +1 -1
  271. data/app/packs/stylesheets/decidim/_datepicker.scss +193 -0
  272. data/app/packs/stylesheets/decidim/_dropdown.scss +45 -9
  273. data/app/packs/stylesheets/decidim/_emoji.scss +36 -0
  274. data/app/packs/stylesheets/decidim/_filters.scss +4 -2
  275. data/app/packs/stylesheets/decidim/_flash.scss +2 -2
  276. data/app/packs/stylesheets/decidim/_footer.scss +1 -3
  277. data/app/packs/stylesheets/decidim/_forms.scss +13 -5
  278. data/app/packs/stylesheets/decidim/_header.scss +70 -68
  279. data/app/packs/stylesheets/decidim/_home.scss +1 -1
  280. data/app/packs/stylesheets/decidim/_layout.scss +13 -0
  281. data/app/packs/stylesheets/decidim/_modal.scss +1 -1
  282. data/app/packs/stylesheets/decidim/_modal_update.scss +1 -5
  283. data/app/packs/stylesheets/decidim/_notifications.scss +4 -0
  284. data/app/packs/stylesheets/decidim/_profile.scss +1 -1
  285. data/app/packs/stylesheets/decidim/_progress-bar.scss +1 -1
  286. data/app/packs/stylesheets/decidim/_tabs_x.scss +5 -1
  287. data/app/packs/stylesheets/decidim/_tooltip.scss +10 -10
  288. data/app/packs/stylesheets/decidim/application.scss +4 -1
  289. data/app/packs/stylesheets/decidim/editor.scss +1 -1
  290. data/app/packs/stylesheets/decidim/legacy/conference-diploma.scss +1 -2
  291. data/app/packs/stylesheets/decidim/legacy/leaflet.scss +1 -1
  292. data/app/packs/stylesheets/decidim/vendor/_datepicker_light.scss +228 -0
  293. data/app/permissions/decidim/default_permissions.rb +2 -2
  294. data/app/presenters/decidim/admin_log/organization_presenter.rb +1 -1
  295. data/app/presenters/decidim/admin_log/static_page_presenter.rb +1 -1
  296. data/app/presenters/decidim/attachment_presenter.rb +1 -1
  297. data/app/presenters/decidim/authorization_transfer_presenter.rb +1 -1
  298. data/app/presenters/decidim/component_attachment_collection_presenter.rb +81 -0
  299. data/app/presenters/decidim/footer_menu_presenter.rb +1 -1
  300. data/app/presenters/decidim/home_stats_presenter.rb +1 -1
  301. data/app/presenters/decidim/log/user_presenter.rb +0 -1
  302. data/app/presenters/decidim/menu_item_presenter.rb +1 -1
  303. data/app/presenters/decidim/organization_presenter.rb +1 -1
  304. data/app/queries/decidim/last_activity.rb +5 -16
  305. data/app/queries/decidim/metric_measure.rb +1 -1
  306. data/app/queries/decidim/public_activities.rb +1 -1
  307. data/app/queries/decidim/user_groups/admin_memberships.rb +1 -1
  308. data/app/queries/decidim/user_groups/member_memberships.rb +1 -1
  309. data/app/services/decidim/action_logger.rb +3 -3
  310. data/app/services/decidim/base_diff_renderer.rb +2 -28
  311. data/app/services/decidim/download_your_data_exporter.rb +25 -36
  312. data/app/services/decidim/email_notification_generator.rb +5 -14
  313. data/app/services/decidim/log/diff_changeset_calculator.rb +2 -2
  314. data/app/services/decidim/notifications_digest_sending_decider.rb +1 -1
  315. data/app/services/decidim/open_data_exporter.rb +7 -8
  316. data/app/services/decidim/static_map_generator.rb +1 -1
  317. data/app/services/decidim/zip_stream/writer.rb +39 -0
  318. data/app/uploaders/decidim/organization_favicon_uploader.rb +1 -1
  319. data/app/uploaders/decidim/record_image_uploader.rb +2 -2
  320. data/app/validators/organization_present_validator.rb +1 -1
  321. data/app/validators/passthru_validator.rb +1 -1
  322. data/app/validators/uploader_image_dimensions_validator.rb +2 -2
  323. data/app/views/decidim/account/show.html.erb +1 -1
  324. data/app/views/decidim/amendments/_wizard_header.html.erb +1 -2
  325. data/app/views/decidim/application/_collection.html.erb +3 -1
  326. data/app/views/decidim/application/_component_documents.html.erb +4 -0
  327. data/app/views/decidim/application/_document.html.erb +23 -9
  328. data/app/views/decidim/block_user_mailer/notify.html.erb +2 -2
  329. data/app/views/decidim/devise/invitations/edit.html.erb +2 -2
  330. data/app/views/decidim/devise/omniauth_registrations/new.html.erb +2 -2
  331. data/app/views/decidim/devise/registrations/new.html.erb +1 -1
  332. data/app/views/decidim/devise/shared/_login_boxes.html.erb +1 -1
  333. data/app/views/decidim/doorkeeper/authorizations/new.html.erb +1 -1
  334. data/app/views/decidim/endorsements/_identity.html.erb +1 -1
  335. data/app/views/decidim/gamification/badges/index.html.erb +1 -1
  336. data/app/views/decidim/last_activities/index.html.erb +1 -1
  337. data/app/views/decidim/manifests/show.json.erb +4 -4
  338. data/app/views/decidim/messaging/conversations/_add_conversation_users.html.erb +2 -2
  339. data/app/views/decidim/messaging/conversations/_error_modal.html.erb +5 -5
  340. data/app/views/decidim/newsletter_mailer/newsletter.html.erb +1 -1
  341. data/app/views/decidim/newsletters/show.html.erb +1 -1
  342. data/app/views/decidim/newsletters_opt_in_mailer/notify.html.erb +2 -2
  343. data/app/views/decidim/offline/show.html.erb +1 -1
  344. data/app/views/decidim/pages/_tabbed.html.erb +5 -5
  345. data/app/views/decidim/pages/index.html.erb +1 -2
  346. data/app/views/decidim/reported_mailer/hide.html.erb +1 -1
  347. data/app/views/decidim/reported_mailer/report.html.erb +5 -3
  348. data/app/views/decidim/scopes/picker.html.erb +5 -5
  349. data/app/views/decidim/searches/_count.html.erb +1 -1
  350. data/app/views/decidim/searches/_filters.html.erb +38 -40
  351. data/app/views/decidim/searches/_resources_filter_block.html.erb +6 -6
  352. data/app/views/decidim/shared/_extended_navigation_bar.html.erb +8 -8
  353. data/app/views/decidim/shared/_filters.html.erb +5 -5
  354. data/app/views/decidim/shared/_login_modal.html.erb +1 -1
  355. data/app/views/decidim/shared/_orders.html.erb +2 -3
  356. data/app/views/decidim/shared/filters/_check_boxes_tree.html.erb +1 -1
  357. data/app/views/decidim/shared/filters/_collection.html.erb +1 -1
  358. data/app/views/decidim/user_interests/_areas.html.erb +2 -2
  359. data/app/views/decidim/user_report_mailer/notify.html.erb +2 -2
  360. data/app/views/decidim/user_update_mailer/notify.html.erb +1 -1
  361. data/app/views/decidim/widgets/_data_picker.html.erb +1 -1
  362. data/app/views/devise/mailer/invitation_instructions.html.erb +1 -1
  363. data/app/views/devise/mailer/invitation_instructions.text.erb +1 -1
  364. data/app/views/devise/mailer/invite_admin.html.erb +2 -2
  365. data/app/views/devise/mailer/invite_admin.text.erb +2 -2
  366. data/app/views/devise/mailer/invite_collaborator.html.erb +2 -2
  367. data/app/views/devise/mailer/invite_collaborator.text.erb +2 -2
  368. data/app/views/devise/mailer/invite_private_user.html.erb +2 -2
  369. data/app/views/devise/mailer/invite_private_user.text.erb +2 -2
  370. data/app/views/devise/mailer/organization_admin_invitation_instructions.html.erb +1 -1
  371. data/app/views/devise/mailer/organization_admin_invitation_instructions.text.erb +1 -1
  372. data/app/views/layouts/decidim/_application.html.erb +3 -6
  373. data/app/views/layouts/decidim/_data_consent_warning.html.erb +2 -2
  374. data/app/views/layouts/decidim/_decidim_javascript.html.erb +1 -1
  375. data/app/views/layouts/decidim/_head.html.erb +1 -1
  376. data/app/views/layouts/decidim/_head_extra.html.erb +2 -2
  377. data/app/views/layouts/decidim/_impersonation_warning.html.erb +1 -1
  378. data/app/views/layouts/decidim/_js_configuration.html.erb +7 -2
  379. data/app/views/layouts/decidim/_logo.html.erb +2 -2
  380. data/app/views/layouts/decidim/_logo_mobile.html.erb +11 -0
  381. data/app/views/layouts/decidim/_mailer_logo.html.erb +2 -2
  382. data/app/views/layouts/decidim/_meta_tags_config.html.erb +1 -1
  383. data/app/views/layouts/decidim/_wrapper.html.erb +16 -9
  384. data/app/views/layouts/decidim/footer/_main.html.erb +2 -3
  385. data/app/views/layouts/decidim/footer/_main_intro.html.erb +2 -2
  386. data/app/views/layouts/decidim/footer/_main_legal.html.erb +2 -3
  387. data/app/views/layouts/decidim/footer/_main_links.html.erb +13 -11
  388. data/app/views/layouts/decidim/footer/_main_social_media_links.html.erb +8 -8
  389. data/app/views/layouts/decidim/header/_main.html.erb +9 -22
  390. data/app/views/layouts/decidim/header/_main_links_desktop.html.erb +4 -5
  391. data/app/views/layouts/decidim/header/_main_links_mobile_account.html.erb +11 -4
  392. data/app/views/layouts/decidim/header/_main_links_mobile_item_account.html.erb +24 -0
  393. data/app/views/layouts/decidim/header/_main_links_mobile_search.html.erb +0 -21
  394. data/app/views/layouts/decidim/header/_main_menu_mobile.html.erb +12 -0
  395. data/app/views/layouts/decidim/header/_menu_breadcrumb_desktop.html.erb +1 -1
  396. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_mobile.html.erb +17 -0
  397. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_top_left.html.erb +1 -1
  398. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile_tablet.html.erb +1 -1
  399. data/app/views/layouts/decidim/header/_menu_form_search_mobile.html.erb +16 -0
  400. data/app/views/layouts/decidim/header/_mobile_language_choose.html.erb +25 -0
  401. data/app/views/layouts/decidim/mailer.html.erb +2 -2
  402. data/app/views/layouts/decidim/shared/_layout_center.html.erb +1 -1
  403. data/app/views/layouts/decidim/shared/_layout_item.html.erb +0 -14
  404. data/app/views/layouts/decidim/shared/_layout_user_profile.html.erb +2 -2
  405. data/config/initializers/active_storage.rb +3 -0
  406. data/config/initializers/devise.rb +1 -1
  407. data/config/initializers/new_framework_defaults_7_0.rb +145 -0
  408. data/config/locales/ar.yml +15 -97
  409. data/config/locales/bg.yml +58 -68
  410. data/config/locales/ca.yml +85 -121
  411. data/config/locales/cs.yml +63 -114
  412. data/config/locales/de.yml +79 -115
  413. data/config/locales/el.yml +3 -46
  414. data/config/locales/en.yml +62 -98
  415. data/config/locales/eo.yml +0 -2
  416. data/config/locales/es-MX.yml +76 -112
  417. data/config/locales/es-PY.yml +80 -116
  418. data/config/locales/es.yml +86 -122
  419. data/config/locales/eu.yml +310 -357
  420. data/config/locales/fi-plain.yml +73 -101
  421. data/config/locales/fi.yml +135 -163
  422. data/config/locales/fr-CA.yml +65 -107
  423. data/config/locales/fr.yml +58 -100
  424. data/config/locales/ga-IE.yml +0 -22
  425. data/config/locales/gl.yml +3 -51
  426. data/config/locales/hu.yml +43 -69
  427. data/config/locales/id-ID.yml +3 -46
  428. data/config/locales/is-IS.yml +2 -31
  429. data/config/locales/it.yml +12 -107
  430. data/config/locales/ja.yml +86 -122
  431. data/config/locales/lb.yml +7 -57
  432. data/config/locales/lt.yml +4 -57
  433. data/config/locales/lv.yml +2 -47
  434. data/config/locales/nl.yml +6 -57
  435. data/config/locales/no.yml +0 -50
  436. data/config/locales/pl.yml +67 -64
  437. data/config/locales/pt-BR.yml +8 -263
  438. data/config/locales/pt.yml +0 -56
  439. data/config/locales/ro-RO.yml +253 -561
  440. data/config/locales/ru.yml +1 -48
  441. data/config/locales/sk.yml +7 -60
  442. data/config/locales/sl.yml +0 -12
  443. data/config/locales/sr-CS.yml +0 -2
  444. data/config/locales/sv.yml +169 -629
  445. data/config/locales/tr-TR.yml +12 -59
  446. data/config/locales/uk.yml +2 -30
  447. data/config/locales/zh-CN.yml +2 -49
  448. data/config/locales/zh-TW.yml +1 -61
  449. data/config/routes.rb +0 -2
  450. data/db/migrate/20170128112958_change_user_groups_verified_to_timestamp.rb +1 -1
  451. data/db/migrate/20181025082245_add_timestamps_to_components.rb +1 -5
  452. data/db/migrate/20240110150230_rename_external_domain_whitelist_to_external_domain_allowlist.rb +7 -0
  453. data/db/migrate/20240326104215_remove_show_in_footer_in_static_pages.rb +7 -0
  454. data/db/migrate/20240401192628_change_name_on_decidim_organizations.rb +31 -0
  455. data/db/seeds/avatars/001.jpg +0 -0
  456. data/db/seeds/avatars/002.jpg +0 -0
  457. data/db/seeds/avatars/003.jpg +0 -0
  458. data/db/seeds/avatars/004.jpg +0 -0
  459. data/db/seeds/avatars/005.jpg +0 -0
  460. data/db/seeds/avatars/006.jpg +0 -0
  461. data/db/seeds/avatars/007.jpg +0 -0
  462. data/db/seeds/avatars/008.jpg +0 -0
  463. data/db/seeds/avatars/009.jpg +0 -0
  464. data/db/seeds/avatars/010.jpg +0 -0
  465. data/db/seeds/avatars/011.jpg +0 -0
  466. data/db/seeds/avatars/012.jpg +0 -0
  467. data/db/seeds/avatars/013.jpg +0 -0
  468. data/db/seeds/avatars/014.jpg +0 -0
  469. data/db/seeds/avatars/015.jpg +0 -0
  470. data/db/seeds/avatars/016.jpg +0 -0
  471. data/db/seeds/avatars/017.jpg +0 -0
  472. data/db/seeds/avatars/018.jpg +0 -0
  473. data/db/seeds/avatars/019.jpg +0 -0
  474. data/db/seeds/avatars/020.jpg +0 -0
  475. data/db/seeds/avatars/021.jpg +0 -0
  476. data/db/seeds/avatars/022.jpg +0 -0
  477. data/db/seeds/avatars/023.jpg +0 -0
  478. data/db/seeds/avatars/024.jpg +0 -0
  479. data/db/seeds/avatars/025.jpg +0 -0
  480. data/db/seeds/avatars/026.jpg +0 -0
  481. data/db/seeds/avatars/027.jpg +0 -0
  482. data/db/seeds/avatars/028.jpg +0 -0
  483. data/db/seeds/avatars/029.jpg +0 -0
  484. data/db/seeds/avatars/030.jpg +0 -0
  485. data/db/seeds/avatars/031.jpg +0 -0
  486. data/db/seeds/avatars/032.jpg +0 -0
  487. data/db/seeds/avatars/033.jpg +0 -0
  488. data/db/seeds/avatars/034.jpg +0 -0
  489. data/db/seeds/avatars/035.jpg +0 -0
  490. data/db/seeds/avatars/036.jpg +0 -0
  491. data/db/seeds/avatars/037.jpg +0 -0
  492. data/db/seeds/avatars/038.jpg +0 -0
  493. data/db/seeds/avatars/039.jpg +0 -0
  494. data/db/seeds/avatars/040.jpg +0 -0
  495. data/db/seeds/avatars/041.jpg +0 -0
  496. data/db/seeds/avatars/042.jpg +0 -0
  497. data/db/seeds/avatars/043.jpg +0 -0
  498. data/db/seeds/avatars/044.jpg +0 -0
  499. data/db/seeds/avatars/045.jpg +0 -0
  500. data/db/seeds/avatars/046.jpg +0 -0
  501. data/db/seeds/avatars/047.jpg +0 -0
  502. data/db/seeds/avatars/048.jpg +0 -0
  503. data/db/seeds/avatars/049.jpg +0 -0
  504. data/db/seeds/avatars/050.jpg +0 -0
  505. data/db/seeds/avatars/051.jpg +0 -0
  506. data/db/seeds/avatars/052.jpg +0 -0
  507. data/db/seeds/avatars/053.jpg +0 -0
  508. data/db/seeds/avatars/054.jpg +0 -0
  509. data/db/seeds/avatars/055.jpg +0 -0
  510. data/db/seeds/avatars/056.jpg +0 -0
  511. data/db/seeds/avatars/057.jpg +0 -0
  512. data/db/seeds/avatars/058.jpg +0 -0
  513. data/db/seeds/avatars/059.jpg +0 -0
  514. data/db/seeds/avatars/060.jpg +0 -0
  515. data/db/seeds/avatars/061.jpg +0 -0
  516. data/db/seeds/avatars/062.jpg +0 -0
  517. data/db/seeds/avatars/063.jpg +0 -0
  518. data/db/seeds/avatars/064.jpg +0 -0
  519. data/db/seeds/avatars/065.jpg +0 -0
  520. data/db/seeds/avatars/066.jpg +0 -0
  521. data/db/seeds/avatars/067.jpg +0 -0
  522. data/db/seeds/avatars/068.jpg +0 -0
  523. data/db/seeds/avatars/069.jpg +0 -0
  524. data/db/seeds/avatars/070.jpg +0 -0
  525. data/db/seeds/avatars/071.jpg +0 -0
  526. data/db/seeds/avatars/072.jpg +0 -0
  527. data/db/seeds/avatars/073.jpg +0 -0
  528. data/db/seeds/avatars/074.jpg +0 -0
  529. data/db/seeds/avatars/075.jpg +0 -0
  530. data/db/seeds/avatars/076.jpg +0 -0
  531. data/db/seeds/avatars/077.jpg +0 -0
  532. data/db/seeds/avatars/078.jpg +0 -0
  533. data/db/seeds/avatars/079.jpg +0 -0
  534. data/db/seeds/avatars/080.jpg +0 -0
  535. data/db/seeds/avatars/081.jpg +0 -0
  536. data/db/seeds/avatars/082.jpg +0 -0
  537. data/db/seeds/avatars/083.jpg +0 -0
  538. data/db/seeds/avatars/084.jpg +0 -0
  539. data/db/seeds/avatars/085.jpg +0 -0
  540. data/db/seeds/avatars/086.jpg +0 -0
  541. data/db/seeds/avatars/087.jpg +0 -0
  542. data/db/seeds/avatars/088.jpg +0 -0
  543. data/db/seeds/avatars/089.jpg +0 -0
  544. data/db/seeds/avatars/090.jpg +0 -0
  545. data/db/seeds/avatars/091.jpg +0 -0
  546. data/db/seeds/avatars/092.jpg +0 -0
  547. data/db/seeds/avatars/093.jpg +0 -0
  548. data/db/seeds/avatars/094.jpg +0 -0
  549. data/db/seeds/avatars/095.jpg +0 -0
  550. data/db/seeds/avatars/096.jpg +0 -0
  551. data/db/seeds/avatars/097.jpg +0 -0
  552. data/db/seeds/avatars/098.jpg +0 -0
  553. data/db/seeds/avatars/099.jpg +0 -0
  554. data/db/seeds/avatars/100.jpg +0 -0
  555. data/db/seeds/avatars/CREDITS.md +114 -0
  556. data/db/seeds/avatars/README.md +25 -0
  557. data/decidim-core.gemspec +8 -9
  558. data/lib/decidim/acts_as_author.rb +1 -1
  559. data/lib/decidim/admin_filter.rb +44 -0
  560. data/lib/decidim/admin_filters_registry.rb +55 -0
  561. data/lib/decidim/amendable.rb +1 -2
  562. data/lib/decidim/api/functions/component_finder_base.rb +1 -1
  563. data/lib/decidim/api/functions/component_list.rb +1 -1
  564. data/lib/decidim/api/functions/needs_api_filter_and_order.rb +3 -3
  565. data/lib/decidim/api/functions/participatory_space_finder_base.rb +2 -12
  566. data/lib/decidim/api/functions/participatory_space_list_base.rb +1 -1
  567. data/lib/decidim/api/input_filters/user_entity_input_filter.rb +3 -3
  568. data/lib/decidim/api/interfaces/author_interface.rb +1 -1
  569. data/lib/decidim/api/interfaces/participatory_space_interface.rb +1 -1
  570. data/lib/decidim/api/types/component_type.rb +0 -7
  571. data/lib/decidim/api/types/organization_type.rb +1 -1
  572. data/lib/decidim/api/types/user_group_type.rb +1 -5
  573. data/lib/decidim/api/types/user_type.rb +1 -5
  574. data/lib/decidim/asset_router/pipeline.rb +2 -2
  575. data/lib/decidim/asset_router/storage.rb +11 -214
  576. data/lib/decidim/assets/tailwind/instance.rb +1 -1
  577. data/lib/decidim/assets/tailwind/tailwind.config.js.erb +8 -3
  578. data/lib/decidim/attribute_object/model.rb +2 -2
  579. data/lib/decidim/attribute_object/type_resolver.rb +1 -3
  580. data/lib/decidim/attribute_object.rb +2 -2
  581. data/lib/decidim/attributes/time_with_zone.rb +2 -16
  582. data/lib/decidim/attributes.rb +0 -6
  583. data/lib/decidim/authorable.rb +5 -0
  584. data/lib/decidim/command.rb +2 -2
  585. data/lib/decidim/commands/create_resource.rb +63 -0
  586. data/lib/decidim/commands/destroy_resource.rb +74 -0
  587. data/lib/decidim/commands/hook_error.rb +8 -0
  588. data/lib/decidim/commands/resource_handler.rb +85 -0
  589. data/lib/decidim/commands/update_resource.rb +64 -0
  590. data/lib/decidim/component_manifest.rb +3 -1
  591. data/lib/decidim/component_validator.rb +1 -1
  592. data/lib/decidim/content_blocks/has_related_components.rb +1 -1
  593. data/lib/decidim/content_parsers/resource_parser.rb +2 -2
  594. data/lib/decidim/content_parsers/user_parser.rb +1 -1
  595. data/lib/decidim/content_parsers.rb +0 -1
  596. data/lib/decidim/content_processor.rb +1 -1
  597. data/lib/decidim/content_renderers.rb +0 -1
  598. data/lib/decidim/content_security_policy.rb +1 -1
  599. data/lib/decidim/core/engine.rb +13 -58
  600. data/lib/decidim/core/menu.rb +13 -3
  601. data/lib/decidim/core/seeds.rb +120 -147
  602. data/lib/decidim/core/test/factories.rb +24 -31
  603. data/lib/decidim/core/test/shared_examples/acts_as_author_examples.rb +1 -1
  604. data/lib/decidim/core/test/shared_examples/amendable/withdraw_amendment_examples.rb +2 -2
  605. data/lib/decidim/core/test/shared_examples/announcements_examples.rb +3 -3
  606. data/lib/decidim/core/test/shared_examples/assembly_announcements_examples.rb +4 -4
  607. data/lib/decidim/core/test/shared_examples/attachable_interface_examples.rb +1 -1
  608. data/lib/decidim/core/test/shared_examples/authorable_interface_examples.rb +1 -1
  609. data/lib/decidim/core/test/shared_examples/comments_examples.rb +90 -107
  610. data/lib/decidim/core/test/shared_examples/comments_reports_examples.rb +4 -4
  611. data/lib/decidim/core/test/shared_examples/digest_mail_examples.rb +1 -1
  612. data/lib/decidim/core/test/shared_examples/edit_link_shared_examples.rb +1 -1
  613. data/lib/decidim/core/test/shared_examples/editor_shared_examples.rb +7 -7
  614. data/lib/decidim/core/test/shared_examples/fingerprint_examples.rb +1 -1
  615. data/lib/decidim/core/test/shared_examples/follows_examples.rb +6 -11
  616. data/lib/decidim/core/test/shared_examples/has_attachment_collections.rb +4 -2
  617. data/lib/decidim/core/test/shared_examples/has_attachments.rb +3 -2
  618. data/lib/decidim/core/test/shared_examples/has_contextual_help.rb +4 -4
  619. data/lib/decidim/core/test/shared_examples/has_reference.rb +1 -1
  620. data/lib/decidim/core/test/shared_examples/logo_email.rb +1 -1
  621. data/lib/decidim/core/test/shared_examples/manage_component_share_tokens.rb +9 -9
  622. data/lib/decidim/core/test/shared_examples/map_examples.rb +5 -5
  623. data/lib/decidim/core/test/shared_examples/paginated_resource_examples.rb +7 -7
  624. data/lib/decidim/core/test/shared_examples/participatory_space_dropdown_metadata_cell_examples.rb +3 -3
  625. data/lib/decidim/core/test/shared_examples/preview_component_with_share_token_examples.rb +3 -3
  626. data/lib/decidim/core/test/shared_examples/process_announcements_examples.rb +4 -4
  627. data/lib/decidim/core/test/shared_examples/reports_examples.rb +11 -53
  628. data/lib/decidim/core/test/shared_examples/rich_text_editor_examples.rb +10 -10
  629. data/lib/decidim/core/test/shared_examples/searchable_participatory_space_examples.rb +1 -1
  630. data/lib/decidim/core/test/shared_examples/searchable_results_examples.rb +8 -8
  631. data/lib/decidim/core/test/shared_examples/share_link_examples.rb +2 -2
  632. data/lib/decidim/core/test/shared_examples/simple_event.rb +1 -1
  633. data/lib/decidim/core/test/shared_examples/space_cell_changes_button_text_cta.rb +3 -3
  634. data/lib/decidim/core/test/shared_examples/system_endorse_resource_examples.rb +15 -113
  635. data/lib/decidim/core/test/shared_examples/translated_event_examples.rb +2 -2
  636. data/lib/decidim/core/test/shared_examples/uncommentable_component_examples.rb +2 -28
  637. data/lib/decidim/core/test/shared_examples/versions_controller_examples.rb +0 -26
  638. data/lib/decidim/core/test/shared_examples/with_endorsable_permissions_examples.rb +1 -1
  639. data/lib/decidim/core/version.rb +1 -1
  640. data/lib/decidim/core.rb +24 -17
  641. data/lib/decidim/dependency_resolver.rb +3 -3
  642. data/lib/decidim/diffy_extension.rb +1 -19
  643. data/lib/decidim/download_your_data_serializers/download_your_data_user_serializer.rb +2 -1
  644. data/lib/decidim/engine_router.rb +2 -2
  645. data/lib/decidim/events/base_event.rb +19 -0
  646. data/lib/decidim/events/simple_event.rb +1 -0
  647. data/lib/decidim/exporters/export_manifest.rb +1 -1
  648. data/lib/decidim/faker/localized.rb +3 -3
  649. data/lib/decidim/form_builder.rb +5 -5
  650. data/lib/decidim/hashtag.rb +1 -1
  651. data/lib/decidim/jsonb_attributes.rb +4 -4
  652. data/lib/decidim/manifest_messages.rb +2 -2
  653. data/lib/decidim/map/autocomplete.rb +0 -1
  654. data/lib/decidim/map/provider/dynamic_map/here.rb +40 -1
  655. data/lib/decidim/map/provider/static_map/here.rb +0 -34
  656. data/lib/decidim/nicknamizable.rb +1 -1
  657. data/lib/decidim/organization_settings.rb +5 -8
  658. data/lib/decidim/paddable.rb +1 -1
  659. data/lib/decidim/participable.rb +1 -1
  660. data/lib/decidim/participatory_space_manifest.rb +1 -1
  661. data/lib/decidim/participatory_space_user.rb +0 -4
  662. data/lib/decidim/query_extensions.rb +26 -0
  663. data/lib/decidim/reportable.rb +2 -6
  664. data/lib/decidim/resourceable.rb +1 -1
  665. data/lib/decidim/search_resource_fields_mapper.rb +2 -2
  666. data/lib/decidim/searchable.rb +3 -3
  667. data/lib/decidim/seeds.rb +62 -0
  668. data/lib/decidim/settings_manifest.rb +0 -2
  669. data/lib/decidim/stats_registry.rb +2 -2
  670. data/lib/decidim/translatable_attributes.rb +4 -13
  671. data/lib/decidim/translatable_resource.rb +1 -1
  672. data/lib/decidim/view_hooks.rb +1 -1
  673. data/lib/decidim/view_model.rb +4 -1
  674. data/lib/decidim/webpacker/esbuild.config.js +14 -0
  675. data/lib/decidim/webpacker/shakapacker.yml +2 -2
  676. data/lib/decidim/webpacker/tsconfig.json +11 -0
  677. data/lib/decidim/webpacker/webpack/custom.js +13 -35
  678. data/lib/devise/models/decidim_newsletterable.rb +1 -1
  679. data/lib/tasks/decidim_download_your_data_tasks.rake +2 -2
  680. data/lib/tasks/decidim_locales_tasks.rake +1 -1
  681. data/lib/tasks/decidim_mailers_tasks.rake +2 -2
  682. data/lib/tasks/decidim_metrics_tasks.rake +6 -6
  683. data/lib/tasks/decidim_procfile.rake +9 -3
  684. data/lib/tasks/decidim_tasks.rake +5 -4
  685. data/lib/tasks/decidim_webpacker_tasks.rake +126 -117
  686. data/lib/tasks/upgrade/decidim_active_storage_migration_tasks.rake +80 -0
  687. data/lib/tasks/upgrade/decidim_content_blocks_tasks.rake +50 -0
  688. data/lib/tasks/upgrade/decidim_deduplicate_endorsements.rake +1 -1
  689. data/lib/tasks/upgrade/decidim_fix_categorization.rake +6 -132
  690. data/lib/tasks/upgrade/decidim_fix_nickname_uniqueness.rake +20 -23
  691. data/lib/tasks/upgrade/decidim_fix_short_url_resolver.rake +1 -1
  692. data/lib/tasks/upgrade/decidim_moderation_tasks.rake +1 -1
  693. data/lib/tasks/upgrade/decidim_user_moderation.rake +1 -1
  694. metadata +220 -103
  695. data/app/cells/decidim/content_blocks/cta/show.erb +0 -12
  696. data/app/cells/decidim/content_blocks/cta_cell.rb +0 -31
  697. data/app/cells/decidim/footer_pages/pages.erb +0 -3
  698. data/app/cells/decidim/footer_pages/topics.erb +0 -12
  699. data/app/cells/decidim/footer_pages_cell.rb +0 -68
  700. data/app/controllers/concerns/decidim/direct_upload.rb +0 -82
  701. data/app/helpers/concerns/decidim/user_role_checker.rb +0 -46
  702. data/app/packs/src/decidim/remote_tooltips.js +0 -38
  703. data/app/packs/src/decidim/vendor/modernizr.js +0 -5
  704. data/app/packs/stylesheets/decidim/_hashtags.scss +0 -5
  705. data/app/queries/decidim/similar_emendations.rb +0 -56
  706. data/app/uploaders/decidim/cw/application_uploader.rb +0 -77
  707. data/app/uploaders/decidim/cw/attachment_uploader.rb +0 -56
  708. data/app/uploaders/decidim/cw/avatar_uploader.rb +0 -24
  709. data/app/uploaders/decidim/cw/banner_image_uploader.rb +0 -7
  710. data/app/uploaders/decidim/cw/download_your_data_uploader.rb +0 -15
  711. data/app/uploaders/decidim/cw/downloader.rb +0 -9
  712. data/app/uploaders/decidim/cw/hero_image_uploader.rb +0 -10
  713. data/app/uploaders/decidim/cw/homepage_image_uploader.rb +0 -14
  714. data/app/uploaders/decidim/cw/image_uploader.rb +0 -78
  715. data/app/uploaders/decidim/cw/newsletter_template_image_uploader.rb +0 -38
  716. data/app/uploaders/decidim/cw/oauth_application_logo_uploader.rb +0 -10
  717. data/app/uploaders/decidim/cw/official_image_footer_uploader.rb +0 -10
  718. data/app/uploaders/decidim/cw/official_image_header_uploader.rb +0 -10
  719. data/app/uploaders/decidim/cw/open_data_uploader.rb +0 -23
  720. data/app/uploaders/decidim/cw/organization_favicon_uploader.rb +0 -18
  721. data/app/uploaders/decidim/cw/organization_logo_uploader.rb +0 -10
  722. data/app/uploaders/decidim/cw/record_image_uploader.rb +0 -15
  723. data/app/uploaders/decidim/downloader.rb +0 -9
  724. data/app/views/decidim/amendments/compare_draft.html.erb +0 -18
  725. data/app/views/layouts/decidim/_edit_link.html.erb +0 -0
  726. data/app/views/layouts/decidim/header/_main_links_mobile.html.erb +0 -36
  727. data/config/initializers/carrierwave.rb +0 -15
  728. data/config/locales/bn-BD.yml +0 -1
  729. data/config/locales/bs-BA.yml +0 -100
  730. data/config/locales/ca-IT.yml +0 -2115
  731. data/lib/decidim/attributes/rich_text.rb +0 -38
  732. data/lib/decidim/carrier_wave_migrator_service.rb +0 -287
  733. data/lib/decidim/content_parsers/blob_parser.rb +0 -95
  734. data/lib/decidim/content_renderers/blob_renderer.rb +0 -90
  735. data/lib/decidim/seven_zip_wrapper.rb +0 -29
  736. data/lib/tasks/decidim_active_storage_migration_tasks.rake +0 -114
  737. data/lib/tasks/decidim_content_blocks_tasks.rake +0 -48
  738. data/lib/tasks/upgrade/decidim_attachments.rake +0 -14
  739. /data/app/views/layouts/decidim/header/{_menu_breadcrumb_main_dropdown.html.erb → _menu_breadcrumb_main_dropdown_desktop.html.erb} +0 -0
@@ -6,23 +6,6 @@ module Decidim
6
6
  # saved through ActiveStorage. This handles the different cases for routing
7
7
  # to the remote routes when using an assets CDN or to local routes when
8
8
  # using the local disk storage driver.
9
- #
10
- # Note that when the assets are stored in a remote storage service, such as
11
- # Amazon S3, Google Cloud Storage or Azure Storage, this generates the asset
12
- # URL directly to the storage service itself bypassing the Rails server and
13
- # saving CPU time from serving the asset redirect requests. This causes a
14
- # significant performance improvement on pages that display a lot of images.
15
- # It will also produce a less significant performance improvement when using
16
- # the local disk storage because in this situation, the images are served
17
- # using one request instead of two when served directly from the storage
18
- # service rather than through the asset redirect URL.
19
- #
20
- # When implementing changes to the logic, please keep the remote storage
21
- # options and performance implications in mind because the specs for this
22
- # utility do not cover the remote storage options because the extra
23
- # configuration needed to test, the service itself needed for testing and
24
- # the extra dependency overhead for adding these remote storage gems when
25
- # they are not needed.
26
9
  class Storage
27
10
  # Initializes the router.
28
11
  #
@@ -30,36 +13,25 @@ module Decidim
30
13
  # to
31
14
  def initialize(asset)
32
15
  @asset = asset
33
- @blob =
34
- case asset
35
- when ActiveStorage::Blob
36
- asset
37
- else
38
- asset&.blob
39
- end
40
16
  end
41
17
 
42
18
  # Generates the correct URL to the asset with the provided options.
43
19
  #
44
20
  # @param options The options for the URL that are the normal route options
45
21
  # Rails route helpers accept
46
- # @return [String] The URL of the asset
47
22
  def url(**options)
48
- case asset
49
- when ActiveStorage::Attached
50
- ensure_current_host(asset.record, **options)
51
- blob_url(**options)
52
- when ActiveStorage::Blob
53
- blob_url(**options)
54
- else # ActiveStorage::VariantWithRecord, ActiveStorage::Variant
55
- ensure_current_host(nil, **options)
23
+ if asset.is_a? ActiveStorage::Attached
24
+ routes.rails_blob_url(asset.blob, **default_options.merge(options))
25
+ elsif asset.is_a? ActiveStorage::Blob
26
+ routes.rails_blob_url(asset, **default_options.merge(options))
27
+ else
56
28
  representation_url(**options)
57
29
  end
58
30
  end
59
31
 
60
32
  private
61
33
 
62
- attr_reader :asset, :blob
34
+ attr_reader :asset
63
35
 
64
36
  # Provides the route helpers depending on whether the URL is generated to
65
37
  # the local host or an external CDN (remote).
@@ -108,199 +80,24 @@ module Decidim
108
80
  }.compact
109
81
  end
110
82
 
111
- # Most of the times the current host should be set through the controller
112
- # already when the logic below is unnecessary. This logic is needed e.g.
113
- # for serializers where the request context is not available.
114
- #
115
- # @param record The record for which to check the organization
116
- # @param opts Options for building the URL
117
- # @return [void]
118
- def ensure_current_host(record, **opts)
119
- return if asset_url_available?
120
-
121
- options = remote? ? remote_storage_options : routes.default_url_options
122
- options = options.merge(opts)
123
-
124
- if opts[:host].blank? && record.present?
125
- organization = organization_for(record)
126
- options[:host] = organization.host if organization
127
- end
128
-
129
- uri =
130
- if options[:protocol] == "https" || options[:scheme] == "https"
131
- URI::HTTPS.build(options)
132
- else
133
- URI::HTTP.build(options)
134
- end
135
-
136
- ActiveStorage::Current.host = uri.to_s
137
- end
138
-
139
- # Determines the organization for the passed record.
140
- #
141
- # @param record The record for which to fetch the organization
142
- # @return [Decidim::Organization, nil] The organization for the record or
143
- # `nil` if the organization cannot be determined
144
- def organization_for(record)
145
- if record.is_a?(Decidim::Organization)
146
- record
147
- elsif record.respond_to?(:organization)
148
- record.organization
149
- end
150
- end
151
-
152
- # Returns the URL for the given blob object.
153
- #
154
- # @param blob The blob object
155
- # @param options Options for building the URL
156
- # @return [String, nil] The URL to the blob object or `nil` if the blob is
157
- # not defined.
158
- def blob_url(**options)
159
- return unless blob
160
-
161
- if options[:only_path] || remote? || !asset_url_available?
162
- routes.rails_blob_url(blob, **default_options.merge(options))
163
- else
164
- blob.url(**options)
165
- end
166
- end
167
-
168
- # Returns a representation URL for the asset either directly through the
169
- # storage service or through the Rails representation URL in case the
170
- # path URL is requested or if the asset variant has not been processed yet
171
- # and is not therefore yet stored at the storage service.
172
- #
173
- # @return [String] The representation URL for the image variant
174
- def representation_url(**options)
175
- return rails_representation_url(**options) if options[:only_path] || remote?
176
-
177
- representation_url = variant_url(**options)
178
- return representation_url if representation_url.present?
179
-
180
- # In case the representation has not been processed yet, it may not have
181
- # a representation URL yet and it therefore needs to be served through
182
- # the local representation URL for the first time (or until it has been
183
- # processed).
184
- if options[:host]
185
- rails_representation_url(**options)
186
- else
187
- representation_url(**options.merge(only_path: true))
188
- end
189
- end
190
-
191
- # Returns the local Rails representation URL meaning that the asset will
192
- # be served through the service itself. This may be necessary if the asset
193
- # variant (e.g. a thumbnail) has not been processed yet because the
194
- # variant representation has not been requested before.
195
- #
196
- # Due to performance reasons it is advised to avoid requesting the assets
197
- # through the Rails representation URLs when possible because that causes
198
- # a lot of requests to the Rails backend and slowness to the service under
199
- # heavy loads.
200
- #
201
83
  # Converts the variation URLs last part to the correct file extension in
202
- # case the variation has a different format than the original image. The
203
- # conversion needs to be only done for the Rails representation URLs
204
- # because once the image is stored at the storage service, it already has
205
- # the correct file extension.
84
+ # case the variation has a different format than the original image.
206
85
  #
207
- # @param options The options for building the URL
208
- # @return [String, nil] The converted representation URL or `nil` if the
209
- # asset is not defined.
210
- def rails_representation_url(**options)
211
- return unless asset
212
-
86
+ # @return [String] The converted representation URL
87
+ def representation_url(**options)
213
88
  representation_url = routes.rails_representation_url(asset, **default_options.merge(options))
214
-
215
89
  variation = asset.try(:variation)
216
90
  return representation_url unless variation
217
91
 
218
92
  format = variation.try(:format)
219
93
  return representation_url unless format
220
- return unless blob
221
94
 
222
- original_ext = File.extname(blob.filename.to_s)
95
+ original_ext = File.extname(asset.blob.filename.to_s)
223
96
  return representation_url if original_ext == ".#{format}"
224
97
 
225
- basename = File.basename(blob.filename.to_s, original_ext)
98
+ basename = File.basename(asset.blob.filename.to_s, original_ext)
226
99
  representation_url.sub(/#{basename}\.#{original_ext.tr(".", "")}$/, "#{basename}.#{format}")
227
100
  end
228
-
229
- # Fetches the image variant's URL at the storage service if the variant
230
- # has already been processed and is stored at the storage service. If the
231
- # variant has not been processed yet, returns `nil` in which case the
232
- # variant has to be served through the service's own representation URL
233
- # causing it to be processed and stored at the storage service.
234
- #
235
- # @param options The options for building the URL
236
- # @return [String, nil] The variant URL at the storage service or `nil` if
237
- # the variant has not been processed yet and does not yet exist at the
238
- # storage service or `nil` when the asset is not defined
239
- def variant_url(**options)
240
- return unless asset
241
- return unless asset_url_available?
242
- return unless asset_exist?
243
-
244
- case asset
245
- when ActiveStorage::VariantWithRecord
246
- # This is used when `ActiveStorage.track_variants` is enabled through
247
- # `config.active_storage.track_variants`. In case the variant has not
248
- # been processed yet, the `#url` method would return nil.
249
- #
250
- # Note that if the `asset.processed?` returns `true`, the variant
251
- # record has been created in the database but it does not mean that
252
- # it has been uploaded to the storage service yet. Likely a bug in
253
- # ActiveStorage but to be sure that the asset is uploaded to the
254
- # storage service, we also check that.
255
- asset.url(**options) if asset.processed?
256
- else # ActiveStorage::Variant
257
- # Check whether the variant exists at the storage service before
258
- # returning its URL. Otherwise the URL would be returned even when the
259
- # variant is not yet processed causing 404 errors for the images on
260
- # the page.
261
- #
262
- # Note that the `ActiveStorage::Variant#url` method only accepts
263
- # certain keyword arguments where as the other objects allow any
264
- # keyword arguments.
265
- possible_kwargs = asset.method(:url).parameters.select { |p| p[0] == :key }.map { |p| p[1] }
266
- asset.url(**options.slice(*possible_kwargs))
267
- end
268
- end
269
-
270
- # Determines if the asset exists at the storage service.
271
- #
272
- # @return [Boolean] A boolean answering the question "does this asset
273
- # exist at the storage service?".
274
- def asset_exist?
275
- return false if asset.key.blank?
276
-
277
- blob.service.exist?(asset.key)
278
- end
279
-
280
- # Determines if the current host is required to build the asset URL.
281
- #
282
- # @return [Boolean] A boolean indicating if the current host is required
283
- # to build the asset URL.
284
- def current_host_required?
285
- return false unless blob
286
- return false unless defined?(ActiveStorage::Service::DiskService)
287
-
288
- blob.service.is_a?(ActiveStorage::Service::DiskService)
289
- end
290
-
291
- # Determines if the asset URL can be generated.
292
- #
293
- # @return [Boolean] A boolean indicating if the asset URL can be
294
- # generated.
295
- def asset_url_available?
296
- # If the service is an external service, the URL can be generated
297
- # regardless of the current host being set.
298
- return true unless current_host_required?
299
-
300
- # For the disk service, the URL can be only generated if the current
301
- # host has been set.
302
- ActiveStorage::Current.host.present?
303
- end
304
101
  end
305
102
  end
306
103
  end
@@ -21,7 +21,7 @@ module Decidim
21
21
  decidim_gems = Bundler.load.specs.select { |spec| spec.name =~ /^decidim-/ }.map(&:full_gem_path)
22
22
  content_directories = decidim_gems.push(".")
23
23
 
24
- # The variable expected by tailwind is a Javascript array of strings
24
+ # The variable expected by tailwind is a JavaScript array of strings
25
25
  # The directory globbing with the star is done in Ruby because it was causing an infinite loop
26
26
  # when processed by Tailwind
27
27
  content_directories_as_array_of_strings = content_directories.map { |content_directory| "'#{content_directory}'" }.join(",")
@@ -36,9 +36,9 @@ module.exports = {
36
36
  primary: withOpacity("--primary-rgb"),
37
37
  secondary: withOpacity("--secondary-rgb"),
38
38
  tertiary: withOpacity("--tertiary-rgb"),
39
- success: withOpacity("--success-rgb"),
40
- alert: withOpacity("--alert-rgb"),
41
- warning: withOpacity("--warning-rgb"),
39
+ success: "#28A745",
40
+ alert: "#ED1C24",
41
+ warning: "#FFB703",
42
42
  black: "#020203",
43
43
  gray: {
44
44
  DEFAULT: "#6B7280CC", // 80% opacity
@@ -74,6 +74,11 @@ module.exports = {
74
74
  "3xl": ["32px", "40px"],
75
75
  "4xl": ["36px", "45px"],
76
76
  "5xl": ["48px", "60px"]
77
+ },
78
+ extend: {
79
+ transitionProperty: {
80
+ 'top': 'top',
81
+ }
77
82
  }
78
83
  },
79
84
  plugins: [require("@tailwindcss/typography")]
@@ -31,8 +31,8 @@ module Decidim
31
31
  end
32
32
 
33
33
  class_methods do
34
- def attribute(name, type = ActiveModel::Type::Value.new, **options)
35
- typedef = AttributeObject.types.resolve(type, **options)
34
+ def attribute(name, type = ActiveModel::Type::Value.new, **)
35
+ typedef = AttributeObject.types.resolve(type, **)
36
36
 
37
37
  super(name, typedef[:type], **typedef[:options])
38
38
 
@@ -27,9 +27,7 @@ module Decidim
27
27
  end
28
28
 
29
29
  def exists?(type)
30
- # This needs to be changed after upgrade to Rails 7.0 as follows:
31
- # ActiveModel::Type.registry.send(:registrations).has_key?(type)
32
- ActiveModel::Type.registry.send(:registrations).any? { |t| t.send(:name) == type }
30
+ ActiveModel::Type.registry.send(:registrations).has_key?(type)
33
31
  end
34
32
 
35
33
  private
@@ -17,8 +17,8 @@ module Decidim
17
17
  @types ||= TypeResolver.new
18
18
  end
19
19
 
20
- def self.type(type, **options)
21
- typedef = types.resolve(type, **options)
20
+ def self.type(type, **)
21
+ typedef = types.resolve(type, **)
22
22
 
23
23
  ActiveModel::Type.lookup(typedef[:type], **typedef[:options])
24
24
  end
@@ -5,15 +5,6 @@ module Decidim
5
5
  # Custom attributes value to parse a String representing a Time using
6
6
  # the app TimeZone.
7
7
  class TimeWithZone < ActiveModel::Type::DateTime
8
- # Date format: 2020-06-20T, 2020-06-20, 20/06/2020T or 20/06/2020
9
- # Time format: 10:20, 10:20:30 or 10:20:30.123456
10
- ISO_DATETIME_WITHOUT_TIMEZONE = %r{
11
- \A
12
- ((\d{4})-(\d\d)-(\d\d)|(\d\d)/(\d\d)/(\d{4}))(?:T|\s)
13
- (\d\d):(\d\d)(:(\d\d)(?:\.(\d{1,6})\d*)?)?
14
- \z
15
- }x
16
-
17
8
  def type
18
9
  :"decidim/attributes/time_with_zone"
19
10
  end
@@ -23,17 +14,12 @@ module Decidim
23
14
  def cast_value(value)
24
15
  return value unless value.is_a?(String)
25
16
 
26
- if Date._iso8601(value).present?
27
- Time.zone.iso8601(value)
28
- else
29
- Time.zone.strptime(value, I18n.t("time.formats.decidim_short"))
30
- end
17
+ Time.zone.strptime(value, I18n.t("time.formats.decidim_short"))
31
18
  rescue ArgumentError
32
19
  fallback = super
33
20
  return fallback unless fallback.is_a?(Time)
34
- return Time.zone.parse(fallback.strftime("%F %T")) if ISO_DATETIME_WITHOUT_TIMEZONE.match?(value)
35
21
 
36
- ActiveSupport::TimeWithZone.new(fallback, Time.zone)
22
+ Time.zone.parse(fallback.strftime("%F %T"))
37
23
  end
38
24
  end
39
25
  end
@@ -5,7 +5,6 @@ module Decidim
5
5
  autoload :TimeWithZone, "decidim/attributes/time_with_zone"
6
6
  autoload :LocalizedDate, "decidim/attributes/localized_date"
7
7
  autoload :CleanString, "decidim/attributes/clean_string"
8
- autoload :RichText, "decidim/attributes/rich_text"
9
8
  autoload :Blob, "decidim/attributes/blob"
10
9
  autoload :Array, "decidim/attributes/array"
11
10
  autoload :Hash, "decidim/attributes/hash"
@@ -28,13 +27,8 @@ module Decidim
28
27
  ActiveModel::Type.register(:"decidim/attributes/time_with_zone", Decidim::Attributes::TimeWithZone)
29
28
  ActiveModel::Type.register(:"decidim/attributes/localized_date", Decidim::Attributes::LocalizedDate)
30
29
  ActiveModel::Type.register(:"decidim/attributes/clean_string", Decidim::Attributes::CleanString)
31
- ActiveModel::Type.register(:"decidim/attributes/rich_text", Decidim::Attributes::RichText)
32
30
  ActiveModel::Type.register(:"decidim/attributes/blob", Decidim::Attributes::Blob)
33
31
 
34
- # Overrides
35
- # The overrides deletion can be omitted after upgrade to Rails 7.0 (delete this after upgrade)
36
- ActiveModel::Type.registry.send(:registrations).delete_if { |r| r.send(:name) == :integer }
37
-
38
32
  ActiveModel::Type.register(:integer, Decidim::Attributes::Integer)
39
33
  end
40
34
  end
@@ -7,6 +7,7 @@ module Decidim
7
7
  # this latest case the Coauthorable concern should be used instead of Authorable.
8
8
  module Authorable
9
9
  extend ActiveSupport::Concern
10
+ include Decidim::TranslatableAttributes
10
11
 
11
12
  included do
12
13
  belongs_to :author, polymorphic: true, foreign_key: "decidim_author_id", foreign_type: "decidim_author_type"
@@ -68,6 +69,10 @@ module Decidim
68
69
  decidim_author_type == Decidim::Organization.name
69
70
  end
70
71
 
72
+ def author_name
73
+ translated_attribute(normalized_author.name)
74
+ end
75
+
71
76
  private
72
77
 
73
78
  def verified_user_group
@@ -10,10 +10,10 @@ module Decidim
10
10
  include ::Wisper::Publisher
11
11
  delegate :locale, to: :I18n
12
12
 
13
- def self.call(*args, **kwargs, &)
13
+ def self.call(*, **, &)
14
14
  event_recorder = Decidim::EventRecorder.new
15
15
 
16
- command = new(*args, **kwargs)
16
+ command = new(*, **)
17
17
  command.subscribe(event_recorder)
18
18
  command.evaluate(&) if block_given?
19
19
  command.call
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Commands
5
+ class CreateResource < ::Decidim::Command
6
+ include Decidim::Commands::ResourceHandler
7
+
8
+ # Initializes the command.
9
+ # @param form [Decidim::Form] the form object to create the resource.
10
+ def initialize(form)
11
+ @form = form
12
+ end
13
+
14
+ # Creates the result if valid.
15
+ #
16
+ # Broadcasts :ok if successful, :invalid otherwise.
17
+ def call
18
+ return broadcast(:invalid) if invalid?
19
+
20
+ perform!
21
+ broadcast(:ok, resource)
22
+ rescue ActiveRecord::RecordInvalid
23
+ add_file_attribute_errors!
24
+ broadcast(:invalid)
25
+ rescue Decidim::Commands::HookError
26
+ broadcast(:invalid)
27
+ end
28
+
29
+ protected
30
+
31
+ # @usage
32
+ # create_resource - Will create the resource, raising any validation errors.
33
+ def create_resource
34
+ @resource = Decidim.traceability.send(create_method, resource_class, current_user, attributes, **extra_params)
35
+ @resource.persisted? ? resource : raise(ActiveRecord::RecordInvalid, resource)
36
+ end
37
+
38
+ attr_reader :form, :resource
39
+
40
+ delegate :current_user, to: :form
41
+
42
+ def create_method
43
+ has_file_attributes? ? :create : :create!
44
+ end
45
+
46
+ # Useful for running any code that you may want to execute before creating the resource.
47
+ def run_before_hooks; end
48
+
49
+ # Useful for running any code that you may want to execute after creating the resource.
50
+ def run_after_hooks; end
51
+
52
+ private
53
+
54
+ def perform!
55
+ transaction do
56
+ run_before_hooks
57
+ create_resource
58
+ run_after_hooks
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Commands
5
+ class DestroyResource < ::Decidim::Command
6
+ # Initializes the command.
7
+ #
8
+ # @param resource [ActiveRecord::Base] the resource to destroy.
9
+ # @param current_user [Decidim::User] the current user.
10
+ def initialize(resource, current_user)
11
+ @resource = resource
12
+ @current_user = current_user
13
+ end
14
+
15
+ # Destroys the result.
16
+ #
17
+ # Broadcasts :ok if successful, :invalid otherwise.
18
+ def call
19
+ return broadcast(:invalid) if invalid?
20
+
21
+ run_before_hooks
22
+ destroy_resource
23
+ run_after_hooks
24
+
25
+ broadcast(:ok, resource)
26
+ rescue Decidim::Commands::HookError, StandardError
27
+ broadcast(:invalid)
28
+ end
29
+
30
+ protected
31
+
32
+ attr_reader :resource, :current_user
33
+
34
+ def invalid? = false
35
+
36
+ def destroy_resource
37
+ Decidim.traceability.perform_action!(
38
+ :delete,
39
+ resource,
40
+ current_user,
41
+ **extra_params
42
+ ) do
43
+ resource.destroy!
44
+ end
45
+ end
46
+
47
+ # Any extra params that you want to pass to the traceability service.
48
+ #
49
+ # @usage
50
+ # def extra_params = { "visibility" => "all"}
51
+ # def extra_params = { "visibility" => "public-only" }
52
+ # def extra_params = { "visibility" => "admin-only" }
53
+ # def extra_params
54
+ # {
55
+ # resource: {
56
+ # title: resource.title
57
+ # },
58
+ # participatory_space: {
59
+ # title: resource.participatory_space.title
60
+ # }
61
+ # }
62
+ # end
63
+ #
64
+ # @return [Hash] a hash with the extra params.
65
+ def extra_params = {}
66
+
67
+ # Useful for running any code that you may want to execute before deleting the resource.
68
+ def run_before_hooks; end
69
+
70
+ # Useful for running any code that you may want to execute after deleting the resource.
71
+ def run_after_hooks; end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Commands
5
+ class HookError < StandardError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Commands
5
+ module ResourceHandler
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ include ::Decidim::AttachmentAttributesMethods
10
+
11
+ protected
12
+
13
+ attr_reader :form
14
+
15
+ def resource_class = raise "#{self.class.name} needs to implement #{__method__}"
16
+
17
+ # Hydrates the attributes from the form object that you need to update/create the resource.
18
+ #
19
+ # @return [Hash] a hash with the attributes.
20
+ def attributes
21
+ @attributes ||= {}.merge(form_attribute_values).merge(file_attribute_values)
22
+ end
23
+
24
+ def form_attribute_values
25
+ raise "You need to define the list of attributes to be fetched from form object fetch_form_attributes" unless defined?(:form_attributes)
26
+
27
+ form_attributes.index_with do |field|
28
+ form.send(field)
29
+ end
30
+ end
31
+
32
+ def file_attribute_values
33
+ return {} unless defined?(:file_attributes)
34
+
35
+ attachment_attributes(*file_attributes)
36
+ end
37
+
38
+ def has_file_attributes?
39
+ file_attributes.any?
40
+ end
41
+
42
+ def add_file_attribute_errors!
43
+ file_attributes.each do |field|
44
+ form.errors.add(field, resource.errors.messages_for(field)&.first) if resource.errors.include? field
45
+ end
46
+ end
47
+
48
+ # Any extra params that you want to pass to the traceability service.
49
+ #
50
+ # @usage
51
+ # def extra_params = { "visibility" => "all"}
52
+ # def extra_params = { "visibility" => "public-only" }
53
+ # def extra_params = { "visibility" => "admin-only" }
54
+ # def extra_params
55
+ # {
56
+ # resource: {
57
+ # title: resource.title
58
+ # },
59
+ # participatory_space: {
60
+ # title: resource.participatory_space.title
61
+ # }
62
+ # }
63
+ # end
64
+ # @return [Hash] a hash with the extra params.
65
+ def extra_params = {}
66
+
67
+ delegate :invalid?, to: :form
68
+
69
+ class_attribute :form_attributes
70
+ self.form_attributes = []
71
+
72
+ class_attribute :file_attributes
73
+ self.file_attributes = []
74
+
75
+ def self.fetch_form_attributes(*fields)
76
+ self.form_attributes += Array(fields)
77
+ end
78
+
79
+ def self.fetch_file_attributes(*fields)
80
+ self.file_attributes += Array(fields)
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end