decidim-proposals 0.31.6 → 0.32.0.rc1

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 (176) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -14
  3. data/app/cells/decidim/proposals/proposal_vote/show.erb +16 -1
  4. data/app/commands/decidim/proposals/admin/merge_proposals.rb +1 -0
  5. data/app/commands/decidim/proposals/admin/notify_proposal_answer.rb +13 -1
  6. data/app/commands/decidim/proposals/admin/update_proposal.rb +1 -1
  7. data/app/commands/decidim/proposals/admin/update_proposal_taxonomies.rb +1 -0
  8. data/app/commands/decidim/proposals/create_proposal.rb +1 -1
  9. data/app/commands/decidim/proposals/gallery_methods.rb +17 -0
  10. data/app/commands/decidim/proposals/unvote_proposal.rb +0 -1
  11. data/app/commands/decidim/proposals/update_proposal.rb +1 -1
  12. data/app/controllers/concerns/decidim/proposals/admin/filterable.rb +0 -4
  13. data/app/controllers/concerns/decidim/proposals/orderable.rb +22 -3
  14. data/app/controllers/decidim/proposals/admin/evaluation_assignments_controller.rb +2 -2
  15. data/app/controllers/decidim/proposals/admin/participatory_texts_controller.rb +4 -4
  16. data/app/controllers/decidim/proposals/admin/proposal_answers_controller.rb +1 -1
  17. data/app/controllers/decidim/proposals/admin/proposal_states_controller.rb +2 -2
  18. data/app/controllers/decidim/proposals/admin/proposals_controller.rb +2 -2
  19. data/app/controllers/decidim/proposals/admin/proposals_imports_controller.rb +1 -1
  20. data/app/controllers/decidim/proposals/admin/proposals_merges_controller.rb +1 -1
  21. data/app/controllers/decidim/proposals/invite_coauthors_controller.rb +2 -2
  22. data/app/controllers/decidim/proposals/proposal_votes_controller.rb +1 -1
  23. data/app/controllers/decidim/proposals/proposals_controller.rb +30 -8
  24. data/app/controllers/decidim/proposals/versions_controller.rb +12 -8
  25. data/app/events/decidim/proposals/admin/proposal_assigned_to_evaluator_event.rb +1 -1
  26. data/app/events/decidim/proposals/admin/proposal_note_created_event.rb +1 -1
  27. data/app/forms/decidim/proposals/admin/proposal_form.rb +53 -4
  28. data/app/forms/decidim/proposals/admin/proposals_import_form.rb +2 -0
  29. data/app/forms/decidim/proposals/admin/proposals_merge_form.rb +3 -2
  30. data/app/forms/decidim/proposals/proposal_form.rb +3 -3
  31. data/app/helpers/decidim/proposals/application_helper.rb +25 -39
  32. data/app/jobs/decidim/proposals/admin/import_proposals_job.rb +1 -3
  33. data/app/jobs/decidim/proposals/hide_all_created_by_author_job.rb +0 -3
  34. data/app/models/decidim/proposals/proposal.rb +43 -20
  35. data/app/packs/entrypoints/decidim_proposals_geocoding.js +2 -0
  36. data/app/packs/stylesheets/decidim/proposals/proposals.scss +2 -2
  37. data/app/permissions/decidim/proposals/permissions.rb +1 -58
  38. data/app/views/decidim/proposals/admin/participatory_texts/index.html.erb +1 -1
  39. data/app/views/decidim/proposals/admin/proposal_states/index.html.erb +1 -1
  40. data/app/views/decidim/proposals/admin/proposals/_actions.html.erb +2 -2
  41. data/app/views/decidim/proposals/admin/proposals/_form.html.erb +1 -1
  42. data/app/views/decidim/proposals/admin/proposals/index.html.erb +0 -4
  43. data/app/views/decidim/proposals/admin/proposals/show.html.erb +7 -5
  44. data/app/views/decidim/proposals/admin/proposals_merges/_form.html.erb +1 -1
  45. data/app/views/decidim/proposals/proposal_votes/update_buttons_and_counters.js.erb +1 -1
  46. data/app/views/decidim/proposals/proposals/_edit_form_fields.html.erb +1 -1
  47. data/app/views/decidim/proposals/proposals/_proposal_actions.html.erb +4 -4
  48. data/app/views/decidim/proposals/proposals/_proposal_aside.html.erb +1 -2
  49. data/app/views/decidim/proposals/proposals/_votes_count.html.erb +16 -0
  50. data/app/views/decidim/proposals/proposals/index.html.erb +1 -8
  51. data/app/{cells/decidim/proposals/proposal_votes_count/participatory_texts.erb → views/decidim/proposals/proposals/participatory_texts/_proposal_votes_count.html.erb} +17 -17
  52. data/app/views/decidim/proposals/proposals/show.html.erb +2 -25
  53. data/app/views/decidim/proposals/versions/show.html.erb +0 -5
  54. data/config/locales/ar.yml +11 -105
  55. data/config/locales/bg.yml +11 -105
  56. data/config/locales/bs-BA.yml +0 -1
  57. data/config/locales/ca-IT.yml +22 -115
  58. data/config/locales/ca.yml +19 -115
  59. data/config/locales/cs.yml +11 -114
  60. data/config/locales/de.yml +12 -111
  61. data/config/locales/el.yml +11 -102
  62. data/config/locales/en.yml +11 -106
  63. data/config/locales/es-MX.yml +18 -114
  64. data/config/locales/es-PY.yml +18 -114
  65. data/config/locales/es.yml +18 -114
  66. data/config/locales/eu.yml +34 -130
  67. data/config/locales/fi-plain.yml +17 -113
  68. data/config/locales/fi.yml +17 -113
  69. data/config/locales/fr-CA.yml +18 -114
  70. data/config/locales/fr.yml +18 -114
  71. data/config/locales/ga-IE.yml +0 -33
  72. data/config/locales/gl.yml +10 -93
  73. data/config/locales/he-IL.yml +0 -1
  74. data/config/locales/hu.yml +10 -93
  75. data/config/locales/id-ID.yml +10 -87
  76. data/config/locales/is-IS.yml +1 -26
  77. data/config/locales/it.yml +11 -93
  78. data/config/locales/ja.yml +18 -112
  79. data/config/locales/lb.yml +0 -1
  80. data/config/locales/lt.yml +11 -109
  81. data/config/locales/lv.yml +10 -91
  82. data/config/locales/nl.yml +11 -91
  83. data/config/locales/no.yml +11 -91
  84. data/config/locales/pl.yml +11 -109
  85. data/config/locales/pt-BR.yml +18 -110
  86. data/config/locales/pt.yml +11 -93
  87. data/config/locales/ro-RO.yml +11 -95
  88. data/config/locales/ru.yml +8 -32
  89. data/config/locales/sk.yml +11 -689
  90. data/config/locales/sl.yml +0 -7
  91. data/config/locales/sr-CS.yml +0 -1
  92. data/config/locales/sv.yml +22 -116
  93. data/config/locales/tr-TR.yml +13 -95
  94. data/config/locales/uk.yml +8 -28
  95. data/config/locales/zh-CN.yml +11 -91
  96. data/config/locales/zh-TW.yml +11 -100
  97. data/db/data/20260224210316_remove_collaborative_drafts_references.rb +119 -0
  98. data/db/migrate/20171212102250_enable_pg_trgm_extension_for_proposals.rb +1 -1
  99. data/db/migrate/20200212120110_sync_proposals_state_with_amendments_state.rb +2 -2
  100. data/db/migrate/20200306123652_publish_existing_proposals_state.rb +2 -2
  101. data/db/migrate/20200827154156_add_commentable_counter_cache_to_proposals.rb +12 -4
  102. data/db/migrate/20210310120812_add_followable_counter_cache_to_collaborative_drafts.rb +6 -2
  103. data/db/migrate/20250515132352_drop_collaborative_drafts_tables.rb +12 -0
  104. data/decidim-proposals.gemspec +12 -15
  105. data/lib/decidim/api/mutations/answer_proposal_attributes.rb +2 -2
  106. data/lib/decidim/api/mutations/create_proposal_type.rb +52 -0
  107. data/lib/decidim/api/mutations/proposal_answer_type.rb +7 -15
  108. data/lib/decidim/api/mutations/proposal_attributes.rb +17 -0
  109. data/lib/decidim/api/mutations/proposal_mutation_type.rb +4 -0
  110. data/lib/decidim/api/mutations/proposals_mutation_type.rb +1 -0
  111. data/lib/decidim/api/mutations/unvote_proposal_type.rb +26 -0
  112. data/lib/decidim/api/mutations/update_proposal_type.rb +53 -0
  113. data/lib/decidim/api/mutations/vote_proposal_type.rb +30 -0
  114. data/lib/decidim/api/mutations/withdraw_proposal_type.rb +31 -0
  115. data/lib/decidim/api/proposal_type.rb +0 -2
  116. data/lib/decidim/proposals/api.rb +6 -0
  117. data/lib/decidim/proposals/commentable_proposal.rb +0 -6
  118. data/lib/decidim/proposals/component.rb +16 -13
  119. data/lib/decidim/proposals/engine.rb +0 -14
  120. data/lib/decidim/proposals/seeds.rb +1 -54
  121. data/lib/decidim/proposals/test/factories.rb +3 -63
  122. data/lib/decidim/proposals/version.rb +1 -1
  123. data/lib/decidim/proposals.rb +9 -8
  124. metadata +34 -78
  125. data/app/cells/decidim/proposals/collaborative_draft_cell.rb +0 -49
  126. data/app/cells/decidim/proposals/collaborative_draft_l_cell.rb +0 -16
  127. data/app/cells/decidim/proposals/collaborative_draft_link_to_proposal/show.erb +0 -5
  128. data/app/cells/decidim/proposals/collaborative_draft_link_to_proposal_cell.rb +0 -28
  129. data/app/cells/decidim/proposals/collaborative_draft_metadata_cell.rb +0 -30
  130. data/app/cells/decidim/proposals/collaborative_drafts/reported_content/show.erb +0 -3
  131. data/app/cells/decidim/proposals/collaborative_drafts/reported_content_cell.rb +0 -15
  132. data/app/cells/decidim/proposals/irreversible_action_modal_cell.rb +0 -78
  133. data/app/cells/decidim/proposals/proposal_link_to_collaborative_draft_cell.rb +0 -28
  134. data/app/cells/decidim/proposals/proposal_votes_count/show.erb +0 -12
  135. data/app/cells/decidim/proposals/proposal_votes_count_cell.rb +0 -81
  136. data/app/commands/decidim/proposals/accept_access_to_collaborative_draft.rb +0 -70
  137. data/app/commands/decidim/proposals/create_collaborative_draft.rb +0 -85
  138. data/app/commands/decidim/proposals/publish_collaborative_draft.rb +0 -92
  139. data/app/commands/decidim/proposals/reject_access_to_collaborative_draft.rb +0 -62
  140. data/app/commands/decidim/proposals/request_access_to_collaborative_draft.rb +0 -49
  141. data/app/commands/decidim/proposals/update_collaborative_draft.rb +0 -70
  142. data/app/commands/decidim/proposals/withdraw_collaborative_draft.rb +0 -65
  143. data/app/controllers/decidim/proposals/collaborative_draft_collaborator_requests_controller.rb +0 -53
  144. data/app/controllers/decidim/proposals/collaborative_drafts_controller.rb +0 -152
  145. data/app/events/decidim/proposals/collaborative_draft_access_accepted_event.rb +0 -8
  146. data/app/events/decidim/proposals/collaborative_draft_access_rejected_event.rb +0 -8
  147. data/app/events/decidim/proposals/collaborative_draft_access_request_event.rb +0 -27
  148. data/app/events/decidim/proposals/collaborative_draft_access_requested_event.rb +0 -8
  149. data/app/events/decidim/proposals/collaborative_draft_access_requester_accepted_event.rb +0 -8
  150. data/app/events/decidim/proposals/collaborative_draft_access_requester_rejected_event.rb +0 -8
  151. data/app/events/decidim/proposals/collaborative_draft_withdrawn_event.rb +0 -33
  152. data/app/forms/decidim/proposals/accept_access_to_collaborative_draft_form.rb +0 -10
  153. data/app/forms/decidim/proposals/access_to_collaborative_draft_form.rb +0 -33
  154. data/app/forms/decidim/proposals/collaborative_draft_form.rb +0 -8
  155. data/app/forms/decidim/proposals/reject_access_to_collaborative_draft_form.rb +0 -9
  156. data/app/forms/decidim/proposals/request_access_to_collaborative_draft_form.rb +0 -20
  157. data/app/helpers/decidim/proposals/collaborative_draft_cells_helper.rb +0 -48
  158. data/app/helpers/decidim/proposals/collaborative_draft_helper.rb +0 -69
  159. data/app/models/decidim/proposals/collaborative_draft.rb +0 -79
  160. data/app/models/decidim/proposals/collaborative_draft_collaborator_request.rb +0 -11
  161. data/app/presenters/decidim/proposals/collaborative_draft_presenter.rb +0 -20
  162. data/app/services/decidim/proposals/collaborative_draft_diff_renderer.rb +0 -22
  163. data/app/views/decidim/proposals/collaborative_drafts/_accept_request_access_form.html.erb +0 -8
  164. data/app/views/decidim/proposals/collaborative_drafts/_collaborative_actions.html.erb +0 -9
  165. data/app/views/decidim/proposals/collaborative_drafts/_collaborative_draft_aside.html.erb +0 -38
  166. data/app/views/decidim/proposals/collaborative_drafts/_collaborative_drafts.html.erb +0 -15
  167. data/app/views/decidim/proposals/collaborative_drafts/_collaborator_requests.html.erb +0 -16
  168. data/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb +0 -26
  169. data/app/views/decidim/proposals/collaborative_drafts/_reject_request_access_form.html.erb +0 -8
  170. data/app/views/decidim/proposals/collaborative_drafts/_request_access_form.html.erb +0 -7
  171. data/app/views/decidim/proposals/collaborative_drafts/edit.html.erb +0 -31
  172. data/app/views/decidim/proposals/collaborative_drafts/index.html.erb +0 -35
  173. data/app/views/decidim/proposals/collaborative_drafts/index.js.erb +0 -5
  174. data/app/views/decidim/proposals/collaborative_drafts/new.html.erb +0 -30
  175. data/app/views/decidim/proposals/collaborative_drafts/show.html.erb +0 -74
  176. data/lib/decidim/proposals/commentable_collaborative_draft.rb +0 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f885c60dad4625728a498f01b934fef5e17db6e67c2b32b090f993959600102
4
- data.tar.gz: 5ff2cca8bd53d5f13de93fa1b6d1a6498c968935cfaa1babecb1e7e475d92dce
3
+ metadata.gz: e42a3076ac40dede627a7f03d7aaad459a2b0caf0164c2df9fdcac1aa50101b8
4
+ data.tar.gz: b3648c993a746a2e530fd2ee2bf766392a45a16ebdd56b5f336ffe4fed1116aa
5
5
  SHA512:
6
- metadata.gz: 84932a4f8c33981816817c176b496333be80d48910226140a68b6adf546378a77387b2960a2ff87ca55cd476aa067dd38393899c93b11bbbdf0e612c19720276
7
- data.tar.gz: 56d53ba84ec61b93635566d7436b16e496638ad4cc90727cdf17b66abfcc14640c2042dbd749d804e55ea0f10e957452d6879862764fbcb47dda8398187756fb
6
+ metadata.gz: 8651a09e209979a5eaca293fb56dc5c33eba17bf38393edb10deeddccf82b58fec4ad43eb2c0bf3f466dd7010f24a42c043751044673590140a0b5fe22055b69
7
+ data.tar.gz: cd789df1ac62a3b52d3278e3a55e0cca8bf8375351cf5f6ac5a897f6f0e2582c29780754b738849e8eeb16e37303831762a2678817d251205fe6d5696a72286c
data/README.md CHANGED
@@ -1,24 +1,14 @@
1
- # Decidim::Proposals
1
+ # decidim-proposals
2
2
 
3
- The Proposals module adds one of the main components of Decidim: allows users to contribute to a participatory process by creating proposals.
3
+ The Proposals module adds one of the main components of Decidim: allows users to contribute to a participatory space by creating proposals.
4
4
 
5
5
  ## Usage
6
6
 
7
- Proposals will be available as a Component for a Participatory Process.
7
+ Proposals will be available as a Component for a Participatory Space.
8
8
 
9
9
  ## Installation
10
10
 
11
- Add this line to your application's Gemfile:
12
-
13
- ```ruby
14
- gem 'decidim-proposals'
15
- ```
16
-
17
- And then execute:
18
-
19
- ```bash
20
- bundle
21
- ```
11
+ This is on the default Decidim installation so you should not change anything to use this component.
22
12
 
23
13
  ## Global Search
24
14
 
@@ -1,4 +1,19 @@
1
- <%= cell("decidim/proposals/proposal_votes_count", resource, from_proposals_list:) %>
1
+ <% if !current_settings.votes_hidden? && (current_component.participatory_space.can_participate?(current_user) || current_user&.admin?) %>
2
+ <% if component_settings.participatory_texts_enabled? && from_proposals_list %>
3
+ <%= render partial: "decidim/proposals/proposals/participatory_texts/proposal_votes_count", locals: { proposal: resource, from_proposals_list: true } %>
4
+ <% else %>
5
+ <% progress ||= resource.proposal_votes_count || 0 %>
6
+ <% total ||= resource.maximum_votes || 0 %>
7
+ <%= cell(
8
+ "decidim/progress_bar",
9
+ progress,
10
+ total:,
11
+ units_name: "decidim.proposals.proposals.votes_count.count",
12
+ element_id: "proposal-#{resource.id}-votes-count",
13
+ class: total.positive? ? "card__proposals-votes-limited" : "card__proposals-votes-unlimited"
14
+ ) %>
15
+ <% end %>
16
+ <% end %>
2
17
 
3
18
  <% button_classes = "button button__sm button__secondary w-full" %>
4
19
 
@@ -7,6 +7,7 @@ module Decidim
7
7
  # one component to another.
8
8
  class MergeProposals < Decidim::Command
9
9
  include ::Decidim::MultipleAttachmentsMethods
10
+
10
11
  # Public: Initializes the command.
11
12
  #
12
13
  # form - A form object with the params.
@@ -27,6 +27,7 @@ module Decidim
27
27
  transaction do
28
28
  increment_score
29
29
  notify_followers
30
+ notify_authors
30
31
  end
31
32
  end
32
33
 
@@ -48,11 +49,22 @@ module Decidim
48
49
  event: "decidim.events.proposals.proposal_state_changed",
49
50
  event_class: Decidim::Proposals::ProposalStateChangedEvent,
50
51
  resource: proposal,
51
- affected_users: proposal.notifiable_identities,
52
52
  followers: proposal.followers - proposal.notifiable_identities
53
53
  )
54
54
  end
55
55
 
56
+ def notify_authors
57
+ return if proposal.state == "not_answered"
58
+
59
+ Decidim::EventsManager.publish(
60
+ event: "decidim.events.proposals.proposal_state_changed_for_authors",
61
+ event_class: Decidim::Proposals::ProposalStateChangedEvent,
62
+ resource: proposal,
63
+ affected_users: proposal.authors,
64
+ extra: { force_email: true }
65
+ )
66
+ end
67
+
56
68
  def increment_score
57
69
  if proposal.accepted?
58
70
  proposal.coauthorships.find_each do |coauthorship|
@@ -36,7 +36,7 @@ module Decidim
36
36
  transaction do
37
37
  update_proposal
38
38
  update_proposal_author
39
- attachment_cleanup!(include_all_attachments: true)
39
+ document_cleanup!(include_all_attachments: true)
40
40
  create_attachments(first_weight: first_attachment_weight) if process_attachments?
41
41
  end
42
42
 
@@ -6,6 +6,7 @@ module Decidim
6
6
  # A command with all the business logic when an admin batch updates proposals taxonomies.
7
7
  class UpdateProposalTaxonomies < UpdateResourcesTaxonomies
8
8
  include TranslatableAttributes
9
+
9
10
  # Public: Initializes the command.
10
11
  #
11
12
  # taxonomy_ids - the taxonomy ids to update
@@ -82,7 +82,7 @@ module Decidim
82
82
  )
83
83
 
84
84
  proposal.taxonomizations = form.taxonomizations if form.taxonomizations.present?
85
- proposal.attachments = form.attachments if form.attachments.present?
85
+ proposal.documents = form.documents if form.documents.present?
86
86
  if form.geocoded?
87
87
  proposal.latitude = form.latitude
88
88
  proposal.longitude = form.longitude
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Proposals
5
+ # A module with all the gallery common methods for proposals commands.
6
+ # Allows to create several image attachments at once
7
+ module GalleryMethods
8
+ include ::Decidim::GalleryMethods
9
+
10
+ private
11
+
12
+ def gallery_allowed?
13
+ @form.current_component.settings.attachments_allowed?
14
+ end
15
+ end
16
+ end
17
+ end
@@ -16,7 +16,6 @@ module Decidim
16
16
  # Executes the command. Broadcasts these events:
17
17
  #
18
18
  # - :ok when everything is valid, together with the proposal.
19
- # - :invalid if the form was not valid and we could not proceed.
20
19
  #
21
20
  # Returns nothing.
22
21
  def call
@@ -39,7 +39,7 @@ module Decidim
39
39
  update_proposal
40
40
  end
41
41
 
42
- attachment_cleanup!(include_all_attachments: true)
42
+ document_cleanup!(include_all_attachments: true)
43
43
 
44
44
  create_attachments(first_weight: first_attachment_weight) if process_attachments?
45
45
  end
@@ -32,10 +32,6 @@ module Decidim
32
32
  collection.with_evaluation_assigned_to(current_user, current_participatory_space)
33
33
  end
34
34
 
35
- def search_field_predicate
36
- :id_string_or_title_cont
37
- end
38
-
39
35
  def filter_config
40
36
  @filter_config ||= Decidim::AdminFilter.new(:proposals).build_for(self)
41
37
  end
@@ -22,9 +22,10 @@ module Decidim
22
22
  @possible_orders ||= begin
23
23
  possible_orders = %w(random recent)
24
24
  possible_orders << "most_voted" if most_voted_order_available?
25
- possible_orders << "most_liked" if current_settings.likes_enabled?
26
- possible_orders << "most_commented" if component_settings.comments_enabled?
27
- possible_orders << "most_followed" << "with_more_authors"
25
+ possible_orders << "most_liked" if most_liked_order_available?
26
+ possible_orders << "most_commented" if most_commented_order_available?
27
+ possible_orders << "most_followed" # always shown, as the author automatically follows their proposals
28
+ possible_orders << "with_more_authors" if with_more_authors_order_available?
28
29
  possible_orders
29
30
  end
30
31
  end
@@ -52,6 +53,24 @@ module Decidim
52
53
  current_settings.votes_enabled? && !current_settings.votes_hidden?
53
54
  end
54
55
 
56
+ def with_more_authors_order_available?
57
+ return @with_more_authors_order_available if defined?(@with_more_authors_order_available)
58
+
59
+ @with_more_authors_order_available = Decidim::Proposals::Proposal.with_more_authors_available?(current_component)
60
+ end
61
+
62
+ def most_commented_order_available?
63
+ return @most_commented_order_available if defined?(@most_commented_order_available)
64
+
65
+ @most_commented_order_available = Decidim::Proposals::Proposal.most_commented_available?(current_component)
66
+ end
67
+
68
+ def most_liked_order_available?
69
+ return @most_liked_order_available if defined?(@most_liked_order_available)
70
+
71
+ @most_liked_order_available = Decidim::Proposals::Proposal.most_liked_available?(current_component)
72
+ end
73
+
55
74
  def order_by_votes?
56
75
  most_voted_order_available? && current_settings.votes_blocked?
57
76
  end
@@ -34,12 +34,12 @@ module Decidim
34
34
  Admin::UnassignProposalsFromEvaluator.call(@form) do
35
35
  on(:ok) do |_proposal|
36
36
  flash.keep[:notice] = I18n.t("evaluation_assignments.delete.success", scope: "decidim.proposals.admin")
37
- redirect_back fallback_location: EngineRouter.admin_proxy(current_component).root_path
37
+ redirect_back_or_to(EngineRouter.admin_proxy(current_component).root_path)
38
38
  end
39
39
 
40
40
  on(:invalid) do
41
41
  flash.keep[:alert] = I18n.t("evaluation_assignments.delete.invalid", scope: "decidim.proposals.admin")
42
- redirect_back fallback_location: EngineRouter.admin_proxy(current_component).root_path
42
+ redirect_back_or_to(EngineRouter.admin_proxy(current_component).root_path)
43
43
  end
44
44
  end
45
45
  end
@@ -32,12 +32,12 @@ module Decidim
32
32
 
33
33
  on(:invalid) do
34
34
  flash.now[:alert] = I18n.t("participatory_texts.import.invalid", scope: "decidim.proposals.admin")
35
- render action: "new_import", status: :unprocessable_entity
35
+ render action: "new_import", status: :unprocessable_content
36
36
  end
37
37
 
38
38
  on(:invalid_file) do
39
39
  flash.now[:alert] = I18n.t("participatory_texts.import.invalid_file", scope: "decidim.proposals.admin")
40
- render action: "new_import", status: :unprocessable_entity
40
+ render action: "new_import", status: :unprocessable_content
41
41
  end
42
42
  end
43
43
  end
@@ -62,7 +62,7 @@ module Decidim
62
62
  failures.each_pair { |id, msg| alert_msg << "ID:[#{id}] #{msg}" }
63
63
  flash.now[:alert] = alert_msg.join("<br/>").html_safe
64
64
  index
65
- render action: "index", status: :unprocessable_entity
65
+ render action: "index", status: :unprocessable_content
66
66
  end
67
67
  end
68
68
  else
@@ -77,7 +77,7 @@ module Decidim
77
77
  failures.each_pair { |id, msg| alert_msg << "ID:[#{id}] #{msg}" }
78
78
  flash.now[:alert] = alert_msg.join("<br/>").html_safe
79
79
  index
80
- render action: "index", status: :unprocessable_entity
80
+ render action: "index", status: :unprocessable_content
81
81
  end
82
82
  end
83
83
  end
@@ -34,7 +34,7 @@ module Decidim
34
34
 
35
35
  on(:invalid) do
36
36
  flash.keep[:alert] = I18n.t("proposals.answer.invalid", scope: "decidim.proposals.admin")
37
- render template: "decidim/proposals/admin/proposals/show", status: :unprocessable_entity
37
+ render template: "decidim/proposals/admin/proposals/show", status: :unprocessable_content
38
38
  end
39
39
  end
40
40
  end
@@ -30,7 +30,7 @@ module Decidim
30
30
  on(:invalid) do
31
31
  flash.keep[:alert] = I18n.t("proposal_states.create.error", scope: "decidim.proposals.admin")
32
32
 
33
- render action: :new, status: :unprocessable_entity
33
+ render action: :new, status: :unprocessable_content
34
34
  end
35
35
  end
36
36
  end
@@ -54,7 +54,7 @@ module Decidim
54
54
  on(:invalid) do
55
55
  flash.now[:alert] = I18n.t("proposal_states.update.error", scope: "decidim.proposals.admin")
56
56
 
57
- render action: :edit, status: :unprocessable_entity
57
+ render action: :edit, status: :unprocessable_content
58
58
  end
59
59
  end
60
60
  end
@@ -44,7 +44,7 @@ module Decidim
44
44
 
45
45
  on(:invalid) do
46
46
  flash.now[:alert] = I18n.t("proposals.create.invalid", scope: "decidim.proposals.admin")
47
- render action: "new", status: :unprocessable_entity
47
+ render action: "new", status: :unprocessable_content
48
48
  end
49
49
  end
50
50
  end
@@ -129,7 +129,7 @@ module Decidim
129
129
 
130
130
  on(:invalid) do
131
131
  flash.now[:alert] = t("proposals.update.error", scope: "decidim")
132
- render :edit, status: :unprocessable_entity
132
+ render :edit, status: :unprocessable_content
133
133
  end
134
134
  end
135
135
  end
@@ -23,7 +23,7 @@ module Decidim
23
23
 
24
24
  on(:invalid) do
25
25
  flash.now[:alert] = I18n.t("proposals_imports.create.invalid", scope: "decidim.proposals.admin")
26
- render action: "new", status: :unprocessable_entity
26
+ render action: "new", status: :unprocessable_content
27
27
  end
28
28
  end
29
29
  end
@@ -29,7 +29,7 @@ module Decidim
29
29
  I18n.t("proposals_merges.create.invalid", scope: "decidim.proposals.admin"),
30
30
  @form
31
31
  ).message
32
- render :new, status: :unprocessable_entity
32
+ render :new, status: :unprocessable_content
33
33
  end
34
34
  end
35
35
  end
@@ -53,7 +53,7 @@ module Decidim
53
53
  end
54
54
 
55
55
  on(:invalid) do
56
- render json: { message: I18n.t("update.error", scope: "decidim.proposals.invite_coauthors") }, status: :unprocessable_entity
56
+ render json: { message: I18n.t("update.error", scope: "decidim.proposals.invite_coauthors") }, status: :unprocessable_content
57
57
  end
58
58
  end
59
59
  end
@@ -68,7 +68,7 @@ module Decidim
68
68
  end
69
69
 
70
70
  on(:invalid) do
71
- render json: { message: I18n.t("destroy.error", scope: "decidim.proposals.invite_coauthors") }, status: :unprocessable_entity
71
+ render json: { message: I18n.t("destroy.error", scope: "decidim.proposals.invite_coauthors") }, status: :unprocessable_content
72
72
  end
73
73
  end
74
74
  end
@@ -29,7 +29,7 @@ module Decidim
29
29
  end
30
30
 
31
31
  on(:invalid) do
32
- render json: { error: I18n.t("proposal_votes.create.error", scope: "decidim.proposals") }, status: :unprocessable_entity
32
+ render json: { error: I18n.t("proposal_votes.create.error", scope: "decidim.proposals") }, status: :unprocessable_content
33
33
  end
34
34
  end
35
35
  end
@@ -20,7 +20,7 @@ module Decidim
20
20
 
21
21
  before_action :authenticate_user!, only: [:new, :create]
22
22
  before_action :ensure_is_draft, only: [:preview, :publish, :edit_draft, :update_draft, :destroy_draft]
23
- before_action :set_proposal, only: [:show, :edit, :update, :withdraw]
23
+ before_action :proposal, only: [:show, :edit, :update, :withdraw]
24
24
  before_action :edit_form, only: [:edit_draft, :edit]
25
25
  before_action :set_view_mode, only: [:index]
26
26
 
@@ -79,7 +79,7 @@ module Decidim
79
79
 
80
80
  on(:invalid) do
81
81
  flash.now[:alert] = I18n.t("proposals.create.error", scope: "decidim")
82
- render :new, status: :unprocessable_entity
82
+ render :new, status: :unprocessable_content
83
83
  end
84
84
  end
85
85
  end
@@ -101,7 +101,7 @@ module Decidim
101
101
 
102
102
  on(:invalid) do
103
103
  flash.now[:alert] = I18n.t("proposals.publish.error", scope: "decidim")
104
- render :edit_draft, status: :unprocessable_entity
104
+ render :edit_draft, status: :unprocessable_content
105
105
  end
106
106
  end
107
107
  end
@@ -124,7 +124,7 @@ module Decidim
124
124
 
125
125
  on(:invalid) do
126
126
  flash.now[:alert] = I18n.t("proposals.update_draft.error", scope: "decidim")
127
- render :edit_draft, status: :unprocessable_entity
127
+ render :edit_draft, status: :unprocessable_content
128
128
  end
129
129
  end
130
130
  end
@@ -140,7 +140,7 @@ module Decidim
140
140
 
141
141
  on(:invalid) do
142
142
  flash.now[:alert] = I18n.t("proposals.destroy_draft.error", scope: "decidim")
143
- render :edit_draft, status: :unprocessable_entity
143
+ render :edit_draft, status: :unprocessable_content
144
144
  end
145
145
  end
146
146
  end
@@ -161,7 +161,7 @@ module Decidim
161
161
 
162
162
  on(:invalid) do
163
163
  flash.now[:alert] = I18n.t("proposals.update.error", scope: "decidim")
164
- render :edit, status: :unprocessable_entity
164
+ render :edit, status: :unprocessable_content
165
165
  end
166
166
  end
167
167
  end
@@ -216,8 +216,8 @@ module Decidim
216
216
  redirect_to Decidim::ResourceLocatorPresenter.new(@proposal).path unless @proposal.draft?
217
217
  end
218
218
 
219
- def set_proposal
220
- @proposal = Proposal.published.not_hidden.where(component: current_component).find_by(id: params[:id])
219
+ def proposal
220
+ @proposal ||= Proposal.published.not_hidden.where(component: current_component).find_by(id: params[:id])
221
221
  end
222
222
 
223
223
  # Returns true if the proposal is NOT an emendation or the user IS an admin.
@@ -295,6 +295,28 @@ module Decidim
295
295
  def default_view_mode
296
296
  @default_view_mode ||= current_component.settings.attachments_allowed? ? "grid" : "list"
297
297
  end
298
+
299
+ def add_parent_breadcrumb_item
300
+ return {} if proposal.blank?
301
+
302
+ object = proposal.emendation? ? proposal.amendable : proposal
303
+ {
304
+ label: translated_attribute(object.title),
305
+ url: Decidim::EngineRouter.main_proxy(current_component).proposal_path(object),
306
+ active: false
307
+ }
308
+ end
309
+
310
+ def add_breadcrumb_item
311
+ return {} if proposal.blank?
312
+ return {} if proposal.amendable?
313
+
314
+ {
315
+ label: I18n.t("decidim.amendments.name"),
316
+ url: Decidim::EngineRouter.main_proxy(current_component).proposal_path(proposal),
317
+ active: false
318
+ }
319
+ end
298
320
  end
299
321
  end
300
322
  end
@@ -2,19 +2,23 @@
2
2
 
3
3
  module Decidim
4
4
  module Proposals
5
- # Exposes Proposals versions so users can see how a Proposal/CollaborativeDraft
6
- # has been updated through time.
5
+ # Exposes Proposals versions so users can see how a Proposal has been updated through time.
7
6
  class VersionsController < Decidim::Proposals::ApplicationController
8
7
  include Decidim::ApplicationHelper
9
8
  include Decidim::ResourceVersionsConcern
10
9
 
11
10
  def versioned_resource
12
- @versioned_resource ||=
13
- if params[:proposal_id]
14
- present(Proposal.not_hidden.published.where(component: current_component).find(params[:proposal_id]))
15
- else
16
- CollaborativeDraft.where(component: current_component).find(params[:collaborative_draft_id])
17
- end
11
+ @versioned_resource ||= Proposal.not_hidden.published.where(component: current_component).find(params[:proposal_id])
12
+ end
13
+
14
+ def add_breadcrumb_item
15
+ return {} if versioned_resource.blank?
16
+
17
+ {
18
+ label: translated_attribute(versioned_resource.title),
19
+ url: Decidim::EngineRouter.main_proxy(current_component).proposal_path(versioned_resource),
20
+ active: false
21
+ }
18
22
  end
19
23
  end
20
24
  end
@@ -13,7 +13,7 @@ module Decidim
13
13
  end
14
14
 
15
15
  def admin_proposal_info_url
16
- send(resource.component.mounted_admin_engine).proposal_url(resource, resource.component.mounted_params)
16
+ EngineRouter.admin_proxy(resource.component).proposal_url(resource)
17
17
  end
18
18
 
19
19
  private
@@ -14,7 +14,7 @@ module Decidim
14
14
  end
15
15
 
16
16
  def admin_proposal_info_url
17
- send(resource.component.mounted_admin_engine).proposal_url(resource, resource.component.mounted_params)
17
+ EngineRouter.admin_proxy(resource.component).proposal_url(resource)
18
18
  end
19
19
 
20
20
  private
@@ -14,7 +14,7 @@ module Decidim
14
14
  translatable_attribute :body, Decidim::Attributes::RichText
15
15
  attribute :attachment, AttachmentForm
16
16
 
17
- attachments_attribute :attachments
17
+ attachments_attribute :documents
18
18
 
19
19
  validates :title, :body, translatable_presence: true
20
20
  validates :title, :body, translated_etiquette: true
@@ -27,12 +27,61 @@ module Decidim
27
27
 
28
28
  self.title = presenter.title(all_locales: title.is_a?(Hash))
29
29
  self.body = presenter.editor_body(all_locales: body.is_a?(Hash))
30
- self.attachments = model.attachments.ids
31
- self.add_attachments = model.attachments.map { |att| { id: att.id, title: att.title } }
30
+ self.documents = model.attachments.ids
31
+ self.add_documents = model.attachments.map { |att| { id: att.id, title: att.title } }
32
+ end
33
+
34
+ def documents=(value)
35
+ case value
36
+ when String
37
+ super(parse_string_documents(value))
38
+ when Integer
39
+ super([value])
40
+ else
41
+ super
42
+ end
43
+ end
44
+
45
+ def documents
46
+ result = super
47
+
48
+ if should_use_add_documents?(result)
49
+ extract_ids_from_add_documents
50
+ else
51
+ result.is_a?(Array) ? result : []
52
+ end
32
53
  end
33
54
 
34
55
  def notify_missing_attachment_if_errored
35
- errors.add(:add_attachments, :needs_to_be_reattached) if errors.any? && add_attachments.present?
56
+ errors.add(:add_documents, :needs_to_be_reattached) if errors.any? && add_documents.present?
57
+ end
58
+
59
+ private
60
+
61
+ def should_use_add_documents?(result)
62
+ (result.blank? || result.is_a?(String)) && add_documents.present?
63
+ end
64
+
65
+ def extract_ids_from_add_documents
66
+ add_documents
67
+ .select { |doc| doc.is_a?(Hash) && (doc[:id].present? || doc["id"].present?) }
68
+ .map { |doc| (doc[:id] || doc["id"]).to_i }
69
+ end
70
+
71
+ def parse_string_documents(value)
72
+ return [] if value.blank?
73
+
74
+ parse_document_ids(value)
75
+ end
76
+
77
+ def parse_document_ids(value)
78
+ ids = begin
79
+ Array(JSON.parse(value))
80
+ rescue JSON::ParserError
81
+ value.split(",").map(&:strip)
82
+ end
83
+
84
+ ids.map(&:to_i).reject(&:zero?)
36
85
  end
37
86
  end
38
87
  end
@@ -7,6 +7,7 @@ module Decidim
7
7
  # from another component.
8
8
  class ProposalsImportForm < Decidim::Form
9
9
  include TranslatableAttributes
10
+
10
11
  mimic :proposals_import
11
12
 
12
13
  attribute :origin_component_id, Integer
@@ -15,6 +16,7 @@ module Decidim
15
16
  attribute :states, Array[String]
16
17
 
17
18
  validates :origin_component_id, :origin_component, :current_component, presence: true
19
+ validates :states, presence: true
18
20
  validate :valid_states
19
21
 
20
22
  def states
@@ -8,6 +8,7 @@ module Decidim
8
8
  class ProposalsMergeForm < ProposalBaseForm
9
9
  include Decidim::HasUploadValidations
10
10
  include Decidim::AttachmentAttributes
11
+
11
12
  translatable_attribute :title, String do |field, _locale|
12
13
  validates field, length: { in: 15..150 }, if: proc { |resource| resource.send(field).present? }
13
14
  end
@@ -15,7 +16,7 @@ module Decidim
15
16
  attribute :target_component_id, Array[Integer]
16
17
  attribute :proposal_ids, Array
17
18
 
18
- attachments_attribute :attachments
19
+ attachments_attribute :documents
19
20
 
20
21
  validates :target_component, :proposals, :current_component, presence: true
21
22
  validates :proposal_ids, length: { minimum: 2 }
@@ -61,7 +62,7 @@ module Decidim
61
62
  end
62
63
 
63
64
  def notify_missing_attachment_if_errored
64
- errors.add(:add_attachments, :needs_to_be_reattached) if errors.any? && add_attachments.present?
65
+ errors.add(:add_documents, :needs_to_be_reattached) if errors.any? && add_documents.present?
65
66
  end
66
67
  end
67
68
  end