decidim-consultations 0.18.1 → 0.19.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/config/decidim_consultations_manifest.css +0 -1
- data/app/assets/config/decidim_consultations_manifest.js +1 -1
- data/app/assets/javascripts/decidim/consultations/utils_multiple.js +21 -0
- data/app/assets/javascripts/decidim/consultations/vote_dialog.js +13 -0
- data/app/cells/decidim/consultations/consultation_m/data.erb +2 -2
- data/app/cells/decidim/consultations/content_blocks/highlighted_consultations_cell.rb +1 -0
- data/app/commands/decidim/consultations/admin/create_consultation.rb +2 -0
- data/app/commands/decidim/consultations/admin/create_question.rb +2 -0
- data/app/commands/decidim/consultations/admin/create_response.rb +1 -0
- data/app/commands/decidim/consultations/admin/update_consultation.rb +1 -0
- data/app/commands/decidim/consultations/admin/update_question.rb +1 -0
- data/app/commands/decidim/consultations/admin/update_question_configuration.rb +55 -0
- data/app/commands/decidim/consultations/admin/update_response.rb +1 -0
- data/app/commands/decidim/consultations/multiple_vote_question.rb +47 -0
- data/app/controllers/concerns/decidim/consultations/admin/question_admin.rb +1 -0
- data/app/controllers/concerns/decidim/consultations/needs_question.rb +24 -2
- data/app/controllers/concerns/decidim/consultations/orderable.rb +1 -21
- data/app/controllers/decidim/consultations/admin/consultations_controller.rb +7 -1
- data/app/controllers/decidim/consultations/admin/question_configuration_controller.rb +54 -0
- data/app/controllers/decidim/consultations/admin/question_permissions_controller.rb +36 -0
- data/app/controllers/decidim/consultations/admin/questions_controller.rb +1 -0
- data/app/controllers/decidim/consultations/authorization_vote_modals_controller.rb +26 -0
- data/app/controllers/decidim/consultations/consultations_controller.rb +1 -1
- data/app/controllers/decidim/consultations/question_multiple_votes_controller.rb +39 -0
- data/app/controllers/decidim/consultations/question_votes_controller.rb +1 -1
- data/app/forms/decidim/consultations/admin/question_configuration_form.rb +27 -0
- data/app/forms/decidim/consultations/multi_vote_form.rb +41 -0
- data/app/forms/decidim/consultations/vote_form.rb +1 -0
- data/app/helpers/decidim/consultations/questions_helper.rb +25 -4
- data/app/models/decidim/consultation.rb +9 -7
- data/app/models/decidim/consultations/question.rb +26 -7
- data/app/models/decidim/consultations/vote.rb +11 -1
- data/app/permissions/decidim/consultations/admin/permissions.rb +1 -1
- data/app/permissions/decidim/consultations/permissions.rb +10 -0
- data/app/views/decidim/consultations/admin/consultations/edit.html.erb +4 -1
- data/app/views/decidim/consultations/admin/consultations/index.html.erb +2 -2
- data/app/views/decidim/consultations/admin/consultations/results.html.erb +42 -0
- data/app/views/decidim/consultations/admin/question_configuration/_form.html.erb +19 -0
- data/app/views/decidim/consultations/admin/question_configuration/edit.html.erb +12 -0
- data/app/views/decidim/consultations/admin/questions/edit.html.erb +1 -0
- data/app/views/decidim/consultations/admin/questions/index.html.erb +6 -2
- data/app/views/decidim/consultations/consultations/_consultations.html.erb +1 -1
- data/app/views/decidim/consultations/consultations/_highlighted_questions.html.erb +7 -5
- data/app/views/decidim/consultations/question_multiple_votes/_form.html.erb +14 -0
- data/app/views/decidim/consultations/question_multiple_votes/_results_rules.html.erb +14 -0
- data/app/views/decidim/consultations/question_multiple_votes/_voting_rules.html.erb +29 -0
- data/app/views/decidim/consultations/question_multiple_votes/show.html.erb +36 -0
- data/app/views/decidim/consultations/question_votes/update_vote_button.js.erb +9 -0
- data/app/views/decidim/consultations/questions/_results.html.erb +4 -0
- data/app/views/decidim/consultations/questions/_vote_button.html.erb +29 -4
- data/app/views/decidim/consultations/questions/_vote_modal_confirm.html.erb +1 -0
- data/app/views/decidim/consultations/questions/show.html.erb +1 -1
- data/app/views/layouts/decidim/_question_header.html.erb +2 -14
- data/app/views/layouts/decidim/_question_header_buttons.html.erb +11 -0
- data/app/views/layouts/decidim/admin/consultation.html.erb +4 -0
- data/app/views/layouts/decidim/admin/question.html.erb +66 -44
- data/app/views/layouts/decidim/question.html.erb +3 -3
- data/app/views/layouts/decidim/question_multivote.html.erb +9 -0
- data/config/locales/ar.yml +8 -0
- data/config/locales/ca.yml +51 -0
- data/config/locales/cs.yml +51 -0
- data/config/locales/en.yml +51 -0
- data/config/locales/es-MX.yml +13 -0
- data/config/locales/es-PY.yml +13 -0
- data/config/locales/es.yml +51 -0
- data/config/locales/fi-plain.yml +51 -0
- data/config/locales/fi.yml +51 -0
- data/config/locales/fr.yml +50 -0
- data/config/locales/hu.yml +51 -0
- data/config/locales/it.yml +15 -0
- data/config/locales/nl.yml +52 -1
- data/config/locales/sv.yml +9 -0
- data/config/locales/tr-TR.yml +5 -0
- data/db/migrate/20190702162755_add_options_to_decidim_consultations_questions.rb +8 -0
- data/db/migrate/20190710121122_add_free_instructions_field_to_consultations_questions.rb +7 -0
- data/lib/decidim/consultations/admin_engine.rb +3 -0
- data/lib/decidim/consultations/engine.rb +4 -0
- data/lib/decidim/consultations/participatory_space.rb +5 -0
- data/lib/decidim/consultations/test/factories.rb +5 -0
- data/lib/decidim/consultations/version.rb +1 -1
- metadata +29 -11
- data/app/assets/javascripts/decidim/consultations/social_share.js +0 -2
- data/app/assets/stylesheets/decidim/consultations/social_share.css.scss +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e211d930720567fda60e8679412d8b5242242f3e4910268c5621a5cb15843b7
|
4
|
+
data.tar.gz: 9f90cf27d78ae903ff0558b2351dc3f746ef4f30a2b70fdc0f1bc56a024bb6f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12c499d436225a6c0824558b793fc8807277d9b38b71f2e0a40d5567effa7d3b2fc175576fc5a4aa8414010ec48becd108bc08a29847929df6766462e35597fe
|
7
|
+
data.tar.gz: b1b4e4ca6e93212b39cf72b01a90be8746586b38db8c5d3068ab6e0b763b036b5a8740be792e4d7f81004a05488595d9177662257c6c4584b222bcbf445aed44
|
@@ -1,5 +1,5 @@
|
|
1
1
|
//= link_directory ../images/decidim/consultations
|
2
|
-
//= link decidim/consultations/social_share.js
|
3
2
|
//= link decidim/consultations/utils.js
|
3
|
+
//= link decidim/consultations/utils_multiple.js
|
4
4
|
//= link decidim/consultations/vote_dialog.js
|
5
5
|
//= link decidim/consultations/show_more.js
|
@@ -0,0 +1,21 @@
|
|
1
|
+
/* eslint-disable no-invalid-this, no-undefined */
|
2
|
+
|
3
|
+
$(document).ready(function () {
|
4
|
+
let $remainingVotesCount = $("#remaining-votes-count");
|
5
|
+
$('form .multiple_votes_form input[type="checkbox"]').on("change", function(event) {
|
6
|
+
let max = parseInt($remainingVotesCount.text(), 10);
|
7
|
+
if ($(this).is(":checked")) {
|
8
|
+
max -= 1;
|
9
|
+
}
|
10
|
+
else {
|
11
|
+
max += 1;
|
12
|
+
}
|
13
|
+
if (max < 0) {
|
14
|
+
$(this).attr("checked", false);
|
15
|
+
event.preventDefault();
|
16
|
+
}
|
17
|
+
else {
|
18
|
+
$remainingVotesCount.text(max);
|
19
|
+
}
|
20
|
+
});
|
21
|
+
});
|
@@ -30,7 +30,20 @@ $(document).ready(function () {
|
|
30
30
|
});
|
31
31
|
}
|
32
32
|
|
33
|
+
$("#confirm-vote-form").on("ajax:beforeSend", function() {
|
34
|
+
$("#confirm-vote-form-loader,#confirm-vote-form").toggleClass("hide");
|
35
|
+
});
|
36
|
+
|
33
37
|
$("#confirm-vote-form").on("ajax:success", function() {
|
34
38
|
voteConfirmDialog.foundation("close");
|
35
39
|
});
|
40
|
+
|
41
|
+
$("#confirm-vote-form").on("ajax:error", function(event) {
|
42
|
+
const error = event && event.detail && event.detail[0].error;
|
43
|
+
$("#vote-result-callout").addClass("alert").removeClass("hide warning");
|
44
|
+
$("#vote-result-callout .callout-title").text($("#vote-result-callout").data("title-ko"));
|
45
|
+
$("#vote-result-callout .callout-message").text(error || $("#vote-result-callout").data("message-ko"));
|
46
|
+
$("#confirm-vote-form-loader,#confirm-vote-form").toggleClass("hide");
|
47
|
+
voteConfirmDialog.foundation("close");
|
48
|
+
});
|
36
49
|
});
|
@@ -6,14 +6,14 @@
|
|
6
6
|
<li class="card-data__item">
|
7
7
|
<div class="card-data__item--centerblock">
|
8
8
|
<strong><%= t("activemodel.attributes.consultation.start_voting_date") %></strong>
|
9
|
-
<br
|
9
|
+
<br>
|
10
10
|
<%= start_date ? l(start_date, format: :decidim_short) : t("decidim.consultations.show.unspecified") %>
|
11
11
|
</div>
|
12
12
|
</li>
|
13
13
|
<li class="card-data__item">
|
14
14
|
<div class="card-data__item--centerblock">
|
15
15
|
<strong><%= t("activemodel.attributes.consultation.end_voting_date") %></strong>
|
16
|
-
<br
|
16
|
+
<br>
|
17
17
|
<%= end_date ? l(end_date, format: :decidim_short) : t("decidim.consultations.show.unspecified") %>
|
18
18
|
</div>
|
19
19
|
</li>
|
@@ -32,6 +32,7 @@ module Decidim
|
|
32
32
|
def voting_ends_text_for(consultation)
|
33
33
|
remaining_days = (consultation.end_voting_date - Time.zone.today).to_i
|
34
34
|
return I18n.t("voting_ends_today", scope: i18n_scope) if remaining_days.zero?
|
35
|
+
|
35
36
|
I18n.t("voting_ends_in", scope: i18n_scope, count: remaining_days)
|
36
37
|
end
|
37
38
|
end
|
@@ -21,6 +21,7 @@ module Decidim
|
|
21
21
|
# Returns nothing.
|
22
22
|
def call
|
23
23
|
return broadcast(:invalid) if form.invalid?
|
24
|
+
|
24
25
|
consultation = create_consultation
|
25
26
|
|
26
27
|
if consultation.persisted?
|
@@ -52,6 +53,7 @@ module Decidim
|
|
52
53
|
)
|
53
54
|
|
54
55
|
return consultation unless consultation.valid?
|
56
|
+
|
55
57
|
consultation.save
|
56
58
|
consultation
|
57
59
|
end
|
@@ -20,6 +20,7 @@ module Decidim
|
|
20
20
|
# Returns nothing.
|
21
21
|
def call
|
22
22
|
return broadcast(:invalid) if form.invalid?
|
23
|
+
|
23
24
|
question = create_question
|
24
25
|
|
25
26
|
if question.persisted?
|
@@ -59,6 +60,7 @@ module Decidim
|
|
59
60
|
)
|
60
61
|
|
61
62
|
return question unless question.valid?
|
63
|
+
|
62
64
|
question.save
|
63
65
|
question
|
64
66
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Consultations
|
5
|
+
module Admin
|
6
|
+
# A command that configures how many and how much questions can be voted.
|
7
|
+
class UpdateQuestionConfiguration < Rectify::Command
|
8
|
+
# Public: Initializes the command.
|
9
|
+
#
|
10
|
+
# question - the Question to update
|
11
|
+
# form - A form object with the params.
|
12
|
+
def initialize(question, form)
|
13
|
+
@question = question
|
14
|
+
@form = form
|
15
|
+
end
|
16
|
+
|
17
|
+
# Executes the command. Broadcasts these events:
|
18
|
+
#
|
19
|
+
# - :ok when everything is valid.
|
20
|
+
# - :invalid if the form wasn't valid and we couldn't proceed.
|
21
|
+
#
|
22
|
+
# Returns nothing.
|
23
|
+
def call
|
24
|
+
return broadcast(:invalid) if form.invalid?
|
25
|
+
|
26
|
+
# We don't have other question fields in this forms so any additional
|
27
|
+
# validation error will be just shown in a flash message
|
28
|
+
begin
|
29
|
+
update_question!
|
30
|
+
broadcast(:ok, question)
|
31
|
+
rescue StandardError => e
|
32
|
+
broadcast(:invalid, question, e.message)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
attr_reader :form, :question
|
39
|
+
|
40
|
+
def update_question!
|
41
|
+
question.assign_attributes(attributes)
|
42
|
+
question.save!
|
43
|
+
end
|
44
|
+
|
45
|
+
def attributes
|
46
|
+
{
|
47
|
+
max_votes: form.max_votes,
|
48
|
+
min_votes: form.min_votes,
|
49
|
+
instructions: form.instructions
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Consultations
|
5
|
+
# A command with all the business logic when a user votes a multivote question.
|
6
|
+
class MultipleVoteQuestion < Rectify::Command
|
7
|
+
# Public: Initializes the command.
|
8
|
+
#
|
9
|
+
# form - A Decidim::Consultations::MultiVoteForm object.
|
10
|
+
# current_user - The current user.
|
11
|
+
def initialize(form, current_user)
|
12
|
+
@form = form
|
13
|
+
@current_user = current_user
|
14
|
+
end
|
15
|
+
|
16
|
+
# Executes the command. Broadcasts these events:
|
17
|
+
#
|
18
|
+
# - :ok when everything is valid, together with the vote.
|
19
|
+
# - :invalid if the form wasn't valid and we couldn't proceed.
|
20
|
+
#
|
21
|
+
# Returns nothing.
|
22
|
+
def call
|
23
|
+
return broadcast(:invalid, form, form.errors[:responses].first) if form.invalid?
|
24
|
+
|
25
|
+
ActiveRecord::Base.transaction do
|
26
|
+
form.vote_forms.each do |form|
|
27
|
+
create_vote! form
|
28
|
+
end
|
29
|
+
broadcast(:ok, form)
|
30
|
+
rescue StandardError => e
|
31
|
+
broadcast(:invalid, form, e.message)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
attr_reader :form
|
38
|
+
|
39
|
+
def create_vote!(vote_form)
|
40
|
+
@form.context.current_question.votes.create!(
|
41
|
+
author: @current_user,
|
42
|
+
response: vote_form.response
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -7,8 +7,8 @@ module Decidim
|
|
7
7
|
module NeedsQuestion
|
8
8
|
def self.enhance_controller(instance_or_module)
|
9
9
|
instance_or_module.class_eval do
|
10
|
-
helper_method :current_question, :previous_question, :next_question, :
|
11
|
-
:sorted_results
|
10
|
+
helper_method :current_question, :previous_question, :next_question, :previous_published_question, :next_published_question,
|
11
|
+
:current_consultation, :current_participatory_space, :stats, :sorted_results
|
12
12
|
|
13
13
|
helper Decidim::WidgetUrlsHelper
|
14
14
|
end
|
@@ -55,6 +55,20 @@ module Decidim
|
|
55
55
|
current_consultation_questions.at(current_question_index + 1)
|
56
56
|
end
|
57
57
|
|
58
|
+
# same as next_question but for published questions only
|
59
|
+
def next_published_question
|
60
|
+
return nil if current_published_question_index + 1 >= current_consultation_published_questions.size
|
61
|
+
|
62
|
+
current_consultation_published_questions.at(current_published_question_index + 1)
|
63
|
+
end
|
64
|
+
|
65
|
+
# same as previous_question but for published questions only
|
66
|
+
def previous_published_question
|
67
|
+
return nil if (current_published_question_index - 1).negative?
|
68
|
+
|
69
|
+
current_consultation_published_questions.at(current_published_question_index - 1)
|
70
|
+
end
|
71
|
+
|
58
72
|
# Public: Finds the current Consultation given this controller's
|
59
73
|
# context.
|
60
74
|
#
|
@@ -89,9 +103,17 @@ module Decidim
|
|
89
103
|
@current_consultation_questions ||= current_question.consultation.questions.to_a
|
90
104
|
end
|
91
105
|
|
106
|
+
def current_consultation_published_questions
|
107
|
+
@current_consultation_published_questions ||= current_question.consultation.questions.published.to_a
|
108
|
+
end
|
109
|
+
|
92
110
|
def current_question_index
|
93
111
|
current_consultation_questions.find_index(current_question)
|
94
112
|
end
|
113
|
+
|
114
|
+
def current_published_question_index
|
115
|
+
current_consultation_published_questions.find_index(current_question)
|
116
|
+
end
|
95
117
|
end
|
96
118
|
end
|
97
119
|
end
|
@@ -9,29 +9,15 @@ module Decidim
|
|
9
9
|
extend ActiveSupport::Concern
|
10
10
|
|
11
11
|
included do
|
12
|
-
|
12
|
+
include Decidim::Orderable
|
13
13
|
|
14
14
|
private
|
15
15
|
|
16
|
-
# Gets how the proposals should be ordered based on the choice
|
17
|
-
# made by the user.
|
18
|
-
def order
|
19
|
-
@order ||= detect_order(params[:order]) || default_order
|
20
|
-
end
|
21
|
-
|
22
|
-
def detect_order(candidate)
|
23
|
-
available_orders.detect { |order| order == candidate }
|
24
|
-
end
|
25
|
-
|
26
16
|
# Available orders based on enabled settings
|
27
17
|
def available_orders
|
28
18
|
%w(random recent)
|
29
19
|
end
|
30
20
|
|
31
|
-
def default_order
|
32
|
-
"random"
|
33
|
-
end
|
34
|
-
|
35
21
|
def reorder(consultations)
|
36
22
|
case order
|
37
23
|
when "recent"
|
@@ -40,12 +26,6 @@ module Decidim
|
|
40
26
|
consultations.order_randomly(random_seed)
|
41
27
|
end
|
42
28
|
end
|
43
|
-
|
44
|
-
# Returns: A random float number between -1 and 1 to be used as a
|
45
|
-
# random seed at the database.
|
46
|
-
def random_seed
|
47
|
-
@random_seed ||= (params[:random_seed] ? params[:random_seed].to_f : (rand * 2 - 1))
|
48
|
-
end
|
49
29
|
end
|
50
30
|
end
|
51
31
|
end
|
@@ -44,7 +44,7 @@ module Decidim
|
|
44
44
|
render layout: "decidim/admin/consultation"
|
45
45
|
end
|
46
46
|
|
47
|
-
# PUT /admin/
|
47
|
+
# PUT /admin/consultations/:slug
|
48
48
|
def update
|
49
49
|
enforce_permission_to :update, :consultation, consultation: current_consultation
|
50
50
|
|
@@ -64,6 +64,12 @@ module Decidim
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
+
# GET /admin/consultations/:slug/results
|
68
|
+
def results
|
69
|
+
enforce_permission_to :read, :consultation, consultation: current_consultation
|
70
|
+
render layout: "decidim/admin/consultation"
|
71
|
+
end
|
72
|
+
|
67
73
|
private
|
68
74
|
|
69
75
|
def current_consultation
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Consultations
|
5
|
+
module Admin
|
6
|
+
class QuestionConfigurationController < Decidim::Consultations::Admin::ApplicationController
|
7
|
+
include QuestionAdmin
|
8
|
+
|
9
|
+
before_action :check_external_voting
|
10
|
+
|
11
|
+
def edit
|
12
|
+
enforce_permission_to :configure, :question, question: current_question
|
13
|
+
@form = question_form.from_model(current_question, current_consultation: current_consultation)
|
14
|
+
render layout: "decidim/admin/question"
|
15
|
+
end
|
16
|
+
|
17
|
+
def update
|
18
|
+
enforce_permission_to :configure, :question, question: current_question
|
19
|
+
|
20
|
+
@form = question_form
|
21
|
+
.from_params(params, question_id: current_question.id, current_consultation: current_consultation)
|
22
|
+
|
23
|
+
UpdateQuestionConfiguration.call(current_question, @form) do
|
24
|
+
on(:ok) do |question|
|
25
|
+
flash[:notice] = I18n.t("questions.update.success", scope: "decidim.admin")
|
26
|
+
redirect_to edit_question_configuration_path(question)
|
27
|
+
end
|
28
|
+
|
29
|
+
on(:invalid) do |_question, error|
|
30
|
+
flash[:error] = I18n.t("questions.update.error", scope: "decidim.admin")
|
31
|
+
flash[:error] << " (#{error})" if error
|
32
|
+
render :edit, layout: "decidim/admin/question"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def question_form
|
40
|
+
form(QuestionConfigurationForm)
|
41
|
+
end
|
42
|
+
|
43
|
+
# This is checked here (and not in permissions) to warn the user
|
44
|
+
# specifically about disabling external voting before using multivote questions
|
45
|
+
def check_external_voting
|
46
|
+
return unless current_question.external_voting
|
47
|
+
|
48
|
+
flash[:alert] = I18n.t("question_configuration.disable_external_voting", scope: "decidim.admin")
|
49
|
+
redirect_to edit_question_path(current_question)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|