decidim-admin 0.30.2 → 0.31.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 (255) hide show
  1. checksums.yaml +4 -4
  2. data/app/commands/decidim/admin/update_organization.rb +18 -3
  3. data/app/controllers/concerns/decidim/admin/content_blocks/landing_page_content_blocks.rb +1 -1
  4. data/app/controllers/concerns/decidim/admin/filterable.rb +1 -1
  5. data/app/controllers/decidim/admin/area_types_controller.rb +2 -2
  6. data/app/controllers/decidim/admin/areas_controller.rb +2 -2
  7. data/app/controllers/decidim/admin/block_user_controller.rb +2 -2
  8. data/app/controllers/decidim/admin/component_permissions_controller.rb +1 -1
  9. data/app/controllers/decidim/admin/components_controller.rb +2 -2
  10. data/app/controllers/decidim/admin/concerns/has_attachment_collections.rb +2 -2
  11. data/app/controllers/decidim/admin/concerns/has_attachments.rb +2 -2
  12. data/app/controllers/decidim/admin/concerns/has_private_users.rb +3 -3
  13. data/app/controllers/decidim/admin/concerns/has_private_users_csv_import.rb +1 -1
  14. data/app/controllers/decidim/admin/conflicts_controller.rb +1 -1
  15. data/app/controllers/decidim/admin/dashboard_controller.rb +0 -9
  16. data/app/controllers/decidim/admin/impersonations_controller.rb +1 -1
  17. data/app/controllers/decidim/admin/imports_controller.rb +1 -1
  18. data/app/controllers/decidim/admin/managed_users/promotions_controller.rb +1 -1
  19. data/app/controllers/decidim/admin/newsletters_controller.rb +4 -4
  20. data/app/controllers/decidim/admin/organization_appearance_controller.rb +1 -3
  21. data/app/controllers/decidim/admin/organization_controller.rb +3 -5
  22. data/app/controllers/decidim/admin/organization_external_domain_allowlist_controller.rb +1 -1
  23. data/app/controllers/decidim/admin/organization_homepage_controller.rb +4 -0
  24. data/app/controllers/decidim/admin/participatory_space/user_role_controller.rb +2 -2
  25. data/app/controllers/decidim/admin/reminders_controller.rb +1 -1
  26. data/app/controllers/decidim/admin/resource_permissions_controller.rb +1 -1
  27. data/app/controllers/decidim/admin/scope_types_controller.rb +2 -2
  28. data/app/controllers/decidim/admin/scopes_controller.rb +2 -2
  29. data/app/controllers/decidim/admin/share_tokens_controller.rb +2 -2
  30. data/app/controllers/decidim/admin/static_page_topics_controller.rb +2 -2
  31. data/app/controllers/decidim/admin/static_pages_controller.rb +2 -2
  32. data/app/controllers/decidim/admin/statistics_controller.rb +34 -0
  33. data/app/controllers/decidim/admin/taxonomies_controller.rb +2 -2
  34. data/app/controllers/decidim/admin/taxonomy_filters_controller.rb +2 -2
  35. data/app/controllers/decidim/admin/taxonomy_items_controller.rb +2 -2
  36. data/app/controllers/decidim/admin/users_controller.rb +1 -1
  37. data/app/forms/decidim/admin/block_user_form.rb +1 -1
  38. data/app/forms/decidim/admin/block_users_form.rb +1 -1
  39. data/app/forms/decidim/admin/organization_form.rb +35 -6
  40. data/app/helpers/decidim/admin/filterable_helper.rb +27 -8
  41. data/app/helpers/decidim/admin/icon_link_helper.rb +2 -3
  42. data/app/helpers/decidim/admin/icon_with_tooltip_helper.rb +1 -2
  43. data/app/helpers/decidim/admin/imports_helper.rb +0 -5
  44. data/app/helpers/decidim/admin/menu_helper.rb +3 -2
  45. data/app/helpers/decidim/admin/moderations/reports_helper.rb +1 -1
  46. data/app/helpers/decidim/admin/resource_permissions_helper.rb +13 -13
  47. data/app/helpers/decidim/admin/settings_helper.rb +11 -3
  48. data/app/jobs/decidim/admin/newsletter_job.rb +1 -0
  49. data/app/packs/entrypoints/decidim_admin.js +2 -3
  50. data/app/packs/entrypoints/decidim_admin.scss +1 -1
  51. data/app/packs/entrypoints/decidim_admin_overrides.scss +1 -1
  52. data/app/packs/src/decidim/admin/admin_autocomplete.js +2 -2
  53. data/app/packs/src/decidim/admin/application.js +11 -10
  54. data/app/packs/src/decidim/admin/budget_rule_toggler.component.js +84 -34
  55. data/app/packs/src/decidim/admin/controllers/slug/controller.js +25 -0
  56. data/app/packs/src/decidim/admin/controllers/slug/slug.test.js +239 -0
  57. data/app/packs/src/decidim/admin/css_preview.js +1 -1
  58. data/app/packs/src/decidim/admin/draggable-list.js +1 -1
  59. data/app/packs/src/decidim/admin/draggable-table.js +1 -1
  60. data/app/packs/src/decidim/admin/dynamic_fields.component.js +13 -12
  61. data/app/packs/src/decidim/admin/external_domain_allowlist.js +1 -1
  62. data/app/packs/src/decidim/admin/form.js +21 -4
  63. data/app/packs/src/decidim/admin/global_moderations.js +2 -2
  64. data/app/packs/src/decidim/admin/managed_moderated_users.js +2 -2
  65. data/app/packs/src/decidim/admin/moderations.js +1 -1
  66. data/app/packs/src/decidim/admin/newsletters.js +1 -1
  67. data/app/packs/src/decidim/admin/officializations.js +1 -1
  68. data/app/packs/src/decidim/admin/participatory_space_search.js +2 -2
  69. data/app/packs/src/decidim/admin/proposal_infinite_edit.js +1 -1
  70. data/app/packs/src/decidim/admin/resources_permissions.js +1 -1
  71. data/app/packs/src/decidim/admin/sortable.js +1 -1
  72. data/app/packs/src/decidim/admin/sync_radio_buttons.js +1 -1
  73. data/app/packs/src/decidim/admin/tab_focus.js +1 -1
  74. data/app/packs/src/decidim/admin/text_copy.js +1 -1
  75. data/app/packs/src/decidim/admin/triadic_color_picker.js +1 -1
  76. data/app/packs/stylesheets/decidim/admin/_datepicker.scss +2 -2
  77. data/app/packs/stylesheets/decidim/admin/_dropdown.scss +12 -2
  78. data/app/packs/stylesheets/decidim/admin/_filters.scss +1 -57
  79. data/app/packs/stylesheets/decidim/admin/_forms.scss +1 -10
  80. data/app/packs/stylesheets/decidim/admin/_item_edit.scss +2 -10
  81. data/app/packs/stylesheets/decidim/admin/_item_show.scss +1 -5
  82. data/app/packs/stylesheets/decidim/admin/_legacy_foundation.scss +0 -412
  83. data/app/packs/stylesheets/decidim/admin/_main-nav.scss +75 -3
  84. data/app/packs/stylesheets/decidim/admin/_secondary-nav.scss +6 -10
  85. data/app/packs/stylesheets/decidim/admin/_select_picker.scss +1 -1
  86. data/app/packs/stylesheets/decidim/admin/_sidebar-menu.scss +2 -2
  87. data/app/packs/stylesheets/decidim/admin/_table-list.scss +25 -7
  88. data/app/packs/stylesheets/decidim/admin/_tabs.scss +4 -0
  89. data/app/packs/stylesheets/decidim/admin/_taxonomies.scss +6 -2
  90. data/app/packs/stylesheets/decidim/admin/application.scss +28 -29
  91. data/app/permissions/decidim/admin/permissions.rb +17 -5
  92. data/app/presenters/decidim/admin/dashboard_statistic_charts_presenter.rb +18 -0
  93. data/app/queries/decidim/admin/user_filter.rb +3 -3
  94. data/app/views/decidim/admin/area_types/index.html.erb +34 -11
  95. data/app/views/decidim/admin/areas/index.html.erb +32 -12
  96. data/app/views/decidim/admin/attachment_collections/index.html.erb +42 -14
  97. data/app/views/decidim/admin/attachments/index.html.erb +32 -13
  98. data/app/views/decidim/admin/block_user/bulk_new.html.erb +1 -1
  99. data/app/views/decidim/admin/block_user/new.html.erb +1 -1
  100. data/app/views/decidim/admin/components/_actions.html.erb +114 -54
  101. data/app/views/decidim/admin/components/_component_row.html.erb +5 -5
  102. data/app/views/decidim/admin/components/_components_table.html.erb +1 -1
  103. data/app/views/decidim/admin/components/_form.html.erb +4 -4
  104. data/app/views/decidim/admin/components/index.html.erb +12 -13
  105. data/app/views/decidim/admin/dashboard/show.html.erb +9 -21
  106. data/app/views/decidim/admin/exports/_dropdown.html.erb +16 -14
  107. data/app/views/decidim/admin/help_sections/_form.html.erb +1 -1
  108. data/app/views/decidim/admin/impersonatable_users/index.html.erb +68 -33
  109. data/app/views/decidim/admin/imports/_dropdown.html.erb +13 -11
  110. data/app/views/decidim/admin/imports/new.html.erb +13 -12
  111. data/app/views/decidim/admin/moderated_users/bulk_actions/_dropdown.html.erb +29 -32
  112. data/app/views/decidim/admin/moderated_users/index.html.erb +61 -21
  113. data/app/views/decidim/admin/moderations/_moderation-tr.html.erb +87 -32
  114. data/app/views/decidim/admin/moderations/_report.html.erb +2 -4
  115. data/app/views/decidim/admin/moderations/bulk_actions/_dropdown.html.erb +30 -34
  116. data/app/views/decidim/admin/moderations/index.html.erb +1 -1
  117. data/app/views/decidim/admin/moderations/reports/index.html.erb +1 -2
  118. data/app/views/decidim/admin/newsletters/index.html.erb +64 -21
  119. data/app/views/decidim/admin/officializations/index.html.erb +91 -32
  120. data/app/views/decidim/admin/organization/_form.html.erb +6 -92
  121. data/app/views/decidim/admin/organization/edit.html.erb +1 -5
  122. data/app/views/decidim/admin/organization/form/_admin_terms_of_service.html.erb +15 -0
  123. data/app/views/decidim/admin/organization/form/_basic_configuration.html.erb +31 -0
  124. data/app/views/decidim/admin/{organization_appearance → organization}/form/_colors.html.erb +9 -9
  125. data/app/views/decidim/admin/organization/form/_extra_features.html.erb +84 -0
  126. data/app/views/decidim/admin/{organization_appearance/form/_images.html.erb → organization/form/_logos.html.erb} +4 -4
  127. data/app/views/decidim/admin/organization/form/_welcome_notification.html.erb +25 -0
  128. data/app/views/decidim/admin/organization_external_domain_allowlist/_external_domain.html.erb +8 -6
  129. data/app/views/decidim/admin/participatory_space_private_users/index.html.erb +49 -22
  130. data/app/views/decidim/admin/resource_permissions/edit.html.erb +1 -1
  131. data/app/views/decidim/admin/scope_types/index.html.erb +31 -12
  132. data/app/views/decidim/admin/scopes/index.html.erb +40 -13
  133. data/app/views/decidim/admin/share_tokens/_form.html.erb +1 -1
  134. data/app/views/decidim/admin/share_tokens/edit.html.erb +1 -1
  135. data/app/views/decidim/admin/share_tokens/index.html.erb +69 -12
  136. data/app/views/decidim/admin/share_tokens/new.html.erb +1 -1
  137. data/app/views/decidim/admin/shared/_filters.html.erb +8 -10
  138. data/app/views/decidim/admin/shared/landing_page/_content_blocks.html.erb +14 -11
  139. data/app/views/decidim/admin/shared/landing_page_content_blocks/edit.html.erb +2 -4
  140. data/app/views/decidim/admin/static_page_topics/index.html.erb +31 -10
  141. data/app/views/decidim/admin/static_pages/_form.html.erb +1 -1
  142. data/app/views/decidim/admin/static_pages/_topic.html.erb +46 -16
  143. data/app/views/decidim/admin/statistics/_statistics.html.erb +13 -0
  144. data/app/views/decidim/admin/statistics/index.html.erb +6 -0
  145. data/app/views/decidim/admin/taxonomies/_form.html.erb +1 -1
  146. data/app/views/decidim/admin/taxonomies/_row.html.erb +24 -6
  147. data/app/views/decidim/admin/taxonomies/_table.html.erb +2 -2
  148. data/app/views/decidim/admin/taxonomies/_taxonomy_actions.html.erb +48 -15
  149. data/app/views/decidim/admin/taxonomies/edit.html.erb +10 -0
  150. data/app/views/decidim/admin/taxonomy_filters/_form.html.erb +1 -1
  151. data/app/views/decidim/admin/taxonomy_filters/_table.html.erb +52 -15
  152. data/app/views/decidim/admin/taxonomy_filters/new.html.erb +1 -1
  153. data/app/views/decidim/admin/taxonomy_filters_selector/_component_table.html.erb +38 -23
  154. data/app/views/decidim/admin/taxonomy_items/_form.html.erb +1 -1
  155. data/app/views/decidim/admin/users/index.html.erb +48 -24
  156. data/app/views/layouts/decidim/admin/_application.html.erb +3 -6
  157. data/app/views/layouts/decidim/admin/_header.html.erb +3 -1
  158. data/app/views/layouts/decidim/admin/_js_configuration.html.erb +11 -12
  159. data/app/views/layouts/decidim/admin/_sidebar_menu.html.erb +1 -1
  160. data/app/views/layouts/decidim/admin/_title_bar.html.erb +4 -4
  161. data/app/views/layouts/decidim/admin/_title_bar_responsive.html.erb +4 -4
  162. data/app/views/layouts/decidim/admin/insights.html.erb +6 -0
  163. data/config/assets.rb +2 -2
  164. data/config/locales/ar.yml +0 -90
  165. data/config/locales/bg.yml +1 -110
  166. data/config/locales/bs-BA.yml +0 -44
  167. data/config/locales/ca-IT.yml +59 -117
  168. data/config/locales/ca.yml +59 -117
  169. data/config/locales/cs.yml +51 -119
  170. data/config/locales/de.yml +60 -118
  171. data/config/locales/el.yml +2 -102
  172. data/config/locales/en.yml +61 -119
  173. data/config/locales/eo.yml +0 -4
  174. data/config/locales/es-MX.yml +61 -119
  175. data/config/locales/es-PY.yml +61 -119
  176. data/config/locales/es.yml +61 -119
  177. data/config/locales/eu.yml +61 -119
  178. data/config/locales/fi-plain.yml +60 -118
  179. data/config/locales/fi.yml +60 -118
  180. data/config/locales/fr-CA.yml +61 -119
  181. data/config/locales/fr.yml +61 -119
  182. data/config/locales/ga-IE.yml +1 -34
  183. data/config/locales/gl.yml +0 -95
  184. data/config/locales/he-IL.yml +0 -8
  185. data/config/locales/hu.yml +2 -105
  186. data/config/locales/id-ID.yml +0 -62
  187. data/config/locales/is-IS.yml +1 -36
  188. data/config/locales/it.yml +35 -116
  189. data/config/locales/ja.yml +60 -118
  190. data/config/locales/kaa.yml +0 -12
  191. data/config/locales/ko.yml +0 -75
  192. data/config/locales/lb.yml +2 -95
  193. data/config/locales/lt.yml +1 -103
  194. data/config/locales/lv.yml +2 -74
  195. data/config/locales/nl.yml +2 -96
  196. data/config/locales/no.yml +2 -96
  197. data/config/locales/pl.yml +2 -108
  198. data/config/locales/pt-BR.yml +6 -110
  199. data/config/locales/pt.yml +2 -96
  200. data/config/locales/ro-RO.yml +10 -102
  201. data/config/locales/ru.yml +2 -54
  202. data/config/locales/sk.yml +2 -72
  203. data/config/locales/sl.yml +1 -18
  204. data/config/locales/sq-AL.yml +0 -45
  205. data/config/locales/sr-CS.yml +1 -44
  206. data/config/locales/sv.yml +58 -119
  207. data/config/locales/th-TH.yml +0 -10
  208. data/config/locales/tr-TR.yml +5 -88
  209. data/config/locales/uk.yml +1 -45
  210. data/config/locales/val-ES.yml +0 -1
  211. data/config/locales/zh-CN.yml +0 -72
  212. data/config/locales/zh-TW.yml +1 -102
  213. data/config/routes.rb +1 -12
  214. data/lib/decidim/admin/engine.rb +5 -1
  215. data/lib/decidim/admin/form_builder.rb +1 -1
  216. data/lib/decidim/admin/menu.rb +32 -16
  217. data/lib/decidim/admin/test/filterable_examples.rb +8 -18
  218. data/lib/decidim/admin/test/invite_participatory_space_admins_shared_examples.rb +4 -4
  219. data/lib/decidim/admin/test/invite_participatory_space_collaborators_shared_examples.rb +2 -2
  220. data/lib/decidim/admin/test/invite_participatory_space_moderators_shared_examples.rb +9 -6
  221. data/lib/decidim/admin/test/invite_participatory_space_users_shared_context.rb +1 -0
  222. data/lib/decidim/admin/test/manage_attachment_collections_examples.rb +5 -1
  223. data/lib/decidim/admin/test/manage_attachments_examples.rb +5 -1
  224. data/lib/decidim/admin/test/manage_component_permissions_examples.rb +31 -4
  225. data/lib/decidim/admin/test/manage_moderations_examples.rb +12 -5
  226. data/lib/decidim/admin/test/manage_participatory_space_publications_examples.rb +12 -6
  227. data/lib/decidim/admin/test/manage_resource_soft_deletion_examples.rb +19 -4
  228. data/lib/decidim/admin/test/manage_taxonomy_filters_examples.rb +28 -8
  229. data/lib/decidim/admin/version.rb +1 -1
  230. metadata +22 -35
  231. data/app/commands/decidim/admin/process_user_group_verification_csv.rb +0 -44
  232. data/app/commands/decidim/admin/reject_user_group.rb +0 -42
  233. data/app/commands/decidim/admin/update_organization_appearance.rb +0 -39
  234. data/app/commands/decidim/admin/update_user_groups.rb +0 -44
  235. data/app/commands/decidim/admin/verify_user_group.rb +0 -43
  236. data/app/controllers/concerns/decidim/admin/user_groups/filterable.rb +0 -45
  237. data/app/controllers/concerns/decidim/admin/user_groups.rb +0 -24
  238. data/app/controllers/decidim/admin/metrics_controller.rb +0 -23
  239. data/app/controllers/decidim/admin/user_groups_controller.rb +0 -76
  240. data/app/controllers/decidim/admin/user_groups_csv_verifications_controller.rb +0 -36
  241. data/app/forms/decidim/admin/organization_appearance_form.rb +0 -88
  242. data/app/forms/decidim/admin/user_group_csv_verification_form.rb +0 -25
  243. data/app/jobs/decidim/admin/verify_user_group_from_csv_job.rb +0 -30
  244. data/app/packs/src/decidim/admin/welcome_notification.js +0 -32
  245. data/app/packs/stylesheets/decidim/admin/_bulk_actions.scss +0 -16
  246. data/app/presenters/decidim/admin/dashboard_metric_charts_presenter.rb +0 -33
  247. data/app/queries/decidim/admin/user_groups_evaluation.rb +0 -56
  248. data/app/views/decidim/admin/metrics/_metrics.html.erb +0 -16
  249. data/app/views/decidim/admin/metrics/index.html.erb +0 -7
  250. data/app/views/decidim/admin/organization_appearance/_form.html.erb +0 -100
  251. data/app/views/decidim/admin/organization_appearance/edit.html.erb +0 -18
  252. data/app/views/decidim/admin/organization_appearance/form/_header_snippets.html.erb +0 -17
  253. data/app/views/decidim/admin/user_groups/index.html.erb +0 -68
  254. data/app/views/decidim/admin/user_groups_csv_verifications/new.html.erb +0 -31
  255. /data/app/views/decidim/admin/{organization_appearance → organization}/form/_minimap.html.erb +0 -0
@@ -11,25 +11,44 @@ module Decidim
11
11
  mimic :organization
12
12
 
13
13
  translatable_attribute :name, String
14
+ translatable_attribute :description, Decidim::Attributes::RichText
14
15
  attribute :reference_prefix, String
15
16
  attribute :time_zone, String
16
- attribute :twitter_handler, String
17
- attribute :facebook_handler, String
18
- attribute :instagram_handler, String
19
- attribute :youtube_handler, String
20
- attribute :github_handler, String
21
17
  attribute :default_locale, String
22
18
  attribute :badges_enabled, Boolean
23
- attribute :user_groups_enabled, Boolean
24
19
  attribute :comments_max_length, Integer, default: 0
25
20
  attribute :rich_text_editor_in_public_views, Boolean
26
21
  attribute :enable_machine_translations, Boolean
27
22
  attribute :machine_translation_display_priority, String
28
23
  attribute :enable_participatory_space_filters, Boolean
29
24
 
25
+ attribute :twitter_handler, String
26
+ attribute :facebook_handler, String
27
+ attribute :instagram_handler, String
28
+ attribute :youtube_handler, String
29
+ attribute :github_handler, String
30
+
31
+ attribute :logo
32
+ attribute :remove_logo, Boolean, default: false
33
+ attribute :favicon
34
+ attribute :remove_favicon, Boolean, default: false
35
+ attribute :official_url
36
+ attribute :official_img_footer
37
+ attribute :remove_official_img_footer, Boolean, default: false
38
+
39
+ attribute :primary_color, String
40
+ attribute :secondary_color, String
41
+ attribute :tertiary_color, String
42
+
30
43
  attribute :send_welcome_notification, Boolean
31
44
  attribute :customize_welcome_notification, Boolean
32
45
 
46
+ attribute :enable_omnipresent_banner, Boolean, default: false
47
+ attribute :omnipresent_banner_url, String
48
+
49
+ translatable_attribute :omnipresent_banner_title, String
50
+ translatable_attribute :omnipresent_banner_short_description, String
51
+
33
52
  translatable_attribute :welcome_notification_subject, String
34
53
  translatable_attribute :welcome_notification_body, Decidim::Attributes::RichText
35
54
 
@@ -48,6 +67,16 @@ module Decidim
48
67
  inclusion: { in: Decidim::Organization::AVAILABLE_MACHINE_TRANSLATION_DISPLAY_PRIORITIES },
49
68
  if: :machine_translation_enabled?
50
69
 
70
+ validates :official_img_footer,
71
+ :logo,
72
+ passthru: { to: Decidim::Organization }
73
+
74
+ validates :omnipresent_banner_url, url: true, presence: true, if: :enable_omnipresent_banner?
75
+ validates :omnipresent_banner_title, translatable_presence: true, if: :enable_omnipresent_banner?
76
+ validates :omnipresent_banner_short_description, translatable_presence: true, if: :enable_omnipresent_banner?
77
+
78
+ alias enable_omnipresent_banner? enable_omnipresent_banner
79
+
51
80
  def machine_translation_priorities
52
81
  Decidim::Organization::AVAILABLE_MACHINE_TRANSLATION_DISPLAY_PRIORITIES.map do |priority|
53
82
  [
@@ -52,20 +52,40 @@ module Decidim
52
52
 
53
53
  # Produces the html for the dropdown submenu from the options tree.
54
54
  # Returns a ActiveSupport::SafeBuffer.
55
- def dropdown_submenu(options)
56
- content_tag(:ul, class: "vertical menu", "aria-hidden": true) do
55
+ #
56
+ def dropdown_submenu(options, menu_id)
57
+ css_classes = menu_id.starts_with?("top-") ? "dropdown" : "dropdown dropdown__right z-#{options.length * 10}"
58
+
59
+ content_tag(:ul, id: "dropdown-filters-#{menu_id}", class: css_classes, "aria-hidden": true) do
57
60
  options.map do |key, value|
58
61
  if value.nil?
59
- content_tag(:li, key)
62
+ content_tag(:li, class: "dropdown__item") do
63
+ concat content_tag(:span, class: "dropdown__button") { key }
64
+ end
60
65
  elsif value.is_a?(Hash)
61
- content_tag(:li, class: "is-dropdown-submenu-parent") do
62
- key + dropdown_submenu(value)
66
+ child_id = SecureRandom.uuid
67
+ content_tag(:li, class: "dropdown__item") do
68
+ dropdown_link(key, child_id) + dropdown_submenu(value, child_id)
63
69
  end
64
70
  end
65
71
  end.join.html_safe
66
72
  end
67
73
  end
68
74
 
75
+ def dropdown_link(key, menu_id)
76
+ link_to("#", class: "dropdown__button", data: { controller: "dropdown", target: "dropdown-filters-#{menu_id}" }) do
77
+ safe_join([
78
+ content_tag(:span) { extract_html_value(key) },
79
+ icon("arrow-right-s-line", class: "fill-secondary absolute right-2"),
80
+ icon("arrow-right-s-line", class: "!fill-current !text-white absolute right-2")
81
+ ])
82
+ end
83
+ end
84
+
85
+ def extract_html_value(html_string)
86
+ Nokogiri::HTML.fragment(html_string).at("a").text
87
+ end
88
+
69
89
  def filter_link_label(filter, i18n_scope)
70
90
  link_to(i18n_filter_label(filter, i18n_scope), href: "#")
71
91
  end
@@ -109,7 +129,7 @@ module Decidim
109
129
  end
110
130
 
111
131
  def applied_filter_tag(filter, value, i18n_scope)
112
- content_tag(:span, class: "label secondary") do
132
+ content_tag(:span, class: "label reverse") do
113
133
  concat "#{i18n_filter_label(filter, i18n_scope)}: "
114
134
  concat i18n_filter_value(filter, value, i18n_scope)
115
135
  concat remove_filter_icon_link(filter)
@@ -127,8 +147,7 @@ module Decidim
127
147
  icon_link_to(
128
148
  "delete-bin-line",
129
149
  url_for(query_params_without(filter)),
130
- t("decidim.admin.actions.cancel"),
131
- class: "action-icon--remove"
150
+ t("decidim.admin.actions.cancel")
132
151
  )
133
152
  end
134
153
 
@@ -17,12 +17,11 @@ module Decidim
17
17
  with_tooltip(title, options.merge(class: "top")) do
18
18
  link_to(link,
19
19
  method: options[:method],
20
- class: "action-icon #{options[:class]}",
20
+ class: options[:class],
21
21
  data: options[:data] || {},
22
22
  title:,
23
23
  target: options[:target]) do
24
- content_tag(:span, data: { tooltip: true, disable_hover: false, click_open: false },
25
- title:) do
24
+ content_tag(:span) do
26
25
  icon(icon_name, aria_label: title, role: "img")
27
26
  end
28
27
  end
@@ -11,8 +11,7 @@ module Decidim
11
11
  # data - This option can be used to add custom data attributes.
12
12
  def icon_with_tooltip(icon_name, title, options = {})
13
13
  with_tooltip(title, options.merge(class: "top")) do
14
- content_tag(:span, data: { tooltip: true, disable_hover: false, click_open: false },
15
- title:) do
14
+ content_tag(:span) do
16
15
  icon(icon_name, aria_label: title, role: "img")
17
16
  end
18
17
  end
@@ -43,11 +43,6 @@ module Decidim
43
43
  accepted_mime_types = Decidim::Admin::Import::Readers::ACCEPTED_MIME_TYPES.keys
44
44
  accepted_mime_types.index_with { |mime_type| I18n.t("decidim.admin.imports.new.accepted_mime_types.#{mime_type}") }
45
45
  end
46
-
47
- # Returns verified user groups of current user
48
- def user_groups
49
- Decidim::UserGroups::ManageableUserGroups.for(current_user).verified
50
- end
51
46
  end
52
47
  end
53
48
  end
@@ -29,7 +29,8 @@ module Decidim
29
29
  target_menu,
30
30
  self,
31
31
  container_options: { class: "dropdown dropdown__bottom" },
32
- element_class: "dropdown__item",
32
+ element_class: "dropdown__button",
33
+ element_wrapper_class: "dropdown__item",
33
34
  active_class: "is-active"
34
35
  )
35
36
  end
@@ -38,7 +39,7 @@ module Decidim
38
39
  ::Decidim::Admin::SecondaryMenuPresenter.new(
39
40
  target_menu,
40
41
  self,
41
- element_class: "sidebar-menu__item",
42
+ element_wrapper_class: "sidebar-menu__item",
42
43
  active_class: "is-active"
43
44
  )
44
45
  end
@@ -12,7 +12,7 @@ module Decidim
12
12
 
13
13
  # Public: Returns the reportable's author names separated by commas.
14
14
  def reportable_author_name(reportable)
15
- reportable_authors = reportable.try(:authors) || [reportable.try(:normalized_author)]
15
+ reportable_authors = reportable.try(:authors) || [reportable.try(:author)]
16
16
  content_tag :ul, class: "reportable-authors" do
17
17
  reportable_authors.compact_blank.map do |author|
18
18
  case author
@@ -6,18 +6,18 @@ module Decidim
6
6
  # Public: Render a link to the permissions page for the resource.
7
7
  #
8
8
  # resource - The resource which permissions are going to be modified
9
- def resource_permissions_link(resource)
9
+ def dropdown_resource_permissions_link(resource)
10
10
  return unless resource.allow_resource_permissions? && allowed_to?(:update, :component, component: resource.component)
11
11
 
12
12
  current_participatory_space_admin_proxy = ::Decidim::EngineRouter.admin_proxy(current_participatory_space)
13
- icon_link_to "key-2-line",
14
- current_participatory_space_admin_proxy.edit_component_permissions_path(
15
- current_component.id,
16
- resource_name: resource.resource_manifest.name,
17
- resource_id: resource.id
18
- ),
19
- t("actions.permissions", scope: "decidim.admin"),
20
- class: "action-icon--permissions #{"action-icon--highlighted" if resource.permissions.present?}"
13
+ link_to current_participatory_space_admin_proxy.edit_component_permissions_path(
14
+ current_component.id,
15
+ resource_name: resource.resource_manifest.name,
16
+ resource_id: resource.id
17
+ ), class: "dropdown__button" do
18
+ concat icon "key-2-line"
19
+ concat t("actions.permissions", scope: "decidim.admin")
20
+ end
21
21
  end
22
22
 
23
23
  # Public: Render a link to the permissions page for a resource not
@@ -28,10 +28,10 @@ module Decidim
28
28
  resource_key = resource.resource_manifest.name.to_sym
29
29
  return unless resource.allow_resource_permissions? && allowed_to?(:update, resource_key, resource_key => resource)
30
30
 
31
- icon_link_to "key-2-line",
32
- send("edit_#{resource_key}_permissions_path", resource, resource_name: resource.resource_manifest.name),
33
- t("actions.permissions", scope: "decidim.admin"),
34
- class: "action-icon--permissions #{"action-icon--highlighted" if resource.permissions.present?}"
31
+ link_to send("edit_#{resource_key}_permissions_path", resource, resource_name: resource.resource_manifest.name), class: "dropdown__button" do
32
+ concat icon "key-2-line"
33
+ concat t("actions.permissions", scope: "decidim.admin")
34
+ end
35
35
  end
36
36
  end
37
37
  end
@@ -91,15 +91,23 @@ module Decidim
91
91
  # @param name (see #settings_attribute_input)
92
92
  # @param i18n_scope (see #settings_attribute_input)
93
93
  # @param options (see #settings_attribute_input)
94
- # @option :tabs_prefix (see #settings_attribute_input)
95
- # @option :readonly (see #settings_attribute_input)
94
+ # @option options [String] :tabs_prefix (see #settings_attribute_input)
95
+ # @option options [Boolean] :readonly (see #settings_attribute_input)
96
96
  # @option options [String] :label The label that this field has
97
97
  # @option options [String] :help_text The help text shown after the input field
98
98
  # @return (see #settings_attribute_input)
99
99
  def render_select_form_field(form, attribute, name, i18n_scope, options)
100
+ choices = attribute.build_choices(component: @component).map do |o|
101
+ if attribute.raw_choices
102
+ o
103
+ else
104
+ [t("#{name}_options.#{o}", scope: i18n_scope), o]
105
+ end
106
+ end
107
+
100
108
  html = form.select(
101
109
  name,
102
- attribute.build_choices.map { |o| [t("#{name}_options.#{o}", scope: i18n_scope), o] },
110
+ choices,
103
111
  { include_blank: attribute.include_blank, label: options[:label] }
104
112
  )
105
113
  html << content_tag(:p, options[:help_text], class: "help-text") if options[:help_text]
@@ -6,6 +6,7 @@ module Decidim
6
6
  #
7
7
  class NewsletterJob < ApplicationJob
8
8
  queue_as :newsletter
9
+ self.enqueue_after_transaction_commit = :never
9
10
 
10
11
  def perform(newsletter, form, recipients_ids)
11
12
  @newsletter = newsletter
@@ -5,7 +5,6 @@ import "src/decidim/admin/tab_focus"
5
5
  import initLanguageChangeSelect from "src/decidim/admin/choose_language"
6
6
  import "src/decidim/admin/application"
7
7
  import "src/decidim/admin/resources_permissions"
8
- import "src/decidim/admin/welcome_notification"
9
8
  import "src/decidim/admin/newsletters"
10
9
  import "src/decidim/admin/form"
11
10
  import "src/decidim/admin/external_domain_allowlist"
@@ -16,7 +15,6 @@ import "src/decidim/admin/managed_moderated_users"
16
15
  import "src/decidim/admin/moderations"
17
16
  import "src/decidim/admin/global_moderations"
18
17
  import "src/decidim/admin/officializations"
19
- import "src/decidim/slug_form"
20
18
  import "src/decidim/admin/admin_autocomplete"
21
19
  import "src/decidim/admin/triadic_color_picker"
22
20
  import "src/decidim/admin/participatory_space_search"
@@ -28,6 +26,7 @@ import "src/decidim/admin/taxonomy_filters"
28
26
  // CSS
29
27
  import "entrypoints/decidim_admin.scss";
30
28
 
31
- window.addEventListener("DOMContentLoaded", () => {
29
+ document.addEventListener("turbo:load", () => {
32
30
  initLanguageChangeSelect(document.querySelectorAll("select.language-change"));
33
31
  });
32
+
@@ -1 +1 @@
1
- @import "stylesheets/decidim/admin/application.scss";
1
+ @use "stylesheets/decidim/admin/application";
@@ -1,2 +1,2 @@
1
1
  // Application specific styles: https://docs.decidim.org/en/customize/styles/
2
- @import "stylesheets/decidim/admin/decidim_application";
2
+ @use "stylesheets/decidim/admin/decidim_application";
@@ -1,4 +1,4 @@
1
- import AutoComplete from "src/decidim/autocomplete";
1
+ import AutoComplete from "src/decidim/refactor/moved/autocomplete";
2
2
 
3
3
  /**
4
4
  * This function can be used to create an autocomplete input automatically
@@ -74,7 +74,7 @@ const autoConfigure = (el) => {
74
74
  return ac;
75
75
  }
76
76
 
77
- $(() => {
77
+ document.addEventListener("turbo:load", () => {
78
78
  const $autocompleteDiv = $("[data-autocomplete]");
79
79
  if ($autocompleteDiv.length < 1) {
80
80
  return;
@@ -1,10 +1,10 @@
1
1
  /* eslint-disable no-invalid-this */
2
2
 
3
+ import Configuration from "src/decidim/refactor/implementation/configuration"
4
+
5
+
3
6
  import toggleNav from "src/decidim/admin/toggle_nav";
4
7
  import createSortList from "src/decidim/admin/sort_list.component";
5
- import FormFilterComponent from "src/decidim/form_filter";
6
- import Configuration from "src/decidim/configuration";
7
- import InputCharacterCounter from "src/decidim/input_character_counter";
8
8
  import managedUsersForm from "src/decidim/admin/managed_users";
9
9
 
10
10
  import "chartkick/chart.js";
@@ -12,14 +12,18 @@ import "chartkick/chart.js";
12
12
  window.Decidim = window.Decidim || {};
13
13
  window.Decidim.managedUsersForm = managedUsersForm;
14
14
  window.Decidim.config = new Configuration();
15
- window.Decidim.InputCharacterCounter = InputCharacterCounter;
15
+
16
+
17
+ const context = require.context("./controllers", true, /controller\.js$/)
18
+ window.Stimulus.load(window.definitionsFromContext(context))
19
+
16
20
 
17
21
  // REDESIGN_PENDING: deprecated
18
22
  window.initFoundation = (element) => {
19
23
  $(element).foundation();
20
24
  };
21
25
 
22
- $(() => {
26
+ document.addEventListener("turbo:load", () => {
23
27
  window.initFoundation(document);
24
28
 
25
29
  $(document).on("show.zf.dropdownMenu", function(event, $element) {
@@ -51,9 +55,6 @@ $(() => {
51
55
  }
52
56
  });
53
57
 
54
- $("form.new_filter").each(function () {
55
- const formFilter = new FormFilterComponent($(this));
56
-
57
- formFilter.mountComponent();
58
- });
58
+ document.querySelectorAll("form.new_filter").forEach((container) =>
59
+ window.deprecate(container, "form-filter", "form.new_filter"))
59
60
  });
@@ -1,50 +1,100 @@
1
+ /**
2
+ * BudgetRuleTogglerComponent
3
+ *
4
+ * Handles showing and hiding rule-specific input containers
5
+ * based on the selected radio option.
6
+ */
1
7
  export default class BudgetRuleTogglerComponent {
8
+
9
+ /**
10
+ * @param {Object} options - Configuration options
11
+ * @param {HTMLInputElement[]} options.ruleRadios - Array of radio inputs controlling the rules
12
+ * @param {Record<string, string[]>} options.mapping - Mapping from radio values to selectors of containers to show
13
+ */
2
14
  constructor(options = {}) {
3
- this.ruleCheckboxes = options.ruleCheckboxes;
4
- this._runAll();
15
+ this.ruleRadios = options.ruleRadios;
16
+ this.mapping = options.mapping || {};
5
17
  }
6
18
 
7
- _runAll() {
8
- this.ruleCheckboxes.each((_i, checkbox) => {
9
- this._bindEvent(checkbox);
10
- this.run(checkbox);
11
- });
19
+ /**
20
+ * Initialize the component (bind events + run initial state).
21
+ * @returns {void}
22
+ */
23
+ init() {
24
+ this._bindEvents();
25
+ this._runInitial();
12
26
  }
13
27
 
14
- _bindEvent(target) {
15
- $(target).on("change", (event) => {
16
- this.run(event.target);
28
+ /**
29
+ * Bind change events on all radios
30
+ * @private
31
+ * @returns {void}
32
+ */
33
+ _bindEvents() {
34
+ this.ruleRadios.forEach((radio) => {
35
+ radio.addEventListener("change", (event) => {
36
+ this._run(event.target);
37
+ });
17
38
  });
18
39
  }
19
40
 
20
- run(target) {
21
- this.toggleTextInput(target);
22
-
23
- if ($(target).prop("checked")) {
24
- this.ruleCheckboxes.filter(
25
- (_i, checkbox) => {
26
- return checkbox !== target;
27
- }).prop("checked", false).each(
28
- (_i, checkbox) => {
29
- this.toggleTextInput(checkbox);
30
- });
41
+ /**
42
+ * Run toggler logic on page load
43
+ * @private
44
+ * @returns {void}
45
+ */
46
+ _runInitial() {
47
+ const checked = this.ruleRadios.find((radio) => radio.checked);
48
+ if (checked) {
49
+ this._run(checked);
50
+ } else {
51
+ this._hideAll();
31
52
  }
32
53
  }
33
54
 
34
- toggleTextInput(target) {
35
- const container = $(target).closest("div");
36
- if (container.length < 1) {
37
- return;
38
- }
39
- const containerClassPrefix = container.attr("class").
40
- replace(/^vote_rule_/, "vote_").
41
- replace(/_enabled_container$/, "");
42
- const input = $(`[class^="${containerClassPrefix}"][class$="_container"]`);
55
+ /**
56
+ * Show the containers associated with the selected radio
57
+ * @param {HTMLInputElement} target - The radio input that triggered the change
58
+ * @private
59
+ * @returns {void}
60
+ */
61
+ _run(target) {
62
+ this._hideAll();
43
63
 
44
- if ($(target).prop("checked")) {
45
- input.slideDown();
46
- } else {
47
- input.slideUp();
64
+ // Normalize radio value (snake_case → camelCase)
65
+ const rawValue = target.value;
66
+ const camelValue = rawValue.replace(/_([a-z])/g, (_match, letter) => letter.toUpperCase());
67
+
68
+ const selectors = this.mapping[camelValue] || [];
69
+
70
+ selectors.forEach((selector) => this._show(selector));
71
+ }
72
+
73
+ /**
74
+ * Hide all containers referenced in the mapping
75
+ * @private
76
+ * @returns {void}
77
+ */
78
+ _hideAll() {
79
+ const allSelectors = Object.values(this.mapping).flat();
80
+ allSelectors.forEach((selector) => {
81
+ const el = document.querySelector(selector);
82
+ if (el) {
83
+ el.style.display = "none";
84
+ }
85
+ });
86
+ }
87
+
88
+ /**
89
+ * Show a container by selector
90
+ * @param {string} selector - CSS selector of the container to show
91
+ * @private
92
+ * @returns {void}
93
+ */
94
+ _show(selector) {
95
+ const el = document.querySelector(selector);
96
+ if (el) {
97
+ el.style.display = "";
48
98
  }
49
99
  }
50
100
  }
@@ -0,0 +1,25 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ export default class extends Controller {
4
+ connect() {
5
+ this.input = this.element.querySelector("input");
6
+ this.target = this.element.querySelector("span.slug-url-value");
7
+ this.boundUpdate = null;
8
+
9
+ if (this.input) {
10
+ this.boundUpdate = this.slugUpdater.bind(this);
11
+ this.input.addEventListener("keyup", this.boundUpdate)
12
+ }
13
+ }
14
+
15
+ disconnect() {
16
+ if (this.boundUpdate !== null) {
17
+ this.input.removeEventListener("keyup", this.boundUpdate)
18
+ this.boundUpdate = null;
19
+ }
20
+ }
21
+
22
+ slugUpdater(event) {
23
+ this.target.innerHTML = event.target.value;
24
+ }
25
+ }