decidim-proposals 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -0
  3. data/app/commands/decidim/proposals/admin/answer_proposal.rb +1 -0
  4. data/app/commands/decidim/proposals/admin/create_proposal.rb +1 -0
  5. data/app/commands/decidim/proposals/create_proposal.rb +1 -0
  6. data/app/commands/decidim/proposals/create_proposal_export.rb +1 -0
  7. data/app/controllers/concerns/decidim/proposals/orderable.rb +64 -0
  8. data/app/controllers/decidim/proposals/admin/application_controller.rb +1 -0
  9. data/app/controllers/decidim/proposals/admin/proposal_answers_controller.rb +1 -0
  10. data/app/controllers/decidim/proposals/admin/proposals_controller.rb +1 -0
  11. data/app/controllers/decidim/proposals/proposals_controller.rb +2 -33
  12. data/app/forms/decidim/proposals/admin/proposal_answer_form.rb +1 -0
  13. data/app/forms/decidim/proposals/admin/proposal_form.rb +1 -0
  14. data/app/forms/decidim/proposals/proposal_form.rb +1 -0
  15. data/app/helpers/decidim/proposals/application_helper.rb +1 -1
  16. data/app/helpers/decidim/proposals/map_helper.rb +1 -0
  17. data/app/helpers/decidim/proposals/proposal_votes_helper.rb +1 -0
  18. data/app/models/decidim/proposals/abilities/admin_user.rb +1 -0
  19. data/app/models/decidim/proposals/abilities/current_user.rb +2 -1
  20. data/app/models/decidim/proposals/abilities/process_admin_user.rb +1 -0
  21. data/app/models/decidim/proposals/application_record.rb +1 -0
  22. data/app/models/decidim/proposals/proposal.rb +9 -1
  23. data/app/models/decidim/proposals/proposal_vote.rb +3 -2
  24. data/app/queries/decidim/proposals/filtered_proposals.rb +1 -0
  25. data/app/services/decidim/proposals/proposal_search.rb +1 -0
  26. data/app/views/decidim/proposals/admin/proposals/index.html.erb +1 -8
  27. data/app/views/decidim/proposals/proposals/_proposal.html.erb +1 -1
  28. data/app/views/decidim/proposals/proposals/_proposals.html.erb +2 -2
  29. data/app/views/decidim/proposals/proposals/_vote_button.html.erb +4 -10
  30. data/app/views/decidim/proposals/proposals/show.html.erb +2 -2
  31. data/config/i18n-tasks.yml +4 -1
  32. data/config/initializers/social_share_button.rb +1 -0
  33. data/config/locales/ca.yml +3 -3
  34. data/config/locales/en.yml +3 -4
  35. data/config/locales/es.yml +3 -3
  36. data/config/locales/eu.yml +10 -0
  37. data/config/locales/fr.yml +0 -3
  38. data/lib/decidim/proposals/admin.rb +1 -0
  39. data/lib/decidim/proposals/admin_engine.rb +1 -4
  40. data/lib/decidim/proposals/engine.rb +1 -0
  41. data/lib/decidim/proposals/feature.rb +20 -0
  42. data/{app/services → lib}/decidim/proposals/proposal_serializer.rb +1 -1
  43. data/lib/decidim/proposals/test/factories.rb +9 -0
  44. data/lib/decidim/proposals.rb +2 -0
  45. metadata +16 -18
  46. data/app/controllers/decidim/proposals/admin/exports_controller.rb +0 -24
  47. data/app/helpers/decidim/proposals/proposal_order_helper.rb +0 -16
  48. data/app/jobs/decidim/proposals/export_job.rb +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 57be816bd788ab639e3f356480d2e2b82099b816
4
- data.tar.gz: 849c9453e5e32cd736d7172e10c45b310110fbe4
3
+ metadata.gz: 656619a854b4e23c556abee9a2641287a8b0b9e4
4
+ data.tar.gz: fe25ef91ada0e02ce0c8a41b4155843b70de8049
5
5
  SHA512:
6
- metadata.gz: 4a680b98cdb8fcc5038a25cd50ff7dcd309b99e12fddba0905a960bd87fc5876ac6800c90faa458f117be54b1d8103d69e228a89374d51022e7fc1018f0f3418
7
- data.tar.gz: 443db12a69fce3d32c4199e989c0536437bdf4b79f8158783c8b47a205ffc72eb7f2b597893df8ac7c12b2b28e28486f02c463e9ae2150092142082cbb128b52
6
+ metadata.gz: efdb25720d97e47ce218640b118012b790755a30c13b8e1193a017e53763c8c261f5af140355c5a44864c1cf2b68dfe9ed8dc16e361e4409bea88cbc3a7d583a
7
+ data.tar.gz: 5b72de0eb3baba3c6430706cf7157ae7cdb459d3a2955af0fd5678dc42b58ca1a5ebc9b38e8b5a727473cd5300b3d4315704844fc12ce5de8221c8fabed46478
data/Rakefile CHANGED
@@ -1,2 +1,3 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "decidim/dev/common_rake"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  module Admin
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  module Admin
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  # A command with all the business logic when a user creates a new proposal.
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  # A command with all the business logic when a user creates a new proposal.
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ module Proposals
7
+ # Common logic to ordering resources
8
+ module Orderable
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ helper_method :order, :available_orders, :random_seed
13
+
14
+ private
15
+
16
+ # Gets how the proposals should be ordered based on the choice made by the user.
17
+ def order
18
+ @order ||= detect_order(params[:order]) || default_order
19
+ end
20
+
21
+ # Available orders based on enabled settings
22
+ def available_orders
23
+ @available_orders ||= begin
24
+ available_orders = %w(random recent)
25
+ available_orders << "most_voted" if votes_visible?
26
+ available_orders
27
+ end
28
+ end
29
+
30
+ def default_order
31
+ if current_settings.votes_blocked?
32
+ detect_order("most_voted")
33
+ else
34
+ "random"
35
+ end
36
+ end
37
+
38
+ def votes_visible?
39
+ current_settings.votes_enabled? && !current_settings.votes_hidden?
40
+ end
41
+
42
+ # Returns: A random float number between -1 and 1 to be used as a random seed at the database.
43
+ def random_seed
44
+ @random_seed ||= (params[:random_seed] ? params[:random_seed].to_f : (rand * 2 - 1))
45
+ end
46
+
47
+ def detect_order(candidate)
48
+ available_orders.detect { |order| order == candidate }
49
+ end
50
+
51
+ def reorder(proposals)
52
+ case order
53
+ when "random"
54
+ proposals.order_randomly(random_seed)
55
+ when "most_voted"
56
+ proposals.order(proposal_votes_count: :desc)
57
+ when "recent"
58
+ proposals.order(created_at: :desc)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  module Admin
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  module Admin
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  module Admin
@@ -7,8 +7,9 @@ module Decidim
7
7
  helper Decidim::WidgetUrlsHelper
8
8
  include FormFactory
9
9
  include FilterResource
10
+ include Orderable
10
11
 
11
- helper_method :order, :random_seed, :geocoded_proposals
12
+ helper_method :geocoded_proposals
12
13
 
13
14
  before_action :authenticate_user!, only: [:new, :create]
14
15
 
@@ -64,38 +65,6 @@ module Decidim
64
65
 
65
66
  private
66
67
 
67
- # Gets how the proposals should be ordered based on the choice made by the user.
68
- #
69
- # Note that when votes are active and hidden at the same time, the "most_voted"
70
- # option is not available, so it's replaced to "random" to avoid people
71
- # changing the URL manually.
72
- def order
73
- return @order if @order
74
- @order = "random" if current_settings.votes_enabled? && current_settings.votes_hidden? && params[:order] == "most_voted"
75
- @order ||= params[:order] || "random"
76
- end
77
-
78
- # Returns: A random float number between -1 and 1 to be used as a random seed at the database.
79
- def random_seed
80
- @random_seed ||= (params[:random_seed] ? params[:random_seed].to_f : (rand * 2 - 1))
81
- end
82
-
83
- def reorder(proposals)
84
- case order
85
- when "random"
86
- Proposal.transaction do
87
- Proposal.connection.execute("SELECT setseed(#{Proposal.connection.quote(random_seed)})")
88
- proposals.order("RANDOM()").load
89
- end
90
- when "most_voted"
91
- proposals.order(proposal_votes_count: :desc)
92
- when "recent"
93
- proposals.order(created_at: :desc)
94
- else
95
- proposals
96
- end
97
- end
98
-
99
68
  def geocoded_proposals
100
69
  @geocoded_proposals ||= search.results.not_hidden.select(&:geocoded?)
101
70
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  module Admin
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  module Admin
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  # A form object to be used when public users want to create a proposal.
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  # Custom helpers, scoped to the proposals engine.
@@ -7,7 +8,6 @@ module Decidim
7
8
  include Decidim::Comments::CommentsHelper
8
9
  include PaginateHelper
9
10
  include ProposalVotesHelper
10
- include ProposalOrderHelper
11
11
  include Decidim::MapHelper
12
12
  include Decidim::Proposals::MapHelper
13
13
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  # This helper include some methods for rendering proposals dynamic maps.
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  # Simple helpers to handle markup variations for proposal votes partials
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  module Abilities
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  module Abilities
@@ -20,7 +21,7 @@ module Decidim
20
21
  end
21
22
 
22
23
  can :unvote, Proposal do |_proposal|
23
- authorized?(:vote) && voting_enabled? && vote_limit_enabled?
24
+ authorized?(:vote) && voting_enabled?
24
25
  end
25
26
 
26
27
  can :create, Proposal if authorized?(:create) && creation_enabled?
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  module Abilities
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  # Abstract class from which all models in this engine inherit.
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  # The data store for a Proposal in the Decidim::Proposals component.
@@ -14,7 +15,7 @@ module Decidim
14
15
 
15
16
  feature_manifest_name "proposals"
16
17
 
17
- has_many :votes, foreign_key: "decidim_proposal_id", class_name: ProposalVote, dependent: :destroy, counter_cache: "proposal_votes_count"
18
+ has_many :votes, foreign_key: "decidim_proposal_id", class_name: "ProposalVote", dependent: :destroy, counter_cache: "proposal_votes_count"
18
19
 
19
20
  validates :title, :body, presence: true
20
21
 
@@ -23,6 +24,13 @@ module Decidim
23
24
  scope :accepted, -> { where(state: "accepted") }
24
25
  scope :rejected, -> { where(state: "rejected") }
25
26
 
27
+ def self.order_randomly(seed)
28
+ transaction do
29
+ connection.execute("SELECT setseed(#{connection.quote(seed)})")
30
+ order("RANDOM()").load
31
+ end
32
+ end
33
+
26
34
  def author_name
27
35
  user_group&.name || author&.name || I18n.t("decidim.proposals.models.proposal.fields.official_proposal")
28
36
  end
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  # A proposal can include a vote per user.
5
6
  class ProposalVote < ApplicationRecord
6
- belongs_to :proposal, foreign_key: "decidim_proposal_id", class_name: Decidim::Proposals::Proposal, counter_cache: true
7
- belongs_to :author, foreign_key: "decidim_author_id", class_name: Decidim::User
7
+ belongs_to :proposal, foreign_key: "decidim_proposal_id", class_name: "Decidim::Proposals::Proposal", counter_cache: true
8
+ belongs_to :author, foreign_key: "decidim_author_id", class_name: "Decidim::User"
8
9
 
9
10
  validates :proposal, :author, presence: true
10
11
  validates :proposal, uniqueness: { scope: :author }
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  # A class used to find proposals filtered by features and a date range
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  # A service to encapsualte all the logic when searching and filtering
@@ -9,14 +9,7 @@
9
9
  <%= 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_feature %>
10
10
  <% end %>
11
11
 
12
- <button class="exports dropdown tiny button button--simple" data-toggle="export-dropdown"><%= t "actions.export", scope: "decidim.proposals" %></button>
13
- <div class="dropdown-pane" id="export-dropdown" data-dropdown data-auto-focus="true" data-close-on-click="true">
14
- <ul class="vertical menu add-features">
15
- <li class="exports--csv"><%= link_to "CSV", exports_path(feature_id: current_feature, participatory_process_id: current_participatory_process, format: :csv), method: :post %></li>
16
- <li class="exports--json"><%= link_to "JSON", exports_path(feature_id: current_feature, participatory_process_id: current_participatory_process, format: :json), method: :post %></li>
17
- </ul>
18
- </div>
19
-
12
+ <%= export_dropdown %>
20
13
  </div>
21
14
  </h2>
22
15
  </div>
@@ -26,7 +26,7 @@
26
26
  <% if current_settings.votes_enabled? %>
27
27
  <%= render partial: "votes_count", locals: { proposal: proposal, from_proposals_list: true } %>
28
28
  <%= render partial: "vote_button", locals: { proposal: proposal, from_proposals_list: true } %>
29
- <% elsif !current_settings.votes_enabled? || current_settings.votes_enabled? && current_settings.votes_blocked? %>
29
+ <% else %>
30
30
  <div class="card__support__data"></div>
31
31
  <%= link_to t(".view_proposal"), proposal, class: "card__button button small secondary" %>
32
32
  <% end %>
@@ -1,5 +1,5 @@
1
- <%= order_selector order_fields, i18n_scope: "decidim.proposals.proposals.orders" %>
1
+ <%= order_selector available_orders, i18n_scope: "decidim.proposals.proposals.orders" %>
2
2
  <div class="row small-up-1 medium-up-2 card-grid">
3
3
  <%= render @proposals %>
4
4
  </div>
5
- <%= decidim_paginate @proposals, random_seed: random_seed %>
5
+ <%= decidim_paginate @proposals, random_seed: random_seed %>
@@ -1,7 +1,7 @@
1
1
  <div id="proposal-<%= proposal.id %>-vote-button">
2
2
  <% if !current_user %>
3
3
  <% if current_settings.votes_blocked? %>
4
- <button class="card__button button <%= vote_button_classes(from_proposals_list) %> disabled" data-toggle="loginModal">
4
+ <button class="card__button button <%= vote_button_classes(from_proposals_list) %> disabled" disabled data-toggle="loginModal">
5
5
  <%= t('.votes_blocked') %>
6
6
  </button>
7
7
  <% else %>
@@ -11,22 +11,16 @@
11
11
  <% end %>
12
12
  <% else %>
13
13
  <% if @voted_proposals ? @voted_proposals.include?(proposal.id) : proposal.voted_by?(current_user) %>
14
- <% if vote_limit_enabled? %>
15
- <%= 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 }, class: "card__button button #{vote_button_classes(from_proposals_list)} success" %>
16
- <% else %>
17
- <button class="card__button button <%= vote_button_classes(from_proposals_list) %> success">
18
- <%= t('.already_voted') %>
19
- </button>
20
- <% end %>
14
+ <%= 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 }, class: "card__button button #{vote_button_classes(from_proposals_list)} success" %>
21
15
  <% else %>
22
16
  <% if vote_limit_enabled? && remaining_votes_count_for(current_user) == 0 %>
23
17
  <%= action_authorized_button_to :vote, t('.no_votes_remaining'), proposal_proposal_vote_path(proposal_id: proposal, from_proposals_list: from_proposals_list), remote: true, data: { disable: true }, class: "card__button button #{vote_button_classes(from_proposals_list)}", disabled: true %>
24
18
  <% elsif current_settings.votes_blocked? %>
25
- <button class="card__button button <%= vote_button_classes(from_proposals_list) %> disabled">
19
+ <button class="card__button button <%= vote_button_classes(from_proposals_list) %> disabled" disabled>
26
20
  <%= t('.votes_blocked') %>
27
21
  </button>
28
22
  <% else %>
29
- <%= 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 }, class: "card__button button #{vote_button_classes(from_proposals_list)}" %>
23
+ <%= 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 }, class: "card__button button #{vote_button_classes(from_proposals_list)}" %>
30
24
  <% end %>
31
25
  <% end %>
32
26
  <% end %>
@@ -43,7 +43,7 @@
43
43
  <div class="columns mediumlarge-8 mediumlarge-pull-4">
44
44
  <div class="section">
45
45
  <%= render partial: "proposal_badge", locals: { proposal: @proposal } %>
46
- <p><%= @proposal.body %></p>
46
+ <%= simple_format @proposal.body %>
47
47
  <% if feature_settings.geocoding_enabled? %>
48
48
  <%= render partial: "decidim/shared/static_map", locals: { icon_name: "proposals", geolocalizable: @proposal } %>
49
49
  <% end %>
@@ -61,7 +61,7 @@
61
61
  <div class="section">
62
62
  <div class="callout warning">
63
63
  <h5><%= t(".proposal_rejected_reason") %></h5>
64
- <p><%= translated_attribute @proposal.answer %></p>
64
+ <p><%== translated_attribute @proposal.answer %></p>
65
65
  </div>
66
66
  </div>
67
67
  <% end %>
@@ -1,5 +1,4 @@
1
1
  base_locale: en
2
- locales: [en]
3
2
  ignore_unused:
4
3
  - "decidim.features.proposals.name"
5
4
  - "decidim.features.proposals.settings.*"
@@ -8,5 +7,9 @@ ignore_unused:
8
7
  - "decidim.proposals.answers.*"
9
8
  - "decidim.features.proposals.actions.*"
10
9
  - "decidim.proposals.proposals.orders.*"
10
+ - "decidim.proposals.admin.exports.proposals"
11
+ - "decidim.proposals.admin.exports.comments"
11
12
  ignore_missing:
12
13
  - decidim.participatory_processes.scopes.global
14
+ search:
15
+ strict: false
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  SocialShareButton.configure do |config|
3
4
  config.allow_sites = %w(twitter facebook google_plus)
4
5
  end
@@ -33,12 +33,14 @@ ca:
33
33
  proposals:
34
34
  actions:
35
35
  answer: Respondre
36
- export: Exporta
37
36
  new: Nova
38
37
  title: Accions
39
38
  admin:
40
39
  actions:
41
40
  preview: Previsualitzar
41
+ exports:
42
+ comments: Comentaris
43
+ proposals: Propostes
42
44
  models:
43
45
  proposal:
44
46
  name: Proposta
@@ -69,8 +71,6 @@ ca:
69
71
  create:
70
72
  error: Hi ha hagut errors en desar la proposta.
71
73
  success: Proposta creada correctament.
72
- exports:
73
- notice: La seva exportació està actualment en curs. Rebràs un correu electrònic quan estigui complet.
74
74
  models:
75
75
  proposal:
76
76
  fields:
@@ -35,12 +35,14 @@ en:
35
35
  proposals:
36
36
  actions:
37
37
  answer: Answer
38
- export: Export
39
38
  new: New
40
39
  title: Actions
41
40
  admin:
42
41
  actions:
43
42
  preview: Preview
43
+ exports:
44
+ comments: Comments
45
+ proposals: Proposals
44
46
  models:
45
47
  proposal:
46
48
  name: Proposal
@@ -71,9 +73,6 @@ en:
71
73
  create:
72
74
  error: There's been errors when saving the proposal.
73
75
  success: Proposal created successfully.
74
- exports:
75
- notice: Your export is currently in progress. You'll receive an email when
76
- it's complete.
77
76
  models:
78
77
  proposal:
79
78
  fields:
@@ -33,12 +33,14 @@ es:
33
33
  proposals:
34
34
  actions:
35
35
  answer: Respuesta
36
- export: Exportar
37
36
  new: Nueva
38
37
  title: Acciones
39
38
  admin:
40
39
  actions:
41
40
  preview: Previsualizar
41
+ exports:
42
+ comments: Comentarios
43
+ proposals: Propuestas
42
44
  models:
43
45
  proposal:
44
46
  name: Propuesta
@@ -69,8 +71,6 @@ es:
69
71
  create:
70
72
  error: Ha habido errores al guardar la propuesta.
71
73
  success: Propuesta creada correctamente.
72
- exports:
73
- notice: Su exportación está actualmente en curso. Recibirá un correo electrónico cuando esté completo.
74
74
  models:
75
75
  proposal:
76
76
  fields:
@@ -13,6 +13,7 @@ eu:
13
13
  features:
14
14
  proposals:
15
15
  actions:
16
+ create: Sortu
16
17
  vote: Proiektuaren alde egin
17
18
  name: Proposamenak
18
19
  settings:
@@ -28,19 +29,25 @@ eu:
28
29
  proposal_answering_enabled: Erantzuna aktibatutako proposamenei
29
30
  votes_blocked: Bozketa blokeatuta
30
31
  votes_enabled: Botoak gaituta
32
+ votes_hidden: Boto ezkutuak (Botoak gaituta egon eta aukera hau markatuz gero, ezkutuan geldituko da botoen kopurua)
31
33
  proposals:
32
34
  actions:
33
35
  answer: Erantzuna
36
+ new: Berria
34
37
  title: Ekintzak
35
38
  admin:
36
39
  actions:
37
40
  preview: Aurreikusi
41
+ exports:
42
+ comments: Iruzkinak
43
+ proposals: Proposamenak
38
44
  models:
39
45
  proposal:
40
46
  name: Proposamena
41
47
  proposal_answers:
42
48
  edit:
43
49
  accepted: Onartuta
50
+ answer_proposal: Erantzuna
44
51
  rejected: Baztertuta
45
52
  title: 'Erantzun proposamen honi: %{title}'
46
53
  proposals:
@@ -54,6 +61,9 @@ eu:
54
61
  select_a_category: Aukeratu kategoria bat
55
62
  index:
56
63
  title: Proposamenak
64
+ new:
65
+ create: Sortu
66
+ title: Sortu proposamena
57
67
  answers:
58
68
  accepted: Onartuta
59
69
  not_answered: Erantzun gabe
@@ -33,7 +33,6 @@ fr:
33
33
  proposals:
34
34
  actions:
35
35
  answer: Répondre
36
- export: Exporter
37
36
  new: Nouveau
38
37
  title: Actions
39
38
  admin:
@@ -69,8 +68,6 @@ fr:
69
68
  create:
70
69
  error: Il y a eu des erreurs lors de la sauvegarde de la proposition.
71
70
  success: Proposition créée avec succès.
72
- exports:
73
- notice: Votre exportation est en cours. Vous recevrez un e-mail quand elle sera terminée.
74
71
  models:
75
72
  proposal:
76
73
  fields:
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  # This module contains all the domain logic associated to Decidim's Proposal
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Decidim
3
4
  module Proposals
4
5
  # This is the engine that runs on the public interface of `decidim-proposals`.
@@ -10,10 +11,6 @@ module Decidim
10
11
  routes do
11
12
  resources :proposals, only: [:index, :new, :create] do
12
13
  resources :proposal_answers, only: [:edit, :update]
13
-
14
- collection do
15
- resources :exports, only: [:create]
16
- end
17
14
  end
18
15
 
19
16
  root to: "proposals#index"
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "kaminari"
3
4
  require "social-share-button"
4
5
 
@@ -51,6 +51,26 @@ Decidim.register_feature(:proposals) do |feature|
51
51
  Decidim::Comments::Comment.where(root_commentable: proposals).count
52
52
  end
53
53
 
54
+ feature.exports :proposals do |exports|
55
+ exports.collection do |feature_instance|
56
+ Decidim::Proposals::Proposal
57
+ .where(feature: feature_instance)
58
+ .includes(:category, feature: { participatory_process: :organization })
59
+ end
60
+
61
+ exports.serializer Decidim::Proposals::ProposalSerializer
62
+ end
63
+
64
+ feature.exports :comments do |exports|
65
+ exports.collection do |feature_instance|
66
+ Decidim::Comments::Export.comments_for_resource(
67
+ Decidim::Proposals::Proposal, feature_instance
68
+ )
69
+ end
70
+
71
+ exports.serializer Decidim::Comments::CommentSerializer
72
+ end
73
+
54
74
  feature.seeds do
55
75
  Decidim::ParticipatoryProcess.all.each do |process|
56
76
  next unless process.steps.any?
@@ -4,7 +4,7 @@ module Decidim
4
4
  module Proposals
5
5
  # This class serializes a Proposal so can be exported to CSV, JSON or other
6
6
  # formats.
7
- class ProposalSerializer
7
+ class ProposalSerializer < Decidim::Exporters::Serializer
8
8
  include Rails.application.routes.url_helpers
9
9
  include Decidim::ResourceHelper
10
10
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "decidim/core/test/factories"
3
4
  require "decidim/admin/test/factories"
4
5
  require "decidim/comments/test/factories"
@@ -20,6 +21,14 @@ FactoryGirl.define do
20
21
  end
21
22
  end
22
23
 
24
+ trait :with_votes_disabled do
25
+ step_settings do
26
+ {
27
+ participatory_process.active_step.id => { votes_enabled: false }
28
+ }
29
+ end
30
+ end
31
+
23
32
  trait :with_vote_limit do
24
33
  transient do
25
34
  vote_limit 10
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "decidim/proposals/admin"
3
4
  require "decidim/proposals/engine"
4
5
  require "decidim/proposals/admin_engine"
@@ -8,5 +9,6 @@ module Decidim
8
9
  # This namespace holds the logic of the `Proposals` component. This component
9
10
  # allows users to create proposals in a participatory process.
10
11
  module Proposals
12
+ autoload :ProposalSerializer, "decidim/proposals/proposal_serializer"
11
13
  end
12
14
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decidim-proposals
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josep Jaume Rey Peroy
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2017-05-18 00:00:00.000000000 Z
13
+ date: 2017-06-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: decidim-core
@@ -18,28 +18,28 @@ dependencies:
18
18
  requirements:
19
19
  - - '='
20
20
  - !ruby/object:Gem::Version
21
- version: 0.1.0
21
+ version: 0.2.0
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
26
  - - '='
27
27
  - !ruby/object:Gem::Version
28
- version: 0.1.0
28
+ version: 0.2.0
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: decidim-comments
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
33
  - - '='
34
34
  - !ruby/object:Gem::Version
35
- version: 0.1.0
35
+ version: 0.2.0
36
36
  type: :runtime
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
40
  - - '='
41
41
  - !ruby/object:Gem::Version
42
- version: 0.1.0
42
+ version: 0.2.0
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: rectify
45
45
  requirement: !ruby/object:Gem::Requirement
@@ -88,56 +88,56 @@ dependencies:
88
88
  requirements:
89
89
  - - '='
90
90
  - !ruby/object:Gem::Version
91
- version: 0.1.0
91
+ version: 0.2.0
92
92
  type: :development
93
93
  prerelease: false
94
94
  version_requirements: !ruby/object:Gem::Requirement
95
95
  requirements:
96
96
  - - '='
97
97
  - !ruby/object:Gem::Version
98
- version: 0.1.0
98
+ version: 0.2.0
99
99
  - !ruby/object:Gem::Dependency
100
100
  name: decidim-meetings
101
101
  requirement: !ruby/object:Gem::Requirement
102
102
  requirements:
103
103
  - - '='
104
104
  - !ruby/object:Gem::Version
105
- version: 0.1.0
105
+ version: 0.2.0
106
106
  type: :development
107
107
  prerelease: false
108
108
  version_requirements: !ruby/object:Gem::Requirement
109
109
  requirements:
110
110
  - - '='
111
111
  - !ruby/object:Gem::Version
112
- version: 0.1.0
112
+ version: 0.2.0
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: decidim-results
115
115
  requirement: !ruby/object:Gem::Requirement
116
116
  requirements:
117
117
  - - '='
118
118
  - !ruby/object:Gem::Version
119
- version: 0.1.0
119
+ version: 0.2.0
120
120
  type: :development
121
121
  prerelease: false
122
122
  version_requirements: !ruby/object:Gem::Requirement
123
123
  requirements:
124
124
  - - '='
125
125
  - !ruby/object:Gem::Version
126
- version: 0.1.0
126
+ version: 0.2.0
127
127
  - !ruby/object:Gem::Dependency
128
128
  name: decidim-budgets
129
129
  requirement: !ruby/object:Gem::Requirement
130
130
  requirements:
131
131
  - - '='
132
132
  - !ruby/object:Gem::Version
133
- version: 0.1.0
133
+ version: 0.2.0
134
134
  type: :development
135
135
  prerelease: false
136
136
  version_requirements: !ruby/object:Gem::Requirement
137
137
  requirements:
138
138
  - - '='
139
139
  - !ruby/object:Gem::Version
140
- version: 0.1.0
140
+ version: 0.2.0
141
141
  description: A proposals component for decidim's participatory processes.
142
142
  email:
143
143
  - josepjaume@gmail.com
@@ -158,8 +158,8 @@ files:
158
158
  - app/commands/decidim/proposals/admin/create_proposal.rb
159
159
  - app/commands/decidim/proposals/create_proposal.rb
160
160
  - app/commands/decidim/proposals/create_proposal_export.rb
161
+ - app/controllers/concerns/decidim/proposals/orderable.rb
161
162
  - app/controllers/decidim/proposals/admin/application_controller.rb
162
- - app/controllers/decidim/proposals/admin/exports_controller.rb
163
163
  - app/controllers/decidim/proposals/admin/proposal_answers_controller.rb
164
164
  - app/controllers/decidim/proposals/admin/proposals_controller.rb
165
165
  - app/controllers/decidim/proposals/application_controller.rb
@@ -171,9 +171,7 @@ files:
171
171
  - app/forms/decidim/proposals/proposal_form.rb
172
172
  - app/helpers/decidim/proposals/application_helper.rb
173
173
  - app/helpers/decidim/proposals/map_helper.rb
174
- - app/helpers/decidim/proposals/proposal_order_helper.rb
175
174
  - app/helpers/decidim/proposals/proposal_votes_helper.rb
176
- - app/jobs/decidim/proposals/export_job.rb
177
175
  - app/models/decidim/proposals/abilities/admin_user.rb
178
176
  - app/models/decidim/proposals/abilities/current_user.rb
179
177
  - app/models/decidim/proposals/abilities/process_admin_user.rb
@@ -182,7 +180,6 @@ files:
182
180
  - app/models/decidim/proposals/proposal_vote.rb
183
181
  - app/queries/decidim/proposals/filtered_proposals.rb
184
182
  - app/services/decidim/proposals/proposal_search.rb
185
- - app/services/decidim/proposals/proposal_serializer.rb
186
183
  - app/views/decidim/proposals/admin/proposal_answers/edit.html.erb
187
184
  - app/views/decidim/proposals/admin/proposals/_form.html.erb
188
185
  - app/views/decidim/proposals/admin/proposals/index.html.erb
@@ -233,6 +230,7 @@ files:
233
230
  - lib/decidim/proposals/admin_engine.rb
234
231
  - lib/decidim/proposals/engine.rb
235
232
  - lib/decidim/proposals/feature.rb
233
+ - lib/decidim/proposals/proposal_serializer.rb
236
234
  - lib/decidim/proposals/test/factories.rb
237
235
  homepage: https://github.com/decidim/decidim
238
236
  licenses:
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
- module Decidim
3
- module Proposals
4
- module Admin
5
- # This controller allows admins to manage proposals in a participatory process.
6
- class ExportsController < Admin::ApplicationController
7
- def create
8
- # call the new proposal export command
9
- authorize! :read, Proposal
10
- authorize! :export, Proposal
11
-
12
- ExportJob.perform_later(
13
- current_user,
14
- current_feature,
15
- params[:format]
16
- )
17
-
18
- flash[:notice] = t("decidim.proposals.exports.notice")
19
- redirect_to :back
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
- module Decidim
3
- module Proposals
4
- # Simple helpers to handle proposals ordering
5
- module ProposalOrderHelper
6
- # Returns the options the user will see to order proposals
7
- def order_fields
8
- @order_fields ||= begin
9
- order_fields = [:random, :recent]
10
- order_fields << :most_voted if current_settings.votes_enabled? && !current_settings.votes_hidden?
11
- order_fields
12
- end
13
- end
14
- end
15
- end
16
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
- module Decidim
3
- module Proposals
4
- class ExportJob < ApplicationJob
5
- queue_as :default
6
-
7
- def perform(user, feature, format)
8
- proposals = Proposal
9
- .where(feature: feature)
10
- .includes(:category, feature: { participatory_process: :organization })
11
-
12
- export_data = Decidim::Exporters.const_get(format.upcase)
13
- .new(proposals, ProposalSerializer).export
14
-
15
- name = "proposals-#{I18n.localize(DateTime.now.to_date, format: :default)}-#{Time.now.seconds_since_midnight.to_i}"
16
-
17
- ExportMailer.export(user, name, export_data).deliver_now
18
- end
19
- end
20
- end
21
- end