From 815a526d78dcea2a3cc681f8a8a4de52f237d081 Mon Sep 17 00:00:00 2001 From: decabeza Date: Tue, 30 Aug 2022 13:13:33 +0200 Subject: [PATCH] Add `VotationType` fields to admin poll question form --- .../admin/votation_types/fields.js | 21 ++++++++++++++ app/assets/javascripts/application.js | 1 + .../poll/questions/form_component.html.erb | 8 ++++++ .../votation_types/fields_component.html.erb | 20 +++++++++++++ .../admin/votation_types/fields_component.rb | 7 +++++ .../admin/poll/questions_controller.rb | 5 ++-- app/models/concerns/questionable.rb | 1 + app/views/admin/poll/questions/show.html.erb | 15 ++++++++++ config/locales/en/activerecord.yml | 9 ++++++ config/locales/en/admin.yml | 4 +++ config/locales/es/activerecord.yml | 9 ++++++ config/locales/es/admin.yml | 4 +++ spec/system/admin/poll/questions_spec.rb | 28 +++++++++++++++++++ 13 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 app/assets/javascripts/admin/votation_types/fields.js create mode 100644 app/components/admin/votation_types/fields_component.html.erb create mode 100644 app/components/admin/votation_types/fields_component.rb diff --git a/app/assets/javascripts/admin/votation_types/fields.js b/app/assets/javascripts/admin/votation_types/fields.js new file mode 100644 index 000000000..85649e675 --- /dev/null +++ b/app/assets/javascripts/admin/votation_types/fields.js @@ -0,0 +1,21 @@ +(function() { + "use strict"; + App.AdminVotationTypesFields = { + adjustForm: function() { + if ($(this).val() === "unique") { + $(".max-votes").hide(); + $(".description-unique").show(); + $(".description-multiple").hide(); + $(".votation-type-max-votes").prop("disabled", true); + } else { + $(".max-votes").show(); + $(".description-unique").hide(); + $(".description-multiple").show(); + $(".votation-type-max-votes").prop("disabled", false); + } + }, + initialize: function() { + $(".votation-type-vote-type").on("change", App.AdminVotationTypesFields.adjustForm).trigger("change"); + } + }; +}).call(this); diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 52e178b4b..58f344977 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -167,6 +167,7 @@ var initialize_modules = function() { } App.AdminBudgetsWizardCreationStep.initialize(); App.AdminMachineLearningScripts.initialize(); + App.AdminVotationTypesFields.initialize(); App.BudgetEditAssociations.initialize(); App.BudgetHideMoney.initialize(); App.Datepicker.initialize(); diff --git a/app/components/admin/poll/questions/form_component.html.erb b/app/components/admin/poll/questions/form_component.html.erb index fc183f186..bd72edd40 100644 --- a/app/components/admin/poll/questions/form_component.html.erb +++ b/app/components/admin/poll/questions/form_component.html.erb @@ -29,6 +29,14 @@ <% end %> +
+
+ <%= f.fields_for :votation_type do |votation_f| %> + <%= render Admin::VotationTypes::FieldsComponent.new(form: votation_f) %> + <% end %> +
+
+
<%= f.submit(class: "button success expanded", value: t("shared.save")) %> diff --git a/app/components/admin/votation_types/fields_component.html.erb b/app/components/admin/votation_types/fields_component.html.erb new file mode 100644 index 000000000..f55d74579 --- /dev/null +++ b/app/components/admin/votation_types/fields_component.html.erb @@ -0,0 +1,20 @@ +
+ <%= form.enum_select :vote_type, {}, class: "votation-type-vote-type" %> +
+ +
+
+ + <%= t("admin.polls.votation_type.unique_description") %> + + +
+
+ +
+
+ <%= form.number_field :max_votes, min: 2, max: 999, class: "votation-type-max-votes" %> +
+
diff --git a/app/components/admin/votation_types/fields_component.rb b/app/components/admin/votation_types/fields_component.rb new file mode 100644 index 000000000..6fe487397 --- /dev/null +++ b/app/components/admin/votation_types/fields_component.rb @@ -0,0 +1,7 @@ +class Admin::VotationTypes::FieldsComponent < ApplicationComponent + attr_reader :form + + def initialize(form:) + @form = form + end +end diff --git a/app/controllers/admin/poll/questions_controller.rb b/app/controllers/admin/poll/questions_controller.rb index c0c8540f8..3981f652b 100644 --- a/app/controllers/admin/poll/questions_controller.rb +++ b/app/controllers/admin/poll/questions_controller.rb @@ -14,10 +14,10 @@ class Admin::Poll::QuestionsController < Admin::Poll::BaseController end def new - @polls = Poll.all proposal = Proposal.find(params[:proposal_id]) if params[:proposal_id].present? @question.copy_attributes_from_proposal(proposal) @question.poll = @poll + @question.votation_type = VotationType.new authorize! :create, @question end @@ -58,8 +58,7 @@ class Admin::Poll::QuestionsController < Admin::Poll::BaseController end def allowed_params - attributes = [:poll_id, :question, :proposal_id] - + attributes = [:poll_id, :question, :proposal_id, votation_type_attributes: [:vote_type, :max_votes]] [*attributes, translation_params(Poll::Question)] end diff --git a/app/models/concerns/questionable.rb b/app/models/concerns/questionable.rb index 12d8ce399..f7b20b8f4 100644 --- a/app/models/concerns/questionable.rb +++ b/app/models/concerns/questionable.rb @@ -3,6 +3,7 @@ module Questionable included do has_one :votation_type, as: :questionable, dependent: :destroy + accepts_nested_attributes_for :votation_type delegate :max_votes, :multiple?, :vote_type, to: :votation_type, allow_nil: true end diff --git a/app/views/admin/poll/questions/show.html.erb b/app/views/admin/poll/questions/show.html.erb index ec4e9cecc..f6c8ef32b 100644 --- a/app/views/admin/poll/questions/show.html.erb +++ b/app/views/admin/poll/questions/show.html.erb @@ -28,6 +28,21 @@ <%= link_to @question.proposal.title, proposal_path(@question.proposal) %>

<% end %> + + <% if @question.votation_type.present? %> +

+ <%= t("admin.polls.votation_type.title") %> +
+ <%= VotationType.human_attribute_name("vote_type.#{@question.vote_type}") %> +

+ <% if @question.max_votes.present? %> +

+ <%= VotationType.human_attribute_name("max_votes") %> +
+ <%= @question.max_votes %> +

+ <% end %> + <% end %>
diff --git a/config/locales/en/activerecord.yml b/config/locales/en/activerecord.yml index c9e4cd7c6..7b1311da8 100644 --- a/config/locales/en/activerecord.yml +++ b/config/locales/en/activerecord.yml @@ -145,6 +145,9 @@ en: local_census_record: one: Local census record other: Local census records + votation_type: + one: Votation type + other: Votation types attributes: budget: name: "Name" @@ -514,6 +517,12 @@ en: document_number: Document number date_of_birth: Date of birth postal_code: Postal code + votation_type: + max_votes: Maximum number of votes + vote_type: Votation type + votation_type/vote_type: + unique: Unique answer + multiple: Multiple answers errors: models: user: diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 20635ee3a..b1b68b4b8 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -1107,6 +1107,10 @@ en: alert: "This action will remove the poll and all its associated questions." success_notice: "Poll deleted successfully" unable_notice: "You cannot delete a poll that has votes" + votation_type: + title: "Votation type" + unique_description: "It's only possible to answer one time to the question." + multiple_description: "Allows to choose multiple answers. It's possible to set the maximum number of answers." questions: index: title: "Questions" diff --git a/config/locales/es/activerecord.yml b/config/locales/es/activerecord.yml index b7cf2fc07..99ce9c5b0 100644 --- a/config/locales/es/activerecord.yml +++ b/config/locales/es/activerecord.yml @@ -145,6 +145,9 @@ es: local_census_record: one: Registro del censo local other: Registros del censo local + votation_type: + one: Tipo de votación + other: Tipos de votación attributes: budget: name: "Nombre" @@ -514,6 +517,12 @@ es: document_number: Número de documento date_of_birth: Fecha de nacimiento postal_code: Código postal + votation_type: + max_votes: Número máximo de votos + vote_type: Tipo de votación + votation_type/vote_type: + unique: Respuesta única + multiple: Respuesta múltiple errors: models: user: diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index d40af634b..08caffd41 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -1106,6 +1106,10 @@ es: alert: "Esta acción eliminará la votación y todas sus preguntas asociadas." success_notice: "Votación eliminada correctamente" unable_notice: "No se pueden eliminar votaciones con votos" + votation_type: + title: "Tipo de votación" + unique_description: "Solo se puede responder a la pregunta con una única respuesta." + multiple_description: "Permite elegir más de una respuesta. Se puede elegir el número máximo de respuestas." questions: index: title: "Preguntas de votaciones" diff --git a/spec/system/admin/poll/questions_spec.rb b/spec/system/admin/poll/questions_spec.rb index 99c81a34c..d6f559fd7 100644 --- a/spec/system/admin/poll/questions_spec.rb +++ b/spec/system/admin/poll/questions_spec.rb @@ -65,6 +65,34 @@ describe "Admin poll questions", :admin do expect(page).not_to have_link "Create question" end + + describe "With votation type" do + before do + poll = create(:poll, :future) + visit admin_poll_path(poll) + click_link "Create question" + end + + scenario "Unique" do + fill_in "Question", with: "Question with unique answer" + select "Unique answer", from: "Votation type" + + click_button "Save" + + expect(page).to have_content "Question with unique answer" + expect(page).to have_content "Unique answer" + end + + scenario "Multiple" do + fill_in "Question", with: "Question with multiple answers" + select "Multiple answers", from: "Votation type" + fill_in "Maximum number of votes", with: 6 + click_button "Save" + + expect(page).to have_content "Question with multiple answers" + expect(page).to have_content "Multiple answers" + end + end end scenario "Create from proposal" do