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
@@ -14,8 +14,12 @@ module Decidim
14
14
  include Decidim::HasAttachments
15
15
  include Decidim::Followable
16
16
  include Decidim::Proposals::CommentableProposal
17
+ include Decidim::Searchable
17
18
  include Decidim::Traceable
18
19
  include Decidim::Loggable
20
+ include Decidim::Fingerprintable
21
+
22
+ fingerprint fields: [:title, :body]
19
23
 
20
24
  component_manifest_name "proposals"
21
25
 
@@ -31,13 +35,22 @@ module Decidim
31
35
  scope :rejected, -> { where(state: "rejected") }
32
36
  scope :evaluating, -> { where(state: "evaluating") }
33
37
  scope :withdrawn, -> { where(state: "withdrawn") }
38
+ scope :except_rejected, -> { where.not(state: "rejected").or(where(state: nil)) }
34
39
  scope :except_withdrawn, -> { where.not(state: "withdrawn").or(where(state: nil)) }
35
40
  scope :published, -> { where.not(published_at: nil) }
36
41
 
42
+ searchable_fields(
43
+ scope_id: :decidim_scope_id,
44
+ participatory_space: { component: :participatory_space },
45
+ A: :title,
46
+ D: :body,
47
+ datetime: :published_at
48
+ )
49
+
37
50
  def self.order_randomly(seed)
38
51
  transaction do
39
52
  connection.execute("SELECT setseed(#{connection.quote(seed)})")
40
- order("RANDOM()").load
53
+ order(Arel.sql("RANDOM()")).load
41
54
  end
42
55
  end
43
56
 
@@ -60,11 +73,18 @@ module Decidim
60
73
  endorsements.where(author: user, user_group: user_group).any?
61
74
  end
62
75
 
76
+ # Public: Checks if the proposal has been published or not.
77
+ #
78
+ # Returns Boolean.
79
+ def published?
80
+ published_at.present?
81
+ end
82
+
63
83
  # Public: Checks if the organization has given an answer for the proposal.
64
84
  #
65
85
  # Returns Boolean.
66
86
  def answered?
67
- answered_at.present?
87
+ answered_at.present? && state.present?
68
88
  end
69
89
 
70
90
  # Public: Checks if the organization has accepted a proposal.
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Proposals
5
+ module Admin
6
+ class Permissions < Decidim::DefaultPermissions
7
+ def permissions
8
+ # The public part needs to be implemented yet
9
+ return permission_action if permission_action.scope != :admin
10
+
11
+ if create_permission_action?
12
+ # There's no special condition to create proposal notes, only
13
+ # users with access to the admin section can do it.
14
+ allow! if permission_action.subject == :proposal_note
15
+
16
+ # Proposals can only be created from the admin when the
17
+ # corresponding setting is enabled.
18
+ toggle_allow(admin_creation_is_enabled?) if permission_action.subject == :proposal
19
+
20
+ # Proposals can only be answered from the admin when the
21
+ # corresponding setting is enabled.
22
+ toggle_allow(admin_proposal_answering_is_enabled?) if permission_action.subject == :proposal_answer
23
+ end
24
+
25
+ # Every user allowed by the space can update the category of the proposal
26
+ allow! if permission_action.subject == :proposal_category && permission_action.action == :update
27
+
28
+ # Every user allowed by the space can import proposals from another_component
29
+ allow! if permission_action.subject == :proposals && permission_action.action == :import
30
+
31
+ permission_action
32
+ end
33
+
34
+ private
35
+
36
+ def admin_creation_is_enabled?
37
+ current_settings.try(:creation_enabled?) &&
38
+ component_settings.try(:official_proposals_enabled)
39
+ end
40
+
41
+ def admin_proposal_answering_is_enabled?
42
+ current_settings.try(:proposal_answering_enabled) &&
43
+ component_settings.try(:proposal_answering_enabled)
44
+ end
45
+
46
+ def create_permission_action?
47
+ permission_action.action == :create
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Proposals
5
+ class Permissions < Decidim::DefaultPermissions
6
+ def permissions
7
+ return permission_action unless user
8
+
9
+ # Delegate the admin permission checks to the admin permissions class
10
+ return Decidim::Proposals::Admin::Permissions.new(user, permission_action, context).permissions if permission_action.scope == :admin
11
+ return permission_action if permission_action.scope != :public
12
+
13
+ return permission_action if permission_action.subject != :proposal
14
+
15
+ case permission_action.action
16
+ when :create
17
+ can_create_proposal?
18
+ when :edit
19
+ can_edit_proposal?
20
+ when :withdraw
21
+ can_withdraw_proposal?
22
+ when :endorse
23
+ can_endorse_proposal?
24
+ when :unendorse
25
+ can_unendorse_proposal?
26
+ when :vote
27
+ can_vote_proposal?
28
+ when :unvote
29
+ can_unvote_proposal?
30
+ when :report
31
+ true
32
+ end
33
+
34
+ permission_action
35
+ end
36
+
37
+ private
38
+
39
+ def proposal
40
+ @proposal ||= context.fetch(:proposal, nil)
41
+ end
42
+
43
+ def voting_enabled?
44
+ return unless current_settings
45
+ current_settings.votes_enabled? && !current_settings.votes_blocked?
46
+ end
47
+
48
+ def vote_limit_enabled?
49
+ return unless component_settings
50
+ component_settings.vote_limit.present? && component_settings.vote_limit.positive?
51
+ end
52
+
53
+ def remaining_votes
54
+ return 1 unless vote_limit_enabled?
55
+
56
+ proposals = Proposal.where(component: component)
57
+ votes_count = ProposalVote.where(author: user, proposal: proposals).size
58
+ component_settings.vote_limit - votes_count
59
+ end
60
+
61
+ def can_create_proposal?
62
+ toggle_allow(authorized?(:create) && current_settings&.creation_enabled?)
63
+ end
64
+
65
+ def can_edit_proposal?
66
+ toggle_allow(proposal && proposal.editable_by?(user))
67
+ end
68
+
69
+ def can_withdraw_proposal?
70
+ toggle_allow(proposal && proposal.author == user)
71
+ end
72
+
73
+ def can_endorse_proposal?
74
+ is_allowed = proposal &&
75
+ authorized?(:endorse) &&
76
+ current_settings&.endorsements_enabled? &&
77
+ !current_settings&.endorsements_blocked?
78
+
79
+ toggle_allow(is_allowed)
80
+ end
81
+
82
+ def can_unendorse_proposal?
83
+ is_allowed = proposal &&
84
+ authorized?(:endorse) &&
85
+ current_settings&.endorsements_enabled?
86
+
87
+ toggle_allow(is_allowed)
88
+ end
89
+
90
+ def can_vote_proposal?
91
+ is_allowed = proposal &&
92
+ authorized?(:vote) &&
93
+ voting_enabled? &&
94
+ remaining_votes.positive?
95
+
96
+ toggle_allow(is_allowed)
97
+ end
98
+
99
+ def can_unvote_proposal?
100
+ is_allowed = proposal &&
101
+ authorized?(:vote) &&
102
+ voting_enabled?
103
+
104
+ toggle_allow(is_allowed)
105
+ end
106
+ end
107
+ end
108
+ end
@@ -56,6 +56,8 @@ module Decidim
56
56
  query.evaluating
57
57
  when "withdrawn"
58
58
  query.withdrawn
59
+ when "except_rejected"
60
+ query.except_rejected
59
61
  else # Assume 'not_withdrawn'
60
62
  query.except_withdrawn
61
63
  end
@@ -7,11 +7,11 @@ module Decidim
7
7
  description "A proposal"
8
8
 
9
9
  interfaces [
10
- Decidim::Comments::CommentableInterface,
11
- Decidim::Core::AuthorableInterface,
12
- Decidim::Core::CategorizableInterface,
13
- Decidim::Core::ScopableInterface,
14
- Decidim::Core::AttachableInterface
10
+ -> { Decidim::Comments::CommentableInterface },
11
+ -> { Decidim::Core::AuthorableInterface },
12
+ -> { Decidim::Core::CategorizableInterface },
13
+ -> { Decidim::Core::ScopableInterface },
14
+ -> { Decidim::Core::AttachableInterface }
15
15
  ]
16
16
 
17
17
  field :id, !types.ID
@@ -1,27 +1 @@
1
- <div class="column">
2
- <article class="card card--proposal">
3
- <div class="card__content">
4
- <div class="card__header">
5
- <%= link_to resource_locator(proposal).path do %>
6
- <h5 class="card__title"><%= proposal.title %></h5>
7
- <% end %>
8
- <div class="card__author author-data author-data--small">
9
- <%= render partial: "decidim/shared/author_reference", locals: { author: present(proposal).author } %>
10
- </div>
11
- <div class="tech-info tech-info--text-left">
12
- <%= t(".creation_date", date: l(proposal.created_at, format: :decidim_short)) %>
13
- </div>
14
- <%= resource_reference(proposal, class: "tech-info--text-left") %>
15
- </div>
16
- <%= render partial: "decidim/proposals/proposals/proposal_badge", locals: { proposal: proposal } %>
17
- <p><%= truncate(proposal.body, length: 100) %></p>
18
- <%= render partial: "decidim/shared/tags", locals: { resource: proposal, tags_class_extra: "tags--proposal" } %>
19
- </div>
20
- <div class="card__footer">
21
- <div class="card__support">
22
- <div class="card__support__data"></div>
23
- <%= link_to t(".view_proposal"), resource_locator(proposal).path, class: "card__button button small secondary" %>
24
- </div>
25
- </div>
26
- </article>
27
- </div>
1
+ <%= card_for proposal %>
@@ -1,27 +1 @@
1
- <div class="column">
2
- <article class="card card--proposal">
3
- <div class="card__content">
4
- <div class="card__header">
5
- <%= link_to resource_locator(proposal).path do %>
6
- <h5 class="card__title"><%= proposal.title %></h5>
7
- <% end %>
8
- <div class="card__author author-data author-data--small">
9
- <%= render partial: "decidim/shared/author_reference", locals: { author: present(proposal).author } %>
10
- </div>
11
- <div class="tech-info tech-info--text-left">
12
- <%= t(".creation_date", date: l(proposal.created_at, format: :decidim_short)) %>
13
- </div>
14
- <%= resource_reference(proposal, class: "tech-info--text-left") %>
15
- </div>
16
- <%= render partial: "decidim/proposals/proposals/proposal_badge", locals: { proposal: proposal } %>
17
- <p><%= truncate(proposal.body, length: 100) %></p>
18
- <%= render partial: "decidim/shared/tags", locals: { resource: proposal, tags_class_extra: "tags--proposal" } %>
19
- </div>
20
- <div class="card__footer">
21
- <div class="card__support">
22
- <div class="card__support__data"></div>
23
- <%= link_to t(".view_proposal"), resource_locator(proposal).path, class: "card__button button small secondary" %>
24
- </div>
25
- </div>
26
- </article>
27
- </div>
1
+ <%= card_for proposal %>
@@ -21,7 +21,7 @@
21
21
  </div>
22
22
  </div>
23
23
  <div class="comment__content">
24
- <%= note.body %>
24
+ <%= simple_format note.body %>
25
25
  </div>
26
26
  </article>
27
27
  </div>
@@ -2,10 +2,10 @@
2
2
  <%= bulk_actions_dropdown %>
3
3
 
4
4
  <div id="js-other-actions-wrapper">
5
- <%= link_to t("actions.import", scope: "decidim.proposals", name: t("models.proposal.name", scope: "decidim.proposals.admin")), new_proposals_import_path, class: "button tiny button--simple" if can? :manage, current_component %>
5
+ <%= link_to t("actions.import", scope: "decidim.proposals", name: t("models.proposal.name", scope: "decidim.proposals.admin")), new_proposals_import_path, class: "button tiny button--simple" if allowed_to? :import, :proposals %>
6
6
 
7
- <% if can? :create, Decidim::Proposals::Proposal %>
8
- <%= link_to t("actions.new", scope: "decidim.proposals", name: t("models.proposal.name", scope: "decidim.proposals.admin")), new_proposal_path, class: "button tiny button--simple" if can? :manage, current_component %>
7
+ <% if allowed_to? :create, :proposal %>
8
+ <%= link_to t("actions.new", scope: "decidim.proposals", name: t("models.proposal.name", scope: "decidim.proposals.admin")), new_proposal_path, class: "button tiny button--simple" %>
9
9
  <% end %>
10
10
 
11
11
  <%= export_dropdown %>
@@ -40,7 +40,7 @@
40
40
  </td>
41
41
  <% end %>
42
42
 
43
- <% if can? :create, Decidim::Proposals::ProposalNote %>
43
+ <% if allowed_to? :create, :proposal_note %>
44
44
  <td>
45
45
  <%= proposal.proposal_notes_count %>
46
46
  </td>
@@ -51,11 +51,11 @@
51
51
  </td>
52
52
 
53
53
  <td class="table-list__actions">
54
- <% if can? :create, Decidim::Proposals::ProposalNote %>
54
+ <% if allowed_to? :create, :proposal_note %>
55
55
  <%= icon_link_to "chat", proposal_proposal_notes_path(proposal_id: proposal.id), t("actions.private_notes", scope: "decidim.proposals"), class: "action-icon--index-notes" %>
56
56
  <% end %>
57
57
 
58
- <% if can? :update, proposal %>
58
+ <% if allowed_to? :create, :proposal_answer %>
59
59
  <%= icon_link_to "comment-square", edit_proposal_proposal_answer_path(proposal_id: proposal.id, id: proposal.id), t("actions.answer", scope: "decidim.proposals"), class: "action-icon--edit-answer" %>
60
60
  <% end %>
61
61
  <%= icon_link_to "eye", resource_locator(proposal).path, t("actions.preview", scope: "decidim.proposals.admin"), class: "action-icon--preview", target: :blank %>
@@ -48,7 +48,7 @@
48
48
  </th>
49
49
  <% end %>
50
50
 
51
- <% if can? :create, Decidim::Proposals::ProposalNote %>
51
+ <% if allowed_to? :create, :proposal_note %>
52
52
  <th>
53
53
  <%= sort_link(query, :proposal_notes_count, t("models.proposal.fields.notes", scope: "decidim.proposals") ) %>
54
54
  </th>
@@ -1,4 +1,5 @@
1
1
  <li class="<%= selected ? "selected" : "" %>" data-method="<%= http_method.to_s.upcase %>" data-url="<%= current_endorsement_url %>">
2
- <%= render partial: "decidim/shared/author_reference", locals: { author: identity } %>
2
+ <%= card_for identity, context: {extra_classes: ["author-data--small"]} %>
3
+
3
4
  <%= icon("circle-check", class: "icon--big #{selected ? '' : 'invisible'}") %>
4
5
  </li>
@@ -1,4 +1,4 @@
1
1
  <% content_for(:title, model.title) %>
2
2
 
3
- <%= render partial: "decidim/proposals/proposals/proposal_badge", locals: { proposal: model } %>
3
+ <%== cell("decidim/proposals/proposal_m", model).badge %>
4
4
  <p><%= truncate(model.body, length: 100) %></p>
@@ -4,7 +4,7 @@
4
4
  <div class="column small-9 collapse">
5
5
  <div class="button-group button-group--collapse button--nomargin small">
6
6
  <%= render partial: "endorsements_count", locals: { proposal: @proposal, fully_endorsed: fully_endorsed } %>
7
- <% if current_settings.endorsements_blocked? %>
7
+ <% if current_settings.endorsements_blocked? || !current_component.participatory_space.can_participate?(current_user) %>
8
8
  <%= content_tag :span, t(".endorse"), class: "card__button button #{endorsement_button_classes(false)} disabled", disabled: true, title: t(".endorse") %>
9
9
  <% elsif current_user %>
10
10
  <%= render partial: "endorsement_identities_cabin", locals: { proposal: @proposal, fully_endorsed: fully_endorsed } %>
@@ -16,7 +16,7 @@
16
16
  <% end %>
17
17
  <div class="column collapse <%= endorsements_enabled? ? "small-3" : "" %>">
18
18
  <%= link_to "#comments", class: "button small compact hollow secondary button--nomargin expanded" do %>
19
- <%= icon "comment-square", class: "icon--small", aria_label: "Comentarios", role: "img" %> <%= @proposal.comments.count %>
19
+ <%= icon "comment-square", class: "icon--small", aria_label: t(".comments"), role: "img" %> <%= @proposal.comments.count %>
20
20
  <% end %>
21
21
  </div>
22
22
  </div>
@@ -17,7 +17,7 @@
17
17
  <% end %>
18
18
 
19
19
  <% if component_settings.proposal_answering_enabled && current_settings.proposal_answering_enabled %>
20
- <%= form.collection_radio_buttons :state, [["all", t(".all")], ["accepted", t(".accepted")], ["rejected", t(".rejected")], ["evaluating", t(".evaluating")]], :first, :last, legend_title: t(".state") %>
20
+ <%= form.collection_radio_buttons :state, [["except_rejected", t(".except_rejected")], ["accepted", t(".accepted")], ["evaluating", t(".evaluating")], ["rejected", t(".rejected")], ["all", t(".all")]], :first, :last, legend_title: t(".state") %>
21
21
  <% end %>
22
22
 
23
23
  <% if linked_classes_for(Decidim::Proposals::Proposal).any? %>
@@ -1,6 +1,5 @@
1
1
  <div class="card card--action card--list">
2
2
  <% resources.each do |proposal| %>
3
- <% next unless proposal.component.published? %>
4
3
  <div class="card--list__item">
5
4
  <div class="card--list__text">
6
5
  <%= link_to resource_locator(proposal).path do %>
@@ -23,11 +22,13 @@
23
22
  <% end %>
24
23
  </div>
25
24
  </div>
26
- <div class="card--list__data">
27
- <span class="card--list__data__number">
28
- <%= proposal.votes.size %>
29
- </span> <%= t(".proposal_votes", count: proposal.votes.size) %>
30
- </div>
25
+ <% if !current_settings.try(:votes_hidden?) && !proposal.component.current_settings.votes_hidden? %>
26
+ <div class="card--list__data">
27
+ <span class="card--list__data__number">
28
+ <%= proposal.votes.size %>
29
+ </span> <%= t(".proposal_votes", count: proposal.votes.size) %>
30
+ </div>
31
+ <% end %>
31
32
  </div>
32
33
  <% end %>
33
34
  </div>
@@ -1,32 +1 @@
1
- <div class="column">
2
- <article class="card card--proposal">
3
- <div class="card__content">
4
- <div class="card__header">
5
- <%= link_to proposal do %>
6
- <h5 class="card__title"><%= proposal.title %></h5>
7
- <% end %>
8
- <div class="card__author">
9
- <%= render partial: "decidim/shared/author_reference", locals: { author: present(proposal).author } %>
10
- </div>
11
- <div class="tech-info tech-info--text-left">
12
- <%= t(".creation_date", date: l(proposal.created_at, format: :decidim_short)) %>
13
- </div>
14
- <%= resource_reference(proposal, class: "tech-info--text-left") %>
15
- </div>
16
- <%= render partial: "proposal_badge", locals: { proposal: proposal } %>
17
- <p><%= truncate(proposal.body, length: 100) %></p>
18
- <%= render partial: "decidim/shared/tags", locals: { resource: proposal, tags_class_extra: "tags--proposal" } %>
19
- </div>
20
- <div class="card__footer">
21
- <div class="card__support">
22
- <% if current_settings.votes_enabled? && !proposal.draft? %>
23
- <%= render partial: "votes_count", locals: { proposal: proposal, from_proposals_list: true } %>
24
- <%= render partial: "vote_button", locals: { proposal: proposal, from_proposals_list: true } %>
25
- <% else %>
26
- <div class="card__support__data"></div>
27
- <%= link_to t(".view_proposal"), proposal, class: "card__button button small secondary" %>
28
- <% end %>
29
- </div>
30
- </div>
31
- </article>
32
- </div>
1
+ <%= card_for proposal, from: proposal, context: { current_user: current_user } %>
@@ -1,36 +1 @@
1
- <article class="card card--proposal">
2
- <div class="card__content">
3
- <div class="card__header">
4
- <%= link_to proposal, class: "card__link" do %>
5
- <h5 class="card__title"><%= proposal.title %></h5>
6
- <% end %>
7
- <div class="card__author author-data author-data--small">
8
- <%= render partial: "decidim/shared/author_reference", locals: { author: present(proposal).author } %>
9
- </div>
10
- </div>
11
- <p><%= truncate(proposal.body, length: 100) %></p>
12
- <%= render partial: "decidim/shared/tags", locals: { resource: proposal, tags_class_extra: "tags--proposal" } %>
13
- </div>
14
- <div class="card__status">
15
- <ul class="card-data">
16
- <li class="card-data__item">
17
- <%= render partial: "proposal_badge", locals: { proposal: proposal } %>
18
- </li>
19
- <li class="card-data__item">
20
- <%= l(proposal.created_at, format: :decidim_short) %>
21
- </li>
22
- <li class="card-data__item">
23
- <a href="#comments">
24
- <%= icon "bullhorn", class: "icon--small", role: "img" %>
25
- 0
26
- </a>
27
- </li>
28
- <li class="card-data__item">
29
- <a href="#comments">
30
- <%= icon "comment-square", class: "icon--small", role: "img" %>
31
- 0
32
- </a>
33
- </li>
34
- </ul>
35
- </div>
36
- </article>
1
+ <%= card_for proposal, size: :m, context: { current_user: current_user } %>
@@ -5,17 +5,18 @@
5
5
  <%= link_to proposal, target: "_blank" do %>
6
6
  <h5 class="card__title"><%= proposal.title %></h5>
7
7
  <% end %>
8
- <div class="card__author author-data author-data--small">
9
- <%= render partial: "decidim/shared/author_reference", locals: { author: present(proposal).author } %>
10
- </div>
8
+ <%= cell "decidim/author", present(proposal).author, context: {extra_classes: ["author-data--small"]} %>
9
+
11
10
  <div class="tech-info tech-info--text-left">
12
11
  <%= t("decidim.proposals.proposals.proposal.creation_date", date: l(proposal.created_at, format: :decidim_short)) %>
13
12
  </div>
14
13
  <%= resource_reference(proposal, class: "tech-info--text-left") %>
15
14
  </div>
16
- <%= render partial: "decidim/proposals/proposals/proposal_badge", locals: { proposal: proposal } %>
15
+
16
+ <%== cell("decidim/proposals/proposal_m", proposal).badge %>
17
+
17
18
  <p><%= truncate(proposal.body, length: 100) %></p>
18
- <%= render partial: "decidim/shared/tags", locals: { resource: proposal, tags_class_extra: "tags--proposal" } %>
19
+ <%= cell "decidim/tags", proposal, context: {extra_classes: ["tags--proposal"]} %>
19
20
  </div>
20
21
  </article>
21
22
  </div>
@@ -1,24 +1,42 @@
1
- <% unless proposal.rejected? %>
1
+ <% if proposal.rejected? %>
2
+ <div></div>
3
+ <% else %>
2
4
  <div id="proposal-<%= proposal.id %>-vote-button">
3
5
  <% if !current_user %>
4
6
  <% if current_settings.votes_blocked? %>
5
- <%= action_authorized_button_to :vote, t(".votes_blocked"), proposal_proposal_vote_path(proposal_id: proposal, from_proposals_list: from_proposals_list), class: "button #{vote_button_classes(from_proposals_list)} disabled", disabled: true %>
7
+ <%= action_authorized_button_to :vote, t("decidim.proposals.proposals.vote_button.votes_blocked"), proposal_proposal_vote_path(proposal_id: proposal, from_proposals_list: from_proposals_list), class: "button #{vote_button_classes(from_proposals_list)} disabled", disabled: true %>
6
8
  <% else %>
7
- <%= action_authorized_button_to :vote, t(".vote"), proposal_proposal_vote_path(proposal_id: proposal, from_proposals_list: from_proposals_list), class: "button #{vote_button_classes(from_proposals_list)}", data: { disable: true, "redirect-url": proposal_path(proposal) } %>
9
+ <%= action_authorized_button_to :vote, t("decidim.proposals.proposals.vote_button.vote"), proposal_proposal_vote_path(proposal_id: proposal, from_proposals_list: from_proposals_list), class: "button #{vote_button_classes(from_proposals_list)}", data: { disable: true, "redirect-url": proposal_path(proposal) } %>
8
10
  <% end %>
9
11
  <% else %>
10
12
  <% if @voted_proposals ? @voted_proposals.include?(proposal.id) : proposal.voted_by?(current_user) %>
11
- <%= action_authorized_button_to :vote, t(".already_voted"), proposal_proposal_vote_path(proposal_id: proposal, from_proposals_list: from_proposals_list), method: :delete, remote: true, data: { disable: true, original: t(".already_voted"), replace: t(".already_voted_hover"), "redirect-url": proposal_path(proposal) }, class: "button #{vote_button_classes(from_proposals_list)} success", id: "vote_button" %>
13
+ <%= action_authorized_button_to(
14
+ :vote,
15
+ proposal_proposal_vote_path(proposal_id: proposal, from_proposals_list: from_proposals_list),
16
+ method: :delete,
17
+ remote: true,
18
+ data: {
19
+ disable: true,
20
+ original: t("decidim.proposals.proposals.vote_button.already_voted"),
21
+ replace: t("decidim.proposals.proposals.vote_button.already_voted_hover"),
22
+ "redirect-url": proposal_path(proposal)
23
+ },
24
+ class: "button #{vote_button_classes(from_proposals_list)} success light",
25
+ id: "vote_button"
26
+ ) do %>
27
+ <%= icon("check", class: "icon--small") %>
28
+ <%= t("decidim.proposals.proposals.vote_button.already_voted") %>
29
+ <% end %>
12
30
  <% else %>
13
- <% if proposal.maximum_votes_reached? && !proposal.can_accumulate_supports_beyond_threshold %>
14
- <%= content_tag :span, t(".maximum_votes_reached"), class: "button #{vote_button_classes(from_proposals_list)} disabled", disabled: true %>
31
+ <% if proposal.maximum_votes_reached? && !proposal.can_accumulate_supports_beyond_threshold && current_component.participatory_space.can_participate?(current_user) %>
32
+ <%= content_tag :span, t("decidim.proposals.proposals.vote_button.maximum_votes_reached"), class: "button #{vote_button_classes(from_proposals_list)} disabled", disabled: true %>
15
33
  <% else %>
16
34
  <% if vote_limit_enabled? && remaining_votes_count_for(current_user) == 0 %>
17
- <%= content_tag :span, t(".no_votes_remaining"), class: "button #{vote_button_classes(from_proposals_list)}", disabled: true %>
18
- <% elsif current_settings.votes_blocked? %>
19
- <%= content_tag :span, t(".votes_blocked"), class: "button #{vote_button_classes(from_proposals_list)} disabled", disabled: true %>
35
+ <%= content_tag :span, t("decidim.proposals.proposals.vote_button.no_votes_remaining"), class: "button #{vote_button_classes(from_proposals_list)}", disabled: true %>
36
+ <% elsif current_settings.votes_blocked? || !current_component.participatory_space.can_participate?(current_user) %>
37
+ <%= content_tag :span, t("decidim.proposals.proposals.vote_button.votes_blocked"), class: "button #{vote_button_classes(from_proposals_list)} disabled", disabled: true %>
20
38
  <% else %>
21
- <%= action_authorized_button_to :vote, t(".vote"), proposal_proposal_vote_path(proposal_id: proposal, from_proposals_list: from_proposals_list), remote: true, data: { disable: true, "redirect-url": proposal_path(proposal) }, class: "button #{vote_button_classes(from_proposals_list)}" %>
39
+ <%= action_authorized_button_to :vote, t("decidim.proposals.proposals.vote_button.vote"), proposal_proposal_vote_path(proposal_id: proposal, from_proposals_list: from_proposals_list), remote: true, data: { disable: true, "redirect-url": proposal_path(proposal) }, class: "button #{vote_button_classes(from_proposals_list)}" %>
22
40
  <% end %>
23
41
  <% end %>
24
42
  <% end %>
@@ -1,28 +1,14 @@
1
- <div id="proposal-<%= proposal.id %>-votes-count" class="card__support__data">
2
- <% if !current_settings.votes_hidden? %>
3
- <% progress ||= proposal.proposal_votes_count || 0 %>
4
- <% total ||= proposal.maximum_votes || 0 %>
5
- <% percent = (progress.to_f/total) * 100 %>
6
- <% vertical ||= from_proposals_list %>
7
- <div class="progress__bar<%= (!vertical) ? " progress__bar--vertical" : "" %>">
8
- <div class="progress__bar__title">
9
- <span class="progress__bar__number"><%= progress %></span><%= "/#{total}" if total != 0 %>
10
- <span class="progress__bar__text"><%= t(".count", count: proposal.proposal_votes_count) %></span>
11
- </div>
12
- <% if total != 0 %>
13
- <div class="progress progress__bar__bar" role="progressbar" tabindex="0" aria-valuenow="<%= percent %>" aria-valuemin="0" aria-valuetext="<%= percent %> percent" aria-valuemax="100">
14
- <div class="progress-meter progress__bar__bar--complete" style="width: <%= percent %>%"></div>
15
- <div class="progress__bar__bar--incomplete" style="width:calc(100% - <%= percent %>%);"></div>
16
- </div>
17
- <div class="progress__bar__subtitle">
18
- <% if progress >= total %>
19
- <%= t(".most_popular_proposal") %>
20
- <% else %>
21
- <%= t(".need_more_votes") %>
22
- <% end %>
23
- </div>
24
- <% end %>
25
- </div>
26
-
27
- <% end %>
28
- </div>
1
+ <% if !current_settings.votes_hidden? && current_component.participatory_space.can_participate?(current_user) %>
2
+ <% progress ||= proposal.proposal_votes_count || 0 %>
3
+ <% total ||= proposal.maximum_votes || 0 %>
4
+ <% subtitle_text = progress >= total ? t("decidim.proposals.proposals.votes_count.most_popular_proposal") : t("decidim.proposals.proposals.votes_count.need_more_votes") %>
5
+ <%= cell(
6
+ "decidim/progress_bar",
7
+ progress,
8
+ total: total,
9
+ units_name: "decidim.proposals.proposals.votes_count.count",
10
+ element_id: "proposal-#{proposal.id}-votes-count",
11
+ subtitle_text: subtitle_text,
12
+ small: from_proposals_list
13
+ ) %>
14
+ <% end %>