Add Admin changes to create Poll:Questions with votation type

This commit is contained in:
lalo
2019-05-29 17:57:20 +02:00
committed by Javi Martín
parent 7c9c50f4c6
commit 23d36835d7
16 changed files with 485 additions and 16 deletions

View File

@@ -87,6 +87,7 @@
//= require cookies
//= require columns_selector
//= require budget_edit_associations.js.coffee
//= require votations
var initialize_modules = function() {
App.Answers.initialize();
@@ -140,6 +141,8 @@ var initialize_modules = function() {
if ( $('#js-columns-selector').length )
App.ColumnsSelector.initialize();
App.BudgetEditAssociations.initialize();
if ( $("#votation_type_enum_type").length )
App.Votations.initialize();
};
$(function(){

View File

@@ -0,0 +1,45 @@
App.Votations =
checkMaxVotes: ->
if $("#votation_type_enum_type").val() == "0"
$(".js-max_votes").hide()
$("#max_votes").attr(disabled: true)
else
$(".js-max_votes").show()
$("#max_votes").attr(disabled: false)
checkPrioritization: ->
if $("#votation_type_enum_type").val() == "2"
$(".js-prioritization_type").show()
$("#prioritization_type").attr(disabled: false)
else
$(".js-prioritization_type").hide()
$("#prioritization_type").attr(disabled: true)
checkMaxGroups: ->
if $("#votation_type_enum_type").val() == "7" || $("#votation_type_enum_type").val() == "8"
$(".js-max_group_votes").show()
$("#max_groups_answers").attr(disabled: false)
else
$(".js-max_group_votes").hide()
$("#max_groups_answers").attr(disabled: true)
setTraduction: (response) ->
console.log response
$(".js-description_text").text(response["traduction"])
updateChecks: () ->
App.Votations.checkMaxVotes()
App.Votations.checkPrioritization()
App.Votations.checkMaxGroups()
initialize: ->
App.Votations.updateChecks()
$("#votation_type_enum_type").on
change: ->
App.Votations.updateChecks()
url = "/admin/get_options_traductions.json"
params = { enum_type: $("#votation_type_enum_type").val() }
$.get(url, params, (response) -> App.Votations.setTraduction response, "json")
false

View File

@@ -786,6 +786,10 @@ code {
font-weight: bold;
}
.hidden {
display: none;
}
table {
.callout {
@@ -796,6 +800,15 @@ table {
}
}
.info-type {
background-color: #ccf5ff;
padding: 15px;
}
.margin-description {
margin-top: rem-calc(20);
}
// 07. Legislation
// --------------

View File

@@ -17,6 +17,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
before_action :load_change_log, only: [:show]
def index
load_tags
respond_to do |format|
format.html
format.js

View File

@@ -22,6 +22,7 @@ class Admin::Poll::QuestionsController < Admin::Poll::BaseController
def create
@question.author = @question.proposal.try(:author) || current_user
@question.votation_type = VotationType.build_by_type(@question, params[:votation_type])
if @question.save
redirect_to admin_question_path(@question)
@@ -53,11 +54,18 @@ class Admin::Poll::QuestionsController < Admin::Poll::BaseController
redirect_to admin_questions_path, notice: notice
end
def get_options_traductions
render json: {
traduction: t("polls.index.descriptions.#{VotationType.enum_types.key params[:enum_type].to_i}")
}
end
private
def question_params
attributes = [:poll_id, :question, :proposal_id]
params.require(:poll_question).permit(*attributes, translation_params(Poll::Question))
params.require(:poll_question).permit(*attributes, translation_params(Poll::Question),
:votation_type, :max_votes, :prioritization_type, :max_groups_answers)
end
def search_params

View File

@@ -78,8 +78,8 @@ module Abilities
can [:search, :create, :index, :destroy], ::Poll::Officer
can [:create, :destroy, :manage], ::Poll::BoothAssignment
can [:create, :destroy], ::Poll::OfficerAssignment
can [:read, :create, :update], Poll::Question
can :destroy, Poll::Question # , comments_count: 0, votes_up: 0
can [:read, :create, :update, :get_options_traductions], Poll::Question
can :destroy, Poll::Question
can :manage, SiteCustomization::Page
can :manage, SiteCustomization::Image

View File

@@ -25,6 +25,38 @@
<%= translations_form.text_field :title %>
<% end %>
<% if !@question.persisted? %>
<%= fields_for :votation_type do |votation_f| %>
<div class="small-12 medium-6">
<%= votation_f.select :enum_type,
options_for_select(VotationType.enum_types.map {|k, v| [t(k, scope: :enum_type), v]},
params.dig(:votation_type, :enum_type)), default: 0,
disabled: @question.persisted?, label: t("enum_type.title") %>
</div>
<div class="info-type">
<span class="js-description_text">
<%= t("polls.index.descriptions.unique") %>
</span>
<div class="small-12 medium-6 margin-description js-max_votes hidden ">
<%= votation_f.number_field :max_votes, min: 1, max: 999,
value: params.dig(:votation_type, :max_votes),
label: t("question.max_votes") %>
</div>
<div class="small-12 medium-6 js-prioritization_type hidden">
<%= votation_f.select :prioritization_type,
options_for_select(VotationType.prioritization_types.map {|k, v| [t(k, scope: :prioritization_type), v]},
params.dig(:votation_type, :prioritization_type) ), default: 0,
disabled: @question.persisted?, label: t("prioritization_type.title") %>
</div>
<div class="small-12 medium-6 js-max_group_votes hidden">
<%= votation_f.number_field :max_groups_answers, min: 1, max: 999,
value: params.dig(:votation_type, :max_groups_answers), label: t("question.max_group_answers") %>
</div>
</div>
<% end %>
<% end %>
<div class="small-12 medium-4 large-2 margin-top">
<%= f.submit(class: "button success expanded", value: t("shared.save")) %>
</div>

View File

@@ -26,6 +26,35 @@
<%= link_to @question.proposal.title, proposal_path(@question.proposal) %>
</p>
<% end %>
<% unless @question.votation_type.nil? %>
<p>
<strong><%= t("question.votation_type") %></strong>
<br>
<%= t("enum_type.#{@question.votation_type.enum_type}") %>
</p>
<% if !@question.votation_type.max_votes.nil? %>
<p>
<strong><%= t("question.max_votes") %></strong>
<br>
<%= @question.votation_type.max_votes %>
</p>
<% end %>
<% if !@question.votation_type.prioritization_type.nil? %>
<p>
<strong><%= t("prioritization_type.title") %></strong>
<br>
<%= t("prioritization_type.#{@question.votation_type.prioritization_type}") %>
</p>
<% end %>
<% if !@question.votation_type.max_groups_answers.nil? %>
<p>
<strong><%= t("question.max_group_answers") %></strong>
<br>
<%= @question.votation_type.max_groups_answers %>
</p>
<% end %>
<% end %>
</div>
</div>

View File

@@ -0,0 +1,40 @@
<div class="polls-results-stats">
<div class="row margin">
<div class="small-12 medium-3 column">
<p><strong><%= t("polls.show.results.title") %></strong></p>
<ul class="menu vertical">
<%- @poll.questions.each do |question| %>
<li><%= link_to question.title, "##{question.title.parameterize}" %></li>
<% end %>
</ul>
</div>
<div class="small-12 medium-9 column">
<%- @poll.questions.each do |question| %>
<h3 id="<%= question.title.parameterize %>"><%= question.title %></h3>
<table id="question_<%= question.id %>_results_table">
<tbody>
<%- question.question_answers.visibles.each do |answer| %>
<tr scope="col" <%= answer.most_voted? ? "class=win" : "" %>>
<td>
<% if answer.most_voted %>
<span class="show-for-sr"><%= t("polls.show.results.most_voted_answer") %></span>
<% end %>
<%= answer.title %>
</td>
<td id="answer_<%= answer.id %>_result" <%= answer.most_voted? ? "class=win" : "" %>>
<%= answer.total_votes %>
<% unless question.enum_type == "positive_negative_open" %>
(<%= answer.total_votes_percentage.round(2) %>%)
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
</div>
</div>
</div>

View File

@@ -11,10 +11,14 @@
</div>
<% end %>
<% if @partial_results.present? %>
<%= render "recount", resource: @poll %>
<%= render "result" %>
<%= render "results_by_booth" %>
<% if @poll.questions.any? { |question| question.votation_type.present? } %>
<%= render "votation_types_results" %>
<% else %>
<% if @partial_results.present? %>
<%= render "recount", resource: @poll %>
<%= render "result" %>
<%= render "results_by_booth" %>
<% end %>
<% end %>
<% if @poll.voters.any? %>

View File

@@ -556,6 +556,7 @@ en:
index:
title: Polls
create: Create poll
succesfull: Answer added succesfully
count:
one: You have created %{count} poll.
other: You have created %{count} polls.
@@ -648,6 +649,17 @@ en:
title: Help about voting
description: Citizens' polls are a participatory mechanism by which citizens with voting rights can make direct decisions
no_polls: "There are no open votings."
max_votes_reached: "You have already made the maximum number of votes. Thank you very much for participating"
descriptions:
unique: It's only possible to answer one time to the question.
multiple: Allows to choose multiple answers. It's possible to set the maximum number of answers.
prioritized: Allows to choose more than one answer and they will be prioritized. It's possible to set the maximum number of answers chosen and the answer count type.
positive_open: Allows to vote positively a maximum number of times to questions. It's possible to set the maximum number of answers and add other answers.
positive_negative_open: Allows to vote positively and negatively a maximum number of times to questions. It's possible to set the maximum number of answers and add other answers.
answer_couples_open: Allows to vote a maximum number of times to couples of possible answers. It's possible to set the maximum number of couples and add other answers.
answer_couples_closed: Allows to vote a maximum number of times to couples of possible answers. It's possible to set the maximum number of couples and it's not possible to add other answers.
answer_set_open: Allows to vote a maximum number of answers to a group of them. It's possible to set the maximum number of answers, the size of the group and add other answers.
answer_set_closed: Allows to vote a maximum number of answers to a group of them. It's possible to set the maximum number of answers and the size of the group.
show:
already_voted_in_booth: "You have already participated in a physical booth. You can not participate again."
already_voted_in_web: "You have already participated in this poll. If you vote again it will be overwritten."
@@ -689,6 +701,18 @@ en:
show:
vote_answer: "Vote %{answer}"
voted: "You have voted %{answer}"
add_answer: "Add answer"
description:
multiple: "You can select a maximum of %{maximum} answers."
positive_negative_open: "You can vote positive or negative a maximum of %{maximum} answers. And you can add your own answers."
answer_couples_open: "Choose an option from the following pair. You can choose a maximum of %{maximum} answers."
answer_couples_closed: "Choose an option from the following pair. You can choose a maximum of %{maximum} answers."
answer_set_open: "You can choose a maximum of %{maximum} answers."
answer_set_closed: "You can choose a maximum of %{maximum} answers."
prioritized: "You can select a maximum of %{maximum} answers. This question will use the %{system} system for count."
positive_open: "You can select a maximum of %{maximum} answers and add your own answers."
unique: ""
read_more_about: "Read more about:"
proposal_notifications:
new:
title: "Send message"
@@ -992,3 +1016,22 @@ en:
surveys: Surveys
poll:
take_part: Take part from %{from} to %{to}
question:
max_votes: Maximum number of votes
max_group_answers: Maximum number of answers in the set
votation_type: Votation type
enum_type:
title: Votation type
unique: Unique answer, closed
multiple: Multiple answers, closed
prioritized: Multiple prioritized answer, closed
positive_open: Votable positive, open
positive_negative_open: Votable positive and negative, open
answer_couples_open: Couples of answers, open
answer_couples_closed: Couples of answers, closed
answer_set_open: Set of answers, open
answer_set_closed: Set of answers, closed
prioritization_type:
title: Prioritization type
borda: Borda votation
dowdall: Dowdall votation

View File

@@ -556,6 +556,7 @@ es:
index:
title: Encuestas
create: Crear encuesta
succesfull: Respuesta añadida correctamente.
count:
one: Has creado %{count} encuesta.
other: Has creado %{count} encuestas.
@@ -646,6 +647,17 @@ es:
title: Ayuda sobre las votaciones
description: Las votaciones ciudadanas son un mecanismo de participación por el que la ciudadanía con derecho a voto puede tomar decisiones de forma directa.
no_polls: "No hay votaciones abiertas."
max_votes_reached: "Ya has realizado el número máximo de votos. Muchas gracias por participar"
descriptions:
unique: Solo se puede responder a la pregunta con una única respuesta.
multiple: Permite elegir más de una respuesta. Se puede elegir el número máximo de respuestas.
prioritized: Permite elegir mas de una respuesta, que a su vez se podran ordenar por prioridad. Se puede elegir el número máximo de respuestas y que tipo de recuento se utilizará en la priorización.
positive_open: Permite votar positivamente a un número máximo de respuestas. Se puede elegir el número máximo y los usuarios podran añadir resuestas.
positive_negative_open: Permite votar positiva y negativamente a un máximo de respuestas. Se puede elegir el número máximo y los usuarios podran añadir resuestas.
answer_couples_open: Permite votar a un número maximo de pares de respuestas. Se puede elegir el número maximo de pares y los usuarios podran añadir respuestas.
answer_couples_closed: Permite votar a un número maximo de pares de respuestas. Se puede elegir el número maximo de pares y los usuarios NO podran añadir respuestas.
answer_set_open: Permite votar un número máximo de respuestas en un conjunto de ellas. Se puede elegir el numero máximo de respuestas y el número de respuestas que hay en el conjunto. Los usuarios podran añadir respuestas.
answer_set_closed: Permite votar un número máximo de respuestas en un conjunto de ellas. Se puede elegir el numero máximo de respuestas y el número de respuestas que hay en el conjunto.
show:
already_voted_in_booth: "Ya has participado en esta votación en urnas presenciales, no puedes volver a participar."
already_voted_in_web: "Ya has participado en esta votación. Si vuelves a votar se sobreescribirá tu resultado anterior."
@@ -687,6 +699,17 @@ es:
show:
vote_answer: "Votar %{answer}"
voted: "Has votado %{answer}"
add_answer: "Añadir respuesta"
description:
multiple: "Puedes seleccionar un máximo de %{maximum} respuestas."
positive_negative_open: "Puedes votar, positiva o negativamente, un máximo de %{maximum} respuestas. Puedes añadir tus propias respuestas."
multiple: "Puedes seleccionar un máximo de %{maximum} respuestas"
answer_couples_open: "Elige una opción entre el siguiente par. Puedes elegir un máximo de %{maximum} respuestas"
answer_couples_closed: "Elige una opción entre el siguiente par. Puedes elegir un máximo de %{maximum} respuestas"
prioritized: "Puedes seleccionar un máximo de %{maximum} respuestas. Esta pregunta utilizara el método %{system} para el recuento."
positive_open: "Puedes seleccionar un máximo de %{maximum} respuestas y añadir tus propias respuestas."
unique: ""
read_more_about: "Leer más:"
proposal_notifications:
new:
title: "Enviar mensaje"
@@ -990,3 +1013,22 @@ es:
surveys: Encuestas
poll:
take_part: Participa del %{from} al %{to}
question:
max_votes: Número máximo de votos
max_group_answers: Número máximo de respuestas en el conjunto
votation_type: Tipo de votación
enum_type:
title: Tipo de votación
unique: Respuesta única, cerrada
multiple: Respuesta múltiple, cerrada
prioritized: Respuesta múltiple priorizada, cerrada
positive_open: Respuestas votables positivamente, abiertas
positive_negative_open: Respuestas votables positiva y negativamente, abiertas
answer_couples_open: Respuestas a pares, abiertas
answer_couples_closed: Respuestas a pares, cerradas
answer_set_open: Conjunto de respuestas, abiertas
answer_set_closed: Conjunto de respuestas, cerradas
prioritization_type:
title: Tipo de priorizacion
borda: Votación con recuento Borda
dowdall: Votación con recuento Dowdall

View File

@@ -163,6 +163,7 @@ namespace :admin do
end
resource :active_polls, only: [:create, :edit, :update]
get :get_options_traductions, controller: "questions"
end
resources :verifications, controller: :verifications, only: :index do

View File

@@ -248,14 +248,17 @@ describe "Admin polls" do
scenario "Question list", :js do
poll = create(:poll)
question = create(:poll_question, poll: poll)
votation_type_question = create(:poll_question_unique, poll: poll)
other_question = create(:poll_question)
visit admin_poll_path(poll)
expect(page).to have_content "Questions (1)"
expect(page).to have_content "Questions (2)"
expect(page).to have_content question.title
expect(page).to have_content votation_type_question.title
expect(page).not_to have_content other_question.title
expect(page).not_to have_content "There are no questions assigned to this poll"
end
end

View File

@@ -19,6 +19,7 @@ describe "Admin poll questions" do
question1 = create(:poll_question, poll: poll1)
question2 = create(:poll_question, poll: poll2)
question3 = create(:poll_question, poll: poll3, proposal: proposal)
question4 = create(:poll_question_unique, poll: poll1)
visit admin_poll_path(poll1)
expect(page).to have_content(poll1.name)
@@ -30,6 +31,13 @@ describe "Admin poll questions" do
expect(page).to have_content("Delete")
end
within("#poll_question_#{question4.id}") do
expect(page).to have_content(question4.title)
expect(page).to have_content("Edit answers")
expect(page).to have_content("Edit")
expect(page).to have_content("Delete")
end
visit admin_poll_path(poll2)
expect(page).to have_content(poll2.name)
@@ -52,16 +60,35 @@ describe "Admin poll questions" do
end
end
scenario "Show" do
geozone = create(:geozone)
poll = create(:poll, geozone_restricted: true, geozone_ids: [geozone.id])
question = create(:poll_question, poll: poll)
context "Show" do
scenario "Without Votation type" do
geozone = create(:geozone)
poll = create(:poll, geozone_restricted: true, geozone_ids: [geozone.id])
question = create(:poll_question, poll: poll)
visit admin_poll_path(poll)
click_link "#{question.title}"
visit admin_poll_path(poll)
click_link question.title
expect(page).to have_content(question.title)
expect(page).to have_content(question.author.name)
expect(page).to have_content(question.title)
expect(page).to have_content(question.author.name)
expect(page).not_to have_content("Votation type")
end
scenario "With Votation type" do
geozone = create(:geozone)
poll = create(:poll, geozone_restricted: true, geozone_ids: [geozone.id])
question = create(:poll_question_multiple, poll: poll)
visit admin_poll_path(poll)
click_link "#{question.title}"
expect(page).to have_content(question.title)
expect(page).to have_content(question.author.name)
expect(page).to have_content("Votation type")
expect(page).to have_content("Multiple")
expect(page).to have_content("Maximum number of votes")
expect(page).to have_content("5")
end
end
scenario "Create" do
@@ -123,6 +150,179 @@ describe "Admin poll questions" do
expect(page).to have_content(proposal.title)
end
context "create with votation type" do
before do
poll = create(:poll, name: "Movies")
visit admin_poll_path(poll)
click_link "Create question"
end
scenario "unique" do
title = "unique question"
fill_in "Question", with: title
select "Unique answer, closed", from: "votation_type_enum_type"
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Unique answer, closed")
end
scenario "multiple" do
title = "multiple question"
fill_in "Question", with: title
select "Multiple answers, closed", from: "votation_type_enum_type"
expect(page).to have_content("Maximum number of votes")
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of votes", with: 6
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Multiple answers, closed")
end
scenario "prioritized" do
title = "prioritized question"
fill_in "Question", with: title
select "Multiple prioritized answer, closed", from: "votation_type_enum_type"
expect(page).to have_content("Maximum number of votes")
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of votes", with: 6
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Multiple prioritized answer, closed")
end
scenario "positive_open" do
title = "positive open question"
fill_in "Question", with: title
select "Votable positive, open", from: "votation_type_enum_type"
expect(page).to have_content("Maximum number of votes")
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of votes", with: 6
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Votable positive, open")
end
scenario "positive_negative_open" do
title = "positive negative open question"
fill_in "Question", with: title
select "Votable positive and negative, open", from: "votation_type_enum_type"
expect(page).to have_content("Maximum number of votes")
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of votes", with: 6
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Votable positive and negative, open")
end
scenario "answer_couples_open" do
title = "answer couples open question"
fill_in "Question", with: title
select "Couples of answers, open", from: "votation_type_enum_type"
expect(page).to have_content("Maximum number of votes")
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of votes", with: 6
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Couples of answers, open")
end
scenario "answer_couples_closed" do
title = "answer couples closed question"
fill_in "Question", with: title
select "Couples of answers, closed", from: "votation_type_enum_type"
expect(page).to have_content("Maximum number of votes")
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of votes", with: 6
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Couples of answers, closed")
end
scenario "answer_set_open" do
title = "answer set open question"
fill_in "Question", with: title
select "Set of answers, open", from: "votation_type_enum_type"
expect(page).to have_content("Maximum number of votes")
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of votes", with: 6
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of answers in the set", with: 3
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Set of answers, open")
end
scenario "answer_set_closed" do
title = "answer set closed question"
fill_in "Question", with: title
select "Set of answers, closed", from: "votation_type_enum_type"
expect(page).to have_content("Maximum number of votes")
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of votes", with: 6
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of answers in the set", with: 3
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Set of answers, closed")
end
end
scenario "Update" do
poll = create(:poll)
question1 = create(:poll_question, poll: poll)

View File

@@ -88,6 +88,11 @@ describe Abilities::Administrator do
it { should be_able_to(:stats, poll) }
it { should be_able_to(:results, poll) }
it { should be_able_to(:read, Poll::Question)}
it { should be_able_to(:create, Poll::Question)}
it { should be_able_to(:update, Poll::Question)}
it { should be_able_to(:get_options_traductions, Poll::Question)}
it { is_expected.to be_able_to :manage, Dashboard::AdministratorTask }
it { is_expected.to be_able_to :manage, dashboard_administrator_task }
end