decidim-core 0.27.0 → 0.27.1

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.

Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/amendable/announcement_cell.rb +1 -1
  3. data/app/cells/decidim/card_m_cell.rb +1 -1
  4. data/app/controllers/decidim/devise/invitations_controller.rb +9 -2
  5. data/app/controllers/decidim/last_activities_controller.rb +5 -2
  6. data/app/forms/decidim/account_form.rb +2 -2
  7. data/app/forms/decidim/amendable/form.rb +2 -1
  8. data/app/forms/decidim/registration_form.rb +2 -2
  9. data/app/forms/decidim/upload_validation_form.rb +51 -7
  10. data/app/helpers/decidim/layout_helper.rb +12 -4
  11. data/app/helpers/decidim/sanitize_helper.rb +1 -1
  12. data/app/mailers/decidim/notification_mailer.rb +1 -0
  13. data/app/mailers/decidim/notifications_digest_mailer.rb +1 -0
  14. data/app/packs/src/decidim/editor/clipboard_override.js +143 -0
  15. data/app/packs/src/decidim/editor/clipboard_utilities.js +119 -0
  16. data/app/packs/src/decidim/editor/linebreak_module.js +0 -8
  17. data/app/packs/src/decidim/editor.js +9 -2
  18. data/app/packs/stylesheets/decidim/_editor.scss +129 -0
  19. data/app/packs/stylesheets/decidim/extras/_quill.scss +0 -6
  20. data/app/presenters/decidim/home_stats_presenter.rb +11 -4
  21. data/app/presenters/decidim/stats_presenter.rb +7 -8
  22. data/app/presenters/decidim/user_presenter.rb +9 -4
  23. data/app/queries/decidim/public_activities.rb +1 -0
  24. data/app/validators/etiquette_validator.rb +7 -3
  25. data/app/validators/file_content_type_validator.rb +103 -0
  26. data/app/validators/passthru_validator.rb +11 -0
  27. data/app/validators/uploader_content_type_validator.rb +22 -0
  28. data/app/views/decidim/notification_mailer/event_received.html.erb +1 -1
  29. data/app/views/decidim/notifications_digest_mailer/_email_content.html.erb +1 -1
  30. data/config/locales/ar.yml +0 -13
  31. data/config/locales/bg.yml +0 -13
  32. data/config/locales/ca.yml +5 -13
  33. data/config/locales/cs.yml +6 -14
  34. data/config/locales/de.yml +0 -13
  35. data/config/locales/el.yml +0 -13
  36. data/config/locales/en.yml +5 -13
  37. data/config/locales/es-MX.yml +5 -13
  38. data/config/locales/es-PY.yml +5 -13
  39. data/config/locales/es.yml +9 -17
  40. data/config/locales/eu.yml +4 -13
  41. data/config/locales/fi-plain.yml +5 -13
  42. data/config/locales/fi.yml +5 -13
  43. data/config/locales/fr-CA.yml +5 -13
  44. data/config/locales/fr.yml +5 -13
  45. data/config/locales/ga-IE.yml +0 -2
  46. data/config/locales/gl.yml +0 -13
  47. data/config/locales/gn-PY.yml +1 -0
  48. data/config/locales/hu.yml +0 -13
  49. data/config/locales/id-ID.yml +0 -13
  50. data/config/locales/it.yml +0 -13
  51. data/config/locales/ja.yml +5 -13
  52. data/config/locales/lb.yml +0 -13
  53. data/config/locales/lo-LA.yml +1 -0
  54. data/config/locales/lt.yml +0 -13
  55. data/config/locales/lv.yml +0 -13
  56. data/config/locales/nl.yml +0 -13
  57. data/config/locales/no.yml +0 -13
  58. data/config/locales/pl.yml +0 -13
  59. data/config/locales/pt-BR.yml +0 -13
  60. data/config/locales/pt.yml +0 -13
  61. data/config/locales/ro-RO.yml +0 -13
  62. data/config/locales/ru.yml +0 -2
  63. data/config/locales/sk.yml +0 -13
  64. data/config/locales/sv.yml +0 -13
  65. data/config/locales/tr-TR.yml +0 -13
  66. data/config/locales/zh-CN.yml +0 -13
  67. data/lib/decidim/attributes/localized_date.rb +1 -1
  68. data/lib/decidim/attributes/time_with_zone.rb +5 -2
  69. data/lib/decidim/core/engine.rb +7 -5
  70. data/lib/decidim/core/test/shared_examples/comments_examples.rb +1 -1
  71. data/lib/decidim/core/test/shared_examples/editor_shared_examples.rb +30 -0
  72. data/lib/decidim/core/test/shared_examples/mcell_examples.rb +17 -0
  73. data/lib/decidim/core/test.rb +2 -0
  74. data/lib/decidim/core/version.rb +1 -1
  75. data/lib/decidim/file_validator_humanizer.rb +1 -1
  76. data/lib/decidim/form_builder.rb +10 -3
  77. data/lib/decidim/resourceable.rb +5 -4
  78. data/lib/decidim/settings_manifest.rb +1 -1
  79. metadata +13 -7
  80. data/app/packs/images/decidim/gamification/badges/decidim_gamification_badges_invitations.svg +0 -1
@@ -10,4 +10,133 @@
10
10
  margin-bottom: $paragraph-margin-bottom;
11
11
  text-rendering: $paragraph-text-rendering;
12
12
  }
13
+
14
+ ul,
15
+ ol{
16
+ margin-bottom: $paragraph-margin-bottom;
17
+ }
18
+ }
19
+
20
+ .ql-editor-display{
21
+ ul,
22
+ ol{
23
+ li{
24
+ list-style-type: none;
25
+ margin-bottom: .5rem;
26
+
27
+ &::before{
28
+ content: "\2022";
29
+ display: inline-block;
30
+ white-space: nowrap;
31
+ width: 1.2em;
32
+ }
33
+
34
+ &.ql-indent-1{
35
+ padding-left: 3em;
36
+ }
37
+
38
+ &.ql-indent-2{
39
+ padding-left: 6em;
40
+ }
41
+
42
+ &.ql-indent-3{
43
+ padding-left: 9em;
44
+ }
45
+
46
+ &.ql-indent-4{
47
+ padding-left: 12em;
48
+ }
49
+
50
+ &.ql-indent-5{
51
+ padding-left: 15em;
52
+ }
53
+
54
+ &.ql-indent-6{
55
+ padding-left: 18em;
56
+ }
57
+
58
+ &.ql-indent-7{
59
+ padding-left: 21em;
60
+ }
61
+
62
+ &.ql-indent-8{
63
+ padding-left: 24em;
64
+ }
65
+
66
+ &.ql-indent-9{
67
+ padding-left: 27em;
68
+ }
69
+ }
70
+ }
71
+
72
+ ol{
73
+ li{
74
+ counter-reset: list-1 list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
75
+ counter-increment: list-0;
76
+
77
+ &::before{ content: counter(list-0, decimal) ". "; }
78
+
79
+ &.ql-indent-1{
80
+ counter-increment: list-1;
81
+ counter-reset: list-2 list-3 list-4 list-5 list-6 list-7 list-8 list-9;
82
+
83
+ &::before{ content: counter(list-1, lower-alpha) ". "; }
84
+ }
85
+
86
+ &.ql-indent-2{
87
+ counter-increment: list-2;
88
+ counter-reset: list-3 list-4 list-5 list-6 list-7 list-8 list-9;
89
+
90
+ &::before{ content: counter(list-2, lower-roman) ". "; }
91
+ }
92
+
93
+ &.ql-indent-3{
94
+ counter-increment: list-3;
95
+ counter-reset: list-4 list-5 list-6 list-7 list-8 list-9;
96
+
97
+ &::before{ content: counter(list-3, decimal) ". "; }
98
+ }
99
+
100
+ &.ql-indent-4{
101
+ counter-increment: list-4;
102
+ counter-reset: list-5 list-6 list-7 list-8 list-9;
103
+
104
+ &::before{ content: counter(list-4, lower-alpha) ". "; }
105
+ }
106
+
107
+ &.ql-indent-5{
108
+ counter-increment: list-5;
109
+ counter-reset: list-6 list-7 list-8 list-9;
110
+
111
+ &::before{ content: counter(list-5, lower-roman) ". "; }
112
+ }
113
+
114
+ &.ql-indent-6{
115
+ counter-increment: list-6;
116
+ counter-reset: list-7 list-8 list-9;
117
+
118
+ &::before{ content: counter(list-6, decimal) ". "; }
119
+ }
120
+
121
+ &.ql-indent-7{
122
+ counter-increment: list-7;
123
+ counter-reset: list-8 list-9;
124
+
125
+ &::before{ content: counter(list-7, lower-alpha) ". "; }
126
+ }
127
+
128
+ &.ql-indent-8{
129
+ counter-increment: list-8;
130
+ counter-reset: list-9;
131
+
132
+ &::before{ content: counter(list-8, lower-roman) ". "; }
133
+ }
134
+
135
+ &.ql-indent-9{
136
+ counter-increment: list-9;
137
+
138
+ &::before{ content: counter(list-9, decimal) ". "; }
139
+ }
140
+ }
141
+ }
13
142
  }
@@ -11,9 +11,3 @@
11
11
  margin-top: 0;
12
12
  margin-bottom: 0;
13
13
  }
14
-
15
- .ql-reset-decidim{
16
- display: inline;
17
- padding: 0;
18
- white-space: inherit;
19
- }
@@ -42,12 +42,19 @@ module Decidim
42
42
  end
43
43
 
44
44
  def component_stats(conditions)
45
+ stats = {}
45
46
  Decidim.component_manifests.flat_map do |component|
46
- component.stats.except([:supports_count])
47
- .filter(conditions)
48
- .with_context(published_components)
49
- .map { |name, data| [name, data] }
47
+ component
48
+ .stats.except([:supports_count])
49
+ .filter(conditions)
50
+ .with_context(published_components)
51
+ .each do |name, data|
52
+ stats[name] ||= 0
53
+ stats[name] += data
54
+ end
50
55
  end
56
+
57
+ stats.to_a
51
58
  end
52
59
 
53
60
  def published_components
@@ -15,18 +15,17 @@ module Decidim
15
15
  end
16
16
 
17
17
  def statistics(grouped_stats)
18
- statistics = []
18
+ statistics = {}
19
+
19
20
  grouped_stats.each do |_manifest_name, stats|
20
- stats.each_with_index.each do |stat, _index|
21
- stat.each_with_index.map do |_item, subindex|
22
- next unless (subindex % 3).zero?
23
- next if stat[subindex + 2].zero?
21
+ stats.each do |_space_manifest, component_manifest, count|
22
+ next if count.zero?
24
23
 
25
- statistics << { stat_title: stat[subindex + 1], stat_number: stat[subindex + 2] }
26
- end
24
+ statistics[component_manifest] ||= 0
25
+ statistics[component_manifest] += count
27
26
  end
28
27
  end
29
- statistics
28
+ statistics.map { |key, number| { stat_title: key, stat_number: number } }
30
29
  end
31
30
  end
32
31
  end
@@ -5,7 +5,6 @@ module Decidim
5
5
  # Decorator for users
6
6
  #
7
7
  class UserPresenter < SimpleDelegator
8
- include Rails.application.routes.mounted_helpers
9
8
  include ActionView::Helpers::UrlHelper
10
9
  include Decidim::TranslatableAttributes
11
10
 
@@ -27,7 +26,7 @@ module Decidim
27
26
  def profile_url
28
27
  return "" if respond_to?(:deleted?) && deleted?
29
28
 
30
- decidim.profile_url(__getobj__.nickname, host: __getobj__.organization.host)
29
+ decidim.profile_url(__getobj__.nickname)
31
30
  end
32
31
 
33
32
  def avatar
@@ -36,13 +35,13 @@ module Decidim
36
35
 
37
36
  def avatar_url(variant = nil)
38
37
  return default_avatar_url if __getobj__.blocked?
39
- return avatar.default_url unless avatar.attached?
38
+ return default_avatar_url unless avatar.attached?
40
39
 
41
40
  avatar.path(variant: variant)
42
41
  end
43
42
 
44
43
  def default_avatar_url
45
- attached_uploader(:avatar).default_url
44
+ avatar.default_url
46
45
  end
47
46
 
48
47
  def profile_path
@@ -77,5 +76,11 @@ module Decidim
77
76
  def has_tooltip?
78
77
  true
79
78
  end
79
+
80
+ private
81
+
82
+ def decidim
83
+ @decidim ||= Decidim::EngineRouter.new("decidim", { host: __getobj__.organization.host })
84
+ end
80
85
  end
81
86
  end
@@ -107,6 +107,7 @@ module Decidim
107
107
  LEFT JOIN decidim_participatory_space_private_users AS #{manifest.name}_private_users
108
108
  ON #{manifest.name}_private_users.privatable_to_type = '#{manifest.model_class_name}'
109
109
  AND #{table}.id = #{manifest.name}_private_users.privatable_to_id
110
+ AND #{table}.private_space = 't'
110
111
  SQL
111
112
  ).to_s
112
113
  ).where(
@@ -3,12 +3,16 @@
3
3
  # This validator takes care of ensuring the validated content is
4
4
  # respectful, doesn't use caps, and overall is meaningful.
5
5
  class EtiquetteValidator < ActiveModel::EachValidator
6
+ include ActionView::Helpers::SanitizeHelper
7
+
6
8
  def validate_each(record, attribute, value)
7
9
  return if value.blank?
8
10
 
9
- validate_caps(record, attribute, value)
10
- validate_marks(record, attribute, value)
11
- validate_caps_first(record, attribute, value)
11
+ text_value = strip_tags(value)
12
+
13
+ validate_caps(record, attribute, text_value)
14
+ validate_marks(record, attribute, text_value)
15
+ validate_caps_first(record, attribute, text_value)
12
16
  end
13
17
 
14
18
  private
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ # We need to define the validator in the `ActiveModel::Validations` namespace as
4
+ # this is what the `file_validators` uses and this is what gets priority over
5
+ # the root namespace class.
6
+ module ActiveModel
7
+ module Validations
8
+ # This validator provides content type validation for uploaded files. Extends
9
+ # the validator provided by the `file_validators` gem by fixing some weird
10
+ # messages in that validator.
11
+ class FileContentTypeValidator
12
+ private
13
+
14
+ alias mark_invalid_original mark_invalid unless private_method_defined?(:mark_invalid_original)
15
+
16
+ # This fixes the "weird" error messages such as "(?-mix:image\\/.*)" because
17
+ # this is the notation Regexp#to_s will return. Instead, we want to show the
18
+ # inner contents of the regular expressions.
19
+ #
20
+ # @see ActiveModel::Validations::FileContentTypeValidator#mark_invalid
21
+ def mark_invalid(record, attribute, error, option_types)
22
+ mark_invalid_original(record, attribute, error, invalid_types(option_types))
23
+ end
24
+
25
+ # Converts the configured content type matches to extensions if extensions are
26
+ # recognized for the specified content type and if not, the content type
27
+ # string itself.
28
+ #
29
+ # @param option_types [Array<Regexp, String>] Array of configured types.
30
+ # @param allowed_extensions [Array<String>, nil] Array of allowed extensions
31
+ # or nil if all extensions are "allowed" (in case we want to show the
32
+ # denylist error or hard code the types).
33
+ # @return [Array<String>] The invalid types as strings.
34
+ def invalid_types(option_types, allowed_extensions = nil)
35
+ extensions = []
36
+ content_types = []
37
+ option_types.each do |type|
38
+ # Since the original content types may have endings such as image/.*?, we
39
+ # want to replace the regexp pattern just with a star with the fallback
40
+ # option.
41
+ content_type = (type.try(:source) || type.to_s).gsub(".*?", "*")
42
+ if (exts = content_type_extensions(content_type, allowed_extensions))
43
+ extensions += exts
44
+ else
45
+ content_types << content_type
46
+ end
47
+ end
48
+
49
+ extensions.sort + content_types.sort
50
+ end
51
+
52
+ # Resolves the content type extensions through MiniMime or looks up all the
53
+ # possible extensions for wildcard content types such as `image/*`. For the
54
+ # wildcard extension types only those listed in the `allowed_extensions` will
55
+ # be returned.
56
+ #
57
+ # @param content_type [String] The content type, such as application/pdf or
58
+ # image/*.
59
+ # @param allowed_extensions [Array, nil] Array of allowed extensions
60
+ # or nil if all extensions are "allowed" (in case we want to show the
61
+ # denylist error or hard code the types).
62
+ # @return [Array<String>, nil] An array of the allowed extensions or nil when
63
+ # no extensions could be found.
64
+ def content_type_extensions(content_type, allowed_extensions = nil)
65
+ extensions =
66
+ if content_type.ends_with?("/*")
67
+ main_type = content_type.split("/")[0]
68
+ extensions_matching(%r{#{main_type}/.*})
69
+ else
70
+ extensions_matching(content_type)
71
+ end
72
+ return if extensions.count.zero?
73
+ return extensions unless allowed_extensions
74
+
75
+ extensions & allowed_extensions
76
+ end
77
+
78
+ # Looks up the extensions matching the content type lookup based on the
79
+ # MiniMime content types.
80
+ #
81
+ # @param content_type_lookup [String, Regexp] The lookup to be matched
82
+ # against.
83
+ # @return [Array<String>] The array of extensions.
84
+ def extensions_matching(content_type_lookup)
85
+ extensions = []
86
+ File.open(MiniMime::Configuration.ext_db_path).each do |line|
87
+ info = line.split(/\s+/)
88
+ next unless info[1].match?(content_type_lookup)
89
+
90
+ extensions << info[0]
91
+ end
92
+
93
+ extensions
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ # This is just to make Zeitwerk happy. The actual validator that gets priority
100
+ # is the class above as all validators in the `ActiveModel::Validations`
101
+ # namespace will be used primarily and only if a matching validator is not found
102
+ # in that namespace, the ones at the root level are used.
103
+ class FileContentTypeValidator < ActiveModel::Validations::FileContentTypeValidator; end
@@ -62,9 +62,20 @@ class PassthruValidator < ActiveModel::EachValidator
62
62
  elsif dummy.respond_to?(:organization=) && record.respond_to?(:organization)
63
63
  dummy.organization = record.organization
64
64
  end
65
+ validation_record_context(dummy, record)
65
66
  dummy
66
67
  end
67
68
 
69
+ def validation_record_context(dummy, record)
70
+ if dummy.is_a?(Decidim::Form)
71
+ dummy.with_context(
72
+ current_organization: record.try(:current_organization) || record.try(:ganization),
73
+ current_participatory_space: record.try(:current_participatory_space) || record.try(:participatory_space),
74
+ current_component: record.try(:current_component) || record.try(:component)
75
+ )
76
+ end
77
+ end
78
+
68
79
  def target_validators(attribute)
69
80
  target_class.validators_on(target_attribute(attribute))
70
81
  end
@@ -41,4 +41,26 @@ class UploaderContentTypeValidator < ActiveModel::Validations::FileContentTypeVa
41
41
  # rubocop: enable Metrics/CyclomaticComplexity
42
42
 
43
43
  def check_validity!; end
44
+
45
+ private
46
+
47
+ # This fixes the "weird" error messages such as "(?-mix:image\\/.*)" because
48
+ # this is the notation Regexp#to_s will return. Instead, we want to show the
49
+ # inner contents of the regular expressions.
50
+ #
51
+ # @see ActiveModel::Validations::FileContentTypeValidator#mark_invalid
52
+ def mark_invalid(record, attribute, error, option_types)
53
+ allowed_extensions = nil
54
+ if error == :allowed_file_content_types
55
+ uploader = record.attached_uploader(attribute) if record.respond_to?(:attached_uploader)
56
+ allowed_extensions =
57
+ # Note that this may be a private method in some uploaders.
58
+ if uploader && uploader.respond_to?(:extension_allowlist, true)
59
+ uploader.send(:extension_allowlist)
60
+ else
61
+ Decidim.organization_settings(record).upload_allowed_file_extensions
62
+ end
63
+ end
64
+ mark_invalid_original(record, attribute, error, invalid_types(option_types, allowed_extensions))
65
+ end
44
66
  end
@@ -4,7 +4,7 @@
4
4
 
5
5
  <% if @event_instance.resource_path.present? && @event_instance.resource_title.present? %>
6
6
  <p class="email-button email-button__cta">
7
- <%= link_to @event_instance.resource_title, @event_instance.resource_url %>
7
+ <%= link_to decidim_sanitize(@event_instance.resource_title, strip_tags: true), @event_instance.resource_url %>
8
8
  </p>
9
9
  <% end %>
10
10
 
@@ -5,7 +5,7 @@
5
5
  </p>
6
6
  <% if notification.resource_path.present? && notification.resource_title.present? %>
7
7
  <p class="email-button email-button__cta">
8
- <%= link_to notification.resource_title, notification.resource_url %>
8
+ <%= link_to decidim_sanitize(notification.resource_title, strip_tags: true), notification.resource_url %>
9
9
  </p>
10
10
  <% end %>
11
11
  </div>
@@ -654,18 +654,6 @@ ar:
654
654
  how: كيف يمكنك كسب ذلك
655
655
  page_description: الشارات عبارة عن اعتراف بإجراءات المشارك والتقدم في المنصة. عند البدء في الاكتشاف والمشاركة والتفاعل في المنصة ، ستربح شارات مختلفة. فيما يلي قائمة بالشارات وبعض الطرق التي يمكنك من خلالها كسبها.
656
656
  title: شارات
657
- invitations:
658
- conditions:
659
- - استخدم رابط "دعوة الأصدقاء" في صفحة المستخدم الخاصة بك لدعوة أصدقائك
660
- - تخصيص ، إذا كنت تريد ، الرسالة التي ترسلها
661
- - ستصل إلى أعلى مستوى عن طريق إرسال الدعوات وتسجيلها.
662
- description: تُمنح هذه الشارة عند قيامك بدعوة بعض الأشخاص وقضاء بعض الوقت للتسجيل في %{organization_name} وتصبح مشاركًا. شكرًا لك على تعريف شخص %{organization_name} للآخرين والمساعدة في توسيع نطاق المجتمع!
663
- description_another: قام هذا المشارك بدعوة %{score} شخصًا.
664
- description_own: لقد قمت بدعوة %{score} شخصًا.
665
- name: دعوات
666
- next_level_in: دعوة %{score} أشخاص آخرين للوصول إلى المستوى التالي!
667
- unearned_another: هذا المشارك لم يدع أي شخص حتى الآن
668
- unearned_own: لم تقم بدعوة أي شخص حتى الآن.
669
657
  description: الشارات عبارة عن اعتراف بإجراءات المشارك والتقدم في المنصة. عند البدء في الاكتشاف والمشاركة والتفاعل في المنصة ، ستربح شارات مختلفة.
670
658
  level: المستوى %{level}
671
659
  reached_top: لقد وصلت إلى المستوى الأعلى لهذه الشارة.
@@ -1268,7 +1256,6 @@ ar:
1268
1256
  not_locked: لم يكن مغلقا
1269
1257
  too_many_marks: يستخدم الكثير من علامات الترقيم المتتالية (مثل! و؟)
1270
1258
  too_much_caps: يستخدم عددًا كبيرًا جدًا من الأحرف الكبيرة (أكثر من 25٪ من النص)
1271
- too_short: قصير جدًا (أقل من 15 حرفًا)
1272
1259
  forms:
1273
1260
  required: مطلوب
1274
1261
  invisible_captcha:
@@ -643,18 +643,6 @@ bg:
643
643
  how: Как може да я заслужите
644
644
  page_description: Значките са признания за действия на участниците и напредък в платформата. Когато започнете да откривате, участвате и взаимодействате в платформата, ще заслужите различни значки. Ето списъка със значки и някои начини, по които можете да ги заслужите.
645
645
  title: Значки
646
- invitations:
647
- conditions:
648
- - Използвайте връзката "покани приятели" на своята страница, за да поканите приятелите си
649
- - Персонализирайте, ако жеаете, съобщението, което изпращате
650
- - Ще се повишите нивото си, като изпращате покани и те бъдат регистрирани.
651
- description: Тази значка се предоставя, когато поканите някои хора и те отделят малко време да се регистрират в %{organization_name} и станат участници. Благодарим ви, че разказвате за %{organization_name} и така помогнете за разширяването на общността!
652
- description_another: Този участник покани %{score} човека.
653
- description_own: Вие поканихте %{score} човека.
654
- name: Покани
655
- next_level_in: Поканете още %{score} за да достигнете следващо ниво!
656
- unearned_another: Този участник все още не е поканил никой.
657
- unearned_own: Не сте поканил(а) никого все ще.
658
646
  description: Значките са признания за действия на участниците и напредък в платформата. Когато започнете да откривате, участвате и взаимодействате в платформата, ще спечелите различни значки.
659
647
  level: Ниво %{level}
660
648
  reached_top: Достигнахте максималното ниво на значката.
@@ -1334,7 +1322,6 @@ bg:
1334
1322
  other: 'При обработката на заявката Ви имаше няколко грешки:'
1335
1323
  too_many_marks: използва твърде много последователни препинателни знаци (напр. ! и ?)
1336
1324
  too_much_caps: използва твърде много главни букви (над 25% от текста)
1337
- too_short: е твърде къс (под 15 знака)
1338
1325
  forms:
1339
1326
  required: Задължително
1340
1327
  invisible_captcha:
@@ -30,6 +30,7 @@ ca:
30
30
  password_confirmation: Confirma la teva contrasenya
31
31
  personal_url: URL personal
32
32
  remove_avatar: Elimina la imatge de perfil
33
+ tos_agreement: Acord de termes i condicions d'ús
33
34
  models:
34
35
  decidim/attachment_created_event: Arxiu adjunt
35
36
  decidim/component_published_event: Component actiu
@@ -820,6 +821,8 @@ ca:
820
821
  allowed_file_extensions: 'Tipus de fitxers admesos: %{extensions}'
821
822
  max_file_dimension: 'Mides máximes de l''arxiu: %{resolution} pixels'
822
823
  max_file_size: 'Mida màxima del fitxer:%{megabytes}MB'
824
+ files:
825
+ extension_allowlist: 'Formats acceptats: %{extensions}'
823
826
  upload:
824
827
  labels:
825
828
  add_attachment: Afegir adjunt
@@ -858,18 +861,6 @@ ca:
858
861
  how: Com pots aconseguir-la
859
862
  page_description: Les insígnies són reconeixements de les accions de les participants i del progrés en la plataforma. A mesura que comencis a descobrir, participar i interactuar amb la plataforma, n'obtindràs de diferents tipus. Aquí tens la llista d'insígnies i algunes formes d'aconseguir-les.
860
863
  title: Insígnies
861
- invitations:
862
- conditions:
863
- - Utilitza l'enllaç "convidar amigues" a la teva pàgina d'usuària per convidar a les teves amistats
864
- - Personalitza, si vols, el missatge que estàs enviant
865
- - Pujaràs per mitjà de l'enviament d'invitacions i de registrar-les.
866
- description: Aquesta insígna s'aconsegueix quan has convidat a algunes persones a la plataforma %{organization_name}, i s'hi han registrat com a participants. Gràcies per donar a conèixer %{organization_name} a d'altres i ajudar a ampliar la comunitat!
867
- description_another: Aquesta participant ha convidat a %{score} persones.
868
- description_own: Has convidat %{score} persones.
869
- name: Invitacions
870
- next_level_in: Convida a %{score} persones més per arribar al següent nivell!
871
- unearned_another: Aquesta participant encara no ha convidat ningú.
872
- unearned_own: Encara no has convidat a ningú.
873
864
  description: Les insígnies són reconeixements de les accions de les participants i del progrés en la plataforma. A mesura que comencis a descobrir, participar i interactuar amb la plataforma, n'obtindràs de diferents tipus.
874
865
  level: Nivell %{level}
875
866
  reached_top: Has arribat al màxim nivell d'aquesta insígnia.
@@ -1685,6 +1676,7 @@ ca:
1685
1676
  public: La teva informació pública.
1686
1677
  errors:
1687
1678
  messages:
1679
+ allowed_file_content_types: 'Només s''accepten arxius amb les següents extensions: %{types}'
1688
1680
  already_confirmed: ja s'ha confirmat, si us plau intenta iniciar la sessió
1689
1681
  confirmation_period_expired: s'ha de confirmar dins de %{period}, si us plau sol·licita'n un de nou
1690
1682
  content_type_allowlist_error: el tipus de fitxer no és vàlid
@@ -1702,7 +1694,7 @@ ca:
1702
1694
  other: 'S''han produït múltiples errors en processar la vostra sol·licitud:'
1703
1695
  too_many_marks: Estàs fent servir massa signes de puntuació consecutius (p. ex. i?)
1704
1696
  too_much_caps: Estàs utilitzant massa lletres majúscules (més del 25% del text)
1705
- too_short: És massa curt (menys de 15 caràcters)
1697
+ too_short: És massa curt (menys %{count} caràcters)
1706
1698
  forms:
1707
1699
  correct_errors: Hi ha errors al formulari, si us plau corregeix-los per continuar.
1708
1700
  length_validator:
@@ -28,8 +28,9 @@ cs:
28
28
  nickname: Přezdívka
29
29
  password: Heslo
30
30
  password_confirmation: Potvrzení hesla
31
- personal_url: Osobní adresa URL
31
+ personal_url: Osobní URL
32
32
  remove_avatar: Odstranit avatara
33
+ tos_agreement: Smluvní podmínky užití
33
34
  models:
34
35
  decidim/attachment_created_event: Příloha
35
36
  decidim/component_published_event: Aktivní součást
@@ -861,6 +862,8 @@ cs:
861
862
  allowed_file_extensions: 'Povolené přípony souborů: %{extensions}'
862
863
  max_file_dimension: 'Maximální rozměry souboru: %{resolution} pixelů'
863
864
  max_file_size: 'Maximální velikost souboru: %{megabytes}MB'
865
+ files:
866
+ extension_allowlist: 'Přijaté formáty: %{extensions}'
864
867
  upload:
865
868
  labels:
866
869
  add_attachment: Přidat přílohu
@@ -899,18 +902,6 @@ cs:
899
902
  how: Jak ho můžete získat
900
903
  page_description: Odznaky jsou uznání akcí účastníků a pokrok v platformě. Jakmile začnete objevovat, účastnit se a spolupracovat v platformě, získáte různé odznaky. Zde je seznam odznaků a některé způsoby, jak si je můžete vydělat.
901
904
  title: Odznaky
902
- invitations:
903
- conditions:
904
- - Pomocí odkazu "pozvat přátele" na své uživatelské stránce můžete pozvat své přátele
905
- - Přizpůsobte, pokud chcete, zprávu, kterou posíláte
906
- - Posíláním pozvánek a jejich registrací se dostáváte výš.
907
- description: Tento odznak je udělen, když jste pozvali některé lidi a tráví čas, aby se zaregistrovali v %{organization_name} a stali se účastníky. Děkujeme za %{organization_name} je známo, že ostatní a pomáhá rozšířit komunitu!
908
- description_another: Tento uživatel pozval %{score} uživatelů.
909
- description_own: Pozvali jste %{score} uživatelů.
910
- name: Pozvánky
911
- next_level_in: Pozvat %{score} dalších uživatelů, abyste se dostali na další úroveň!
912
- unearned_another: Tento uživatel zatím nepozval žádného uživatele.
913
- unearned_own: Dosud jste nepozvali žádné uživatele.
914
905
  description: Odznaky jsou uznání akcí účastníků a pokrok v platformě. Jakmile začnete objevovat, účastnit se a spolupracovat v platformě, získáte různé odznaky.
915
906
  level: Úroveň %{level}
916
907
  reached_top: Dosáhli jste nejvyšší úrovně tohoto odznaku.
@@ -1731,6 +1722,7 @@ cs:
1731
1722
  public: Vaše veřejné informace.
1732
1723
  errors:
1733
1724
  messages:
1725
+ allowed_file_content_types: 'jsou povoleny pouze soubory s následujícími příponami: %{types}'
1734
1726
  already_confirmed: bylo již potvrzeno, zkuste prosím přihlásit
1735
1727
  confirmation_period_expired: musí být potvrzeno v rámci %{period}, požádejte o nový
1736
1728
  content_type_allowlist_error: typ souboru není platný
@@ -1750,7 +1742,7 @@ cs:
1750
1742
  other: 'Při zpracování vašeho požadavku došlo k nějakým chybám:'
1751
1743
  too_many_marks: používá příliš mnoho po sobě jdoucích interpunkčních znamének (např.! a?)
1752
1744
  too_much_caps: používá příliš mnoho velkých písmen (více než 25% textu)
1753
- too_short: je příliš krátká (pod 15 znaků)
1745
+ too_short: je příliš krátká (pod %{count} znaků)
1754
1746
  forms:
1755
1747
  correct_errors: Na formuláři jsou chyby, opravte je a pokračujte.
1756
1748
  length_validator:
@@ -850,18 +850,6 @@ de:
850
850
  how: Wie kannst du es verdienen?
851
851
  page_description: Badges sind Anerkennungen für Aktionen der Teilnehmer und Fortschritt in der Plattform. Wenn Sie auf der Plattform entdecken, teilnehmen und interagieren, verdienen Sie verschiedene Abzeichen. Hier ist die Liste der Abzeichen und einige Möglichkeiten, wie Sie sie verdienen können.
852
852
  title: Abzeichen
853
- invitations:
854
- conditions:
855
- - Verwenden Sie den Link "Freunde einladen" auf Ihrer Nutzerseite, um Ihre Freunde einzuladen
856
- - Passen Sie, wenn Sie möchten, die gesendete Nachricht an
857
- - Sie werden auf den neuesten Stand gebracht, indem Sie Einladungen senden und sie registrieren lassen.
858
- description: Dieses Abzeichen wird gewährt, wenn Sie einige Personen eingeladen haben und sie sich ein wenig Zeit genommen haben, um sich in %{organization_name} zu registrieren und Teilnehmer zu werden. Vielen Dank für die Herstellung von %{organization_name} anderen bekannt und helfen , die Gemeinschaft zu erweitern!
859
- description_another: Diese*r Benutzer*in hat %{score} Benutzer*innen eingeladen.
860
- description_own: Sie haben %{score} Benutzer*innen eingeladen.
861
- name: Einladungen
862
- next_level_in: Laden Sie %{score} weitere Benutzer*innen ein, um das nächste Level zu erreichen!
863
- unearned_another: Diese*r Benutzer*in hat noch niemanden eingeladen.
864
- unearned_own: Sie haben noch keine Benutzer*innen eingeladen.
865
853
  description: Badges sind Anerkennungen für Aktionen der Teilnehmer und Fortschritt in der Plattform. Wenn Sie auf der Plattform entdecken, teilnehmen und interagieren, verdienen Sie verschiedene Abzeichen.
866
854
  level: Level %{level}
867
855
  reached_top: Du hast die höchste Stufe für dieses Abzeichen erreicht.
@@ -1685,7 +1673,6 @@ de:
1685
1673
  other: 'Bei der Bearbeitung Ihrer Anfrage sind mehrere Fehler aufgetreten:'
1686
1674
  too_many_marks: benutzt zu viele aufeinanderfolgende Satzzeichen (zB! und?)
1687
1675
  too_much_caps: verwendet zu viele Großbuchstaben (über 25% des Textes)
1688
- too_short: ist zu kurz (unter 15 Zeichen)
1689
1676
  forms:
1690
1677
  correct_errors: Es gibt Fehler auf dem Formular, bitte korrigieren Sie sie, um fortzufahren.
1691
1678
  length_validator: