decidim-proposals 0.1.0 → 0.2.0

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 (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