decidim-core 0.29.4 → 0.30.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 (562) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/address/show.erb +3 -3
  3. data/app/cells/decidim/amendable/amend_button_card/show.erb +6 -4
  4. data/app/cells/decidim/amendable/amend_button_card_cell.rb +8 -0
  5. data/app/cells/decidim/amendable/amendments/show.erb +1 -1
  6. data/app/cells/decidim/amendable/promote_button_card/show.erb +2 -0
  7. data/app/cells/decidim/author/flag.erb +6 -0
  8. data/app/cells/decidim/author/flag_user.erb +14 -0
  9. data/app/cells/decidim/author/show.erb +4 -2
  10. data/app/cells/decidim/author_cell.rb +1 -1
  11. data/app/cells/decidim/card_l/extra_data.erb +1 -0
  12. data/app/cells/decidim/card_metadata_cell.rb +9 -16
  13. data/app/cells/decidim/comments_button_cell.rb +14 -2
  14. data/app/cells/decidim/content_blocks/highlighted_elements_cell.rb +2 -0
  15. data/app/cells/decidim/content_blocks/highlighted_elements_with_cell_for_list_cell.rb +1 -1
  16. data/app/cells/decidim/content_blocks/participatory_space_extra_data/extra_data.erb +2 -2
  17. data/app/cells/decidim/endorsement_block/show.erb +0 -1
  18. data/app/cells/decidim/endorsement_block_cell.rb +6 -0
  19. data/app/cells/decidim/endorsement_buttons/button_content.erb +1 -1
  20. data/app/cells/decidim/endorsement_buttons/select_identity_button.erb +1 -1
  21. data/app/cells/decidim/endorsement_buttons/show.erb +7 -7
  22. data/app/cells/decidim/endorsement_buttons/verification_modal.erb +4 -2
  23. data/app/cells/decidim/endorsers_list/empty.erb +3 -0
  24. data/app/cells/decidim/endorsers_list/full.erb +17 -5
  25. data/app/cells/decidim/endorsers_list/show.erb +19 -10
  26. data/app/cells/decidim/endorsers_list_cell.rb +19 -6
  27. data/app/cells/decidim/flag_modal/flag_user.erb +34 -0
  28. data/app/cells/decidim/flag_modal/show.erb +52 -0
  29. data/app/cells/decidim/flag_modal_cell.rb +56 -0
  30. data/app/cells/decidim/follow_button/show.erb +1 -2
  31. data/app/cells/decidim/follow_button_cell.rb +5 -0
  32. data/app/cells/decidim/map/show.erb +3 -0
  33. data/app/cells/decidim/map/template.erb +14 -0
  34. data/app/cells/decidim/map_cell.rb +39 -0
  35. data/app/cells/decidim/notification_actions/buttons_cell.rb +1 -1
  36. data/app/cells/decidim/onboarding_action_message/show.erb +15 -0
  37. data/app/cells/decidim/onboarding_action_message_cell.rb +81 -0
  38. data/app/cells/decidim/participatory_space_dropdown_metadata/metadata.erb +4 -4
  39. data/app/cells/decidim/participatory_space_dropdown_metadata/show.erb +3 -5
  40. data/app/cells/decidim/participatory_space_private_user/show.erb +23 -0
  41. data/app/cells/decidim/participatory_space_private_user_cell.rb +21 -0
  42. data/app/cells/decidim/profile_actions/show.erb +1 -1
  43. data/app/cells/decidim/profile_sidebar/show.erb +167 -0
  44. data/app/cells/decidim/profile_sidebar_cell.rb +68 -0
  45. data/app/cells/decidim/progress_bar/show.erb +2 -2
  46. data/app/cells/decidim/report_button/already_reported_modal.erb +2 -2
  47. data/app/cells/decidim/report_button/flag_modal.erb +27 -13
  48. data/app/cells/decidim/report_button_cell.rb +9 -2
  49. data/app/cells/decidim/resource_history/show.erb +20 -0
  50. data/app/cells/decidim/resource_history_cell.rb +66 -0
  51. data/app/cells/decidim/resource_types_filter/show.erb +1 -1
  52. data/app/cells/decidim/resource_types_filter_cell.rb +6 -6
  53. data/app/cells/decidim/share_button_cell.rb +0 -4
  54. data/app/cells/decidim/share_widget/modal.erb +26 -0
  55. data/app/cells/decidim/share_widget/show.erb +2 -0
  56. data/app/cells/decidim/share_widget_cell.rb +20 -0
  57. data/app/cells/decidim/tags/show.erb +7 -4
  58. data/app/cells/decidim/tags_cell.rb +11 -72
  59. data/app/cells/decidim/user_activity/show.erb +1 -1
  60. data/app/commands/decidim/amendable/create_draft.rb +2 -2
  61. data/app/commands/decidim/create_ephemeral_user.rb +52 -0
  62. data/app/commands/decidim/create_omniauth_registration.rb +21 -17
  63. data/app/commands/decidim/create_report.rb +8 -11
  64. data/app/commands/decidim/create_user_group.rb +6 -2
  65. data/app/commands/decidim/destroy_ephemeral_user.rb +47 -0
  66. data/app/commands/decidim/invite_user.rb +1 -1
  67. data/app/commands/decidim/search.rb +0 -14
  68. data/app/commands/decidim/update_account.rb +11 -3
  69. data/app/commands/decidim/update_notifications_settings.rb +1 -0
  70. data/app/commands/decidim/update_resources_taxonomies.rb +67 -0
  71. data/app/commands/decidim/update_user_group.rb +7 -1
  72. data/app/constraints/decidim/current_component.rb +1 -1
  73. data/app/controllers/concerns/decidim/ajax_permission_handler.rb +21 -0
  74. data/app/controllers/concerns/decidim/devise_authentication_methods.rb +3 -6
  75. data/app/controllers/concerns/decidim/devise_controllers.rb +2 -0
  76. data/app/controllers/concerns/decidim/disable_redirection_to_external_host.rb +1 -1
  77. data/app/controllers/concerns/decidim/ephemeral_session_checker.rb +87 -0
  78. data/app/controllers/concerns/decidim/filter_resource.rb +4 -2
  79. data/app/controllers/concerns/decidim/has_members_page.rb +25 -0
  80. data/app/controllers/concerns/decidim/headers/browser_feature_permissions.rb +50 -0
  81. data/app/controllers/concerns/decidim/locale_switcher.rb +2 -2
  82. data/app/controllers/concerns/decidim/needs_password_change.rb +0 -1
  83. data/app/controllers/concerns/decidim/needs_permission.rb +2 -1
  84. data/app/controllers/concerns/decidim/needs_tos_accepted.rb +4 -5
  85. data/app/controllers/concerns/decidim/onboarding_action_methods.rb +52 -0
  86. data/app/controllers/concerns/decidim/participatory_space_context.rb +1 -4
  87. data/app/controllers/decidim/application_controller.rb +10 -0
  88. data/app/controllers/decidim/authorization_modals_controller.rb +8 -2
  89. data/app/controllers/decidim/components/base_controller.rb +3 -7
  90. data/app/controllers/decidim/devise/confirmations_controller.rb +4 -0
  91. data/app/controllers/decidim/devise/omniauth_registrations_controller.rb +8 -1
  92. data/app/controllers/decidim/devise/registrations_controller.rb +1 -1
  93. data/app/controllers/decidim/devise/sessions_controller.rb +2 -0
  94. data/app/controllers/decidim/download_your_data_controller.rb +33 -2
  95. data/app/controllers/decidim/editor_images_controller.rb +1 -11
  96. data/app/controllers/decidim/follows_controller.rb +1 -1
  97. data/app/controllers/decidim/geolocation_controller.rb +19 -0
  98. data/app/controllers/decidim/homepage_controller.rb +0 -1
  99. data/app/controllers/decidim/open_data_controller.rb +33 -8
  100. data/app/controllers/decidim/profiles_controller.rb +2 -2
  101. data/app/controllers/decidim/reports_controller.rb +2 -7
  102. data/app/controllers/decidim/user_activities_controller.rb +1 -1
  103. data/app/controllers/decidim/user_conversations_controller.rb +1 -11
  104. data/app/events/decidim/soft_delete_resource_event.rb +15 -0
  105. data/app/forms/decidim/account_form.rb +2 -5
  106. data/app/forms/decidim/amendable/form.rb +4 -2
  107. data/app/forms/decidim/ephemeral_user_form.rb +22 -0
  108. data/app/forms/decidim/notifications_settings_form.rb +1 -0
  109. data/app/forms/decidim/omniauth_registration_form.rb +15 -2
  110. data/app/forms/decidim/registration_form.rb +1 -1
  111. data/app/helpers/concerns/decidim/flash_helper_extensions.rb +17 -2
  112. data/app/helpers/decidim/action_authorization_helper.rb +75 -14
  113. data/app/helpers/decidim/amendments_helper.rb +0 -9
  114. data/app/helpers/decidim/application_helper.rb +6 -2
  115. data/app/helpers/decidim/breadcrumb_helper.rb +6 -0
  116. data/app/helpers/decidim/cache_helper.rb +1 -1
  117. data/app/helpers/decidim/check_boxes_tree_helper.rb +25 -53
  118. data/app/helpers/decidim/decidim_form_helper.rb +0 -44
  119. data/app/helpers/decidim/endorsable_helper.rb +0 -10
  120. data/app/helpers/decidim/layout_helper.rb +6 -0
  121. data/app/helpers/decidim/menu_helper.rb +2 -2
  122. data/app/helpers/decidim/messaging/conversation_helper.rb +2 -3
  123. data/app/helpers/decidim/meta_tags_helper.rb +32 -23
  124. data/app/helpers/decidim/modal_helper.rb +23 -0
  125. data/app/helpers/decidim/omniauth_helper.rb +5 -5
  126. data/app/helpers/decidim/onboarding_action_helper.rb +13 -0
  127. data/app/helpers/decidim/orders_helper.rb +1 -2
  128. data/app/helpers/decidim/paginate_helper.rb +1 -1
  129. data/app/helpers/decidim/participatory_space_helpers.rb +1 -1
  130. data/app/helpers/decidim/passwords_helper.rb +2 -2
  131. data/app/helpers/decidim/taxonomies_helper.rb +40 -0
  132. data/app/helpers/decidim/tooltip_helper.rb +1 -4
  133. data/app/jobs/decidim/download_your_data_export_job.rb +2 -19
  134. data/app/jobs/decidim/event_publisher_job.rb +18 -9
  135. data/app/jobs/decidim/export_job.rb +5 -1
  136. data/app/jobs/decidim/export_participatory_space_job.rb +4 -1
  137. data/app/jobs/decidim/open_data_job.rb +4 -4
  138. data/app/mailers/decidim/export_mailer.rb +7 -12
  139. data/app/mailers/decidim/notifications_digest_mailer.rb +1 -7
  140. data/app/mailers/decidim/reported_mailer.rb +2 -18
  141. data/app/models/decidim/action_log.rb +20 -1
  142. data/app/models/decidim/category.rb +4 -0
  143. data/app/models/decidim/component.rb +25 -3
  144. data/app/models/decidim/metric.rb +2 -1
  145. data/app/models/decidim/moderation.rb +16 -0
  146. data/app/models/decidim/newsletter.rb +12 -8
  147. data/app/models/decidim/organization.rb +7 -3
  148. data/app/models/decidim/participatory_space_private_user.rb +20 -0
  149. data/app/models/decidim/private_export.rb +24 -0
  150. data/app/models/decidim/push_notification_message.rb +1 -1
  151. data/app/models/decidim/report.rb +1 -1
  152. data/app/models/decidim/scope.rb +4 -0
  153. data/app/models/decidim/share_token.rb +36 -10
  154. data/app/models/decidim/taxonomization.rb +23 -0
  155. data/app/models/decidim/taxonomy.rb +139 -0
  156. data/app/models/decidim/taxonomy_filter.rb +130 -0
  157. data/app/models/decidim/taxonomy_filter_item.rb +33 -0
  158. data/app/models/decidim/user.rb +13 -23
  159. data/app/models/decidim/user_base_entity.rb +12 -4
  160. data/app/models/decidim/user_moderation.rb +9 -0
  161. data/app/models/decidim/user_report.rb +4 -0
  162. data/app/packs/entrypoints/decidim_core.js +1 -0
  163. data/app/packs/entrypoints/decidim_geocoding.js +2 -0
  164. data/app/packs/images/decidim/brands/facebook.svg +10 -0
  165. data/app/packs/images/decidim/brands/google.svg +7 -1
  166. data/app/packs/images/decidim/brands/twitter-x.svg +3 -0
  167. data/app/packs/src/decidim/check_boxes_tree.js +0 -1
  168. data/app/packs/src/decidim/clipboard.js +18 -9
  169. data/app/packs/src/decidim/confirm.js +79 -59
  170. data/app/packs/src/decidim/datepicker/datepicker_functions.js +3 -3
  171. data/app/packs/src/decidim/decidim_application.js +1 -0
  172. data/app/packs/src/decidim/form_remote.js +1 -1
  173. data/app/packs/src/decidim/geocoding/reverse_geocoding.js +60 -0
  174. data/app/packs/src/decidim/impersonation.js +1 -1
  175. data/app/packs/src/decidim/index.js +13 -5
  176. data/app/packs/src/decidim/input_character_counter.js +1 -1
  177. data/app/packs/src/decidim/map/provider/here.js +1 -1
  178. data/app/packs/src/decidim/onboarding_pending_action.js +24 -0
  179. data/app/packs/src/decidim/session_timeouter.js +1 -1
  180. data/app/packs/src/decidim/sticky_footer.js +29 -0
  181. data/app/packs/src/decidim/sticky_header.js +6 -31
  182. data/app/packs/src/decidim/user_registrations.js +13 -0
  183. data/app/packs/src/decidim/utilities/dom.js +148 -0
  184. data/app/packs/src/decidim/vendor/leaflet-tilelayer-here.js +212 -0
  185. data/app/packs/stylesheets/decidim/_accordion.scss +30 -0
  186. data/app/packs/stylesheets/decidim/_buttons.scss +19 -0
  187. data/app/packs/stylesheets/decidim/_cards.scss +1 -1
  188. data/app/packs/stylesheets/decidim/_content_blocks.scss +0 -4
  189. data/app/packs/stylesheets/decidim/_dropdown.scss +1 -1
  190. data/app/packs/stylesheets/decidim/_endorsers_list.scss +26 -20
  191. data/app/packs/stylesheets/decidim/_forms.scss +2 -2
  192. data/app/packs/stylesheets/decidim/_header.scss +37 -60
  193. data/app/packs/stylesheets/decidim/_layout.scss +32 -2
  194. data/app/packs/stylesheets/decidim/_login.scss +53 -6
  195. data/app/packs/stylesheets/decidim/_modal.scss +42 -0
  196. data/app/packs/stylesheets/decidim/_modal_tos_refuse.scss +4 -0
  197. data/app/packs/stylesheets/decidim/_participatory_spaces.scss +46 -0
  198. data/app/packs/stylesheets/decidim/_profile.scss +1 -1
  199. data/app/packs/stylesheets/decidim/_success_image.scss +64 -0
  200. data/app/packs/stylesheets/decidim/_tribute.scss +36 -0
  201. data/app/packs/stylesheets/decidim/application.scss +1 -1
  202. data/app/packs/stylesheets/decidim/geocoding_addons.scss +5 -0
  203. data/app/packs/stylesheets/decidim/map.scss +7 -10
  204. data/app/packs/stylesheets/decidim/resource_history.scss +31 -0
  205. data/app/permissions/decidim/default_permissions.rb +0 -2
  206. data/app/permissions/decidim/permissions.rb +8 -2
  207. data/app/presenters/decidim/admin_log/base_user_presenter.rb +67 -0
  208. data/app/presenters/decidim/admin_log/component_presenter.rb +32 -3
  209. data/app/presenters/decidim/admin_log/moderation_presenter.rb +30 -3
  210. data/app/presenters/decidim/admin_log/share_token_presenter.rb +39 -0
  211. data/app/presenters/decidim/admin_log/taxonomy_filter_presenter.rb +57 -0
  212. data/app/presenters/decidim/admin_log/taxonomy_presenter.rb +48 -0
  213. data/app/presenters/decidim/admin_log/user_group_presenter.rb +6 -6
  214. data/app/presenters/decidim/admin_log/user_presenter.rb +4 -18
  215. data/app/presenters/decidim/log/user_presenter.rb +0 -1
  216. data/app/presenters/decidim/log/value_types/date_presenter.rb +1 -0
  217. data/app/presenters/decidim/log/value_types/taxonomy_presenter.rb +29 -0
  218. data/app/presenters/decidim/notification_to_mailer_presenter.rb +3 -7
  219. data/app/presenters/decidim/participatory_space_private_user_presenter.rb +50 -0
  220. data/app/presenters/decidim/taxonomy_filter_presenter.rb +19 -0
  221. data/app/presenters/decidim/taxonomy_presenter.rb +14 -0
  222. data/app/presenters/decidim/user_presenter.rb +1 -1
  223. data/app/queries/decidim/last_activity.rb +0 -25
  224. data/app/queries/decidim/metrics/blocked_users_metric_manage.rb +2 -2
  225. data/app/queries/decidim/metrics/users_metric_manage.rb +2 -2
  226. data/app/queries/decidim/public_activities.rb +1 -12
  227. data/app/queries/decidim/stats_users_count.rb +2 -2
  228. data/app/resolvers/decidim/meta_image_url_resolver.rb +128 -0
  229. data/app/serializers/decidim/exporters/open_data_blocked_user_serializer.rb +25 -0
  230. data/app/serializers/decidim/exporters/open_data_metric_serializer.rb +22 -0
  231. data/app/serializers/decidim/exporters/open_data_moderation_serializer.rb +30 -0
  232. data/app/serializers/decidim/exporters/open_data_taxonomy_serializer.rb +30 -0
  233. data/app/serializers/decidim/exporters/open_data_user_group_serializer.rb +38 -0
  234. data/app/serializers/decidim/exporters/open_data_user_serializer.rb +39 -0
  235. data/app/serializers/decidim/exporters/participatory_space_serializer.rb +104 -0
  236. data/app/serializers/decidim/exporters/serializer.rb +25 -0
  237. data/app/serializers/decidim/schema_org_breadcrumb_list_serializer.rb +52 -0
  238. data/app/services/decidim/action_authorizer.rb +32 -3
  239. data/app/services/decidim/base_diff_renderer.rb +1 -3
  240. data/app/services/decidim/download_your_data_exporter.rb +58 -24
  241. data/app/services/decidim/onboarding_manager.rb +272 -0
  242. data/app/services/decidim/open_data_exporter.rb +139 -13
  243. data/app/services/decidim/static_map_generator.rb +1 -1
  244. data/app/services/decidim/traceability.rb +13 -0
  245. data/app/uploaders/decidim/application_uploader.rb +1 -1
  246. data/app/validators/etiquette_validator.rb +9 -2
  247. data/app/validators/passthru_validator.rb +1 -1
  248. data/app/validators/translated_etiquette_validator.rb +32 -0
  249. data/app/views/decidim/account/_password_fields.html.erb +2 -2
  250. data/app/views/decidim/application/_accordion_section.html.erb +14 -0
  251. data/app/views/decidim/application/_collection.html.erb +30 -18
  252. data/app/views/decidim/devise/omniauth_registrations/new.html.erb +5 -1
  253. data/app/views/decidim/devise/omniauth_registrations/new_tos_fields.html.erb +29 -0
  254. data/app/views/decidim/devise/registrations/new.html.erb +10 -22
  255. data/app/views/decidim/devise/sessions/new.html.erb +24 -29
  256. data/app/views/decidim/devise/shared/_omniauth_buttons.html.erb +2 -4
  257. data/app/views/decidim/devise/shared/_tos_fields.html.erb +16 -0
  258. data/app/views/decidim/download_your_data/_export.html.erb +15 -0
  259. data/app/views/decidim/download_your_data/show.html.erb +51 -5
  260. data/app/views/decidim/endorsements/update_buttons_and_counters.js.erb +16 -19
  261. data/app/views/decidim/export_mailer/download_your_data_export.html.erb +2 -2
  262. data/app/views/decidim/export_mailer/export.html.erb +5 -1
  263. data/app/views/decidim/last_activities/index.html.erb +1 -1
  264. data/app/views/decidim/messaging/conversations/_reply_form.html.erb +2 -1
  265. data/app/views/decidim/messaging/conversations/_start.html.erb +1 -1
  266. data/app/views/decidim/notifications_settings/show.html.erb +22 -0
  267. data/app/views/decidim/open_data/_how_to_open_accordion_section.html.erb +15 -0
  268. data/app/views/decidim/open_data/index.html.erb +108 -0
  269. data/app/views/decidim/pages/show.html.erb +2 -1
  270. data/app/views/decidim/participatory_space_private_users/_participatory_space_private_user.html.erb +1 -0
  271. data/app/views/decidim/reported_mailer/hide.html.erb +9 -0
  272. data/app/views/decidim/reported_mailer/report.html.erb +1 -1
  273. data/app/views/decidim/searches/_count.html.erb +1 -1
  274. data/app/views/decidim/searches/_filters.html.erb +38 -40
  275. data/app/views/decidim/shared/_login_modal.html.erb +26 -20
  276. data/app/views/decidim/shared/_orders.html.erb +2 -2
  277. data/app/views/decidim/shared/_resource_actions.html.erb +21 -0
  278. data/app/views/decidim/shared/_results_per_page.html.erb +1 -1
  279. data/app/views/decidim/shared/filters/_check_boxes_tree.html.erb +1 -2
  280. data/app/views/decidim/shared/filters/_collection.html.erb +1 -1
  281. data/app/views/decidim/shared/filters/_dropdown_label.html.erb +7 -4
  282. data/app/views/kaminari/decidim/_page.html.erb +1 -1
  283. data/app/views/kaminari/decidim/_paginator.html.erb +1 -1
  284. data/app/views/layouts/decidim/_application.html.erb +0 -1
  285. data/app/views/layouts/decidim/_js_configuration.html.erb +1 -0
  286. data/app/views/layouts/decidim/_logo.html.erb +2 -2
  287. data/app/views/layouts/decidim/_logo_mobile.html.erb +1 -1
  288. data/app/views/layouts/decidim/_meta_tags_config.html.erb +6 -11
  289. data/app/views/layouts/decidim/_schema_org_breadcrumb_list.html.erb +3 -0
  290. data/app/views/layouts/decidim/_wrapper.html.erb +15 -9
  291. data/app/views/layouts/decidim/footer/_main_legal.html.erb +1 -1
  292. data/app/views/layouts/decidim/footer/_main_links.html.erb +1 -1
  293. data/app/views/layouts/decidim/header/_close_ephemeral_session.html.erb +25 -0
  294. data/app/views/layouts/decidim/header/_main.html.erb +14 -10
  295. data/app/views/layouts/decidim/header/_menu_breadcrumb_items.html.erb +2 -0
  296. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_desktop.html.erb +11 -5
  297. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile_tablet.html.erb +5 -5
  298. data/app/views/layouts/decidim/shared/_layout_item.html.erb +1 -1
  299. data/config/assets.rb +2 -1
  300. data/config/locales/ar.yml +35 -74
  301. data/config/locales/bg.yml +33 -74
  302. data/config/locales/bs-BA.yml +0 -2
  303. data/config/locales/ca.yml +370 -102
  304. data/config/locales/cs.yml +374 -102
  305. data/config/locales/de.yml +350 -88
  306. data/config/locales/el.yml +22 -58
  307. data/config/locales/en.yml +350 -82
  308. data/config/locales/eo.yml +0 -4
  309. data/config/locales/es-MX.yml +364 -99
  310. data/config/locales/es-PY.yml +369 -104
  311. data/config/locales/es.yml +370 -102
  312. data/config/locales/eu.yml +426 -156
  313. data/config/locales/fi-plain.yml +366 -76
  314. data/config/locales/fi.yml +370 -77
  315. data/config/locales/fr-CA.yml +176 -97
  316. data/config/locales/fr.yml +176 -94
  317. data/config/locales/ga-IE.yml +4 -25
  318. data/config/locales/gl.yml +20 -58
  319. data/config/locales/hu.yml +30 -62
  320. data/config/locales/id-ID.yml +21 -57
  321. data/config/locales/is-IS.yml +5 -25
  322. data/config/locales/it.yml +36 -94
  323. data/config/locales/ja.yml +231 -112
  324. data/config/locales/lb.yml +28 -76
  325. data/config/locales/lt.yml +24 -64
  326. data/config/locales/lv.yml +21 -58
  327. data/config/locales/nl.yml +23 -75
  328. data/config/locales/no.yml +23 -70
  329. data/config/locales/pl.yml +30 -72
  330. data/config/locales/pt-BR.yml +41 -63
  331. data/config/locales/pt.yml +23 -70
  332. data/config/locales/ro-RO.yml +115 -184
  333. data/config/locales/ru.yml +13 -43
  334. data/config/locales/sk.yml +24 -70
  335. data/config/locales/sl.yml +0 -4
  336. data/config/locales/sr-CS.yml +0 -2
  337. data/config/locales/sv.yml +138 -106
  338. data/config/locales/tr-TR.yml +29 -75
  339. data/config/locales/uk.yml +6 -29
  340. data/config/locales/zh-CN.yml +21 -68
  341. data/config/locales/zh-TW.yml +23 -62
  342. data/config/routes.rb +4 -10
  343. data/db/migrate/20171212103803_create_unique_nicknames.rb +1 -1
  344. data/db/migrate/20180221101934_fix_nickname_index.rb +1 -1
  345. data/db/migrate/20180706104107_add_nickname_to_managed_users.rb +1 -1
  346. data/db/migrate/20181001124950_move_users_groups_to_users_table.rb +1 -1
  347. data/db/migrate/20181025082245_add_timestamps_to_components.rb +2 -0
  348. data/db/migrate/20190412131728_fix_user_names.rb +1 -1
  349. data/db/migrate/20240628111905_add_visible_to_components.rb +7 -0
  350. data/db/migrate/20240704115429_create_decidim_taxonomies.rb +23 -0
  351. data/db/migrate/20240717093514_add_registered_only_to_decidim_share_tokens.rb +7 -0
  352. data/db/migrate/20240722215500_change_object_changes_on_versions.rb +39 -0
  353. data/db/migrate/20240806065417_create_decidim_taxonomy_filters.rb +23 -0
  354. data/db/migrate/20240822161348_add_deleted_at_to_decidim_components.rb +8 -0
  355. data/db/migrate/20240906162524_add_part_of_to_taxonomies.rb +26 -0
  356. data/db/migrate/20241001135825_add_role_to_participatory_space_private_users.rb +7 -0
  357. data/db/migrate/20241001140408_add_published_to_participatory_space_private_users.rb +7 -0
  358. data/db/migrate/20241022002600_create_private_exports.rb +18 -0
  359. data/db/migrate/20241028114430_add_component_counter_to_taxonomy_filters.rb +7 -0
  360. data/db/migrate/20241111104357_add_names_and_space_boolean_to_taxonomy_filters.rb +9 -0
  361. data/db/migrate/20241127093708_add_taxonomy_to_metrics.rb +7 -0
  362. data/db/migrate/20241204121445_add_participatory_space_manifests_from_taxonomy_filters.rb +9 -0
  363. data/decidim-core.gemspec +14 -17
  364. data/lib/decidim/action_authorization.rb +3 -2
  365. data/lib/decidim/amendable.rb +1 -1
  366. data/lib/decidim/api/input_filters/category_input_filter.rb +5 -3
  367. data/lib/decidim/api/input_filters/component_input_filter.rb +33 -20
  368. data/lib/decidim/api/input_filters/user_entity_input_filter.rb +53 -44
  369. data/lib/decidim/api/input_sorts/component_input_sort.rb +15 -13
  370. data/lib/decidim/api/input_sorts/user_entity_input_sort.rb +4 -4
  371. data/lib/decidim/api/interfaces/author_interface.rb +3 -2
  372. data/lib/decidim/api/interfaces/coauthorable_interface.rb +5 -5
  373. data/lib/decidim/api/interfaces/endorsable_interface.rb +2 -2
  374. data/lib/decidim/api/interfaces/participatory_space_interface.rb +5 -10
  375. data/lib/decidim/api/interfaces/taxonomizable_interface.rb +13 -0
  376. data/lib/decidim/api/types/amendment_type.rb +5 -7
  377. data/lib/decidim/api/types/area_api_type.rb +3 -3
  378. data/lib/decidim/api/types/attachment_type.rb +3 -3
  379. data/lib/decidim/api/types/category_type.rb +2 -2
  380. data/lib/decidim/api/types/decidim_type.rb +5 -1
  381. data/lib/decidim/api/types/fingerprint_type.rb +1 -1
  382. data/lib/decidim/api/types/localized_string_type.rb +1 -1
  383. data/lib/decidim/api/types/metric_history_type.rb +2 -0
  384. data/lib/decidim/api/types/metric_type.rb +1 -1
  385. data/lib/decidim/api/types/organization_type.rb +5 -0
  386. data/lib/decidim/api/types/participatory_space_link_type.rb +2 -2
  387. data/lib/decidim/api/types/participatory_space_manifest_type.rb +1 -1
  388. data/lib/decidim/api/types/quantifiable_translated_field_type.rb +1 -1
  389. data/lib/decidim/api/types/scope_api_type.rb +2 -3
  390. data/lib/decidim/api/types/session_type.rb +1 -2
  391. data/lib/decidim/api/types/taxonomy_type.rb +15 -0
  392. data/lib/decidim/api/types/trace_version_type.rb +2 -2
  393. data/lib/decidim/api/types/translated_field_type.rb +3 -5
  394. data/lib/decidim/api/types/user_group_type.rb +7 -20
  395. data/lib/decidim/api/types/user_type.rb +7 -20
  396. data/lib/decidim/asset_router/storage.rb +6 -11
  397. data/lib/decidim/assets/tailwind/tailwind.config.js.erb +2 -1
  398. data/lib/decidim/attachment_attributes.rb +1 -1
  399. data/lib/decidim/attribute_encryptor.rb +1 -1
  400. data/lib/decidim/attribute_object/nested_validator.rb +1 -1
  401. data/lib/decidim/attributes/integer_with_units.rb +27 -0
  402. data/lib/decidim/attributes/time_with_zone.rb +1 -5
  403. data/lib/decidim/attributes.rb +2 -0
  404. data/lib/decidim/authorization_form_builder.rb +0 -7
  405. data/lib/decidim/coauthorable.rb +1 -1
  406. data/lib/decidim/command.rb +3 -3
  407. data/lib/decidim/commands/destroy_resource.rb +5 -1
  408. data/lib/decidim/commands/resource_handler.rb +2 -2
  409. data/lib/decidim/commands/restore_resource.rb +45 -0
  410. data/lib/decidim/commands/soft_delete_resource.rb +63 -0
  411. data/lib/decidim/component_manifest.rb +7 -0
  412. data/lib/decidim/content_parsers/blob_parser.rb +8 -10
  413. data/lib/decidim/content_parsers/user_parser.rb +1 -1
  414. data/lib/decidim/core/api.rb +2 -0
  415. data/lib/decidim/core/engine.rb +21 -7
  416. data/lib/decidim/core/menu.rb +0 -5
  417. data/lib/decidim/core/seeds.rb +42 -2
  418. data/lib/decidim/core/test/factories.rb +105 -2
  419. data/lib/decidim/core/test/shared_examples/admin_resource_gallery_examples.rb +85 -0
  420. data/lib/decidim/core/test/shared_examples/comments_examples.rb +393 -38
  421. data/lib/decidim/core/test/shared_examples/components_controller_hide_shared_examples.rb +11 -0
  422. data/lib/decidim/core/test/shared_examples/components_controller_reorder_shared_examples.rb +21 -0
  423. data/lib/decidim/core/test/shared_examples/download_open_data_shared_context.rb +36 -0
  424. data/lib/decidim/core/test/shared_examples/download_open_data_shared_examples.rb +45 -0
  425. data/lib/decidim/core/test/shared_examples/download_your_data_shared_examples.rb +17 -0
  426. data/lib/decidim/core/test/shared_examples/etiquette_validator_examples.rb +25 -0
  427. data/lib/decidim/core/test/shared_examples/follows_examples.rb +43 -0
  428. data/lib/decidim/core/test/shared_examples/has_taxonomies.rb +94 -0
  429. data/lib/decidim/core/test/shared_examples/manage_share_tokens_examples.rb +237 -0
  430. data/lib/decidim/core/test/shared_examples/map_examples.rb +2 -0
  431. data/lib/decidim/core/test/shared_examples/open_data_exporter_examples.rb +102 -0
  432. data/lib/decidim/core/test/shared_examples/participatory_space_members_page_examples.rb +46 -0
  433. data/lib/decidim/core/test/shared_examples/participatory_space_search_examples.rb +98 -0
  434. data/lib/decidim/core/test/shared_examples/permissions.rb +7 -7
  435. data/lib/decidim/core/test/shared_examples/preview_with_share_token_examples.rb +94 -0
  436. data/lib/decidim/core/test/shared_examples/reports_examples.rb +15 -53
  437. data/lib/decidim/core/test/shared_examples/resource_endorsed_event_examples.rb +2 -2
  438. data/lib/decidim/core/test/shared_examples/resource_search_examples.rb +75 -69
  439. data/lib/decidim/core/test/shared_examples/searchable_resources_shared_context.rb +1 -1
  440. data/lib/decidim/core/test/shared_examples/simple_event.rb +33 -19
  441. data/lib/decidim/core/test/shared_examples/social_share_examples.rb +7 -14
  442. data/lib/decidim/core/test/shared_examples/softdeleteable_components_examples.rb +173 -0
  443. data/lib/decidim/core/test/shared_examples/system_endorse_resource_examples.rb +54 -8
  444. data/lib/decidim/core/test/shared_examples/taxonomizable_interface_examples.rb +20 -0
  445. data/lib/decidim/core/test/shared_examples/taxonomizable_resource_examples.rb +37 -0
  446. data/lib/decidim/core/test/shared_examples/taxonomy_settings.rb +49 -0
  447. data/lib/decidim/core/test/shared_examples/translated_event_examples.rb +1 -1
  448. data/lib/decidim/core/test/shared_examples/uncommentable_component_examples.rb +0 -26
  449. data/lib/decidim/core/test/shared_examples/versions_controller_examples.rb +2 -28
  450. data/lib/decidim/core/test/shared_examples/with_endorsable_permissions_examples.rb +1 -1
  451. data/lib/decidim/core/test.rb +9 -5
  452. data/lib/decidim/core/version.rb +1 -1
  453. data/lib/decidim/core.rb +58 -0
  454. data/lib/decidim/download_your_data_serializers/download_your_data_identity_serializer.rb +0 -4
  455. data/lib/decidim/download_your_data_serializers/download_your_data_participatory_space_private_user_serializer.rb +3 -1
  456. data/lib/decidim/download_your_data_serializers/download_your_data_report_serializer.rb +2 -1
  457. data/lib/decidim/download_your_data_serializers/download_your_data_user_serializer.rb +6 -7
  458. data/lib/decidim/download_your_data_serializers.rb +19 -0
  459. data/lib/decidim/exporters/csv.rb +6 -0
  460. data/lib/decidim/exporters/export_manifest.rb +14 -0
  461. data/lib/decidim/exporters/pdf.rb +26 -22
  462. data/lib/decidim/filter_form_builder.rb +12 -15
  463. data/lib/decidim/form_builder.rb +6 -129
  464. data/lib/decidim/has_category.rb +5 -1
  465. data/lib/decidim/has_private_users.rb +4 -0
  466. data/lib/decidim/has_taxonomy_settings.rb +47 -0
  467. data/lib/decidim/has_upload_validations.rb +1 -1
  468. data/lib/decidim/legacy_form_builder.rb +118 -0
  469. data/lib/decidim/maintenance/import_models/application_record.rb +93 -0
  470. data/lib/decidim/maintenance/import_models/area.rb +82 -0
  471. data/lib/decidim/maintenance/import_models/area_type.rb +12 -0
  472. data/lib/decidim/maintenance/import_models/assembly_type.rb +49 -0
  473. data/lib/decidim/maintenance/import_models/categorization.rb +14 -0
  474. data/lib/decidim/maintenance/import_models/category.rb +107 -0
  475. data/lib/decidim/maintenance/import_models/participatory_process_type.rb +21 -0
  476. data/lib/decidim/maintenance/import_models/scope.rb +163 -0
  477. data/lib/decidim/maintenance/import_models.rb +19 -0
  478. data/lib/decidim/maintenance/taxonomy_importer.rb +132 -0
  479. data/lib/decidim/maintenance/taxonomy_plan.rb +78 -0
  480. data/lib/decidim/maintenance.rb +12 -0
  481. data/lib/decidim/map/autocomplete.rb +52 -8
  482. data/lib/decidim/map/dynamic_map.rb +1 -1
  483. data/lib/decidim/map/provider/dynamic_map/here.rb +40 -1
  484. data/lib/decidim/map/provider/geocoding/here.rb +9 -3
  485. data/lib/decidim/map/provider/static_map/here.rb +0 -34
  486. data/lib/decidim/map.rb +3 -6
  487. data/lib/decidim/moderation_tools.rb +16 -19
  488. data/lib/decidim/newsletter_encryptor.rb +1 -1
  489. data/lib/decidim/nicknamizable.rb +9 -6
  490. data/lib/decidim/paddable.rb +1 -1
  491. data/lib/decidim/participable.rb +10 -10
  492. data/lib/decidim/participatory_space_user.rb +10 -0
  493. data/lib/decidim/private_download_helper.rb +15 -0
  494. data/lib/decidim/record_encryptor.rb +51 -46
  495. data/lib/decidim/reportable.rb +2 -6
  496. data/lib/decidim/resourceable.rb +16 -0
  497. data/lib/decidim/seeds.rb +18 -20
  498. data/lib/decidim/settings_manifest.rb +34 -1
  499. data/lib/decidim/soft_deletable.rb +17 -0
  500. data/lib/decidim/taxonomizable.rb +72 -0
  501. data/lib/decidim/translatable_attributes.rb +1 -5
  502. data/lib/decidim/view_model.rb +0 -1
  503. data/lib/tasks/decidim_download_your_data_tasks.rake +2 -4
  504. data/lib/tasks/decidim_procfile.rake +6 -0
  505. data/lib/tasks/decidim_tasks.rake +1 -0
  506. data/lib/tasks/decidim_taxonomies.rake +155 -0
  507. data/lib/tasks/upgrade/{decidim_fix_categorization.rake → clean.rake} +25 -18
  508. data/lib/tasks/upgrade/decidim_active_storage_migration_tasks.rake +1 -1
  509. data/lib/tasks/upgrade/decidim_fix_nickname_uniqueness.rake +20 -23
  510. data/lib/tasks/upgrade/migrations.rake +91 -0
  511. metadata +203 -112
  512. data/app/cells/decidim/amendable/amenders_list/show.erb +0 -0
  513. data/app/cells/decidim/content_blocks/base/content.erb +0 -0
  514. data/app/cells/decidim/endorsers_list/full_endorsers_list.erb +0 -3
  515. data/app/cells/decidim/endorsers_list_button/content.erb +0 -1
  516. data/app/cells/decidim/endorsers_list_button_cell.rb +0 -15
  517. data/app/cells/decidim/report_user_button/already_reported_modal.erb +0 -11
  518. data/app/cells/decidim/report_user_button/flag_modal.erb +0 -46
  519. data/app/cells/decidim/report_user_button/show.erb +0 -2
  520. data/app/cells/decidim/report_user_button_cell.rb +0 -59
  521. data/app/cells/decidim/scopes_picker/scope_picker_prompt.erb +0 -3
  522. data/app/cells/decidim/scopes_picker/scope_picker_values.erb +0 -5
  523. data/app/cells/decidim/scopes_picker/show.erb +0 -14
  524. data/app/cells/decidim/scopes_picker_cell.rb +0 -92
  525. data/app/commands/decidim/update_user_interests.rb +0 -41
  526. data/app/controllers/decidim/scopes_controller.rb +0 -84
  527. data/app/controllers/decidim/user_interests_controller.rb +0 -30
  528. data/app/forms/decidim/user_interest_scope_form.rb +0 -25
  529. data/app/forms/decidim/user_interests_form.rb +0 -17
  530. data/app/helpers/decidim/categories_helper.rb +0 -26
  531. data/app/helpers/decidim/scopes_helper.rb +0 -105
  532. data/app/jobs/decidim/hide_child_resources_job.rb +0 -24
  533. data/app/packs/images/decidim/vendor/leaflet/layers-2x.png +0 -0
  534. data/app/packs/images/decidim/vendor/leaflet/layers.png +0 -0
  535. data/app/packs/images/decidim/vendor/leaflet/marker-icon-2x.png +0 -0
  536. data/app/packs/images/decidim/vendor/leaflet/marker-icon.png +0 -0
  537. data/app/packs/images/decidim/vendor/leaflet/marker-shadow.png +0 -0
  538. data/app/packs/stylesheets/decidim/_hashtags.scss +0 -5
  539. data/app/packs/stylesheets/decidim/legacy/MarkerCluster.Default.scss +0 -67
  540. data/app/packs/stylesheets/decidim/legacy/MarkerCluster.scss +0 -18
  541. data/app/packs/stylesheets/decidim/legacy/leaflet.scss +0 -705
  542. data/app/validators/scope_belongs_to_component_validator.rb +0 -16
  543. data/app/views/decidim/account/_user_groups.html.erb +0 -0
  544. data/app/views/decidim/reported_mailer/hidden_automatically.html.erb +0 -25
  545. data/app/views/decidim/reported_mailer/hidden_manually.html.erb +0 -25
  546. data/app/views/decidim/scopes/_scopes_picker_input.html.erb +0 -19
  547. data/app/views/decidim/scopes/picker.html.erb +0 -53
  548. data/app/views/decidim/shared/_comments.html.erb +0 -0
  549. data/app/views/decidim/shared/_share_modal.html.erb +0 -26
  550. data/app/views/decidim/shared/_tags.html.erb +0 -1
  551. data/app/views/decidim/user_interests/_areas.html.erb +0 -14
  552. data/app/views/decidim/user_interests/_scopes.html.erb +0 -22
  553. data/app/views/decidim/user_interests/show.html.erb +0 -22
  554. data/config/initializers/foundation_rails_helper.rb +0 -4
  555. data/config/locales/ca-IT.yml +0 -2122
  556. data/lib/decidim/core/test/shared_examples/has_category.rb +0 -38
  557. data/lib/decidim/core/test/shared_examples/has_scope.rb +0 -11
  558. data/lib/decidim/core/test/shared_examples/manage_component_share_tokens.rb +0 -83
  559. data/lib/decidim/core/test/shared_examples/preview_component_with_share_token_examples.rb +0 -49
  560. data/lib/decidim/core/test/shared_examples/scope_helper_examples.rb +0 -93
  561. data/lib/decidim/seven_zip_wrapper.rb +0 -29
  562. data/lib/tasks/upgrade/clean_hidden_resources.rake +0 -33
@@ -53,54 +53,59 @@ module Decidim
53
53
  # def name=(value)
54
54
  # super(encrypt_value(value))
55
55
  # end
56
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
57
-
58
- # def full_name
59
- # return @full_name_decrypted if instance_variable_defined?(:@full_name_decrypted)
60
- #
61
- # encrypted_value = begin
62
- # if defined?(super)
63
- # super
64
- # elsif instance_variable_defined?(:@full_name)
65
- # @full_name
66
- # end
67
- # end
68
- # @full_name_decrypted = decrypt_value(encrypted_value)
69
- # end
70
- def #{attribute}
71
- return @#{attribute}_decrypted if instance_variable_defined?(:@#{attribute}_decrypted)
72
-
73
- encrypted_value = begin
74
- if defined?(super)
75
- super
76
- elsif instance_variable_defined?(:@#{attribute})
77
- @#{attribute}
78
- end
79
- end
80
- @#{attribute}_decrypted = decrypt_#{method_suffix}(encrypted_value)
81
- end
56
+ create_encrypted_getter(attribute, method_suffix)
57
+ create_encrypted_setter(attribute, method_suffix)
58
+ end
59
+
60
+ # def full_name
61
+ # return @full_name_decrypted if instance_variable_defined?(:@full_name_decrypted)
62
+ #
63
+ # encrypted_value = begin
64
+ # if defined?(super)
65
+ # super
66
+ # elsif instance_variable_defined?(:@full_name)
67
+ # @full_name
68
+ # end
69
+ # end
70
+ # @full_name_decrypted = decrypt_value(encrypted_value)
71
+ # end
72
+ def create_encrypted_getter(attribute, method_suffix)
73
+ define_method(attribute) do
74
+ return instance_variable_get(:"@#{attribute}_decrypted") if instance_variable_defined?(:"@#{attribute}_decrypted")
75
+
76
+ encrypted_value = if defined?(super)
77
+ super()
78
+ elsif instance_variable_defined?(:"@#{attribute}")
79
+ instance_variable_get(:"@#{attribute}")
80
+ end
81
+
82
+ decrypted_value = send(:"decrypt_#{method_suffix}", encrypted_value)
83
+ instance_variable_set(:"@#{attribute}_decrypted", decrypted_value)
84
+ end
85
+ end
82
86
 
83
- # def full_name=(value)
84
- # remove_instance_variable(:@full_name_decrypted) if instance_variable_defined?(:@full_name_decrypted)
85
- # encrypted_value = encrypt_value(value)
86
- #
87
- # if defined?(super)
88
- # super(encrypted_value)
89
- # else
90
- # @full_name = encrypted_value
91
- # end
92
- # end
93
- def #{attribute}=(value)
94
- remove_instance_variable(:@#{attribute}_decrypted) if instance_variable_defined?(:@#{attribute}_decrypted)
95
- encrypted_value = encrypt_#{method_suffix}(value)
96
-
97
- if defined?(super)
98
- super(encrypted_value)
99
- else
100
- @#{attribute} = encrypted_value
101
- end
87
+ # def full_name=(value)
88
+ # remove_instance_variable(:@full_name_decrypted) if instance_variable_defined?(:@full_name_decrypted)
89
+ # encrypted_value = encrypt_value(value)
90
+ #
91
+ # if defined?(super)
92
+ # super(encrypted_value)
93
+ # else
94
+ # @full_name = encrypted_value
95
+ # end
96
+ # end
97
+ def create_encrypted_setter(attribute, method_suffix)
98
+ define_method("#{attribute}=") do |value|
99
+ remove_instance_variable(:"@#{attribute}_decrypted") if instance_variable_defined?(:"@#{attribute}_decrypted")
100
+
101
+ encrypted_value = send(:"encrypt_#{method_suffix}", value)
102
+
103
+ if defined?(super)
104
+ super(encrypted_value)
105
+ else
106
+ instance_variable_set(:"@#{attribute}", encrypted_value)
102
107
  end
103
- RUBY
108
+ end
104
109
  end
105
110
  end
106
111
 
@@ -53,12 +53,8 @@ module Decidim
53
53
  # Public: The reported content url
54
54
  #
55
55
  # Returns String
56
- def reported_content_url(options = {})
57
- if hidden?
58
- ResourceLocatorPresenter.new(self).index(options)
59
- else
60
- ResourceLocatorPresenter.new(self).url(options)
61
- end
56
+ def reported_content_url
57
+ raise NotImplementedError
62
58
  end
63
59
 
64
60
  # Public: The collection of attribute names that are considered
@@ -50,6 +50,22 @@ module Decidim
50
50
  scope.where(id: from).or(scope.where(id: to))
51
51
  end
52
52
 
53
+ def linked_resources_from(resource_name, link_name, component_published: true)
54
+ scope = sibling_scope(resource_name, component_published:)
55
+
56
+ scope
57
+ .joins(:resource_links_from)
58
+ .where(decidim_resource_links: { name: link_name, to_id: id, to_type: self.class.name })
59
+ end
60
+
61
+ def linked_resources_to(resource_name, link_name, component_published: true)
62
+ scope = sibling_scope(resource_name, component_published:)
63
+
64
+ scope
65
+ .joins(:resource_links_to)
66
+ .where(decidim_resource_links: { name: link_name, from_id: id, from_type: self.class.name })
67
+ end
68
+
53
69
  # Builds an ActiveRecord::Relation in order to load all the resources
54
70
  # that are in the same parent as this model.
55
71
  #
data/lib/decidim/seeds.rb CHANGED
@@ -21,7 +21,7 @@ module Decidim
21
21
  user = Decidim::User.find_or_initialize_by(email:)
22
22
  user.update!(
23
23
  name: ::Faker::Name.name,
24
- nickname: ::Faker::Twitter.unique.screen_name,
24
+ nickname: "#{::Faker::Twitter.unique.screen_name}-#{rand(10_000)}"[0...20],
25
25
  password: "decidim123456789",
26
26
  organization:,
27
27
  confirmed_at: Time.current,
@@ -38,18 +38,6 @@ module Decidim
38
38
  user
39
39
  end
40
40
 
41
- def random_scope(participatory_space:)
42
- if participatory_space.scope
43
- scopes = participatory_space.scope.descendants
44
- global = participatory_space.scope
45
- else
46
- scopes = participatory_space.organization.scopes
47
- global = nil
48
- end
49
-
50
- ::Faker::Boolean.boolean(true_ratio: 0.5) ? global : scopes.sample
51
- end
52
-
53
41
  def seeds_root = File.join(__dir__, "..", "..", "db", "seeds")
54
42
 
55
43
  def hero_image = create_blob!(seeds_file: "city.jpeg", filename: "hero_image.jpeg", content_type: "image/jpeg")
@@ -97,13 +85,23 @@ module Decidim
97
85
  )
98
86
  end
99
87
 
100
- def create_category!(participatory_space:)
101
- Decidim::Category.create!(
102
- name: Decidim::Faker::Localized.sentence(word_count: 5),
103
- description: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
104
- Decidim::Faker::Localized.paragraph(sentence_count: 3)
105
- end,
106
- participatory_space:
88
+ def create_taxonomy!(name:, parent:)
89
+ Decidim::Taxonomy.create!(
90
+ name: Decidim::Faker::Localized.literal(name),
91
+ organization:,
92
+ parent:
93
+ )
94
+ end
95
+
96
+ def create_taxonomy_filter!(root_taxonomy:, taxonomies:, participatory_space_manifests: [])
97
+ Decidim::TaxonomyFilter.create!(
98
+ root_taxonomy:,
99
+ participatory_space_manifests:,
100
+ filter_items: taxonomies.map do |taxonomy_item|
101
+ Decidim::TaxonomyFilterItem.new(
102
+ taxonomy_item:
103
+ )
104
+ end
107
105
  )
108
106
  end
109
107
 
@@ -70,6 +70,8 @@ module Decidim
70
70
  validates name, presence: true if attribute.required
71
71
  validates name, inclusion: { in: attribute.build_choices } if attribute.type == :enum
72
72
  end
73
+
74
+ SettingsManifest.add_integer_with_units_validation(self, name, attribute) if attribute.type == :integer_with_units
73
75
  end
74
76
  end
75
77
 
@@ -77,6 +79,20 @@ module Decidim
77
79
  @schema
78
80
  end
79
81
 
82
+ def self.add_integer_with_units_validation(schema, name, attribute)
83
+ schema.class_eval do
84
+ validate do
85
+ value = send(name)
86
+ value = [value["0"].to_i, value["1"].to_s] if value.is_a?(::Hash)
87
+
88
+ errors.add(name, :invalid) unless value.is_a?(::Array) &&
89
+ value.size == 2 &&
90
+ value[0].is_a?(Integer) &&
91
+ attribute.build_units.include?(value[1])
92
+ end
93
+ end
94
+ end
95
+
80
96
  def required_attributes_for_authorization
81
97
  attributes.select { |_, attribute| attribute.required_for_authorization? }
82
98
  end
@@ -91,6 +107,7 @@ module Decidim
91
107
  TYPES = {
92
108
  boolean: { klass: Boolean, default: false },
93
109
  integer: { klass: Integer, default: 0 },
110
+ integer_with_units: { klass: Decidim::Attributes::IntegerWithUnits, default: [5, "minutes"] },
94
111
  string: { klass: String, default: nil },
95
112
  float: { klass: Float, default: nil },
96
113
  text: { klass: String, default: nil },
@@ -98,7 +115,8 @@ module Decidim
98
115
  enum: { klass: String, default: nil },
99
116
  select: { klass: String, default: nil },
100
117
  scope: { klass: Integer, default: nil },
101
- time: { klass: Decidim::Attributes::TimeWithZone, default: nil }
118
+ time: { klass: Decidim::Attributes::TimeWithZone, default: nil },
119
+ taxonomy_filters: { klass: Array, default: [] }
102
120
  }.freeze
103
121
 
104
122
  attribute :type, Symbol, default: :boolean
@@ -111,9 +129,20 @@ module Decidim
111
129
  attribute :required_for_authorization, Boolean, default: false
112
130
  attribute :readonly
113
131
  attribute :choices
132
+ attribute :units
114
133
  attribute :include_blank, Boolean, default: false
115
134
 
116
135
  validates :type, inclusion: { in: TYPES.keys }
136
+ validate :validate_integer_with_units_structure
137
+
138
+ def validate_integer_with_units_structure
139
+ return unless type == :integer_with_units
140
+
141
+ errors.add(:default, :invalid) unless default_value.is_a?(::Array) &&
142
+ default_value.size == 2 &&
143
+ default_value[0].is_a?(Integer) &&
144
+ build_units.include?(default_value[1])
145
+ end
117
146
 
118
147
  def type_class
119
148
  return Decidim::Attributes::RichText if type == :text && editor == true
@@ -129,6 +158,10 @@ module Decidim
129
158
  choices.try(:call) || choices
130
159
  end
131
160
 
161
+ def build_units
162
+ units.try(:call) || units
163
+ end
164
+
132
165
  def readonly?(context)
133
166
  readonly&.call(context)
134
167
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+ require "paranoia"
5
+
6
+ module Decidim
7
+ # This concern contains the logic related to soft deletion (trashing).
8
+ module SoftDeletable
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ acts_as_paranoid
13
+
14
+ scope :deleted_at_desc, -> { order(deleted_at: :desc) }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ # A concern with the components needed when you want a model to have taxonomies.
7
+ #
8
+ # The including model needs to implement the following interface:
9
+ #
10
+ # @abstract method that gives an associated organization
11
+ # @method organization
12
+ # @return [Decidim::Organization]
13
+ #
14
+ module Taxonomizable
15
+ extend ActiveSupport::Concern
16
+
17
+ included do
18
+ has_many :taxonomizations, as: :taxonomizable, class_name: "Decidim::Taxonomization", dependent: :destroy
19
+ has_many :taxonomies, through: :taxonomizations
20
+
21
+ validate :no_root_taxonomies
22
+ validate :taxonomies_belong_to_organization
23
+
24
+ # finds taxonomizables belonging to a specific taxonomy
25
+ scope :with_taxonomy, ->(taxonomy_id) { includes(:taxonomies).references(:decidim_taxonomies).where("? = ANY(decidim_taxonomies.part_of)", taxonomy_id) }
26
+
27
+ # finds taxonomizables belonging to any of the taxonomies specified (or its children)
28
+ scope :with_taxonomies, lambda { |*taxonomy_ids|
29
+ conditions = ["? = ANY(part_of)"] * taxonomy_ids.count
30
+ taxonomies = Decidim::Taxonomy.where(conditions.join(" OR "), *taxonomy_ids.map(&:to_i))
31
+ includes(:taxonomies).joins(:taxonomies).where(decidim_taxonomies: { id: taxonomies })
32
+ }
33
+
34
+ # finds taxonomizables belonging to all groups of taxonomies specified, each group is an array of taxonomy ids that are ORed together
35
+ scope :with_any_taxonomies, lambda { |*taxonomy_groups|
36
+ return with_taxonomies(*taxonomy_groups) unless taxonomy_groups.first.is_a?(Array)
37
+
38
+ queries = []
39
+ taxonomy_groups.each do |root_id, taxonomy_ids|
40
+ taxonomy_ids = taxonomy_ids.flatten.compact_blank
41
+ next if taxonomy_ids.empty?
42
+
43
+ taxonomy_ids = [root_id] if taxonomy_ids.include?("all")
44
+
45
+ queries << with_taxonomies(*taxonomy_ids)
46
+ end
47
+ return self if queries.empty?
48
+ return queries.first if queries.count == 1
49
+
50
+ subquery = queries.map(&:arel).reduce do |memo, query|
51
+ Arel::Nodes::Intersect.new(memo, query)
52
+ end
53
+
54
+ @klass.from(Arel::Nodes::As.new(subquery, Arel.sql(@klass.arel_table.name)))
55
+ }
56
+
57
+ private
58
+
59
+ def no_root_taxonomies
60
+ return unless taxonomies.any?(&:root?)
61
+
62
+ errors.add(:taxonomies, :invalid)
63
+ end
64
+
65
+ def taxonomies_belong_to_organization
66
+ return if taxonomies.all? { |taxonomy| taxonomy.organization == organization }
67
+
68
+ errors.add(:taxonomies, :invalid)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -62,7 +62,7 @@ module Decidim
62
62
  final = super(value)
63
63
  return unless final # Do not set the `nil` values for the parent hash
64
64
 
65
- final = value_type.serialize(final) if value_type && !attachment?(final)
65
+ final = value_type.serialize(final) if value_type
66
66
 
67
67
  public_send("#{name}=", field.merge(locale => final))
68
68
  end
@@ -127,9 +127,5 @@ module Decidim
127
127
  locale.to_s == try(:default_locale).to_s ||
128
128
  locale.to_s == try(:current_organization).try(:default_locale).to_s
129
129
  end
130
-
131
- def attachment?(value)
132
- value.is_a?(String) && value.include?(ActiveStorage.routes_prefix)
133
- end
134
130
  end
135
131
  end
@@ -8,7 +8,6 @@ module Decidim
8
8
  include ActionView::Helpers::TranslationHelper
9
9
  include ::Cell::Translation
10
10
  include Decidim::ResourceHelper
11
- include Decidim::ScopesHelper
12
11
  include ActionController::Helpers
13
12
  include Decidim::ActionAuthorization
14
13
  include Decidim::ActionAuthorizationHelper
@@ -64,7 +64,7 @@ namespace :decidim do
64
64
  input = $stdin.gets.chomp
65
65
  if input.casecmp("y").zero?
66
66
  puts %( Continue...)
67
- Decidim::User.where("newsletter_notifications_at < ?", Time.zone.parse("2018-05-25 00:00 +02:00")).find_each(&:newsletter_opt_in_notify)
67
+ Decidim::User.where(newsletter_notifications_at: ...Time.zone.parse("2018-05-25 00:00 +02:00")).find_each(&:newsletter_opt_in_notify)
68
68
  else
69
69
  puts %( Execution cancelled...)
70
70
  end
@@ -76,9 +76,7 @@ namespace :decidim do
76
76
  attachments = ActiveStorage::Attachment.joins(:blob).where(
77
77
  name: "download_your_data_file",
78
78
  record_type: "Decidim::UserBaseEntity"
79
- ).where(
80
- "active_storage_blobs.created_at < ?", Decidim.download_your_data_expiry_time.ago
81
- )
79
+ ).where(active_storage_blobs: { created_at: ...Decidim.download_your_data_expiry_time.ago })
82
80
  attachments.each do |attachment|
83
81
  delete_download_your_data_file attachment
84
82
  end
@@ -11,6 +11,12 @@ namespace :decidim do
11
11
  shakapacker: bin/shakapacker-dev-server
12
12
  RUBY
13
13
 
14
+ if defined?(Sidekiq)
15
+ actions :append_file, "Procfile.dev", <<~RUBY
16
+ sidekiq: bundle exec sidekiq -C config/sidekiq.yml
17
+ RUBY
18
+ end
19
+
14
20
  actions :create_file, "bin/dev", %(#!/usr/bin/env sh
15
21
 
16
22
  set -e
@@ -6,6 +6,7 @@ namespace :decidim do
6
6
  :choose_target_plugins,
7
7
  :"decidim:upgrade_app",
8
8
  :"railties:install:migrations",
9
+ :"decidim:upgrade:migrations",
9
10
  :"decidim:upgrade:webpacker",
10
11
  :"decidim_api:generate_docs"
11
12
  ]
@@ -0,0 +1,155 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "decidim/maintenance"
4
+
5
+ namespace :decidim do
6
+ namespace :taxonomies do
7
+ desc "Creates a JSON file with the taxonomies structure imported from older models"
8
+ task :make_plan, [] => :environment do |_task, _args|
9
+ Decidim::Organization.find_each do |organization|
10
+ log(true).info "Creating a plan for organization #{organization.id} in #{plan_file_path(organization)}"
11
+ FileUtils.mkdir_p(Rails.root.join("tmp/taxonomies"))
12
+ json = planner(organization).to_json do |model|
13
+ log.info "...Exporting taxonomies for #{model.table_name}"
14
+ end
15
+ File.write(plan_file_path(organization), json)
16
+ log.info "Plan created, you can review or edit if needed before importing."
17
+ log.info "Import the plan with this command:"
18
+ log.info "bin/rails decidim:taxonomies:import_plan[#{plan_file_path(organization)}]"
19
+ end
20
+ end
21
+
22
+ desc "Imports taxonomies and filters structure from a JSON file"
23
+ task :import_plan, [:file] => :environment do |_task, args|
24
+ file = args[:file].to_s
25
+ abort "File not found! [#{file}]" unless File.exist?(file)
26
+
27
+ data = JSON.parse(File.read(file))
28
+ organization = Decidim::Organization.find_by(id: data.dig("organization", "id"))
29
+ abort "Organization not found! [#{data["organization"]}]" unless organization
30
+ log(true).info "Importing taxonomies and filters for organization #{organization.id}"
31
+
32
+ planner(organization).import(data) do |importer, model_name|
33
+ taxonomies = importer.roots
34
+ result = importer.result
35
+ log.info "...Importing #{taxonomies.count} root taxonomies from #{model_name}"
36
+ taxonomies.each do |name, taxonomy|
37
+ log.info " - Root taxonomy: #{name}"
38
+ log.info " 1st level taxonomies: #{taxonomy["taxonomies"].count}"
39
+ log.info " Filters: #{taxonomy["filters"].count}"
40
+ taxonomy["filters"].each do |filter|
41
+ log.info " - Filter name: #{filter["name"]}"
42
+ log.info " Internal name: #{filter["internal_name"] || "-"}"
43
+ log.info " Space manifests: #{filter["participatory_space_manifests"]&.join(", ") || "-"}"
44
+ log.info " Items: #{filter["items"].count}"
45
+ log.info " Components: #{filter["components"].count}"
46
+ end
47
+ end
48
+ importer.import! do |type, detail|
49
+ log.info " !#{type}: #{detail}"
50
+ end
51
+ log.info " Created taxonomies: #{result[:taxonomies_created].count}"
52
+ result[:taxonomies_created].each do |name|
53
+ log.info " - #{name}"
54
+ end
55
+ log.info " Created filters: #{result[:filters_created].count}"
56
+ result[:filters_created].each do |name, items|
57
+ log.info " - #{name}: #{items.count} items"
58
+ end
59
+ log.info " Assigned resources: #{result[:taxonomies_assigned].count}"
60
+ result[:taxonomies_assigned].each do |name, items|
61
+ log.info " - #{name}: #{items.count} resources"
62
+ end
63
+ log.info " Assigned components: #{result[:components_assigned].count}"
64
+ result[:components_assigned].each do |name, items|
65
+ log.info " - #{name}: #{items.count} components"
66
+ end
67
+ log.info " Failed resources: #{result[:failed_resources].count}"
68
+ result[:failed_resources].each do |object_id|
69
+ log.info " - #{object_id}"
70
+ end
71
+ log.info " Failed components: #{result[:failed_components].count}"
72
+ result[:failed_components].each do |component_id|
73
+ log.info " - #{component_id}"
74
+ end
75
+ Rails.root.join("tmp/taxonomies", "#{organization.host}_result.json").write(JSON.pretty_generate(result))
76
+ log.info "Result saved in tmp/taxonomies/#{organization.host}_result.json"
77
+ end
78
+ log.info "Taxonomies and filters imported successfully."
79
+ end
80
+
81
+ desc "Imports taxonomies and filters structure from all JSON files inside tmp/taxonomies"
82
+ task :import_all_plans, [] => :environment do |_task, _args|
83
+ Rails.root.glob("tmp/taxonomies/*_plan.json").each do |file|
84
+ log.info "Importing plan from #{file}"
85
+ Rake::Task["decidim:taxonomies:import_plan"].invoke(file)
86
+ end
87
+ end
88
+
89
+ desc "Adds taxonomies to metrics from old categories"
90
+ task :update_metrics, [:file] => :environment do |_task, args|
91
+ file = args[:file].to_s
92
+ abort "File not found! [#{file}]" unless File.exist?(file)
93
+
94
+ data = JSON.parse(File.read(file))
95
+ taxonomies = data["taxonomy_map"]
96
+ abort "No taxonomies found in the file" unless taxonomies && taxonomies&.any?
97
+
98
+ total = taxonomies.count
99
+ taxonomies.each_with_index do |(id, object_id), index|
100
+ next unless object_id.include?("ImportModels::Category")
101
+
102
+ category_id = object_id.split("/").last
103
+ percent = ((index + 1) * 100 / total).to_i
104
+
105
+ count = Decidim::Metric.where(decidim_category_id: category_id).count
106
+ log.info "...#{percent}% Updating #{count} metrics for category #{category_id} to taxonomy #{id}"
107
+ Decidim::Metric.where(decidim_category_id: category_id).update_all(decidim_taxonomy_id: id) # rubocop:disable Rails/SkipsModelValidations
108
+ end
109
+ end
110
+
111
+ desc "Processes all metrics for result files in tmp/taxonomies"
112
+ task :update_all_metrics, [] => :environment do |_task, _args|
113
+ Rails.root.glob("tmp/taxonomies/*_result.json").each do |file|
114
+ log.info "Processing metrics from #{file}"
115
+ Rake::Task["decidim:taxonomies:update_metrics"].invoke(file)
116
+ end
117
+ end
118
+
119
+ desc "Reset counters for taxonomies and taxonomy filters"
120
+ task :reset_counters, [] => :environment do |_task, _args|
121
+ Decidim::Taxonomy.find_each do |taxonomy|
122
+ taxonomy.reset_all_counters
123
+ log.info "Counters reset for taxonomy #{taxonomy.id}:"
124
+ log.info " Children: #{taxonomy.children_count}"
125
+ log.info " Taxonomizations: #{taxonomy.taxonomizations_count}"
126
+ log.info " Filters: #{taxonomy.filters_count}"
127
+ log.info " Filter items: #{taxonomy.filter_items_count}"
128
+ end
129
+ Decidim::TaxonomyFilter.find_each do |filter|
130
+ filter.reset_all_counters
131
+ log.info "Counters reset for taxonomy filter #{filter.id}:"
132
+ log.info " Filter items: #{filter.filter_items_count}"
133
+ log.info " Components: #{filter.components_count}"
134
+ end
135
+ end
136
+
137
+ def planner(organization)
138
+ models = ENV.fetch("IMPORTS", "ParticipatoryProcessType AssemblyType Scope Area Category").split.map do |model_name|
139
+ "Decidim::Maintenance::ImportModels::#{model_name}".constantize
140
+ end
141
+ Decidim::Maintenance::TaxonomyPlan.new(organization, models)
142
+ end
143
+
144
+ def plan_file_path(organization)
145
+ Rails.root.join("tmp/taxonomies", "#{organization.host}_plan.json")
146
+ end
147
+
148
+ def log(reset = false) # rubocop:disable Style/OptionalBooleanParameter
149
+ @log = nil if reset
150
+ @log ||= Logger.new($stdout, formatter: proc { |_severity, _time, _progname, msg|
151
+ "#{msg}\n"
152
+ })
153
+ end
154
+ end
155
+ end