decidim-core 0.30.4 → 0.30.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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/card_g/show.erb +1 -1
  3. data/app/cells/decidim/notification/deleted.erb +12 -0
  4. data/app/cells/decidim/notification/not_available.erb +12 -0
  5. data/app/cells/decidim/notification_cell.rb +5 -1
  6. data/app/cells/decidim/share_widget/modal.erb +2 -1
  7. data/app/commands/decidim/destroy_account.rb +49 -4
  8. data/app/events/decidim/welcome_notification_event.rb +1 -1
  9. data/app/jobs/decidim/remove_search_indexes_job.rb +18 -0
  10. data/app/mailers/decidim/notifications_digest_mailer.rb +18 -1
  11. data/app/models/decidim/component.rb +3 -0
  12. data/app/models/decidim/notification.rb +10 -0
  13. data/app/models/decidim/user.rb +4 -0
  14. data/app/models/decidim/user_base_entity.rb +1 -1
  15. data/app/packs/src/decidim/editor/extensions/link/index.js +0 -1
  16. data/app/packs/src/decidim/editor/index.js +5 -1
  17. data/app/packs/src/decidim/editor/test/extensions/link.test.js +2 -2
  18. data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_link.js +1 -1
  19. data/app/packs/stylesheets/decidim/_modal.scss +5 -1
  20. data/app/packs/stylesheets/decidim/_modal_fingerprint.scss +1 -1
  21. data/app/presenters/decidim/log/user_presenter.rb +2 -1
  22. data/app/presenters/decidim/user_presenter.rb +6 -1
  23. data/app/views/decidim/pages/_tabbed.html.erb +1 -1
  24. data/app/views/decidim/shared/_orders.html.erb +1 -1
  25. data/app/views/layouts/decidim/header/_main_links_mobile_account.html.erb +15 -1
  26. data/config/locales/ar.yml +0 -4
  27. data/config/locales/bg.yml +0 -8
  28. data/config/locales/ca-IT.yml +13 -11
  29. data/config/locales/ca.yml +13 -11
  30. data/config/locales/cs.yml +9 -19
  31. data/config/locales/de.yml +4 -20
  32. data/config/locales/el.yml +0 -3
  33. data/config/locales/en.yml +19 -17
  34. data/config/locales/es-MX.yml +12 -10
  35. data/config/locales/es-PY.yml +12 -10
  36. data/config/locales/es.yml +11 -9
  37. data/config/locales/eu.yml +42 -41
  38. data/config/locales/fa-IR.yml +3 -0
  39. data/config/locales/fi-plain.yml +11 -8
  40. data/config/locales/fi.yml +11 -8
  41. data/config/locales/fr-CA.yml +20 -11
  42. data/config/locales/fr.yml +20 -11
  43. data/config/locales/ga-IE.yml +0 -4
  44. data/config/locales/gl.yml +0 -3
  45. data/config/locales/hu.yml +0 -6
  46. data/config/locales/id-ID.yml +0 -3
  47. data/config/locales/it.yml +1 -4
  48. data/config/locales/ja.yml +24 -22
  49. data/config/locales/ko.yml +3 -0
  50. data/config/locales/lb.yml +0 -3
  51. data/config/locales/lt.yml +0 -5
  52. data/config/locales/lv.yml +0 -3
  53. data/config/locales/mt.yml +3 -0
  54. data/config/locales/nl.yml +0 -3
  55. data/config/locales/no.yml +0 -3
  56. data/config/locales/pl.yml +11 -7
  57. data/config/locales/pt-BR.yml +552 -5
  58. data/config/locales/pt.yml +0 -3
  59. data/config/locales/ro-RO.yml +453 -126
  60. data/config/locales/ru.yml +0 -3
  61. data/config/locales/sk.yml +0 -3
  62. data/config/locales/sv.yml +28 -13
  63. data/config/locales/tr-TR.yml +0 -5
  64. data/config/locales/uk.yml +0 -3
  65. data/config/locales/vi.yml +3 -0
  66. data/config/locales/zh-CN.yml +0 -3
  67. data/config/locales/zh-TW.yml +0 -5
  68. data/decidim-core.gemspec +1 -0
  69. data/lib/decidim/core/seeds.rb +3 -3
  70. data/lib/decidim/core/test/factories.rb +20 -0
  71. data/lib/decidim/core/test/shared_examples/comments_examples.rb +35 -5
  72. data/lib/decidim/core/test/shared_examples/fingerprint_examples.rb +13 -0
  73. data/lib/decidim/core/test/shared_examples/process_announcements_examples.rb +35 -1
  74. data/lib/decidim/core/version.rb +1 -1
  75. data/lib/decidim/events/base_event.rb +4 -0
  76. data/lib/decidim/has_private_users.rb +1 -0
  77. data/lib/decidim/seeds.rb +1 -1
  78. data/lib/tasks/upgrade/decidim_remove_deleted_users_left_data_tasks.rake +30 -0
  79. data/lib/tasks/upgrade/fix_deleted_private_follows.rake +26 -0
  80. metadata +25 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 170c5d444f05cfbcae31786562762966232e9fadad30da014a19a6ceb239a768
4
- data.tar.gz: cb838708158da84fdea7082175501cd7d2bed5499b7a2450c10e3ab1b79858b9
3
+ metadata.gz: f8792833d7ba900781bcd99e714b0fc117c8bf63b1d92894a12a4d8d9eebfcab
4
+ data.tar.gz: 21ae4185554af11eb516c1e7e0b6af616497331ab28234bd1c5199636fe40402
5
5
  SHA512:
6
- metadata.gz: db97bde00dcc402180828529bb1801c527a4565d7205ce1432f6eba97348c83ce58770548fddd6c71421c6202bb70cd269bd898d7059e5cb61db3d9d84fd903c
7
- data.tar.gz: c5cb74531f7240c2d1a9feb356c5e3b44e9da7016b127b048d081dc968796ce546d59bbd0088b4d1134aad40c4abe65db9cd358981c93c3ca84d9964365eebab
6
+ metadata.gz: 8d56c970e80a667e474858352900d599b48dc392d99c239e3ea732af530f457cbe0a72276b9da630e5aff999eff6585dbe8ce7a8da66346df7ee491901366d59
7
+ data.tar.gz: aba95c516675ae9eff886fb93c4c29c94fede6adb809c26aa2fb2bf17fde468c7e1a7f9a8875708f13061595410f0dfaff83938ff7ff011682b8011f1e99d776
@@ -1,7 +1,7 @@
1
1
  <%= link_to resource_path, class: classes[:default], id: resource_id do %>
2
2
  <div class="<%= classes[:img] %>">
3
3
  <% if has_image? %>
4
- <%= image_tag resource_image_url, alt: alt_title %>
4
+ <%= image_tag resource_image_url, alt: "" %>
5
5
  <% else %>
6
6
  <%= external_icon "media/images/placeholder-card-g.svg", class: "card__placeholder-g" %>
7
7
  <% end %>
@@ -0,0 +1,12 @@
1
+ <div class="notification" data-notification>
2
+ <div class="notification__wrapper">
3
+ <div class="notification__time" title="<%= l(notification.created_at) %>"> <%= notification.created_at_in_words %></div>
4
+ <div class="notification__snippet">
5
+ <span class="notification__snippet-title text-gray"><%= t("decidim.notifications.show.deleted") %></span>
6
+ </div>
7
+ </div>
8
+ <%= link_to model, remote: true, method: :delete, class: "notification__button", data: { "notification-read": "" } do %>
9
+ <span class="sr-only md:not-sr-only"><%= t("mark_as_read", scope: "layouts.decidim.notifications_dashboard") %></span>
10
+ <%= icon "check-line", class: "fill-current" %>
11
+ <% end %>
12
+ </div>
@@ -0,0 +1,12 @@
1
+ <div class="notification" data-notification>
2
+ <div class="notification__wrapper">
3
+ <div class="notification__time" title="<%= l(notification.created_at) %>"> <%= notification.created_at_in_words %></div>
4
+ <div class="notification__snippet">
5
+ <span class="notification__snippet-title text-gray"><%= t("decidim.notifications.show.not_available") %></span>
6
+ </div>
7
+ </div>
8
+ <%= link_to model, remote: true, method: :delete, class: "notification__button", data: { "notification-read": "" } do %>
9
+ <span class="sr-only md:not-sr-only"><%= t("mark_as_read", scope: "layouts.decidim.notifications_dashboard") %></span>
10
+ <%= icon "check-line", class: "fill-current" %>
11
+ <% end %>
12
+ </div>
@@ -7,7 +7,11 @@ module Decidim
7
7
  include Decidim::Core::Engine.routes.url_helpers
8
8
 
9
9
  def show
10
- if notification.event_class_instance.try(:hidden_resource?)
10
+ if !notification.can_participate?(current_user)
11
+ render :not_available
12
+ elsif notification.deleted_resource?
13
+ render :deleted
14
+ elsif notification.hidden_resource?
11
15
  render :moderated
12
16
  else
13
17
  render :show
@@ -1,7 +1,8 @@
1
1
  <%= decidim_modal id: "socialShare", class: "share-modal" do %>
2
2
  <div data-dialog-container>
3
3
  <%= icon "share-line" %>
4
- <h2 id="dialog-title-socialShare" tabindex="-1" data-dialog-title><%= t("share", scope: "decidim.shared.share_modal") %></h2>
4
+ <h2 id="dialog-title-social-share-modal" tabindex="-1" data-dialog-title><%= t("share", scope: "decidim.shared.share_modal") %></h2>
5
+
5
6
  <div>
6
7
  <%= social_share_button_tag(decidim_page_title,
7
8
  url: decidim_meta_url,
@@ -20,6 +20,15 @@ module Decidim
20
20
  destroy_user_identities
21
21
  destroy_user_group_memberships
22
22
  destroy_follows
23
+ destroy_user_versions
24
+ destroy_user_private_exports
25
+ destroy_user_access_grants
26
+ destroy_user_access_tokens
27
+ destroy_user_reminders
28
+ destroy_user_notifications
29
+ destroy_user_badges
30
+ destroy_user_endorsements
31
+ destroy_user_reports
23
32
  destroy_participatory_space_private_user
24
33
  delegate_destroy_to_participatory_spaces
25
34
  end
@@ -48,8 +57,44 @@ module Decidim
48
57
  current_user.save!
49
58
  end
50
59
 
60
+ def destroy_user_badges
61
+ Decidim::Gamification::BadgeScore.where(user: current_user).find_each(&:destroy)
62
+ end
63
+
64
+ def destroy_user_reports
65
+ Decidim::UserModeration.where(user: current_user).find_each(&:destroy)
66
+ end
67
+
68
+ def destroy_user_endorsements
69
+ Decidim::Endorsement.where(author: current_user).find_each(&:destroy)
70
+ end
71
+
51
72
  def destroy_user_identities
52
- current_user.identities.destroy_all
73
+ current_user.identities.find_each(&:destroy)
74
+ end
75
+
76
+ def destroy_user_versions
77
+ current_user.versions.find_each(&:destroy)
78
+ end
79
+
80
+ def destroy_user_private_exports
81
+ current_user.private_exports.find_each(&:destroy)
82
+ end
83
+
84
+ def destroy_user_access_grants
85
+ current_user.access_grants.find_each(&:destroy)
86
+ end
87
+
88
+ def destroy_user_access_tokens
89
+ current_user.access_tokens.find_each(&:destroy)
90
+ end
91
+
92
+ def destroy_user_reminders
93
+ current_user.reminders.find_each(&:destroy)
94
+ end
95
+
96
+ def destroy_user_notifications
97
+ current_user.notifications.find_each(&:destroy)
53
98
  end
54
99
 
55
100
  def destroy_user_group_memberships
@@ -57,12 +102,12 @@ module Decidim
57
102
  end
58
103
 
59
104
  def destroy_follows
60
- Decidim::Follow.where(followable: current_user).destroy_all
61
- Decidim::Follow.where(user: current_user).destroy_all
105
+ Decidim::Follow.where(followable: current_user).find_each(&:destroy)
106
+ Decidim::Follow.where(user: current_user).find_each(&:destroy)
62
107
  end
63
108
 
64
109
  def destroy_participatory_space_private_user
65
- Decidim::ParticipatorySpacePrivateUser.where(user: current_user).destroy_all
110
+ Decidim::ParticipatorySpacePrivateUser.where(user: current_user).find_each(&:destroy)
66
111
  end
67
112
 
68
113
  def delegate_destroy_to_participatory_spaces
@@ -43,7 +43,7 @@ module Decidim
43
43
 
44
44
  def interpolate(template)
45
45
  template
46
- .gsub("{{name}}", user.name)
46
+ .gsub("{{name}}", user.presenter.name)
47
47
  .gsub("{{organization}}", organization_name(organization))
48
48
  .gsub("{{help_url}}", url_helpers.pages_url(host: organization.host))
49
49
  .gsub("{{badges_url}}", url_helpers.gamification_badges_url(host: organization.host))
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ class RemoveSearchIndexesJob < ApplicationJob
5
+ queue_as :default
6
+
7
+ def perform(elements)
8
+ elements.each do |element|
9
+ element.remove_from_index(element)
10
+ next unless element.respond_to?(:comments)
11
+
12
+ element.comments.each do |comment|
13
+ Decidim::RemoveSearchIndexesJob.perform_later([comment])
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -17,13 +17,30 @@ module Decidim
17
17
  # Note that this could be improved by adding a "type" column to the notifications table
18
18
  # This fix can generate lists of notifications that are below the SIZE_LIMIT
19
19
  @notifications = notifications[0...SIZE_LIMIT].filter_map do |notification|
20
+ # Check if is a notification that can be sent on email
20
21
  next unless notification.event_class_instance.respond_to?(:email_intro)
22
+ # checks if the resource exists, as we have implemented the possibility of soft deleting resources
23
+ next unless resource_is_present?(notification)
24
+ # checks if the resource is visible
25
+ next unless notification.can_participate?(@user)
26
+ # It usually checks if the resource is reportable and is not hidden, however, there are some exceptions
27
+ # like in the comments, where we check if the resource and intended comment is visible.
28
+ next if notification.hidden_resource?
29
+ # It usually checks if the resource is deletable and is not deleted, however, there are some exceptions
30
+ # like in the comments, where we check if the resource and intended comment is visible.
31
+ next if notification.deleted_resource?
21
32
 
22
33
  Decidim::NotificationToMailerPresenter.new(notification)
23
34
  end
24
35
 
25
- mail(to: user.email, subject: @notifications_digest.subject)
36
+ mail(to: user.email, subject: @notifications_digest.subject) if @notifications.any?
26
37
  end
27
38
  end
39
+
40
+ private
41
+
42
+ def resource_is_present?(notification)
43
+ notification.resource
44
+ end
28
45
  end
29
46
  end
@@ -97,11 +97,14 @@ module Decidim
97
97
  def resource_description; end
98
98
 
99
99
  def can_participate_in_space?(user)
100
+ return false unless published?
101
+ return false unless participatory_space.published?
100
102
  return true unless participatory_space.try(:private_space?)
101
103
  return false unless user
102
104
 
103
105
  participatory_space.can_participate?(user)
104
106
  end
107
+ alias can_participate? can_participate_in_space?
105
108
 
106
109
  def private_non_transparent_space?
107
110
  return false unless participatory_space.respond_to?(:private_space?)
@@ -7,6 +7,8 @@ module Decidim
7
7
  belongs_to :resource, foreign_key: "decidim_resource_id", foreign_type: "decidim_resource_type", polymorphic: true
8
8
  belongs_to :user, foreign_key: "decidim_user_id", class_name: "Decidim::User"
9
9
 
10
+ delegate :can_participate?, to: :resource
11
+
10
12
  # Daily notifications should contain all notifications within the previous
11
13
  # day from the given day.
12
14
  scope :daily, ->(time = Time.now.utc) { where(created_at: (time - 1.day).all_day) }
@@ -40,5 +42,13 @@ module Decidim
40
42
  def self.export_serializer
41
43
  Decidim::DownloadYourDataSerializers::DownloadYourDataNotificationSerializer
42
44
  end
45
+
46
+ def hidden_resource?
47
+ event_class_instance.respond_to?(:hidden_resource?) && event_class_instance.hidden_resource?
48
+ end
49
+
50
+ def deleted_resource?
51
+ event_class_instance.respond_to?(:deleted_resource?) && event_class_instance.deleted_resource?
52
+ end
43
53
  end
44
54
  end
@@ -130,6 +130,10 @@ module Decidim
130
130
  deleted_at.present?
131
131
  end
132
132
 
133
+ def can_participate?(_user)
134
+ true
135
+ end
136
+
133
137
  # Public: whether the user has been officialized or not
134
138
  def officialized?
135
139
  !officialized_at.nil?
@@ -20,7 +20,7 @@ module Decidim
20
20
  has_one :blocking, class_name: "Decidim::UserBlock", foreign_key: :id, primary_key: :block_id, dependent: :destroy
21
21
 
22
22
  # Regex for name & nickname format validations
23
- REGEXP_NAME = /\A(?!.*[<>?%&\^*#@()\[\]=+:;"{}\\|])/
23
+ REGEXP_NAME = /\A(?!.*[<>?%&\^*#@()\[\]=+:;"{}\\|\n\r])/m
24
24
  REGEXP_NICKNAME = /\A[a-z0-9_-]+\z/
25
25
 
26
26
  has_one_attached :avatar
@@ -28,7 +28,6 @@ export default Link.extend({
28
28
  ...this.parent?.(),
29
29
  allowTargetControl: false,
30
30
  HTMLAttributes: {
31
- target: "_blank",
32
31
  class: null
33
32
  }
34
33
  }
@@ -80,7 +80,11 @@ export default function createEditor(container) {
80
80
  const toolbar = createEditorToolbar(editor);
81
81
  container.insertBefore(toolbar, editorContainer);
82
82
 
83
- editor.on("update", () => (input.value = editor.getHTML()));
83
+ editor.on("update", () => {
84
+ input.value = editor.isEmpty
85
+ ? ""
86
+ : editor.getHTML();
87
+ });
84
88
 
85
89
  return editor;
86
90
  }
@@ -37,14 +37,14 @@ describe("Link", () => {
37
37
  await sleep(50);
38
38
 
39
39
  expect(editor.getHTML()).toEqual(
40
- '<p>Hello, <a target="_blank" href="https://decidim.org">world</a>!</p>'
40
+ '<p>Hello, <a href="https://decidim.org" target="_blank">world</a>!</p>'
41
41
  );
42
42
  });
43
43
 
44
44
  it("allows editing the link through the dialog", async () => {
45
45
  editorElement.focus();
46
46
  await updateContent(editorElement,
47
- '<p>Hello, <a target="_blank" href="https://decidim.org">world</a>!</p>'
47
+ '<p>Hello, <a href="https://decidim.org" target="_blank" >world</a>!</p>'
48
48
  );
49
49
 
50
50
  // Set the editor cursor inside the link
@@ -26,7 +26,7 @@ export default (ctx) => {
26
26
  await sleep(0);
27
27
 
28
28
  expect(ctx.prosemirror.innerHTML).toEqual(
29
- '<p>Hello, <a target="_blank" href="https://decidim.org">world</a>!</p>'
29
+ '<p>Hello, <a href="https://decidim.org" target="_blank">world</a>!</p>'
30
30
  );
31
31
  });
32
32
  });
@@ -2,7 +2,11 @@
2
2
  @apply invisible opacity-0 fixed z-50 inset-0 bg-[rgba(0,0,0,0.25)] transition duration-300;
3
3
 
4
4
  & > * {
5
- @apply absolute inset-1/2 ltr:-translate-x-1/2 rtl:translate-x-1/2 -translate-y-1/2 w-[90%] lg:max-w-[900px] max-h-[95vh] h-fit overflow-y-auto p-6 bg-white z-50 rounded shadow-[0_4px_6px_rgba(211,211,211,0.25)];
5
+ @apply absolute inset-1/2 translate-x-[-50%] translate-y-[-50%] w-[90%] lg:max-w-[900px] max-h-[95vh] h-fit overflow-y-auto p-6 bg-white z-50 rounded shadow-[0_4px_6px_rgba(211,211,211,0.25)];
6
+
7
+ [dir="rtl"] & {
8
+ @apply translate-x-[50%];
9
+ }
6
10
 
7
11
  & > svg:only-child {
8
12
  @apply w-8 h-8 mx-auto text-gray-2 fill-current animate-spin;
@@ -8,7 +8,7 @@
8
8
  }
9
9
 
10
10
  &__code {
11
- @apply block max-h-24 overflow-auto border border-gray-3 bg-background p-2 break-all;
11
+ @apply block max-h-24 overflow-auto border border-gray-3 bg-background p-2 break-words whitespace-pre-wrap;
12
12
  }
13
13
 
14
14
  a {
@@ -10,6 +10,7 @@ module Decidim
10
10
  # overwrite `BasePresenter#user_presenter` to return your custom user presenter.
11
11
  # The only requirement for custom renderers is that they should respond to `present`.
12
12
  class UserPresenter
13
+ include Decidim::SanitizeHelper
13
14
  # Public: Initializes the presenter.
14
15
  #
15
16
  # user - An instance of Decidim::User
@@ -60,7 +61,7 @@ module Decidim
60
61
  #
61
62
  # Returns an HTML-safe String.
62
63
  def present_user_name
63
- extra["name"].html_safe
64
+ decidim_sanitize_translated(extra["name"]).html_safe
64
65
  end
65
66
 
66
67
  # Private: Presents the nickname of the user performing the action.
@@ -6,7 +6,12 @@ module Decidim
6
6
  #
7
7
  class UserPresenter < SimpleDelegator
8
8
  include ActionView::Helpers::UrlHelper
9
- include Decidim::TranslatableAttributes
9
+ include Decidim::SanitizeHelper
10
+
11
+ # name sanitized
12
+ def name
13
+ decidim_sanitize_translated(__getobj__.name)
14
+ end
10
15
 
11
16
  #
12
17
  # nickname presented in a twitter-like style
@@ -21,7 +21,7 @@
21
21
  <ul id="dropdown-menu-pages" class="vertical-tabs__list" role="menu">
22
22
  <% pages.each do |sibling| %>
23
23
  <li class="<%= "is-active" if page == sibling %>" role="menuitem">
24
- <%= link_to translated_attribute(sibling.title), page_path(sibling.slug), "aria-current": (page == sibling).to_s %>
24
+ <%= link_to translated_attribute(sibling.title), page_path(sibling.slug), "aria-current": ("page" if page == sibling) %>
25
25
  </li>
26
26
  <% end %>
27
27
  </ul>
@@ -9,6 +9,6 @@
9
9
  i18n_scope:,
10
10
  title: t("#{i18n_scope}.label"),
11
11
  role: :menuitem,
12
- class: "button button__sm button__text-secondary #{order_name == order ? "underline font-bold" : "font-normal"}" %>
12
+ class: "button button__sm button__text-secondary #{order_name == order ? "underline font-bold" : "font-normal"}", "aria-current": order_name == order ? "true" : "" %>
13
13
  <% end %>
14
14
  </div>
@@ -10,8 +10,9 @@
10
10
  </div>
11
11
 
12
12
  <div>
13
- <div class="main-bar__links-mobile__trigger" onclick="document.querySelector('#dropdown-trigger-links-mobile').click();document.querySelector('#dropdown-menu-account-mobile').removeAttribute('aria-modal')">
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')">
14
14
  <%= icon "close-line" %>
15
+ <p class="sr-only"><%= t("close", scope: "decidim.shared.flag_modal") %></p>
15
16
  </div>
16
17
  </div>
17
18
  </div>
@@ -37,3 +38,16 @@
37
38
  </ul>
38
39
  </div>
39
40
  </div>
41
+ <script type="text/javascript">
42
+ const closeDiv = document.querySelector('div.main-bar__links-mobile__trigger');
43
+ const menuDropdown = document.querySelector('#dropdown-menu-account-mobile');
44
+ const dropdownTrigger = document.querySelector('#dropdown-trigger-links-mobile');
45
+ // 32 is code for space bar and 13 is code for enter
46
+ closeDiv.addEventListener('keydown', function(e){
47
+ if (e.keyCode === 13 || e.keyCode === 32) {
48
+ menuDropdown.removeAttribute('aria-modal');
49
+ menuDropdown.setAttribute('aria-hidden', "true");
50
+ dropdownTrigger.focus();
51
+ }
52
+ })
53
+ </script>
@@ -1053,7 +1053,6 @@ ar:
1053
1053
  hello: مرحبا %{name}،
1054
1054
  intro:
1055
1055
  daily: 'هذه هي إخطارات اليوم الأخير بناءً على النشاط الذي تتابعه:'
1056
- real_time: 'هذا تنبيه عن النشاط الذي تتبعّه:'
1057
1056
  weekly: 'هذه هي إخطارات الأسبوع الأخير بناءً على النشاط الذي تتابعه:'
1058
1057
  outro: لقد تلقيت هذه الإشعارات لأنك تتبع هذا المحتوى أو مؤلفيه. يمكنك إلغاء متابعتها من صفحات كل منهم.
1059
1058
  see_more: عرض المزيد من الإشعارات
@@ -1102,15 +1101,12 @@ ar:
1102
1101
  proposals_explanation: تقديم مقترحات ، ودعم المقترحات الحالية وتعزيز التغييرات التي تريد رؤيتها.
1103
1102
  footer_sub_hero:
1104
1103
  footer_sub_hero_headline: مرحبًا بكم على المنصة التشاركية لـ %{organization}.
1105
- register: تسجيل
1106
1104
  hero:
1107
1105
  participate: مشاركة
1108
1106
  participate_title: المشاركة في مسارات المنصة
1109
1107
  welcome: مرحبًا بكم على %{organization}!
1110
1108
  statistics:
1111
1109
  headline: الحالة الحالية لـ %{organization}
1112
- sub_hero:
1113
- register: تسجيل
1114
1110
  index:
1115
1111
  standalone_pages: صفحات
1116
1112
  subheading: انتقل من خلال صفحات المساعدة من %{name}
@@ -648,7 +648,6 @@ bg:
648
648
  files:
649
649
  file_cannot_be_processed: Файлът не може да бъде обработен
650
650
  file_resolution_too_large: Разделителната способност на файла е твърде голяма
651
- not_inside_organization: Файлът не е прикачен към никоя организация.
652
651
  internal_server_error:
653
652
  copied: Текстът е копиран!
654
653
  copy_error_message_clarification: Копирайте съобщението за грешка в клипборда
@@ -1207,11 +1206,9 @@ bg:
1207
1206
  same_language: Съдържанието е публикувано на предпочитания от вас език (%{language}), поради което в този имейл не се показва автоматичен превод.
1208
1207
  translated_text: 'Автоматично преведен текст:'
1209
1208
  notifications:
1210
- action_error: Възникна проблем при актуализирането на известията.
1211
1209
  no_notifications: Още няма известия.
1212
1210
  show:
1213
1211
  missing_event: Упс, това известие принадлежи на съдържание, което вече не е налично. Можете да го подминете.
1214
- moderated: Съдържанието е модерирано
1215
1212
  notifications_digest_mailer:
1216
1213
  header:
1217
1214
  daily: Ежедневно обобщение на известията
@@ -1275,15 +1272,12 @@ bg:
1275
1272
  footer_sub_hero:
1276
1273
  footer_sub_hero_body_html: Нека изградим по-отворено, прозрачно и задружно общество.<br /> Присъединете се, участвайте и решавайте.
1277
1274
  footer_sub_hero_headline: Добре дошли в платформата за сътрудничество %{organization}!
1278
- register: Регистрация
1279
1275
  hero:
1280
1276
  participate: Участвайте
1281
1277
  participate_title: Участвайте в процесите на платформата
1282
1278
  welcome: Добре дошли в %{organization}!
1283
1279
  statistics:
1284
1280
  headline: Текущо състояние на %{organization}
1285
- sub_hero:
1286
- register: Регистрация
1287
1281
  index:
1288
1282
  standalone_pages: Страници
1289
1283
  subheading: Придвижвайте се в помощта на %{name}
@@ -1586,8 +1580,6 @@ bg:
1586
1580
  subject: Получихте покана да управлявате %{organization}
1587
1581
  invite_collaborator:
1588
1582
  subject: Получихте покана да сътрудничите на %{organization}
1589
- invite_private_user:
1590
- subject: Поканени сте в частен процес на сътрудничество в %{organization}
1591
1583
  organization_admin_invitation_instructions:
1592
1584
  subject: Получихте покана да управлявате %{organization}
1593
1585
  password_change:
@@ -788,7 +788,7 @@ ca-IT:
788
788
  phone: El número de telèfon d'aquest grup d'usuàries
789
789
  verified_at: La data i l'hora en què es va verificar aquest grup d'usuàries
790
790
  users:
791
- about: L'àlies d'aquesta usuària
791
+ about: La descripció de perfil d'aquesta participant
792
792
  accepted_tos_version: La data en què la usuària va acceptar els Termes i Condicions d'ús d'aquesta plataforma
793
793
  admin: Si aquesta usuària és una administradora
794
794
  confirmation_sent_at: La data i l'hora en què es va enviar la confirmació
@@ -799,7 +799,7 @@ ca-IT:
799
799
  delete_reason: La raó donada per eliminar a aquesta usuària
800
800
  deleted_at: La data i l'hora en què es va eliminar aquesta usuària
801
801
  email: L'adreça de correu electrònic d'aquesta usuària
802
- followers_count: El nombre de participants que segueixen aquesta participant
802
+ followers_count: El nombre de participants que segueixen a aquesta participant
803
803
  following_count: El nombre de participants a què segueix aquesta participant
804
804
  id: L'identificador únic d'aquesta usuària
805
805
  invitation_accepted_at: La data i l'hora en què es va acceptar la invitació
@@ -812,11 +812,11 @@ ca-IT:
812
812
  locale: La configuració regional (idioma) que ha seleccionat aquesta usuària
813
813
  managed: Si es tracta d'una usuària gestionada (impersonada) o no
814
814
  name: El nom d'usuària de la usuària
815
- newsletter_notifications_at: La data i l'hora en què aquesta usuària va rebre un butlletí informatiu per darrera vegada
815
+ newsletter_notifications_at: La data i l'hora en què aquesta usuària es va subscriure per rebre el butlletí informatiu
816
816
  nickname: L'àlies d'aquesta usuària
817
817
  notification_settings: La configuració de les notificacions que ha seleccionat aquesta usuària
818
818
  notifications_sending_frequency: La freqüència amb què aquesta usuària rep les notificacions
819
- officialized_as: La descripció de l'oficialització (Alcaldia, Conselleria, etc.)
819
+ officialized_as: La descripció de l'oficialització (Alcaldia, Regidoria, etc.)
820
820
  officialized_at: La data i l'hora en què aquesta usuària va ser oficialitzada
821
821
  organization: L'organització a la qual pertany aquesta usuària
822
822
  password_updated_at: La data en què van canviar per darrera vegada les seves contrasenyes
@@ -868,7 +868,7 @@ ca-IT:
868
868
  files:
869
869
  file_cannot_be_processed: No s'ha pogut processar el fitxer
870
870
  file_resolution_too_large: La resolució de l'arxiu és massa gran
871
- not_inside_organization: L'arxiu no està relacionat amb cap organització
871
+ not_inside_organization: L'arxiu no està vinculat a cap organització.
872
872
  internal_server_error:
873
873
  copied: Text copiat!
874
874
  copy_error_message_clarification: Missatge d'error copiat amb el porta-retalls
@@ -1480,11 +1480,13 @@ ca-IT:
1480
1480
  same_language: El contingut s'ha publicat en la teva llengua de preferència (%{language}), és per això que no es mostra cap traducció automàtica en aquest correu electrònic.
1481
1481
  translated_text: 'Text de la traducció automàtica:'
1482
1482
  notifications:
1483
- action_error: S'ha produït un error en actualitzar les notificacions.
1483
+ action_error: S'ha produït un error en actualitzar la configuració de les notificacions.
1484
1484
  no_notifications: Encara no hi ha notificacions.
1485
1485
  show:
1486
+ deleted: El contingut ha estat eliminat per l'autora.
1486
1487
  missing_event: Vaja, aquesta notificació pertany a un element que ja no està disponible. Pots descartar-la.
1487
- moderated: Contingut moderat
1488
+ moderated: El contingut s'ha amagat correctament a través de la moderació.
1489
+ not_available: Vaja, aquesta notificació pertany a un element que ja no està disponible. Pots descartar-la.
1488
1490
  notifications_digest_mailer:
1489
1491
  header:
1490
1492
  daily: Resum diari de notificacions
@@ -1647,9 +1649,9 @@ ca-IT:
1647
1649
  title: Com obrir i treballar amb aquests fitxers
1648
1650
  license:
1649
1651
  body_1_html: Aquesta base de dades de "%{organization_name}" està disponible sota %{link_database}. Qualsevol dret sobre els continguts individuals de la base de dades està sota la llicència %{link_contents}.
1650
- license_contents_link: https://opendatacommons.org/licenses/dbcl/1-0/
1652
+ license_contents_link: https://opendatacommons.org/licenses/dbcl/1.0/
1651
1653
  license_contents_name: Llicència dels continguts a la base de dades
1652
- license_database_link: https://opendatacommons.org/licenses/odbl/1-0/
1654
+ license_database_link: https://opendatacommons.org/licenses/odbl/1.0/
1653
1655
  license_database_name: Llicència Oberta per a base de dades
1654
1656
  title: Llicència
1655
1657
  title: Dades obertes
@@ -1672,7 +1674,7 @@ ca-IT:
1672
1674
  footer_sub_hero:
1673
1675
  footer_sub_hero_body_html: Construïm una societat més oberta, transparent i col·laborativa.<br /> Uneix-te, participa i decideix.
1674
1676
  footer_sub_hero_headline: Benvinguda a la plataforma participativa %{organization}.
1675
- register: Registra't
1677
+ register: Crear un compte
1676
1678
  hero:
1677
1679
  participate: Participa
1678
1680
  participate_title: Participa en els processos de la plataforma
@@ -1680,7 +1682,7 @@ ca-IT:
1680
1682
  statistics:
1681
1683
  headline: Estat actual de %{organization}
1682
1684
  sub_hero:
1683
- register: Registra't
1685
+ register: Crear un compte
1684
1686
  register_title: Crea un compte
1685
1687
  index:
1686
1688
  standalone_pages: Pàgines