decidim-proposals 0.23.1 → 0.23.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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/proposals/proposal_activity_cell.rb +13 -5
  3. data/app/cells/decidim/proposals/proposals_picker_cell.rb +1 -1
  4. data/app/commands/decidim/proposals/admin/update_proposal.rb +2 -0
  5. data/app/controllers/decidim/proposals/admin/proposals_controller.rb +1 -1
  6. data/app/controllers/decidim/proposals/proposals_controller.rb +7 -5
  7. data/app/forms/decidim/proposals/admin/proposal_form.rb +13 -0
  8. data/app/forms/decidim/proposals/proposal_wizard_create_step_form.rb +0 -8
  9. data/app/helpers/decidim/proposals/map_helper.rb +8 -4
  10. data/app/models/decidim/proposals/proposal.rb +3 -1
  11. data/app/presenters/decidim/proposals/admin_log/proposal_presenter.rb +2 -2
  12. data/app/presenters/decidim/proposals/admin_log/valuation_assignment_presenter.rb +2 -2
  13. data/app/presenters/decidim/proposals/proposal_presenter.rb +31 -12
  14. data/app/services/decidim/proposals/collaborative_draft_search.rb +1 -1
  15. data/app/services/decidim/proposals/proposal_builder.rb +4 -2
  16. data/app/validators/proposal_length_validator.rb +4 -2
  17. data/app/views/decidim/proposals/admin/proposals/_form.html.erb +8 -2
  18. data/app/views/decidim/proposals/collaborative_drafts/edit.html.erb +6 -4
  19. data/app/views/decidim/proposals/collaborative_drafts/show.html.erb +6 -4
  20. data/app/views/decidim/proposals/proposals/edit.html.erb +6 -4
  21. data/app/views/decidim/proposals/proposals/index.html.erb +1 -1
  22. data/app/views/decidim/proposals/proposals/show.html.erb +6 -4
  23. data/config/locales/ar.yml +1 -0
  24. data/config/locales/bg.yml +4 -0
  25. data/config/locales/ca.yml +10 -8
  26. data/config/locales/cs.yml +51 -49
  27. data/config/locales/de.yml +107 -78
  28. data/config/locales/el.yml +1 -1
  29. data/config/locales/en.yml +2 -0
  30. data/config/locales/es-MX.yml +5 -3
  31. data/config/locales/es-PY.yml +5 -3
  32. data/config/locales/es.yml +5 -3
  33. data/config/locales/eu.yml +5 -2
  34. data/config/locales/fi-plain.yml +3 -1
  35. data/config/locales/fi.yml +10 -8
  36. data/config/locales/fr-CA.yml +6 -4
  37. data/config/locales/fr.yml +6 -4
  38. data/config/locales/gl.yml +78 -3
  39. data/config/locales/hu.yml +1 -0
  40. data/config/locales/id-ID.yml +1 -0
  41. data/config/locales/is-IS.yml +4 -1
  42. data/config/locales/it.yml +3 -3
  43. data/config/locales/ja.yml +1 -1
  44. data/config/locales/lv.yml +1 -0
  45. data/config/locales/nl.yml +18 -16
  46. data/config/locales/no.yml +3 -2
  47. data/config/locales/pl.yml +10 -3
  48. data/config/locales/pt-BR.yml +2 -1
  49. data/config/locales/ro-RO.yml +59 -0
  50. data/config/locales/ru.yml +4 -1
  51. data/config/locales/si-LK.yml +1 -0
  52. data/config/locales/sk.yml +2 -1
  53. data/config/locales/sv.yml +14 -5
  54. data/config/locales/sw-KE.yml +1 -0
  55. data/config/locales/tr-TR.yml +381 -217
  56. data/config/locales/uk.yml +4 -1
  57. data/db/migrate/20210127115628_fix_answered_proposals_after_copy.rb +14 -0
  58. data/db/migrate/20210318082934_fix_counters_for_copied_proposals.rb +16 -0
  59. data/lib/decidim/proposals/version.rb +1 -1
  60. metadata +25 -22
  61. data/db/migrate/20200915151348_fix_proposals_data_to_ensure_title_and_body_are_hashes.rb +0 -37
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 82abb8e700200d86798c63c09f42604c50e8117ec6f162eac16f93fbbe51d2b4
4
- data.tar.gz: 8becaeaae84754886571c87b1f2df2caa01e8dd17b81808aa1af4e2dff9ecaaa
3
+ metadata.gz: 9bf25b623709eab1b21a1fb192f79de33e0d372384d67435e7e945d0e40fe7b0
4
+ data.tar.gz: a05a461559454ad127097d7344f5fb8d50e6fc2c9537319e711bb7e09c3f6355
5
5
  SHA512:
6
- metadata.gz: bc3725296a98abca0ae3b7634813ceb50a28be31045082b7764bb12b39974a5de013e01b86818c648293ca6147ba4a900ea985413a023bc6b73b71ce73ede570
7
- data.tar.gz: b586bdd3ebec54dc6f29de58a2bbabc6dbd77209884cdde6fbd3eef3b7e53f282d862536eb84a064e1105fe51cb1e58d2d64e0ce25e2f0f1428b065b22b002bf
6
+ metadata.gz: e5ea130360aadb726c4a03b283f542bffed6c5b55eb1451115cddd26e07ef4ac85f26ed3c2da83a07a53abf68b4dce404f144614beb6e4074f2ab0d2b8a3230b
7
+ data.tar.gz: 16db0fb106633338d4253fa0c92cade541a68894c92807d89839004de283e27e41b0d2472dd1cc6e646f41c78b90acf6b06efc4126f46ac59b342561e19ccc79
@@ -2,13 +2,21 @@
2
2
 
3
3
  module Decidim
4
4
  module Proposals
5
- # A cell to display when a proposal has been published.
5
+ # A cell to display when actions happen on a proposal.
6
6
  class ProposalActivityCell < ActivityCell
7
7
  def title
8
- I18n.t(
9
- "decidim.proposals.last_activity.new_proposal_at_html",
10
- link: participatory_space_link
11
- )
8
+ case action
9
+ when "update"
10
+ I18n.t(
11
+ "decidim.proposals.last_activity.proposal_updated_at_html",
12
+ link: participatory_space_link
13
+ )
14
+ else
15
+ I18n.t(
16
+ "decidim.proposals.last_activity.new_proposal_at_html",
17
+ link: participatory_space_link
18
+ )
19
+ end
12
20
  end
13
21
 
14
22
  def resource_link_text
@@ -50,7 +50,7 @@ module Decidim
50
50
 
51
51
  def filtered_proposals
52
52
  @filtered_proposals ||= if filtered?
53
- proposals.where("title ILIKE ?", "%#{search_text}%")
53
+ proposals.where("title::text ILIKE ?", "%#{search_text}%")
54
54
  .or(proposals.where("reference ILIKE ?", "%#{search_text}%"))
55
55
  .or(proposals.where("id::text ILIKE ?", "%#{search_text}%"))
56
56
  else
@@ -28,6 +28,8 @@ module Decidim
28
28
  def call
29
29
  return broadcast(:invalid) if form.invalid?
30
30
 
31
+ delete_attachment(form.attachment) if delete_attachment?
32
+
31
33
  if process_attachments?
32
34
  @proposal.attachments.destroy_all
33
35
 
@@ -124,13 +124,13 @@ module Decidim
124
124
  def edit
125
125
  enforce_permission_to :edit, :proposal, proposal: proposal
126
126
  @form = form(Admin::ProposalForm).from_model(proposal)
127
- @form.attachment = form(AttachmentForm).from_params({})
128
127
  end
129
128
 
130
129
  def update
131
130
  enforce_permission_to :edit, :proposal, proposal: proposal
132
131
 
133
132
  @form = form(Admin::ProposalForm).from_params(params)
133
+
134
134
  Admin::UpdateProposal.call(@form, @proposal) do
135
135
  on(:ok) do |_proposal|
136
136
  flash[:notice] = t("proposals.update.success", scope: "decidim")
@@ -35,11 +35,13 @@ module Decidim
35
35
  .order(position: :asc)
36
36
  render "decidim/proposals/proposals/participatory_texts/participatory_text"
37
37
  else
38
- @proposals = search
39
- .results
40
- .published
41
- .not_hidden
42
- .includes(:amendable, :category, :component, :resource_permission, :scope)
38
+ @base_query = search
39
+ .results
40
+ .published
41
+ .not_hidden
42
+
43
+ @proposals = @base_query.includes(:amendable, :category, :component, :resource_permission, :scope)
44
+ @all_geocoded_proposals = @base_query.geocoded
43
45
 
44
46
  @voted_proposals = if current_user
45
47
  ProposalVote.where(
@@ -13,6 +13,19 @@ module Decidim
13
13
  validates :title, :body, translatable_presence: true
14
14
 
15
15
  validate :notify_missing_attachment_if_errored
16
+
17
+ def map_model(model)
18
+ super(model)
19
+ presenter = ProposalPresenter.new(model)
20
+
21
+ self.title = presenter.title(all_locales: title.is_a?(Hash))
22
+ self.body = presenter.body(all_locales: body.is_a?(Hash))
23
+ self.attachment = if model.documents.first.present?
24
+ { file: model.documents.first.file, title: translated_attribute(model.documents.first.title) }
25
+ else
26
+ {}
27
+ end
28
+ end
16
29
  end
17
30
  end
18
31
  end
@@ -18,7 +18,6 @@ module Decidim
18
18
  maximum: ->(record) { record.component.settings.proposal_length }
19
19
  }
20
20
 
21
- validate :proposal_length
22
21
  validate :body_is_not_bare_template
23
22
 
24
23
  alias component current_component
@@ -32,13 +31,6 @@ module Decidim
32
31
 
33
32
  private
34
33
 
35
- def proposal_length
36
- return unless body.presence
37
-
38
- length = current_component.settings.proposal_length
39
- errors.add(:body, :too_long, count: length) if body.length > length
40
- end
41
-
42
34
  def body_is_not_bare_template
43
35
  return if body_template.blank?
44
36
 
@@ -10,10 +10,14 @@ module Decidim
10
10
  # geocoded_proposals - A collection of geocoded proposals
11
11
  def proposals_data_for_map(geocoded_proposals)
12
12
  geocoded_proposals.map do |proposal|
13
- proposal.slice(:latitude, :longitude, :address).merge(title: present(proposal).title,
14
- body: truncate(present(proposal).body, length: 100),
15
- icon: icon("proposals", width: 40, height: 70, remove_icon_class: true),
16
- link: proposal_path(proposal))
13
+ proposal
14
+ .slice(:latitude, :longitude, :address)
15
+ .merge(
16
+ title: decidim_html_escape(present(proposal).title),
17
+ body: html_truncate(decidim_sanitize(present(proposal).body), length: 100),
18
+ icon: icon("proposals", width: 40, height: 70, remove_icon_class: true),
19
+ link: proposal_path(proposal)
20
+ )
17
21
  end
18
22
  end
19
23
  end
@@ -130,7 +130,9 @@ module Decidim
130
130
  .where(decidim_author_type: "Decidim::UserBaseEntity")
131
131
  .pluck(:decidim_author_id).to_a.compact.uniq
132
132
 
133
- (endorsements_participants_ids + participants_has_voted_ids + coauthors_recipients_ids).flatten.compact.uniq
133
+ commentators_ids = Decidim::Comments::Comment.user_commentators_ids_in(proposals)
134
+
135
+ (endorsements_participants_ids + participants_has_voted_ids + coauthors_recipients_ids + commentators_ids).flatten.compact.uniq
134
136
  end
135
137
 
136
138
  # Public: Updates the vote count of this proposal.
@@ -42,8 +42,8 @@ module Decidim
42
42
  "activemodel.attributes.proposal"
43
43
  end
44
44
 
45
- def has_diff?
46
- action == "answer" || super
45
+ def diff_actions
46
+ super + %w(answer)
47
47
  end
48
48
  end
49
49
  end
@@ -38,8 +38,8 @@ module Decidim
38
38
  "activemodel.attributes.valuation_assignment.admin_log"
39
39
  end
40
40
 
41
- def has_diff?
42
- %w(create delete).include?(action) || super
41
+ def diff_actions
42
+ super + %w(create delete)
43
43
  end
44
44
 
45
45
  def i18n_params
@@ -38,28 +38,33 @@ module Decidim
38
38
  # extras - should include extra hashtags?
39
39
  #
40
40
  # Returns a String.
41
- def title(links: false, extras: true, html_escape: false)
42
- text = translated_attribute(proposal.title)
43
- text = decidim_html_escape(text) if html_escape
41
+ def title(links: false, extras: true, html_escape: false, all_locales: false)
42
+ return unless proposal
44
43
 
45
- renderer = Decidim::ContentRenderers::HashtagRenderer.new(text)
46
- renderer.render(links: links, extras: extras).html_safe
44
+ handle_locales(proposal.title, all_locales) do |content|
45
+ content = decidim_html_escape(content) if html_escape
46
+
47
+ renderer = Decidim::ContentRenderers::HashtagRenderer.new(content)
48
+ renderer.render(links: links, extras: extras).html_safe
49
+ end
47
50
  end
48
51
 
49
52
  def id_and_title(links: false, extras: true, html_escape: false)
50
53
  "##{proposal.id} - #{title(links: links, extras: extras, html_escape: html_escape)}"
51
54
  end
52
55
 
53
- def body(links: false, extras: true, strip_tags: false)
54
- text = translated_attribute(proposal.body)
56
+ def body(links: false, extras: true, strip_tags: false, all_locales: false)
57
+ return unless proposal
55
58
 
56
- text = strip_tags(sanitize_text(text)) if strip_tags
59
+ handle_locales(proposal.body, all_locales) do |content|
60
+ content = strip_tags(sanitize_text(content)) if strip_tags
57
61
 
58
- renderer = Decidim::ContentRenderers::HashtagRenderer.new(text)
59
- text = renderer.render(links: links, extras: extras).html_safe
62
+ renderer = Decidim::ContentRenderers::HashtagRenderer.new(content)
63
+ content = renderer.render(links: links, extras: extras).html_safe
60
64
 
61
- text = Decidim::ContentRenderers::LinkRenderer.new(text).render if links
62
- text
65
+ content = Decidim::ContentRenderers::LinkRenderer.new(content).render if links
66
+ content
67
+ end
63
68
  end
64
69
 
65
70
  # Returns the proposal versions, hiding not published answers
@@ -130,6 +135,20 @@ module Decidim
130
135
  def sanitize_text(text)
131
136
  add_line_feeds(sanitize_ordered_lists(sanitize_unordered_lists(text)))
132
137
  end
138
+
139
+ def handle_locales(content, all_locales, &block)
140
+ if all_locales
141
+ content.each_with_object({}) do |(key, value), parsed_content|
142
+ parsed_content[key] = if key == "machine_translations"
143
+ handle_locales(value, all_locales, &block)
144
+ else
145
+ block.call(value)
146
+ end
147
+ end
148
+ else
149
+ yield(translated_attribute(content))
150
+ end
151
+ end
133
152
  end
134
153
  end
135
154
  end
@@ -21,7 +21,7 @@ module Decidim
21
21
  # translated.
22
22
  def search_search_text
23
23
  query
24
- .where("title ILIKE ?", "%#{search_text}%")
24
+ .where("title::text ILIKE ?", "%#{search_text}%")
25
25
  .or(query.where("body ILIKE ?", "%#{search_text}%"))
26
26
  end
27
27
 
@@ -63,13 +63,15 @@ module Decidim
63
63
  "created_at",
64
64
  "updated_at",
65
65
  "state",
66
+ "state_published_at",
66
67
  "answer",
67
68
  "answered_at",
68
69
  "decidim_component_id",
69
70
  "reference",
70
- "proposal_votes_count",
71
+ "comments_count",
71
72
  "endorsements_count",
72
- "proposal_notes_count"
73
+ "proposal_notes_count",
74
+ "proposal_votes_count"
73
75
  ).merge(
74
76
  "category" => original_proposal.category
75
77
  ).merge(
@@ -20,7 +20,8 @@ class ProposalLengthValidator < ActiveModel::EachValidator
20
20
  if min && min.positive? && value.length < min
21
21
  record.errors.add(
22
22
  attribute,
23
- options[:message] || :too_short
23
+ options[:message] || :too_short,
24
+ count: min
24
25
  )
25
26
  end
26
27
  end
@@ -31,7 +32,8 @@ class ProposalLengthValidator < ActiveModel::EachValidator
31
32
  if max && max.positive? && value.length > max
32
33
  record.errors.add(
33
34
  attribute,
34
- options[:message] || :too_long
35
+ options[:message] || :too_long,
36
+ count: max
35
37
  )
36
38
  end
37
39
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  <div class="card-section">
7
7
  <div class="row column hashtags__container">
8
- <%= form.translated :text_field, :title, class: "js-hashtags", value: form_presenter.title(extras: false).strip, hashtaggable: true %>
8
+ <%= form.translated :text_field, :title, autofocus: true, class: "js-hashtags", hashtaggable: true %>
9
9
  </div>
10
10
 
11
11
  <div class="row column hashtags__container">
12
- <%= form.translated :editor, :body, hashtaggable: true, value: form_presenter.body(extras: false).strip %>
12
+ <%= form.translated :editor, :body, hashtaggable: true %>
13
13
  </div>
14
14
 
15
15
  <% if @form.component_automatic_hashtags.any? %>
@@ -84,6 +84,12 @@
84
84
 
85
85
  <div class="row column">
86
86
  <%= form.upload :file, optional: false %>
87
+ <% if params[:id].present? %>
88
+ <% if proposal.documents.present? %>
89
+ <%= form.hidden_field :id, value: proposal.documents.first.id %>
90
+ <%= form.check_box :delete_file, label: t(".delete_attachment"), value: proposal.documents.first.id %>
91
+ <% end %>
92
+ <% end %>
87
93
  </div>
88
94
  <% end %>
89
95
  </fieldset>
@@ -1,10 +1,12 @@
1
1
  <% add_decidim_page_title(proposal_wizard_step_title(action_name)) %>
2
2
 
3
3
  <div class="row columns">
4
- <%= link_to :back, class: "muted-link" do %>
5
- <%= icon "chevron-left", class: "icon--small", role: "img", "aria-hidden": true %>
6
- <%= t(".back") %>
7
- <% end %>
4
+ <div class="m-bottom">
5
+ <%= link_to :back, class: "muted-link" do %>
6
+ <%= icon "chevron-left", class: "icon--small", role: "img", "aria-hidden": true %>
7
+ <%= t(".back") %>
8
+ <% end %>
9
+ </div>
8
10
  <h2 class="section-heading"><%= t(".title") %></h2>
9
11
  </div>
10
12
 
@@ -14,10 +14,12 @@
14
14
  <% end %>
15
15
 
16
16
  <div class="row column view-header">
17
- <%= link_to collaborative_drafts_path do %>
18
- <%= icon "chevron-left", class: "icon--small", role: "img", "aria-hidden": true %>
19
- <%= t(".back") %>
20
- <% end %>
17
+ <div class="m-bottom">
18
+ <%= link_to collaborative_drafts_path do %>
19
+ <%= icon "chevron-left", class: "icon--small", role: "img", "aria-hidden": true %>
20
+ <%= t(".back") %>
21
+ <% end %>
22
+ </div>
21
23
 
22
24
  <h2 class="heading2">
23
25
  <%= present(@collaborative_draft).title(links: true, html_escape: true) %>
@@ -1,10 +1,12 @@
1
1
  <% add_decidim_page_title(proposal_wizard_step_title(action_name)) %>
2
2
 
3
3
  <div class="row columns">
4
- <%= link_to :back, class: "muted-link" do %>
5
- <%= icon "chevron-left", class: "icon--small", role: "img", "aria-hidden": true %>
6
- <%= t(".back") %>
7
- <% end %>
4
+ <div class="m-bottom">
5
+ <%= link_to :back, class: "muted-link" do %>
6
+ <%= icon "chevron-left", class: "icon--small", role: "img", "aria-hidden": true %>
7
+ <%= t(".back") %>
8
+ <% end %>
9
+ </div>
8
10
  <h2 class="section-heading"><%= t(".title") %></h2>
9
11
  </div>
10
12
 
@@ -1,7 +1,7 @@
1
1
  <%= render partial: "decidim/shared/component_announcement" %>
2
2
 
3
3
  <% if component_settings.geocoding_enabled? %>
4
- <%= dynamic_map_for proposals_data_for_map(@proposals.select(&:geocoded?)) do %>
4
+ <%= dynamic_map_for proposals_data_for_map(@all_geocoded_proposals) do %>
5
5
  <template id="marker-popup">
6
6
  <div class="map-info__content">
7
7
  <h3>${title}</h3>
@@ -34,10 +34,12 @@ extra_admin_link(
34
34
  <%= emendation_announcement_for @proposal %>
35
35
  <div class="row column view-header">
36
36
 
37
- <%= link_to proposals_path(filter_link_params), class: "small hollow" do %>
38
- <%= icon "chevron-left", class: "icon--small", role: "img", "aria-hidden": true %>
39
- <%= t(".back_to_list") %>
40
- <% end %>
37
+ <div class="m-bottom">
38
+ <%= link_to proposals_path(filter_link_params), class: "small hollow" do %>
39
+ <%= icon "chevron-left", class: "icon--small", role: "img", "aria-hidden": true %>
40
+ <%= t(".back_to_list") %>
41
+ <% end %>
42
+ </div>
41
43
 
42
44
  <% if @proposal.emendation? %>
43
45
  <h3 class="heading3"><%= t(".changes_at_title", title: present(@proposal.amendable).title(links: true, html_escape: true)) %></h3>
@@ -578,6 +578,7 @@ ar:
578
578
  update:
579
579
  error: حدثت مشكلة في حفظ المسودة التعاونية.
580
580
  success: تم تحديث المسودة التعاونية بنجاح.
581
+ title: تحرير المسودة التعاونية
581
582
  wizard_aside:
582
583
  back: الى الخلف
583
584
  info: إنك لعلى خلق <strong>مشروع تعاوني</strong>.
@@ -229,6 +229,10 @@ bg:
229
229
  proposal_published_for_space:
230
230
  email_intro: Предложението "%{resource_title}" беше добавено в "%{participatory_space_title}", което следвате.
231
231
  email_outro: Получавате това известие, защото следвате "%{participatory_space_title}". Може да прекратите известията чрез предната връзка.
232
+ participatory_processes:
233
+ participatory_process_groups:
234
+ highlighted_proposals:
235
+ proposals: Предложения
232
236
  proposals:
233
237
  versions:
234
238
  collaborative_drafts: