decidim-core 0.30.3 → 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.
- checksums.yaml +4 -4
- data/app/cells/decidim/activity_cell.rb +6 -0
- data/app/cells/decidim/card_g/show.erb +1 -1
- data/app/cells/decidim/notification/deleted.erb +12 -0
- data/app/cells/decidim/notification/not_available.erb +12 -0
- data/app/cells/decidim/notification_cell.rb +5 -1
- data/app/cells/decidim/share_widget/modal.erb +2 -1
- data/app/commands/decidim/destroy_account.rb +49 -4
- data/app/controllers/decidim/download_your_data_controller.rb +5 -2
- data/app/events/decidim/welcome_notification_event.rb +1 -1
- data/app/jobs/decidim/remove_search_indexes_job.rb +18 -0
- data/app/mailers/decidim/notifications_digest_mailer.rb +18 -1
- data/app/models/decidim/component.rb +3 -0
- data/app/models/decidim/notification.rb +10 -0
- data/app/models/decidim/private_export.rb +4 -0
- data/app/models/decidim/user.rb +4 -0
- data/app/models/decidim/user_base_entity.rb +1 -1
- data/app/packs/src/decidim/editor/extensions/link/index.js +0 -1
- data/app/packs/src/decidim/editor/index.js +5 -1
- data/app/packs/src/decidim/editor/test/extensions/link.test.js +2 -2
- data/app/packs/src/decidim/editor/test/toolbar/shared/behaves_like_basic_link.js +1 -1
- data/app/packs/src/decidim/map/controller/markers.js +3 -1
- data/app/packs/stylesheets/decidim/_footer.scss +5 -0
- data/app/packs/stylesheets/decidim/_modal.scss +5 -1
- data/app/packs/stylesheets/decidim/_modal_fingerprint.scss +1 -1
- data/app/presenters/decidim/log/user_presenter.rb +2 -1
- data/app/presenters/decidim/user_presenter.rb +6 -1
- data/app/services/decidim/download_your_data_exporter.rb +15 -4
- data/app/services/decidim/open_data_exporter.rb +2 -1
- data/app/views/decidim/download_your_data/_export.html.erb +1 -1
- data/app/views/decidim/export_mailer/download_your_data_export.html.erb +1 -1
- data/app/views/decidim/export_mailer/export.html.erb +1 -1
- data/app/views/decidim/pages/_tabbed.html.erb +1 -1
- data/app/views/decidim/shared/_orders.html.erb +1 -1
- data/app/views/layouts/decidim/header/_main_links_mobile_account.html.erb +15 -1
- data/config/locales/ar.yml +0 -4
- data/config/locales/bg.yml +0 -8
- data/config/locales/ca-IT.yml +17 -13
- data/config/locales/ca.yml +15 -11
- data/config/locales/cs.yml +9 -19
- data/config/locales/de.yml +5 -21
- data/config/locales/el.yml +0 -3
- data/config/locales/en.yml +21 -17
- data/config/locales/es-MX.yml +14 -10
- data/config/locales/es-PY.yml +14 -10
- data/config/locales/es.yml +13 -9
- data/config/locales/eu.yml +54 -51
- data/config/locales/fa-IR.yml +3 -0
- data/config/locales/fi-plain.yml +12 -8
- data/config/locales/fi.yml +12 -8
- data/config/locales/fr-CA.yml +23 -12
- data/config/locales/fr.yml +23 -12
- data/config/locales/ga-IE.yml +0 -4
- data/config/locales/gl.yml +0 -3
- data/config/locales/hu.yml +0 -6
- data/config/locales/id-ID.yml +0 -3
- data/config/locales/it.yml +3 -4
- data/config/locales/ja.yml +26 -22
- data/config/locales/ko.yml +3 -0
- data/config/locales/lb.yml +0 -3
- data/config/locales/lt.yml +0 -5
- data/config/locales/lv.yml +0 -3
- data/config/locales/mt.yml +3 -0
- data/config/locales/nl.yml +0 -3
- data/config/locales/no.yml +0 -3
- data/config/locales/pl.yml +11 -7
- data/config/locales/pt-BR.yml +552 -5
- data/config/locales/pt.yml +0 -3
- data/config/locales/ro-RO.yml +453 -126
- data/config/locales/ru.yml +0 -4
- data/config/locales/sk.yml +0 -3
- data/config/locales/sl.yml +0 -1
- data/config/locales/sv.yml +28 -13
- data/config/locales/tr-TR.yml +0 -5
- data/config/locales/uk.yml +0 -3
- data/config/locales/vi.yml +3 -0
- data/config/locales/zh-CN.yml +0 -3
- data/config/locales/zh-TW.yml +0 -5
- data/db/migrate/20250819110800_convert_private_exports_id_to_uuid.rb +55 -0
- data/decidim-core.gemspec +1 -0
- data/lib/decidim/core/engine.rb +1 -0
- data/lib/decidim/core/seeds.rb +3 -3
- data/lib/decidim/core/test/factories.rb +27 -2
- data/lib/decidim/core/test/shared_examples/comments_examples.rb +59 -5
- data/lib/decidim/core/test/shared_examples/fingerprint_examples.rb +13 -0
- data/lib/decidim/core/test/shared_examples/process_announcements_examples.rb +35 -1
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/events/base_event.rb +4 -0
- data/lib/decidim/has_private_users.rb +1 -0
- data/lib/decidim/seeds.rb +1 -1
- data/lib/decidim/webpacker/configuration.rb +5 -1
- data/lib/tasks/upgrade/clean.rake +11 -0
- data/lib/tasks/upgrade/decidim_fix_action_log.rake +28 -0
- data/lib/tasks/upgrade/decidim_remove_deleted_users_left_data_tasks.rake +30 -0
- data/lib/tasks/upgrade/fix_deleted_private_follows.rake +26 -0
- metadata +27 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f8792833d7ba900781bcd99e714b0fc117c8bf63b1d92894a12a4d8d9eebfcab
|
|
4
|
+
data.tar.gz: 21ae4185554af11eb516c1e7e0b6af616497331ab28234bd1c5199636fe40402
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8d56c970e80a667e474858352900d599b48dc392d99c239e3ea732af530f457cbe0a72276b9da630e5aff999eff6585dbe8ce7a8da66346df7ee491901366d59
|
|
7
|
+
data.tar.gz: aba95c516675ae9eff886fb93c4c29c94fede6adb809c26aa2fb2bf17fde468c7e1a7f9a8875708f13061595410f0dfaff83938ff7ff011682b8011f1e99d776
|
|
@@ -12,6 +12,12 @@ module Decidim
|
|
|
12
12
|
return unless renderable?
|
|
13
13
|
|
|
14
14
|
render
|
|
15
|
+
rescue NoMethodError => e
|
|
16
|
+
# Soft-deleted components or participatory spaces could cause errors
|
|
17
|
+
# when rendering activities. We log them for further inspection but
|
|
18
|
+
# avoid breaking the entire activity feed.
|
|
19
|
+
Rails.logger.error("Error rendering activity cell for #{model.id}: #{e.message}")
|
|
20
|
+
nil
|
|
15
21
|
end
|
|
16
22
|
|
|
17
23
|
# Since activity logs could be linked to resource no longer available
|
|
@@ -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:
|
|
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.
|
|
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-
|
|
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.
|
|
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).
|
|
61
|
-
Decidim::Follow.where(user: current_user).
|
|
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).
|
|
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,10 @@ module Decidim
|
|
|
43
43
|
def download_file
|
|
44
44
|
enforce_permission_to(:download, :user, current_user:)
|
|
45
45
|
|
|
46
|
-
if private_export.
|
|
46
|
+
if private_export.blank?
|
|
47
|
+
flash[:error] = t("decidim.account.download_your_data_export.export_not_found")
|
|
48
|
+
redirect_to download_your_data_path
|
|
49
|
+
elsif private_export.expired?
|
|
47
50
|
flash[:error] = t("decidim.account.download_your_data_export.export_expired")
|
|
48
51
|
redirect_to download_your_data_path
|
|
49
52
|
elsif private_export.file.attached?
|
|
@@ -57,7 +60,7 @@ module Decidim
|
|
|
57
60
|
private
|
|
58
61
|
|
|
59
62
|
def private_export
|
|
60
|
-
@private_export ||= current_user.private_exports.
|
|
63
|
+
@private_export ||= current_user.private_exports.where(uuid: params[:uuid]).first
|
|
61
64
|
end
|
|
62
65
|
|
|
63
66
|
def help_definitions
|
|
@@ -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
|
data/app/models/decidim/user.rb
CHANGED
|
@@ -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
|
|
@@ -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", () =>
|
|
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
|
|
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
|
|
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
|
|
29
|
+
'<p>Hello, <a href="https://decidim.org" target="_blank">world</a>!</p>'
|
|
30
30
|
);
|
|
31
31
|
});
|
|
32
32
|
});
|
|
@@ -67,7 +67,9 @@ export default class MapMarkersController extends MapController {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
clearMarkers() {
|
|
70
|
-
|
|
70
|
+
if (this.markerClusters !== null) {
|
|
71
|
+
this.map.removeLayer(this.markerClusters);
|
|
72
|
+
}
|
|
71
73
|
this.markerClusters = new L.MarkerClusterGroup();
|
|
72
74
|
this.map.addLayer(this.markerClusters);
|
|
73
75
|
}
|
|
@@ -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
|
|
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;
|
|
@@ -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::
|
|
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
|
|
@@ -22,14 +22,21 @@ module Decidim
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
# i18n-tasks-use t("decidim.download_your_data.show.download_your_data")
|
|
25
|
-
def export
|
|
26
|
-
|
|
25
|
+
def export(retries: 0)
|
|
26
|
+
data.rewind
|
|
27
|
+
user_export = user.private_exports.build(file_size: data.length)
|
|
27
28
|
user_export.export_type = name
|
|
28
|
-
user_export.
|
|
29
|
+
user_export.content_type = "application/zip"
|
|
29
30
|
user_export.expires_at = Decidim.download_your_data_expiry_time.from_now
|
|
30
31
|
user_export.metadata = {}
|
|
31
32
|
user_export.save!
|
|
32
|
-
user_export
|
|
33
|
+
user_export.file.attach(io: data, filename: "#{name}.zip", content_type: "application/zip")
|
|
34
|
+
|
|
35
|
+
return user_export.reload if user_export.reload.file.attached?
|
|
36
|
+
return user_export.reload if retries >= 3
|
|
37
|
+
|
|
38
|
+
user_export.destroy!
|
|
39
|
+
export(retries: retries + 1)
|
|
33
40
|
end
|
|
34
41
|
|
|
35
42
|
private
|
|
@@ -37,6 +44,10 @@ module Decidim
|
|
|
37
44
|
attr_reader :user, :export_format, :name
|
|
38
45
|
|
|
39
46
|
def data
|
|
47
|
+
@data ||= load_data!
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def load_data!
|
|
40
51
|
user_data, user_attachments = data_and_attachments_for_user
|
|
41
52
|
buffer = Zip::OutputStream.write_buffer do |out|
|
|
42
53
|
save_user_data(out, user_data)
|
|
@@ -116,9 +116,10 @@ module Decidim
|
|
|
116
116
|
end
|
|
117
117
|
|
|
118
118
|
def data_for_participatory_space(export_manifest)
|
|
119
|
-
collection = participatory_spaces.flat_map do |participatory_space|
|
|
119
|
+
collection = participatory_spaces.filter { |space| space.manifest.name == export_manifest.manifest.name }.flat_map do |participatory_space|
|
|
120
120
|
export_manifest.collection.call(participatory_space)
|
|
121
121
|
end
|
|
122
|
+
|
|
122
123
|
serializer = export_manifest.open_data_serializer.nil? ? export_manifest.serializer : export_manifest.open_data_serializer
|
|
123
124
|
exporter = Decidim::Exporters::CSV.new(collection, serializer)
|
|
124
125
|
get_help_definition(:spaces, exporter, export_manifest) unless collection.empty?
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<td class="text-left p-4"><%= t(export.export_type, scope:"decidim.download_your_data.show") %></td>
|
|
3
3
|
<td class="text-center"><%= export.expired? ? t("expired", scope:"decidim.download_your_data.show") : l(export.expires_at, format: :decidim_short) %></td>
|
|
4
4
|
<td class="py-4">
|
|
5
|
-
<%= button_to download_download_your_data_path(export),
|
|
5
|
+
<%= button_to download_download_your_data_path(uuid: export.uuid),
|
|
6
6
|
class: "button button__sm button__transparent-secondary m-auto block",
|
|
7
7
|
disabled: export.expired?,
|
|
8
8
|
aria: { label: t("download", scope:"decidim.download_your_data.show") },
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p class="email-button email-button__cta">
|
|
6
|
-
<%= link_to t(".download"), download_download_your_data_url(@private_export, host: @organization.host), class: "button expanded hollow button--sc" %>
|
|
6
|
+
<%= link_to t(".download"), download_download_your_data_url(uuid: @private_export.uuid, host: @organization.host), class: "button expanded hollow button--sc" %>
|
|
7
7
|
</p>
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p class="email-button email-button__cta">
|
|
6
|
-
<%= link_to t(".download"), download_download_your_data_url(@private_export, host: @organization.host), class: "button expanded hollow button--sc" %>
|
|
6
|
+
<%= link_to t(".download"), download_download_your_data_url(uuid: @private_export.uuid, host: @organization.host), class: "button expanded hollow button--sc" %>
|
|
7
7
|
</p>
|
|
@@ -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)
|
|
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>
|
data/config/locales/ar.yml
CHANGED
|
@@ -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}
|