decidim-proposals 0.30.2 → 0.31.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 (186) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/proposals/collaborative_draft_metadata_cell.rb +1 -1
  3. data/app/cells/decidim/proposals/proposal_g_cell.rb +4 -4
  4. data/app/cells/decidim/proposals/proposal_l_cell.rb +4 -4
  5. data/app/cells/decidim/proposals/proposal_metadata_cell.rb +2 -2
  6. data/app/commands/decidim/proposals/admin/{assign_proposals_to_valuator.rb → assign_proposals_to_evaluator.rb} +16 -16
  7. data/app/commands/decidim/proposals/admin/create_proposal.rb +1 -2
  8. data/app/commands/decidim/proposals/admin/create_proposal_note.rb +4 -4
  9. data/app/commands/decidim/proposals/admin/merge_proposals.rb +60 -13
  10. data/app/commands/decidim/proposals/admin/notify_proposal_answer.rb +2 -2
  11. data/app/commands/decidim/proposals/admin/proposal_notes_methods.rb +5 -5
  12. data/app/commands/decidim/proposals/admin/reply_proposal_note.rb +1 -1
  13. data/app/commands/decidim/proposals/admin/{unassign_proposals_from_valuator.rb → unassign_proposals_from_evaluator.rb} +7 -7
  14. data/app/commands/decidim/proposals/admin/update_proposal.rb +1 -2
  15. data/app/commands/decidim/proposals/create_collaborative_draft.rb +3 -8
  16. data/app/commands/decidim/proposals/create_proposal.rb +4 -17
  17. data/app/commands/decidim/proposals/publish_collaborative_draft.rb +2 -2
  18. data/app/commands/decidim/proposals/publish_proposal.rb +1 -5
  19. data/app/commands/decidim/proposals/update_collaborative_draft.rb +2 -4
  20. data/app/commands/decidim/proposals/update_proposal.rb +5 -18
  21. data/app/controllers/concerns/decidim/proposals/admin/filterable.rb +6 -6
  22. data/app/controllers/concerns/decidim/proposals/orderable.rb +3 -3
  23. data/app/controllers/decidim/proposals/admin/evaluation_assignments_controller.rb +55 -0
  24. data/app/controllers/decidim/proposals/admin/participatory_texts_controller.rb +6 -6
  25. data/app/controllers/decidim/proposals/admin/proposal_answers_controller.rb +1 -1
  26. data/app/controllers/decidim/proposals/admin/proposal_states_controller.rb +2 -2
  27. data/app/controllers/decidim/proposals/admin/proposals_controller.rb +2 -2
  28. data/app/controllers/decidim/proposals/admin/proposals_imports_controller.rb +1 -1
  29. data/app/controllers/decidim/proposals/admin/proposals_merges_controller.rb +12 -3
  30. data/app/controllers/decidim/proposals/collaborative_drafts_controller.rb +2 -3
  31. data/app/controllers/decidim/proposals/proposals_controller.rb +5 -6
  32. data/app/events/decidim/proposals/admin/{proposal_assigned_to_valuator_event.rb → proposal_assigned_to_evaluator_event.rb} +1 -1
  33. data/app/events/decidim/proposals/{endorsing_enabled_event.rb → liking_enabled_event.rb} +1 -1
  34. data/app/events/decidim/proposals/merged_proposal_event.rb +9 -0
  35. data/app/events/decidim/proposals/proposal_liked_event.rb +33 -0
  36. data/app/forms/decidim/proposals/admin/evaluation_assignment_form.rb +38 -0
  37. data/app/forms/decidim/proposals/admin/proposal_base_form.rb +1 -27
  38. data/app/forms/decidim/proposals/admin/proposals_fork_form.rb +1 -1
  39. data/app/forms/decidim/proposals/admin/proposals_merge_form.rb +58 -2
  40. data/app/forms/decidim/proposals/collaborative_draft_form.rb +1 -5
  41. data/app/forms/decidim/proposals/proposal_form.rb +0 -29
  42. data/app/helpers/decidim/proposals/admin/proposal_bulk_actions_helper.rb +8 -8
  43. data/app/helpers/decidim/proposals/admin/proposal_rankings_helper.rb +6 -6
  44. data/app/helpers/decidim/proposals/admin/proposals_helper.rb +2 -17
  45. data/app/helpers/decidim/proposals/application_helper.rb +3 -6
  46. data/app/jobs/decidim/proposals/settings_change_job.rb +6 -6
  47. data/app/models/decidim/proposals/collaborative_draft.rb +1 -1
  48. data/app/models/decidim/proposals/{valuation_assignment.rb → evaluation_assignment.rb} +7 -7
  49. data/app/models/decidim/proposals/proposal.rb +22 -32
  50. data/app/packs/entrypoints/decidim_proposals_admin.js +1 -0
  51. data/app/packs/src/decidim/proposals/add_proposal.js +1 -1
  52. data/app/packs/src/decidim/proposals/admin/proposals.js +22 -11
  53. data/app/packs/src/decidim/proposals/admin/proposals_form.js +1 -1
  54. data/app/packs/src/decidim/proposals/admin/proposals_merge.js +92 -0
  55. data/app/packs/src/decidim/proposals/choose_proposals.js +1 -1
  56. data/app/packs/src/decidim/proposals/exit_handler.js +1 -1
  57. data/app/packs/src/decidim/proposals/utils.js +1 -1
  58. data/app/packs/stylesheets/decidim/proposals/proposals.scss +29 -1
  59. data/app/permissions/decidim/proposals/admin/permissions.rb +20 -20
  60. data/app/presenters/decidim/proposals/admin_log/{valuation_assignment_presenter.rb → evaluation_assignment_presenter.rb} +7 -7
  61. data/app/presenters/decidim/proposals/admin_log/proposal_presenter.rb +15 -0
  62. data/app/presenters/decidim/proposals/admin_log/value_types/{valuator_role_user_presenter.rb → evaluator_role_user_presenter.rb} +2 -2
  63. data/app/presenters/decidim/proposals/admin_log/value_types/proposal_title_body_presenter.rb +1 -1
  64. data/app/presenters/decidim/proposals/collaborative_draft_presenter.rb +1 -6
  65. data/app/presenters/decidim/proposals/log/{valuation_assignment_presenter.rb → evaluation_assignment_presenter.rb} +1 -1
  66. data/app/presenters/decidim/proposals/proposal_presenter.rb +9 -13
  67. data/app/services/decidim/proposals/diff_renderer.rb +0 -1
  68. data/app/services/decidim/proposals/proposal_builder.rb +5 -10
  69. data/app/views/decidim/proposals/admin/participatory_texts/_article-preview.html.erb +1 -1
  70. data/app/views/decidim/proposals/admin/participatory_texts/index.html.erb +1 -2
  71. data/app/views/decidim/proposals/admin/proposal_notes/_form.html.erb +1 -1
  72. data/app/views/decidim/proposals/admin/proposal_notes/_proposal_notes.html.erb +1 -1
  73. data/app/views/decidim/proposals/admin/proposal_states/index.html.erb +42 -12
  74. data/app/views/decidim/proposals/admin/proposals/_actions.html.erb +87 -21
  75. data/app/views/decidim/proposals/admin/proposals/_bulk-actions.html.erb +9 -13
  76. data/app/views/decidim/proposals/admin/proposals/_form.html.erb +2 -24
  77. data/app/views/decidim/proposals/admin/proposals/_likes.html.erb +25 -0
  78. data/app/views/decidim/proposals/admin/proposals/_proposal-tr.html.erb +13 -12
  79. data/app/views/decidim/proposals/admin/proposals/_proposals-thead.html.erb +1 -1
  80. data/app/views/decidim/proposals/admin/proposals/bulk_actions/_assign_to_evaluator.html.erb +19 -0
  81. data/app/views/decidim/proposals/admin/proposals/bulk_actions/_dropdown.html.erb +45 -49
  82. data/app/views/decidim/proposals/admin/proposals/bulk_actions/{_valuators_picker.html.erb → _evaluators_picker.html.erb} +4 -4
  83. data/app/views/decidim/proposals/admin/proposals/bulk_actions/_merge.html.erb +7 -14
  84. data/app/views/decidim/proposals/admin/proposals/bulk_actions/_unassign_from_evaluator.html.erb +19 -0
  85. data/app/views/decidim/proposals/admin/proposals/index.html.erb +9 -5
  86. data/app/views/decidim/proposals/admin/proposals/manage_trash.html.erb +2 -1
  87. data/app/views/decidim/proposals/admin/proposals/show.html.erb +17 -17
  88. data/app/views/decidim/proposals/admin/proposals_merges/_form.html.erb +49 -0
  89. data/app/views/decidim/proposals/admin/proposals_merges/new.html.erb +14 -0
  90. data/app/views/decidim/proposals/collaborative_drafts/_collaborative_actions.html.erb +2 -2
  91. data/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb +1 -21
  92. data/app/views/decidim/proposals/collaborative_drafts/show.html.erb +1 -1
  93. data/app/views/decidim/proposals/proposals/_actions.html.erb +2 -2
  94. data/app/views/decidim/proposals/proposals/_edit_form_fields.html.erb +1 -21
  95. data/app/views/decidim/proposals/proposals/_proposal_actions.html.erb +4 -4
  96. data/app/views/decidim/proposals/proposals/_proposal_aside.html.erb +2 -2
  97. data/app/views/decidim/proposals/proposals/_proposal_voting_rules.html.erb +1 -1
  98. data/app/views/decidim/proposals/proposals/participatory_texts/_view_index.html.erb +1 -1
  99. data/app/views/decidim/proposals/proposals/preview.html.erb +1 -1
  100. data/app/views/decidim/proposals/proposals/show.html.erb +2 -2
  101. data/config/assets.rb +2 -2
  102. data/config/locales/ar.yml +0 -65
  103. data/config/locales/bg.yml +0 -71
  104. data/config/locales/bs-BA.yml +0 -25
  105. data/config/locales/ca-IT.yml +64 -72
  106. data/config/locales/ca.yml +64 -72
  107. data/config/locales/cs.yml +52 -81
  108. data/config/locales/de.yml +66 -73
  109. data/config/locales/el.yml +0 -66
  110. data/config/locales/en.yml +69 -77
  111. data/config/locales/es-MX.yml +68 -76
  112. data/config/locales/es-PY.yml +68 -76
  113. data/config/locales/es.yml +68 -76
  114. data/config/locales/eu.yml +66 -74
  115. data/config/locales/fi-plain.yml +67 -75
  116. data/config/locales/fi.yml +67 -75
  117. data/config/locales/fr-CA.yml +49 -74
  118. data/config/locales/fr.yml +49 -74
  119. data/config/locales/ga-IE.yml +0 -22
  120. data/config/locales/gl.yml +0 -47
  121. data/config/locales/hu.yml +0 -64
  122. data/config/locales/id-ID.yml +0 -34
  123. data/config/locales/is-IS.yml +0 -14
  124. data/config/locales/it.yml +0 -58
  125. data/config/locales/ja.yml +68 -76
  126. data/config/locales/lb.yml +0 -3
  127. data/config/locales/lt.yml +0 -68
  128. data/config/locales/lv.yml +0 -62
  129. data/config/locales/nl.yml +0 -63
  130. data/config/locales/no.yml +0 -42
  131. data/config/locales/pl.yml +0 -73
  132. data/config/locales/pt-BR.yml +0 -59
  133. data/config/locales/pt.yml +0 -60
  134. data/config/locales/ro-RO.yml +45 -64
  135. data/config/locales/ru.yml +0 -15
  136. data/config/locales/sk.yml +0 -60
  137. data/config/locales/sr-CS.yml +0 -25
  138. data/config/locales/sv.yml +58 -76
  139. data/config/locales/tr-TR.yml +0 -58
  140. data/config/locales/uk.yml +0 -15
  141. data/config/locales/zh-CN.yml +0 -57
  142. data/config/locales/zh-TW.yml +0 -65
  143. data/db/migrate/20240110203500_add_withdrawn_at_field_to_proposals.rb +1 -1
  144. data/db/migrate/20240110203504_create_default_proposal_states.rb +1 -1
  145. data/db/migrate/20250121110014_rename_proposal_valuation_assignments_to_evaluation_assignments.rb +15 -0
  146. data/db/migrate/20250121110904_rename_valuation_assignments_count_to_evaluation_assignments_count.rb +16 -0
  147. data/db/migrate/20250211141313_rename_valuator_columns.rb +8 -0
  148. data/db/migrate/20250515132351_rename_proposals_endorsements_count_to_likes.rb +7 -0
  149. data/decidim-proposals.gemspec +1 -1
  150. data/lib/decidim/api/mutations/answer_proposal_attributes.rb +17 -0
  151. data/lib/decidim/api/mutations/proposal_answer_type.rb +57 -0
  152. data/lib/decidim/api/mutations/proposal_mutation_type.rb +14 -0
  153. data/lib/decidim/api/mutations/proposals_mutation_type.rb +23 -0
  154. data/lib/decidim/api/proposal_input_sort.rb +1 -1
  155. data/lib/decidim/api/proposal_state_type.rb +16 -0
  156. data/lib/decidim/api/proposal_type.rb +59 -9
  157. data/lib/decidim/proposals/admin_engine.rb +3 -3
  158. data/lib/decidim/proposals/admin_filter.rb +3 -3
  159. data/lib/decidim/proposals/api.rb +5 -0
  160. data/lib/decidim/proposals/component.rb +44 -24
  161. data/lib/decidim/proposals/engine.rb +18 -83
  162. data/lib/decidim/proposals/evaluable.rb +22 -0
  163. data/lib/decidim/proposals/import/proposal_creator.rb +1 -1
  164. data/lib/decidim/proposals/proposal_serializer.rb +9 -11
  165. data/lib/decidim/proposals/seeds.rb +16 -27
  166. data/lib/decidim/proposals/test/factories.rb +21 -53
  167. data/lib/decidim/proposals/version.rb +1 -1
  168. data/lib/decidim/proposals.rb +3 -3
  169. data/lib/tasks/proposals/upgrade/decidim_proposals_upgrade_tasks.rake +11 -11
  170. metadata +57 -47
  171. data/app/commands/decidim/proposals/hashtags_methods.rb +0 -36
  172. data/app/controllers/decidim/proposals/admin/valuation_assignments_controller.rb +0 -55
  173. data/app/events/decidim/proposals/proposal_endorsed_event.rb +0 -33
  174. data/app/forms/decidim/proposals/admin/proposals_file_import_form.rb +0 -31
  175. data/app/forms/decidim/proposals/admin/valuation_assignment_form.rb +0 -38
  176. data/app/queries/decidim/proposals/metrics/accepted_proposals_metric_manage.rb +0 -32
  177. data/app/queries/decidim/proposals/metrics/endorsements_metric_manage.rb +0 -58
  178. data/app/queries/decidim/proposals/metrics/proposal_followers_metric_measure.rb +0 -58
  179. data/app/queries/decidim/proposals/metrics/proposal_participants_metric_measure.rb +0 -74
  180. data/app/queries/decidim/proposals/metrics/proposals_metric_manage.rb +0 -48
  181. data/app/queries/decidim/proposals/metrics/votes_metric_manage.rb +0 -52
  182. data/app/views/decidim/proposals/admin/imports/_proposals_fields.html.erb +0 -11
  183. data/app/views/decidim/proposals/admin/proposals/_endorsers.html.erb +0 -25
  184. data/app/views/decidim/proposals/admin/proposals/bulk_actions/_assign_to_valuator.html.erb +0 -19
  185. data/app/views/decidim/proposals/admin/proposals/bulk_actions/_unassign_from_valuator.html.erb +0 -19
  186. data/lib/decidim/proposals/valuatable.rb +0 -22
@@ -22,7 +22,7 @@ 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_endorsed" if current_settings.endorsements_enabled?
25
+ possible_orders << "most_liked" if current_settings.likes_enabled?
26
26
  possible_orders << "most_commented" if component_settings.comments_enabled?
27
27
  possible_orders << "most_followed" << "with_more_authors"
28
28
  possible_orders
@@ -60,8 +60,8 @@ module Decidim
60
60
  case order
61
61
  when "most_commented"
62
62
  proposals.order(comments_count: :desc)
63
- when "most_endorsed"
64
- proposals.order(endorsements_count: :desc)
63
+ when "most_liked"
64
+ proposals.order(likes_count: :desc)
65
65
  when "most_followed"
66
66
  proposals.order(follows_count: :desc)
67
67
  when "most_voted"
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Proposals
5
+ module Admin
6
+ class EvaluationAssignmentsController < Admin::ApplicationController
7
+ def create
8
+ @form = form(Admin::EvaluationAssignmentForm).from_params(params)
9
+
10
+ @form.proposals.each do |proposal|
11
+ enforce_permission_to :assign_to_evaluator, :proposals, proposal:
12
+ end
13
+
14
+ Admin::AssignProposalsToEvaluator.call(@form) do
15
+ on(:ok) do |_proposal|
16
+ flash[:notice] = I18n.t("evaluation_assignments.create.success", scope: "decidim.proposals.admin")
17
+ redirect_to EngineRouter.admin_proxy(current_component).root_path
18
+ end
19
+
20
+ on(:invalid) do
21
+ flash.now[:alert] = I18n.t("evaluation_assignments.create.invalid", scope: "decidim.proposals.admin")
22
+ redirect_to EngineRouter.admin_proxy(current_component).root_path
23
+ end
24
+ end
25
+ end
26
+
27
+ def destroy
28
+ @form = form(Admin::EvaluationAssignmentForm).from_params(params)
29
+
30
+ @form.evaluator_roles.each do |evaluator_role|
31
+ enforce_permission_to :unassign_from_evaluator, :proposals, evaluator: evaluator_role.user
32
+ end
33
+
34
+ Admin::UnassignProposalsFromEvaluator.call(@form) do
35
+ on(:ok) do |_proposal|
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
38
+ end
39
+
40
+ on(:invalid) do
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
43
+ end
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def skip_manage_component_permission
50
+ true
51
+ end
52
+ end
53
+ end
54
+ end
55
+ 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"
35
+ render action: "new_import", status: :unprocessable_entity
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"
40
+ render action: "new_import", status: :unprocessable_entity
41
41
  end
42
42
  end
43
43
  end
@@ -47,8 +47,8 @@ module Decidim
47
47
  def update
48
48
  enforce_permission_to :manage, :participatory_texts
49
49
 
50
- form_params = params.require(:preview_participatory_text)
51
- @preview_form = form(Admin::PreviewParticipatoryTextForm).from_params(proposals: form_params[:proposals_attributes]&.values)
50
+ form_params = params.require(:preview_participatory_text).fetch(:proposals_attributes).to_unsafe_h
51
+ @preview_form = form(Admin::PreviewParticipatoryTextForm).from_params(proposals: form_params)
52
52
 
53
53
  if params.has_key?("save_draft")
54
54
  UpdateParticipatoryText.call(@preview_form) do
@@ -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"
65
+ render action: "index", status: :unprocessable_entity
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"
80
+ render action: "index", status: :unprocessable_entity
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"
37
+ render template: "decidim/proposals/admin/proposals/show", status: :unprocessable_entity
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
33
+ render action: :new, status: :unprocessable_entity
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
57
+ render action: :edit, status: :unprocessable_entity
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"
47
+ render action: "new", status: :unprocessable_entity
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
132
+ render :edit, status: :unprocessable_entity
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"
26
+ render action: "new", status: :unprocessable_entity
27
27
  end
28
28
  end
29
29
  end
@@ -4,6 +4,15 @@ module Decidim
4
4
  module Proposals
5
5
  module Admin
6
6
  class ProposalsMergesController < Admin::ApplicationController
7
+ layout false
8
+ helper Decidim::Proposals::Admin::ProposalsHelper
9
+
10
+ def new
11
+ @form = form(Admin::ProposalsMergeForm).from_params(
12
+ params.merge(attachment: form(AttachmentForm).from_params({}))
13
+ )
14
+ end
15
+
7
16
  def create
8
17
  enforce_permission_to :merge, :proposals
9
18
 
@@ -12,15 +21,15 @@ module Decidim
12
21
  Admin::MergeProposals.call(@form) do
13
22
  on(:ok) do |_proposal|
14
23
  flash[:notice] = I18n.t("proposals_merges.create.success", scope: "decidim.proposals.admin")
15
- redirect_to EngineRouter.admin_proxy(@form.target_component).root_path
24
+ render json: { redirect_url: EngineRouter.admin_proxy(@form.target_component).root_path }, status: :ok
16
25
  end
17
26
 
18
27
  on(:invalid) do
19
- flash[:alert_html] = Decidim::ValidationErrorsPresenter.new(
28
+ flash.now[:alert_html] = Decidim::ValidationErrorsPresenter.new(
20
29
  I18n.t("proposals_merges.create.invalid", scope: "decidim.proposals.admin"),
21
30
  @form
22
31
  ).message
23
- redirect_to EngineRouter.admin_proxy(current_component).root_path
32
+ render :new, status: :unprocessable_entity
24
33
  end
25
34
  end
26
35
  end
@@ -6,7 +6,6 @@ module Decidim
6
6
  class CollaborativeDraftsController < Decidim::Proposals::ApplicationController
7
7
  helper ProposalWizardHelper
8
8
  helper TooltipHelper
9
- helper UserGroupHelper
10
9
 
11
10
  include Decidim::ApplicationHelper
12
11
  include Decidim::IconHelper
@@ -62,7 +61,7 @@ module Decidim
62
61
 
63
62
  on(:invalid) do
64
63
  flash.now[:alert] = I18n.t("proposals.collaborative_drafts.create.error", scope: "decidim")
65
- render :new
64
+ render :new, status: :unprocessable_entity
66
65
  end
67
66
  end
68
67
  end
@@ -86,7 +85,7 @@ module Decidim
86
85
 
87
86
  on(:invalid) do
88
87
  flash.now[:alert] = I18n.t("proposals.collaborative_drafts.update.error", scope: "decidim")
89
- render :edit
88
+ render :edit, status: :unprocessable_entity
90
89
  end
91
90
  end
92
91
  end
@@ -6,7 +6,6 @@ module Decidim
6
6
  class ProposalsController < Decidim::Proposals::ApplicationController
7
7
  helper ProposalWizardHelper
8
8
  helper ParticipatoryTextsHelper
9
- helper UserGroupHelper
10
9
  helper Decidim::Admin::IconLinkHelper
11
10
  include Decidim::ApplicationHelper
12
11
  include Flaggable
@@ -80,7 +79,7 @@ module Decidim
80
79
 
81
80
  on(:invalid) do
82
81
  flash.now[:alert] = I18n.t("proposals.create.error", scope: "decidim")
83
- render :new
82
+ render :new, status: :unprocessable_entity
84
83
  end
85
84
  end
86
85
  end
@@ -102,7 +101,7 @@ module Decidim
102
101
 
103
102
  on(:invalid) do
104
103
  flash.now[:alert] = I18n.t("proposals.publish.error", scope: "decidim")
105
- render :edit_draft
104
+ render :edit_draft, status: :unprocessable_entity
106
105
  end
107
106
  end
108
107
  end
@@ -125,7 +124,7 @@ module Decidim
125
124
 
126
125
  on(:invalid) do
127
126
  flash.now[:alert] = I18n.t("proposals.update_draft.error", scope: "decidim")
128
- render :edit_draft
127
+ render :edit_draft, status: :unprocessable_entity
129
128
  end
130
129
  end
131
130
  end
@@ -141,7 +140,7 @@ module Decidim
141
140
 
142
141
  on(:invalid) do
143
142
  flash.now[:alert] = I18n.t("proposals.destroy_draft.error", scope: "decidim")
144
- render :edit_draft
143
+ render :edit_draft, status: :unprocessable_entity
145
144
  end
146
145
  end
147
146
  end
@@ -162,7 +161,7 @@ module Decidim
162
161
 
163
162
  on(:invalid) do
164
163
  flash.now[:alert] = I18n.t("proposals.update.error", scope: "decidim")
165
- render :edit
164
+ render :edit, status: :unprocessable_entity
166
165
  end
167
166
  end
168
167
  end
@@ -3,7 +3,7 @@
3
3
  module Decidim
4
4
  module Proposals
5
5
  module Admin
6
- class ProposalAssignedToValuatorEvent < Decidim::Events::SimpleEvent
6
+ class ProposalAssignedToEvaluatorEvent < Decidim::Events::SimpleEvent
7
7
  include Rails.application.routes.mounted_helpers
8
8
 
9
9
  i18n_attributes :admin_proposal_info_url, :admin_proposal_info_path
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Decidim
4
4
  module Proposals
5
- class EndorsingEnabledEvent < Decidim::Events::SimpleEvent
5
+ class LikingEnabledEvent < Decidim::Events::SimpleEvent
6
6
  end
7
7
  end
8
8
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Proposals
5
+ class MergedProposalEvent < Decidim::Events::SimpleEvent
6
+ include Decidim::Events::AuthorEvent
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Proposals
5
+ class ProposalLikedEvent < Decidim::Events::SimpleEvent
6
+ i18n_attributes :liker_nickname, :liker_name, :liker_path, :nickname
7
+
8
+ delegate :nickname, :name, to: :liker, prefix: true
9
+
10
+ def nickname
11
+ liker_nickname
12
+ end
13
+
14
+ def liker_path
15
+ liker.profile_path
16
+ end
17
+
18
+ def resource_text
19
+ resource.body
20
+ end
21
+
22
+ private
23
+
24
+ def liker
25
+ @liker ||= Decidim::UserPresenter.new(liker_user)
26
+ end
27
+
28
+ def liker_user
29
+ @liker_user ||= Decidim::User.find_by(id: extra[:liker_id])
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Proposals
5
+ module Admin
6
+ class EvaluationAssignmentForm < Decidim::Form
7
+ attribute :id, Integer
8
+ attribute :proposal_ids, Array
9
+ attribute :evaluator_role_ids, Array
10
+
11
+ validates :evaluator_roles, :proposals, :current_component, presence: true
12
+ validate :same_participatory_space
13
+
14
+ def proposals
15
+ @proposals ||= Decidim::Proposals::Proposal.where(component: current_component, id: proposal_ids).uniq
16
+ end
17
+
18
+ def evaluator_roles
19
+ @evaluator_roles ||= current_component.participatory_space
20
+ .user_roles(:evaluator)
21
+ .order_by_name
22
+ .where(id: evaluator_role_ids)
23
+ end
24
+
25
+ def same_participatory_space
26
+ return if evaluator_roles.empty? || !current_component
27
+
28
+ evaluator_roles.each do |evaluator_role|
29
+ if current_component.participatory_space != evaluator_role.participatory_space
30
+ errors.add(:id, :invalid)
31
+ break
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -19,7 +19,6 @@ module Decidim
19
19
  attribute :position, Integer
20
20
  attribute :created_in_meeting, Boolean
21
21
  attribute :meeting_id, Integer
22
- attribute :suggested_hashtags, Array[String]
23
22
 
24
23
  attachments_attribute :photos
25
24
 
@@ -30,7 +29,7 @@ module Decidim
30
29
 
31
30
  def map_model(model)
32
31
  body = translated_attribute(model.body)
33
- @suggested_hashtags = Decidim::ContentRenderers::HashtagRenderer.new(body).extra_hashtags.map(&:name).map(&:downcase)
32
+ Decidim::ContentRenderers::BlobRenderer.new(body)
34
33
  end
35
34
 
36
35
  alias component current_component
@@ -68,27 +67,6 @@ module Decidim
68
67
  meeting_as_author
69
68
  end
70
69
 
71
- def extra_hashtags
72
- @extra_hashtags ||= (component_automatic_hashtags + suggested_hashtags).uniq
73
- end
74
-
75
- def suggested_hashtags
76
- downcased_suggested_hashtags = super.to_set(&:downcase)
77
- component_suggested_hashtags.select { |hashtag| downcased_suggested_hashtags.member?(hashtag.downcase) }
78
- end
79
-
80
- def suggested_hashtag_checked?(hashtag)
81
- suggested_hashtags.member?(hashtag)
82
- end
83
-
84
- def component_automatic_hashtags
85
- @component_automatic_hashtags ||= ordered_hashtag_list(current_component.current_settings.automatic_hashtags)
86
- end
87
-
88
- def component_suggested_hashtags
89
- @component_suggested_hashtags ||= ordered_hashtag_list(current_component.current_settings.suggested_hashtags)
90
- end
91
-
92
70
  private
93
71
 
94
72
  # This method will add an error to the `attachment` field only if there is
@@ -99,10 +77,6 @@ module Decidim
99
77
  errors.add(:attachment, :needs_to_be_reattached) if errors.any? && attachment.present?
100
78
  errors.add(:add_photos, :needs_to_be_reattached) if errors.any? && add_photos.present?
101
79
  end
102
-
103
- def ordered_hashtag_list(string)
104
- string.to_s.split.compact_blank.uniq.sort_by(&:parameterize)
105
- end
106
80
  end
107
81
  end
108
82
  end
@@ -39,7 +39,7 @@ module Decidim
39
39
 
40
40
  proposals.each do |proposal|
41
41
  errors_set << :not_official unless proposal.official?
42
- errors_set << :voted if proposal.votes.any? || proposal.endorsements.any?
42
+ errors_set << :voted if proposal.votes.any? || proposal.likes.any?
43
43
  end
44
44
 
45
45
  errors_set.each { |error| errors.add(:base, error) } if errors_set.any?
@@ -5,8 +5,64 @@ module Decidim
5
5
  module Admin
6
6
  # A form object to be used when admin users wants to merge two or more
7
7
  # proposals into a new one to another proposal component in the same space.
8
- class ProposalsMergeForm < ProposalsForkForm
9
- validates :proposals, length: { minimum: 2 }
8
+ class ProposalsMergeForm < ProposalBaseForm
9
+ include Decidim::HasUploadValidations
10
+ include Decidim::AttachmentAttributes
11
+ translatable_attribute :title, String do |field, _locale|
12
+ validates field, length: { in: 15..150 }, if: proc { |resource| resource.send(field).present? }
13
+ end
14
+ translatable_attribute :body, Decidim::Attributes::RichText
15
+ attribute :target_component_id, Array[Integer]
16
+ attribute :proposal_ids, Array
17
+
18
+ attachments_attribute :documents
19
+
20
+ validates :target_component, :proposals, :current_component, presence: true
21
+ validates :proposal_ids, length: { minimum: 2 }
22
+ validates :title, :body, translatable_presence: true
23
+ validate :mergeable_to_same_component
24
+ validate :notify_missing_attachment_if_errored
25
+
26
+ def proposals
27
+ @proposals ||= Decidim::Proposals::Proposal.where(component: current_component, id: proposal_ids).uniq
28
+ end
29
+
30
+ def target_component
31
+ return current_component if clean_target_component_id == current_component.id
32
+
33
+ @target_component ||= current_component.siblings.find_by(id: target_component_id)
34
+ end
35
+
36
+ def same_component?
37
+ target_component == current_component
38
+ end
39
+
40
+ private
41
+
42
+ def errors_set
43
+ @errors_set ||= Set[]
44
+ end
45
+
46
+ def mergeable_to_same_component
47
+ return true unless same_component?
48
+
49
+ proposals.each do |proposal|
50
+ errors_set << :voted if proposal.votes.any?
51
+ end
52
+
53
+ errors_set.each { |error| errors.add(:base, error) } if errors_set.any?
54
+ end
55
+
56
+ # Private: Returns the id of the target component.
57
+ #
58
+ # We receive this as ["id"] since it is from a select in a form.
59
+ def clean_target_component_id
60
+ target_component_id.first
61
+ end
62
+
63
+ def notify_missing_attachment_if_errored
64
+ errors.add(:add_documents, :needs_to_be_reattached) if errors.any? && add_documents.present?
65
+ end
10
66
  end
11
67
  end
12
68
  end
@@ -3,10 +3,6 @@
3
3
  module Decidim
4
4
  module Proposals
5
5
  # A form object to be used when public users want to create a Collaborative Draft.
6
- class CollaborativeDraftForm < Decidim::Proposals::ProposalForm
7
- def user_group
8
- @user_group ||= Decidim::UserGroup.find user_group_id if user_group_id.present?
9
- end
10
- end
6
+ class CollaborativeDraftForm < Decidim::Proposals::ProposalForm; end
11
7
  end
12
8
  end
@@ -14,12 +14,10 @@ module Decidim
14
14
  attribute :title, String
15
15
  attribute :body, Decidim::Attributes::CleanString
16
16
  attribute :body_template, String
17
- attribute :user_group_id, Integer
18
17
  attribute :address, String
19
18
  attribute :latitude, Float
20
19
  attribute :longitude, Float
21
20
  attribute :attachment, AttachmentForm
22
- attribute :suggested_hashtags, Array[String]
23
21
 
24
22
  attachments_attribute :documents
25
23
 
@@ -40,12 +38,10 @@ module Decidim
40
38
  def map_model(model)
41
39
  self.title = translated_attribute(model.title)
42
40
  self.body = translated_attribute(model.body)
43
- @suggested_hashtags = Decidim::ContentRenderers::HashtagRenderer.new(body).extra_hashtags.map(&:name).map(&:downcase)
44
41
 
45
42
  presenter = ProposalPresenter.new(model)
46
43
  self.body = presenter.editor_body(all_locales: body.is_a?(Hash))
47
44
 
48
- self.user_group_id = model.user_groups.first&.id
49
45
  self.documents = model.attachments
50
46
  end
51
47
 
@@ -65,27 +61,6 @@ module Decidim
65
61
  latitude.present? && longitude.present?
66
62
  end
67
63
 
68
- def extra_hashtags
69
- @extra_hashtags ||= (component_automatic_hashtags + suggested_hashtags).uniq
70
- end
71
-
72
- def suggested_hashtags
73
- downcased_suggested_hashtags = super.to_set(&:downcase)
74
- component_suggested_hashtags.select { |hashtag| downcased_suggested_hashtags.member?(hashtag.downcase) }
75
- end
76
-
77
- def suggested_hashtag_checked?(hashtag)
78
- suggested_hashtags.member?(hashtag)
79
- end
80
-
81
- def component_automatic_hashtags
82
- @component_automatic_hashtags ||= ordered_hashtag_list(current_component.current_settings.automatic_hashtags)
83
- end
84
-
85
- def component_suggested_hashtags
86
- @component_suggested_hashtags ||= ordered_hashtag_list(current_component.current_settings.suggested_hashtags)
87
- end
88
-
89
64
  private
90
65
 
91
66
  def body_is_not_bare_template
@@ -100,10 +75,6 @@ module Decidim
100
75
  def notify_missing_attachment_if_errored
101
76
  errors.add(:add_documents, :needs_to_be_reattached) if errors.any? && add_documents.present?
102
77
  end
103
-
104
- def ordered_hashtag_list(string)
105
- string.to_s.split.compact_blank.uniq.sort_by(&:parameterize)
106
- end
107
78
  end
108
79
  end
109
80
  end
@@ -33,19 +33,19 @@ module Decidim
33
33
  end
34
34
  end
35
35
 
36
- # find the valuators for the current space.
37
- def find_valuators_for_select(participatory_space, current_user)
38
- valuator_roles = participatory_space.user_roles(:valuator).order_by_name
39
- valuators = Decidim::User.where(id: valuator_roles.pluck(:decidim_user_id)).to_a
36
+ # find the evaluators for the current space.
37
+ def find_evaluators_for_select(participatory_space, current_user)
38
+ evaluator_roles = participatory_space.user_roles(:evaluator).order_by_name
39
+ evaluators = Decidim::User.where(id: evaluator_roles.pluck(:decidim_user_id)).to_a
40
40
 
41
- filtered_valuator_roles = valuator_roles.filter do |role|
41
+ filtered_evaluator_roles = evaluator_roles.filter do |role|
42
42
  role.decidim_user_id != current_user.id
43
43
  end
44
44
 
45
- filtered_valuator_roles.map do |role|
46
- valuator = valuators.find { |user| user.id == role.decidim_user_id }
45
+ filtered_evaluator_roles.map do |role|
46
+ evaluator = evaluators.find { |user| user.id == role.decidim_user_id }
47
47
 
48
- [valuator.name, role.id]
48
+ [evaluator.name, role.id]
49
49
  end
50
50
  end
51
51
  end
@@ -17,7 +17,7 @@ module Decidim
17
17
  #
18
18
  # Examples:
19
19
  # ranking_for(proposal, proposal_votes_count: :desc)
20
- # ranking_for(proposal, endorsements_count: :desc)
20
+ # ranking_for(proposal, likes_count: :desc)
21
21
  def ranking_for(proposal, order = {})
22
22
  siblings = Decidim::Proposals::Proposal.where(component: proposal.component)
23
23
  ranked = siblings.order([order, { id: :asc }])
@@ -26,9 +26,9 @@ module Decidim
26
26
  { ranking: ranked_ids.index(proposal.id) + 1, total: ranked_ids.count }
27
27
  end
28
28
 
29
- # Public: Gets the ranking for a given proposal, ordered by endorsements.
30
- def endorsements_ranking_for(proposal)
31
- ranking_for(proposal, endorsements_count: :desc)
29
+ # Public: Gets the ranking for a given proposal, ordered by likes.
30
+ def likes_ranking_for(proposal)
31
+ ranking_for(proposal, likes_count: :desc)
32
32
  end
33
33
 
34
34
  # Public: Gets the ranking for a given proposal, ordered by votes.
@@ -36,8 +36,8 @@ module Decidim
36
36
  ranking_for(proposal, proposal_votes_count: :desc)
37
37
  end
38
38
 
39
- def i18n_endorsements_ranking_for(proposal)
40
- rankings = endorsements_ranking_for(proposal)
39
+ def i18n_likes_ranking_for(proposal)
40
+ rankings = likes_ranking_for(proposal)
41
41
 
42
42
  I18n.t(
43
43
  "ranking",