Skip to content

Commit

Permalink
UI for open questions
Browse files Browse the repository at this point in the history
  • Loading branch information
dzenreda committed Oct 30, 2023
1 parent 6341b6d commit 8f7cfde
Show file tree
Hide file tree
Showing 11 changed files with 231 additions and 5 deletions.
36 changes: 36 additions & 0 deletions app/assets/javascripts/custom/polls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
(function () {
"use strict";
App.Polls = {
text_input_listener: function () {
$(".text-input-form textarea").on("input", function (event) {
let submitButton = $(event.target).next();
if (submitButton.hasClass("answered")) {
submitButton.removeClass("answered");
submitButton.addClass("secondary hollow");
submitButton.val("Enviar");
}
});
},
initialize: function () {
$(".zoom-link").on("click", function (event) {
var answer;
answer = $(event.target).closest("div.answer");

if ($(answer).hasClass("medium-6")) {
$(answer).removeClass("medium-6");
$(answer).addClass("answer-divider");
if (!$(answer).hasClass("first")) {
$(answer).insertBefore($(answer).prev("div.answer"));
}
} else {
$(answer).addClass("medium-6");
$(answer).removeClass("answer-divider");
if (!$(answer).hasClass("first")) {
$(answer).insertAfter($(answer).next("div.answer"));
}
}
});
App.Polls.text_input_listener();
},
};
}).call(this);
7 changes: 7 additions & 0 deletions app/assets/stylesheets/custom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,13 @@
z-index: 1;
}

// POLLS OPEN QUESTION

.poll-question-answers {
.text-input-form {
width: 100%;
}
}
// /* This controls how many elements will be on each row of the block grid. */
// /* Set this to whatever number you need, up to the max allowed in the variable */
// $per-row: false;
Expand Down
57 changes: 57 additions & 0 deletions app/components/custom/polls/questions/answers_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<div class="poll-question-answers">
<% if question.vote_type == "open" %>
<% if can?(:answer, question) && !question.poll.voted_in_booth?(current_user) %>
<%= form_tag answer_question_path(question), remote: true, :"data-turbolinks"=>"true", id: "question-#{question.id}", class: "text-input-form" do %>
<%= text_area_tag :answer, open_answer, rows: 4, required: true %>
<% if open_answer.empty? %>
<%= submit_tag("Enviar", :class => "button secondary hollow") %>
<% else %>
<%= submit_tag("Enviado", :class => "button answered") %>
<% end %>
<% end %>
<% elsif !user_signed_in? %>
<%= form_tag answer_question_path(question), remote: true, class: "text-input-form" do %>
<%= text_area_tag :answer, nil, rows: 4, required: true, disabled: true %>
<%= submit_tag("Enviar", :class => "button secondary hollow") %>
<% end %>
<% else %>
<%= text_area_tag :answer, open_answer, rows: 4, required: true, disabled: true %>
<% end %>
<% end %>

<% if can?(:answer, question) && !question.poll.voted_in_booth?(current_user) %>
<% question_answers.each do |question_answer| %>
<% if already_answered?(question_answer) %>
<%= button_to question_answer_path(question, user_answer(question_answer)),
method: :delete,
remote: true,
title: t("poll_questions.show.voted", answer: question_answer.title),
class: "button answered",
"aria-pressed": true do %>
<%= question_answer.title %>
<% end %>
<% else %>
<%= button_to answer_question_path(question, answer: question_answer.title),
remote: true,
title: t("poll_questions.show.vote_answer", answer: question_answer.title),
class: "button secondary hollow",
"aria-pressed": false,
disabled: disable_answer?(question_answer) do %>
<%= question_answer.title %>
<% end %>
<% end %>
<% end %>
<% elsif !user_signed_in? %>
<% question_answers.each do |question_answer| %>
<%= link_to question_answer.title, new_user_session_path, class: "button secondary hollow" %>
<% end %>
<% elsif !current_user.level_two_or_three_verified? %>
<% question_answers.each do |question_answer| %>
<%= link_to question_answer.title, verification_path, class: "button secondary hollow" %>
<% end %>
<% else %>
<% question_answers.each do |question_answer| %>
<span class="button secondary hollow disabled"><%= question_answer.title %></span>
<% end %>
<% end %>
</div>
37 changes: 37 additions & 0 deletions app/components/custom/polls/questions/answers_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
class Polls::Questions::AnswersComponent < ApplicationComponent
attr_reader :question
delegate :can?, :current_user, :user_signed_in?, to: :helpers

def initialize(question)
@question = question
end

def already_answered?(question_answer)
user_answer(question_answer).present?
end

def question_answers
question.question_answers
end

def open_answer
if question.answers.nil? || question.answers.empty?
return ''
end
question.answers.by_author(current_user).first.answer
end

def user_answer(question_answer)
user_answers.find_by(answer: question_answer.title)
end

def disable_answer?(question_answer)
question.multiple? && user_answers.count == question.max_votes
end

private

def user_answers
@user_answers ||= question.answers.by_author(current_user)
end
end
2 changes: 1 addition & 1 deletion app/controllers/custom/admin/poll/questions_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require_dependency Rails.root.join("app", "controllers", "admin", "poll", "question_controller").to_s
require_dependency Rails.root.join("app", "controllers", "admin", "poll", "questions_controller").to_s

class Admin::Poll::QuestionsController
def create
Expand Down
16 changes: 16 additions & 0 deletions app/models/custom/concerns/questionable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require_dependency Rails.root.join("app", "models", "concerns", "questionable").to_s

module Questionable
private

def find_by_attributes(user, title)
case vote_type
when "unique", nil
{ author: user }
when "multiple"
{ author: user, answer: title }
when "open"
{ author: user }
end
end
end
54 changes: 54 additions & 0 deletions app/models/custom/poll/answer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
class Poll::Answer < ApplicationRecord
belongs_to :question, -> { with_hidden }, inverse_of: :answers
belongs_to :author, -> { with_hidden }, class_name: "User", inverse_of: :poll_answers

delegate :poll, :poll_id, to: :question

validates :question, presence: true
validates :author, presence: true
validates :answer, presence: true
validate :max_votes

validate :answer_inclusion_if_not_open

scope :by_author, ->(author_id) { where(author_id: author_id) }
scope :by_question, ->(question_id) { where(question_id: question_id) }

def answer_inclusion_if_not_open
if question.present? && question.vote_type != 'open'
unless question.possible_answers.include?(answer)
errors.add(:answer, 'is not included in the list of possible answers')
end
end
end

def save_and_record_voter_participation
transaction do
touch if persisted?
save!
Poll::Voter.find_or_create_by!(user: author, poll: poll, origin: "web")
end
end

def destroy_and_remove_voter_participation
transaction do
destroy!

if author.poll_answers.where(question_id: poll.question_ids).none?
Poll::Voter.find_by(user: author, poll: poll, origin: "web").destroy!
end
end
end

private

def max_votes
return if !question || question&.unique? || question.vote_type == 'open' || persisted?

author.lock!

if question.answers.by_author(author).count >= question.max_votes
errors.add(:answer, "Maximum number of votes per user exceeded")
end
end
end
17 changes: 17 additions & 0 deletions app/models/custom/votation_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class VotationType < ApplicationRecord
belongs_to :questionable, polymorphic: true

QUESTIONABLE_TYPES = %w[Poll::Question].freeze

enum vote_type: %w[unique multiple open]

validates :questionable, presence: true
validates :questionable_type, inclusion: { in: ->(*) { QUESTIONABLE_TYPES }}
validates :max_votes, presence: true, if: :max_votes_required?

private

def max_votes_required?
multiple?
end
end
2 changes: 1 addition & 1 deletion app/models/votation_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ class VotationType < ApplicationRecord

QUESTIONABLE_TYPES = %w[Poll::Question].freeze

enum vote_type: %w[unique multiple open]
enum vote_type: %w[unique multiple]

validates :questionable, presence: true
validates :questionable_type, inclusion: { in: ->(*) { QUESTIONABLE_TYPES }}
Expand Down
5 changes: 2 additions & 3 deletions config/locales/custom/es/admin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,6 @@ es:
author_date_of_birth: Fecha de nacimiento del autor
author_geozone: Localidad del autor
author_gender: Género del autor
polls:
votation_type:
open_description: "Permite que el usuario responda libremente en un cuadro de texto."
proposals:
export_list:
id: ID
Expand All @@ -74,6 +71,8 @@ es:
audits: Registro de cambios
legislation: Propuestas del Cabildo
polls:
votation_type:
open_description: "Permite que el usuario responda libremente en un cuadro de texto."
results:
export_list:
id: ID
Expand Down
3 changes: 3 additions & 0 deletions config/locales/custom/es/general.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ es:
services: Servicios Digitales
collaborative_legislation: Propuestas del Cabildo
tenerife_logo: "Cabildo Tenerife"
poll_questions:
description:
open: "Escribe aquí tu respuesta."
shared:
main_links:
cabildo: Cabildo Abierto
Expand Down

0 comments on commit 8f7cfde

Please sign in to comment.