decidim-core 0.26.2 → 0.26.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of decidim-core might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/app/cells/decidim/amendable/announcement_cell.rb +1 -1
- data/app/cells/decidim/card_m_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/cta/show.erb +1 -1
- data/app/cells/decidim/content_blocks/hero/show.erb +1 -1
- data/app/cells/decidim/content_blocks/highlighted_content_banner/show.erb +1 -1
- data/app/cells/decidim/content_blocks/stats_cell.rb +1 -0
- data/app/controllers/concerns/decidim/resource_versions_concern.rb +4 -0
- data/app/controllers/decidim/devise/invitations_controller.rb +9 -2
- data/app/controllers/decidim/devise/registrations_controller.rb +5 -1
- data/app/events/decidim/resource_endorsed_event.rb +2 -1
- data/app/forms/decidim/account_form.rb +8 -7
- data/app/forms/decidim/amendable/form.rb +2 -1
- data/app/forms/decidim/registration_form.rb +11 -5
- data/app/helpers/decidim/filters_helper.rb +5 -1
- data/app/mailers/decidim/notification_mailer.rb +1 -0
- data/app/models/decidim/action_log.rb +9 -9
- data/app/models/decidim/user_base_entity.rb +1 -0
- data/app/packs/src/decidim/editor/clipboard_override.js +143 -0
- data/app/packs/src/decidim/editor/clipboard_utilities.js +119 -0
- data/app/packs/src/decidim/editor/linebreak_module.js +0 -8
- data/app/packs/src/decidim/editor.js +9 -2
- data/app/packs/src/decidim/map/factory.js +3 -1
- data/app/packs/src/decidim/map/legacy.js +2 -2
- data/app/packs/src/decidim/map.js +2 -2
- data/app/packs/stylesheets/decidim/modules/_cards.scss +2 -0
- data/app/packs/stylesheets/decidim/modules/_comments.scss +2 -0
- data/app/packs/stylesheets/decidim/modules/_forms.scss +5 -0
- data/app/permissions/decidim/permissions.rb +4 -2
- data/app/presenters/decidim/home_stats_presenter.rb +11 -4
- data/app/presenters/decidim/stats_presenter.rb +7 -8
- data/app/presenters/decidim/user_presenter.rb +12 -4
- data/app/services/decidim/activity_search.rb +1 -0
- data/app/validators/etiquette_validator.rb +7 -3
- data/app/views/decidim/data_portability/show.html.erb +1 -1
- data/app/views/decidim/notification_mailer/event_received.html.erb +1 -1
- data/app/views/decidim/notifications_settings/show.html.erb +49 -51
- data/app/views/decidim/user_interests/show.html.erb +11 -13
- data/config/locales/ar.yml +0 -24
- data/config/locales/bg.yml +1 -23
- data/config/locales/ca.yml +5 -25
- data/config/locales/cs.yml +13 -33
- data/config/locales/de.yml +64 -25
- data/config/locales/el.yml +0 -22
- data/config/locales/en.yml +2 -22
- data/config/locales/es-MX.yml +5 -25
- data/config/locales/es-PY.yml +5 -25
- data/config/locales/es.yml +10 -30
- data/config/locales/eu.yml +5 -26
- data/config/locales/fi-plain.yml +2 -22
- data/config/locales/fi.yml +2 -22
- data/config/locales/fr-CA.yml +4 -24
- data/config/locales/fr.yml +11 -31
- data/config/locales/ga-IE.yml +1 -5
- data/config/locales/gl.yml +0 -24
- data/config/locales/gn-PY.yml +1 -0
- data/config/locales/hu.yml +173 -23
- data/config/locales/id-ID.yml +0 -24
- data/config/locales/is-IS.yml +2 -1
- data/config/locales/it.yml +3 -25
- data/config/locales/ja.yml +4 -24
- data/config/locales/lb.yml +1 -23
- data/config/locales/lo-LA.yml +1 -0
- data/config/locales/lt.yml +1780 -0
- data/config/locales/lv.yml +0 -22
- data/config/locales/nl.yml +3 -25
- data/config/locales/no.yml +1 -23
- data/config/locales/oc-FR.yml +1 -0
- data/config/locales/pl.yml +50 -23
- data/config/locales/pt-BR.yml +3 -25
- data/config/locales/pt.yml +2 -24
- data/config/locales/ro-RO.yml +1 -23
- data/config/locales/ru.yml +0 -5
- data/config/locales/sk.yml +1 -26
- data/config/locales/sv.yml +2 -23
- data/config/locales/tr-TR.yml +2 -24
- data/config/locales/uk.yml +1 -2
- data/config/locales/zh-CN.yml +2 -24
- data/config/routes.rb +20 -2
- data/lib/decidim/attributes/localized_date.rb +9 -1
- data/lib/decidim/attributes/time_with_zone.rb +13 -1
- data/lib/decidim/content_parsers/hashtag_parser.rb +1 -1
- data/lib/decidim/core/engine.rb +1 -6
- data/lib/decidim/core/test/shared_examples/mcell_examples.rb +17 -0
- data/lib/decidim/core/test/shared_examples/resource_endorsed_event_examples.rb +60 -0
- data/lib/decidim/core/test/shared_examples/versions_controller_examples.rb +40 -0
- data/lib/decidim/core/test/shared_examples/with_endorsable_permissions_examples.rb +1 -1
- data/lib/decidim/core/test.rb +3 -0
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/events/simple_event.rb +8 -1
- data/lib/decidim/form_builder.rb +8 -1
- data/lib/decidim/has_resource_permission.rb +0 -2
- data/lib/decidim/map/provider/dynamic_map/here.rb +46 -1
- data/lib/decidim/nicknamizable.rb +1 -1
- data/lib/decidim/resourceable.rb +5 -4
- data/lib/decidim/settings_manifest.rb +1 -1
- data/lib/decidim/translatable_attributes.rb +8 -1
- metadata +14 -8
- data/app/packs/images/decidim/gamification/badges/decidim_gamification_badges_invitations.svg +0 -1
- data/app/views/decidim/devise/registrations/edit.html.erb +0 -41
data/config/locales/tr-TR.yml
CHANGED
@@ -729,18 +729,6 @@ tr:
|
|
729
729
|
how: Nasıl kazanabilirsin
|
730
730
|
page_description: Rozetler, katılımcı eylemleri ve platformdaki ilerlemeleri tanımaktadır. Platformda keşfetmeye, katılmaya ve etkileşim kurmaya başladığınızda farklı rozetler kazanacaksınız. İşte rozetlerin listesi ve bunları kazanmanın bazı yolları.
|
731
731
|
title: Rozetler
|
732
|
-
invitations:
|
733
|
-
conditions:
|
734
|
-
- Arkadaşlarınızı davet etmek için kullanıcı sayfanızdaki “arkadaşlarını davet et” bağlantısını kullanın.
|
735
|
-
- İsterseniz, göndermek istediğiniz mesajı özelleştirin
|
736
|
-
- Davetiyeler göndererek ve onları kayıt altına alarak seviye atlayacaksınız.
|
737
|
-
description: Bu rozeti, bazı kişileri davet ettiğinizde ve %{organization_name} kaydolmak ve katılımcı olmak için biraz zaman ayırdıklarında verilir. Yaptığınız için teşekkür ederiz %{organization_name} başkalarına bilinen ve topluluğu genişletmek için yardımcı!
|
738
|
-
description_another: Bu kullanıcı %{score} kullanıcı davet etti.
|
739
|
-
description_own: '%{score} kullanıcıyı davet ettiniz.'
|
740
|
-
name: Davetiyeler
|
741
|
-
next_level_in: Bir sonraki seviyeye ulaşmak için %{score} kullanıcı daha davet edin!
|
742
|
-
unearned_another: Bu kullanıcı henüz bir kullanıcıyı davet etmedi.
|
743
|
-
unearned_own: Henüz hiç kullanıcı davet etmediniz.
|
744
732
|
description: Rozetler, katılımcı eylemleri ve platformdaki ilerlemeleri tanımaktadır. Platformda keşfetmeye, katılmaya ve etkileşim kurmaya başladığınızda farklı rozetler kazanacaksınız.
|
745
733
|
level: Seviye %{level}
|
746
734
|
reached_top: Bu rozetin en üst seviyesine ulaştınız.
|
@@ -929,7 +917,7 @@ tr:
|
|
929
917
|
ok: OK
|
930
918
|
index:
|
931
919
|
ago: önce
|
932
|
-
close:
|
920
|
+
close: Yakın kalıcı
|
933
921
|
from: Gönderen
|
934
922
|
groups: Gruplarım
|
935
923
|
last_message: Son mesaj
|
@@ -947,7 +935,7 @@ tr:
|
|
947
935
|
title: '%{usernames} ile görüşme'
|
948
936
|
start:
|
949
937
|
send: Gönder
|
950
|
-
title: Bir görüşme
|
938
|
+
title: Bir görüşme başlatın
|
951
939
|
update:
|
952
940
|
error: Bir hata nedeniyle mesaj gönderilemedi
|
953
941
|
metrics:
|
@@ -1446,15 +1434,6 @@ tr:
|
|
1446
1434
|
updated_not_active: Şifreniz başarıyla değiştirildi.
|
1447
1435
|
registrations:
|
1448
1436
|
destroyed: Hoşçakal! Hesabınız başarıyla iptal edildi. Kısa süre sonra tekrar görmeyi umuyoruz.
|
1449
|
-
edit:
|
1450
|
-
are_you_sure: Emin misiniz?
|
1451
|
-
cancel_my_account: Hesabımı iptal et
|
1452
|
-
currently_waiting_confirmation_for_email: 'Şu an için bekleme onayı: %{email}'
|
1453
|
-
leave_blank_if_you_don_t_want_to_change_it: değiştirmek istemiyorsanız boş bırakın
|
1454
|
-
title: '%{resource}düzenle'
|
1455
|
-
unhappy: Mutsuz?
|
1456
|
-
update: Güncelleştirme
|
1457
|
-
we_need_your_current_password_to_confirm_your_changes: değişikliklerinizi onaylamak için mevcut şifrenize ihtiyacımız var
|
1458
1437
|
new:
|
1459
1438
|
sign_up: kaydol
|
1460
1439
|
signed_up: Hoşgeldiniz! Başarıyla kaydoldunuz.
|
@@ -1509,7 +1488,6 @@ tr:
|
|
1509
1488
|
other: 'İsteğinizi işlerken birden çok hata oluştu:'
|
1510
1489
|
too_many_marks: çok fazla ardışık noktalama işareti kullanıyor (örneğin! ve?)
|
1511
1490
|
too_much_caps: çok fazla büyük harf kullanıyor (metnin% 25'inden fazlası)
|
1512
|
-
too_short: çok kısa (15 karakterin altında)
|
1513
1491
|
forms:
|
1514
1492
|
correct_errors: Aşağıdaki formda hatalar oluştu, Devam etmek için lütfen bunları düzeltin.
|
1515
1493
|
required: gereklidir
|
data/config/locales/uk.yml
CHANGED
@@ -385,10 +385,9 @@ uk:
|
|
385
385
|
close: Закрити віконце
|
386
386
|
no_conversations: У вас ще немає бесід
|
387
387
|
reply:
|
388
|
-
|
388
|
+
send: Надіслати
|
389
389
|
start:
|
390
390
|
send: Надіслати
|
391
|
-
title: Почати бесіду
|
392
391
|
newsletter_mailer:
|
393
392
|
newsletter:
|
394
393
|
note: Ви отримали цього електронного листа, оскільки ви підписалися на новини щодо %{organization_name}. Ви можете змінити свої налаштування на <a href="%{link}">сторінці сповіщень</a>.
|
data/config/locales/zh-CN.yml
CHANGED
@@ -656,18 +656,6 @@ zh-CN:
|
|
656
656
|
how: 你如何赚钱
|
657
657
|
page_description: 徽章是对参与者行动和平台进展的承认。 当您开始发现、参与和互动平台时,您将获得不同的徽章。 这里是徽章列表和您可以赚取它们的某些方式。
|
658
658
|
title: 徽章
|
659
|
-
invitations:
|
660
|
-
conditions:
|
661
|
-
- 使用您用户页面上的“邀请好友”链接来邀请您的朋友
|
662
|
-
- 自定义,如果您想要,您正在发送的消息
|
663
|
-
- 您将通过发送邀请和注册来提高等级。
|
664
|
-
description: 当您已经邀请了一些人并且他们花了一些时间在 %{organization_name} 注册并成为参与者时,这个徽章将被授予。 感谢您向其他人宣传了 %{organization_name} 并帮助扩展社区!
|
665
|
-
description_another: 此参与者已邀请了 %{score} 人。
|
666
|
-
description_own: 您已邀请了 %{score} 人。
|
667
|
-
name: 邀请
|
668
|
-
next_level_in: 邀请更多 %{score} 人到达下一个关卡!
|
669
|
-
unearned_another: 此参与者尚未邀请任何人。
|
670
|
-
unearned_own: 你还没有邀请任何人。
|
671
659
|
description: 徽章是对参与者行动和平台进展的承认。 当您开始发现、参与和互动平台时,您将获得不同的徽章。
|
672
660
|
level: 等级 %{level}
|
673
661
|
reached_top: 你已经达到了这个徽章的顶级了。
|
@@ -1350,15 +1338,6 @@ zh-CN:
|
|
1350
1338
|
updated_not_active: 您的密码已成功更改。
|
1351
1339
|
registrations:
|
1352
1340
|
destroyed: 您的帐户已成功取消。我们希望很快再见到您。
|
1353
|
-
edit:
|
1354
|
-
are_you_sure: 您确定吗?
|
1355
|
-
cancel_my_account: 取消我的帐户
|
1356
|
-
currently_waiting_confirmation_for_email: '正在等待确认: %{email}'
|
1357
|
-
leave_blank_if_you_don_t_want_to_change_it: 如果您不想更改它,请留空
|
1358
|
-
title: 编辑 %{resource}
|
1359
|
-
unhappy: 不愉快?
|
1360
|
-
update: 更新
|
1361
|
-
we_need_your_current_password_to_confirm_your_changes: 我们需要您当前的密码来确认您的更改
|
1362
1341
|
new:
|
1363
1342
|
sign_up: 注册
|
1364
1343
|
signed_up: 欢迎!您已成功注册。
|
@@ -1411,7 +1390,6 @@ zh-CN:
|
|
1411
1390
|
other: '处理您的请求时发生多个错误:'
|
1412
1391
|
too_many_marks: 正在使用太多连续标点符号(例如! 和 ?)
|
1413
1392
|
too_much_caps: 正在使用太多大写字母(超过25%文本)
|
1414
|
-
too_short: 太短(低于15个字符)
|
1415
1393
|
forms:
|
1416
1394
|
correct_errors: 表单上有错误,请更正以继续。
|
1417
1395
|
required: 必填字段
|
@@ -1472,8 +1450,8 @@ zh-CN:
|
|
1472
1450
|
widget:
|
1473
1451
|
see_more: 查看更多
|
1474
1452
|
locale:
|
1475
|
-
name:
|
1476
|
-
name_with_error:
|
1453
|
+
name: 中文
|
1454
|
+
name_with_error: 中文(错误!)
|
1477
1455
|
password_validator:
|
1478
1456
|
domain_included_in_password: 与这个域名太近了
|
1479
1457
|
email_included_in_password: 与您的电子邮件太相似了
|
data/config/routes.rb
CHANGED
@@ -11,11 +11,29 @@ Decidim::Core::Engine.routes.draw do
|
|
11
11
|
invitations: "decidim/devise/invitations",
|
12
12
|
sessions: "decidim/devise/sessions",
|
13
13
|
confirmations: "decidim/devise/confirmations",
|
14
|
-
registrations: "decidim/devise/registrations",
|
15
14
|
passwords: "decidim/devise/passwords",
|
16
15
|
unlocks: "decidim/devise/unlocks",
|
17
16
|
omniauth_callbacks: "decidim/devise/omniauth_registrations"
|
18
|
-
}
|
17
|
+
},
|
18
|
+
skip: [:registrations]
|
19
|
+
|
20
|
+
# Manually define the registration routes because otherwise the default "edit"
|
21
|
+
# route would be exposed through Devise while we already have the edit and
|
22
|
+
# destroy routes available through the account pages.
|
23
|
+
resource(
|
24
|
+
:registration,
|
25
|
+
only: [:new, :create],
|
26
|
+
as: :user_registration,
|
27
|
+
path: "/users",
|
28
|
+
path_names: { new: "sign_up" },
|
29
|
+
controller: "devise/registrations"
|
30
|
+
) do
|
31
|
+
# The "cancel" route forces the session data which is usually expired after
|
32
|
+
# sign in to be expired now. This is useful if the user wants to cancel
|
33
|
+
# OAuth signing in/up in the middle of the process, removing all OAuth
|
34
|
+
# session data. @see [Devise::RegistrationsController#cancel]
|
35
|
+
get :cancel
|
36
|
+
end
|
19
37
|
|
20
38
|
devise_for :user_groups,
|
21
39
|
class_name: "Decidim::UserGroup",
|
@@ -10,12 +10,20 @@ module Decidim
|
|
10
10
|
|
11
11
|
Date.strptime(value, I18n.t("date.formats.decidim_short"))
|
12
12
|
rescue ArgumentError
|
13
|
-
|
13
|
+
coerce_fallback(value)
|
14
14
|
end
|
15
15
|
|
16
16
|
def type
|
17
17
|
Axiom::Types::Date
|
18
18
|
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def coerce_fallback(value)
|
23
|
+
coercer.coercers[DateTime].public_send(type.coercion_method, value)
|
24
|
+
rescue Date::Error
|
25
|
+
nil
|
26
|
+
end
|
19
27
|
end
|
20
28
|
end
|
21
29
|
end
|
@@ -10,12 +10,24 @@ module Decidim
|
|
10
10
|
|
11
11
|
Time.zone.strptime(value, I18n.t("time.formats.decidim_short"))
|
12
12
|
rescue ArgumentError
|
13
|
-
|
13
|
+
coerce_fallback(value)
|
14
14
|
end
|
15
15
|
|
16
16
|
def type
|
17
17
|
Axiom::Types::Time
|
18
18
|
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def coerce_fallback(value)
|
23
|
+
fallback = coercer.coercers[Time].public_send(type.coercion_method, value)
|
24
|
+
return Time.zone.strptime(fallback.split(".").first, "%FT%R:%S") if fallback.is_a?(String)
|
25
|
+
return nil unless fallback.is_a?(Time)
|
26
|
+
|
27
|
+
ActiveSupport::TimeWithZone.new(fallback, Time.zone)
|
28
|
+
rescue ArgumentError, TypeError
|
29
|
+
nil
|
30
|
+
end
|
19
31
|
end
|
20
32
|
end
|
21
33
|
end
|
@@ -18,7 +18,7 @@ module Decidim
|
|
18
18
|
|
19
19
|
# Matches a hashtag if it starts with a letter or number
|
20
20
|
# and only contains letters, numbers or underscores.
|
21
|
-
HASHTAG_REGEX =
|
21
|
+
HASHTAG_REGEX = /(?:\A|\s\K)\B#([[:alnum:]](?:[[:alnum:]]|_)*)\b/i.freeze
|
22
22
|
|
23
23
|
# Replaces hashtags name with new or existing hashtags models global ids.
|
24
24
|
#
|
data/lib/decidim/core/engine.rb
CHANGED
@@ -254,7 +254,7 @@ module Decidim
|
|
254
254
|
Cell::ViewModel.view_paths << File.expand_path("#{Decidim::Core::Engine.root}/app/views") # for partials
|
255
255
|
end
|
256
256
|
|
257
|
-
initializer "doorkeeper" do
|
257
|
+
initializer "doorkeeper", before: "doorkeeper.params.filter" do
|
258
258
|
Doorkeeper.configure do
|
259
259
|
orm :active_record
|
260
260
|
|
@@ -531,11 +531,6 @@ module Decidim
|
|
531
531
|
end
|
532
532
|
|
533
533
|
initializer "decidim.core.add_badges" do
|
534
|
-
Decidim::Gamification.register_badge(:invitations) do |badge|
|
535
|
-
badge.levels = [1, 5, 10, 30, 50]
|
536
|
-
badge.reset = ->(user) { Decidim::User.where(invited_by: user.id).count }
|
537
|
-
end
|
538
|
-
|
539
534
|
Decidim::Gamification.register_badge(:followers) do |badge|
|
540
535
|
badge.levels = [1, 15, 30, 60, 100]
|
541
536
|
badge.reset = ->(user) { user.followers.count }
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
shared_examples_for "m-cell" do |model_name|
|
6
|
+
context "with decorated title" do
|
7
|
+
let(:cell_model) { send(model_name) }
|
8
|
+
|
9
|
+
before do
|
10
|
+
cell_model.update!(title: { en: "Model <strong>decorated title</strong>" })
|
11
|
+
end
|
12
|
+
|
13
|
+
it "renders the escaped title correctly" do
|
14
|
+
expect(cell_html.to_s).to include("Model <strong>decorated title</strong>")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
shared_examples_for "resource endorsed event" do
|
6
|
+
include_context "when a simple event"
|
7
|
+
|
8
|
+
let(:event_name) { "decidim.events.resource_endorsed" }
|
9
|
+
let(:author) { create :user, organization: resource.organization }
|
10
|
+
|
11
|
+
let(:extra) { { endorser_id: author.id } }
|
12
|
+
let(:endorsement) { create :endorsement, resource: resource, author: author }
|
13
|
+
let(:resource_path) { resource_locator(resource).path }
|
14
|
+
let(:follower) { create(:user, organization: resource.organization) }
|
15
|
+
let(:follow) { create(:follow, followable: author, user: follower) }
|
16
|
+
|
17
|
+
it_behaves_like "a simple event"
|
18
|
+
|
19
|
+
describe "types" do
|
20
|
+
subject { described_class }
|
21
|
+
|
22
|
+
it "supports notifications" do
|
23
|
+
expect(subject.types).to include :notification
|
24
|
+
end
|
25
|
+
|
26
|
+
it "supports emails" do
|
27
|
+
expect(subject.types).to include :email
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "email_subject" do
|
32
|
+
it "is generated correctly" do
|
33
|
+
expect(subject.email_subject).to eq("#{author_presenter.nickname} has performed a new endorsement")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "email_intro" do
|
38
|
+
it "is generated correctly" do
|
39
|
+
expect(subject.email_intro)
|
40
|
+
.to eq("#{author.name} #{author_presenter.nickname}, who you are following," \
|
41
|
+
" has just endorsed \"#{translated resource.title}\" and we think it may be interesting to you. Check it out and contribute:")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "notification_title" do
|
46
|
+
it "is generated correctly" do
|
47
|
+
expect(subject.notification_title)
|
48
|
+
.to include("The <a href=\"#{resource_path}\">#{translated resource.title}</a> #{resource_type} has been endorsed by ")
|
49
|
+
|
50
|
+
expect(subject.notification_title)
|
51
|
+
.to include("<a href=\"/profiles/#{author.nickname}\">#{author.name} #{author_presenter.nickname}</a>.")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "resource_text" do
|
56
|
+
it "shows the resource text" do
|
57
|
+
expect(subject.resource_text).to eq resource_text
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
shared_examples "versions controller" do
|
6
|
+
let(:base_params) do
|
7
|
+
if resource.is_a?(Decidim::Participable)
|
8
|
+
{ "#{resource.model_name.singular_route_key}_slug".to_sym => resource.slug }
|
9
|
+
else
|
10
|
+
{ "#{resource.model_name.singular_route_key}_id".to_sym => resource.id }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
before do
|
15
|
+
request.env["decidim.current_organization"] = resource.organization
|
16
|
+
|
17
|
+
if resource.is_a?(Decidim::HasComponent)
|
18
|
+
request.env["decidim.current_participatory_space"] = resource.participatory_space
|
19
|
+
request.env["decidim.current_component"] = resource.component
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "GET show" do
|
24
|
+
context "with an existing version" do
|
25
|
+
it "returns a HTTP 200" do
|
26
|
+
get :show, params: base_params.merge(id: 1)
|
27
|
+
|
28
|
+
expect(response).to have_http_status(:ok)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when the resource does not exist" do
|
33
|
+
it "raises a routing error" do
|
34
|
+
expect do
|
35
|
+
get :show, params: base_params.merge(id: 999_999_999)
|
36
|
+
end.to raise_error(ActionController::RoutingError)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -5,7 +5,7 @@ require "spec_helper"
|
|
5
5
|
# users of this test should delare the `subject` variable.
|
6
6
|
shared_examples "with endorsable permissions can perform actions related to endorsable" do
|
7
7
|
let(:action_subject) { :endorsement }
|
8
|
-
let(:resource) { create :dummy_resource }
|
8
|
+
let(:resource) { create :dummy_resource, component: component }
|
9
9
|
before do
|
10
10
|
context[:current_settings] = double(current_settings)
|
11
11
|
context[:resource] = resource
|
data/lib/decidim/core/test.rb
CHANGED
@@ -71,3 +71,6 @@ require "decidim/core/test/shared_examples/categories_container_examples"
|
|
71
71
|
require "decidim/core/test/shared_examples/assembly_announcements_examples"
|
72
72
|
require "decidim/core/test/shared_examples/translated_event_examples"
|
73
73
|
require "decidim/core/test/shared_examples/conversations_examples"
|
74
|
+
require "decidim/core/test/shared_examples/versions_controller_examples"
|
75
|
+
require "decidim/core/test/shared_examples/resource_endorsed_event_examples"
|
76
|
+
require "decidim/core/test/shared_examples/mcell_examples"
|
data/lib/decidim/core/version.rb
CHANGED
@@ -32,7 +32,14 @@ module Decidim
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def email_subject
|
35
|
-
I18n.t("email_subject",
|
35
|
+
I18n.t("email_subject", email_subject_i18n_options).html_safe
|
36
|
+
end
|
37
|
+
|
38
|
+
def email_subject_i18n_options
|
39
|
+
sanitized_values = { resource_title: decidim_sanitize(resource_title) }
|
40
|
+
sanitized_values[:mentioned_proposal_title] = decidim_sanitize(mentioned_proposal_title) if i18n_options.has_key?(:mentioned_proposal_title)
|
41
|
+
sanitized_values[:participatory_space_title] = decidim_sanitize(participatory_space_title) if i18n_options.has_key?(:participatory_space_title)
|
42
|
+
i18n_options.merge(sanitized_values)
|
36
43
|
end
|
37
44
|
|
38
45
|
def email_intro
|
data/lib/decidim/form_builder.rb
CHANGED
@@ -380,7 +380,14 @@ module Decidim
|
|
380
380
|
def datetime_field(attribute, options = {})
|
381
381
|
value = object.send(attribute)
|
382
382
|
data = { datepicker: "", timepicker: "" }
|
383
|
-
|
383
|
+
if value.present?
|
384
|
+
case value
|
385
|
+
when ActiveSupport::TimeWithZone
|
386
|
+
data[:startdate] = I18n.l(value, format: :decidim_short)
|
387
|
+
when Time, DateTime
|
388
|
+
data[:startdate] = I18n.l(value.in_time_zone(Time.zone), format: :decidim_short)
|
389
|
+
end
|
390
|
+
end
|
384
391
|
datepicker_format = ruby_format_to_datepicker(I18n.t("time.formats.decidim_short"))
|
385
392
|
data[:"date-format"] = datepicker_format
|
386
393
|
|
@@ -14,8 +14,6 @@ module Decidim
|
|
14
14
|
|
15
15
|
delegate :resource_manifest, :resource_key, to: :class
|
16
16
|
|
17
|
-
alias_method :manifest, :resource_manifest
|
18
|
-
|
19
17
|
# Public: Whether the permissions for this object actions can be set at resource level.
|
20
18
|
def allow_resource_permissions?
|
21
19
|
false
|
@@ -33,7 +33,7 @@ module Decidim
|
|
33
33
|
)
|
34
34
|
end
|
35
35
|
|
36
|
-
base_config.merge(api_key: api_key)
|
36
|
+
base_config.merge(api_key: api_key, language: language_code)
|
37
37
|
end
|
38
38
|
|
39
39
|
# A builder for the HERE maps which needs to be configured differently
|
@@ -44,6 +44,51 @@ module Decidim
|
|
44
44
|
template.javascript_pack_tag("decidim_map_provider_here", defer: false)
|
45
45
|
end
|
46
46
|
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def language_code
|
51
|
+
primary = I18n.locale.to_s
|
52
|
+
secondary = primary.split("-")[0]
|
53
|
+
available_language_codes[primary] || available_language_codes[secondary] || ""
|
54
|
+
end
|
55
|
+
|
56
|
+
def available_language_codes
|
57
|
+
@available_language_codes ||= {
|
58
|
+
"ar" => "ara", # Arabic
|
59
|
+
"eu" => "baq", # Basque
|
60
|
+
"ca" => "cat", # Catalan
|
61
|
+
"zh" => "chi", # Chinese (simplified)
|
62
|
+
# "" => "cht", # Chinese (traditional)
|
63
|
+
"cs" => "cze", # Czech
|
64
|
+
"da" => "dan", # Danish
|
65
|
+
"nl" => "dut", # Dutch
|
66
|
+
"en" => "eng", # English
|
67
|
+
"fi" => "fin", # Finnish
|
68
|
+
"fr" => "fre", # French
|
69
|
+
"de" => "ger", # German
|
70
|
+
"ga" => "gle", # Gaelic
|
71
|
+
"el" => "gre", # Greek
|
72
|
+
"he" => "heb", # Hebrew
|
73
|
+
"hi" => "hin", # Hindi
|
74
|
+
"id" => "ind", # Indonesian
|
75
|
+
"it" => "ita", # Italian
|
76
|
+
"no" => "nor", # Norwegian
|
77
|
+
"fa" => "per", # Persian
|
78
|
+
"pl" => "pol", # Polish
|
79
|
+
"pt" => "por", # Portuguese
|
80
|
+
"ru" => "rus", # Russian
|
81
|
+
"si" => "sin", # Sinhalese
|
82
|
+
"es" => "spa", # Spanish
|
83
|
+
"sv" => "swe", # Swedish
|
84
|
+
"th" => "tha", # Thai
|
85
|
+
"tr" => "tur", # Turkish
|
86
|
+
"uk" => "ukr", # Ukrainian
|
87
|
+
"ur" => "urd", # Urdu
|
88
|
+
"vi" => "vie", # Vietnamese
|
89
|
+
"cy" => "wel" # Welsh
|
90
|
+
}
|
91
|
+
end
|
47
92
|
end
|
48
93
|
end
|
49
94
|
end
|
@@ -52,7 +52,7 @@ module Decidim
|
|
52
52
|
candidate = name
|
53
53
|
|
54
54
|
2.step do |n|
|
55
|
-
return candidate
|
55
|
+
return candidate if Decidim::UserBaseEntity.where("nickname ILIKE ?", candidate.downcase).where(scope).empty?
|
56
56
|
|
57
57
|
candidate = numbered_variation_of(name, n)
|
58
58
|
end
|
data/lib/decidim/resourceable.rb
CHANGED
@@ -25,8 +25,8 @@ module Decidim
|
|
25
25
|
# link_name - The String name of the link between this model and the target resource.
|
26
26
|
#
|
27
27
|
# Returns an ActiveRecord::Relation.
|
28
|
-
def linked_resources(resource_name, link_name)
|
29
|
-
scope = sibling_scope(resource_name)
|
28
|
+
def linked_resources(resource_name, link_name, component_published: true)
|
29
|
+
scope = sibling_scope(resource_name, component_published: component_published)
|
30
30
|
|
31
31
|
from = scope
|
32
32
|
.joins(:resource_links_from)
|
@@ -45,14 +45,15 @@ module Decidim
|
|
45
45
|
# resource_name - The String name of the resource manifest exposed by a component.
|
46
46
|
#
|
47
47
|
# Returns an ActiveRecord::Relation.
|
48
|
-
def sibling_scope(resource_name)
|
48
|
+
def sibling_scope(resource_name, component_published: true)
|
49
49
|
manifest = Decidim.find_resource_manifest(resource_name)
|
50
50
|
return self.class.none unless manifest
|
51
51
|
|
52
52
|
scope = manifest.resource_scope(component)
|
53
53
|
scope = scope.where("#{self.class.table_name}.id != ?", id) if manifest.model_class == self.class
|
54
54
|
scope = scope.not_hidden if manifest.model_class.respond_to?(:not_hidden)
|
55
|
-
scope.includes(:component).where.not(decidim_components: { published_at: nil })
|
55
|
+
scope = scope.includes(:component).where.not(decidim_components: { published_at: nil }) if component_published
|
56
|
+
scope
|
56
57
|
end
|
57
58
|
|
58
59
|
# Links the given resources to this model, replaces any previous links with the same name.
|
@@ -97,7 +97,7 @@ module Decidim
|
|
97
97
|
enum: { klass: String, default: nil },
|
98
98
|
select: { klass: String, default: nil },
|
99
99
|
scope: { klass: Integer, default: nil },
|
100
|
-
time: { klass:
|
100
|
+
time: { klass: Decidim::Attributes::TimeWithZone, default: nil }
|
101
101
|
}.freeze
|
102
102
|
|
103
103
|
attribute :type, Symbol, default: :boolean
|
@@ -43,7 +43,14 @@ module Decidim
|
|
43
43
|
|
44
44
|
define_method attribute_name do
|
45
45
|
field = public_send(name) || {}
|
46
|
-
value =
|
46
|
+
value =
|
47
|
+
if field.is_a?(Hash)
|
48
|
+
field[locale.to_s] || field[locale.to_sym]
|
49
|
+
else
|
50
|
+
# The value may not be a hash in case the attribute type was
|
51
|
+
# changed and the old value is still stored against the record.
|
52
|
+
field
|
53
|
+
end
|
47
54
|
attribute_set[attribute_name].coerce(value)
|
48
55
|
end
|
49
56
|
|