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.
- checksums.yaml +4 -4
- data/Rakefile +1 -0
- data/app/commands/decidim/proposals/admin/answer_proposal.rb +1 -0
- data/app/commands/decidim/proposals/admin/create_proposal.rb +1 -0
- data/app/commands/decidim/proposals/create_proposal.rb +1 -0
- data/app/commands/decidim/proposals/create_proposal_export.rb +1 -0
- data/app/controllers/concerns/decidim/proposals/orderable.rb +64 -0
- data/app/controllers/decidim/proposals/admin/application_controller.rb +1 -0
- data/app/controllers/decidim/proposals/admin/proposal_answers_controller.rb +1 -0
- data/app/controllers/decidim/proposals/admin/proposals_controller.rb +1 -0
- data/app/controllers/decidim/proposals/proposals_controller.rb +2 -33
- data/app/forms/decidim/proposals/admin/proposal_answer_form.rb +1 -0
- data/app/forms/decidim/proposals/admin/proposal_form.rb +1 -0
- data/app/forms/decidim/proposals/proposal_form.rb +1 -0
- data/app/helpers/decidim/proposals/application_helper.rb +1 -1
- data/app/helpers/decidim/proposals/map_helper.rb +1 -0
- data/app/helpers/decidim/proposals/proposal_votes_helper.rb +1 -0
- data/app/models/decidim/proposals/abilities/admin_user.rb +1 -0
- data/app/models/decidim/proposals/abilities/current_user.rb +2 -1
- data/app/models/decidim/proposals/abilities/process_admin_user.rb +1 -0
- data/app/models/decidim/proposals/application_record.rb +1 -0
- data/app/models/decidim/proposals/proposal.rb +9 -1
- data/app/models/decidim/proposals/proposal_vote.rb +3 -2
- data/app/queries/decidim/proposals/filtered_proposals.rb +1 -0
- data/app/services/decidim/proposals/proposal_search.rb +1 -0
- data/app/views/decidim/proposals/admin/proposals/index.html.erb +1 -8
- data/app/views/decidim/proposals/proposals/_proposal.html.erb +1 -1
- data/app/views/decidim/proposals/proposals/_proposals.html.erb +2 -2
- data/app/views/decidim/proposals/proposals/_vote_button.html.erb +4 -10
- data/app/views/decidim/proposals/proposals/show.html.erb +2 -2
- data/config/i18n-tasks.yml +4 -1
- data/config/initializers/social_share_button.rb +1 -0
- data/config/locales/ca.yml +3 -3
- data/config/locales/en.yml +3 -4
- data/config/locales/es.yml +3 -3
- data/config/locales/eu.yml +10 -0
- data/config/locales/fr.yml +0 -3
- data/lib/decidim/proposals/admin.rb +1 -0
- data/lib/decidim/proposals/admin_engine.rb +1 -4
- data/lib/decidim/proposals/engine.rb +1 -0
- data/lib/decidim/proposals/feature.rb +20 -0
- data/{app/services → lib}/decidim/proposals/proposal_serializer.rb +1 -1
- data/lib/decidim/proposals/test/factories.rb +9 -0
- data/lib/decidim/proposals.rb +2 -0
- metadata +16 -18
- data/app/controllers/decidim/proposals/admin/exports_controller.rb +0 -24
- data/app/helpers/decidim/proposals/proposal_order_helper.rb +0 -16
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 656619a854b4e23c556abee9a2641287a8b0b9e4
|
4
|
+
data.tar.gz: fe25ef91ada0e02ce0c8a41b4155843b70de8049
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: efdb25720d97e47ce218640b118012b790755a30c13b8e1193a017e53763c8c261f5af140355c5a44864c1cf2b68dfe9ed8dc16e361e4409bea88cbc3a7d583a
|
7
|
+
data.tar.gz: 5b72de0eb3baba3c6430706cf7157ae7cdb459d3a2955af0fd5678dc42b58ca1a5ebc9b38e8b5a727473cd5300b3d4315704844fc12ce5de8221c8fabed46478
|
data/Rakefile
CHANGED
@@ -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
|
@@ -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 :
|
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
|
# 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
|
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?
|
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
|
# 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 }
|
@@ -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
|
-
|
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
|
-
<%
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
64
|
+
<p><%== translated_attribute @proposal.answer %></p>
|
65
65
|
</div>
|
66
66
|
</div>
|
67
67
|
<% end %>
|
data/config/i18n-tasks.yml
CHANGED
@@ -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
|
data/config/locales/ca.yml
CHANGED
@@ -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:
|
data/config/locales/en.yml
CHANGED
@@ -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:
|
data/config/locales/es.yml
CHANGED
@@ -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:
|
data/config/locales/eu.yml
CHANGED
@@ -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
|
data/config/locales/fr.yml
CHANGED
@@ -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 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"
|
@@ -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
|
data/lib/decidim/proposals.rb
CHANGED
@@ -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.
|
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-
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|