decidim-core 0.30.0.rc2 → 0.30.0.rc3
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/amendable/amendments/show.erb +1 -1
- data/app/cells/decidim/profile_actions/show.erb +1 -1
- data/app/cells/decidim/report_button/already_reported_modal.erb +2 -2
- data/app/cells/decidim/report_button/flag_modal.erb +13 -27
- data/app/cells/decidim/report_button_cell.rb +2 -8
- data/app/cells/decidim/report_user_button/already_reported_modal.erb +11 -0
- data/app/cells/decidim/report_user_button/flag_modal.erb +46 -0
- data/app/cells/decidim/report_user_button/show.erb +2 -0
- data/app/cells/decidim/report_user_button_cell.rb +59 -0
- data/app/cells/decidim/resource_types_filter/show.erb +1 -1
- data/app/cells/decidim/resource_types_filter_cell.rb +6 -6
- data/app/cells/decidim/user_activity/show.erb +1 -1
- data/app/commands/decidim/create_omniauth_registration.rb +14 -8
- data/app/controllers/decidim/profiles_controller.rb +2 -2
- data/app/controllers/decidim/user_activities_controller.rb +1 -1
- data/app/forms/decidim/account_form.rb +2 -2
- data/app/jobs/decidim/hide_child_resources_job.rb +3 -3
- data/app/jobs/decidim/migrate/paper_trail_job.rb +33 -0
- data/app/models/decidim/user.rb +0 -4
- data/app/models/decidim/user_base_entity.rb +4 -0
- data/app/packs/src/decidim/sticky_footer.js +19 -0
- data/app/packs/stylesheets/decidim/_cards.scss +4 -0
- data/app/packs/stylesheets/decidim/_content_blocks.scss +1 -1
- data/app/packs/stylesheets/decidim/_login.scss +4 -0
- data/app/packs/stylesheets/decidim/_modal_authorization.scss +1 -1
- data/app/packs/stylesheets/decidim/_profile.scss +1 -1
- data/app/resolvers/decidim/meta_image_url_resolver.rb +1 -0
- data/app/services/decidim/static_map_generator.rb +1 -1
- data/app/views/decidim/devise/registrations/new.html.erb +1 -1
- data/app/views/decidim/devise/sessions/new.html.erb +1 -1
- data/app/views/decidim/devise/shared/_omniauth_buttons.html.erb +1 -1
- data/app/views/decidim/last_activities/index.html.erb +1 -1
- data/app/views/decidim/open_data/index.html.erb +1 -1
- data/config/locales/ar.yml +12 -25
- data/config/locales/bg.yml +8 -22
- data/config/locales/ca.yml +19 -33
- data/config/locales/cs.yml +16 -31
- data/config/locales/de.yml +6 -21
- data/config/locales/el.yml +8 -13
- data/config/locales/en.yml +2 -16
- data/config/locales/eo.yml +2 -0
- data/config/locales/es-MX.yml +14 -28
- data/config/locales/es-PY.yml +19 -33
- data/config/locales/es.yml +19 -33
- data/config/locales/eu.yml +52 -67
- data/config/locales/fi-plain.yml +11 -26
- data/config/locales/fi.yml +12 -27
- data/config/locales/fr-CA.yml +58 -20
- data/config/locales/fr.yml +58 -20
- data/config/locales/ga-IE.yml +2 -4
- data/config/locales/gl.yml +22 -13
- data/config/locales/hu.yml +7 -21
- data/config/locales/id-ID.yml +22 -13
- data/config/locales/is-IS.yml +10 -0
- data/config/locales/it.yml +22 -20
- data/config/locales/ja.yml +120 -21
- data/config/locales/lb.yml +19 -19
- data/config/locales/lt.yml +5 -17
- data/config/locales/lv.yml +16 -13
- data/config/locales/nl.yml +20 -17
- data/config/locales/no.yml +16 -16
- data/config/locales/pl.yml +4 -18
- data/config/locales/pt-BR.yml +8 -21
- data/config/locales/pt.yml +16 -16
- data/config/locales/ro-RO.yml +15 -20
- data/config/locales/ru.yml +23 -8
- data/config/locales/sk.yml +27 -16
- data/config/locales/sv.yml +11 -25
- data/config/locales/tr-TR.yml +21 -20
- data/config/locales/uk.yml +12 -1
- data/config/locales/zh-CN.yml +16 -13
- data/config/locales/zh-TW.yml +6 -16
- data/db/migrate/20240722215500_change_object_changes_on_versions.rb +4 -24
- data/lib/decidim/content_parsers/user_parser.rb +1 -1
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/map/provider/static_map/here.rb +34 -0
- data/lib/decidim/nicknamizable.rb +1 -1
- data/lib/tasks/upgrade/decidim_fix_nickname_uniqueness.rake +23 -20
- metadata +11 -13
- data/app/cells/decidim/author/flag.erb +0 -6
- data/app/cells/decidim/author/flag_user.erb +0 -14
- data/app/cells/decidim/flag_modal/flag_user.erb +0 -34
- data/app/cells/decidim/flag_modal/show.erb +0 -52
- data/app/cells/decidim/flag_modal_cell.rb +0 -56
- data/app/cells/decidim/profile_sidebar/show.erb +0 -167
- data/app/cells/decidim/profile_sidebar_cell.rb +0 -68
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1741dcb0de873587b3e2ff7eb8faae32fa98107e26b42a1c30e1cff7c876f7b3
|
4
|
+
data.tar.gz: 7d5c4a405e277850a00645b6625097cf69a0b4b18dfdfa876be69ca045e71062
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd16b3dbf24ccaf8cced5f0b23eb3dd496e5269bb19fb14010c4db9cc21e01f19c9cd19cff38540d1c9fd474d5e28d3e2a191d9a4e7d2bebde039eff54cdcf1b
|
7
|
+
data.tar.gz: 598051abedb973a6c95e2504d03a30de39f050a57d414aa625c474a2483cc0db42b78e0c923456aab83b960f2ed0dc42983304bc1798d24e9e80a4f08907ad1d
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<%= decidim_modal id: modal_id, class: "flag-modal" do %>
|
2
2
|
<div data-dialog-container>
|
3
3
|
<%= icon "flag-line" %>
|
4
|
-
<h2
|
4
|
+
<h2 tabindex="-1" data-dialog-title><%= t("decidim.shared.flag_modal.title") %></h2>
|
5
5
|
<div>
|
6
6
|
<div class="form__wrapper flag-modal__form">
|
7
|
-
<p
|
7
|
+
<p class="flag-modal__form-description"><%= t("decidim.shared.flag_modal.already_reported") %></p>
|
8
8
|
</div>
|
9
9
|
</div>
|
10
10
|
</div>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<%= form_for report_form, builder:, url: report_path, method: :post, html: { id: nil } do |f| %>
|
3
3
|
<div data-dialog-container>
|
4
4
|
<%= icon "flag-line" %>
|
5
|
-
<h2
|
5
|
+
<h2 tabindex="-1" data-dialog-title><%= t("decidim.shared.flag_modal.title") %></h2>
|
6
6
|
<div>
|
7
7
|
<div class="form__wrapper flag-modal__form">
|
8
8
|
<p id="dialog-desc-<%= modal_id %>" class="flag-modal__form-description"><%= t("decidim.shared.flag_modal.description") %></p>
|
@@ -18,32 +18,18 @@
|
|
18
18
|
<%= f.text_area :details, rows: 4, label_options: { class: "flag-modal__form-textarea-label", for: nil }, id: nil %>
|
19
19
|
|
20
20
|
<% if frontend_administrable? %>
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
<% else %>
|
34
|
-
<%= f.check_box :hide,
|
35
|
-
label: t("decidim.shared.flag_modal.hide_content"),
|
36
|
-
include_hidden: false,
|
37
|
-
id: hide_checkbox_id,
|
38
|
-
data: {
|
39
|
-
label_action: t("decidim.shared.flag_modal.hide"),
|
40
|
-
label_report: t("decidim.shared.flag_modal.report"),
|
41
|
-
hide: "true"
|
42
|
-
},
|
43
|
-
label_options: {
|
44
|
-
for: hide_checkbox_id
|
45
|
-
} %>
|
46
|
-
<% end %>
|
21
|
+
<%= f.check_box :hide,
|
22
|
+
label: t("decidim.shared.flag_modal.hide_content"),
|
23
|
+
include_hidden: false,
|
24
|
+
id: hide_checkbox_id,
|
25
|
+
data: {
|
26
|
+
label_action: t("decidim.shared.flag_modal.hide"),
|
27
|
+
label_report: t("decidim.shared.flag_modal.report"),
|
28
|
+
hide: "true"
|
29
|
+
},
|
30
|
+
label_options: {
|
31
|
+
for: hide_checkbox_id
|
32
|
+
} %>
|
47
33
|
<% end %>
|
48
34
|
|
49
35
|
</div>
|
@@ -11,8 +11,6 @@ module Decidim
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def frontend_administrable?
|
14
|
-
return true if user_reportable? && current_user&.admin?
|
15
|
-
|
16
14
|
user_entity? &&
|
17
15
|
model.can_be_administered_by?(current_user) &&
|
18
16
|
(model.respond_to?(:official?) && !model.official?)
|
@@ -48,16 +46,12 @@ module Decidim
|
|
48
46
|
options[:modal_id] || "flagModal"
|
49
47
|
end
|
50
48
|
|
51
|
-
def user_reportable?
|
52
|
-
model.is_a?(Decidim::UserReportable)
|
53
|
-
end
|
54
|
-
|
55
49
|
def report_form
|
56
|
-
@report_form ||=
|
50
|
+
@report_form ||= Decidim::ReportForm.new(reason: "spam")
|
57
51
|
end
|
58
52
|
|
59
53
|
def report_path
|
60
|
-
@report_path ||=
|
54
|
+
@report_path ||= decidim.report_path(sgid: model.to_sgid.to_s)
|
61
55
|
end
|
62
56
|
|
63
57
|
def builder
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<%= decidim_modal id: modal_id, class: "flag-user-modal" do %>
|
2
|
+
<div data-dialog-container>
|
3
|
+
<%= icon "flag-line" %>
|
4
|
+
<h2 tabindex="-1" data-dialog-title><%= t("decidim.shared.flag_user_modal.title") %></h2>
|
5
|
+
<div>
|
6
|
+
<div class="form__wrapper flag-modal__form">
|
7
|
+
<p class="flag-modal__form-description"><%= t("decidim.shared.flag_user_modal.already_reported") %></p>
|
8
|
+
</div>
|
9
|
+
</div>
|
10
|
+
</div>
|
11
|
+
<% end %>
|
@@ -0,0 +1,46 @@
|
|
1
|
+
<%= decidim_modal id: modal_id, class: "flag-user-modal" do %>
|
2
|
+
<%= form_for report_form, builder:, url: report_path, method: :post, html: { id: nil } do |f| %>
|
3
|
+
<div data-dialog-container>
|
4
|
+
<%= icon "flag-line" %>
|
5
|
+
<h2 tabindex="-1" data-dialog-title><%= t("decidim.shared.flag_user_modal.title") %></h2>
|
6
|
+
<div>
|
7
|
+
<div class="form__wrapper flag-modal__form">
|
8
|
+
<p class="flag-modal__form-description"><%= t("decidim.shared.flag_user_modal.description") %></p>
|
9
|
+
<p class="flag-modal__form-reason"><%= t("decidim.shared.flag_modal.reason") %>:</p>
|
10
|
+
<%= f.collection_radio_buttons :reason, [
|
11
|
+
[:spam, t("decidim.shared.flag_user_modal.spam")],
|
12
|
+
[:offensive, t("decidim.shared.flag_user_modal.offensive")],
|
13
|
+
[:does_not_belong, t("decidim.shared.flag_user_modal.does_not_belong", organization_name: current_organization_name)]
|
14
|
+
], :first, :last do |builder|
|
15
|
+
builder.label(for: nil, class: "form__wrapper-checkbox-label") { builder.radio_button(id: nil) + builder.text }
|
16
|
+
end %>
|
17
|
+
|
18
|
+
<%= f.text_area :details, rows: 4, label_options: { class: "flag-modal__form-textarea-label", for: nil }, id: nil %>
|
19
|
+
|
20
|
+
<% if frontend_administrable? %>
|
21
|
+
<%= f.check_box :block,
|
22
|
+
label: t("decidim.shared.flag_user_modal.block"),
|
23
|
+
include_hidden: false,
|
24
|
+
data: {
|
25
|
+
label_action: t("decidim.shared.flag_user_modal.block"),
|
26
|
+
label_report: t("decidim.shared.flag_user_modal.report"),
|
27
|
+
block: "true"
|
28
|
+
} %>
|
29
|
+
<%= f.check_box :hide, label: t("decidim.shared.flag_user_modal.hide"), label_options: { class: :invisible, id: "block_and_hide" } %>
|
30
|
+
<% end %>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div data-dialog-actions>
|
36
|
+
<button type="button" class="button button__lg button__transparent-secondary" data-dialog-close="<%= modal_id %>">
|
37
|
+
<%= t("decidim.shared.confirm_modal.cancel") %>
|
38
|
+
</button>
|
39
|
+
|
40
|
+
<button type="submit" class="button button__lg button__secondary">
|
41
|
+
<span><%= t("decidim.shared.flag_modal.report") %></span>
|
42
|
+
<%= icon "arrow-right-line", class: "fill-current" %>
|
43
|
+
</button>
|
44
|
+
</div>
|
45
|
+
<% end %>
|
46
|
+
<% end %>
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
class ReportUserButtonCell < ButtonCell
|
5
|
+
include ActionView::Helpers::FormOptionsHelper
|
6
|
+
|
7
|
+
def flag_modal
|
8
|
+
return render :already_reported_modal if model.reported_by?(current_user)
|
9
|
+
|
10
|
+
render
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def report_form
|
16
|
+
@report_form ||= Decidim::ReportForm.from_params(reason: "spam")
|
17
|
+
end
|
18
|
+
|
19
|
+
def report_path
|
20
|
+
@report_path ||= decidim.report_user_path(sgid: model.to_sgid.to_s)
|
21
|
+
end
|
22
|
+
|
23
|
+
def user_reportable?
|
24
|
+
model.is_a?(Decidim::UserReportable)
|
25
|
+
end
|
26
|
+
|
27
|
+
def frontend_administrable?
|
28
|
+
current_user&.admin?
|
29
|
+
end
|
30
|
+
|
31
|
+
def builder
|
32
|
+
Decidim::FormBuilder
|
33
|
+
end
|
34
|
+
|
35
|
+
def only_button?
|
36
|
+
options[:only_button]
|
37
|
+
end
|
38
|
+
|
39
|
+
def modal_id
|
40
|
+
options[:modal_id] || "flagUserModal"
|
41
|
+
end
|
42
|
+
|
43
|
+
def button_classes
|
44
|
+
options[:button_classes] || "button button__sm button__text button__text-secondary"
|
45
|
+
end
|
46
|
+
|
47
|
+
def text
|
48
|
+
t("decidim.shared.flag_modal.report")
|
49
|
+
end
|
50
|
+
|
51
|
+
def icon_name
|
52
|
+
"flag-line"
|
53
|
+
end
|
54
|
+
|
55
|
+
def html_options
|
56
|
+
{ data: { "dialog-open": current_user ? modal_id : "loginModal" } }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -11,7 +11,7 @@
|
|
11
11
|
<ul id="dropdown-menu-resource">
|
12
12
|
<% resource_types.each do |resource_type| %>
|
13
13
|
<li role="menuitem">
|
14
|
-
<%= link_to
|
14
|
+
<%= link_to filter_url(resource_type[0]), class: "filter#{" is-active" if filter_param == resource_type[0]}" do %>
|
15
15
|
<span class="sr-only"><%= resource_type[1] %></span>
|
16
16
|
<%= text_with_resource_icon(*resource_type) %>
|
17
17
|
<% end %>
|
@@ -27,8 +27,12 @@ module Decidim
|
|
27
27
|
options[:id] || "filters"
|
28
28
|
end
|
29
29
|
|
30
|
-
def
|
31
|
-
options[:
|
30
|
+
def filter_url(resource_type)
|
31
|
+
if options[:source] == :last_activities
|
32
|
+
last_activities_path(filter: { with_resource_type: resource_type })
|
33
|
+
else
|
34
|
+
profile_activity_path(nickname: params[:nickname], filter: { resource_type: })
|
35
|
+
end
|
32
36
|
end
|
33
37
|
|
34
38
|
def filter_param_key
|
@@ -39,10 +43,6 @@ module Decidim
|
|
39
43
|
@filter_param ||= params.dig(:filter, filter_param_key) || all_types_key
|
40
44
|
end
|
41
45
|
|
42
|
-
def filter
|
43
|
-
options[:filter]
|
44
|
-
end
|
45
|
-
|
46
46
|
def all_resource_types_option
|
47
47
|
[all_types_key, I18n.t("all", scope: "decidim.last_activities")]
|
48
48
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<div class="profile__activity">
|
2
|
-
<%= cell "decidim/resource_types_filter", resource_types,
|
2
|
+
<%= cell "decidim/resource_types_filter", resource_types, source: :profile_activity %>
|
3
3
|
<div class="profile__activity__container" id="activities-container">
|
4
4
|
<% if activities.length == 0 %>
|
5
5
|
<%= cell "decidim/announcement", t("decidim.user_activity.index.no_activities_warning") %>
|
@@ -47,6 +47,8 @@ module Decidim
|
|
47
47
|
|
48
48
|
attr_reader :form, :verified_email
|
49
49
|
|
50
|
+
REGEXP_SANITIZER = /[<>?%&\^*#@()\[\]=+:;"{}\\|]/
|
51
|
+
|
50
52
|
def create_or_find_user
|
51
53
|
@user = User.find_or_initialize_by(
|
52
54
|
email: verified_email,
|
@@ -65,16 +67,11 @@ module Decidim
|
|
65
67
|
@user.save!
|
66
68
|
else
|
67
69
|
@user.email = (verified_email || form.email)
|
68
|
-
@user.name = form.name
|
70
|
+
@user.name = form.name.gsub(REGEXP_SANITIZER, "")
|
69
71
|
@user.nickname = form.normalized_nickname
|
70
72
|
@user.newsletter_notifications_at = nil
|
71
73
|
@user.password = SecureRandom.hex
|
72
|
-
if form.avatar_url.present?
|
73
|
-
url = URI.parse(form.avatar_url)
|
74
|
-
filename = File.basename(url.path)
|
75
|
-
file = url.open
|
76
|
-
@user.avatar.attach(io: file, filename:)
|
77
|
-
end
|
74
|
+
attach_avatar(form.avatar_url) if form.avatar_url.present?
|
78
75
|
@user.tos_agreement = form.tos_agreement
|
79
76
|
@user.accepted_tos_version = Time.current
|
80
77
|
raise NeedTosAcceptance if @user.tos_agreement.blank?
|
@@ -85,6 +82,15 @@ module Decidim
|
|
85
82
|
end
|
86
83
|
end
|
87
84
|
|
85
|
+
def attach_avatar(avatar_url)
|
86
|
+
url = URI.parse(avatar_url)
|
87
|
+
filename = File.basename(url.path)
|
88
|
+
file = url.open
|
89
|
+
@user.avatar.attach(io: file, filename:)
|
90
|
+
rescue OpenURI::HTTPError, Errno::ECONNREFUSED
|
91
|
+
# Do not attach the avatar, as it fails to fetch it.
|
92
|
+
end
|
93
|
+
|
88
94
|
def create_identity
|
89
95
|
@user.identities.create!(
|
90
96
|
provider: form.provider,
|
@@ -130,7 +136,7 @@ module Decidim
|
|
130
136
|
provider: form.provider,
|
131
137
|
uid: form.uid,
|
132
138
|
email: form.email,
|
133
|
-
name: form.name,
|
139
|
+
name: form.name.gsub(REGEXP_SANITIZER, ""),
|
134
140
|
nickname: form.normalized_nickname,
|
135
141
|
avatar_url: form.avatar_url,
|
136
142
|
raw_data: form.raw_data,
|
@@ -24,7 +24,7 @@ module Decidim
|
|
24
24
|
def show
|
25
25
|
return redirect_to profile_members_path if profile_holder.is_a?(Decidim::UserGroup)
|
26
26
|
|
27
|
-
redirect_to profile_activity_path(nickname: params[:nickname])
|
27
|
+
redirect_to profile_activity_path(nickname: params[:nickname].downcase)
|
28
28
|
end
|
29
29
|
|
30
30
|
def tooltip
|
@@ -116,7 +116,7 @@ module Decidim
|
|
116
116
|
def profile_holder
|
117
117
|
return if params[:nickname].blank?
|
118
118
|
|
119
|
-
@profile_holder ||= Decidim::UserBaseEntity.find_by("
|
119
|
+
@profile_holder ||= Decidim::UserBaseEntity.find_by("nickname = ? AND decidim_organization_id = ?", params[:nickname].downcase, current_organization.id)
|
120
120
|
end
|
121
121
|
end
|
122
122
|
end
|
@@ -22,7 +22,7 @@ module Decidim
|
|
22
22
|
def user
|
23
23
|
return unless params[:nickname]
|
24
24
|
|
25
|
-
@user ||= current_organization.users.find_by("
|
25
|
+
@user ||= current_organization.users.find_by("nickname = ?", params[:nickname].downcase)
|
26
26
|
end
|
27
27
|
|
28
28
|
def activities
|
@@ -21,7 +21,7 @@ module Decidim
|
|
21
21
|
|
22
22
|
validates :name, presence: true, format: { with: Decidim::User::REGEXP_NAME }
|
23
23
|
validates :email, presence: true, "valid_email_2/email": { disposable: true }
|
24
|
-
validates :nickname, presence: true, format: { with: Decidim::
|
24
|
+
validates :nickname, presence: true, format: { with: Decidim::UserBaseEntity::REGEXP_NAME }
|
25
25
|
|
26
26
|
validates :nickname, length: { maximum: Decidim::User.nickname_max_length, allow_blank: true }
|
27
27
|
validates :password, password: { name: :name, email: :email, username: :nickname }, if: -> { password.present? }
|
@@ -66,7 +66,7 @@ module Decidim
|
|
66
66
|
|
67
67
|
def unique_nickname
|
68
68
|
return true if Decidim::UserBaseEntity.where(
|
69
|
-
"decidim_organization_id = ? AND
|
69
|
+
"decidim_organization_id = ? AND nickname = ? ",
|
70
70
|
context.current_organization.id,
|
71
71
|
nickname.downcase
|
72
72
|
).where.not(id: context.current_user.id).empty?
|
@@ -4,9 +4,9 @@ module Decidim
|
|
4
4
|
class HideChildResourcesJob < ApplicationJob
|
5
5
|
queue_as :user_report
|
6
6
|
|
7
|
-
def perform(resource,
|
8
|
-
spam_user = (resource.organization.users.find_by
|
9
|
-
spam_user = resource.organization.admins.
|
7
|
+
def perform(resource, user_id)
|
8
|
+
spam_user = (resource.organization.users.find_by(email: Decidim::Ai::SpamDetection.reporting_user_email) if Decidim.module_installed?(:ai))
|
9
|
+
spam_user = resource.organization.admins.find(user_id) if spam_user.nil?
|
10
10
|
|
11
11
|
tool = Decidim::ModerationTools.new(resource, spam_user)
|
12
12
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Migrate
|
5
|
+
# this job is created to help migrating the Paperclip from YAML to JSON
|
6
|
+
class PaperTrailJob < Decidim::ApplicationJob
|
7
|
+
def perform(id)
|
8
|
+
version = PaperTrail::Version.where.not(old_object_changes: nil).find(id)
|
9
|
+
# This is an adaptation of PaperTrail internal load_changeset method,having in mind that we
|
10
|
+
# need to call also the code from PaperTrail::AttributeSerializer::ObjectChangesAttribute
|
11
|
+
object_changes = ActiveSupport::HashWithIndifferentAccess.new(YAML.unsafe_load(version.old_object_changes))
|
12
|
+
unless version.item_type.constantize.unscoped.find_by(id: version.item_id).nil?
|
13
|
+
# This is the deserialization code from `PaperTrail::AttributeSerializer::ObjectChangesAttribute`
|
14
|
+
# where we skip checking the object changeset column type, as we migrate it from YAML to JSON
|
15
|
+
changes_to_serialize = object_changes.clone
|
16
|
+
if changes_to_serialize.present?
|
17
|
+
serializer = PaperTrail::AttributeSerializers::CastAttributeSerializer.new(version.item_type.constantize)
|
18
|
+
changes_to_serialize.each do |key, change|
|
19
|
+
# `change` is an Array with two elements, representing before and after.
|
20
|
+
object_changes[key] = Array(change).map do |value|
|
21
|
+
serializer.send(:deserialize, key, value)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
version.update_columns(old_object_changes: nil, object_changes:) # rubocop:disable Rails/SkipsModelValidations
|
28
|
+
rescue NameError
|
29
|
+
Rails.logger.info "Skipping History of #{version.item_type} with id #{version.item_id}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/app/models/decidim/user.rb
CHANGED
@@ -13,8 +13,6 @@ module Decidim
|
|
13
13
|
include Decidim::UserReportable
|
14
14
|
include Decidim::Traceable
|
15
15
|
|
16
|
-
REGEXP_NICKNAME = /\A[\w-]+\z/
|
17
|
-
|
18
16
|
class Roles
|
19
17
|
def self.all
|
20
18
|
Decidim.config.user_roles
|
@@ -53,8 +51,6 @@ module Decidim
|
|
53
51
|
|
54
52
|
has_one_attached :download_your_data_file
|
55
53
|
|
56
|
-
scope :not_deleted, -> { where(deleted_at: nil) }
|
57
|
-
|
58
54
|
scope :managed, -> { where(managed: true) }
|
59
55
|
scope :not_managed, -> { where(managed: false) }
|
60
56
|
|
@@ -21,11 +21,13 @@ module Decidim
|
|
21
21
|
|
22
22
|
# Regex for name & nickname format validations
|
23
23
|
REGEXP_NAME = /\A(?!.*[<>?%&\^*#@()\[\]=+:;"{}\\|])/
|
24
|
+
REGEXP_NICKNAME = /\A[a-z0-9_-]+\z/
|
24
25
|
|
25
26
|
has_one_attached :avatar
|
26
27
|
validates_avatar :avatar, uploader: Decidim::AvatarUploader
|
27
28
|
|
28
29
|
validates :name, format: { with: REGEXP_NAME }
|
30
|
+
validates :nickname, format: { with: REGEXP_NICKNAME }, unless: -> { deleted? || managed? }
|
29
31
|
|
30
32
|
scope :confirmed, -> { where.not(confirmed_at: nil) }
|
31
33
|
scope :not_confirmed, -> { where(confirmed_at: nil) }
|
@@ -34,6 +36,8 @@ module Decidim
|
|
34
36
|
scope :not_blocked, -> { where(blocked: false) }
|
35
37
|
scope :available, -> { where(deleted_at: nil, blocked: false, managed: false) }
|
36
38
|
|
39
|
+
scope :not_deleted, -> { where(deleted_at: nil) }
|
40
|
+
|
37
41
|
# Public: Returns a collection with all the public entities this user is following.
|
38
42
|
#
|
39
43
|
# This cannot be done as with a `has_many :following, through: :following_follows`
|
@@ -8,12 +8,27 @@
|
|
8
8
|
|
9
9
|
const footer = document.querySelector("footer");
|
10
10
|
const stickyButtons = document.querySelector("[data-sticky-buttons]");
|
11
|
+
import { screens } from "tailwindcss/defaultTheme"
|
11
12
|
|
13
|
+
/**
|
14
|
+
* Checks if a key is in the current viewport
|
15
|
+
*
|
16
|
+
* @param {('sm'|'md'|'lg'|'xl'|'2xl')} key - The key to check the screen size.
|
17
|
+
* @returns {boolean} - Returns true if the screen size corresponds with the key
|
18
|
+
*/
|
19
|
+
const isScreenSize = (key) => {
|
20
|
+
return window.matchMedia(`(min-width: ${screens[key]})`).matches;
|
21
|
+
}
|
12
22
|
const adjustCtasButtons = () => {
|
13
23
|
if (!stickyButtons) {
|
14
24
|
return;
|
15
25
|
}
|
16
26
|
|
27
|
+
if (isScreenSize("md")) {
|
28
|
+
footer.style.marginBottom = "0px";
|
29
|
+
return;
|
30
|
+
}
|
31
|
+
|
17
32
|
const marginBottom = stickyButtons.offsetHeight;
|
18
33
|
footer.style.marginBottom = `${marginBottom}px`;
|
19
34
|
};
|
@@ -26,4 +41,8 @@ if (stickyButtons) {
|
|
26
41
|
document.addEventListener("on:toggle", () => {
|
27
42
|
adjustCtasButtons();
|
28
43
|
});
|
44
|
+
|
45
|
+
window.addEventListener("resize", () => {
|
46
|
+
adjustCtasButtons();
|
47
|
+
});
|
29
48
|
}
|
@@ -25,6 +25,7 @@ module Decidim
|
|
25
25
|
# @return [String, nil] - The resolved image blob or nil if no image is found.
|
26
26
|
def resolve
|
27
27
|
return unless blob
|
28
|
+
return unless blob.service.exist?(blob.key)
|
28
29
|
|
29
30
|
resized_variant = blob.variant(resize_to_limit: [1200, 630]).processed
|
30
31
|
Rails.application.routes.url_helpers.rails_representation_url(resized_variant, only_path: true)
|
@@ -15,7 +15,7 @@ module Decidim
|
|
15
15
|
def data
|
16
16
|
return if @resource.blank? || map_utility.nil?
|
17
17
|
|
18
|
-
Rails.cache.fetch(@resource.
|
18
|
+
Rails.cache.fetch(@resource.cache_key_with_version) do
|
19
19
|
map_utility.image_data(
|
20
20
|
latitude: @resource.latitude,
|
21
21
|
longitude: @resource.longitude,
|
@@ -4,7 +4,7 @@
|
|
4
4
|
<%= render "decidim/devise/shared/links" %>
|
5
5
|
<% end %>
|
6
6
|
|
7
|
-
<%= render(layout: "layouts/decidim/shared/layout_center"
|
7
|
+
<%= render(layout: "layouts/decidim/shared/layout_center") do %>
|
8
8
|
<div class="flex justify-center">
|
9
9
|
<h1 class="title-decorator my-12"><%= t("decidim.devise.registrations.new.sign_up") %></h1>
|
10
10
|
</div>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<% add_decidim_page_title(t("devise.sessions.new.log_in")) %>
|
2
2
|
|
3
|
-
<%= render(layout: "layouts/decidim/shared/layout_center"
|
3
|
+
<%= render(layout: "layouts/decidim/shared/layout_center") do %>
|
4
4
|
|
5
5
|
<div class="flex justify-center">
|
6
6
|
<h1 class="title-decorator my-12"><%= t("devise.sessions.new.log_in") %></h1>
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<% link_classes = "login__omniauth-button login__omniauth-button--#{normalize_provider_name(provider)}" %>
|
6
6
|
<%= link_to decidim.send("user_#{provider}_omniauth_authorize_path"), class: link_classes, method: :post, title: t("devise.shared.links.log_in_with_provider", provider: normalize_provider_name(provider).titleize) do %>
|
7
7
|
<%= oauth_icon provider %>
|
8
|
-
<span><%= t("devise.shared.links.log_in_with_provider", provider: normalize_provider_name(provider).titleize) %></span>
|
8
|
+
<span class="sr-only"><%= t("devise.shared.links.log_in_with_provider", provider: normalize_provider_name(provider).titleize) %></span>
|
9
9
|
<% end %>
|
10
10
|
<% end %>
|
11
11
|
</div>
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<h1 class="title-decorator my-12"><%= t("last_activity", scope: "decidim.last_activities.index") %></h1>
|
6
6
|
|
7
7
|
<div class="profile__activity pb-16">
|
8
|
-
<%= cell "decidim/resource_types_filter", resource_types,
|
8
|
+
<%= cell "decidim/resource_types_filter", resource_types, source: :last_activities, filter_param_key: :with_resource_type %>
|
9
9
|
<div id="activities">
|
10
10
|
<%= render partial: "activities" %>
|
11
11
|
</div>
|