decidim-core 0.28.4 → 0.28.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/activity_cell.rb +1 -4
  3. data/app/cells/decidim/author/show.erb +5 -4
  4. data/app/cells/decidim/author_cell.rb +26 -0
  5. data/app/cells/decidim/card_s/show.erb +5 -3
  6. data/app/cells/decidim/diff_cell.rb +4 -0
  7. data/app/cells/decidim/newsletter_templates/image_text_cta_cell.rb +1 -1
  8. data/app/cells/decidim/participatory_space_dropdown_metadata/show.erb +5 -3
  9. data/app/cells/decidim/resource_types_filter/show.erb +1 -1
  10. data/app/cells/decidim/resource_types_filter_cell.rb +6 -6
  11. data/app/cells/decidim/translation_bar/show.erb +3 -3
  12. data/app/cells/decidim/translation_bar_cell.rb +1 -1
  13. data/app/cells/decidim/user_activity/show.erb +1 -1
  14. data/app/commands/decidim/create_omniauth_registration.rb +14 -8
  15. data/app/commands/decidim/destroy_account.rb +3 -0
  16. data/app/commands/decidim/search.rb +14 -0
  17. data/app/controllers/decidim/doorkeeper/credentials_controller.rb +1 -1
  18. data/app/controllers/decidim/links_controller.rb +1 -1
  19. data/app/controllers/decidim/profiles_controller.rb +6 -2
  20. data/app/controllers/decidim/reports_controller.rb +1 -1
  21. data/app/controllers/decidim/user_activities_controller.rb +1 -1
  22. data/app/forms/decidim/account_form.rb +5 -2
  23. data/app/helpers/concerns/decidim/user_role_checker.rb +46 -0
  24. data/app/helpers/decidim/cta_button_helper.rb +1 -1
  25. data/app/helpers/decidim/map_helper.rb +6 -1
  26. data/app/helpers/decidim/orders_helper.rb +2 -1
  27. data/app/helpers/decidim/participatory_space_helpers.rb +1 -1
  28. data/app/helpers/decidim/sanitize_helper.rb +11 -2
  29. data/app/models/decidim/attachment.rb +1 -1
  30. data/app/models/decidim/user.rb +0 -4
  31. data/app/models/decidim/user_base_entity.rb +4 -0
  32. data/app/packs/src/decidim/append_redirect_url_to_modals.js +14 -6
  33. data/app/packs/src/decidim/direct_uploads/upload_field.js +21 -8
  34. data/app/packs/src/decidim/index.js +5 -0
  35. data/app/packs/src/decidim/map/provider/here.js +1 -1
  36. data/app/packs/src/decidim/remote_tooltips.js +38 -0
  37. data/app/packs/src/decidim/toggle.js +1 -1
  38. data/app/packs/src/decidim/tooltips.js +42 -22
  39. data/app/packs/stylesheets/decidim/_hashtags.scss +5 -0
  40. data/app/packs/stylesheets/decidim/_header.scss +20 -2
  41. data/app/packs/stylesheets/decidim/_profile.scss +1 -1
  42. data/app/packs/stylesheets/decidim/_progress-bar.scss +1 -1
  43. data/app/packs/stylesheets/decidim/application.scss +1 -0
  44. data/app/packs/stylesheets/decidim/legacy/conference-diploma.scss +2 -1
  45. data/app/presenters/decidim/attachment_presenter.rb +1 -1
  46. data/app/presenters/decidim/log/user_presenter.rb +1 -0
  47. data/app/services/decidim/base_diff_renderer.rb +28 -2
  48. data/app/services/decidim/email_notification_generator.rb +14 -5
  49. data/app/services/decidim/static_map_generator.rb +1 -1
  50. data/app/views/decidim/last_activities/index.html.erb +1 -1
  51. data/app/views/decidim/pages/_tabbed.html.erb +2 -2
  52. data/app/views/decidim/reported_mailer/hide.html.erb +1 -1
  53. data/app/views/decidim/reported_mailer/report.html.erb +1 -1
  54. data/app/views/decidim/searches/_count.html.erb +1 -1
  55. data/app/views/decidim/searches/_filters.html.erb +40 -38
  56. data/app/views/decidim/shared/_orders.html.erb +2 -2
  57. data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile_tablet.html.erb +1 -1
  58. data/config/locales/ar.yml +55 -12
  59. data/config/locales/bg.yml +17 -8
  60. data/config/locales/bn-BD.yml +1 -0
  61. data/config/locales/bs-BA.yml +100 -0
  62. data/config/locales/ca-IT.yml +2115 -0
  63. data/config/locales/ca.yml +69 -22
  64. data/config/locales/cs.yml +62 -15
  65. data/config/locales/de.yml +67 -20
  66. data/config/locales/el.yml +17 -2
  67. data/config/locales/en.yml +47 -0
  68. data/config/locales/eo.yml +2 -0
  69. data/config/locales/es-MX.yml +61 -14
  70. data/config/locales/es-PY.yml +65 -18
  71. data/config/locales/es.yml +72 -25
  72. data/config/locales/eu.yml +308 -250
  73. data/config/locales/fi-plain.yml +50 -11
  74. data/config/locales/fi.yml +87 -48
  75. data/config/locales/fr-CA.yml +57 -10
  76. data/config/locales/fr.yml +55 -8
  77. data/config/locales/ga-IE.yml +11 -0
  78. data/config/locales/gl.yml +33 -2
  79. data/config/locales/hu.yml +17 -10
  80. data/config/locales/id-ID.yml +32 -3
  81. data/config/locales/is-IS.yml +18 -2
  82. data/config/locales/it.yml +84 -14
  83. data/config/locales/ja.yml +70 -23
  84. data/config/locales/lb.yml +32 -7
  85. data/config/locales/lt.yml +9 -3
  86. data/config/locales/lv.yml +26 -2
  87. data/config/locales/nl.yml +33 -6
  88. data/config/locales/no.yml +25 -0
  89. data/config/locales/pl.yml +15 -6
  90. data/config/locales/pt-BR.yml +18 -8
  91. data/config/locales/pt.yml +31 -0
  92. data/config/locales/ro-RO.yml +475 -207
  93. data/config/locales/ru.yml +33 -1
  94. data/config/locales/sk.yml +39 -7
  95. data/config/locales/sl.yml +4 -0
  96. data/config/locales/sr-CS.yml +2 -0
  97. data/config/locales/sv.yml +35 -16
  98. data/config/locales/tr-TR.yml +32 -8
  99. data/config/locales/uk.yml +20 -2
  100. data/config/locales/zh-CN.yml +27 -2
  101. data/config/locales/zh-TW.yml +14 -0
  102. data/config/routes.rb +1 -0
  103. data/decidim-core.gemspec +4 -1
  104. data/lib/decidim/api/functions/component_list.rb +1 -1
  105. data/lib/decidim/api/functions/participatory_space_finder_base.rb +11 -1
  106. data/lib/decidim/api/interfaces/participatory_space_interface.rb +1 -1
  107. data/lib/decidim/api/types/component_type.rb +7 -0
  108. data/lib/decidim/api/types/user_group_type.rb +4 -0
  109. data/lib/decidim/api/types/user_type.rb +4 -0
  110. data/lib/decidim/attributes/rich_text.rb +38 -0
  111. data/lib/decidim/attributes/time_with_zone.rb +16 -2
  112. data/lib/decidim/attributes.rb +2 -0
  113. data/lib/decidim/content_parsers/blob_parser.rb +95 -0
  114. data/lib/decidim/content_parsers/user_parser.rb +1 -1
  115. data/lib/decidim/content_parsers.rb +1 -0
  116. data/lib/decidim/content_renderers/blob_renderer.rb +90 -0
  117. data/lib/decidim/content_renderers.rb +1 -0
  118. data/lib/decidim/core/engine.rb +29 -1
  119. data/lib/decidim/core/test/factories.rb +28 -0
  120. data/lib/decidim/core/test/shared_examples/authorable_interface_examples.rb +1 -1
  121. data/lib/decidim/core/test/shared_examples/comments_examples.rb +15 -2
  122. data/lib/decidim/core/test/shared_examples/reports_examples.rb +48 -6
  123. data/lib/decidim/core/test/shared_examples/uncommentable_component_examples.rb +26 -0
  124. data/lib/decidim/core/test/shared_examples/versions_controller_examples.rb +26 -0
  125. data/lib/decidim/core/version.rb +1 -1
  126. data/lib/decidim/diffy_extension.rb +18 -0
  127. data/lib/decidim/form_builder.rb +1 -1
  128. data/lib/decidim/map/autocomplete.rb +1 -0
  129. data/lib/decidim/map/provider/dynamic_map/here.rb +1 -40
  130. data/lib/decidim/map/provider/static_map/here.rb +34 -0
  131. data/lib/decidim/nicknamizable.rb +1 -1
  132. data/lib/decidim/participatory_space_user.rb +4 -0
  133. data/lib/decidim/query_extensions.rb +0 -26
  134. data/lib/decidim/reportable.rb +6 -2
  135. data/lib/decidim/settings_manifest.rb +2 -0
  136. data/lib/decidim/translatable_attributes.rb +10 -1
  137. data/lib/decidim/view_model.rb +1 -0
  138. data/lib/tasks/upgrade/decidim_fix_categorization.rake +34 -8
  139. data/lib/tasks/upgrade/decidim_fix_nickname_uniqueness.rake +23 -20
  140. metadata +30 -8
  141. data/app/packs/src/decidim/vendor/leaflet-tilelayer-here.js +0 -212
@@ -613,7 +613,7 @@ shared_examples "comments" do
613
613
  end
614
614
 
615
615
  context "when the user has verified organizations" do
616
- let(:user_group) { create(:user_group, :verified) }
616
+ let(:user_group) { create(:user_group, :verified, organization:) }
617
617
  let(:content) { "This is a new comment" }
618
618
 
619
619
  before do
@@ -741,6 +741,20 @@ shared_examples "comments" do
741
741
  expect(page).to have_content("Edited")
742
742
  end
743
743
  end
744
+
745
+ it "has only one edit modal" do
746
+ expect(page).to have_css("#editCommentModal#{comment.id}", visible: :hidden, count: 1)
747
+ 3.times do |index|
748
+ sleep 2
749
+ within "#comment_#{comment.id}" do
750
+ page.find("[id^='dropdown-trigger']").click
751
+ click_on "Edit"
752
+ end
753
+ fill_in "edit_comment_#{comment.id}", with: " This comment has been edited #{1 + index} times"
754
+ click_on "Send"
755
+ end
756
+ expect(page).to have_css("#editCommentModal#{comment.id}", visible: :all, count: 1)
757
+ end
744
758
  end
745
759
  end
746
760
  end
@@ -1025,7 +1039,6 @@ shared_examples "comments blocked" do
1025
1039
  end
1026
1040
 
1027
1041
  context "when authenticated" do
1028
- let!(:organization) { create(:organization) }
1029
1042
  let!(:user) { create(:user, :confirmed, organization:) }
1030
1043
  let!(:comments) { create_list(:comment, 3, commentable:) }
1031
1044
 
@@ -33,17 +33,47 @@ shared_examples "higher user role hides" do
33
33
  before do
34
34
  login_as user, scope: :user
35
35
  end
36
- around do |example|
37
- previous = Capybara.raise_server_errors
38
36
 
39
- Capybara.raise_server_errors = false
40
- example.run
41
- Capybara.raise_server_errors = previous
37
+ it "reports the resource" do
38
+ visit reportable_path
39
+
40
+ expect(page).to have_css(%(button[data-dialog-open="flagModal"]))
41
+ find(%(button[data-dialog-open="flagModal"])).click
42
+ expect(page).to have_css(".flag-modal", visible: :visible)
43
+
44
+ within ".flag-modal" do
45
+ find(:css, "input[name='report[hide]']").set(true)
46
+ click_on "Hide"
47
+ end
48
+
49
+ sleep(1)
50
+
51
+ expect(page).to have_current_path(reportable_index_path, ignore_query: true)
52
+
53
+ expect(reportable.reload).to be_hidden
42
54
  end
55
+ end
56
+ end
57
+
58
+ shared_examples "higher user role hides resource with comments" do
59
+ context "and the admin hides a resource with comments" do
60
+ let!(:comments) { create_list(:comment, 2, body: "Dummy comment", commentable: reportable, author: user) }
61
+
62
+ before do
63
+ login_as user, scope: :user
64
+ Decidim::Ai::SpamDetection.create_reporting_user!
65
+ end
66
+
67
+ it "hides the resource" do
68
+ visit decidim.search_path
69
+ expect(page).to have_content(translated(comments.first.body))
70
+ expect(page).to have_content(translated(comments.second.body))
43
71
 
44
- it "reports the resource" do
45
72
  visit reportable_path
46
73
 
74
+ expect(page).to have_content(translated(comments.first.body))
75
+ expect(page).to have_content(translated(comments.second.body))
76
+
47
77
  expect(page).to have_css(%(button[data-dialog-open="flagModal"]))
48
78
  find(%(button[data-dialog-open="flagModal"])).click
49
79
  expect(page).to have_css(".flag-modal", visible: :visible)
@@ -53,7 +83,19 @@ shared_examples "higher user role hides" do
53
83
  click_button "Hide"
54
84
  end
55
85
 
86
+ sleep(1)
87
+
88
+ expect(page).to have_current_path(reportable_index_path, ignore_query: true)
89
+
90
+ perform_enqueued_jobs
91
+
56
92
  expect(reportable.reload).to be_hidden
93
+ expect(comments.first.reload).to be_hidden
94
+ expect(comments.second.reload).to be_hidden
95
+
96
+ visit decidim.search_path
97
+ expect(page).not_to have_content(translated(comments.first.body))
98
+ expect(page).not_to have_content(translated(comments.second.body))
57
99
  end
58
100
  end
59
101
  end
@@ -8,6 +8,7 @@ shared_examples "an uncommentable component" do
8
8
  manifest:,
9
9
  participatory_space:)
10
10
  end
11
+ let!(:comment) { create(:comment, commentable: resources.first) }
11
12
 
12
13
  it "does not displays comments count" do
13
14
  component.update!(settings: { comments_enabled: false })
@@ -18,4 +19,29 @@ shared_examples "an uncommentable component" do
18
19
  expect(page).not_to have_link(resource_locator(ressource).path)
19
20
  end
20
21
  end
22
+
23
+ describe "when search a comment in the global search" do
24
+ it "does displays the comments" do
25
+ visit decidim.root_path
26
+
27
+ within ".main-bar__search" do
28
+ fill_in "term", with: comment.body["en"]
29
+ find("input#input-search").native.send_keys :enter
30
+ end
31
+
32
+ expect(page).to have_content("1 Results for the search")
33
+ end
34
+
35
+ it "does not displays the comment when comments are disable" do
36
+ component.update!(settings: { comments_enabled: false })
37
+ visit decidim.root_path
38
+
39
+ within ".main-bar__search" do
40
+ fill_in "term", with: comment.body["en"]
41
+ find("input#input-search").native.send_keys :enter
42
+ end
43
+
44
+ expect(page).to have_content("0 Results for the search")
45
+ end
46
+ end
21
47
  end
@@ -2,6 +2,32 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
+ shared_examples "a version of a hidden object" do
6
+ before do
7
+ visit resource_path
8
+ click_on "see other versions"
9
+ click_on("Version 1 of #{hidden_object.reload.versions.size}")
10
+ end
11
+
12
+ around do |example|
13
+ previous = Capybara.raise_server_errors
14
+
15
+ Capybara.raise_server_errors = false
16
+ example.run
17
+ Capybara.raise_server_errors = previous
18
+ end
19
+
20
+ it "shows an error page" do
21
+ expect(page).to have_content("Changes at")
22
+
23
+ create(:moderation, reportable: hidden_object, hidden_at: 1.day.ago)
24
+
25
+ visit current_path
26
+
27
+ expect(page).to have_content(ActiveRecord::RecordNotFound)
28
+ end
29
+ end
30
+
5
31
  shared_examples "versions controller" do
6
32
  let(:base_params) do
7
33
  if resource.is_a?(Decidim::Participable)
@@ -4,7 +4,7 @@ module Decidim
4
4
  # This holds the decidim-core version.
5
5
  module Core
6
6
  def self.version
7
- "0.28.4"
7
+ "0.28.6"
8
8
  end
9
9
  end
10
10
  end
@@ -13,6 +13,24 @@ module Decidim
13
13
  str = wrap_lines(@diff.map { |line| wrap_line(line) })
14
14
  ActionView::Base.new(ActionView::LookupContext.new(nil), {}, nil).sanitize(str, tags: TAGS)
15
15
  end
16
+
17
+ private
18
+
19
+ def wrap_line(line)
20
+ cleaned = clean_line(line)
21
+ case line
22
+ when /^(---|\+\+\+|\\\\)/
23
+ " <li class=\"diff-comment\"><div>#{line.chomp}</div></li>"
24
+ when /^\+/
25
+ " <li class=\"ins\"><ins>#{cleaned}</ins></li>"
26
+ when /^-/
27
+ " <li class=\"del\"><del>#{cleaned}</del></li>"
28
+ when /^ /
29
+ " <li class=\"unchanged\"><div>#{cleaned}</div></li>"
30
+ when /^@@/
31
+ " <li class=\"diff-block-info\"><div>#{line.chomp}</div></li>"
32
+ end
33
+ end
16
34
  end
17
35
 
18
36
  # Adding a new method to Diffy::Format so we can pass the
@@ -390,7 +390,7 @@ module Decidim
390
390
  # options - A Hash with options to build the field. See upload method for
391
391
  # more detailed information.
392
392
  def attachment(attribute, options = {})
393
- object_attachment = object.attachment.present?
393
+ object_attachment = object.respond_to?(:attachment) && object.attachment.present?
394
394
  record = object_attachment ? object.attachment : object
395
395
  options = {
396
396
  titled: options[:multiple],
@@ -42,6 +42,7 @@ module Decidim
42
42
  @autocomplete_utility ||= Decidim::Map.autocomplete(
43
43
  organization: @template.current_organization
44
44
  )
45
+
45
46
  return text_field(attribute, options) unless @autocomplete_utility
46
47
 
47
48
  # Decidim::Map::Autocomplete::Builder
@@ -49,46 +49,7 @@ module Decidim
49
49
  private
50
50
 
51
51
  def language_code
52
- primary = I18n.locale.to_s
53
- secondary = primary.split("-")[0]
54
- available_language_codes[primary] || available_language_codes[secondary] || ""
55
- end
56
-
57
- def available_language_codes
58
- @available_language_codes ||= {
59
- "ar" => "ara", # Arabic
60
- "eu" => "baq", # Basque
61
- "ca" => "cat", # Catalan
62
- "zh" => "chi", # Chinese (simplified)
63
- # "" => "cht", # Chinese (traditional)
64
- "cs" => "cze", # Czech
65
- "da" => "dan", # Danish
66
- "nl" => "dut", # Dutch
67
- "en" => "eng", # English
68
- "fi" => "fin", # Finnish
69
- "fr" => "fre", # French
70
- "de" => "ger", # German
71
- "ga" => "gle", # Gaelic
72
- "el" => "gre", # Greek
73
- "he" => "heb", # Hebrew
74
- "hi" => "hin", # Hindi
75
- "id" => "ind", # Indonesian
76
- "it" => "ita", # Italian
77
- "no" => "nor", # Norwegian
78
- "fa" => "per", # Persian
79
- "pl" => "pol", # Polish
80
- "pt" => "por", # Portuguese
81
- "ru" => "rus", # Russian
82
- "si" => "sin", # Sinhalese
83
- "es" => "spa", # Spanish
84
- "sv" => "swe", # Swedish
85
- "th" => "tha", # Thai
86
- "tr" => "tur", # Turkish
87
- "uk" => "ukr", # Ukrainian
88
- "ur" => "urd", # Urdu
89
- "vi" => "vie", # Vietnamese
90
- "cy" => "wel" # Welsh
91
- }
52
+ I18n.locale.to_s
92
53
  end
93
54
  end
94
55
  end
@@ -6,8 +6,42 @@ module Decidim
6
6
  module StaticMap
7
7
  # The static map utility class for the HERE maps service
8
8
  class Here < ::Decidim::Map::StaticMap
9
+ def url(latitude:, longitude:, options: {})
10
+ map_url = configuration.fetch(:url, nil)
11
+ return super unless map_url
12
+
13
+ return super unless map_url.include?("mia/v3")
14
+
15
+ w = options[:width] || Decidim::Map::StaticMap::DEFAULT_SIZE
16
+ h = options[:height] || Decidim::Map::StaticMap::DEFAULT_SIZE
17
+
18
+ params = {
19
+ apiKey: configuration[:api_key],
20
+ overlay: "point:#{latitude},#{longitude};icon=cp;size=large|#{latitude},#{longitude};style=circle;width=50m;color=%231B9D2C60"
21
+ }
22
+
23
+ URI.parse("#{map_url}:radius=90/#{w}x#{h}/png8").tap do |uri|
24
+ uri.query = URI.encode_www_form(params)
25
+ end.to_s
26
+ end
27
+
9
28
  # @See Decidim::Map::StaticMap#url_params
10
29
  def url_params(latitude:, longitude:, options: {})
30
+ ActiveSupport::Deprecation.warn(
31
+ <<~DEPRECATION.strip
32
+ Please use a V3 version HERE maps.
33
+ For further information, see:
34
+ https://www.here.com/docs/bundle/map-image-migration-guide-v3/page/README.html
35
+ Also make sure your Decidim.maps configurations are using the
36
+ up to date format.
37
+ You need to change:
38
+ static_url = "https://image.maps.ls.hereapi.com/mia/1.6/mapview" if static_provider == "here" && static_url.blank?
39
+ to:
40
+ static_url = "https://image.maps.hereapi.com/mia/v3/base/mc/overlay" if static_provider == "here"
41
+ in your config/initializers/decidim.rb file.
42
+ DEPRECATION
43
+ )
44
+
11
45
  params = {
12
46
  c: "#{latitude}, #{longitude}",
13
47
  z: options[:zoom] || Decidim::Map::StaticMap::DEFAULT_ZOOM,
@@ -52,7 +52,7 @@ module Decidim
52
52
  candidate = name
53
53
 
54
54
  2.step do |n|
55
- return candidate if Decidim::UserBaseEntity.where("nickname ILIKE ?", candidate.downcase).where(scope).empty?
55
+ return candidate if Decidim::UserBaseEntity.where(nickname: candidate.downcase).where(scope).empty?
56
56
 
57
57
  candidate = numbered_variation_of(name, n)
58
58
  end
@@ -37,6 +37,10 @@ module Decidim
37
37
  raise "Not implemented"
38
38
  end
39
39
 
40
+ def self.order_by_name
41
+ includes(:user).order("decidim_users.name ASC")
42
+ end
43
+
40
44
  private
41
45
 
42
46
  # Private: check if the process and the user have the same organization
@@ -10,22 +10,6 @@ module Decidim
10
10
  #
11
11
  # Returns nothing.
12
12
  def self.included(type)
13
- type.field :participatory_processes,
14
- [Decidim::ParticipatoryProcesses::ParticipatoryProcessType],
15
- null: true,
16
- description: "Lists all participatory_processes" do
17
- argument :filter, Decidim::ParticipatoryProcesses::ParticipatoryProcessInputFilter, "This argument lets you filter the results", required: false
18
- argument :order, Decidim::ParticipatoryProcesses::ParticipatoryProcessInputSort, "This argument lets you order the results", required: false
19
- end
20
-
21
- type.field :participatory_process,
22
- Decidim::ParticipatoryProcesses::ParticipatoryProcessType,
23
- null: true,
24
- description: "Finds a participatory_process" do
25
- argument :id, GraphQL::Types::ID, "The ID of the participatory space", required: false
26
- argument :slug, String, "The slug of the participatory process", required: false
27
- end
28
-
29
13
  type.field :component, Decidim::Core::ComponentInterface, null: true do
30
14
  description "Lists the components this space contains."
31
15
  argument :id, GraphQL::Types::ID, required: true, description: "The ID of the component to be found"
@@ -62,16 +46,6 @@ module Decidim
62
46
  end
63
47
  end
64
48
 
65
- def participatory_processes(filter: {}, order: {})
66
- manifest = Decidim.participatory_space_manifests.select { |m| m.name == :participatory_processes }.first
67
- Decidim::Core::ParticipatorySpaceListBase.new(manifest:).call(object, { filter:, order: }, context)
68
- end
69
-
70
- def participatory_process(id: nil, slug: nil)
71
- manifest = Decidim.participatory_space_manifests.select { |m| m.name == :participatory_processes }.first
72
- Decidim::Core::ParticipatorySpaceFinderBase.new(manifest:).call(object, { id:, slug: }, context)
73
- end
74
-
75
49
  def component(id: {})
76
50
  component = Decidim::Component.published.find_by(id:)
77
51
  component&.organization == context[:current_organization] ? component : nil
@@ -53,8 +53,12 @@ module Decidim
53
53
  # Public: The reported content url
54
54
  #
55
55
  # Returns String
56
- def reported_content_url
57
- raise NotImplementedError
56
+ def reported_content_url(options = {})
57
+ if hidden?
58
+ ResourceLocatorPresenter.new(self).index(options)
59
+ else
60
+ ResourceLocatorPresenter.new(self).url(options)
61
+ end
58
62
  end
59
63
 
60
64
  # Public: The collection of attribute names that are considered
@@ -116,6 +116,8 @@ module Decidim
116
116
  validates :type, inclusion: { in: TYPES.keys }
117
117
 
118
118
  def type_class
119
+ return Decidim::Attributes::RichText if type == :text && editor == true
120
+
119
121
  TYPES[type][:klass]
120
122
  end
121
123
 
@@ -34,6 +34,7 @@ module Decidim
34
34
  # end
35
35
  #
36
36
  # Returns nothing.
37
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
37
38
  def translatable_attribute(name, type, **options)
38
39
  attribute(name, { String => Object }, default: {})
39
40
 
@@ -41,6 +42,8 @@ module Decidim
41
42
  attribute_name = "#{name}_#{locale}".gsub("-", "__")
42
43
  attribute attribute_name, type, **options
43
44
 
45
+ value_type = attribute_types[attribute_name.to_s]
46
+
44
47
  define_method attribute_name do
45
48
  field = public_send(name) || {}
46
49
  value =
@@ -51,7 +54,6 @@ module Decidim
51
54
  # changed and the old value is still stored against the record.
52
55
  field
53
56
  end
54
- value_type = self.class.attribute_types[attribute_name.to_s]
55
57
  value_type ? value_type.cast(value) : value
56
58
  end
57
59
 
@@ -60,12 +62,15 @@ module Decidim
60
62
  final = super(value)
61
63
  return unless final # Do not set the `nil` values for the parent hash
62
64
 
65
+ final = value_type.serialize(final) if value_type && !attachment?(final)
66
+
63
67
  public_send("#{name}=", field.merge(locale => final))
64
68
  end
65
69
 
66
70
  yield(attribute_name, locale) if block_given?
67
71
  end
68
72
  end
73
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
69
74
 
70
75
  def locales
71
76
  Decidim.available_locales
@@ -122,5 +127,9 @@ module Decidim
122
127
  locale.to_s == try(:default_locale).to_s ||
123
128
  locale.to_s == try(:current_organization).try(:default_locale).to_s
124
129
  end
130
+
131
+ def attachment?(value)
132
+ value.is_a?(String) && value.include?(ActiveStorage.routes_prefix)
133
+ end
125
134
  end
126
135
  end
@@ -19,6 +19,7 @@ module Decidim
19
19
  include Decidim::SanitizeHelper
20
20
 
21
21
  delegate :current_organization, to: :controller
22
+ delegate_missing_to :view_context
22
23
 
23
24
  cache :show, if: :perform_caching?, expires_in: :cache_expiry_time do
24
25
  cache_hash
@@ -8,9 +8,18 @@ namespace :decidim do
8
8
  :"decidim:upgrade:clean:searchable_resources",
9
9
  :"decidim:upgrade:clean:notifications",
10
10
  :"decidim:upgrade:clean:follows",
11
- :"decidim:upgrade:clean:action_logs"
11
+ :"decidim:upgrade:clean:action_logs",
12
+ :"decidim:upgrade:clean:clean_deleted_users",
13
+ :"decidim:upgrade:clean:fix_blocked_user_notification"
12
14
  ]
13
15
 
16
+ desc "Remove data from deleted users"
17
+ task clean_deleted_users: :environment do
18
+ logger = Logger.new($stdout)
19
+ logger.info("=== Removing extra data from deleted users")
20
+ Decidim::User.where.not(deleted_at: nil).update_all(personal_url: "", about: "", notifications_sending_frequency: "none") # rubocop:disable Rails/SkipsModelValidations
21
+ end
22
+
14
23
  desc "Removes any action logs belonging to invalid resources"
15
24
  task :action_logs, [] => :environment do
16
25
  puts "=== Deleting Action logs\n"
@@ -100,15 +109,32 @@ namespace :decidim do
100
109
  end
101
110
  puts "===== Deleted #{invalid} invalid resources\n"
102
111
  end
103
- end
104
112
 
105
- desc "Removes orphan categorizations"
106
- task fix_orphan_categorizations: :environment do
107
- logger = Logger.new($stdout)
108
- logger.info("Removing orphan categorizations...")
113
+ desc "Removes orphan categorizations"
114
+ task fix_orphan_categorizations: :environment do
115
+ logger = Logger.new($stdout)
116
+ logger.info("Removing orphan categorizations...")
117
+
118
+ Decidim::Categorization.find_each do |categorization|
119
+ categorization.destroy if categorization.categorizable.nil?
120
+ end
121
+ end
122
+
123
+ desc "Update all blocked users notifications_sending_frequency setting"
124
+ task fix_blocked_user_notification: :environment do
125
+ logger.info("=== Updating all blocked users notifications_sending_frequency ...")
126
+ blocked_users = 0
127
+ Decidim::User.blocked.where.not("notifications_sending_frequency = ?", "none").find_each do |blocked_user|
128
+ unless blocked_user.notifications_sending_frequency == "none"
129
+ blocked_user.update(notifications_sending_frequency: "none")
130
+ blocked_users += 1
131
+ end
132
+ end
133
+ logger.info("===== Updated #{blocked_users} blocked users")
134
+ end
109
135
 
110
- Decidim::Categorization.find_each do |categorization|
111
- categorization.destroy if categorization.categorizable.nil?
136
+ def logger
137
+ @logger ||= Logger.new($stdout)
112
138
  end
113
139
  end
114
140
  end
@@ -2,37 +2,40 @@
2
2
 
3
3
  namespace :decidim do
4
4
  namespace :upgrade do
5
- desc "Modify nicknames with random numbers when exists similar ones case insensitively"
6
- task fix_nickname_uniqueness: :environment do
7
- logger = Logger.new($stdout)
8
- logger.info("Updating conflicting user nicknames...")
5
+ desc "Modifies nickname of the user to lower case"
6
+ task fix_nickname_casing: :environment do
7
+ logger.info("Fixing user nicknames case...")
9
8
 
10
- # list of users already changed in the process
11
9
  has_changed = []
10
+ Decidim::UserBaseEntity.not_deleted.find_each do |user|
11
+ user.nickname.downcase!
12
12
 
13
- Decidim::User.not_deleted.find_each do |user|
14
- next if has_changed.include? user.id
15
-
16
- Decidim::User.where(organization: user.organization)
17
- .where("nickname ILIKE ?", user.nickname.downcase)
18
- .where.not(id: has_changed + [user.id])
19
- .not_deleted
20
- .order(:created_at)
21
- .each do |similar_user|
22
- # change her nickname to the lowercased one with numbers if needed
23
- begin
24
- update_user_nickname(similar_user, Decidim::UserBaseEntity.nicknamize(similar_user.nickname, organization: similar_user.organization))
25
- rescue ActiveRecord::RecordInvalid => e
26
- logger.warn("User ID (#{similar_user.id}) : #{e}")
13
+ begin
14
+ if user.nickname_changed?
15
+ user.save!
16
+ has_changed << user.id
27
17
  end
28
- has_changed.append(similar_user.id)
18
+ rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotUnique
19
+ update_user_nickname(user, Decidim::UserBaseEntity.nicknamize(user.nickname, organization: user.organization))
20
+ has_changed << user.id
21
+ rescue ActiveRecord::RecordInvalid # rubocop:disable Lint/DuplicateRescueException
22
+ logger.warn("User ID (#{user.id}) : #{e}")
29
23
  end
30
24
  end
31
25
  logger.info("Process terminated, #{has_changed.count} users nickname have been updated.")
32
26
  end
33
27
 
28
+ desc "Modifies nicknames with random numbers when exists similar ones case-insensitively"
29
+ task fix_nickname_uniqueness: :environment do
30
+ Rake::Task["decidim:upgrade:fix_nickname_casing"].execute
31
+ end
32
+
34
33
  private
35
34
 
35
+ def logger
36
+ @logger ||= Logger.new($stdout)
37
+ end
38
+
36
39
  def send_notification_to(user)
37
40
  Decidim::EventsManager.publish(
38
41
  event: "decidim.events.nickname_event",