decidim-core 0.29.3 → 0.29.5

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 (140) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/activity/show.erb +6 -6
  3. data/app/cells/decidim/address/show.erb +3 -3
  4. data/app/cells/decidim/author/show.erb +2 -4
  5. data/app/cells/decidim/content_blocks/participatory_space_extra_data/extra_data.erb +2 -2
  6. data/app/cells/decidim/content_blocks/participatory_space_main_data/title.erb +11 -2
  7. data/app/cells/decidim/footer_topics/show.erb +2 -2
  8. data/app/cells/decidim/group_admins/show.erb +3 -1
  9. data/app/cells/decidim/group_members/show.erb +6 -2
  10. data/app/cells/decidim/images_panel/show.erb +5 -2
  11. data/app/cells/decidim/participatory_space_dropdown_metadata/metadata.erb +4 -4
  12. data/app/cells/decidim/report_button/flag_modal.erb +11 -9
  13. data/app/cells/decidim/report_user_button/flag_modal.erb +11 -10
  14. data/app/cells/decidim/upload_modal/files.erb +4 -4
  15. data/app/cells/decidim/upload_modal_cell.rb +5 -3
  16. data/app/commands/decidim/amendable/accept.rb +2 -1
  17. data/app/commands/decidim/create_report.rb +5 -1
  18. data/app/commands/decidim/invite_user.rb +1 -1
  19. data/app/controllers/concerns/decidim/headers/browser_feature_permissions.rb +50 -0
  20. data/app/controllers/concerns/decidim/participatory_space_context.rb +4 -1
  21. data/app/controllers/decidim/amendments_controller.rb +3 -3
  22. data/app/controllers/decidim/application_controller.rb +1 -0
  23. data/app/controllers/decidim/reports_controller.rb +6 -1
  24. data/app/forms/decidim/omniauth_registration_form.rb +1 -1
  25. data/app/forms/decidim/registration_form.rb +1 -1
  26. data/app/helpers/decidim/amendments_helper.rb +2 -1
  27. data/app/helpers/decidim/filters_helper.rb +25 -0
  28. data/app/helpers/decidim/layout_helper.rb +6 -0
  29. data/app/helpers/decidim/menu_helper.rb +2 -2
  30. data/app/helpers/decidim/paginate_helper.rb +1 -1
  31. data/app/helpers/decidim/tooltip_helper.rb +4 -1
  32. data/app/mailers/decidim/notifications_digest_mailer.rb +7 -1
  33. data/app/mailers/decidim/reported_mailer.rb +17 -2
  34. data/app/packs/images/decidim/default-avatar.svg +1 -1
  35. data/app/packs/src/decidim/callout.js +13 -8
  36. data/app/packs/src/decidim/confirm.js +79 -59
  37. data/app/packs/src/decidim/datepicker/generate_datepicker.js +2 -0
  38. data/app/packs/src/decidim/datepicker/generate_timepicker.js +2 -0
  39. data/app/packs/src/decidim/direct_uploads/upload_field.js +3 -4
  40. data/app/packs/src/decidim/direct_uploads/upload_modal.js +8 -9
  41. data/app/packs/src/decidim/dropdown_menu.js +18 -0
  42. data/app/packs/src/decidim/editor/common/suggestion.js +11 -1
  43. data/app/packs/src/decidim/form_remote.js +1 -1
  44. data/app/packs/src/decidim/impersonation.js +1 -1
  45. data/app/packs/src/decidim/index.js +5 -1
  46. data/app/packs/src/decidim/input_character_counter.js +1 -1
  47. data/app/packs/src/decidim/session_timeouter.js +1 -1
  48. data/app/packs/src/decidim/utilities/dom.js +148 -0
  49. data/app/packs/stylesheets/decidim/_activity.scss +4 -4
  50. data/app/packs/stylesheets/decidim/_cards.scss +4 -0
  51. data/app/packs/stylesheets/decidim/_filters.scss +1 -1
  52. data/app/packs/stylesheets/decidim/_header.scss +64 -37
  53. data/app/packs/stylesheets/decidim/_layout.scss +2 -2
  54. data/app/packs/stylesheets/decidim/_modal.scss +1 -5
  55. data/app/packs/stylesheets/decidim/_modal_update.scss +5 -1
  56. data/app/permissions/decidim/default_permissions.rb +2 -0
  57. data/app/permissions/decidim/permissions.rb +13 -1
  58. data/app/presenters/decidim/notification_to_mailer_presenter.rb +7 -3
  59. data/app/queries/decidim/last_activity.rb +25 -0
  60. data/app/views/decidim/errors/internal_server_error.html.erb +1 -1
  61. data/app/views/decidim/errors/not_found.html.erb +1 -1
  62. data/app/views/decidim/messaging/conversations/_reply_form.html.erb +1 -2
  63. data/app/views/decidim/messaging/conversations/_start.html.erb +1 -1
  64. data/app/views/decidim/newsletters/unsubscribe.html.erb +16 -4
  65. data/app/views/decidim/reported_mailer/hidden_manually.html.erb +25 -0
  66. data/app/views/decidim/searches/_filters.html.erb +48 -13
  67. data/app/views/decidim/shared/_component_announcement.html.erb +1 -1
  68. data/app/views/decidim/shared/_confirm_modal.html.erb +3 -5
  69. data/app/views/decidim/shared/_filters.html.erb +6 -4
  70. data/app/views/decidim/shared/_results_per_page.html.erb +1 -1
  71. data/app/views/kaminari/decidim/_page.html.erb +1 -1
  72. data/app/views/kaminari/decidim/_paginator.html.erb +1 -1
  73. data/app/views/layouts/decidim/_js_configuration.html.erb +1 -0
  74. data/app/views/layouts/decidim/_logo.html.erb +2 -2
  75. data/app/views/layouts/decidim/footer/_main.html.erb +1 -1
  76. data/app/views/layouts/decidim/footer/_main_intro.html.erb +1 -1
  77. data/app/views/layouts/decidim/footer/_mini.html.erb +2 -2
  78. data/app/views/layouts/decidim/header/_main.html.erb +2 -2
  79. data/app/views/layouts/decidim/header/_main_links_desktop.html.erb +6 -0
  80. data/app/views/layouts/decidim/header/_main_links_dropdown.html.erb +2 -0
  81. data/app/views/layouts/decidim/header/_main_links_mobile_account.html.erb +1 -1
  82. data/app/views/layouts/decidim/header/_menu_breadcrumb_main_dropdown_desktop.html.erb +5 -11
  83. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile_tablet.html.erb +5 -5
  84. data/app/views/layouts/decidim/header/_mobile_language_choose.html.erb +1 -1
  85. data/config/locales/ar.yml +0 -9
  86. data/config/locales/bg-BG.yml +2 -2
  87. data/config/locales/bg.yml +0 -11
  88. data/config/locales/ca-IT.yml +41 -6
  89. data/config/locales/ca.yml +41 -6
  90. data/config/locales/cs.yml +33 -10
  91. data/config/locales/de.yml +63 -25
  92. data/config/locales/el.yml +0 -10
  93. data/config/locales/en.yml +41 -6
  94. data/config/locales/es-MX.yml +42 -7
  95. data/config/locales/es-PY.yml +42 -7
  96. data/config/locales/es.yml +41 -6
  97. data/config/locales/eu.yml +79 -43
  98. data/config/locales/fi-plain.yml +55 -8
  99. data/config/locales/fi.yml +56 -9
  100. data/config/locales/fr-CA.yml +43 -9
  101. data/config/locales/fr-LU.yml +3 -3
  102. data/config/locales/fr.yml +43 -9
  103. data/config/locales/gl.yml +0 -8
  104. data/config/locales/hu.yml +0 -11
  105. data/config/locales/id-ID.yml +0 -8
  106. data/config/locales/is-IS.yml +0 -6
  107. data/config/locales/it.yml +124 -8
  108. data/config/locales/ja.yml +45 -11
  109. data/config/locales/lb-LU.yml +2 -2
  110. data/config/locales/lb.yml +0 -8
  111. data/config/locales/lt.yml +0 -11
  112. data/config/locales/lv.yml +0 -8
  113. data/config/locales/nl.yml +0 -8
  114. data/config/locales/no.yml +0 -8
  115. data/config/locales/pl.yml +0 -11
  116. data/config/locales/pt-BR.yml +1 -10
  117. data/config/locales/pt.yml +0 -8
  118. data/config/locales/ro-RO.yml +0 -14
  119. data/config/locales/ru.yml +0 -8
  120. data/config/locales/sk-SK.yml +3 -3
  121. data/config/locales/sk.yml +2 -8
  122. data/config/locales/sv.yml +56 -16
  123. data/config/locales/tr-TR.yml +1 -8
  124. data/config/locales/uk.yml +0 -7
  125. data/config/locales/zh-CN.yml +0 -8
  126. data/config/locales/zh-TW.yml +0 -11
  127. data/db/migrate/20171212103803_create_unique_nicknames.rb +1 -1
  128. data/db/migrate/20180221101934_fix_nickname_index.rb +1 -1
  129. data/db/migrate/20180706104107_add_nickname_to_managed_users.rb +1 -1
  130. data/db/migrate/20181001124950_move_users_groups_to_users_table.rb +1 -1
  131. data/db/migrate/20190412131728_fix_user_names.rb +1 -1
  132. data/lib/decidim/assets/tailwind/tailwind.config.js.erb +2 -1
  133. data/lib/decidim/core/test/factories.rb +2 -2
  134. data/lib/decidim/core/test/shared_examples/announcements_examples.rb +4 -0
  135. data/lib/decidim/core/version.rb +1 -1
  136. data/lib/decidim/form_builder.rb +14 -0
  137. data/lib/decidim/nicknamizable.rb +6 -9
  138. data/lib/tasks/upgrade/decidim_fix_nickname_uniqueness.rake +1 -1
  139. metadata +11 -7
  140. /data/app/views/decidim/reported_mailer/{hide.html.erb → hidden_automatically.html.erb} +0 -0
@@ -61,7 +61,7 @@ header {
61
61
  @apply hidden md:block col-span-2 col-start-5 xl:col-start-4;
62
62
 
63
63
  form {
64
- @apply block relative rounded text-md bg-background;
64
+ @apply block relative rounded text-md border border-neutral-200 outline outline-1 outline-transparent rounded bg-background-2 leading-relaxed;
65
65
  }
66
66
 
67
67
  input[type="text"] {
@@ -69,7 +69,7 @@ header {
69
69
  }
70
70
 
71
71
  button[type="submit"] {
72
- @apply absolute ltr:right-2 rtl:left-2 inset-y-2 text-secondary;
72
+ @apply absolute ltr:right-2 rtl:left-2 inset-y-0 text-secondary px-2;
73
73
  }
74
74
  }
75
75
 
@@ -334,10 +334,6 @@ header {
334
334
  &__dropdown-trigger {
335
335
  @apply flex items-center justify-between text-white;
336
336
 
337
- span {
338
- @apply flex flex-wrap md:flex-nowrap gap-x-2.5 overflow-hidden text-white;
339
- }
340
-
341
337
  svg {
342
338
  @apply w-6 h-6 fill-current;
343
339
  }
@@ -373,54 +369,85 @@ header {
373
369
  @apply absolute top-full left-0 bg-white rounded w-full bg-gray-5;
374
370
  }
375
371
 
376
- &__main-dropdown {
377
- @apply bg-white divide-y divide-gray-3 rounded-b shadow-lg text-black w-full lg:w-[1280px] h-screen md:h-auto;
372
+ &__dropdown-menu {
373
+ @apply w-full md:w-1/4 bg-primary px-4 md:px-8 pt-0 pb-3 md:py-3 divide-y divide-gray-3 text-white;
378
374
 
379
- &__bottom,
380
- &__top {
381
- @apply flex flex-col md:flex-row justify-between p-4 md:p-8 gap-x-8;
375
+ > * {
376
+ @apply py-3 md:py-3.5;
377
+ }
382
378
 
383
- &-right {
384
- @apply hidden md:block md:w-1/2;
379
+ a {
380
+ @apply flex items-center justify-start gap-1 font-semibold text-lg text-white;
381
+
382
+ span {
383
+ @apply min-w-0 truncate;
385
384
  }
386
- }
387
385
 
388
- &__bottom {
389
- @apply hidden md:flex;
386
+ svg {
387
+ @apply flex-none fill-current;
388
+ }
390
389
  }
390
+ }
391
391
 
392
- &__title {
393
- @apply hidden h4 md:flex md:h3;
394
- }
392
+ &__main-dropdown {
393
+ @apply bg-white flex flex-row rounded-b shadow-lg text-black w-full lg:w-[1280px] h-screen md:h-auto;
395
394
 
396
- &__subtitle {
397
- @apply hidden text-md md:flex md:text-lg text-gray-2 mt-5;
395
+ &__left {
396
+ @apply flex flex-col justify-between p-4 md:p-8 space-y-5 hidden md:block md:w-3/4;
397
+
398
+ &-top {
399
+ @apply border-b-4 border-gray-3 pb-3;
400
+ }
398
401
  }
399
402
 
400
- &__menu {
401
- @apply w-full md:w-1/2 mt-0 grid md:grid-cols-2 gap-x-6 text-secondary;
403
+ &__top {
404
+ @apply w-full px-4;
402
405
 
403
- > * {
404
- @apply py-3 md:py-3.5 border-b last:border-0 border-gray-3;
406
+ &-menu {
407
+ @apply w-full md:w-[100%] mt-0 grid md:grid-cols-2 gap-x-6 text-secondary;
408
+
409
+ > * {
410
+ @apply py-3 md:py-3.5 border-b last:border-0 border-gray-3;
405
411
 
406
- /* since the grid has 2 columns, remove the border for these last 2 columns */
407
- &:nth-last-child(-n + 2) {
408
- @apply md:border-0;
412
+ /* since the grid has 2 columns, remove the border for these last 2 columns */
413
+ &:nth-last-child(-n + 2) {
414
+ @apply md:border-0;
415
+ }
409
416
  }
410
- }
411
417
 
412
- a {
413
- @apply flex items-center justify-start gap-1 font-semibold text-lg text-secondary;
418
+ a {
419
+ @apply flex items-center justify-start gap-1 font-semibold text-lg text-secondary;
414
420
 
415
- span {
416
- @apply min-w-0 truncate;
417
- }
421
+ span {
422
+ @apply min-w-0 truncate;
423
+ }
418
424
 
419
- svg {
420
- @apply flex-none fill-current;
425
+ svg {
426
+ @apply flex-none fill-current;
427
+ }
421
428
  }
422
429
  }
423
430
  }
431
+
432
+ &__bottom {
433
+ @apply hidden md:flex;
434
+
435
+ &-right {
436
+ @apply mr-2 mb-2;
437
+ }
438
+
439
+ &-left {
440
+ @apply mr-2 mt-1;
441
+ }
442
+ }
443
+
444
+ &__title {
445
+ @apply hidden h4 md:flex md:h3;
446
+ }
447
+
448
+ &__subtitle {
449
+ @apply hidden text-md md:flex md:text-lg text-gray-2 mt-5;
450
+ }
424
451
  }
425
452
 
426
453
  &__secondary-dropdown {
@@ -459,7 +486,7 @@ header {
459
486
  }
460
487
 
461
488
  &__metadata {
462
- @apply flex items-center text-sm space-x-6 py-8;
489
+ @apply flex items-center text-sm space-x-6 pb-6;
463
490
 
464
491
  > span {
465
492
  @apply flex items-center space-x-2;
@@ -2,11 +2,11 @@
2
2
  @apply flex flex-col min-h-screen;
3
3
 
4
4
  &__skip {
5
- @apply absolute z-10 left-0 -translate-x-full py-1 px-4 bg-primary rounded-br-lg text-white cursor-pointer transition focus:translate-x-0;
5
+ @apply absolute z-[9999] left-0 -translate-x-full py-1 px-4 bg-primary rounded-br-lg text-white cursor-pointer transition focus:translate-x-0;
6
6
  }
7
7
 
8
8
  [data-content] {
9
- @apply relative flex flex-col;
9
+ @apply relative flex flex-col flex-1;
10
10
  }
11
11
  }
12
12
 
@@ -18,15 +18,11 @@
18
18
  }
19
19
 
20
20
  [data-dialog-container] {
21
- @apply grid grid-cols-[auto_1fr] items-start md:items-center gap-2 text-left;
21
+ @apply grid grid-rows-[auto_1fr] items-start md:items-center gap-2 text-left;
22
22
 
23
23
  > svg {
24
24
  @apply w-6 h-6 text-gray fill-current flex-none;
25
25
  }
26
-
27
- > :last-child {
28
- @apply col-span-2 md:col-span-1 md:col-start-2;
29
- }
30
26
  }
31
27
 
32
28
  [data-dialog-title] {
@@ -132,8 +132,12 @@
132
132
  }
133
133
 
134
134
  span {
135
- @apply text-sm text-gray-2 mx-auto;
135
+ @apply text-sm text-gray-2 mx-auto w-full break-all mb-2;
136
136
  }
137
137
  }
138
138
  }
139
+
140
+ &__span {
141
+ @apply w-full break-all mb-2;
142
+ }
139
143
  }
@@ -5,6 +5,8 @@ module Decidim
5
5
  # actions by any kind of user. Also works as a default implementation so other
6
6
  # components can inherit from it and get some convenience methods.
7
7
  class DefaultPermissions
8
+ include Decidim::UserRoleChecker
9
+
8
10
  def initialize(user, permission_action, context = {})
9
11
  @user = user
10
12
  @permission_action = permission_action
@@ -106,7 +106,19 @@ module Decidim
106
106
  return allow! if component.current_settings.amendment_creation_enabled
107
107
  when :accept,
108
108
  :reject
109
- return allow! if component.current_settings.amendment_reaction_enabled
109
+ return disallow! unless component.current_settings.amendment_reaction_enabled
110
+
111
+ amendable = context.fetch(:amendable, nil)
112
+
113
+ if amendable.respond_to?(:official?) && amendable.official?
114
+ return allow! if user.admin?
115
+
116
+ return disallow!
117
+ end
118
+
119
+ return disallow! unless amendable.authored_by?(user)
120
+
121
+ return allow!
110
122
  when :promote
111
123
  return allow! if component.current_settings.amendment_promotion_enabled
112
124
  end
@@ -14,15 +14,19 @@ module Decidim
14
14
  delegate :url_helpers, to: "Decidim::Core::Engine.routes"
15
15
  delegate :resource_title, to: :event
16
16
  delegate :resource_url, to: :event
17
- delegate :email_intro, to: :event
18
17
  delegate :resource_path, to: :event
19
18
  delegate :safe_resource_text, to: :event
20
19
 
20
+ def email_intro
21
+ event.email_intro if event.respond_to?(:email_intro)
22
+ end
23
+
21
24
  def date_time
25
+ created_at_in_time_zone = created_at.in_time_zone(resource.organization.time_zone)
22
26
  if frequency == :daily
23
- created_at.strftime("%H:%M")
27
+ I18n.l(created_at_in_time_zone, format: :time_of_day)
24
28
  else
25
- I18n.l(created_at, format: :decidim_short)
29
+ I18n.l(created_at_in_time_zone, format: :decidim_short)
26
30
  end
27
31
  end
28
32
 
@@ -18,6 +18,7 @@ module Decidim
18
18
  query = filter_moderated(query)
19
19
  query = filter_spaces(query)
20
20
  query = filter_deleted(query)
21
+ query = filter_withdrawn(query)
21
22
  query.with_new_resource_type("all")
22
23
  end
23
24
  end
@@ -48,6 +49,30 @@ module Decidim
48
49
  ).where(decidim_moderations: { id: nil })
49
50
  end
50
51
 
52
+ def filter_withdrawn(query)
53
+ # Filter out the items that have been withdrawn.
54
+ conditions = []
55
+
56
+ ActionLog.public_resource_types.each do |resource_type|
57
+ klass = resource_type.constantize
58
+
59
+ condition = if klass.respond_to?(:not_withdrawn)
60
+ Arel.sql(
61
+ [
62
+ "decidim_action_logs.resource_type = '#{resource_type}'",
63
+ "decidim_action_logs.resource_id IN (#{Arel.sql(klass.not_withdrawn.select(:id).to_sql)})"
64
+ ].join(" AND ")
65
+ ).to_s
66
+ else
67
+ Arel.sql("decidim_action_logs.resource_type = '#{resource_type}'").to_s
68
+ end
69
+
70
+ conditions << "(#{condition})"
71
+ end
72
+
73
+ query.where(Arel.sql(conditions.join(" OR ")).to_s)
74
+ end
75
+
51
76
  def filter_spaces(query)
52
77
  conditions = []
53
78
 
@@ -1,6 +1,6 @@
1
1
  <%= render layout: "layouts/decidim/shared/layout_center" do %>
2
2
 
3
- <div class="place-self-center">
3
+ <div class="flex flex-col items-center">
4
4
  <div class="flex justify-center">
5
5
  <h1 class="title-decorator my-12"><%= t("title", scope: "decidim.errors.internal_server_error") %></h1>
6
6
  </div>
@@ -1,6 +1,6 @@
1
1
  <%= render layout: "layouts/decidim/shared/layout_center" do %>
2
2
 
3
- <div class="place-self-center">
3
+ <div class="flex flex-col items-center">
4
4
  <div class="flex justify-center">
5
5
  <h1 class="title-decorator my-12"><%= t("title", scope: "decidim.errors.not_found") %></h1>
6
6
  </div>
@@ -1,8 +1,7 @@
1
1
  <div data-conversation-reply>
2
2
  <%= decidim_form_for form, url: decidim.conversation_path(conversation.id), method: :put, remote: true do |f| %>
3
3
  <div class="conversation__reply">
4
- <%= f.label :body, nil, class: "sr-only" %>
5
- <%= f.text_area :body, label: false, rows: 4, required: true, placeholder: t(".placeholder"), data: { "input-emoji": true } %>
4
+ <%= f.text_area :body, label: false, rows: 4, required: true, placeholder: t(".placeholder"), data: { "input-emoji": true }, aria: { label: t(".placeholder") } %>
6
5
  <%= f.submit "#{t(".send")} #{icon "arrow-right-line", class: "fill-current"}".html_safe, class: "button button__sm button__secondary self-end mt-4" %>
7
6
  </div>
8
7
  <% end %>
@@ -5,7 +5,7 @@
5
5
  <%= f.hidden_field :recipient_id, id: nil, name: "conversation[recipient_id][]", value: recipient.id %>
6
6
  <% end %>
7
7
  <%= f.label :body, nil, class: "sr-only" %>
8
- <%= f.text_area :body, label: false, rows: 4, required: true, placeholder: t(".placeholder"), data: { "input-emoji": true } %>
8
+ <%= f.text_area :body, label: false, rows: 4, required: true, placeholder: t(".placeholder"), data: { "input-emoji": true }, aria: { label: t(".placeholder") } %>
9
9
  <%= f.submit "#{t(".send")} #{icon "arrow-right-line", class: "fill-current"}".html_safe, class: "button button__sm button__secondary self-end mt-4" %>
10
10
  </div>
11
11
  <% end %>
@@ -1,4 +1,16 @@
1
- <div class="row">
2
- <h4><%== t ".unsubscribe" %></h4>
3
- <p><%== t ".check_subscription", link: decidim.notifications_settings_path %></p>
4
- </div>
1
+ <main class="layout-1col cols-6">
2
+ <div class="text-center py-12">
3
+ <h1 class="h1 decorator inline-block text-left"><%= t ".unsubscribe" %></h1>
4
+ </div>
5
+ <div class="page__container">
6
+ <div class="editor-content">
7
+ <div class="rich-text-display">
8
+ <%= t ".subscription_preferences", organization_name: translated_attribute(current_organization.name) %>
9
+ </div>
10
+ <br>
11
+ <div class="rich-text-display">
12
+ <%= t ".check_subscription_html", link: decidim.notifications_settings_path %>
13
+ </div>
14
+ </div>
15
+ </div>
16
+ </main>
@@ -0,0 +1,25 @@
1
+ <p class="email-greeting"><%= t(".hello", name: @user.name) %></p>
2
+
3
+ <p class="email-instructions">
4
+ <%= t(".report_html", url: reported_content_url, moderator: @moderator.name) %>
5
+ </p>
6
+
7
+ <p><b><%= t(".participatory_space") %></b></p>
8
+ <p><%= link_to translated_attribute(@participatory_space.title), resource_locator(@participatory_space).url %></p>
9
+
10
+ <p><b><%= t(".reason") %></b></p>
11
+ <p><%= t(@report.reason, organization_name: organization_name(@participatory_space.organization), scope: "decidim.shared.flag_modal") %></p>
12
+
13
+ <% if @report.details.present? %>
14
+ <p><b><%= t(".details") %></b></p>
15
+ <blockquote>
16
+ <%= @report.details %>
17
+ </blockquote>
18
+ <% end %>
19
+
20
+ <p><b><%= t(".content") %></b></p>
21
+ <%= reported_content_cell %>
22
+
23
+ <p class="email-button email-button__cta">
24
+ <%= link_to t(".manage_moderations"), manage_moderations_url %>
25
+ </p>
@@ -12,35 +12,70 @@
12
12
  <%= icon "arrow-down-s-line", class: "w-8 h-8 flex-none text-secondary fill-current" %>
13
13
  <%= icon "arrow-up-s-line", class: "w-8 h-8 flex-none text-secondary fill-current" %>
14
14
  </button>
15
- <div id="dropdown-menu-search" aria-hidden="true">
16
- <div>
17
- <%= link_to main_search_path, class: "filter#{" is-active" if params.dig(:filter, :with_resource_type) == nil}" do %>
15
+ <ul id="dropdown-menu-search" aria-hidden="true">
16
+ <li>
17
+ <%= link_to main_search_path, class: "filter#{" is-active" if params.dig(:filter, :with_resource_type) == nil}", "aria-current": params.dig(:filter, :with_resource_type) == nil ? "true" : "" do %>
18
18
  <%= resource_type_icon("all") %>
19
19
  <span><%= t("all", scope: "decidim.searches.filters.state") %></span>
20
20
  <span class="label ml-auto"><%= @results_count %></span>
21
21
  <% end %>
22
- </div>
22
+ </li>
23
23
  <% @blocks.each do |elements| %>
24
- <div>
25
- <% elements.each do |type, results| %>
26
- <div>
24
+ <li>
25
+ <ul>
26
+ <% elements.each do |type, results| %>
27
27
  <% if results[:count].positive? %>
28
- <%= link_to search_path_by_resource_type(type), class: "filter#{" is-active" if params.dig(:filter, :with_resource_type) == type}" do %>
28
+ <li>
29
+ <%= link_to search_path_by_resource_type(type), class: "filter#{" is-active" if params.dig(:filter, :with_resource_type) == type}", "aria-current": params.dig(:filter, :with_resource_type) == type ? "true" : "" do %>
29
30
  <%= resource_type_icon(type) %>
30
31
  <span><%= searchable_resource_human_name(type) %></span>
31
32
  <span class="label ml-auto"><%= results[:count] %></span>
32
33
  <% end %>
34
+ </li>
33
35
  <% else %>
34
- <%= content_tag :div, class: "filter#{" is-empty" if results[:count].zero?}" do %>
36
+ <%= content_tag :li, class: "filter#{" is-empty" if results[:count].zero?}" do %>
35
37
  <%= resource_type_icon(type) %>
36
38
  <span><%= searchable_resource_human_name(type) %></span>
37
39
  <span class="label ml-auto"><%= results[:count] %></span>
38
40
  <% end %>
39
41
  <% end %>
40
- </div>
41
- <% end %>
42
- </div>
42
+ <% end %>
43
+ </ul>
44
+ </li>
43
45
  <% end %>
44
- </div>
46
+ </ul>
45
47
  </div>
46
48
  </nav>
49
+ <script type="text/javascript">
50
+ const button = document.querySelector('#dropdown-trigger-search');
51
+ const arrowDown = button.querySelector('svg:first-of-type');
52
+ const arrowUp = button.querySelector('svg:last-of-type');
53
+ const list = document.querySelector('#dropdown-menu-search');
54
+ // the arrow is up when user arrives on the page, with the list displayed
55
+ arrowUp.addEventListener('click', function(){
56
+ setTimeout(() => {
57
+ button.setAttribute('aria-expanded', 'false');
58
+ list.style.display = "none";
59
+ }, 300)
60
+ })
61
+ arrowDown.addEventListener('click', function(){
62
+ setTimeout(() => {
63
+ button.setAttribute('aria-expanded', 'true');
64
+ list.style.display = "block";
65
+ }, 300)
66
+ })
67
+ // 32 is code for space bar and 13 is code for enter
68
+ button.addEventListener('keydown', function(e){
69
+ if ((e.keyCode === 13 || e.keyCode === 32) && button.getAttribute('aria-expanded') === 'true') {
70
+ setTimeout(() => {
71
+ button.setAttribute('aria-expanded', 'false');
72
+ list.style.display = "none";
73
+ }, 300)
74
+ } else if ((e.keyCode === 13 || e.keyCode === 32) && button.getAttribute('aria-expanded') === 'false'){
75
+ setTimeout(() => {
76
+ button.setAttribute('aria-expanded', 'true');
77
+ list.style.display = "block";
78
+ }, 300)
79
+ }
80
+ })
81
+ </script>
@@ -1,5 +1,5 @@
1
1
  <% announcement = translated_attribute(current_settings.announcement).presence || translated_attribute(component_settings.announcement).presence %>
2
- <% if announcement %>
2
+ <% if strip_tags(announcement).present? %>
3
3
  <section class="layout-main__section">
4
4
  <%= cell("decidim/announcement", announcement, local_assigns.merge(callout_class: "editor-content")) %>
5
5
  </section>
@@ -1,16 +1,14 @@
1
1
  <%= decidim_modal id: "confirm-modal" do %>
2
2
  <div data-dialog-container>
3
- <%= icon "delete-bin-line" %>
4
3
  <h2 class="h2" data-dialog-title id="dialog-title-confirm-modal"><%= t("title", scope: "decidim.shared.confirm_modal") %></h2>
5
-
6
4
  <div data-confirm-modal-content></div>
7
5
  </div>
8
6
 
9
- <div data-dialog-actions>
10
- <button class="button button__lg button__transparent-secondary" data-confirm-cancel data-dialog-close="confirm-modal">
7
+ <div data-dialog-actions class="flex flex-col-reverse md:flex-row">
8
+ <button class="button button__lg button__transparent-secondary w-full md:w-auto" data-confirm-cancel data-dialog-close="confirm-modal">
11
9
  <span><%= t("cancel", scope: "decidim.shared.confirm_modal") %></span>
12
10
  </button>
13
- <button class="button button__lg button__secondary" data-confirm-ok>
11
+ <button class="button button__lg button__secondary w-full md:w-auto" data-confirm-ok>
14
12
  <span><%= t("ok", scope: "decidim.shared.confirm_modal") %></span>
15
13
  </button>
16
14
  </div>
@@ -16,16 +16,18 @@
16
16
  <% if local_assigns.has_key?(:skip_to_id) %>
17
17
  <%= link_to t("skip", scope: "decidim.shared.filter_form_help"), "##{skip_to_id}", class: "filter-skip", role: "menuitem" %>
18
18
  <% end %>
19
- <p class="filter-help" role="menuitem" aria-disabled="true"><%= t("help", scope: "decidim.shared.filter_form_help") %></p>
19
+
20
+ <p id="filter-help-text" class="filter-help" role="menuitem" aria-disabled="true"><%= t("help", scope: "decidim.shared.filter_form_help") %></p>
20
21
 
21
22
  <% if local_assigns.has_key?(:search_variable) %>
22
23
  <div class="filter-search filter-container" role="menuitem">
23
24
  <%= form.search_field search_variable,
24
25
  label: false,
25
26
  placeholder: search_label,
26
- title: search_label,
27
- "aria-label": search_label %>
28
- <button type="submit" aria-label="<%= search_label %>">
27
+ title: filter_search_label(search_label, skip_to_id),
28
+ "aria-label": filter_search_label(search_label, skip_to_id),
29
+ "aria-describedby": "filter-help-text" %>
30
+ <button type="submit" aria-label="<%= filter_search_label(search_label, skip_to_id) %>">
29
31
  <%= icon "search-line" %>
30
32
  </button>
31
33
  </div>
@@ -1,7 +1,7 @@
1
1
  <% menu_id = "#{SecureRandom.uuid}_results_per_page_menu" %>
2
2
  <div class="flex items-center gap-1">
3
3
  <%= icon "list-check-2", class: "w-4 h-4 text-gray fill-current" %>
4
- <span class="text-gray-2"><%= t("decidim.shared.results_per_page.label") %></span>
4
+ <p class="text-gray-2"><%= t("decidim.shared.results_per_page.label") %></p>
5
5
 
6
6
  <details class="relative">
7
7
  <summary id="<%= menu_id %>-control" class="flex items-center cursor-pointer text-secondary font-semibold" aria-controls="<%= menu_id %>" aria-haspopup="menu" title="<%= t("decidim.shared.results_per_page.title") %>">
@@ -6,6 +6,6 @@
6
6
  total_pages: total number of pages
7
7
  per_page: number of items to fetch per page
8
8
  remote: data-remote -%>
9
- <li class="w-6 h-6 rounded-full hover:bg-background-3 transition<%= "mx-2 bg-background-3 grid place-items-center" if page.current? %>" <%== 'aria-current="page"' if page.current? %> data-page>
9
+ <li class="w-6 h-6 px-2 rounded-full hover:bg-background-3 transition min-w-fit <%= "bg-background-3 grid place-items-center" if page.current? %>" <%== 'aria-current="page"' if page.current? %> data-page>
10
10
  <%= link_to_unless page.current?, page, url, { class: "w-full h-full grid place-items-center", remote:, rel: page.rel, title: t("views.pagination.title") << page.to_s } %>
11
11
  </li>
@@ -8,7 +8,7 @@ paginator: the paginator that renders the pagination tags inside -%>
8
8
 
9
9
  <% if total_pages > 1 %>
10
10
  <nav aria-label="<%= t("views.pagination.pagination") %>">
11
- <ul class="flex items-center text-sm text-secondary" data-pages>
11
+ <ul class="flex flex-wrap items-center text-sm text-secondary gap-x-1" data-pages>
12
12
  <%= paginator.prev_page_tag unless current_page.first? %>
13
13
 
14
14
  <% paginator.each_page do |page| -%>
@@ -7,6 +7,7 @@ js_configs = {
7
7
  "mentionsModal": {
8
8
  "removeRecipient": t("decidim.shared.mentions_modal.remove_recipient", name: "%name%")
9
9
  },
10
+ "confirmUnload": t("decidim.shared.confirm_unload"),
10
11
  emojis: I18n.t("emojis").deep_transform_keys { |k| k.to_s.camelize(:lower) },
11
12
  editor: I18n.t("editor"),
12
13
  date: I18n.t("date"),
@@ -1,7 +1,7 @@
1
1
  <% if organization %>
2
- <%= link_to decidim.root_url(host: organization.host), "aria-label": t("front_page_link", scope: "decidim.accessibility") do %>
2
+ <%= link_to decidim.root_url(host: organization.host) do %>
3
3
  <% if organization.logo.attached? %>
4
- <%= image_tag organization.attached_uploader(:logo).variant_url(:medium), alt: t("logo", scope: "decidim.accessibility", organization: current_organization_name) %>
4
+ <%= image_tag organization.attached_uploader(:logo).variant_url(:medium), alt: "#{current_organization_name} (#{t("decidim.errors.not_found.back_home")})" %>
5
5
  <% else %>
6
6
  <span><%= current_organization_name %></span>
7
7
  <% end %>
@@ -11,7 +11,7 @@
11
11
  <nav class="md:w-1/2 lg:w-auto" role="navigation" aria-label="Legal">
12
12
  <%= render partial: "layouts/decidim/footer/main_legal" %>
13
13
  </nav>
14
- <nav class="w-full md:w-auto md:ml-auto" role="navigation" aria-label="Social media">
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
17
  <%= render partial: "layouts/decidim/footer/main_language_chooser" %>
@@ -1,6 +1,6 @@
1
1
  <% if current_organization.official_img_footer.attached? %>
2
2
  <%= link_to current_organization.official_url, class: "block mb-6" do %>
3
- <%= image_tag current_organization.attached_uploader(:official_img_footer).url, alt: current_organization_name, class: "max-h-16" %>
3
+ <%= image_tag current_organization.attached_uploader(:official_img_footer).url, alt: t("layouts.decidim.footer.current_organization_img", organization: current_organization_name), class: "max-h-16" %>
4
4
  <% end %>
5
5
  <% end %>
6
6
  <div class="text-sm text-white prose">
@@ -4,9 +4,9 @@
4
4
  <a rel="decidim noopener noreferrer" href="https://decidim.org/" target="_blank" data-external-link="text-only">
5
5
  <%= image_pack_tag("media/images/decidim-logo.svg", alt: t("layouts.decidim.footer.decidim_logo"), class: "max-h-8 block") %>
6
6
  </a>
7
- <div class="text-xs mt-2 [&_a]:underline">
7
+ <p class="text-xs mt-2 [&_a]:underline">
8
8
  <%= t("layouts.decidim.footer.made_with_open_source").html_safe %>
9
- </div>
9
+ </p>
10
10
  </div>
11
11
  <a class="flex gap-1 hover:opacity-50" rel="license noopener noreferrer" href="http://creativecommons.org/licenses/by-sa/4.0/" target="_blank" data-external-link="text-only">
12
12
  <span class="sr-only"><%= t("layouts.decidim.footer.cc_by_license") %></span>
@@ -8,10 +8,10 @@
8
8
  <%= render partial: "layouts/decidim/logo_mobile", locals: { organization: current_organization } %>
9
9
  </div>
10
10
  </div>
11
- <div class="main-bar__search">
11
+ <div role="search" class="main-bar__search">
12
12
  <%= render partial: "layouts/decidim/header/main_search" %>
13
13
  </div>
14
- <div class="main-bar__links-desktop">
14
+ <div role="navigation" class="main-bar__links-desktop">
15
15
  <%= render partial: "layouts/decidim/header/main_links_desktop" %>
16
16
  </div>
17
17
  <div class="main-bar__menu-mobile">
@@ -30,6 +30,12 @@
30
30
  <% unread_data = current_user_unread_data %>
31
31
  <% if unread_data[:unread_items] %>
32
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" %>
38
+ <% end %>
33
39
  <% end %>
34
40
  <% if current_user.avatar.attached? %>
35
41
  <span class="main-bar__avatar">