decidim-proposals 0.22.0 → 0.23.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/decidim/proposals/add_proposal.js.es6 +6 -0
  3. data/app/assets/javascripts/decidim/proposals/admin/proposals_form.js.es6 +3 -0
  4. data/app/cells/decidim/proposals/collaborative_draft_cell.rb +1 -1
  5. data/app/cells/decidim/proposals/participatory_text_proposal/buttons.erb +2 -2
  6. data/app/cells/decidim/proposals/participatory_text_proposal_cell.rb +1 -1
  7. data/app/cells/decidim/proposals/proposal_cell.rb +1 -1
  8. data/app/cells/decidim/proposals/proposal_m_cell.rb +2 -2
  9. data/app/commands/decidim/proposals/admin/create_proposal.rb +4 -2
  10. data/app/commands/decidim/proposals/admin/publish_participatory_text.rb +6 -1
  11. data/app/commands/decidim/proposals/admin/update_participatory_text.rb +10 -2
  12. data/app/commands/decidim/proposals/admin/update_proposal.rb +4 -2
  13. data/app/commands/decidim/proposals/create_proposal.rb +6 -2
  14. data/app/commands/decidim/proposals/publish_collaborative_draft.rb +2 -2
  15. data/app/commands/decidim/proposals/update_proposal.rb +25 -9
  16. data/app/controllers/decidim/proposals/admin/proposals_controller.rb +2 -2
  17. data/app/controllers/decidim/proposals/collaborative_drafts_controller.rb +1 -10
  18. data/app/controllers/decidim/proposals/proposals_controller.rb +3 -17
  19. data/app/controllers/decidim/proposals/{proposal_widgets_controller.rb → widgets_controller.rb} +2 -2
  20. data/app/forms/decidim/proposals/admin/import_participatory_text_form.rb +3 -1
  21. data/app/forms/decidim/proposals/admin/participatory_text_proposal_form.rb +8 -1
  22. data/app/forms/decidim/proposals/admin/proposal_base_form.rb +20 -13
  23. data/app/forms/decidim/proposals/admin/proposal_form.rb +9 -2
  24. data/app/forms/decidim/proposals/proposal_form.rb +21 -12
  25. data/app/helpers/decidim/proposals/admin/proposals_helper.rb +2 -0
  26. data/app/helpers/decidim/proposals/application_helper.rb +13 -8
  27. data/app/helpers/decidim/proposals/proposals_helper.rb +1 -1
  28. data/app/models/decidim/proposals/collaborative_draft.rb +2 -2
  29. data/app/models/decidim/proposals/participatory_text.rb +3 -0
  30. data/app/models/decidim/proposals/proposal.rb +13 -40
  31. data/app/presenters/decidim/proposals/admin_log/value_types/proposal_title_body_presenter.rb +6 -1
  32. data/app/presenters/decidim/proposals/official_author_presenter.rb +1 -29
  33. data/app/presenters/decidim/proposals/proposal_presenter.rb +43 -6
  34. data/app/queries/decidim/proposals/similar_proposals.rb +4 -4
  35. data/app/services/decidim/proposals/collaborative_draft_search.rb +6 -16
  36. data/app/services/decidim/proposals/diff_renderer.rb +15 -5
  37. data/app/services/decidim/proposals/proposal_builder.rb +8 -2
  38. data/app/services/decidim/proposals/proposal_search.rb +7 -58
  39. data/app/types/decidim/proposals/proposal_type.rb +2 -2
  40. data/app/views/decidim/proposals/admin/proposals/_form.html.erb +6 -6
  41. data/app/views/decidim/proposals/admin/proposals/_proposal-tr.html.erb +2 -11
  42. data/app/views/decidim/proposals/admin/proposals/index.html.erb +2 -2
  43. data/app/views/decidim/proposals/admin/proposals/show.html.erb +1 -1
  44. data/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb +5 -5
  45. data/app/views/decidim/proposals/collaborative_drafts/_filters.html.erb +1 -1
  46. data/app/views/decidim/proposals/collaborative_drafts/show.html.erb +1 -1
  47. data/app/views/decidim/proposals/proposals/_edit_form_fields.html.erb +46 -18
  48. data/app/views/decidim/proposals/proposals/_filters.html.erb +1 -1
  49. data/app/views/decidim/proposals/proposals/index.html.erb +0 -2
  50. data/app/views/decidim/proposals/proposals/show.html.erb +3 -3
  51. data/config/locales/am-ET.yml +1 -0
  52. data/config/locales/bg.yml +237 -0
  53. data/config/locales/ca.yml +12 -4
  54. data/config/locales/cs.yml +9 -1
  55. data/config/locales/da.yml +1 -0
  56. data/config/locales/de.yml +3 -0
  57. data/config/locales/en.yml +8 -0
  58. data/config/locales/eo.yml +1 -0
  59. data/config/locales/es-MX.yml +8 -0
  60. data/config/locales/es-PY.yml +8 -0
  61. data/config/locales/es.yml +22 -14
  62. data/config/locales/et.yml +1 -0
  63. data/config/locales/eu.yml +0 -15
  64. data/config/locales/fi-plain.yml +8 -0
  65. data/config/locales/fi.yml +9 -1
  66. data/config/locales/fr-CA.yml +30 -0
  67. data/config/locales/fr.yml +36 -6
  68. data/config/locales/gl.yml +0 -15
  69. data/config/locales/hr.yml +1 -0
  70. data/config/locales/id-ID.yml +0 -15
  71. data/config/locales/is.yml +274 -0
  72. data/config/locales/it.yml +6 -0
  73. data/config/locales/ja-JP.yml +5 -26
  74. data/config/locales/ja.yml +889 -0
  75. data/config/locales/ko-KR.yml +1 -0
  76. data/config/locales/ko.yml +1 -0
  77. data/config/locales/lt.yml +1 -0
  78. data/config/locales/{lv-LV.yml → lv.yml} +0 -0
  79. data/config/locales/mt.yml +1 -0
  80. data/config/locales/nl.yml +9 -1
  81. data/config/locales/om-ET.yml +1 -0
  82. data/config/locales/pl.yml +377 -374
  83. data/config/locales/pt-BR.yml +0 -15
  84. data/config/locales/pt.yml +1 -0
  85. data/config/locales/ro-RO.yml +1 -0
  86. data/config/locales/so-SO.yml +1 -0
  87. data/config/locales/sv.yml +49 -26
  88. data/config/locales/ti-ER.yml +1 -0
  89. data/config/locales/tr-TR.yml +0 -15
  90. data/config/locales/vi-VN.yml +1 -0
  91. data/config/locales/vi.yml +1 -0
  92. data/config/locales/zh-CN.yml +885 -0
  93. data/config/locales/zh-TW.yml +1 -0
  94. data/db/migrate/20200120215928_move_proposal_endorsements_to_core_endorsements.rb +2 -0
  95. data/db/migrate/20200120230130_drop_proposal_endorsements.rb +8 -0
  96. data/db/migrate/20200708091228_move_proposals_fields_to_i18n.rb +80 -0
  97. data/db/migrate/20200827154156_add_commentable_counter_cache_to_proposals.rb +12 -0
  98. data/db/migrate/20200915151348_fix_proposals_data_to_ensure_title_and_body_are_hashes.rb +37 -0
  99. data/db/migrate/20201002085508_fix_proposals_data.rb +37 -0
  100. data/lib/decidim/content_renderers/proposal_renderer.rb +3 -1
  101. data/lib/decidim/proposals/component.rb +9 -6
  102. data/lib/decidim/proposals/engine.rb +1 -1
  103. data/lib/decidim/proposals/markdown_to_proposals.rb +2 -2
  104. data/lib/decidim/proposals/proposal_serializer.rb +3 -3
  105. data/lib/decidim/proposals/test/capybara_proposals_picker.rb +2 -2
  106. data/lib/decidim/proposals/test/factories.rb +44 -18
  107. data/lib/decidim/proposals/version.rb +1 -1
  108. metadata +46 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 95ad7328b3adf635200a9499b7e4f8105621aa050c352988f44f9e6263827f70
4
- data.tar.gz: 381c0320e9e041cd1166a04f6366210abeccd4bcfc07fd4da5369d90202cb31f
3
+ metadata.gz: 0b1d702c001eb32792810f175a1963d5c80edba5f12b34d062247fc4de24cedc
4
+ data.tar.gz: 66e7742e5eb0a37943cafd5fada525162e66dfa8409f5cb270b8a456bbd1328a
5
5
  SHA512:
6
- metadata.gz: 0d242419f3ce6cda013d468c047dca8beebe336be6be871e458d2a805b0e4d2272a2d621e4f952546d17b5087629e45738048d8c2392cc10f402a95c11d9c001
7
- data.tar.gz: be03e252c8ea81291fc8d2931ad348e73d1774e1ccb73550245b4ab8ce1baa8cfa355ee0a15373801df797f6ca70dc38fbe9551cc429c1898056c3b5a65017b5
6
+ metadata.gz: 67449c4a1dd0831103bd357783f509fdf4408eb0908ea6c0d0a43bee0ea949efdf2a9c83d720d46a2a45f80ff24493c6d2ab3c4ec193606ba821eae2b36a8a76
7
+ data.tar.gz: a435ebb30917953b418a20f01d4ee99da0fc4c268210489552c6c4806030d1239c3e84036d9dd3aa529d90f2da3481a35f6702c124c466cd117a451d2361b74f
@@ -1,4 +1,6 @@
1
1
  $(() => {
2
+ const { attachGeocoding } = window.Decidim;
3
+
2
4
  window.DecidimProposals = window.DecidimProposals || {};
3
5
 
4
6
  window.DecidimProposals.bindProposalAddress = () => {
@@ -16,6 +18,10 @@ $(() => {
16
18
  toggleInput();
17
19
  $checkbox.on("change", toggleInput);
18
20
  }
21
+
22
+ if ($addressInput.length > 0) {
23
+ attachGeocoding($("input", $addressInput));
24
+ }
19
25
  };
20
26
 
21
27
  window.DecidimProposals.bindProposalAddress();
@@ -1,4 +1,6 @@
1
1
  $(() => {
2
+ const { attachGeocoding } = window.Decidim;
3
+
2
4
  const $form = $(".proposal_form_admin");
3
5
 
4
6
  if ($form.length > 0) {
@@ -19,5 +21,6 @@ $(() => {
19
21
  $proposalCreatedInMeeting.on("change", toggleDisabledHiddenFields);
20
22
  toggleDisabledHiddenFields();
21
23
 
24
+ attachGeocoding($form.find("#proposal_address"));
22
25
  }
23
26
  });
@@ -22,7 +22,7 @@ module Decidim
22
22
  end
23
23
 
24
24
  def resource_path
25
- resource_locator(model).path
25
+ resource_locator(model).path(filter_link_params)
26
26
  end
27
27
 
28
28
  def current_participatory_space
@@ -16,12 +16,12 @@
16
16
  <% if current_settings.comments_blocked? %>
17
17
  <%= content_tag :button, class: "column medium-4 button light secondary" do %>
18
18
  <%= icon "comment-square", class: "icon--small", aria_label: t("comments", scope: "decidim.proposals.participatory_text_proposal.buttons"), role: "img" %>
19
- <%= model.comments.count %>
19
+ <%= model.comments_count %>
20
20
  <% end %>
21
21
  <%= content_tag :button, t("comment", scope: "decidim.proposals.participatory_text_proposal.buttons"), class: "column button hollow secondary button--sc disabled", disabled: true, title: t("comment", scope: "decidim.proposals.participatory_text_proposal.buttons") %>
22
22
  <% else %>
23
23
  <%= link_to resource_comments_path, class: "column medium-4 button light secondary" do %>
24
- <%= icon "comment-square", class: "icon--small", aria_label: t("comments", scope: "decidim.proposals.participatory_text_proposal.buttons"), role: "img" %> <%= model.comments.count %>
24
+ <%= icon "comment-square", class: "icon--small", aria_label: t("comments", scope: "decidim.proposals.participatory_text_proposal.buttons"), role: "img" %> <%= model.comments_count %>
25
25
  <% end %>
26
26
  <%= link_to resource_comments_path, class: "column button hollow secondary button--sc" do %>
27
27
  <%= t("comment", scope: "decidim.proposals.participatory_text_proposal.buttons") %>
@@ -39,7 +39,7 @@ module Decidim
39
39
  end
40
40
 
41
41
  def resource_path
42
- resource_locator(model).path
42
+ resource_locator(model).path(filter_link_params)
43
43
  end
44
44
 
45
45
  def amend_resource_path
@@ -22,7 +22,7 @@ module Decidim
22
22
  end
23
23
 
24
24
  def resource_path
25
- resource_locator(model).path
25
+ resource_locator(model).path(filter_link_params)
26
26
  end
27
27
 
28
28
  def current_participatory_space
@@ -116,11 +116,11 @@ module Decidim
116
116
  end
117
117
 
118
118
  def has_image?
119
- model.attachments.first.present? && model.attachments.first.file.content_type.start_with?("image") && model.component.settings.allow_card_image
119
+ @has_image ||= model.component.settings.allow_card_image && model.attachments.find_by("content_type like '%image%'").present?
120
120
  end
121
121
 
122
122
  def resource_image_path
123
- model.attachments.first.url if has_image?
123
+ @resource_image_path ||= has_image? ? model.attachments.find_by("content_type like '%image%'").url : nil
124
124
  end
125
125
  end
126
126
  end
@@ -60,9 +60,11 @@ module Decidim
60
60
  end
61
61
 
62
62
  def attributes
63
+ parsed_title = Decidim::ContentProcessor.parse_with_processor(:hashtag, form.title, current_organization: form.current_organization).rewrite
64
+ parsed_body = Decidim::ContentProcessor.parse_with_processor(:hashtag, form.body, current_organization: form.current_organization).rewrite
63
65
  {
64
- title: title_with_hashtags,
65
- body: body_with_hashtags,
66
+ title: parsed_title,
67
+ body: parsed_body,
66
68
  category: form.category,
67
69
  scope: form.scope,
68
70
  component: form.component,
@@ -65,7 +65,12 @@ module Decidim
65
65
  body = proposal.body
66
66
 
67
67
  PaperTrail.request(enabled: false) do
68
- proposal.update_columns(title: "", body: "") # rubocop:disable Rails/SkipsModelValidations
68
+ # rubocop:disable Rails/SkipsModelValidations
69
+ proposal.update_columns(
70
+ title: { I18n.locale => "" },
71
+ body: { I18n.locale => "" }
72
+ )
73
+ # rubocop:enable Rails/SkipsModelValidations
69
74
  end
70
75
 
71
76
  [title, body]
@@ -5,6 +5,8 @@ module Decidim
5
5
  module Admin
6
6
  # A command with all the business logic when an admin updates participatory text proposals.
7
7
  class UpdateParticipatoryText < Rectify::Command
8
+ include Decidim::TranslatableAttributes
9
+
8
10
  # Public: Initializes the command.
9
11
  #
10
12
  # form - A PreviewParticipatoryTextForm form object with the params.
@@ -40,10 +42,16 @@ module Decidim
40
42
  def update_contents_and_resort_proposals(form)
41
43
  PaperTrail.request(enabled: false) do
42
44
  form.proposals.each do |prop_form|
45
+ add_failure(prop_form) if prop_form.invalid?
46
+
43
47
  proposal = Proposal.where(component: form.current_component).find(prop_form.id)
44
48
  proposal.set_list_position(prop_form.position) if proposal.position != prop_form.position
45
- proposal.title = prop_form.title
46
- proposal.body = prop_form.body if proposal.participatory_text_level == ParticipatoryTextSection::LEVELS[:article]
49
+ proposal.title = { I18n.locale => translated_attribute(prop_form.title) }
50
+ proposal.body = if proposal.participatory_text_level == ParticipatoryTextSection::LEVELS[:article]
51
+ { I18n.locale => translated_attribute(prop_form.body) }
52
+ else
53
+ { I18n.locale => "" }
54
+ end
47
55
 
48
56
  add_failure(proposal) unless proposal.save
49
57
  end
@@ -56,11 +56,13 @@ module Decidim
56
56
  attr_reader :form, :proposal, :attachment, :gallery
57
57
 
58
58
  def update_proposal
59
+ parsed_title = Decidim::ContentProcessor.parse_with_processor(:hashtag, form.title, current_organization: form.current_organization).rewrite
60
+ parsed_body = Decidim::ContentProcessor.parse_with_processor(:hashtag, form.body, current_organization: form.current_organization).rewrite
59
61
  Decidim.traceability.update!(
60
62
  proposal,
61
63
  form.current_user,
62
- title: title_with_hashtags,
63
- body: body_with_hashtags,
64
+ title: parsed_title,
65
+ body: parsed_body,
64
66
  category: form.category,
65
67
  scope: form.scope,
66
68
  address: form.address,
@@ -57,8 +57,12 @@ module Decidim
57
57
  visibility: "public-only"
58
58
  ) do
59
59
  proposal = Proposal.new(
60
- title: title_with_hashtags,
61
- body: body_with_hashtags,
60
+ title: {
61
+ I18n.locale => title_with_hashtags
62
+ },
63
+ body: {
64
+ I18n.locale => body_with_hashtags
65
+ },
62
66
  component: form.component
63
67
  )
64
68
  proposal.add_coauthor(@current_user, user_group: user_group)
@@ -59,8 +59,8 @@ module Decidim
59
59
  parsed_title = Decidim::ContentProcessor.parse_with_processor(:hashtag, @collaborative_draft.title, current_organization: @collaborative_draft.organization).rewrite
60
60
  parsed_body = Decidim::ContentProcessor.parse_with_processor(:hashtag, @collaborative_draft.body, current_organization: @collaborative_draft.organization).rewrite
61
61
 
62
- fields[:title] = parsed_title
63
- fields[:body] = parsed_body
62
+ fields[:title] = { I18n.locale => parsed_title }
63
+ fields[:body] = { I18n.locale => parsed_body }
64
64
  fields[:component] = @collaborative_draft.component
65
65
  fields[:scope] = @collaborative_draft.scope
66
66
  fields[:address] = @collaborative_draft.address
@@ -4,7 +4,8 @@ module Decidim
4
4
  module Proposals
5
5
  # A command with all the business logic when a user updates a proposal.
6
6
  class UpdateProposal < Rectify::Command
7
- include ::Decidim::AttachmentMethods
7
+ include ::Decidim::MultipleAttachmentsMethods
8
+ include GalleryMethods
8
9
  include HashtagsMethods
9
10
 
10
11
  # Public: Initializes the command.
@@ -26,15 +27,18 @@ module Decidim
26
27
  #
27
28
  # Returns nothing.
28
29
  def call
29
- return broadcast(:invalid) if form.invalid?
30
- return broadcast(:invalid) unless proposal.editable_by?(current_user)
31
- return broadcast(:invalid) if proposal_limit_reached?
30
+ return broadcast(:invalid) if invalid?
32
31
 
33
32
  if process_attachments?
34
33
  @proposal.attachments.destroy_all
35
34
 
36
- build_attachment
37
- return broadcast(:invalid) if attachment_invalid?
35
+ build_attachments
36
+ return broadcast(:invalid) if attachments_invalid?
37
+ end
38
+
39
+ if process_gallery?
40
+ build_gallery
41
+ return broadcast(:invalid) if gallery_invalid?
38
42
  end
39
43
 
40
44
  transaction do
@@ -43,7 +47,11 @@ module Decidim
43
47
  else
44
48
  update_proposal
45
49
  end
46
- create_attachment if process_attachments?
50
+ create_gallery if process_gallery?
51
+ create_attachments if process_attachments?
52
+
53
+ photo_cleanup!
54
+ document_cleanup!
47
55
  end
48
56
 
49
57
  broadcast(:ok, proposal)
@@ -53,6 +61,10 @@ module Decidim
53
61
 
54
62
  attr_reader :form, :proposal, :current_user, :attachment
55
63
 
64
+ def invalid?
65
+ form.invalid? || !proposal.editable_by?(current_user) || proposal_limit_reached?
66
+ end
67
+
56
68
  # Prevent PaperTrail from creating an additional version
57
69
  # in the proposal multi-step creation process (step 3: complete)
58
70
  #
@@ -79,8 +91,12 @@ module Decidim
79
91
 
80
92
  def attributes
81
93
  {
82
- title: title_with_hashtags,
83
- body: body_with_hashtags,
94
+ title: {
95
+ I18n.locale => title_with_hashtags
96
+ },
97
+ body: {
98
+ I18n.locale => body_with_hashtags
99
+ },
84
100
  category: form.category,
85
101
  scope: form.scope,
86
102
  address: form.address,
@@ -21,14 +21,14 @@ module Decidim
21
21
 
22
22
  def new
23
23
  enforce_permission_to :create, :proposal
24
- @form = form(Admin::ProposalForm).from_params(
24
+ @form = form(Decidim::Proposals::Admin::ProposalForm).from_params(
25
25
  attachment: form(AttachmentForm).from_params({})
26
26
  )
27
27
  end
28
28
 
29
29
  def create
30
30
  enforce_permission_to :create, :proposal
31
- @form = form(Admin::ProposalForm).from_params(params)
31
+ @form = form(Decidim::Proposals::Admin::ProposalForm).from_params(params)
32
32
 
33
33
  Admin::CreateProposal.call(@form) do
34
34
  on(:ok) do
@@ -10,6 +10,7 @@ module Decidim
10
10
 
11
11
  include Decidim::ApplicationHelper
12
12
  include FormFactory
13
+ include Flaggable
13
14
  include FilterResource
14
15
  include CollaborativeOrderable
15
16
  include Paginable
@@ -183,16 +184,6 @@ module Decidim
183
184
 
184
185
  ["without"] + current_component.participatory_space.categories.map { |category| category.id.to_s }
185
186
  end
186
-
187
- def default_filter_scope_params
188
- return unless current_component.participatory_space.scopes.any?
189
-
190
- if current_component.participatory_space.scope
191
- [current_component.participatory_space.scope.id] + current_component.participatory_space.scope.children.map { |scope| scope.id.to_s }
192
- else
193
- ["global"] + current_component.participatory_space.scopes.map { |scope| scope.id.to_s }
194
- end
195
- end
196
187
  end
197
188
  end
198
189
  end
@@ -8,6 +8,8 @@ module Decidim
8
8
  helper ProposalWizardHelper
9
9
  helper ParticipatoryTextsHelper
10
10
  include Decidim::ApplicationHelper
11
+ include Flaggable
12
+ include Withdrawable
11
13
  include FormFactory
12
14
  include FilterResource
13
15
  include Decidim::Proposals::Orderable
@@ -214,7 +216,7 @@ module Decidim
214
216
  origin: default_filter_origin_params,
215
217
  activity: "all",
216
218
  category_id: default_filter_category_params,
217
- state: %w(accepted evaluating not_answered),
219
+ state: %w(accepted evaluating state_not_published),
218
220
  scope_id: default_filter_scope_params,
219
221
  related_to: "",
220
222
  type: "all"
@@ -228,22 +230,6 @@ module Decidim
228
230
  filter_origin_params
229
231
  end
230
232
 
231
- def default_filter_category_params
232
- return "all" unless current_component.participatory_space.categories.any?
233
-
234
- ["all"] + current_component.participatory_space.categories.pluck(:id).map(&:to_s)
235
- end
236
-
237
- def default_filter_scope_params
238
- return "all" unless current_component.participatory_space.scopes.any?
239
-
240
- if current_component.participatory_space.scope
241
- ["all", current_component.participatory_space.scope.id] + current_component.participatory_space.scope.children.map { |scope| scope.id.to_s }
242
- else
243
- %w(all global) + current_component.participatory_space.scopes.pluck(:id).map(&:to_s)
244
- end
245
- end
246
-
247
233
  def proposal_draft
248
234
  Proposal.from_all_author_identities(current_user).not_hidden.only_amendables
249
235
  .where(component: current_component).find_by(published_at: nil)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Decidim
4
4
  module Proposals
5
- class ProposalWidgetsController < Decidim::WidgetsController
5
+ class WidgetsController < Decidim::WidgetsController
6
6
  helper Proposals::ApplicationHelper
7
7
 
8
8
  private
@@ -12,7 +12,7 @@ module Decidim
12
12
  end
13
13
 
14
14
  def iframe_url
15
- @iframe_url ||= proposal_proposal_widget_url(model)
15
+ @iframe_url ||= proposal_widget_url(model)
16
16
  end
17
17
  end
18
18
  end
@@ -8,6 +8,8 @@ module Decidim
8
8
  class ImportParticipatoryTextForm < Decidim::Form
9
9
  include TranslatableAttributes
10
10
 
11
+ # WARNING: consider adding/removing the relative translation key at
12
+ # decidim.assemblies.admin.new_import.accepted_types when modifying this hash
11
13
  ACCEPTED_MIME_TYPES = Decidim::Proposals::DocToMarkdown::ACCEPTED_MIME_TYPES
12
14
 
13
15
  translatable_attribute :title, String
@@ -33,7 +35,7 @@ module Decidim
33
35
 
34
36
  # Return ACCEPTED_MIME_TYPES plus `text/plain` for better markdown support
35
37
  def valid_mime_types
36
- ACCEPTED_MIME_TYPES.values + [Decidim::Proposals::DocToMarkdown::TEXT_PLAIN_MIME_TYPE]
38
+ ACCEPTED_MIME_TYPES.values + [Decidim::Proposals::DocToMarkdown::TEXT_PLAIN_MIME_TYPE] + ["application/octet-stream"]
37
39
  end
38
40
 
39
41
  def document_type
@@ -6,7 +6,14 @@ module Decidim
6
6
  # A form object to be used when admin users want to create a proposal
7
7
  # through the participatory texts.
8
8
  class ParticipatoryTextProposalForm < Admin::ProposalBaseForm
9
- validates :title, length: { maximum: 150 }
9
+ attribute :title, String
10
+ attribute :body, String
11
+ validates :title, length: { maximum: 150 }, presence: true
12
+
13
+ def map_model(model)
14
+ self.title = translated_attribute(model.title)
15
+ self.body = translated_attribute(model.body)
16
+ end
10
17
  end
11
18
  end
12
19
  end
@@ -5,11 +5,11 @@ module Decidim
5
5
  module Admin
6
6
  # A form object to be used when admin users want to create a proposal.
7
7
  class ProposalBaseForm < Decidim::Form
8
+ include Decidim::TranslatableAttributes
8
9
  include Decidim::ApplicationHelper
10
+
9
11
  mimic :proposal
10
12
 
11
- attribute :title, String
12
- attribute :body, String
13
13
  attribute :address, String
14
14
  attribute :latitude, Float
15
15
  attribute :longitude, Float
@@ -23,25 +23,24 @@ module Decidim
23
23
  attribute :photos, Array[String]
24
24
  attribute :add_photos, Array
25
25
 
26
- validates :title, :body, presence: true
27
- validates :address, geocoding: true, if: -> { current_component.settings.geocoding_enabled? }
26
+ validates :address, geocoding: true, if: ->(form) { form.has_address? && !form.geocoded? }
28
27
  validates :category, presence: true, if: ->(form) { form.category_id.present? }
29
28
  validates :scope, presence: true, if: ->(form) { form.scope_id.present? }
29
+ validates :scope_id, scope_belongs_to_component: true, if: ->(form) { form.scope_id.present? }
30
30
  validates :meeting_as_author, presence: true, if: ->(form) { form.created_in_meeting? }
31
31
 
32
- validate :scope_belongs_to_participatory_space_scope
33
-
34
32
  validate :notify_missing_attachment_if_errored
35
33
 
36
34
  delegate :categories, to: :current_component
37
35
 
38
36
  def map_model(model)
37
+ body = translated_attribute(model.body)
38
+ @suggested_hashtags = Decidim::ContentRenderers::HashtagRenderer.new(body).extra_hashtags.map(&:name).map(&:downcase)
39
+
39
40
  return unless model.categorization
40
41
 
41
42
  self.category_id = model.categorization.decidim_category_id
42
43
  self.scope_id = model.decidim_scope_id
43
-
44
- @suggested_hashtags = Decidim::ContentRenderers::HashtagRenderer.new(model.body).extra_hashtags.map(&:name).map(&:downcase)
45
44
  end
46
45
 
47
46
  alias component current_component
@@ -57,7 +56,7 @@ module Decidim
57
56
  #
58
57
  # Returns a Decidim::Scope
59
58
  def scope
60
- @scope ||= @scope_id ? current_participatory_space.scopes.find_by(id: @scope_id) : current_participatory_space.scope
59
+ @scope ||= @scope_id ? current_component.scopes.find_by(id: @scope_id) : current_component.scope
61
60
  end
62
61
 
63
62
  # Scope identifier
@@ -67,6 +66,18 @@ module Decidim
67
66
  @scope_id || scope&.id
68
67
  end
69
68
 
69
+ def geocoding_enabled?
70
+ Decidim::Map.available?(:geocoding) && current_component.settings.geocoding_enabled?
71
+ end
72
+
73
+ def has_address?
74
+ geocoding_enabled? && address.present?
75
+ end
76
+
77
+ def geocoded?
78
+ latitude.present? && longitude.present?
79
+ end
80
+
70
81
  # Finds the Meetings of the current participatory space
71
82
  def meetings
72
83
  @meetings ||= Decidim.find_resource_manifest(:meetings).try(:resource_scope, current_component)
@@ -107,10 +118,6 @@ module Decidim
107
118
 
108
119
  private
109
120
 
110
- def scope_belongs_to_participatory_space_scope
111
- errors.add(:scope_id, :invalid) if current_participatory_space.out_of_scope?(scope)
112
- end
113
-
114
121
  # This method will add an error to the `attachment` field only if there's
115
122
  # any error in any other field. This is needed because when the form has
116
123
  # an error, the attachment is lost, so we need a way to inform the user of