decidim-proposals 0.11.2 → 0.12.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/proposals/endorsers_list/show.erb +18 -0
  3. data/app/cells/decidim/proposals/endorsers_list_cell.rb +30 -0
  4. data/app/cells/decidim/proposals/proposal_cell.rb +55 -0
  5. data/app/cells/decidim/proposals/proposal_m/footer.erb +23 -0
  6. data/app/cells/decidim/proposals/proposal_m/tags.erb +1 -0
  7. data/app/cells/decidim/proposals/proposal_m_cell.rb +74 -0
  8. data/app/cells/decidim/proposals/proposal_tags/show.erb +25 -0
  9. data/app/cells/decidim/proposals/proposal_tags_cell.rb +30 -0
  10. data/app/controllers/decidim/proposals/admin/proposal_answers_controller.rb +2 -2
  11. data/app/controllers/decidim/proposals/admin/proposal_notes_controller.rb +2 -2
  12. data/app/controllers/decidim/proposals/admin/proposals_controller.rb +3 -3
  13. data/app/controllers/decidim/proposals/admin/proposals_imports_controller.rb +2 -4
  14. data/app/controllers/decidim/proposals/application_controller.rb +0 -3
  15. data/app/controllers/decidim/proposals/proposal_endorsements_controller.rb +3 -3
  16. data/app/controllers/decidim/proposals/proposal_votes_controller.rb +2 -2
  17. data/app/controllers/decidim/proposals/proposals_controller.rb +11 -10
  18. data/app/forms/decidim/proposals/admin/proposal_form.rb +10 -0
  19. data/app/forms/decidim/proposals/proposal_form.rb +10 -0
  20. data/app/helpers/decidim/proposals/application_helper.rb +1 -24
  21. data/app/helpers/decidim/proposals/proposal_cells_helper.rb +67 -0
  22. data/app/helpers/decidim/proposals/proposal_votes_helper.rb +1 -1
  23. data/app/models/decidim/proposals/proposal.rb +22 -2
  24. data/app/permissions/decidim/proposals/admin/permissions.rb +52 -0
  25. data/app/permissions/decidim/proposals/permissions.rb +108 -0
  26. data/app/services/decidim/proposals/proposal_search.rb +2 -0
  27. data/app/types/decidim/proposals/proposal_type.rb +5 -5
  28. data/app/views/decidim/participatory_processes/participatory_process_groups/_proposal.html.erb +1 -27
  29. data/app/views/decidim/participatory_spaces/_proposal.html.erb +1 -27
  30. data/app/views/decidim/proposals/admin/proposal_notes/_proposal_notes.html.erb +1 -1
  31. data/app/views/decidim/proposals/admin/proposals/_bulk-actions.html.erb +3 -3
  32. data/app/views/decidim/proposals/admin/proposals/_proposal-tr.html.erb +3 -3
  33. data/app/views/decidim/proposals/admin/proposals/index.html.erb +1 -1
  34. data/app/views/decidim/proposals/proposal_endorsements/_identity.html.erb +2 -1
  35. data/app/views/decidim/proposals/proposal_widgets/show.html.erb +1 -1
  36. data/app/views/decidim/proposals/proposals/_endorsements_card_row.html.erb +2 -2
  37. data/app/views/decidim/proposals/proposals/_filters.html.erb +1 -1
  38. data/app/views/decidim/proposals/proposals/_linked_proposals.html.erb +7 -6
  39. data/app/views/decidim/proposals/proposals/_proposal.html.erb +1 -32
  40. data/app/views/decidim/proposals/proposals/_proposal_preview.html.erb +1 -36
  41. data/app/views/decidim/proposals/proposals/_proposal_similar.html.erb +6 -5
  42. data/app/views/decidim/proposals/proposals/_vote_button.html.erb +28 -10
  43. data/app/views/decidim/proposals/proposals/_votes_count.html.erb +14 -28
  44. data/app/views/decidim/proposals/proposals/complete.html.erb +10 -3
  45. data/app/views/decidim/proposals/proposals/index.html.erb +1 -1
  46. data/app/views/decidim/proposals/proposals/show.html.erb +7 -21
  47. data/config/locales/ca.yml +43 -15
  48. data/config/locales/en.yml +43 -15
  49. data/config/locales/es.yml +42 -14
  50. data/config/locales/eu.yml +42 -14
  51. data/config/locales/fi.yml +42 -14
  52. data/config/locales/fr.yml +42 -14
  53. data/config/locales/gl.yml +42 -14
  54. data/config/locales/it.yml +42 -14
  55. data/config/locales/nl.yml +42 -14
  56. data/config/locales/pl.yml +52 -14
  57. data/config/locales/pt-BR.yml +42 -14
  58. data/config/locales/pt.yml +42 -14
  59. data/config/locales/ru.yml +49 -17
  60. data/config/locales/sv.yml +42 -14
  61. data/config/locales/uk.yml +53 -15
  62. data/db/migrate/{20171212102250_enable_pg_extensions.rb → 20171212102250_enable_pg_trgm_extension_for_proposals.rb} +1 -1
  63. data/db/migrate/20180516131201_index_proposals_as_searchable_resources.rb +24 -0
  64. data/lib/decidim/proposals/admin_engine.rb +0 -10
  65. data/lib/decidim/proposals/component.rb +4 -1
  66. data/lib/decidim/proposals/engine.rb +8 -6
  67. data/lib/decidim/proposals/test/factories.rb +1 -0
  68. data/lib/decidim/proposals/version.rb +1 -1
  69. data/lib/decidim/proposals.rb +1 -0
  70. metadata +61 -28
  71. data/app/models/decidim/proposals/abilities/admin_ability.rb +0 -42
  72. data/app/models/decidim/proposals/abilities/current_user_ability.rb +0 -113
  73. data/app/models/decidim/proposals/abilities/participatory_process_admin_ability.rb +0 -48
  74. data/app/models/decidim/proposals/abilities/participatory_process_moderator_ability.rb +0 -19
  75. data/app/views/decidim/proposals/proposals/_identities_listing.html.erb +0 -30
  76. data/app/views/decidim/proposals/proposals/_identity_xxs.html.erb +0 -8
  77. data/app/views/decidim/proposals/proposals/_tags.html.erb +0 -25
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7b361dc23139798e9d1f00b815ba258bf49aa42a73a187ed9da26a205390cdb
4
- data.tar.gz: f6091d108a9d62789c6e5dd33955045a8be80845d8d0ba130c3f4ff0c67f67d5
3
+ metadata.gz: 2384c4b531953a2fd808d55b6d7fbc1fc4af2a4cd2a0f8c0935cd3358201870a
4
+ data.tar.gz: 83edd0b0d7ee83bc2ae14aef758bb4ab4380342cfc82b32bd7039ecbf5330491
5
5
  SHA512:
6
- metadata.gz: 62db09b1966e92b7cef62c4eec399cbdb37e118c8d90cf3e8501e397f578370f1974354e15e3fef61112b441001625835c3e2f8103d4f6848a9a3feece180d31
7
- data.tar.gz: fb3966a8c2f435b7e99cd549fab55100e4434282be51c207492af7b2ff62eadd6897167b92043c0625228e2d88489caa392928a0c0ada16e7c9b6cb97e945c44
6
+ metadata.gz: eb153981a26cdf7530da2420db8092e2916b851b65edd01a25c2125dd8f70026a2650dd1137e24841378a6c030932347f80250c15511cee79513f1429000383b
7
+ data.tar.gz: 83f36e6351ae01cf77748bf9bbabf842b1383954836a968f52655c6bdeb1328d59fc748616f28a8ad9b25a150bd05735fc13914a94bc2902b80e36cbfd1d7bdd
@@ -0,0 +1,18 @@
1
+ <div class="section">
2
+ <a name="list-of-endorsements"></a>
3
+ <div class="row">
4
+ <div class="columns large-12">
5
+ <h4 class="section-heading"><%= t("decidim.proposals.proposals.show.endorsements_list") %></h4>
6
+ </div>
7
+ <div class="columns large-12">
8
+ <%= cell(
9
+ "decidim/collapsible_list",
10
+ endorsers,
11
+ cell_name: "decidim/author",
12
+ cell_options: { extra_classes: ["author-data--small"] },
13
+ hidden_elements_count_i18n_key: "decidim.proposals.proposals.show.hidden_endorsers_count",
14
+ size: :small
15
+ ) %>
16
+ </div>
17
+ </div>
18
+ </div>
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cell/partial"
4
+
5
+ module Decidim
6
+ module Proposals
7
+ # This cell renders the list of endorsers for the given Proposal.
8
+ #
9
+ # Example:
10
+ #
11
+ # cell("decidim/proposals/endorsers_list", my_proposal)
12
+ class EndorsersListCell < Decidim::ViewModel
13
+ include ProposalCellsHelper
14
+
15
+ def show
16
+ return unless endorsers.any?
17
+ render
18
+ end
19
+
20
+ private
21
+
22
+ # Finds the correct author for each endorsement.
23
+ #
24
+ # Returns an Array of presented Users/UserGroups
25
+ def endorsers
26
+ @endorsers ||= model.endorsements.for_listing.map { |identity| present(identity.normalized_author) }
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cell/partial"
4
+
5
+ module Decidim
6
+ module Proposals
7
+ # This cell renders the proposal card for an instance of a Proposal
8
+ # the default size is the Medium Card (:m)
9
+ class ProposalCell < Decidim::ViewModel
10
+ include ProposalCellsHelper
11
+ include Cell::ViewModel::Partial
12
+ include Messaging::ConversationHelper
13
+
14
+ delegate :user_signed_in?, to: :parent_controller
15
+
16
+ def show
17
+ cell card_size, model, @options
18
+ end
19
+
20
+ private
21
+
22
+ def current_user
23
+ context[:current_user]
24
+ end
25
+
26
+ def card_size
27
+ "decidim/proposals/proposal_m"
28
+ end
29
+
30
+ def resource_path
31
+ resource_locator(model).path
32
+ end
33
+
34
+ def current_participatory_space
35
+ model.component.participatory_space
36
+ end
37
+
38
+ def component_name
39
+ translated_attribute current_component.name
40
+ end
41
+
42
+ def component_type_name
43
+ model.class.model_name.human
44
+ end
45
+
46
+ def participatory_space_name
47
+ translated_attribute current_participatory_space.title
48
+ end
49
+
50
+ def participatory_space_type_name
51
+ translated_attribute current_participatory_space.model_name.human
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,23 @@
1
+ <% if has_link_to_resource? %>
2
+ <div class="card__footer">
3
+ <div class="card__support">
4
+ <% if actionable? %>
5
+ <% if !current_settings.votes_hidden? %>
6
+ <%= cell(
7
+ "decidim/progress_bar",
8
+ progress_bar_progress,
9
+ total: progress_bar_total,
10
+ units_name: "decidim.proposals.proposals.votes_count.count",
11
+ element_id: "proposal-#{model.id}-votes-count",
12
+ subtitle_text: progress_bar_subtitle_text,
13
+ small: true
14
+ ) %>
15
+ <% end %>
16
+ <%= render partial: "decidim/proposals/proposals/vote_button.html", locals: { proposal: model, from_proposals_list: true } %>
17
+ <% else %>
18
+ <div class="card__support__data"></div>
19
+ <%= link_to t("decidim.proposals.proposals.proposal.view_proposal"), resource_path, class: "card__button button--sc light button small secondary" %>
20
+ <% end %>
21
+ </div>
22
+ </div>
23
+ <% end %>
@@ -0,0 +1 @@
1
+ <%= render partial: "decidim/shared/tags.html", locals: { resource: model, tags_class_extra: "tags--proposal" } %>
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cell/partial"
4
+
5
+ module Decidim
6
+ module Proposals
7
+ # This cell renders a proposal with its M-size card.
8
+ class ProposalMCell < Decidim::CardMCell
9
+ include ProposalCellsHelper
10
+
11
+ def badge
12
+ render if has_badge?
13
+ end
14
+
15
+ private
16
+
17
+ def has_state?
18
+ model.published?
19
+ end
20
+
21
+ def has_badge?
22
+ answered? || withdrawn?
23
+ end
24
+
25
+ def has_link_to_resource?
26
+ model.published?
27
+ end
28
+
29
+ def description
30
+ truncate(model.body, length: 100)
31
+ end
32
+
33
+ def badge_classes
34
+ return super unless options[:full_badge]
35
+ state_classes.concat(["label", "proposal-status"]).join(" ")
36
+ end
37
+
38
+ def statuses
39
+ return [:creation_date, :endorsements_count, :comments_count] unless has_link_to_resource?
40
+ [:creation_date, :follow, :endorsements_count, :comments_count]
41
+ end
42
+
43
+ def endorsements_count_status
44
+ return endorsements_count unless has_link_to_resource?
45
+
46
+ link_to resource_path do
47
+ endorsements_count
48
+ end
49
+ end
50
+
51
+ def endorsements_count
52
+ with_tooltip t("decidim.proposals.models.proposal.fields.endorsements") do
53
+ icon("bullhorn", class: "icon--small") + " " + model.proposal_endorsements_count.to_s
54
+ end
55
+ end
56
+
57
+ def progress_bar_progress
58
+ model.proposal_votes_count || 0
59
+ end
60
+
61
+ def progress_bar_total
62
+ model.maximum_votes || 0
63
+ end
64
+
65
+ def progress_bar_subtitle_text
66
+ if progress_bar_progress >= progress_bar_total
67
+ t("decidim.proposals.proposals.votes_count.most_popular_proposal")
68
+ else
69
+ t("decidim.proposals.proposals.votes_count.need_more_votes")
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,25 @@
1
+ <figure>
2
+ <figcaption class="text-uppercase">
3
+ <strong>
4
+ <%= t("filed_as", scope: "decidim.proposals.proposals.tags") %>
5
+ </strong>
6
+ </figcaption>
7
+
8
+ <ul>
9
+ <% if category.present? %>
10
+ <li>
11
+ <%= link_to translated_attribute(category.name), resource_locator(model).index(filter: { category_id: category.id }) %>
12
+ <% if previous_category.present? && show_previous_category? %>
13
+ &nbsp;
14
+ <small class="text-small">
15
+ <%= t("changed_from", scope: "decidim.proposals.proposals.tags", previous_category: "#{previous_category.translated_name}").html_safe %>
16
+ </small>
17
+ <% end %>
18
+ </li>
19
+ <% end %>
20
+
21
+ <% if has_visible_scopes?(model) %>
22
+ <li><%= link_to translated_attribute(scope.name), resource_locator(model).index(filter: { scope_id: [scope.id] }) %></li>
23
+ <% end %>
24
+ </ul>
25
+ </figure>
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "cell/partial"
4
+
5
+ module Decidim
6
+ module Proposals
7
+ # This cell renders the tags for a proposal.
8
+ class ProposalTagsCell < Decidim::ViewModel
9
+ include ProposalCellsHelper
10
+
11
+ property :category
12
+ property :previous_category
13
+ property :scope
14
+
15
+ def show
16
+ render if has_category_or_scopes?
17
+ end
18
+
19
+ private
20
+
21
+ def show_previous_category?
22
+ options[:show_previous_category].to_s != "false"
23
+ end
24
+
25
+ def has_category_or_scopes?
26
+ category.present? || has_visible_scopes?(model)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -8,12 +8,12 @@ module Decidim
8
8
  helper_method :proposal
9
9
 
10
10
  def edit
11
- authorize! :update, proposal
11
+ enforce_permission_to :create, :proposal_answer
12
12
  @form = form(Admin::ProposalAnswerForm).from_model(proposal)
13
13
  end
14
14
 
15
15
  def update
16
- authorize! :update, proposal
16
+ enforce_permission_to :create, :proposal_answer
17
17
  @form = form(Admin::ProposalAnswerForm).from_params(params)
18
18
 
19
19
  Admin::AnswerProposal.call(@form, proposal) do
@@ -8,12 +8,12 @@ module Decidim
8
8
  helper_method :proposal
9
9
 
10
10
  def index
11
- authorize! :create, ProposalNote
11
+ enforce_permission_to :create, :proposal_note
12
12
  @form = form(ProposalNoteForm).instance
13
13
  end
14
14
 
15
15
  def create
16
- authorize! :create, ProposalNote
16
+ enforce_permission_to :create, :proposal_note
17
17
  @form = form(ProposalNoteForm).from_params(params)
18
18
 
19
19
  CreateProposalNote.call(@form, proposal) do
@@ -9,14 +9,14 @@ module Decidim
9
9
  helper_method :proposals, :query
10
10
 
11
11
  def new
12
- authorize! :create, Proposal
12
+ enforce_permission_to :create, :proposal
13
13
  @form = form(Admin::ProposalForm).from_params(
14
14
  attachment: form(AttachmentForm).from_params({})
15
15
  )
16
16
  end
17
17
 
18
18
  def create
19
- authorize! :create, Proposal
19
+ enforce_permission_to :create, :proposal
20
20
  @form = form(Admin::ProposalForm).from_params(params)
21
21
 
22
22
  Admin::CreateProposal.call(@form) do
@@ -33,7 +33,7 @@ module Decidim
33
33
  end
34
34
 
35
35
  def update_category
36
- authorize! :update, Proposal
36
+ enforce_permission_to :update, :proposal_category
37
37
  @proposal_ids = params[:proposal_ids]
38
38
 
39
39
  Admin::UpdateProposalCategory.call(params[:category][:id], params[:proposal_ids]) do
@@ -5,18 +5,16 @@ module Decidim
5
5
  module Admin
6
6
  class ProposalsImportsController < Admin::ApplicationController
7
7
  def new
8
- authorize! :manage, current_component
8
+ enforce_permission_to :import, :proposals
9
9
 
10
10
  @form = form(Admin::ProposalsImportForm).instance
11
11
  end
12
12
 
13
13
  def create
14
- authorize! :manage, current_component
14
+ enforce_permission_to :import, :proposals
15
15
 
16
16
  @form = form(Admin::ProposalsImportForm).from_params(params)
17
17
 
18
- authorize! :manage, @form.origin_component
19
-
20
18
  Admin::ImportProposals.call(@form) do
21
19
  on(:ok) do |proposals|
22
20
  flash[:notice] = I18n.t("proposals_imports.create.success", scope: "decidim.proposals.admin", number: proposals.length)
@@ -9,11 +9,8 @@ module Decidim
9
9
  # override its layout and provide all kinds of useful methods.
10
10
  class ApplicationController < Decidim::Components::BaseController
11
11
  helper Decidim::Messaging::ConversationHelper
12
-
13
12
  helper_method :proposal_limit_reached?
14
13
 
15
- private
16
-
17
14
  def proposal_limit
18
15
  return nil if component_settings.proposal_limit.zero?
19
16
  component_settings.proposal_limit
@@ -9,7 +9,7 @@ module Decidim
9
9
  before_action :authenticate_user!
10
10
 
11
11
  def create
12
- authorize! :endorse, proposal
12
+ enforce_permission_to :endorse, :proposal, proposal: proposal
13
13
  @from_proposals_list = params[:from_proposals_list] == "true"
14
14
  user_group_id = params[:user_group_id]
15
15
 
@@ -26,7 +26,7 @@ module Decidim
26
26
  end
27
27
 
28
28
  def destroy
29
- authorize! :unendorse, proposal
29
+ enforce_permission_to :unendorse, :proposal, proposal: proposal
30
30
  @from_proposals_list = params[:from_proposals_list] == "true"
31
31
  user_group_id = params[:user_group_id]
32
32
  user_group = current_user.user_groups.verified.find(user_group_id) if user_group_id
@@ -40,7 +40,7 @@ module Decidim
40
40
  end
41
41
 
42
42
  def identities
43
- authorize! :endorse, proposal
43
+ enforce_permission_to :endorse, :proposal, proposal: proposal
44
44
 
45
45
  @user_verified_groups = current_user.user_groups.verified
46
46
  render :identities, layout: false
@@ -11,7 +11,7 @@ module Decidim
11
11
  before_action :authenticate_user!
12
12
 
13
13
  def create
14
- authorize! :vote, proposal
14
+ enforce_permission_to :vote, :proposal, proposal: proposal
15
15
  @from_proposals_list = params[:from_proposals_list] == "true"
16
16
 
17
17
  VoteProposal.call(proposal, current_user) do
@@ -27,7 +27,7 @@ module Decidim
27
27
  end
28
28
 
29
29
  def destroy
30
- authorize! :unvote, proposal
30
+ enforce_permission_to :unvote, :proposal, proposal: proposal
31
31
  @from_proposals_list = params[:from_proposals_list] == "true"
32
32
 
33
33
  UnvoteProposal.call(proposal, current_user) do
@@ -43,7 +43,7 @@ module Decidim
43
43
  end
44
44
 
45
45
  def new
46
- authorize! :create, Proposal
46
+ enforce_permission_to :create, :proposal
47
47
  @step = :step_1
48
48
  if proposal_draft.present?
49
49
  redirect_to edit_draft_proposal_path(proposal_draft, component_id: proposal_draft.component.id, question_slug: proposal_draft.component.participatory_space.slug)
@@ -53,7 +53,7 @@ module Decidim
53
53
  end
54
54
 
55
55
  def create
56
- authorize! :create, Proposal
56
+ enforce_permission_to :create, :proposal
57
57
  @step = :step_3
58
58
  @form = form(ProposalForm).from_params(params)
59
59
 
@@ -85,8 +85,9 @@ module Decidim
85
85
  end
86
86
 
87
87
  def complete
88
- authorize! :create, Proposal
88
+ enforce_permission_to :create, :proposal
89
89
  @step = :step_3
90
+
90
91
  if params[:proposal].present?
91
92
  params[:proposal][:attachment] = form(AttachmentForm).from_params({})
92
93
  @form = form(ProposalForm).from_params(params)
@@ -118,14 +119,14 @@ module Decidim
118
119
 
119
120
  def edit_draft
120
121
  @step = :step_3
121
- authorize! :edit, Proposal
122
+ enforce_permission_to :edit, :proposal, proposal: @proposal
122
123
 
123
124
  @form = form(ProposalForm).from_model(@proposal)
124
125
  end
125
126
 
126
127
  def update_draft
127
128
  @step = :step_1
128
- authorize! :edit, @proposal
129
+ enforce_permission_to :edit, :proposal, proposal: @proposal
129
130
 
130
131
  @form = form(ProposalForm).from_params(params)
131
132
  UpdateProposal.call(@form, current_user, @proposal) do
@@ -142,7 +143,7 @@ module Decidim
142
143
  end
143
144
 
144
145
  def destroy_draft
145
- authorize! :edit, Proposal
146
+ enforce_permission_to :edit, :proposal, proposal: @proposal
146
147
 
147
148
  DestroyProposal.call(@proposal, current_user) do
148
149
  on(:ok) do
@@ -159,14 +160,14 @@ module Decidim
159
160
 
160
161
  def edit
161
162
  @proposal = Proposal.published.not_hidden.where(component: current_component).find(params[:id])
162
- authorize! :edit, @proposal
163
+ enforce_permission_to :edit, :proposal, proposal: @proposal
163
164
 
164
165
  @form = form(ProposalForm).from_model(@proposal)
165
166
  end
166
167
 
167
168
  def update
168
169
  @proposal = Proposal.not_hidden.where(component: current_component).find(params[:id])
169
- authorize! :edit, @proposal
170
+ enforce_permission_to :edit, :proposal, proposal: @proposal
170
171
 
171
172
  @form = form(ProposalForm).from_params(params)
172
173
  UpdateProposal.call(@form, current_user, @proposal) do
@@ -184,7 +185,7 @@ module Decidim
184
185
 
185
186
  def withdraw
186
187
  @proposal = Proposal.published.not_hidden.where(component: current_component).find(params[:id])
187
- authorize! :withdraw, @proposal
188
+ enforce_permission_to :withdraw, :proposal, proposal: @proposal
188
189
 
189
190
  WithdrawProposal.call(@proposal, current_user) do
190
191
  on(:ok) do |_proposal|
@@ -214,7 +215,7 @@ module Decidim
214
215
  origin: "all",
215
216
  activity: "",
216
217
  category_id: "",
217
- state: "not_withdrawn",
218
+ state: "except_rejected",
218
219
  scope_id: nil,
219
220
  related_to: ""
220
221
  }
@@ -23,6 +23,8 @@ module Decidim
23
23
 
24
24
  validate :scope_belongs_to_participatory_space_scope
25
25
 
26
+ validate :notify_missing_attachment_if_errored
27
+
26
28
  delegate :categories, to: :current_component
27
29
 
28
30
  def map_model(model)
@@ -59,6 +61,14 @@ module Decidim
59
61
  def scope_belongs_to_participatory_space_scope
60
62
  errors.add(:scope_id, :invalid) if current_participatory_space.out_of_scope?(scope)
61
63
  end
64
+
65
+ # This method will add an error to the `attachment` field only if there's
66
+ # any error in any other field. This is needed because when the form has
67
+ # an error, the attachment is lost, so we need a way to inform the user of
68
+ # this problem.
69
+ def notify_missing_attachment_if_errored
70
+ errors.add(:attachment, :needs_to_be_reattached) if errors.any? && attachment.present?
71
+ end
62
72
  end
63
73
  end
64
74
  end
@@ -26,6 +26,8 @@ module Decidim
26
26
  validate :proposal_length
27
27
  validate :scope_belongs_to_participatory_space_scope
28
28
 
29
+ validate :notify_missing_attachment_if_errored
30
+
29
31
  delegate :categories, to: :current_component
30
32
 
31
33
  def map_model(model)
@@ -72,6 +74,14 @@ module Decidim
72
74
  def scope_belongs_to_participatory_space_scope
73
75
  errors.add(:scope_id, :invalid) if current_participatory_space.out_of_scope?(scope)
74
76
  end
77
+
78
+ # This method will add an error to the `attachment` field only if there's
79
+ # any error in any other field. This is needed because when the form has
80
+ # an error, the attachment is lost, so we need a way to inform the user of
81
+ # this problem.
82
+ def notify_missing_attachment_if_errored
83
+ errors.add(:attachment, :needs_to_be_reattached) if errors.any? && attachment.present?
84
+ end
75
85
  end
76
86
  end
77
87
  end
@@ -74,7 +74,7 @@ module Decidim
74
74
 
75
75
  def follow_button_for(model)
76
76
  if current_user
77
- render partial: "decidim/shared/follow_button", locals: { followable: model }
77
+ render partial: "decidim/shared/follow_button.html", locals: { followable: model }
78
78
  else
79
79
  content_tag(:p, class: "mt-s mb-none") do
80
80
  t("decidim.proposals.proposals.show.sign_in_or_up",
@@ -83,29 +83,6 @@ module Decidim
83
83
  end
84
84
  end
85
85
  end
86
-
87
- # Public - A widget that lists all identities in an xxs card format.
88
- # Shows the first 5 identities and hides the rest, but presents a 'see all'
89
- # button to make the rest of identities visible.
90
- #
91
- # @param identities: The list of identities. Each item must have a user_group or author method.
92
- # @param widget_id: Mandatory when placing more than 1 widget in a page, optional otherwise. Is the id
93
- # uniquely identify this widget in the page.
94
- #
95
- def identities_list_xxs(identities, widget_id = "identities-xxs")
96
- widget_ids = {
97
- ellipsis: "#{widget_id}-ellipsis",
98
- remaining_identities: "#{widget_id}-remaining-identities",
99
- see_all_identities: "#{widget_id}-see-all-identities"
100
- }
101
- render partial: "identities_listing", locals: { identities: identities, widget_ids: widget_ids }
102
- end
103
-
104
- def identities_xxs(identities)
105
- identities.collect do |identity|
106
- render partial: "identity_xxs", locals: { identity: identity.normalized_author }
107
- end.join(", ").html_safe
108
- end
109
86
  end
110
87
  end
111
88
  end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Proposals
5
+ # Custom helpers, scoped to the proposals engine.
6
+ #
7
+ module ProposalCellsHelper
8
+ include Decidim::Proposals::ApplicationHelper
9
+ include Decidim::Proposals::Engine.routes.url_helpers
10
+ include Decidim::LayoutHelper
11
+ include Decidim::ApplicationHelper
12
+ include Decidim::TranslationsHelper
13
+ include Decidim::ResourceReferenceHelper
14
+ include Decidim::TranslatableAttributes
15
+ include Decidim::CardHelper
16
+
17
+ delegate :title, :state, :answered?, :withdrawn?, to: :model
18
+
19
+ def actionable?
20
+ proposals_controller? && index_action? && current_settings.votes_enabled? && !model.draft?
21
+ end
22
+
23
+ def proposals_controller?
24
+ context[:controller].class.to_s == "Decidim::Proposals::ProposalsController"
25
+ end
26
+
27
+ def index_action?
28
+ context[:controller].action_name == "index"
29
+ end
30
+
31
+ def current_settings
32
+ model.component.current_settings
33
+ end
34
+
35
+ def component_settings
36
+ model.component.settings
37
+ end
38
+
39
+ def current_component
40
+ model.component
41
+ end
42
+
43
+ def from_context
44
+ @options[:from]
45
+ end
46
+
47
+ def badge_name
48
+ humanize_proposal_state state
49
+ end
50
+
51
+ def state_classes
52
+ case state
53
+ when "accepted"
54
+ ["success"]
55
+ when "rejected"
56
+ ["alert"]
57
+ when "evaluating"
58
+ ["warning"]
59
+ when "withdrawn"
60
+ ["alert"]
61
+ else
62
+ ["muted"]
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -20,7 +20,7 @@ module Decidim
20
20
  #
21
21
  # Returns a string with the value of the css classes.
22
22
  def vote_button_classes(from_proposals_list)
23
- return "small" if from_proposals_list
23
+ return "card__button button--sc" if from_proposals_list
24
24
  "expanded button--sc"
25
25
  end
26
26