decidim-core 0.31.5 → 0.32.0.rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -13
  3. data/app/cells/decidim/amendable/amend_button_card_cell.rb +1 -1
  4. data/app/cells/decidim/content_blocks/announcement_settings_form/show.erb +5 -0
  5. data/app/cells/decidim/content_blocks/announcement_settings_form_cell.rb +17 -0
  6. data/app/cells/decidim/content_blocks/how_to_participate/show.erb +1 -1
  7. data/app/cells/decidim/content_blocks/participatory_space_announcement_cell.rb +1 -3
  8. data/app/cells/decidim/content_blocks/participatory_space_hero_cell.rb +1 -5
  9. data/app/cells/decidim/{participatory_space_private_user_cell.rb → member_cell.rb} +1 -1
  10. data/app/cells/decidim/onboarding_action_message_cell.rb +1 -0
  11. data/app/cells/decidim/profile/details.erb +1 -1
  12. data/app/cells/decidim/profile_cell.rb +1 -0
  13. data/app/cells/decidim/profile_member_of/show.erb +13 -0
  14. data/app/cells/decidim/profile_member_of_cell.rb +35 -0
  15. data/app/cells/decidim/tags_cell.rb +1 -1
  16. data/app/cells/decidim/versions_list/show.erb +25 -0
  17. data/app/commands/decidim/create_follow.rb +3 -5
  18. data/app/commands/decidim/create_user_report.rb +1 -1
  19. data/app/commands/decidim/destroy_account.rb +3 -3
  20. data/app/commands/decidim/search.rb +5 -5
  21. data/app/controllers/concerns/decidim/ajax_permission_handler.rb +1 -1
  22. data/app/controllers/concerns/decidim/direct_upload.rb +3 -2
  23. data/app/controllers/concerns/decidim/ephemeral_session_checker.rb +1 -1
  24. data/app/controllers/concerns/decidim/force_authentication.rb +10 -1
  25. data/app/controllers/concerns/decidim/impersonate_users.rb +4 -0
  26. data/app/controllers/concerns/decidim/locale_switcher.rb +52 -2
  27. data/app/controllers/concerns/decidim/needs_tos_accepted.rb +1 -1
  28. data/app/controllers/concerns/decidim/participatory_space/has_members_page.rb +27 -0
  29. data/app/controllers/concerns/decidim/participatory_space_context.rb +1 -5
  30. data/app/controllers/decidim/account_controller.rb +1 -1
  31. data/app/controllers/decidim/amendments_controller.rb +5 -4
  32. data/app/controllers/decidim/components/base_controller.rb +20 -3
  33. data/app/controllers/decidim/devise/omniauth_registrations_controller.rb +1 -1
  34. data/app/controllers/decidim/devise/passwords_controller.rb +1 -1
  35. data/app/controllers/decidim/devise/registrations_controller.rb +1 -1
  36. data/app/controllers/decidim/devise/sessions_controller.rb +1 -1
  37. data/app/controllers/decidim/download_your_data_controller.rb +1 -1
  38. data/app/controllers/decidim/editor_images_controller.rb +1 -1
  39. data/app/controllers/decidim/follows_controller.rb +4 -3
  40. data/app/controllers/decidim/geolocation_controller.rb +1 -1
  41. data/app/controllers/decidim/likes_controller.rb +2 -1
  42. data/app/controllers/decidim/locales_controller.rb +3 -11
  43. data/app/controllers/decidim/messaging/conversations_controller.rb +3 -3
  44. data/app/controllers/decidim/newsletters_controller.rb +1 -1
  45. data/app/controllers/decidim/notifications_settings_controller.rb +1 -1
  46. data/app/controllers/decidim/notifications_subscriptions_controller.rb +1 -1
  47. data/app/controllers/decidim/open_data_controller.rb +1 -1
  48. data/app/controllers/decidim/report_users_controller.rb +2 -2
  49. data/app/controllers/decidim/reports_controller.rb +1 -1
  50. data/app/controllers/decidim/user_activities_controller.rb +1 -2
  51. data/app/events/decidim/welcome_notification_event.rb +1 -1
  52. data/app/forms/decidim/upload_validation_form.rb +1 -1
  53. data/app/helpers/concerns/decidim/flash_helper_extensions.rb +1 -0
  54. data/app/helpers/decidim/active_link_to_helper.rb +136 -0
  55. data/app/helpers/decidim/amendments_helper.rb +3 -3
  56. data/app/helpers/decidim/check_boxes_tree_helper.rb +2 -2
  57. data/app/helpers/decidim/component_path_helper.rb +9 -4
  58. data/app/helpers/decidim/filters_helper.rb +0 -2
  59. data/app/helpers/decidim/menu_helper.rb +3 -3
  60. data/app/helpers/decidim/meta_tags_helper.rb +0 -2
  61. data/app/helpers/decidim/paginate_helper.rb +14 -1
  62. data/app/helpers/decidim/sanitize_helper.rb +1 -0
  63. data/app/helpers/decidim/short_link_helper.rb +5 -5
  64. data/app/helpers/decidim/translations_helper.rb +4 -4
  65. data/app/jobs/decidim/delete_inactive_participants_job.rb +2 -2
  66. data/app/mailers/decidim/application_mailer.rb +7 -2
  67. data/app/mailers/decidim/decidim_devise_mailer.rb +1 -0
  68. data/app/mailers/decidim/reported_mailer.rb +4 -1
  69. data/app/models/decidim/action_log.rb +1 -1
  70. data/app/models/decidim/attachment.rb +2 -2
  71. data/app/models/decidim/authorization_transfer.rb +1 -1
  72. data/app/models/decidim/component.rb +6 -9
  73. data/app/models/decidim/content_block.rb +3 -3
  74. data/app/models/decidim/newsletter.rb +2 -2
  75. data/app/models/decidim/participatory_space/member.rb +55 -0
  76. data/app/models/decidim/resource_link.rb +1 -1
  77. data/app/models/decidim/short_link.rb +1 -1
  78. data/app/packs/src/decidim/controllers/assign_role/assign_role.test.js +80 -0
  79. data/app/packs/src/decidim/controllers/assign_role/controller.js +27 -0
  80. data/app/packs/src/decidim/controllers/main_menu/controller.js +115 -0
  81. data/app/packs/src/decidim/controllers/main_menu/main_menu.test.js +185 -0
  82. data/app/packs/src/decidim/datepicker/generate_datepicker.js +1 -13
  83. data/app/packs/src/decidim/editor/common/suggestion.js +1 -1
  84. data/app/packs/src/decidim/editor/extensions/decidim_kit/index.js +4 -1
  85. data/app/packs/src/decidim/editor/extensions/image/index.js +8 -5
  86. data/app/packs/src/decidim/editor/extensions/link/index.js +8 -0
  87. data/app/packs/src/decidim/editor/extensions/mention/index.js +18 -5
  88. data/app/packs/src/decidim/editor/extensions/mention_resource/index.js +16 -7
  89. data/app/packs/src/decidim/editor/test/extensions/decidim_kit.test.js +13 -4
  90. data/app/packs/src/decidim/editor/test/extensions/heading.test.js +1 -1
  91. data/app/packs/src/decidim/editor/test/extensions/image.test.js +26 -28
  92. data/app/packs/src/decidim/editor/test/extensions/mention.test.js +6 -2
  93. data/app/packs/src/decidim/editor/test/extensions/video_embed.test.js +27 -15
  94. data/app/packs/src/decidim/editor/test/helpers.js +8 -10
  95. data/app/packs/src/decidim/editor/test/toolbar/full.test.js +15 -4
  96. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_block.js +8 -4
  97. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_formatting.js +5 -1
  98. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_indent.js +9 -5
  99. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_link.js +5 -1
  100. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_list.js +8 -4
  101. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_styling.js +13 -9
  102. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_content_styling.js +6 -2
  103. data/app/packs/src/decidim/index.js +0 -1
  104. data/app/packs/stylesheets/decidim/_cards.scss +2 -1
  105. data/app/packs/stylesheets/decidim/_datepicker.scss +0 -8
  106. data/app/packs/stylesheets/decidim/_dropdown.scss +21 -31
  107. data/app/packs/stylesheets/decidim/_footer.scss +0 -36
  108. data/app/packs/stylesheets/decidim/_forms.scss +5 -1
  109. data/app/packs/stylesheets/decidim/_header.scss +148 -46
  110. data/app/packs/stylesheets/decidim/_language_chooser.scss +79 -0
  111. data/app/packs/stylesheets/decidim/application.scss +1 -0
  112. data/app/presenters/decidim/admin_log/participatory_space/member_presenter.rb +40 -0
  113. data/app/presenters/decidim/admin_log/static_page_resource_presenter.rb +1 -1
  114. data/app/presenters/decidim/authorization_transfer_presenter.rb +1 -1
  115. data/app/presenters/decidim/breadcrumb_root_menu_item_presenter.rb +3 -3
  116. data/app/presenters/decidim/log/user_presenter.rb +1 -0
  117. data/app/presenters/decidim/log/value_types/access_mode_presenter.rb +45 -0
  118. data/app/presenters/decidim/participatory_space/member_presenter.rb +48 -0
  119. data/app/presenters/decidim/resource_locator_presenter.rb +22 -3
  120. data/app/queries/decidim/last_activity.rb +1 -1
  121. data/app/serializers/decidim/exporters/participatory_space_serializer.rb +15 -1
  122. data/app/services/decidim/email_notification_generator.rb +2 -0
  123. data/app/services/decidim/notification_generator.rb +4 -0
  124. data/app/uploaders/decidim/organization_favicon_uploader.rb +4 -9
  125. data/app/validators/uploader_image_dimensions_validator.rb +13 -11
  126. data/app/views/decidim/homepage/show.html.erb +1 -1
  127. data/app/views/decidim/messaging/conversations/_new_conversation_button.html.erb +1 -1
  128. data/app/views/decidim/messaging/conversations/_reply.html.erb +1 -1
  129. data/app/views/decidim/messaging/conversations/new.html.erb +1 -1
  130. data/app/views/decidim/messaging/conversations/show.html.erb +2 -2
  131. data/app/views/decidim/participatory_space/members/_member.html.erb +1 -0
  132. data/app/views/decidim/shared/_results_per_page.html.erb +1 -1
  133. data/app/views/decidim/shared/filters/_check_boxes_tree.html.erb +1 -1
  134. data/app/views/decidim/shared/filters/_dropdown_label.html.erb +4 -3
  135. data/app/views/devise/mailer/{invite_private_user.html.erb → invite_member.html.erb} +2 -2
  136. data/app/views/devise/mailer/{invite_private_user.text.erb → invite_member.text.erb} +2 -2
  137. data/app/views/layouts/decidim/_head.html.erb +2 -2
  138. data/app/views/layouts/decidim/_wrapper.html.erb +1 -1
  139. data/app/views/layouts/decidim/footer/_focus_mode_main.html.erb +0 -1
  140. data/app/views/layouts/decidim/footer/_main.html.erb +0 -1
  141. data/app/views/layouts/decidim/header/_focus_mode_back_button.html.erb +4 -1
  142. data/app/views/layouts/decidim/header/_main.html.erb +17 -8
  143. data/app/views/layouts/decidim/header/_main_language_chooser.html.erb +24 -0
  144. data/app/views/layouts/decidim/header/_main_links_desktop.html.erb +56 -56
  145. data/app/views/layouts/decidim/header/_main_links_mobile_account.html.erb +2 -2
  146. data/app/views/layouts/decidim/header/_main_links_mobile_item_account.html.erb +3 -1
  147. data/app/views/layouts/decidim/header/_main_menu_mobile.html.erb +18 -5
  148. data/app/views/layouts/decidim/header/_main_search.html.erb +3 -3
  149. data/app/views/layouts/decidim/header/_menu.html.erb +5 -5
  150. data/app/views/layouts/decidim/header/_menu_breadcrumb_desktop.html.erb +13 -12
  151. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile.html.erb +28 -0
  152. data/config/initializers/invisible_captcha.rb +1 -0
  153. data/config/locales/ar.yml +3 -10
  154. data/config/locales/bg.yml +3 -10
  155. data/config/locales/ca-IT.yml +33 -19
  156. data/config/locales/ca.yml +33 -19
  157. data/config/locales/cs.yml +22 -19
  158. data/config/locales/de.yml +13 -18
  159. data/config/locales/el.yml +3 -7
  160. data/config/locales/en.yml +33 -19
  161. data/config/locales/es-MX.yml +33 -19
  162. data/config/locales/es-PY.yml +33 -19
  163. data/config/locales/es.yml +33 -19
  164. data/config/locales/eu.yml +33 -19
  165. data/config/locales/fi-plain.yml +33 -19
  166. data/config/locales/fi.yml +33 -19
  167. data/config/locales/fr-CA.yml +33 -19
  168. data/config/locales/fr.yml +33 -19
  169. data/config/locales/ga-IE.yml +3 -1
  170. data/config/locales/gl.yml +3 -7
  171. data/config/locales/hu.yml +3 -10
  172. data/config/locales/id-ID.yml +3 -7
  173. data/config/locales/it.yml +3 -10
  174. data/config/locales/ja.yml +18 -19
  175. data/config/locales/lb.yml +3 -8
  176. data/config/locales/lt.yml +3 -10
  177. data/config/locales/lv.yml +3 -7
  178. data/config/locales/nl.yml +3 -8
  179. data/config/locales/no.yml +3 -8
  180. data/config/locales/pl.yml +3 -10
  181. data/config/locales/pt-BR.yml +17 -19
  182. data/config/locales/pt.yml +3 -8
  183. data/config/locales/ro-RO.yml +10 -18
  184. data/config/locales/ru.yml +0 -6
  185. data/config/locales/sk.yml +33 -19
  186. data/config/locales/sv.yml +33 -19
  187. data/config/locales/tr-TR.yml +3 -8
  188. data/config/locales/uk.yml +0 -3
  189. data/config/locales/zh-CN.yml +3 -7
  190. data/config/locales/zh-TW.yml +3 -8
  191. data/config/routes.rb +139 -76
  192. data/db/data/20251213075429_rename_members_in_action_log.rb +22 -0
  193. data/db/data/20260319145808_rename_send_to_members_in_newsletter.rb +27 -0
  194. data/db/migrate/20200730142511_add_file_upload_settings_to_decidim_organizations.rb +13 -15
  195. data/db/migrate/20250523104311_move_cta_to_hero_content_block.rb +1 -1
  196. data/db/migrate/20250527122040_move_highlighted_content_banner_settings_to_content_block.rb +1 -1
  197. data/db/migrate/20250819110800_convert_private_exports_id_to_uuid.rb +2 -2
  198. data/db/migrate/20251112132305_remove_legacy_images_from_core_module.rb +27 -0
  199. data/db/migrate/20251205122428_rename_participatory_space_private_users_to_members.rb +9 -0
  200. data/db/migrate/20251216185133_rename_privatable_to_to_participatory_space_in_members.rb +10 -0
  201. data/db/migrate/20260208201405_remove_user_group_core.rb +21 -0
  202. data/db/migrate/20260208201406_remove_user_group_memberships.rb +30 -0
  203. data/db/migrate/20260208201407_remove_user_group_organizations.rb +11 -0
  204. data/db/migrate/20260217152425_remove_enable_participatory_space_filters_from_decidim_organizations.rb +7 -0
  205. data/db/migrate/20260314081619_add_index_on_decidim_members.rb +25 -0
  206. data/decidim-core.gemspec +25 -28
  207. data/lib/decidim/acts_as_tree.rb +12 -12
  208. data/lib/decidim/admin_filters_registry.rb +1 -1
  209. data/lib/decidim/amendable.rb +5 -1
  210. data/lib/decidim/api/functions/category_list.rb +1 -0
  211. data/lib/decidim/api/functions/component_finder_base.rb +1 -1
  212. data/lib/decidim/api/functions/component_list.rb +3 -1
  213. data/lib/decidim/api/functions/component_list_base.rb +1 -0
  214. data/lib/decidim/api/functions/participatory_space_finder_base.rb +1 -1
  215. data/lib/decidim/api/functions/participatory_space_list_base.rb +1 -0
  216. data/lib/decidim/api/functions/user_entity_list.rb +0 -1
  217. data/lib/decidim/api/interfaces/amendable_entity_interface.rb +1 -0
  218. data/lib/decidim/api/interfaces/amendable_interface.rb +1 -0
  219. data/lib/decidim/api/interfaces/attachable_collection_interface.rb +1 -0
  220. data/lib/decidim/api/interfaces/attachable_interface.rb +1 -0
  221. data/lib/decidim/api/interfaces/author_interface.rb +2 -1
  222. data/lib/decidim/api/interfaces/authorable_interface.rb +1 -0
  223. data/lib/decidim/api/interfaces/categories_container_interface.rb +1 -0
  224. data/lib/decidim/api/interfaces/categorizable_interface.rb +1 -0
  225. data/lib/decidim/api/interfaces/coauthorable_interface.rb +1 -0
  226. data/lib/decidim/api/interfaces/component_interface.rb +9 -8
  227. data/lib/decidim/api/interfaces/fingerprint_interface.rb +1 -0
  228. data/lib/decidim/api/interfaces/followable_interface.rb +2 -0
  229. data/lib/decidim/api/interfaces/likeable_interface.rb +2 -2
  230. data/lib/decidim/api/interfaces/localizable_interface.rb +1 -0
  231. data/lib/decidim/api/interfaces/participatory_space_interface.rb +1 -0
  232. data/lib/decidim/api/interfaces/referable_interface.rb +1 -0
  233. data/lib/decidim/api/interfaces/scopable_interface.rb +1 -0
  234. data/lib/decidim/api/interfaces/taxonomizable_interface.rb +1 -0
  235. data/lib/decidim/api/interfaces/timestamps_interface.rb +1 -0
  236. data/lib/decidim/api/interfaces/traceable_interface.rb +1 -0
  237. data/lib/decidim/api/types/attachment_collection_type.rb +5 -3
  238. data/lib/decidim/api/types/attachment_type.rb +11 -4
  239. data/lib/decidim/api/types/badge_score_type.rb +28 -0
  240. data/lib/decidim/api/types/moderation_type.rb +25 -0
  241. data/lib/decidim/api/types/participant_details_type.rb +17 -0
  242. data/lib/decidim/api/types/reportable_type.rb +18 -0
  243. data/lib/decidim/api/types/reportable_user_type.rb +17 -0
  244. data/lib/decidim/api/types/static_page_topic_type.rb +16 -0
  245. data/lib/decidim/api/types/static_page_type.rb +22 -0
  246. data/lib/decidim/api/types/taxonomy_type.rb +2 -0
  247. data/lib/decidim/api/types/user_moderation_type.rb +36 -0
  248. data/lib/decidim/api/types/user_type.rb +13 -0
  249. data/lib/decidim/asset_router/pipeline.rb +1 -1
  250. data/lib/decidim/asset_router/storage.rb +9 -9
  251. data/lib/decidim/assets/tailwind/tailwind.config.js.erb +3 -0
  252. data/lib/decidim/attribute_encryptor.rb +51 -10
  253. data/lib/decidim/attribute_object/model.rb +0 -5
  254. data/lib/decidim/block_registry.rb +1 -1
  255. data/lib/decidim/coauthorable.rb +2 -1
  256. data/lib/decidim/command.rb +1 -0
  257. data/lib/decidim/content_processor.rb +1 -1
  258. data/lib/decidim/core/api.rb +8 -0
  259. data/lib/decidim/core/content_blocks/registry_manager.rb +0 -6
  260. data/lib/decidim/core/engine.rb +2 -34
  261. data/lib/decidim/core/menu.rb +0 -26
  262. data/lib/decidim/core/test/factories.rb +29 -18
  263. data/lib/decidim/core/test/shared_examples/access_mode_restricted_participatory_spaces.rb +172 -0
  264. data/lib/decidim/core/test/shared_examples/access_mode_transparent_participatory_spaces.rb +241 -0
  265. data/lib/decidim/core/test/shared_examples/comments_examples.rb +115 -111
  266. data/lib/decidim/core/test/shared_examples/fingerprint_examples.rb +2 -0
  267. data/lib/decidim/core/test/shared_examples/has_members.rb +63 -0
  268. data/lib/decidim/core/test/shared_examples/manage_share_tokens_examples.rb +1 -1
  269. data/lib/decidim/core/test/shared_examples/map_examples.rb +1 -1
  270. data/lib/decidim/core/test/shared_examples/participant_details_examples.rb +16 -0
  271. data/lib/decidim/core/test/shared_examples/participatory_space_members_page_examples.rb +10 -10
  272. data/lib/decidim/core/test/shared_examples/resource_liked_event_examples.rb +1 -1
  273. data/lib/decidim/core/test/shared_examples/resource_locator_presenter_examples.rb +7 -7
  274. data/lib/decidim/core/test/shared_examples/searchable_participatory_space_examples.rb +3 -3
  275. data/lib/decidim/core/test/shared_examples/searchable_results_examples.rb +2 -2
  276. data/lib/decidim/core/test/shared_examples/simple_event.rb +1 -0
  277. data/lib/decidim/core/test/shared_examples/translated_event_examples.rb +2 -2
  278. data/lib/decidim/core/test/shared_examples/versions_controller_examples.rb +1 -1
  279. data/lib/decidim/core/test.rb +2 -1
  280. data/lib/decidim/core/version.rb +1 -1
  281. data/lib/decidim/core.rb +222 -335
  282. data/lib/decidim/download_your_data_serializers/{download_your_data_participatory_space_private_user_serializer.rb → download_your_data_member_serializer.rb} +6 -6
  283. data/lib/decidim/download_your_data_serializers.rb +2 -2
  284. data/lib/decidim/engine_router.rb +31 -6
  285. data/lib/decidim/exporters/csv.rb +1 -1
  286. data/lib/decidim/filter_form_builder.rb +1 -1
  287. data/{app/controllers/concerns → lib}/decidim/form_factory.rb +11 -1
  288. data/lib/decidim/has_settings.rb +2 -2
  289. data/lib/decidim/legacy_form_builder.rb +1 -0
  290. data/lib/decidim/locale_router_detector.rb +41 -0
  291. data/lib/decidim/maintenance/import_models/scope.rb +1 -1
  292. data/lib/decidim/maintenance/import_models.rb +0 -2
  293. data/lib/decidim/map/frontend.rb +1 -1
  294. data/lib/decidim/map/geocoding.rb +2 -2
  295. data/lib/decidim/map/static_map.rb +10 -22
  296. data/lib/decidim/map/utility.rb +3 -6
  297. data/lib/decidim/map.rb +2 -2
  298. data/lib/decidim/menu.rb +1 -1
  299. data/lib/decidim/menu_item.rb +1 -0
  300. data/lib/decidim/menu_registry.rb +1 -1
  301. data/lib/decidim/moderation_tools.rb +1 -1
  302. data/lib/decidim/newsletter_encryptor.rb +5 -8
  303. data/lib/decidim/organization_settings.rb +2 -2
  304. data/lib/decidim/participable.rb +1 -0
  305. data/lib/decidim/participatory_space/has_members.rb +61 -0
  306. data/lib/decidim/participatory_space_manifest.rb +0 -4
  307. data/lib/decidim/participatory_space_resourceable.rb +10 -1
  308. data/lib/decidim/routes/locale_redirects.rb +47 -0
  309. data/lib/decidim/routes.rb +7 -0
  310. data/lib/decidim/search_resource_fields_mapper.rb +3 -4
  311. data/lib/decidim/seeds.rb +17 -0
  312. data/lib/decidim/shakapacker/runner.rb +4 -4
  313. data/lib/decidim/shakapacker/shakapacker.yml +28 -3
  314. data/lib/decidim/taxonomizable.rb +1 -1
  315. data/lib/decidim/translatable_attributes.rb +9 -3
  316. data/lib/decidim/view_model.rb +4 -0
  317. data/lib/devise/models/decidim_newsletterable.rb +1 -1
  318. data/lib/tasks/decidim_procfile.rake +1 -1
  319. data/lib/tasks/decidim_tasks.rake +0 -1
  320. data/lib/tasks/decidim_taxonomies.rake +1 -1
  321. data/lib/tasks/upgrade/decidim_active_storage_migration_tasks.rake +0 -1
  322. data/lib/tasks/upgrade/decidim_encryption.rake +12 -0
  323. data/lib/tasks/upgrade/decidim_migrate_wysiwyg_content.rake +0 -1
  324. data/lib/tasks/upgrade/decidim_remove_deleted_users_left_data_tasks.rake +1 -1
  325. data/lib/tasks/upgrade/{fix_deleted_private_follows.rake → fix_deleted_members_follows.rake} +5 -5
  326. data/lib/tasks/upgrade/migrations.rake +0 -1
  327. data/lib/tasks/upgrade/user_groups_migration.rake +0 -1
  328. metadata +206 -130
  329. data/app/cells/decidim/content_blocks/global_menu/show.erb +0 -11
  330. data/app/cells/decidim/content_blocks/global_menu_cell.rb +0 -35
  331. data/app/cells/decidim/content_blocks/menu_breadcrumb_last_activity/show.erb +0 -10
  332. data/app/cells/decidim/content_blocks/menu_breadcrumb_last_activity_cell.rb +0 -49
  333. data/app/cells/decidim/participatory_space_dropdown_metadata/links.erb +0 -9
  334. data/app/cells/decidim/participatory_space_dropdown_metadata/metadata.erb +0 -1
  335. data/app/cells/decidim/participatory_space_dropdown_metadata/show.erb +0 -11
  336. data/app/cells/decidim/participatory_space_dropdown_metadata_cell.rb +0 -26
  337. data/app/controllers/concerns/decidim/has_members_page.rb +0 -25
  338. data/app/jobs/decidim/newsletters_opt_in_job.rb +0 -11
  339. data/app/jobs/decidim/user_report_job.rb +0 -11
  340. data/app/models/decidim/participatory_space_private_user.rb +0 -51
  341. data/app/packs/src/decidim/controllers/sticky_header/controller.js +0 -116
  342. data/app/packs/src/decidim/controllers/sticky_header/sticky_header.test.js +0 -320
  343. data/app/packs/src/decidim/dropdown_menu.js +0 -18
  344. data/app/packs/src/decidim/identity_selector_dialog.js +0 -33
  345. data/app/presenters/decidim/admin_log/participatory_space_private_user_presenter.rb +0 -38
  346. data/app/presenters/decidim/participatory_space_private_user_presenter.rb +0 -46
  347. data/app/views/decidim/participatory_space_private_users/_participatory_space_private_user.html.erb +0 -1
  348. data/app/views/layouts/decidim/footer/_main_language_chooser.html.erb +0 -26
  349. data/app/views/layouts/decidim/header/_menu_breadcrumb_items.html.erb +0 -34
  350. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_desktop.html.erb +0 -10
  351. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_mobile.html.erb +0 -17
  352. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_top_left.html.erb +0 -2
  353. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile_tablet.html.erb +0 -33
  354. data/app/views/layouts/decidim/header/_mobile_language_choose.html.erb +0 -25
  355. data/lib/decidim/core/test/shared_examples/has_private_users.rb +0 -63
  356. data/lib/decidim/core/test/shared_examples/participatory_space_dropdown_metadata_cell_examples.rb +0 -81
  357. data/lib/decidim/has_private_users.rb +0 -57
  358. data/lib/decidim/maintenance/import_models/assembly_type.rb +0 -49
  359. data/lib/decidim/maintenance/import_models/participatory_process_type.rb +0 -21
  360. data/lib/decidim/query_extensions.rb +0 -64
  361. /data/app/cells/decidim/{participatory_space_private_user → member}/show.erb +0 -0
@@ -79,7 +79,7 @@ module Decidim
79
79
  Decidim.participatory_space_manifests.map do |manifest|
80
80
  klass = manifest.model_class_name.constantize
81
81
 
82
- condition = if klass.include?(Decidim::HasPrivateUsers)
82
+ condition = if klass.include?(Decidim::ParticipatorySpace::HasMembers)
83
83
  Arel.sql(
84
84
  <<~SQL.squish
85
85
  (
@@ -27,7 +27,8 @@ module Decidim
27
27
  follows_count: resource.follows_count,
28
28
  short_description: resource.short_description,
29
29
  description: resource.description,
30
- promoted: resource.promoted
30
+ promoted: resource.promoted,
31
+ component_settings:
31
32
  }
32
33
  end
33
34
 
@@ -98,6 +99,19 @@ module Decidim
98
99
  serializer = Decidim::Exporters::ParticipatorySpaceComponentsSerializer.new(resource)
99
100
  serializer.run
100
101
  end
102
+
103
+ def component_settings
104
+ return unless resource.respond_to?(:components)
105
+
106
+ resource.components.map do |component|
107
+ {
108
+ id: component.id,
109
+ name: component.name,
110
+ manifest_name: component.manifest_name,
111
+ settings: component.settings.respond_to?(:as_json) ? component.settings.as_json : component.settings
112
+ }
113
+ end
114
+ end
101
115
  end
102
116
  end
103
117
  end
@@ -44,6 +44,7 @@ module Decidim
44
44
 
45
45
  def send_to_affected_users
46
46
  affected_users.each do |recipient|
47
+ next unless recipient.is_a?(Decidim::User)
47
48
  next unless ["all", "own-only"].include?(recipient.notification_types)
48
49
  next if recipient.deleted? || recipient.blocked?
49
50
 
@@ -53,6 +54,7 @@ module Decidim
53
54
 
54
55
  def send_to_followers
55
56
  followers.each do |recipient|
57
+ next unless recipient.is_a?(Decidim::User)
56
58
  next unless ["all", "followed-only"].include?(recipient.notification_types)
57
59
  next if recipient.deleted? || recipient.blocked?
58
60
 
@@ -37,10 +37,14 @@ module Decidim
37
37
  return unless event_class.types.include?(:notification)
38
38
 
39
39
  followers.each do |recipient|
40
+ next unless recipient.is_a?(Decidim::User)
41
+
40
42
  generate_notification_for(recipient, user_role: :follower) if ["all", "followed-only"].include?(recipient.notification_types)
41
43
  end
42
44
 
43
45
  affected_users.each do |recipient|
46
+ next unless recipient.is_a?(Decidim::User)
47
+
44
48
  generate_notification_for(recipient, user_role: :affected_user) if ["all", "own-only"].include?(recipient.notification_types)
45
49
  end
46
50
  end
@@ -7,7 +7,8 @@ module Decidim
7
7
  huge: 512,
8
8
  big: 192,
9
9
  medium: 180,
10
- small: 32
10
+ small: 32,
11
+ favicon: 256
11
12
  }.freeze
12
13
 
13
14
  set_variants do
@@ -16,17 +17,11 @@ module Decidim
16
17
  resize_and_pad: [value, value],
17
18
  format: :png
18
19
  }
19
- end.merge(
20
- favicon: {
21
- resize_and_pad: [256, 256],
22
- define: "icon:auto-resize=16,24,32,48,64,72,96,128,256",
23
- format: :ico
24
- }
25
- )
20
+ end
26
21
  end
27
22
 
28
23
  def extension_allowlist
29
- %w(png jpg jpeg webp ico)
24
+ %w(png jpg jpeg webp)
30
25
  end
31
26
  end
32
27
  end
@@ -3,7 +3,7 @@
3
3
  # This validator checks when the files to be uploaded are images and the attached uploader's
4
4
  # has enabled dimensions validation that the image dimensions are below the
5
5
  # limit defined by the uploader
6
- require "mini_magick"
6
+ require "vips"
7
7
 
8
8
  class UploaderImageDimensionsValidator < ActiveModel::Validations::FileContentTypeValidator
9
9
  def validate_each(record, attribute, value)
@@ -28,14 +28,16 @@ class UploaderImageDimensionsValidator < ActiveModel::Validations::FileContentTy
28
28
  return unless uploader.validable_dimensions
29
29
  return if (image = extract_image(file)).blank?
30
30
 
31
- record.errors.add attribute, I18n.t("decidim.errors.files.file_resolution_too_large") if image.dimensions.any? { |dimension| dimension > uploader.max_image_height_or_width }
32
- rescue MiniMagick::Error
33
- # The error may happen because of many reasons but most commonly the image
34
- # exceeds the default maximum dimensions set for ImageMagick when the
35
- # `identify` command fails to identify the image.
31
+ # A simple check to avoid DoS with maliciously crafted images, or just to
32
+ # avoid reckless users that upload images with too many pixels.
36
33
  #
37
- # To relax ImageMagick default limits, please refer to:
38
- # https://imagemagick.org/script/security-policy.php
34
+ # See https://hackerone.com/reports/390
35
+ max_dimension = [image.width, image.height].max
36
+ record.errors.add attribute, I18n.t("decidim.errors.files.file_resolution_too_large") if max_dimension > uploader.max_image_height_or_width
37
+ rescue Vips::Error
38
+ # The error may happen because of many reasons but most commonly the image
39
+ # exceeds the default maximum dimensions set for libvips when the image
40
+ # fails to load.
39
41
  #
40
42
  # Note that the error can also happen because of other reasons than only
41
43
  # the image dimensions being too large. But as we do not really know the
@@ -47,11 +49,11 @@ class UploaderImageDimensionsValidator < ActiveModel::Validations::FileContentTy
47
49
  return unless file.try(:content_type).to_s.start_with?("image")
48
50
 
49
51
  if uploaded_file?(file)
50
- MiniMagick::Image.new(file.path, File.extname(file.original_filename))
52
+ Vips::Image.new_from_file(file.path)
51
53
  elsif file.is_a?(ActiveStorage::Attached) && file.blob.persisted?
52
- MiniMagick::Image.read(file.blob.download, File.extname(file.blob.filename.to_s))
54
+ Vips::Image.new_from_buffer(file.blob.download, "")
53
55
  end
54
- rescue ActiveStorage::FileNotFoundError, MiniMagick::Invalid
56
+ rescue ActiveStorage::FileNotFoundError, Vips::Error
55
57
  # Although the blob is persisted, the file is not available to download and analyze
56
58
  # after committing the record
57
59
  nil
@@ -1,6 +1,6 @@
1
1
  <%
2
2
  edit_link(
3
- decidim_admin.edit_organization_path,
3
+ decidim_admin.edit_organization_homepage_path,
4
4
  :update,
5
5
  :organization,
6
6
  organization: current_organization
@@ -5,7 +5,7 @@
5
5
 
6
6
  <%= decidim_modal id: "conversation", class: "conversation__modal" do %>
7
7
  <%= decidim_form_for(@form, url: conversations_check_multiple_url, html: { class: "form", id: nil }) do |f| %>
8
- <%= render "add_conversation_users", object: f, locals: { title: "new title" } %>
8
+ <%= render "decidim/messaging/conversations/add_conversation_users", object: f, locals: { title: "new title" } %>
9
9
 
10
10
  <div data-dialog-actions>
11
11
  <button type="button" class="button button__sm md:button__lg button__transparent-secondary" data-dialog-close="conversation">
@@ -2,7 +2,7 @@
2
2
  <% if conversation.with_deleted_users?(current_user) %>
3
3
  <%= cell("decidim/announcement", t("decidim.messaging.conversations.show.deleted_accounts"), callout_class: "warning") %>
4
4
  <% elsif conversation.accept_user?(current_user) %>
5
- <%= render "reply_form", form:, conversation: %>
5
+ <%= render "decidim/messaging/conversations/reply_form", form:, conversation: %>
6
6
  <% else %>
7
7
  <%= cell("decidim/announcement", t("decidim.messaging.conversations.show.not_allowed"), callout_class: "warning") %>
8
8
  <% end %>
@@ -1,4 +1,4 @@
1
1
  <%= render layout: "show", locals: { participants: @form.recipient.to_a } do %>
2
2
  <div id="messages" class="space-y-6" data-controller="scroll-to-last"></div>
3
- <%= render "start", form: @form %>
3
+ <%= render "decidim/messaging/conversations/start", form: @form %>
4
4
  <% end %>
@@ -1,9 +1,9 @@
1
1
  <%= render layout: "show", locals: { participants: conversation.interlocutors(current_user) } do %>
2
2
  <div id="messages" class="space-y-6" data-controller="scroll-to-last">
3
3
  <% user_grouped_messages.each do |sender, messages| %>
4
- <%= render "messages", sender:, messages: %>
4
+ <%= render "decidim/messaging/conversations/messages", sender:, messages: %>
5
5
  <% end %>
6
6
  </div>
7
7
 
8
- <%= render "reply", form: @form, conversation: %>
8
+ <%= render "decidim/messaging/conversations/reply", form: @form, conversation: %>
9
9
  <% end %>
@@ -0,0 +1 @@
1
+ <%= cell "decidim/member", Decidim::ParticipatorySpace::MemberPresenter.new(member) %>
@@ -13,7 +13,7 @@
13
13
  <% Decidim::Paginable::OPTIONS.each do |per_page_option| %>
14
14
  <li role="presentation">
15
15
  <%= link_to per_page_option,
16
- url_for(params.to_unsafe_h.merge(page: nil, per_page: per_page_option)),
16
+ url_for(params.to_unsafe_h.except("locale", :locale).merge(page: nil, per_page: per_page_option)),
17
17
  data: { per_page_option: },
18
18
  class: "dropdown__item",
19
19
  title: t("decidim.shared.results_per_page.title"),
@@ -6,6 +6,6 @@
6
6
  </button>
7
7
 
8
8
  <div id="panel-dropdown-menu-<%= id %>">
9
- <%= form.dropdown_label(collection, method, check_boxes_tree_id:, parent_id: nil) %>
9
+ <%= form.dropdown_label(collection, method, name:, check_boxes_tree_id:, parent_id: nil) %>
10
10
  </div>
11
11
  </div>
@@ -7,7 +7,7 @@
7
7
  <% end %>
8
8
 
9
9
  <% if is_blank_root %>
10
- <%= hidden_field_tag "#{form.object_name}[#{method}][]", "", id: "#{form.options[:namespace] rescue "default"}_filter_#{check_boxes_tree_id}_all" %>
10
+ <%= hidden_field_tag "#{form.object_name}#{name}[]", "", id: "#{form.options[:namespace] rescue "default"}_filter_#{check_boxes_tree_id}_all" %>
11
11
  <% end %>
12
12
 
13
13
  <div class="filter">
@@ -22,7 +22,8 @@
22
22
  id: data_checkboxes_tree_id,
23
23
  namespace: form.options[:namespace],
24
24
  parent_id:,
25
- object: form.object
25
+ object: form.object,
26
+ name: "#{form.object_name}#{name}[]"
26
27
  ),
27
28
  leaf.value.to_s,
28
29
  nil
@@ -38,7 +39,7 @@
38
39
  <% if item.tree_node? && item.node.present? %>
39
40
  <% subitems_content = capture do %>
40
41
  <% item.node.each do |subitem| %>
41
- <%= form.dropdown_label(subitem, method, check_boxes_tree_id:, parent_id: data_checkboxes_tree_id || "") %>
42
+ <%= form.dropdown_label(subitem, method, name:, check_boxes_tree_id:, parent_id: data_checkboxes_tree_id || "") %>
42
43
  <% end %>
43
44
  <% end %>
44
45
 
@@ -2,9 +2,9 @@
2
2
 
3
3
  <p class="email-instructions">
4
4
  <% if @resource.invited_by.present? %>
5
- <%= t("devise.mailer.invitation_instructions.invited_you_as_private_user", invited_by: @resource.invited_by.name, application: organization_name(@resource.organization)) %>
5
+ <%= t("devise.mailer.invitation_instructions.invited_you_as_member", invited_by: @resource.invited_by.name, application: organization_name(@resource.organization)) %>
6
6
  <% else %>
7
- <%= t("devise.mailer.invitation_instructions.someone_invited_you_as_private_user", application: organization_name(@resource.organization)) %>
7
+ <%= t("devise.mailer.invitation_instructions.someone_invited_you_as_member", application: organization_name(@resource.organization)) %>
8
8
  <% end %>
9
9
  </p>
10
10
 
@@ -1,9 +1,9 @@
1
1
  <%= t("devise.mailer.invitation_instructions.hello", email: @resource.name) %>
2
2
 
3
3
  <% if @resource.invited_by.present? %>
4
- <%= t("devise.mailer.invitation_instructions.invited_you_as_private_user", invited_by: @resource.invited_by.name, application: organization_name(@resource.organization)) %>
4
+ <%= t("devise.mailer.invitation_instructions.invited_you_as_member", invited_by: @resource.invited_by.name, application: organization_name(@resource.organization)) %>
5
5
  <% else %>
6
- <%= t("devise.mailer.invitation_instructions.someone_invited_you_as_private_user", application: organization_name(@resource.organization)) %>
6
+ <%= t("devise.mailer.invitation_instructions.someone_invited_you_as_member", application: organization_name(@resource.organization)) %>
7
7
  <% end %>
8
8
 
9
9
  <%= accept_invitation_url(@resource, invitation_token: @token, host: @resource.organization.host) %>
@@ -1,7 +1,7 @@
1
1
  <%= csrf_meta_tags %>
2
2
 
3
- <% available_locales.each do |locale| %>
4
- <link rel="alternate" href="<%= current_url(request.parameters.merge(locale:)) %>" hreflang="<%= locale %>">
3
+ <% available_locales.excluding(current_locale).each do |locale| %>
4
+ <link rel="alternate" href="<%= canonical_url(request.url, locale) %>" hreflang="<%= locale %>">
5
5
  <% end %>
6
6
 
7
7
  <%= tag :meta, name: "viewport", content: "width=device-width, initial-scale=1.0" %>
@@ -12,7 +12,7 @@ end
12
12
 
13
13
  <div class="layout-container">
14
14
  <header <%= "class=with-admin-bar" if current_user && allowed_to?(:read, :admin_dashboard) %>>
15
- <div id="sticky-header-container" data-controller="sticky-header">
15
+ <div id="header-container">
16
16
  <%= render partial: "layouts/decidim/impersonation_warning" %>
17
17
  <%= render partial: "layouts/decidim/omnipresent_banner" %>
18
18
  <%= render partial: "layouts/decidim/offline_banner" %>
@@ -2,6 +2,5 @@
2
2
  <div class="main-footer__down">
3
3
  <%= render partial: "layouts/decidim/footer/main_legal" %>
4
4
  <div class="w-full md:w-auto md:ml-auto"></div>
5
- <%= render partial: "layouts/decidim/footer/main_language_chooser" %>
6
5
  </div>
7
6
  </div>
@@ -14,6 +14,5 @@
14
14
  <nav class="w-full md:w-auto md:ml-auto" role="navigation" aria-label="<%= t("layouts.decidim.footer.social_media") %>">
15
15
  <%= render partial: "layouts/decidim/footer/main_social_media_links" %>
16
16
  </nav>
17
- <%= render partial: "layouts/decidim/footer/main_language_chooser" %>
18
17
  </div>
19
18
  </div>
@@ -9,11 +9,14 @@
9
9
  <% end %>
10
10
  </div>
11
11
 
12
+ <div class="main-bar__language-chooser-desktop focus-mode">
13
+ <%= render partial: "layouts/decidim/header/main_language_chooser", locals: { id: "dropdown-menu-language-chooser-desktop" } %>
14
+ </div>
15
+
12
16
  <div class="main-bar__back-button lg:hidden">
13
17
  <%= link_to(
14
18
  content_for(:focus_mode_return_path),
15
19
  class: "main-bar__links-desktop__item",
16
- type: :button,
17
20
  "aria-label": t("layouts.decidim.header.back")
18
21
  ) do %>
19
22
  <span class="flex items-center gap-1">
@@ -16,14 +16,23 @@
16
16
  <% if current_user&.ephemeral? %>
17
17
  <%= render partial: "layouts/decidim/header/close_ephemeral_session" %>
18
18
  <% else %>
19
- <div role="search" class="main-bar__search">
20
- <%= render partial: "layouts/decidim/header/main_search" %>
21
- </div>
22
- <nav role="navigation" class="main-bar__links-desktop">
23
- <%= render partial: "layouts/decidim/header/main_links_desktop" %>
24
- </nav>
25
- <div class="main-bar__menu-mobile">
26
- <%= render partial: "layouts/decidim/header/main_menu_mobile" %>
19
+ <div class="flex lg:justify-between lg:gap-x-10">
20
+ <div class="hidden lg:flex lg:gap-x-8 border-r border-gray-6 pr-10">
21
+ <div role="search" class="main-bar__search">
22
+ <%= render partial: "layouts/decidim/header/main_search" %>
23
+ </div>
24
+
25
+ <div class="main-bar__language-chooser-desktop">
26
+ <%= render partial: "layouts/decidim/header/main_language_chooser", locals: { id: "dropdown-menu-language-chooser-desktop" } %>
27
+ </div>
28
+ </div>
29
+
30
+ <nav role="navigation" aria-label="<%= t("layouts.decidim.header.user_menu") %>" class="main-bar__links-desktop md:flex md:gap-x-8">
31
+ <%= render partial: "layouts/decidim/header/main_links_desktop" %>
32
+ </nav>
33
+ <div class="main-bar__menu-mobile">
34
+ <%= render partial: "layouts/decidim/header/main_menu_mobile" %>
35
+ </div>
27
36
  </div>
28
37
  <%= render partial: "layouts/decidim/header/main_links_mobile_account" if current_user %>
29
38
  <% end %>
@@ -0,0 +1,24 @@
1
+ <% if available_locales.length > 1 %>
2
+ <div class="main-bar__language-chooser">
3
+ <button id="trigger-<%= id %>" data-controller="dropdown" data-target="<%= id %>" class="main-bar__language-chooser-trigger">
4
+ <span class="main-bar__language-chooser-holder">
5
+ <%= icon "global-line" %>
6
+ <span><%= t("name", scope: "locale" ) %></span>
7
+ </span>
8
+ <%= icon "arrow-down-s-line" %>
9
+ <span class="sr-only" lang="<%= locale %>">
10
+ <%= t("layouts.decidim.language_chooser.choose_language") %>
11
+ </span>
12
+ </button>
13
+
14
+ <div id="<%= id %>" aria-hidden="true">
15
+ <ul class="main-bar__language-chooser-list" role="menu">
16
+ <% available_locales.each do |locale| %>
17
+ <li class="<%= I18n.locale.to_s == locale ? "main-bar__language-chooser-item-active" : "main-bar__language-chooser-item" %>" role="presentation">
18
+ <%= link_to locale_name(locale), decidim.locale_path(locale:), method: :post, role: "menuitem", lang: locale, class: "p-2 w-full block" %>
19
+ </li>
20
+ <% end %>
21
+ </ul>
22
+ </div>
23
+ </div>
24
+ <% end %>
@@ -1,61 +1,61 @@
1
- <div>
2
- <%= link_to decidim.pages_path, class: "main-bar__links-desktop__item", "aria-label": t("decidim.menu.help") do %>
3
- <%= icon "question-line" %><span><%= t("decidim.menu.help") %></span>
4
- <% end %>
5
- </div>
6
- <div class="main-bar__links-desktop__item-wrapper">
7
- <div>
8
- <% if Decidim.module_installed?(:meetings) %>
9
- <%= link_to Decidim::Meetings::DirectoryEngine.routes.url_helpers.root_path, class: "main-bar__links-desktop__item", "aria-label": t("decidim.pages.home.extended.meetings") do %>
10
- <%= icon "road-map-line" %><span><%= t("decidim.pages.home.extended.meetings") %></span>
1
+ <div class="flex items-center gap-x-8">
2
+ <% if !current_user %>
3
+ <div>
4
+ <%= link_to decidim.new_user_session_path, class: "main-bar__links-desktop__item", "aria-label": t("layouts.decidim.header.log_in") do %>
5
+ <%= icon "user-line" %><span><%= t("layouts.decidim.header.log_in") %></span>
11
6
  <% end %>
12
- <% end %>
13
- </div>
14
- <div>
15
- <%= link_to decidim.last_activities_path, class: "main-bar__links-desktop__item", "aria-label": t("decidim.profiles.show.activity") do %>
16
- <%= icon "bubble-chart-line" %><span><%= t("decidim.profiles.show.activity") %></span>
17
- <% end %>
18
- </div>
19
- </div>
20
-
21
- <% if !current_user %>
22
- <div>
23
- <%= link_to decidim.new_user_session_path, class: "main-bar__links-desktop__item", "aria-label": t("layouts.decidim.header.log_in") do %>
24
- <%= icon "user-line" %><span><%= t("layouts.decidim.header.log_in") %></span>
25
- <% end %>
26
- </div>
27
- <% else %>
28
- <div class="main-bar__dropdown-container">
29
- <button id="trigger-dropdown-account" class="main-bar__dropdown-trigger" data-controller="dropdown" data-target="dropdown-menu-account">
30
- <% unread_data = current_user_unread_data %>
31
- <% if unread_data[:unread_items] %>
32
- <%= content_tag :span, "", class: "main-bar__notification", data: unread_data %>
33
- <% if unread_data[:unread_notifications] %>
34
- <%= content_tag :span, t("layouts.decidim.user_menu.unread_notifications"), class: "sr-only" %>
35
- <% end %>
36
- <% if unread_data[:unread_conversations] %>
37
- <%= content_tag :span, t("layouts.decidim.user_menu.unread_conversations"), class: "sr-only" %>
7
+ </div>
8
+ <% else %>
9
+ <div class="main-bar__dropdown-container">
10
+ <button id="trigger-dropdown-account" class="main-bar__dropdown-trigger" data-controller="dropdown" data-target="dropdown-menu-account">
11
+ <% unread_data = current_user_unread_data %>
12
+ <% if unread_data[:unread_items] %>
13
+ <%= content_tag :span, "", class: "main-bar__notification", data: unread_data %>
14
+ <% if unread_data[:unread_notifications] %>
15
+ <%= content_tag :span, t("layouts.decidim.user_menu.unread_notifications"), class: "sr-only" %>
16
+ <% end %>
17
+ <% if unread_data[:unread_conversations] %>
18
+ <%= content_tag :span, t("layouts.decidim.user_menu.unread_conversations"), class: "sr-only" %>
19
+ <% end %>
38
20
  <% end %>
39
- <% end %>
40
- <% if current_user.avatar.attached? %>
41
- <span class="main-bar__avatar">
42
- <span>
43
- <%= image_tag(
44
- current_user.attached_uploader(:avatar).variant_url(:thumb),
45
- alt: t("decidim.author.avatar", name: decidim_sanitize(current_user.avatar.name))
46
- ) %>
21
+ <% if current_user.avatar.attached? %>
22
+ <span class="main-bar__avatar">
23
+ <span>
24
+ <%= image_tag(
25
+ current_user.attached_uploader(:avatar).variant_url(:thumb),
26
+ alt: t("decidim.author.avatar", name: decidim_sanitize(current_user.avatar.name))
27
+ ) %>
28
+ </span>
47
29
  </span>
48
- </span>
49
- <% else %>
50
- <span class="main-bar__links-desktop__item-account">
51
- <%= text_initials(current_user.name) %>
52
- </span>
53
- <% end %>
54
- </button>
55
- <div id="dropdown-menu-account" aria-hidden="true">
56
- <ul class="dropdown dropdown__bottom main-bar__dropdown">
57
- <%= render partial: "layouts/decidim/header/main_links_dropdown", locals: { unread_data: } %>
58
- </ul>
30
+ <% else %>
31
+ <span class="main-bar__links-desktop__item-account">
32
+ <%= text_initials(current_user.name) %>
33
+ </span>
34
+ <% end %>
35
+ </button>
36
+ <div id="dropdown-menu-account" aria-hidden="true" data-controller="assign-role" data-role="dialog">
37
+ <ul class="dropdown dropdown__bottom main-bar__dropdown">
38
+ <%= render partial: "layouts/decidim/header/main_links_dropdown", locals: { unread_data: } %>
39
+ </ul>
40
+ </div>
41
+ </div>
42
+ <% end %>
43
+ <button id="main-dropdown-summary-desktop" class="main-bar__links-desktop__trigger"
44
+ data-controller="main-menu"
45
+ data-close-button="main-dropdown-summary-desktop-close"
46
+ data-target="dropdown-menu-main-desktop" aria-expanded="false">
47
+ <%= icon "menu-line" %><span><%= t("menu", scope: "decidim.admin.titles") %></span>
48
+ </button>
49
+
50
+ <div id="dropdown-menu-main-desktop" class="main-bar__links-desktop__dropdown main-bar__links-desktop__dropdown-before" aria-hidden="true">
51
+ <div id="breadcrumb-main-dropdown-desktop" class="menu-bar__main-dropdown menu-bar__dropdown-desktop">
52
+ <button id="main-dropdown-summary-desktop-close" class="main-bar__links-desktop__trigger">
53
+ <%= icon "close-line" %><span><%= t("close", scope: "layouts.decidim.header") %></span>
54
+ </button>
55
+ <%= breadcrumb_root_menu.render %>
56
+ <div class="menu-bar__main-dropdown__left">
57
+ <%= cell("decidim/highlighted_participatory_process", menu_highlighted_participatory_process) %>
58
+ </div>
59
59
  </div>
60
60
  </div>
61
- <% end %>
61
+ </div>
@@ -1,4 +1,4 @@
1
- <div id="dropdown-menu-account-mobile" class="main-bar__links-mobile__account" aria-hidden="true">
1
+ <div id="dropdown-menu-account-mobile" class="main-bar__links-mobile__account" aria-hidden="true" data-controller="assign-role" data-role="dialog">
2
2
  <div class="main-bar">
3
3
  <div class="main-bar__logo">
4
4
  <div class="main-bar__logo-desktop">
@@ -10,7 +10,7 @@
10
10
  </div>
11
11
 
12
12
  <div>
13
- <div class="main-bar__links-mobile__trigger" tabindex="0" onclick="document.querySelector('#dropdown-trigger-links-mobile').click();document.querySelector('#dropdown-menu-account-mobile').removeAttribute('aria-modal')">
13
+ <div id="dropdown-trigger-links-mobile-close" class="main-bar__links-mobile__trigger" tabindex="0">
14
14
  <%= icon "close-line" %>
15
15
  <p class="sr-only"><%= t("close", scope: "decidim.shared.flag_modal") %></p>
16
16
  </div>
@@ -1,5 +1,7 @@
1
1
  <% if current_user %>
2
- <button id="dropdown-trigger-links-mobile" class="main-bar__links-mobile__item" data-controller="dropdown" data-target="dropdown-menu-account-mobile">
2
+ <button id="dropdown-trigger-links-mobile" class="main-bar__links-mobile__item" data-controller="main-menu"
3
+ data-target="dropdown-menu-account-mobile"
4
+ data-close-button="dropdown-trigger-links-mobile-close">
3
5
  <% if current_user.notifications.any? %>
4
6
  <span class="main-bar__notification"></span>
5
7
  <% end %>
@@ -1,12 +1,25 @@
1
1
  <button id="main-dropdown-summary-mobile" class="main-bar__links-mobile__trigger p-0"
2
- data-controller="dropdown"
3
- data-target="dropdown-menu-main-mobile">
4
- <%= icon "menu-line" %><span class="sr-only"><%= t("main_menu", scope: "layouts.decidim.header") %></span>
5
- <%= icon "close-line" %>
2
+ data-controller="main-menu"
3
+ data-target="dropdown-menu-main-mobile"
4
+ data-close-button="main-dropdown-summary-mobile"
5
+ aria-expanded="false">
6
+ <%= icon "menu-line" %><span><%= t("menu", scope: "decidim.admin.titles") %></span>
7
+ <%= icon "close-line" %><span><%= t("close", scope: "layouts.decidim.header") %></span>
6
8
  </button>
9
+ <div aria-hidden="true" class="md:hidden border-r border-gray-6 h-full"></div>
7
10
 
8
11
  <div id="dropdown-menu-main-mobile" class="main-bar__links-mobile__dropdown main-bar__links-mobile__dropdown-before" aria-hidden="true">
9
- <%= render partial: "layouts/decidim/header/menu_breadcrumb_main_dropdown_mobile", locals: { id: "breadcrumb-main-dropdown-mobile" } %>
12
+ <div id="breadcrumb-main-dropdown-mobile" class="menu-bar__main-dropdown">
13
+ <div class="menu-bar__main-dropdown__top">
14
+ <div class="mb-8">
15
+ <%= render partial: "layouts/decidim/header/menu_form_search_mobile" %>
16
+ </div>
17
+ <%= mobile_breadcrumb_root_menu.render %>
18
+ <div class="menu-bar__language-chooser-mobile">
19
+ <%= render partial: "layouts/decidim/header/main_language_chooser", locals: { id: "dropdown-menu-language-chooser-mobile" } %>
20
+ </div>
21
+ </div>
22
+ </div>
10
23
  </div>
11
24
 
12
25
  <%= render partial: "layouts/decidim/header/main_links_mobile_item_account" %>
@@ -1,4 +1,7 @@
1
1
  <%= form_tag(decidim.search_path, method: :get, id: "form-search_topbar") do %>
2
+ <button type="submit" aria-label="<%= t("decidim.search.term_input_placeholder") %>">
3
+ <%= icon "search-line" %>
4
+ </button>
2
5
  <%= text_field_tag(
3
6
  :term,
4
7
  nil,
@@ -9,7 +12,4 @@
9
12
  title: t("decidim.search.term_input_placeholder"),
10
13
  "aria-label": t("decidim.search.term_input_placeholder")
11
14
  ) %>
12
- <button type="submit" aria-label="<%= t("decidim.search.term_input_placeholder") %>">
13
- <%= icon "search-line" %>
14
- </button>
15
15
  <% end %>
@@ -2,9 +2,9 @@
2
2
  <div class="menu-bar">
3
3
 
4
4
  <%# secondary dropdown only desktop %>
5
- <div class="menu-bar__breadcrumb-desktop">
5
+ <nav class="menu-bar__breadcrumb-desktop">
6
6
  <%= render partial: "layouts/decidim/header/menu_breadcrumb_desktop" %>
7
- </div>
7
+ </nav>
8
8
  <% if content_for?(:participatory_space_actions) %>
9
9
  <div class="menu-bar__actions">
10
10
  <%= content_for :participatory_space_actions %>
@@ -12,9 +12,9 @@
12
12
  <% end %>
13
13
 
14
14
  <%# secondary dropdown mobile-tablet %>
15
- <div class="menu-bar__breadcrumb-mobile">
16
- <%= render partial: "layouts/decidim/header/menu_breadcrumb_mobile_tablet" %>
17
- </div>
15
+ <nav class="menu-bar__breadcrumb-mobile">
16
+ <%= render partial: "layouts/decidim/header/menu_breadcrumb_mobile" %>
17
+ </nav>
18
18
 
19
19
  </div>
20
20
  </div>