Merge pull request #5537 from consuldemocracy/rename_question_answer_to_option

Rename Poll::Question::Answer to Poll::Question::Option
This commit is contained in:
Javi Martín
2024-06-14 15:19:39 +02:00
committed by GitHub
125 changed files with 827 additions and 815 deletions

View File

@@ -1,30 +0,0 @@
(function() {
"use strict";
App.Answers = {
initializeAnswers: function(answers) {
$(answers).on("cocoon:after-insert", function(e, new_answer) {
var given_order;
given_order = App.Answers.maxGivenOrder(answers) + 1;
$(new_answer).find("[name$='[given_order]']").val(given_order);
});
},
maxGivenOrder: function(answers) {
var max_order;
max_order = 0;
$(answers).find("[name$='[given_order]']").each(function(index, answer) {
var value;
value = parseFloat($(answer).val());
max_order = value > max_order ? value : max_order;
});
return max_order;
},
nestedAnswers: function() {
$(".js-answers").each(function(index, answers) {
App.Answers.initializeAnswers(answers);
});
},
initialize: function() {
App.Answers.nestedAnswers();
}
};
}).call(this);

View File

@@ -89,7 +89,7 @@
//= require markdown_editor //= require markdown_editor
//= require html_editor //= require html_editor
//= require cocoon //= require cocoon
//= require answers //= require options
//= require questions //= require questions
//= require legislation_admin //= require legislation_admin
//= require legislation //= require legislation
@@ -129,7 +129,7 @@
var initialize_modules = function() { var initialize_modules = function() {
"use strict"; "use strict";
App.Answers.initialize(); App.Options.initialize();
App.Questions.initialize(); App.Questions.initialize();
App.Comments.initialize(); App.Comments.initialize();
App.ParticipationNotAllowed.initialize(); App.ParticipationNotAllowed.initialize();

View File

@@ -0,0 +1,30 @@
(function() {
"use strict";
App.Options = {
initializeOptions: function(options) {
$(options).on("cocoon:after-insert", function(e, new_option) {
var given_order;
given_order = App.Options.maxGivenOrder(options) + 1;
$(new_option).find("[name$='[given_order]']").val(given_order);
});
},
maxGivenOrder: function(options) {
var max_order;
max_order = 0;
$(options).find("[name$='[given_order]']").each(function(index, option) {
var value;
value = parseFloat($(option).val());
max_order = value > max_order ? value : max_order;
});
return max_order;
},
nestedOptions: function() {
$(".js-options").each(function(index, options) {
App.Options.initializeOptions(options);
});
},
initialize: function() {
App.Options.nestedOptions();
}
};
}).call(this);

View File

@@ -3,20 +3,20 @@
App.Polls = { App.Polls = {
initialize: function() { initialize: function() {
$(".zoom-link").on("click", function(event) { $(".zoom-link").on("click", function(event) {
var answer; var option;
answer = $(event.target).closest("div.answer"); option = $(event.target).closest("div.option");
if ($(answer).hasClass("medium-6")) { if ($(option).hasClass("medium-6")) {
$(answer).removeClass("medium-6"); $(option).removeClass("medium-6");
$(answer).addClass("answer-divider"); $(option).addClass("option-divider");
if (!$(answer).hasClass("first")) { if (!$(option).hasClass("first")) {
$(answer).insertBefore($(answer).prev("div.answer")); $(option).insertBefore($(option).prev("div.option"));
} }
} else { } else {
$(answer).addClass("medium-6"); $(option).addClass("medium-6");
$(answer).removeClass("answer-divider"); $(option).removeClass("option-divider");
if (!$(answer).hasClass("first")) { if (!$(option).hasClass("first")) {
$(answer).insertAfter($(answer).next("div.answer")); $(option).insertAfter($(option).next("div.option"));
} }
} }
}); });

View File

@@ -3,7 +3,7 @@
App.Questions = { App.Questions = {
nestedQuestions: function() { nestedQuestions: function() {
$(".js-questions").on("cocoon:after-insert", function(e, new_question) { $(".js-questions").on("cocoon:after-insert", function(e, new_question) {
App.Answers.initializeAnswers($(new_question).find(".js-answers")); App.Options.initializeOptions($(new_question).find(".js-options"));
}); });
}, },
initialize: function() { initialize: function() {

View File

@@ -6,7 +6,7 @@
update: function() { update: function() {
var new_order; var new_order;
new_order = $(this).sortable("toArray", { new_order = $(this).sortable("toArray", {
attribute: "data-answer-id" attribute: "data-option-id"
}); });
$.ajax({ $.ajax({
url: $(this).data("js-url"), url: $(this).data("js-url"),

View File

@@ -423,7 +423,7 @@
margin-bottom: $line-height; margin-bottom: $line-height;
} }
.answer-fields { .option-fields {
background: #fbfbfb; background: #fbfbfb;
border: 1px solid $border; border: 1px solid $border;
margin-bottom: $line-height; margin-bottom: $line-height;

View File

@@ -1597,7 +1597,7 @@ $font-awesome-icons: (
} }
.configure-link, .configure-link,
.answers-link { .options-link {
@include has-fa-icon(tools, solid); @include has-fa-icon(tools, solid);
} }

View File

@@ -1400,7 +1400,7 @@
} }
.poll-more-info, .poll-more-info,
.poll-more-info-answers { .poll-more-info-options {
.read-more { .read-more {
margin-bottom: $line-height; margin-bottom: $line-height;
@@ -1416,7 +1416,7 @@
border-top: 1px solid #eee; border-top: 1px solid #eee;
} }
.poll-more-info-answers { .poll-more-info-options {
@include full-width-background; @include full-width-background;
@include full-width-border(top, 1px solid #eee); @include full-width-border(top, 1px solid #eee);
@include full-width-border(bottom, 1px solid #eee); @include full-width-border(bottom, 1px solid #eee);
@@ -1426,14 +1426,14 @@
border-right: 2px solid; border-right: 2px solid;
} }
.answer-divider { .option-divider {
border-bottom: 2px solid; border-bottom: 2px solid;
border-right: 0 !important; border-right: 0 !important;
margin-bottom: $line-height; margin-bottom: $line-height;
padding-bottom: $line-height; padding-bottom: $line-height;
} }
.answer-description { .option-description {
height: 100%; height: 100%;
&.short { &.short {
@@ -1544,7 +1544,7 @@
} }
} }
.poll-question-answers { .poll-question-options {
@include flex-with-gap($line-height * 0.25); @include flex-with-gap($line-height * 0.25);
flex-wrap: wrap; flex-wrap: wrap;

View File

@@ -89,7 +89,7 @@ class Admin::ActionComponent < ApplicationComponent
end end
def default_path def default_path
if %i[answers configure destroy preview show].include?(action.to_sym) if %i[configure destroy options preview show].include?(action.to_sym)
namespaced_polymorphic_path(namespace, record) namespaced_polymorphic_path(namespace, record)
else else
namespaced_polymorphic_path(namespace, record, { action: action }.merge(request.query_parameters)) namespaced_polymorphic_path(namespace, record, { action: action }.merge(request.query_parameters))

View File

@@ -39,8 +39,8 @@ class Admin::MenuComponent < ApplicationComponent
end end
def polls? def polls?
controller.class.module_parent == Admin::Poll::Questions::Answers || controller.class.module_parent == Admin::Poll::Questions::Options ||
%w[polls active_polls recounts results questions answers].include?(controller_name) && %w[polls active_polls recounts results questions options].include?(controller_name) &&
action_name != "booth_assignments" action_name != "booth_assignments"
end end
@@ -62,7 +62,7 @@ class Admin::MenuComponent < ApplicationComponent
controllers_names = ["pages", "banners", "information_texts", "documents", "images", "content_blocks"] controllers_names = ["pages", "banners", "information_texts", "documents", "images", "content_blocks"]
(controllers_names.include?(controller_name) || homepage? || pages?) && (controllers_names.include?(controller_name) || homepage? || pages?) &&
controller.class.module_parent != Admin::Poll::Questions::Answers controller.class.module_parent != Admin::Poll::Questions::Options
end end
def homepage? def homepage?
@@ -515,7 +515,7 @@ class Admin::MenuComponent < ApplicationComponent
[ [
t("admin.menu.site_customization.images"), t("admin.menu.site_customization.images"),
admin_site_customization_images_path, admin_site_customization_images_path,
controller_name == "images" && controller.class.module_parent != Admin::Poll::Questions::Answers controller_name == "images" && controller.class.module_parent != Admin::Poll::Questions::Options
] ]
end end

View File

@@ -1,14 +0,0 @@
class Admin::Poll::Questions::Answers::Documents::IndexComponent < ApplicationComponent
attr_reader :answer
use_helpers :can?
def initialize(answer)
@answer = answer
end
private
def documents
@documents ||= @answer.class.find(@answer.id).documents
end
end

View File

@@ -1 +0,0 @@
<%= render Admin::AllowedTableActionsComponent.new(answer) %>

View File

@@ -1,7 +0,0 @@
class Admin::Poll::Questions::Answers::TableActionsComponent < ApplicationComponent
attr_reader :answer
def initialize(answer)
@answer = answer
end
end

View File

@@ -1,16 +1,16 @@
<%= back_link_to admin_question_path(@answer.question) %> <%= back_link_to admin_question_path(option.question) %>
<h2><%= t("admin.questions.show.answers.documents_list") %></h2> <h2><%= t("admin.questions.show.answers.documents_list") %></h2>
<ul class="breadcrumbs"> <ul class="breadcrumbs">
<li><%= answer.question.title %></li> <li><%= option.question.title %></li>
<li><%= answer.title %></li> <li><%= option.title %></li>
</ul> </ul>
<div class="poll-question-form"> <div class="poll-question-form">
<% if can?(:update, @answer) %> <% if can?(:update, option) %>
<%= form_for(Poll::Question::Answer.new, url: admin_answer_documents_path(answer)) do |f| %> <%= form_for(Poll::Question::Option.new, url: admin_option_documents_path(option)) do |f| %>
<%= render "shared/errors", resource: answer %> <%= render "shared/errors", resource: option %>
<%= render Documents::NestedComponent.new(f) %> <%= render Documents::NestedComponent.new(f) %>
@@ -37,7 +37,7 @@
<%= document.title %> <%= document.title %>
</td> </td>
<td> <td>
<%= render Admin::Poll::Questions::Answers::Documents::TableActionsComponent.new(document) %> <%= render Admin::Poll::Questions::Options::Documents::TableActionsComponent.new(document) %>
</td> </td>
</tr> </tr>
<% end %> <% end %>

View File

@@ -0,0 +1,14 @@
class Admin::Poll::Questions::Options::Documents::IndexComponent < ApplicationComponent
attr_reader :option
use_helpers :can?
def initialize(option)
@option = option
end
private
def documents
@documents ||= @option.class.find(@option.id).documents
end
end

View File

@@ -1,4 +1,4 @@
class Admin::Poll::Questions::Answers::Documents::TableActionsComponent < ApplicationComponent class Admin::Poll::Questions::Options::Documents::TableActionsComponent < ApplicationComponent
attr_reader :document attr_reader :document
def initialize(document) def initialize(document)

View File

@@ -0,0 +1 @@
<%= render Admin::AllowedTableActionsComponent.new(option) %>

View File

@@ -0,0 +1,7 @@
class Admin::Poll::Questions::Options::TableActionsComponent < ApplicationComponent
attr_reader :option
def initialize(option)
@option = option
end
end

View File

@@ -1,4 +1,4 @@
class Admin::Poll::Questions::Answers::Videos::TableActionsComponent < ApplicationComponent class Admin::Poll::Questions::Options::Videos::TableActionsComponent < ApplicationComponent
attr_reader :video attr_reader :video
def initialize(video) def initialize(video)

View File

@@ -1,3 +1,3 @@
<%= render Admin::AllowedTableActionsComponent.new(question) do |actions| %> <%= render Admin::AllowedTableActionsComponent.new(question) do |actions| %>
<%= actions.action(:answers, text: t("admin.polls.show.edit_answers")) %> <%= actions.action(:options, text: t("admin.polls.show.edit_answers")) %>
<% end %> <% end %>

View File

@@ -4,7 +4,7 @@
<%= header do %> <%= header do %>
<%= render Admin::ActionComponent.new( <%= render Admin::ActionComponent.new(
:destroy, :destroy,
@page, page,
text: t("admin.site_customization.pages.index.delete"), text: t("admin.site_customization.pages.index.delete"),
confirm: true, confirm: true,
class: "delete" class: "delete"

View File

@@ -14,7 +14,7 @@
</thead> </thead>
<tbody> <tbody>
<% @tenants.each do |tenant| %> <% tenants.each do |tenant| %>
<%= render Admin::Tenants::RowComponent.new(tenant) %> <%= render Admin::Tenants::RowComponent.new(tenant) %>
<% end %> <% end %>
</tbody> </tbody>

View File

@@ -1,35 +1,35 @@
<div class="poll-question-answers"> <div class="poll-question-options">
<% if can?(:answer, question) && !question.poll.voted_in_booth?(current_user) %> <% if can?(:answer, question) && !question.poll.voted_in_booth?(current_user) %>
<% question_answers.each do |question_answer| %> <% question_options.each do |question_option| %>
<% if already_answered?(question_answer) %> <% if already_answered?(question_option) %>
<%= button_to question_answer.title, <%= button_to question_option.title,
question_answer_path(question, user_answer(question_answer)), question_answer_path(question, user_answer(question_option)),
method: :delete, method: :delete,
remote: true, remote: true,
title: t("poll_questions.show.voted", answer: question_answer.title), title: t("poll_questions.show.voted", answer: question_option.title),
class: "button answered", class: "button answered",
"aria-pressed": true %> "aria-pressed": true %>
<% else %> <% else %>
<%= button_to question_answer.title, <%= button_to question_option.title,
answer_question_path(question, answer: question_answer.title), answer_question_path(question, answer: question_option.title),
remote: true, remote: true,
title: t("poll_questions.show.vote_answer", answer: question_answer.title), title: t("poll_questions.show.vote_answer", answer: question_option.title),
class: "button secondary hollow", class: "button secondary hollow",
"aria-pressed": false, "aria-pressed": false,
disabled: disable_answer?(question_answer) %> disabled: disable_option?(question_option) %>
<% end %> <% end %>
<% end %> <% end %>
<% elsif !user_signed_in? %> <% elsif !user_signed_in? %>
<% question_answers.each do |question_answer| %> <% question_options.each do |question_option| %>
<%= link_to question_answer.title, new_user_session_path, class: "button secondary hollow" %> <%= link_to question_option.title, new_user_session_path, class: "button secondary hollow" %>
<% end %> <% end %>
<% elsif !current_user.level_two_or_three_verified? %> <% elsif !current_user.level_two_or_three_verified? %>
<% question_answers.each do |question_answer| %> <% question_options.each do |question_option| %>
<%= link_to question_answer.title, verification_path, class: "button secondary hollow" %> <%= link_to question_option.title, verification_path, class: "button secondary hollow" %>
<% end %> <% end %>
<% else %> <% else %>
<% question_answers.each do |question_answer| %> <% question_options.each do |question_option| %>
<span class="button secondary hollow disabled"><%= question_answer.title %></span> <span class="button secondary hollow disabled"><%= question_option.title %></span>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>

View File

@@ -1,4 +1,4 @@
class Polls::Questions::AnswersComponent < ApplicationComponent class Polls::Questions::OptionsComponent < ApplicationComponent
attr_reader :question attr_reader :question
use_helpers :can?, :current_user, :user_signed_in? use_helpers :can?, :current_user, :user_signed_in?
@@ -6,19 +6,19 @@ class Polls::Questions::AnswersComponent < ApplicationComponent
@question = question @question = question
end end
def already_answered?(question_answer) def already_answered?(question_option)
user_answer(question_answer).present? user_answer(question_option).present?
end end
def question_answers def question_options
question.question_answers question.question_options
end end
def user_answer(question_answer) def user_answer(question_option)
user_answers.find_by(answer: question_answer.title) user_answers.find_by(answer: question_option.title)
end end
def disable_answer?(question_answer) def disable_option?(question_option)
question.multiple? && user_answers.count == question.max_votes question.multiple? && user_answers.count == question.max_votes
end end

View File

@@ -9,14 +9,14 @@
</strong> </strong>
<% end %> <% end %>
<div id="<%= dom_id(question) %>_answers" class="padding"> <div id="<%= dom_id(question) %>_options" class="padding">
<%= render Polls::Questions::AnswersComponent.new(question) %> <%= render Polls::Questions::OptionsComponent.new(question) %>
</div> </div>
<% if question.answers_with_read_more? %> <% if question.options_with_read_more? %>
<div> <div>
<p><%= t("poll_questions.read_more_about") %></p> <p><%= t("poll_questions.read_more_about") %></p>
<p><%= answers_read_more_links %></p> <p><%= options_read_more_links %></p>
</div> </div>
<% end %> <% end %>
</div> </div>

View File

@@ -5,9 +5,9 @@ class Polls::Questions::QuestionComponent < ApplicationComponent
@question = question @question = question
end end
def answers_read_more_links def options_read_more_links
safe_join(question.answers_with_read_more.map do |answer| safe_join(question.options_with_read_more.map do |option|
link_to answer.title, "#answer_#{answer.id}" link_to option.title, "#option_#{option.id}"
end, ", ") end, ", ")
end end
end end

View File

@@ -1,52 +1,52 @@
<h2><%= question.title %></h2> <h2><%= question.title %></h2>
<% question.answers_with_read_more.each do |answer| %> <% question.options_with_read_more.each do |option| %>
<div class="small-12 medium-6 column end answer <%= cycle("first", "") %>" id="answer_<%= answer.id %>"> <div class="small-12 medium-6 column end option <%= cycle("first", "") %>" id="option_<%= option.id %>">
<h3><%= answer.title %></h3> <h3><%= option.title %></h3>
<div class="margin-top"> <div class="margin-top">
<% if answer.description.present? %> <% if option.description.present? %>
<div id="answer_description_<%= answer.id %>" class="answer-description short" data-toggler="short"> <div id="option_description_<%= option.id %>" class="option-description short" data-toggler="short">
<%= wysiwyg(answer.description) %> <%= wysiwyg(option.description) %>
</div> </div>
<div class="read-more"> <div class="read-more">
<button type="button" id="read_more_<%= answer.id %>" <button type="button" id="read_more_<%= option.id %>"
data-toggle="answer_description_<%= answer.id %> read_more_<%= answer.id %> read_less_<%= answer.id %>" data-toggle="option_description_<%= option.id %> read_more_<%= option.id %> read_less_<%= option.id %>"
data-toggler="hide"> data-toggler="hide">
<%= t("polls.show.read_more", answer: answer.title) %> <%= t("polls.show.read_more", answer: option.title) %>
</button> </button>
<button type="button" id="read_less_<%= answer.id %>" <button type="button" id="read_less_<%= option.id %>"
data-toggle="answer_description_<%= answer.id %> read_more_<%= answer.id %> read_less_<%= answer.id %>" data-toggle="option_description_<%= option.id %> read_more_<%= option.id %> read_less_<%= option.id %>"
data-toggler="hide" data-toggler="hide"
class="hide"> class="hide">
<%= t("polls.show.read_less", answer: answer.title) %> <%= t("polls.show.read_less", answer: option.title) %>
</button> </button>
</div> </div>
<% end %> <% end %>
<% if answer.images.any? %> <% if option.images.any? %>
<%= render "polls/gallery", answer: answer %> <%= render "polls/gallery", option: option %>
<% end %> <% end %>
<% if answer.documents.present? %> <% if option.documents.present? %>
<div class="document-link"> <div class="document-link">
<p> <p>
<strong><%= t("polls.show.documents") %></strong> <strong><%= t("polls.show.documents") %></strong>
</p> </p>
<% answer.documents.each do |document| %> <% option.documents.each do |document| %>
<%= render Documents::DocumentComponent.new(document) %> <%= render Documents::DocumentComponent.new(document) %>
<% end %> <% end %>
</div> </div>
<% end %> <% end %>
<% if answer.videos.present? %> <% if option.videos.present? %>
<div class="video-link"> <div class="video-link">
<p> <p>
<span class="icon-video"></span>&nbsp; <span class="icon-video"></span>&nbsp;
<strong><%= t("polls.show.videos") %></strong> <strong><%= t("polls.show.videos") %></strong>
</p> </p>
<% answer.videos.each do |video| %> <% option.videos.each do |video| %>
<%= link_to video.title, <%= link_to video.title,
video.url, video.url,
rel: "nofollow" %><br> rel: "nofollow" %><br>

View File

@@ -8,6 +8,6 @@ class Polls::Questions::ReadMoreComponent < ApplicationComponent
end end
def render? def render?
question.answers_with_read_more? question.options_with_read_more?
end end
end end

View File

@@ -2,22 +2,22 @@
<table id="question_<%= question.id %>_results_table"> <table id="question_<%= question.id %>_results_table">
<thead> <thead>
<tr> <tr>
<%- question.question_answers.each do |answer| %> <%- question.question_options.each do |option| %>
<th scope="col" class="<%= answer_styles(answer) %>"> <th scope="col" class="<%= option_styles(option) %>">
<% if most_voted_answer?(answer) %> <% if most_voted_option?(option) %>
<span class="show-for-sr"><%= t("polls.show.results.most_voted_answer") %></span> <span class="show-for-sr"><%= t("polls.show.results.most_voted_answer") %></span>
<% end %> <% end %>
<%= answer.title %> <%= option.title %>
</th> </th>
<% end %> <% end %>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<%- question.question_answers.each do |answer| %> <%- question.question_options.each do |option| %>
<td id="answer_<%= answer.id %>_result" class="<%= answer_styles(answer) %>"> <td id="option_<%= option.id %>_result" class="<%= option_styles(option) %>">
<%= answer.total_votes %> <%= option.total_votes %>
(<%= answer.total_votes_percentage.round(2) %>%) (<%= option.total_votes_percentage.round(2) %>%)
</td> </td>
<% end %> <% end %>
</tr> </tr>

View File

@@ -5,11 +5,11 @@ class Polls::Results::QuestionComponent < ApplicationComponent
@question = question @question = question
end end
def answer_styles(answer) def option_styles(option)
"win" if most_voted_answer?(answer) "win" if most_voted_option?(option)
end end
def most_voted_answer?(answer) def most_voted_option?(option)
answer.id == question.most_voted_answer_id option.id == question.most_voted_option_id
end end
end end

View File

@@ -8,7 +8,7 @@
<h1><%= t("sdg.goals.help.title") %></h1> <h1><%= t("sdg.goals.help.title") %></h1>
<p><%= t("sdg.goals.help.description") %></p> <p><%= t("sdg.goals.help.description") %></p>
<ul class="tabs" id="help_tabs" data-deep-link="true" data-tabs> <ul class="tabs" id="help_tabs" data-deep-link="true" data-tabs>
<% @goals.each do |goal| %> <% goals.each do |goal| %>
<li class="tabs-title <%= is_active?(goal) %>"> <li class="tabs-title <%= is_active?(goal) %>">
<%= link_to "#goal_#{goal.code}_tab" do %> <%= link_to "#goal_#{goal.code}_tab" do %>
<% render SDG::Goals::IconComponent.new(goal) %> <% render SDG::Goals::IconComponent.new(goal) %>
@@ -18,7 +18,7 @@
</ul> </ul>
<div class="tabs-content" data-tabs-content="help_tabs"> <div class="tabs-content" data-tabs-content="help_tabs">
<% @goals.each do |goal| %> <% goals.each do |goal| %>
<div id="goal_<%= goal.code %>_tab" class="tabs-panel <%= is_active?(goal) %>"> <div id="goal_<%= goal.code %>_tab" class="tabs-panel <%= is_active?(goal) %>">
<h2><%= goal.code_and_title %></h2> <h2><%= goal.code_and_title %></h2>
<p><%= sanitize t("sdg.goals.goal_#{goal.code}.description") %></p> <p><%= sanitize t("sdg.goals.goal_#{goal.code}.description") %></p>

View File

@@ -2,7 +2,7 @@
<ul class="tabs" id="goal_<%= goal.code %>_targets" data-deep-link="true" data-tabs> <ul class="tabs" id="goal_<%= goal.code %>_targets" data-deep-link="true" data-tabs>
<% [global_targets, local_targets].each do |targets| %> <% [global_targets, local_targets].each do |targets| %>
<li class="tabs-title <%= active(targets) %>"> <li class="tabs-title <%= active(targets) %>">
<%= link_to title(targets), "#goal_#{@goal.code}_tab_#{type(targets)}_targets" %> <%= link_to title(targets), "#goal_#{goal.code}_tab_#{type(targets)}_targets" %>
</li> </li>
<% end %> <% end %>
</ul> </ul>

View File

@@ -14,7 +14,7 @@
</thead> </thead>
<tbody> <tbody>
<% @records.each do |record| %> <% records.each do |record| %>
<tr> <tr>
<td><%= record.title %></td> <td><%= record.title %></td>
<td><%= record.sdg_goal_list %></td> <td><%= record.sdg_goal_list %></td>

View File

@@ -1,30 +0,0 @@
class Admin::Poll::Questions::Answers::DocumentsController < Admin::Poll::BaseController
include DocumentAttributes
load_and_authorize_resource :answer, class: "::Poll::Question::Answer"
def index
end
def create
@answer.attributes = documents_params
authorize! :update, @answer
if @answer.save
redirect_to admin_answer_documents_path(@answer),
notice: t("admin.documents.create.success_notice")
else
render :index
end
end
private
def documents_params
params.require(:poll_question_answer).permit(allowed_params)
end
def allowed_params
[documents_attributes: document_attributes]
end
end

View File

@@ -1,41 +0,0 @@
class Admin::Poll::Questions::Answers::ImagesController < Admin::Poll::BaseController
include ImageAttributes
load_and_authorize_resource :answer, class: "::Poll::Question::Answer"
load_and_authorize_resource only: [:destroy]
def index
end
def new
end
def create
@answer.attributes = images_params
authorize! :update, @answer
if @answer.save
redirect_to admin_answer_images_path(@answer),
notice: t("flash.actions.create.poll_question_answer_image")
else
render :new
end
end
def destroy
@image.destroy!
redirect_to admin_answer_images_path(@image.imageable),
notice: t("flash.actions.destroy.poll_question_answer_image")
end
private
def images_params
params.require(:poll_question_answer).permit(allowed_params)
end
def allowed_params
[:answer_id, images_attributes: image_attributes]
end
end

View File

@@ -1,46 +0,0 @@
class Admin::Poll::Questions::Answers::VideosController < Admin::Poll::BaseController
load_and_authorize_resource :answer, class: "::Poll::Question::Answer"
load_and_authorize_resource class: "::Poll::Question::Answer::Video", through: :answer
def index
end
def new
end
def create
if @video.save
redirect_to admin_answer_videos_path(@answer),
notice: t("flash.actions.create.poll_question_answer_video")
else
render :new
end
end
def edit
end
def update
if @video.update(video_params)
redirect_to admin_answer_videos_path(@answer), notice: t("flash.actions.save_changes.notice")
else
render :edit
end
end
def destroy
@video.destroy!
notice = t("flash.actions.destroy.poll_question_answer_video")
redirect_to admin_answer_videos_path(@answer), notice: notice
end
private
def video_params
params.require(:poll_question_answer_video).permit(allowed_params)
end
def allowed_params
[:title, :url]
end
end

View File

@@ -0,0 +1,30 @@
class Admin::Poll::Questions::Options::DocumentsController < Admin::Poll::BaseController
include DocumentAttributes
load_and_authorize_resource :option, class: "::Poll::Question::Option"
def index
end
def create
@option.attributes = documents_params
authorize! :update, @option
if @option.save
redirect_to admin_option_documents_path(@option),
notice: t("admin.documents.create.success_notice")
else
render :index
end
end
private
def documents_params
params.require(:poll_question_option).permit(allowed_params)
end
def allowed_params
[documents_attributes: document_attributes]
end
end

View File

@@ -0,0 +1,41 @@
class Admin::Poll::Questions::Options::ImagesController < Admin::Poll::BaseController
include ImageAttributes
load_and_authorize_resource :option, class: "::Poll::Question::Option"
load_and_authorize_resource only: [:destroy]
def index
end
def new
end
def create
@option.attributes = images_params
authorize! :update, @option
if @option.save
redirect_to admin_option_images_path(@option),
notice: t("flash.actions.create.poll_question_option_image")
else
render :new
end
end
def destroy
@image.destroy!
redirect_to admin_option_images_path(@image.imageable),
notice: t("flash.actions.destroy.poll_question_option_image")
end
private
def images_params
params.require(:poll_question_option).permit(allowed_params)
end
def allowed_params
[:option_id, images_attributes: image_attributes]
end
end

View File

@@ -0,0 +1,46 @@
class Admin::Poll::Questions::Options::VideosController < Admin::Poll::BaseController
load_and_authorize_resource :option, class: "::Poll::Question::Option"
load_and_authorize_resource class: "::Poll::Question::Option::Video", through: :option
def index
end
def new
end
def create
if @video.save
redirect_to admin_option_videos_path(@option),
notice: t("flash.actions.create.poll_question_option_video")
else
render :new
end
end
def edit
end
def update
if @video.update(video_params)
redirect_to admin_option_videos_path(@option), notice: t("flash.actions.save_changes.notice")
else
render :edit
end
end
def destroy
@video.destroy!
notice = t("flash.actions.destroy.poll_question_option_video")
redirect_to admin_option_videos_path(@option), notice: notice
end
private
def video_params
params.require(:poll_question_option_video).permit(allowed_params)
end
def allowed_params
[:title, :url]
end
end

View File

@@ -1,18 +1,18 @@
class Admin::Poll::Questions::AnswersController < Admin::Poll::BaseController class Admin::Poll::Questions::OptionsController < Admin::Poll::BaseController
include Translatable include Translatable
load_and_authorize_resource :question, class: "::Poll::Question" load_and_authorize_resource :question, class: "::Poll::Question"
load_and_authorize_resource class: "::Poll::Question::Answer", load_and_authorize_resource class: "::Poll::Question::Option",
through: :question, through: :question,
through_association: :question_answers through_association: :question_options
def new def new
end end
def create def create
if @answer.save if @option.save
redirect_to admin_question_path(@question), redirect_to admin_question_path(@question),
notice: t("flash.actions.create.poll_question_answer") notice: t("flash.actions.create.poll_question_option")
else else
render :new render :new
end end
@@ -22,7 +22,7 @@ class Admin::Poll::Questions::AnswersController < Admin::Poll::BaseController
end end
def update def update
if @answer.update(answer_params) if @option.update(option_params)
redirect_to admin_question_path(@question), redirect_to admin_question_path(@question),
notice: t("flash.actions.save_changes.notice") notice: t("flash.actions.save_changes.notice")
else else
@@ -31,24 +31,24 @@ class Admin::Poll::Questions::AnswersController < Admin::Poll::BaseController
end end
def destroy def destroy
@answer.destroy! @option.destroy!
redirect_to admin_question_path(@question), notice: t("admin.answers.destroy.success_notice") redirect_to admin_question_path(@question), notice: t("admin.answers.destroy.success_notice")
end end
def order_answers def order_options
::Poll::Question::Answer.order_answers(params[:ordered_list]) ::Poll::Question::Option.order_options(params[:ordered_list])
head :ok head :ok
end end
private private
def answer_params def option_params
params.require(:poll_question_answer).permit(allowed_params) params.require(:poll_question_option).permit(allowed_params)
end end
def allowed_params def allowed_params
attributes = [:title, :description, :given_order] attributes = [:title, :description, :given_order]
[*attributes, translation_params(Poll::Question::Answer)] [*attributes, translation_params(Poll::Question::Option)]
end end
end end

View File

@@ -66,10 +66,10 @@ class Dashboard::PollsController < Dashboard::BaseController
def question_attributes def question_attributes
[:id, :title, :author_id, :proposal_id, :_destroy, [:id, :title, :author_id, :proposal_id, :_destroy,
question_answers_attributes: question_answers_attributes] question_options_attributes: question_options_attributes]
end end
def question_answers_attributes def question_options_attributes
[:id, :_destroy, :title, :description, :given_order, :question_id, [:id, :_destroy, :title, :description, :given_order, :question_id,
documents_attributes: document_attributes] documents_attributes: document_attributes]
end end

View File

@@ -43,7 +43,7 @@ class Officing::ResultsController < Officing::BaseController
results.each_pair do |answer_index, count| results.each_pair do |answer_index, count|
next if count.blank? next if count.blank?
answer = question.question_answers.find_by(given_order: answer_index.to_i + 1).title answer = question.question_options.find_by(given_order: answer_index.to_i + 1).title
go_back_to_new if question.blank? go_back_to_new if question.blank?
partial_result = ::Poll::PartialResult.find_or_initialize_by( partial_result = ::Poll::PartialResult.find_or_initialize_by(

View File

@@ -12,7 +12,7 @@ class Polls::AnswersController < ApplicationController
redirect_to request.referer redirect_to request.referer
end end
format.js do format.js do
render "polls/questions/answers" render "polls/questions/options"
end end
end end
end end

View File

@@ -13,7 +13,7 @@ class Polls::QuestionsController < ApplicationController
redirect_to request.referer redirect_to request.referer
end end
format.js do format.js do
render :answers render :options
end end
end end
end end

View File

@@ -8,11 +8,11 @@ module OfficingHelper
options_for_select(options, params[:oa]) options_for_select(options, params[:oa])
end end
def answer_result_value(question_id, answer_index) def answer_result_value(question_id, option_index)
return nil if params.blank? return nil if params.blank?
return nil if params[:questions].blank? return nil if params[:questions].blank?
return nil if params[:questions][question_id.to_s].blank? return nil if params[:questions][question_id.to_s].blank?
params[:questions][question_id.to_s][answer_index.to_s] params[:questions][question_id.to_s][option_index.to_s]
end end
end end

View File

@@ -96,16 +96,16 @@ module Abilities
can [:update, :destroy], Poll::Question do |question| can [:update, :destroy], Poll::Question do |question|
!question.poll.started? !question.poll.started?
end end
can [:read, :order_answers], Poll::Question::Answer can [:read, :order_options], Poll::Question::Option
can [:create, :update, :destroy], Poll::Question::Answer do |answer| can [:create, :update, :destroy], Poll::Question::Option do |option|
can?(:update, answer.question) can?(:update, option.question)
end end
can :read, Poll::Question::Answer::Video can :read, Poll::Question::Option::Video
can [:create, :update, :destroy], Poll::Question::Answer::Video do |video| can [:create, :update, :destroy], Poll::Question::Option::Video do |video|
can?(:update, video.answer) can?(:update, video.option)
end end
can [:destroy], Image do |image| can [:destroy], Image do |image|
image.imageable_type == "Poll::Question::Answer" && can?(:update, image.imageable) image.imageable_type == "Poll::Question::Option" && can?(:update, image.imageable)
end end
can :manage, SiteCustomization::Page can :manage, SiteCustomization::Page
@@ -127,7 +127,7 @@ module Abilities
can [:create], Document can [:create], Document
can [:destroy], Document do |document| can [:destroy], Document do |document|
document.documentable_type == "Poll::Question::Answer" && can?(:update, document.documentable) document.documentable_type == "Poll::Question::Option" && can?(:update, document.documentable)
end end
can [:create, :destroy], DirectUpload can [:create, :destroy], DirectUpload

View File

@@ -71,11 +71,11 @@ module Abilities
can [:create, :destroy], Follow, user_id: user.id can [:create, :destroy], Follow, user_id: user.id
can [:destroy], Document do |document| can [:destroy], Document do |document|
document.documentable_type != "Poll::Question::Answer" && document.documentable&.author_id == user.id document.documentable_type != "Poll::Question::Option" && document.documentable&.author_id == user.id
end end
can [:destroy], Image do |image| can [:destroy], Image do |image|
image.imageable_type != "Poll::Question::Answer" && image.imageable&.author_id == user.id image.imageable_type != "Poll::Question::Option" && image.imageable&.author_id == user.id
end end
can [:create, :destroy], DirectUpload can [:create, :destroy], DirectUpload

View File

@@ -1,6 +1,4 @@
class Poll < ApplicationRecord class Poll < ApplicationRecord
require_dependency "poll/answer"
include Imageable include Imageable
acts_as_paranoid column: :hidden_at acts_as_paranoid column: :hidden_at
include ActsAsParanoidAliases include ActsAsParanoidAliases

View File

@@ -14,8 +14,8 @@ class Poll::Question < ApplicationRecord
has_many :comments, as: :commentable, inverse_of: :commentable has_many :comments, as: :commentable, inverse_of: :commentable
has_many :answers, class_name: "Poll::Answer" has_many :answers, class_name: "Poll::Answer"
has_many :question_answers, -> { order "given_order asc" }, has_many :question_options, -> { order "given_order asc" },
class_name: "Poll::Question::Answer", class_name: "Poll::Question::Option",
inverse_of: :question, inverse_of: :question,
dependent: :destroy dependent: :destroy
has_many :partial_results has_many :partial_results
@@ -25,7 +25,7 @@ class Poll::Question < ApplicationRecord
validates :author, presence: true validates :author, presence: true
validates :poll_id, presence: true, if: proc { |question| question.poll.nil? } validates :poll_id, presence: true, if: proc { |question| question.poll.nil? }
accepts_nested_attributes_for :question_answers, reject_if: :all_blank, allow_destroy: true accepts_nested_attributes_for :question_options, reject_if: :all_blank, allow_destroy: true
scope :by_poll_id, ->(poll_id) { where(poll_id: poll_id) } scope :by_poll_id, ->(poll_id) { where(poll_id: poll_id) }
@@ -63,23 +63,23 @@ class Poll::Question < ApplicationRecord
where(poll_id: Poll.answerable_by(user).pluck(:id)) where(poll_id: Poll.answerable_by(user).pluck(:id))
end end
def answers_total_votes def options_total_votes
question_answers.reduce(0) { |total, question_answer| total + question_answer.total_votes } question_options.reduce(0) { |total, question_option| total + question_option.total_votes }
end end
def most_voted_answer_id def most_voted_option_id
question_answers.max_by(&:total_votes)&.id question_options.max_by(&:total_votes)&.id
end end
def possible_answers def possible_answers
question_answers.joins(:translations).pluck("poll_question_answer_translations.title") question_options.joins(:translations).pluck(:title)
end end
def answers_with_read_more? def options_with_read_more?
answers_with_read_more.any? options_with_read_more.any?
end end
def answers_with_read_more def options_with_read_more
question_answers.select(&:with_read_more?) question_options.select(&:with_read_more?)
end end
end end

View File

@@ -1,6 +0,0 @@
class Poll::Question::Answer::Video < ApplicationRecord
belongs_to :answer, class_name: "Poll::Question::Answer"
include Videoable
validates :title, presence: true
end

View File

@@ -1,4 +1,6 @@
class Poll::Question::Answer < ApplicationRecord class Poll::Question::Option < ApplicationRecord
self.table_name = "poll_question_answers"
include Galleryable include Galleryable
include Documentable include Documentable
@@ -9,7 +11,10 @@ class Poll::Question::Answer < ApplicationRecord
accepts_nested_attributes_for :documents, allow_destroy: true accepts_nested_attributes_for :documents, allow_destroy: true
belongs_to :question, class_name: "Poll::Question" belongs_to :question, class_name: "Poll::Question"
has_many :videos, class_name: "Poll::Question::Answer::Video", dependent: :destroy has_many :videos, class_name: "Poll::Question::Option::Video",
dependent: :destroy,
foreign_key: "answer_id",
inverse_of: :option
validates_translation :title, presence: true validates_translation :title, presence: true
validates :given_order, presence: true, uniqueness: { scope: :question_id } validates :given_order, presence: true, uniqueness: { scope: :question_id }
@@ -22,9 +27,9 @@ class Poll::Question::Answer < ApplicationRecord
.where.missing(:videos) .where.missing(:videos)
end end
def self.order_answers(ordered_array) def self.order_options(ordered_array)
ordered_array.each_with_index do |answer_id, order| ordered_array.each_with_index do |option_id, order|
find(answer_id).update_column(:given_order, (order + 1)) find(option_id).update_column(:given_order, (order + 1))
end end
end end
@@ -38,7 +43,7 @@ class Poll::Question::Answer < ApplicationRecord
end end
def total_votes_percentage def total_votes_percentage
question.answers_total_votes.zero? ? 0 : (total_votes * 100.0) / question.answers_total_votes question.options_total_votes.zero? ? 0 : (total_votes * 100.0) / question.options_total_votes
end end
def with_read_more? def with_read_more?

View File

@@ -0,0 +1,6 @@
class Poll::Question::Option::Video < ApplicationRecord
belongs_to :option, class_name: "Poll::Question::Option", foreign_key: "answer_id", inverse_of: :videos
include Videoable
validates :title, presence: true
end

View File

@@ -60,10 +60,6 @@ class User < ApplicationRecord
class_name: "Poll::Answer", class_name: "Poll::Answer",
foreign_key: :author_id, foreign_key: :author_id,
inverse_of: :author inverse_of: :author
has_many :poll_pair_answers,
class_name: "Poll::PairAnswer",
foreign_key: :author_id,
inverse_of: :author
has_many :poll_partial_results, has_many :poll_partial_results,
class_name: "Poll::PartialResult", class_name: "Poll::PartialResult",
foreign_key: :author_id, foreign_key: :author_id,

View File

@@ -26,7 +26,7 @@
</td> </td>
<td> <td>
<%= render Admin::TableActionsComponent.new(question) do |actions| %> <%= render Admin::TableActionsComponent.new(question) do |actions| %>
<%= actions.action(:answers, text: t("admin.polls.show.edit_answers")) %> <%= actions.action(:options, text: t("admin.polls.show.edit_answers")) %>
<% end %> <% end %>
</td> </td>
</tr> </tr>

View File

@@ -1 +0,0 @@
<%= render Admin::Poll::Questions::Answers::Documents::IndexComponent.new(@answer) %>

View File

@@ -1,9 +0,0 @@
<%= back_link_to admin_answer_videos_path(@answer) %>
<h2>
<%= t("admin.answers.videos.edit.title") %>
</h2>
<div class="poll-question-answer-video-form">
<%= render "form", form_url: admin_answer_video_path(@answer, @video) %>
</div>

View File

@@ -1,9 +0,0 @@
<%= back_link_to admin_answer_videos_path(@answer) %>
<h2>
<%= t("admin.answers.videos.new.title") %>
</h2>
<div class="poll-question-answer-video-form">
<%= render "form", form_url: admin_answer_videos_path(@answer) %>
</div>

View File

@@ -1,11 +1,11 @@
<%= render "shared/globalize_locales", resource: @answer %> <%= render "shared/globalize_locales", resource: @option %>
<%= translatable_form_for(@answer, url: form_url) do |f| %> <%= translatable_form_for(@option, url: form_url) do |f| %>
<%= render "shared/errors", resource: @answer %> <%= render "shared/errors", resource: @option %>
<%= f.hidden_field :given_order, <%= f.hidden_field :given_order,
value: @answer.persisted? ? @answer.given_order : @answer.class.last_position(@answer.question_id || @question.id) + 1 %> value: @option.persisted? ? @option.given_order : @option.class.last_position(@option.question_id || @question.id) + 1 %>
<div class="row"> <div class="row">
<%= f.translatable_fields do |translations_form| %> <%= f.translatable_fields do |translations_form| %>

View File

@@ -0,0 +1 @@
<%= render Admin::Poll::Questions::Options::Documents::IndexComponent.new(@option) %>

View File

@@ -1,7 +1,7 @@
<%= back_link_to admin_question_path(@question) %> <%= back_link_to admin_question_path(@question) %>
<ul class="breadcrumbs margin-top"> <ul class="breadcrumbs margin-top">
<li><%= @answer.title %></li> <li><%= @option.title %></li>
<li><%= t("admin.answers.edit.title") %></li> <li><%= t("admin.answers.edit.title") %></li>
</ul> </ul>
@@ -9,6 +9,6 @@
<%= t("admin.answers.edit.title") %> <%= t("admin.answers.edit.title") %>
</h2> </h2>
<div class="poll-question-answer-form"> <div class="poll-question-option-form">
<%= render "form", form_url: admin_question_answer_path(@question, @answer) %> <%= render "form", form_url: admin_question_option_path(@question, @option) %>
</div> </div>

View File

@@ -1,4 +1,4 @@
<%= back_link_to admin_question_path(@answer.question) %> <%= back_link_to admin_question_path(@option.question) %>
<div class="clear"></div> <div class="clear"></div>
@@ -6,9 +6,9 @@
<%= t("admin.answers.images.index.title") %> <%= t("admin.answers.images.index.title") %>
</h2> </h2>
<% if can?(:update, @answer) %> <% if can?(:update, @option) %>
<%= link_to t("admin.questions.answers.images.add_image"), <%= link_to t("admin.questions.answers.images.add_image"),
new_admin_answer_image_path(@answer), new_admin_option_image_path(@option),
class: "button hollow float-right" %> class: "button hollow float-right" %>
<% else %> <% else %>
<div class="callout warning"> <div class="callout warning">
@@ -17,11 +17,11 @@
<% end %> <% end %>
<ul class="breadcrumbs margin-top"> <ul class="breadcrumbs margin-top">
<li><%= @answer.question.title %></li> <li><%= @option.question.title %></li>
<li><%= @answer.title %></li> <li><%= @option.title %></li>
</ul> </ul>
<% @answer.images.each do |image| %> <% @option.images.each do |image| %>
<div class="small-12 medium-4 column end"> <div class="small-12 medium-4 column end">
<%= render_image(image, :large, true) if image.present? %> <%= render_image(image, :large, true) if image.present? %>

View File

@@ -1,6 +1,6 @@
<div class="poll-question-form"> <div class="poll-question-form">
<%= form_for(@answer, url: admin_answer_images_path(@answer), method: :post) do |f| %> <%= form_for(@option, url: admin_option_images_path(@option), method: :post) do |f| %>
<%= render "shared/errors", resource: @answer %> <%= render "shared/errors", resource: @option %>
<%= render Images::NestedComponent.new(f, image_fields: :images) %> <%= render Images::NestedComponent.new(f, image_fields: :images) %>

View File

@@ -7,6 +7,6 @@
<h2><%= t("admin.answers.new.title") %></h2> <h2><%= t("admin.answers.new.title") %></h2>
<div class="poll-question-answer-form"> <div class="poll-question-option-form">
<%= render "form", form_url: admin_question_answers_path %> <%= render "form", form_url: admin_question_options_path %>
</div> </div>

View File

@@ -0,0 +1,9 @@
<%= back_link_to admin_option_videos_path(@option) %>
<h2>
<%= t("admin.answers.videos.edit.title") %>
</h2>
<div class="poll-question-option-video-form">
<%= render "form", form_url: admin_option_video_path(@option, @video) %>
</div>

View File

@@ -1,4 +1,4 @@
<%= back_link_to admin_question_path(@answer.question) %> <%= back_link_to admin_question_path(@option.question) %>
<div class="clear"></div> <div class="clear"></div>
@@ -6,9 +6,9 @@
<%= t("admin.answers.videos.index.title") %> <%= t("admin.answers.videos.index.title") %>
</h2> </h2>
<% if can?(:create, Poll::Question::Answer.new(question: @answer.question)) %> <% if can?(:create, Poll::Question::Option.new(question: @option.question)) %>
<%= link_to t("admin.answers.videos.index.add_video"), <%= link_to t("admin.answers.videos.index.add_video"),
new_admin_answer_video_path(@answer), new_admin_option_video_path(@option),
class: "button success float-right" %> class: "button success float-right" %>
<% else %> <% else %>
<div class="callout warning"> <div class="callout warning">
@@ -29,11 +29,11 @@
<tbody> <tbody>
<% @videos.each do |video| %> <% @videos.each do |video| %>
<tr id="<%= dom_id(video) %>" class="poll_question_answer_video"> <tr id="<%= dom_id(video) %>" class="poll_question_option_video">
<td><%= video.title %></td> <td><%= video.title %></td>
<td><%= link_to video.url, video.url %></td> <td><%= link_to video.url, video.url %></td>
<td> <td>
<%= render Admin::Poll::Questions::Answers::Videos::TableActionsComponent.new(video) %> <%= render Admin::Poll::Questions::Options::Videos::TableActionsComponent.new(video) %>
</td> </td>
</tr> </tr>
<% end %> <% end %>

View File

@@ -0,0 +1,9 @@
<%= back_link_to admin_option_videos_path(@option) %>
<h2>
<%= t("admin.answers.videos.new.title") %>
</h2>
<div class="poll-question-option-video-form">
<%= render "form", form_url: admin_option_videos_path(@option) %>
</div>

View File

@@ -47,8 +47,8 @@
</div> </div>
<div class="clear"> <div class="clear">
<% if can?(:create, Poll::Question::Answer.new(question: @question)) %> <% if can?(:create, Poll::Question::Option.new(question: @question)) %>
<%= link_to t("admin.questions.show.add_answer"), new_admin_question_answer_path(@question), <%= link_to t("admin.questions.show.add_answer"), new_admin_question_option_path(@question),
class: "button float-right" %> class: "button float-right" %>
<% else %> <% else %>
<div class="callout warning"> <div class="callout warning">
@@ -70,31 +70,31 @@
</tr> </tr>
</thead> </thead>
<tbody class="sortable" data-js-url="<%= admin_question_answers_order_answers_path(@question.id) %>"> <tbody class="sortable" data-js-url="<%= admin_question_options_order_options_path(@question.id) %>">
<% @question.question_answers.each do |answer| %> <% @question.question_options.each do |option| %>
<tr id="<%= dom_id(answer) %>" class="poll_question_answer" data-answer-id="<%= answer.id %>"> <tr id="<%= dom_id(option) %>" class="poll_question_option" data-option-id="<%= option.id %>">
<td class="align-top"><%= answer.title %></td> <td class="align-top"><%= option.title %></td>
<td class="align-top break"><%= wysiwyg(answer.description) %></td> <td class="align-top break"><%= wysiwyg(option.description) %></td>
<td class="align-top text-center"> <td class="align-top text-center">
(<%= answer.images.count %>) (<%= option.images.count %>)
<br> <br>
<%= link_to t("admin.questions.show.answers.images_list"), <%= link_to t("admin.questions.show.answers.images_list"),
admin_answer_images_path(answer) %> admin_option_images_path(option) %>
</td> </td>
<td class="align-top text-center"> <td class="align-top text-center">
(<%= answer.documents.count rescue 0 %>) (<%= option.documents.count rescue 0 %>)
<br> <br>
<%= link_to t("admin.questions.show.answers.documents_list"), <%= link_to t("admin.questions.show.answers.documents_list"),
admin_answer_documents_path(answer) %> admin_option_documents_path(option) %>
</td> </td>
<td class="align-top text-center"> <td class="align-top text-center">
(<%= answer.videos.count %>) (<%= option.videos.count %>)
<br> <br>
<%= link_to t("admin.questions.show.answers.video_list"), <%= link_to t("admin.questions.show.answers.video_list"),
admin_answer_videos_path(answer) %> admin_option_videos_path(option) %>
</td> </td>
<td> <td>
<%= render Admin::Poll::Questions::Answers::TableActionsComponent.new(answer) %> <%= render Admin::Poll::Questions::Options::TableActionsComponent.new(option) %>
</td> </td>
</tr> </tr>
<% end %> <% end %>

View File

@@ -9,11 +9,11 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<% question.question_answers.each_with_index do |answer, i| %> <% question.question_options.each_with_index do |option, i| %>
<% by_answer = by_question[question.id].present? ? by_question[question.id].group_by(&:answer) : {} %> <% by_answer = by_question[question.id].present? ? by_question[question.id].group_by(&:answer) : {} %>
<tr id="question_<%= question.id %>_<%= i %>_result"> <tr id="question_<%= question.id %>_<%= i %>_result">
<td><%= answer.title %></td> <td><%= option.title %></td>
<td class="text-center"><%= by_answer[answer.title].present? ? by_answer[answer.title].sum(&:amount) : 0 %></td> <td class="text-center"><%= by_answer[option.title].present? ? by_answer[option.title].sum(&:amount) : 0 %></td>
</tr> </tr>
<% end %> <% end %>
</tbody> </tbody>

View File

@@ -12,15 +12,15 @@
</div> </div>
</div> </div>
<div class="js-answers"> <div class="js-options">
<%= f.fields_for :question_answers do |answer| %> <%= f.fields_for :question_options do |option_form| %>
<%= render "question_answer_fields", f: answer %> <%= render "question_option_fields", f: option_form %>
<% end %> <% end %>
<div class="answer-links links row expanded"> <div class="option-links links row expanded">
<div class="small-12 column"> <div class="small-12 column">
<%= link_to_add_association t("dashboard.polls.question_fields.add_answer"), <%= link_to_add_association t("dashboard.polls.question_fields.add_answer"),
f, :question_answers, class: "button hollow" %> f, :question_options, class: "button hollow" %>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,5 +1,5 @@
<div class="nested-fields nested-answers small-12 medium-6 column"> <div class="nested-fields nested-options small-12 medium-6 column">
<div class="answer-fields"> <div class="option-fields">
<%= f.hidden_field :given_order %> <%= f.hidden_field :given_order %>
<div class="row expanded"> <div class="row expanded">
<div class="small-12 medium-9 column"> <div class="small-12 medium-9 column">

View File

@@ -39,11 +39,11 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<% question.question_answers.each_with_index do |answer, i| %> <% question.question_options.each_with_index do |option, i| %>
<% by_answer = by_question[question.id].present? ? by_question[question.id].group_by(&:answer) : {} %> <% by_answer = by_question[question.id].present? ? by_question[question.id].group_by(&:answer) : {} %>
<tr id="question_<%= question.id %>_<%= i %>_result"> <tr id="question_<%= question.id %>_<%= i %>_result">
<td><%= answer.title %></td> <td><%= option.title %></td>
<td><%= by_answer[answer.title].present? ? by_answer[answer.title].first.amount : 0 %></td> <td><%= by_answer[option.title].present? ? by_answer[option.title].first.amount : 0 %></td>
</tr> </tr>
<% end %> <% end %>
</tbody> </tbody>

View File

@@ -16,9 +16,9 @@
<div class="small-12 column"> <div class="small-12 column">
<h3><%= question.title %></h3> <h3><%= question.title %></h3>
</div> </div>
<% question.question_answers.each_with_index do |answer, i| %> <% question.question_options.each_with_index do |option, i| %>
<div class="small-12 medium-6 large-3 column end"> <div class="small-12 medium-6 large-3 column end">
<label><%= answer.title %></label> <label><%= option.title %></label>
<%= text_field_tag "questions[#{question.id}][#{i}]", answer_result_value(question.id, i), placeholder: "0" %> <%= text_field_tag "questions[#{question.id}][#{i}]", answer_result_value(question.id, i), placeholder: "0" %>
</div> </div>
<% end %> <% end %>

View File

@@ -1,6 +1,6 @@
<div class="orbit margin-bottom" role="region" aria-label="<%= answer.title %>" data-orbit data-auto-play="false" data-use-m-u-i="false"> <div class="orbit margin-bottom" role="region" aria-label="<%= option.title %>" data-orbit data-auto-play="false" data-use-m-u-i="false">
<button type="button" data-toggle="answer_<%= answer.id %> zoom_<%= answer.id %>" class="zoom-link hide-for-small-only"> <button type="button" data-toggle="option_<%= option.id %> zoom_<%= option.id %>" class="zoom-link hide-for-small-only">
<span id="zoom_<%= answer.id %>" class="icon-search-plus" data-toggler="icon-search-plus icon-search-minus"></span> <span id="zoom_<%= option.id %>" class="icon-search-plus" data-toggler="icon-search-plus icon-search-minus"></span>
<span class="show-for-sr"><%= t("polls.show.zoom_plus") %></span> <span class="show-for-sr"><%= t("polls.show.zoom_plus") %></span>
</button> </button>
@@ -16,7 +16,7 @@
</button> </button>
</li> </li>
<% answer.images.reverse.each_with_index do |image, index| %> <% option.images.reverse.each_with_index do |image, index| %>
<li class="orbit-slide <%= is_active_class(index) %>"> <li class="orbit-slide <%= is_active_class(index) %>">
<%= link_to image.attachment do %> <%= link_to image.attachment do %>
<%= image_tag image.attachment, <%= image_tag image.attachment,
@@ -30,7 +30,7 @@
</ul> </ul>
<nav class="orbit-bullets"> <nav class="orbit-bullets">
<% answer.images.each_with_index do |image, index| %> <% option.images.each_with_index do |image, index| %>
<button class="<%= is_active_class(index) %>" data-slide="<%= index %>"> <button class="<%= is_active_class(index) %>" data-slide="<%= index %>">
<span class="show-for-sr"><%= image.title.unicode_normalize %></span> <span class="show-for-sr"><%= image.title.unicode_normalize %></span>
</button> </button>

View File

@@ -1 +0,0 @@
$("#<%= dom_id(@question) %>_answers").html("<%= j render Polls::Questions::AnswersComponent.new(@question) %>");

View File

@@ -0,0 +1 @@
$("#<%= dom_id(@question) %>_options").html("<%= j render Polls::Questions::OptionsComponent.new(@question) %>");

View File

@@ -44,7 +44,7 @@
</div> </div>
</div> </div>
<div id="poll_more_info_answers" class="expanded poll-more-info-answers"> <div id="poll_more_info_options" class="expanded poll-more-info-options">
<div class="row padding"> <div class="row padding">
<%= render Polls::Questions::ReadMoreComponent.with_collection(@questions) %> <%= render Polls::Questions::ReadMoreComponent.with_collection(@questions) %>
</div> </div>

View File

@@ -25,8 +25,8 @@ module ActionDispatch::Routing::UrlFor
def namespaced_polymorphic_path(namespace, resource, options = {}) def namespaced_polymorphic_path(namespace, resource, options = {})
if %w[Budget::Group Budget::Heading Legislation::DraftVersion Legislation::Question if %w[Budget::Group Budget::Heading Legislation::DraftVersion Legislation::Question
Poll::Booth Poll::BoothAssignment Poll::Officer Poll::Question Poll::Question::Answer Poll::Booth Poll::BoothAssignment Poll::Officer Poll::Question Poll::Question::Option
Poll::Question::Answer::Video Poll::Shift SDG::LocalTarget].include?(resource.class.name) Poll::Question::Option::Video Poll::Shift SDG::LocalTarget].include?(resource.class.name)
resolve = resolve_for(resource) resolve = resolve_for(resource)
resolve_options = resolve.pop resolve_options = resolve.pop

View File

@@ -459,13 +459,13 @@ en:
image: image:
title: Title title: Title
attachment: "Choose image" attachment: "Choose image"
poll/question/answer: poll/question/option:
title: Answer title: Answer
description: Description description: Description
poll/question/answer/translation: poll/question/option/translation:
title: Answer title: Answer
description: "Description (optional)" description: "Description (optional)"
poll/question/answer/video: poll/question/option/video:
title: Title title: Title
url: External video url: External video
newsletter: newsletter:

View File

@@ -162,7 +162,7 @@ en:
legislation/process: process legislation/process: process
legislation/question: question legislation/question: question
poll/shift: Shift poll/shift: Shift
poll/question/answer: Answer poll/question/option: Answer
user: Account user: Account
verification/sms: phone verification/sms: phone
signature_sheet: Signature sheet signature_sheet: Signature sheet

View File

@@ -7,9 +7,9 @@ en:
direct_message: "You message has been sent successfully." direct_message: "You message has been sent successfully."
poll: "Poll created successfully." poll: "Poll created successfully."
poll_booth: "Booth created successfully." poll_booth: "Booth created successfully."
poll_question_answer: "Answer created successfully" poll_question_option: "Answer created successfully"
poll_question_answer_video: "Video created successfully" poll_question_option_video: "Video created successfully"
poll_question_answer_image: "Image uploaded successfully" poll_question_option_image: "Image uploaded successfully"
proposal: "Proposal created successfully." proposal: "Proposal created successfully."
proposal_notification: "Your message has been sent correctly." proposal_notification: "Your message has been sent correctly."
budget_investment: "Budget Investment created successfully." budget_investment: "Budget Investment created successfully."
@@ -34,7 +34,7 @@ en:
destroy: destroy:
budget_investment: "Investment project deleted successfully." budget_investment: "Investment project deleted successfully."
topic: "Topic deleted successfully." topic: "Topic deleted successfully."
poll_question_answer_image: "Image deleted successfully." poll_question_option_image: "Image deleted successfully."
poll_question_answer_video: "Answer video deleted successfully." poll_question_option_video: "Answer video deleted successfully."
valuator_group: "Valuator group deleted successfully" valuator_group: "Valuator group deleted successfully"
vote: "Vote deleted successfully" vote: "Vote deleted successfully"

View File

@@ -459,13 +459,13 @@ es:
image: image:
title: Título title: Título
attachment: "Selecciona una imagen" attachment: "Selecciona una imagen"
poll/question/answer: poll/question/option:
title: Respuesta title: Respuesta
description: Descripción description: Descripción
poll/question/answer/translation: poll/question/option/translation:
title: Respuesta title: Respuesta
description: "Descripción (opcional)" description: "Descripción (opcional)"
poll/question/answer/video: poll/question/option/video:
title: Título title: Título
url: Vídeo externo url: Vídeo externo
newsletter: newsletter:

View File

@@ -162,7 +162,7 @@ es:
legislation/process: el proceso legislation/process: el proceso
legislation/question: la pregunta legislation/question: la pregunta
poll/shift: el turno poll/shift: el turno
poll/question/answer: la respuesta poll/question/option: la respuesta
user: la cuenta user: la cuenta
verification/sms: el teléfono verification/sms: el teléfono
signature_sheet: la hoja de firmas signature_sheet: la hoja de firmas

View File

@@ -7,9 +7,9 @@ es:
direct_message: "Tu mensaje ha sido enviado correctamente." direct_message: "Tu mensaje ha sido enviado correctamente."
poll: "Votación creada correctamente." poll: "Votación creada correctamente."
poll_booth: "Urna creada correctamente." poll_booth: "Urna creada correctamente."
poll_question_answer: "Respuesta creada correctamente" poll_question_option: "Respuesta creada correctamente"
poll_question_answer_video: "Vídeo creado correctamente" poll_question_option_video: "Vídeo creado correctamente"
poll_question_answer_image: "Imagen cargada correctamente" poll_question_option_image: "Imagen cargada correctamente"
proposal: "Propuesta creada correctamente." proposal: "Propuesta creada correctamente."
proposal_notification: "Tu mensaje ha sido enviado correctamente." proposal_notification: "Tu mensaje ha sido enviado correctamente."
budget_investment: "Proyecto de gasto creado correctamente." budget_investment: "Proyecto de gasto creado correctamente."
@@ -34,7 +34,7 @@ es:
destroy: destroy:
budget_investment: "Proyecto de gasto eliminado." budget_investment: "Proyecto de gasto eliminado."
topic: "Tema eliminado." topic: "Tema eliminado."
poll_question_answer_image: "Imagen eliminada correctamente." poll_question_option_image: "Imagen eliminada correctamente."
poll_question_answer_video: "Vídeo de respuesta eliminado." poll_question_option_video: "Vídeo de respuesta eliminado."
valuator_group: "Grupo de evaluadores eliminado correctamente" valuator_group: "Grupo de evaluadores eliminado correctamente"
vote: "Voto eliminado correctamente" vote: "Voto eliminado correctamente"

View File

@@ -175,13 +175,13 @@ namespace :admin do
end end
resources :questions, shallow: true do resources :questions, shallow: true do
resources :answers, except: [:index, :show], controller: "questions/answers", shallow: false resources :options, except: [:index, :show], controller: "questions/options", shallow: false
resources :answers, only: [], controller: "questions/answers" do resources :options, only: [], controller: "questions/options" do
resources :images, controller: "questions/answers/images" resources :images, controller: "questions/options/images"
resources :videos, controller: "questions/answers/videos", shallow: false resources :videos, controller: "questions/options/videos", shallow: false
resources :documents, only: [:index, :create], controller: "questions/answers/documents" resources :documents, only: [:index, :create], controller: "questions/options/documents"
end end
post "/answers/order_answers", to: "questions/answers#order_answers" post "/options/order_options", to: "questions/options#order_options"
end end
resource :active_polls, only: [:create, :edit, :update] resource :active_polls, only: [:create, :edit, :update]
@@ -336,12 +336,12 @@ resolve "Poll::Officer" do |officer, options|
[:officer, options.merge(id: officer)] [:officer, options.merge(id: officer)]
end end
resolve "Poll::Question::Answer" do |answer, options| resolve "Poll::Question::Option" do |option, options|
[:question, :answer, options.merge(question_id: answer.question, id: answer)] [:question, :option, options.merge(question_id: option.question, id: option)]
end end
resolve "Poll::Question::Answer::Video" do |video, options| resolve "Poll::Question::Option::Video" do |video, options|
[:answer, :video, options.merge(answer_id: video.answer, id: video)] [:option, :video, options.merge(option_id: video.option, id: video)]
end end
resolve "Legislation::DraftVersion" do |version, options| resolve "Legislation::DraftVersion" do |version, options|

View File

@@ -1,6 +1,3 @@
require_dependency "poll/answer"
require_dependency "poll/question/answer"
section "Creating polls" do section "Creating polls" do
def create_poll!(attributes) def create_poll!(attributes)
poll = Poll.create!(attributes.merge(starts_at: 1.day.from_now, ends_at: 2.days.from_now)) poll = Poll.create!(attributes.merge(starts_at: 1.day.from_now, ends_at: 2.days.from_now))
@@ -52,7 +49,7 @@ section "Creating polls" do
end end
end end
section "Creating Poll Questions & Answers" do section "Creating Poll Questions & Options" do
Poll.find_each do |poll| Poll.find_each do |poll|
(3..5).to_a.sample.times do (3..5).to_a.sample.times do
question_title = Faker::Lorem.sentence(word_count: 3).truncate(60) + "?" question_title = Faker::Lorem.sentence(word_count: 3).truncate(60) + "?"
@@ -67,17 +64,17 @@ section "Creating Poll Questions & Answers" do
question.save! question.save!
Faker::Lorem.words(number: (2..4).to_a.sample).each_with_index do |title, index| Faker::Lorem.words(number: (2..4).to_a.sample).each_with_index do |title, index|
description = "<p>#{Faker::Lorem.paragraphs.join("</p><p>")}</p>" description = "<p>#{Faker::Lorem.paragraphs.join("</p><p>")}</p>"
answer = Poll::Question::Answer.new(question: question, option = Poll::Question::Option.new(question: question,
title: title.capitalize, title: title.capitalize,
description: description, description: description,
given_order: index + 1) given_order: index + 1)
Setting.enabled_locales.map do |locale| Setting.enabled_locales.map do |locale|
Globalize.with_locale(locale) do Globalize.with_locale(locale) do
answer.title = "#{title} (#{locale})" option.title = "#{title} (#{locale})"
answer.description = "#{description} (#{locale})" option.description = "#{description} (#{locale})"
end end
end end
answer.save! option.save!
end end
end end
end end
@@ -163,7 +160,7 @@ section "Creating Poll Voters" do
Poll::Answer.create!(question_id: question.id, Poll::Answer.create!(question_id: question.id,
author: user, author: user,
answer: question.question_answers.sample.title) answer: question.question_options.sample.title)
end end
end end
@@ -213,12 +210,12 @@ section "Creating Poll Results" do
author = Poll::Officer.first.user author = Poll::Officer.first.user
poll.questions.each do |question| poll.questions.each do |question|
question.question_answers.each do |answer| question.question_options.each do |option|
Poll::PartialResult.create!(officer_assignment: officer_assignment, Poll::PartialResult.create!(officer_assignment: officer_assignment,
booth_assignment: booth_assignment, booth_assignment: booth_assignment,
date: Date.current, date: Date.current,
question: question, question: question,
answer: answer.title, answer: option.title,
author: author, author: author,
amount: rand(999), amount: rand(999),
origin: "booth") origin: "booth")
@@ -243,17 +240,17 @@ section "Creating Poll Questions from Proposals" do
question.save! question.save!
Faker::Lorem.words(number: (2..4).to_a.sample).each_with_index do |title, index| Faker::Lorem.words(number: (2..4).to_a.sample).each_with_index do |title, index|
description = "<p>#{Faker::ChuckNorris.fact}</p>" description = "<p>#{Faker::ChuckNorris.fact}</p>"
answer = Poll::Question::Answer.new(question: question, option = Poll::Question::Option.new(question: question,
title: title.capitalize, title: title.capitalize,
description: description, description: description,
given_order: index + 1) given_order: index + 1)
Setting.enabled_locales.map do |locale| Setting.enabled_locales.map do |locale|
Globalize.with_locale(locale) do Globalize.with_locale(locale) do
answer.title = "#{title} (#{locale})" option.title = "#{title} (#{locale})"
answer.description = "#{description} (#{locale})" option.description = "#{description} (#{locale})"
end end
end end
answer.save! option.save!
end end
end end
end end
@@ -273,17 +270,17 @@ section "Creating Successful Proposals" do
question.save! question.save!
Faker::Lorem.words(number: (2..4).to_a.sample).each_with_index do |title, index| Faker::Lorem.words(number: (2..4).to_a.sample).each_with_index do |title, index|
description = "<p>#{Faker::ChuckNorris.fact}</p>" description = "<p>#{Faker::ChuckNorris.fact}</p>"
answer = Poll::Question::Answer.new(question: question, option = Poll::Question::Option.new(question: question,
title: title.capitalize, title: title.capitalize,
description: description, description: description,
given_order: index + 1) given_order: index + 1)
Setting.enabled_locales.map do |locale| Setting.enabled_locales.map do |locale|
Globalize.with_locale(locale) do Globalize.with_locale(locale) do
answer.title = "#{title} (#{locale})" option.title = "#{title} (#{locale})"
answer.description = "#{description} (#{locale})" option.description = "#{description} (#{locale})"
end end
end end
answer.save! option.save!
end end
end end
end end

View File

@@ -19,4 +19,20 @@ describe Admin::MenuComponent, controller: Admin::NewslettersController do
expect(page).to have_css "button[aria-expanded='false']", exact_text: "Settings" expect(page).to have_css "button[aria-expanded='false']", exact_text: "Settings"
end end
describe "#polls_link" do
it "is marked as current when managing poll options",
controller: Admin::Poll::Questions::OptionsController do
render_inline Admin::MenuComponent.new
expect(page).to have_css "[aria-current]", exact_text: "Polls"
end
it "is marked as current when managing poll options content",
controller: Admin::Poll::Questions::Options::VideosController do
render_inline Admin::MenuComponent.new
expect(page).to have_css "[aria-current]", exact_text: "Polls"
end
end
end end

View File

@@ -1,18 +1,18 @@
require "rails_helper" require "rails_helper"
describe Admin::Poll::Questions::Answers::Documents::IndexComponent do describe Admin::Poll::Questions::Options::Documents::IndexComponent do
before { sign_in(create(:administrator).user) } before { sign_in(create(:administrator).user) }
let(:future_answer) { create(:poll_question_answer, poll: create(:poll, :future)) } let(:future_option) { create(:poll_question_option, poll: create(:poll, :future)) }
let(:current_answer) { create(:poll_question_answer, poll: create(:poll)) } let(:current_option) { create(:poll_question_option, poll: create(:poll)) }
it "displays the 'Add new document' link when the poll has not started" do it "displays the 'Add new document' link when the poll has not started" do
render_inline Admin::Poll::Questions::Answers::Documents::IndexComponent.new(future_answer) render_inline Admin::Poll::Questions::Options::Documents::IndexComponent.new(future_option)
expect(page).to have_link "Add new document" expect(page).to have_link "Add new document"
end end
it "does not display the 'Add new document' link when the poll has started" do it "does not display the 'Add new document' link when the poll has started" do
render_inline Admin::Poll::Questions::Answers::Documents::IndexComponent.new(current_answer) render_inline Admin::Poll::Questions::Options::Documents::IndexComponent.new(current_option)
expect(page).not_to have_link "Add new document" expect(page).not_to have_link "Add new document"
end end

View File

@@ -1,13 +1,13 @@
require "rails_helper" require "rails_helper"
describe Admin::Poll::Questions::Answers::Documents::TableActionsComponent, :admin do describe Admin::Poll::Questions::Options::Documents::TableActionsComponent, :admin do
let(:future_answer) { create(:poll_question_answer, poll: create(:poll, :future)) } let(:future_option) { create(:poll_question_option, poll: create(:poll, :future)) }
let(:current_answer) { create(:poll_question_answer, poll: create(:poll)) } let(:current_option) { create(:poll_question_option, poll: create(:poll)) }
it "displays the destroy action when the poll has not started" do it "displays the destroy action when the poll has not started" do
document = create(:document, documentable: future_answer) document = create(:document, documentable: future_option)
render_inline Admin::Poll::Questions::Answers::Documents::TableActionsComponent.new(document) render_inline Admin::Poll::Questions::Options::Documents::TableActionsComponent.new(document)
expect(page).to have_link "Download file" expect(page).to have_link "Download file"
expect(page).to have_button "Delete" expect(page).to have_button "Delete"
@@ -15,9 +15,9 @@ describe Admin::Poll::Questions::Answers::Documents::TableActionsComponent, :adm
end end
it "does not display the destroy action when the poll has started" do it "does not display the destroy action when the poll has started" do
document = create(:document, documentable: current_answer) document = create(:document, documentable: current_option)
render_inline Admin::Poll::Questions::Answers::Documents::TableActionsComponent.new(document) render_inline Admin::Poll::Questions::Options::Documents::TableActionsComponent.new(document)
expect(page).to have_link "Download file" expect(page).to have_link "Download file"
expect(page).not_to have_button "Delete" expect(page).not_to have_button "Delete"

View File

@@ -1,19 +1,19 @@
require "rails_helper" require "rails_helper"
describe Admin::Poll::Questions::Answers::TableActionsComponent, :admin do describe Admin::Poll::Questions::Options::TableActionsComponent, :admin do
it "displays the edit and destroy actions when the poll has not started" do it "displays the edit and destroy actions when the poll has not started" do
answer = create(:poll_question_answer, poll: create(:poll, :future)) option = create(:poll_question_option, poll: create(:poll, :future))
render_inline Admin::Poll::Questions::Answers::TableActionsComponent.new(answer) render_inline Admin::Poll::Questions::Options::TableActionsComponent.new(option)
expect(page).to have_link "Edit" expect(page).to have_link "Edit"
expect(page).to have_button "Delete" expect(page).to have_button "Delete"
end end
it "does not display the edit and destroy actions when the poll has started" do it "does not display the edit and destroy actions when the poll has started" do
answer = create(:poll_question_answer, poll: create(:poll)) option = create(:poll_question_option, poll: create(:poll))
render_inline Admin::Poll::Questions::Answers::TableActionsComponent.new(answer) render_inline Admin::Poll::Questions::Options::TableActionsComponent.new(option)
expect(page).not_to have_link "Edit" expect(page).not_to have_link "Edit"
expect(page).not_to have_button "Delete" expect(page).not_to have_button "Delete"

View File

@@ -1,19 +1,19 @@
require "rails_helper" require "rails_helper"
describe Admin::Poll::Questions::Answers::Videos::TableActionsComponent, :admin do describe Admin::Poll::Questions::Options::Videos::TableActionsComponent, :admin do
it "displays the edit and destroy actions when the poll has not started" do it "displays the edit and destroy actions when the poll has not started" do
video = create(:poll_answer_video, poll: create(:poll, :future)) video = create(:poll_option_video, poll: create(:poll, :future))
render_inline Admin::Poll::Questions::Answers::Videos::TableActionsComponent.new(video) render_inline Admin::Poll::Questions::Options::Videos::TableActionsComponent.new(video)
expect(page).to have_link "Edit" expect(page).to have_link "Edit"
expect(page).to have_button "Delete" expect(page).to have_button "Delete"
end end
it "does not display the edit and destroy actions when the poll has started" do it "does not display the edit and destroy actions when the poll has started" do
video = create(:poll_answer_video, poll: create(:poll)) video = create(:poll_option_video, poll: create(:poll))
render_inline Admin::Poll::Questions::Answers::Videos::TableActionsComponent.new(video) render_inline Admin::Poll::Questions::Options::Videos::TableActionsComponent.new(video)
expect(page).not_to have_link "Edit" expect(page).not_to have_link "Edit"
expect(page).not_to have_button "Delete" expect(page).not_to have_button "Delete"

View File

@@ -1,12 +1,12 @@
require "rails_helper" require "rails_helper"
describe Polls::Questions::AnswersComponent do describe Polls::Questions::OptionsComponent do
include Rails.application.routes.url_helpers include Rails.application.routes.url_helpers
let(:poll) { create(:poll) } let(:poll) { create(:poll) }
let(:question) { create(:poll_question, :yes_no, poll: poll) } let(:question) { create(:poll_question, :yes_no, poll: poll) }
it "renders answers in given order" do it "renders answers in given order" do
render_inline Polls::Questions::AnswersComponent.new(question) render_inline Polls::Questions::OptionsComponent.new(question)
expect("Yes").to appear_before("No") expect("Yes").to appear_before("No")
end end
@@ -14,7 +14,7 @@ describe Polls::Questions::AnswersComponent do
it "renders buttons to vote question answers" do it "renders buttons to vote question answers" do
sign_in(create(:user, :verified)) sign_in(create(:user, :verified))
render_inline Polls::Questions::AnswersComponent.new(question) render_inline Polls::Questions::OptionsComponent.new(question)
expect(page).to have_button "Yes" expect(page).to have_button "Yes"
expect(page).to have_button "No" expect(page).to have_button "No"
@@ -26,7 +26,7 @@ describe Polls::Questions::AnswersComponent do
create(:poll_answer, author: user, question: question, answer: "Yes") create(:poll_answer, author: user, question: question, answer: "Yes")
sign_in(user) sign_in(user)
render_inline Polls::Questions::AnswersComponent.new(question) render_inline Polls::Questions::OptionsComponent.new(question)
expect(page).to have_button "You have voted Yes" expect(page).to have_button "You have voted Yes"
expect(page).to have_button "Vote No" expect(page).to have_button "Vote No"
@@ -40,7 +40,7 @@ describe Polls::Questions::AnswersComponent do
create(:poll_answer, author: user, question: question, answer: "Answer C") create(:poll_answer, author: user, question: question, answer: "Answer C")
sign_in(user) sign_in(user)
render_inline Polls::Questions::AnswersComponent.new(question) render_inline Polls::Questions::OptionsComponent.new(question)
expect(page).to have_button "You have voted Answer A" expect(page).to have_button "You have voted Answer A"
expect(page).to have_button "Vote Answer B", disabled: true expect(page).to have_button "Vote Answer B", disabled: true
@@ -48,7 +48,7 @@ describe Polls::Questions::AnswersComponent do
end end
it "when user is not signed in, renders answers links pointing to user sign in path" do it "when user is not signed in, renders answers links pointing to user sign in path" do
render_inline Polls::Questions::AnswersComponent.new(question) render_inline Polls::Questions::OptionsComponent.new(question)
expect(page).to have_link "Yes", href: new_user_session_path expect(page).to have_link "Yes", href: new_user_session_path
expect(page).to have_link "No", href: new_user_session_path expect(page).to have_link "No", href: new_user_session_path
@@ -57,7 +57,7 @@ describe Polls::Questions::AnswersComponent do
it "when user is not verified, renders answers links pointing to user verification in path" do it "when user is not verified, renders answers links pointing to user verification in path" do
sign_in(create(:user)) sign_in(create(:user))
render_inline Polls::Questions::AnswersComponent.new(question) render_inline Polls::Questions::OptionsComponent.new(question)
expect(page).to have_link "Yes", href: verification_path expect(page).to have_link "Yes", href: verification_path
expect(page).to have_link "No", href: verification_path expect(page).to have_link "No", href: verification_path
@@ -68,7 +68,7 @@ describe Polls::Questions::AnswersComponent do
create(:poll_voter, :from_booth, poll: poll, user: user) create(:poll_voter, :from_booth, poll: poll, user: user)
sign_in(user) sign_in(user)
render_inline Polls::Questions::AnswersComponent.new(question) render_inline Polls::Questions::OptionsComponent.new(question)
expect(page).to have_css "span.disabled", text: "Yes" expect(page).to have_css "span.disabled", text: "Yes"
expect(page).to have_css "span.disabled", text: "No" expect(page).to have_css "span.disabled", text: "No"
@@ -78,7 +78,7 @@ describe Polls::Questions::AnswersComponent do
question = create(:poll_question, :yes_no, poll: create(:poll, :expired)) question = create(:poll_question, :yes_no, poll: create(:poll, :expired))
sign_in(create(:user, :level_two)) sign_in(create(:user, :level_two))
render_inline Polls::Questions::AnswersComponent.new(question) render_inline Polls::Questions::OptionsComponent.new(question)
expect(page).to have_css "span.disabled", text: "Yes" expect(page).to have_css "span.disabled", text: "Yes"
expect(page).to have_css "span.disabled", text: "No" expect(page).to have_css "span.disabled", text: "No"
@@ -93,7 +93,7 @@ describe Polls::Questions::AnswersComponent do
poll.geozones << geozone poll.geozones << geozone
sign_in(create(:user, :level_two)) sign_in(create(:user, :level_two))
render_inline Polls::Questions::AnswersComponent.new(question) render_inline Polls::Questions::OptionsComponent.new(question)
expect(page).to have_css "span.disabled", text: "Yes" expect(page).to have_css "span.disabled", text: "Yes"
expect(page).to have_css "span.disabled", text: "No" expect(page).to have_css "span.disabled", text: "No"
@@ -103,7 +103,7 @@ describe Polls::Questions::AnswersComponent do
poll.geozones << geozone poll.geozones << geozone
sign_in(create(:user, :level_two, geozone: geozone)) sign_in(create(:user, :level_two, geozone: geozone))
render_inline Polls::Questions::AnswersComponent.new(question) render_inline Polls::Questions::OptionsComponent.new(question)
expect(page).to have_button "Yes" expect(page).to have_button "Yes"
expect(page).to have_button "No" expect(page).to have_button "No"

View File

@@ -1,18 +1,18 @@
require "rails_helper" require "rails_helper"
describe Polls::Questions::QuestionComponent do describe Polls::Questions::QuestionComponent do
it "renders more information links when any question answer has additional information" do it "renders more information links when any question option has additional information" do
question = create(:poll_question) question = create(:poll_question)
answer_a = create(:poll_question_answer, question: question, title: "Answer A") option_a = create(:poll_question_option, question: question, title: "Answer A")
answer_b = create(:poll_question_answer, question: question, title: "Answer B") option_b = create(:poll_question_option, question: question, title: "Answer B")
allow_any_instance_of(Poll::Question::Answer).to receive(:with_read_more?).and_return(true) allow_any_instance_of(Poll::Question::Option).to receive(:with_read_more?).and_return(true)
render_inline Polls::Questions::QuestionComponent.new(question: question) render_inline Polls::Questions::QuestionComponent.new(question: question)
poll_question = page.find("#poll_question_#{question.id}") poll_question = page.find("#poll_question_#{question.id}")
expect(poll_question).to have_content("Read more about") expect(poll_question).to have_content("Read more about")
expect(poll_question).to have_link("Answer A", href: "#answer_#{answer_a.id}") expect(poll_question).to have_link("Answer A", href: "#option_#{option_a.id}")
expect(poll_question).to have_link("Answer B", href: "#answer_#{answer_b.id}") expect(poll_question).to have_link("Answer B", href: "#option_#{option_b.id}")
expect(poll_question).to have_content("Answer A, Answer B") expect(poll_question).to have_content("Answer A, Answer B")
end end
end end

View File

@@ -4,51 +4,51 @@ describe Polls::Questions::ReadMoreComponent do
include Rails.application.routes.url_helpers include Rails.application.routes.url_helpers
let(:poll) { create(:poll) } let(:poll) { create(:poll) }
let(:question) { create(:poll_question, poll: poll, title: "Question title?") } let(:question) { create(:poll_question, poll: poll, title: "Question title?") }
let(:answer) { create(:poll_question_answer, question: question) } let(:option) { create(:poll_question_option, question: question) }
it "renders question title" do it "renders question title" do
create(:poll_question_answer, question: question, description: "Question answer description") create(:poll_question_option, question: question, description: "Question option description")
render_inline Polls::Questions::ReadMoreComponent.new(question: question) render_inline Polls::Questions::ReadMoreComponent.new(question: question)
expect(page).to have_content "Question title?" expect(page).to have_content "Question title?"
end end
it "renders answers in the given order" do it "renders options in the given order" do
create(:poll_question_answer, title: "Answer A", question: question, given_order: 2) create(:poll_question_option, title: "Answer A", question: question, given_order: 2)
create(:poll_question_answer, title: "Answer B", question: question, given_order: 1) create(:poll_question_option, title: "Answer B", question: question, given_order: 1)
render_inline Polls::Questions::ReadMoreComponent.new(question: question) render_inline Polls::Questions::ReadMoreComponent.new(question: question)
expect("Answer B").to appear_before("Answer A") expect("Answer B").to appear_before("Answer A")
end end
it "does not render when answers does not have more information" do it "does not render when options does not have more information" do
answer.update!(description: nil) option.update!(description: nil)
render_inline Polls::Questions::ReadMoreComponent.new(question: question) render_inline Polls::Questions::ReadMoreComponent.new(question: question)
expect(page).not_to be_rendered expect(page).not_to be_rendered
end end
it "renders answers with videos" do it "renders options with videos" do
create(:poll_answer_video, answer: answer, title: "Awesome video", url: "youtube.com/watch?v=123") create(:poll_option_video, option: option, title: "Awesome video", url: "youtube.com/watch?v=123")
render_inline Polls::Questions::ReadMoreComponent.new(question: question) render_inline Polls::Questions::ReadMoreComponent.new(question: question)
expect(page).to have_link("Awesome video", href: "youtube.com/watch?v=123") expect(page).to have_link("Awesome video", href: "youtube.com/watch?v=123")
end end
it "renders answers with images" do it "renders options with images" do
create(:image, imageable: answer, title: "The yes movement") create(:image, imageable: option, title: "The yes movement")
render_inline Polls::Questions::ReadMoreComponent.new(question: question) render_inline Polls::Questions::ReadMoreComponent.new(question: question)
expect(page).to have_css "img[alt='The yes movement']" expect(page).to have_css "img[alt='The yes movement']"
end end
it "renders answers with documents" do it "renders options with documents" do
create(:document, documentable: answer, title: "The yes movement") create(:document, documentable: option, title: "The yes movement")
render_inline Polls::Questions::ReadMoreComponent.new(question: question) render_inline Polls::Questions::ReadMoreComponent.new(question: question)

View File

@@ -1,11 +1,11 @@
require "rails_helper" require "rails_helper"
describe Admin::Poll::Questions::Answers::DocumentsController, :admin do describe Admin::Poll::Questions::Options::DocumentsController, :admin do
let(:current_answer) { create(:poll_question_answer, poll: create(:poll)) } let(:current_option) { create(:poll_question_option, poll: create(:poll)) }
let(:future_answer) { create(:poll_question_answer, poll: create(:poll, :future)) } let(:future_option) { create(:poll_question_option, poll: create(:poll, :future)) }
describe "POST create" do describe "POST create" do
let(:answer_attributes) do let(:option_attributes) do
{ {
documents_attributes: { documents_attributes: {
"0" => { "0" => {
@@ -18,16 +18,16 @@ describe Admin::Poll::Questions::Answers::DocumentsController, :admin do
end end
it "is not possible for an already started poll" do it "is not possible for an already started poll" do
post :create, params: { poll_question_answer: answer_attributes, answer_id: current_answer } post :create, params: { poll_question_option: option_attributes, option_id: current_option }
expect(flash[:alert]).to eq "You do not have permission to carry out the action 'update' on Answer." expect(flash[:alert]).to eq "You do not have permission to carry out the action 'update' on Option."
expect(Document.count).to eq 0 expect(Document.count).to eq 0
end end
it "is possible for a not started poll" do it "is possible for a not started poll" do
post :create, params: { poll_question_answer: answer_attributes, answer_id: future_answer } post :create, params: { poll_question_option: option_attributes, option_id: future_option }
expect(response).to redirect_to admin_answer_documents_path(future_answer) expect(response).to redirect_to admin_option_documents_path(future_option)
expect(flash[:notice]).to eq "Document uploaded successfully" expect(flash[:notice]).to eq "Document uploaded successfully"
expect(Document.count).to eq 1 expect(Document.count).to eq 1
end end

View File

@@ -1,11 +1,11 @@
require "rails_helper" require "rails_helper"
describe Admin::Poll::Questions::Answers::ImagesController, :admin do describe Admin::Poll::Questions::Options::ImagesController, :admin do
let(:current_answer) { create(:poll_question_answer, poll: create(:poll)) } let(:current_option) { create(:poll_question_option, poll: create(:poll)) }
let(:future_answer) { create(:poll_question_answer, poll: create(:poll, :future)) } let(:future_option) { create(:poll_question_option, poll: create(:poll, :future)) }
describe "POST create" do describe "POST create" do
let(:answer_attributes) do let(:option_attributes) do
{ {
images_attributes: { images_attributes: {
"0" => { "0" => {
@@ -18,16 +18,16 @@ describe Admin::Poll::Questions::Answers::ImagesController, :admin do
end end
it "is not possible for an already started poll" do it "is not possible for an already started poll" do
post :create, params: { poll_question_answer: answer_attributes, answer_id: current_answer } post :create, params: { poll_question_option: option_attributes, option_id: current_option }
expect(flash[:alert]).to eq "You do not have permission to carry out the action 'update' on Answer." expect(flash[:alert]).to eq "You do not have permission to carry out the action 'update' on Option."
expect(Image.count).to eq 0 expect(Image.count).to eq 0
end end
it "is possible for a not started poll" do it "is possible for a not started poll" do
post :create, params: { poll_question_answer: answer_attributes, answer_id: future_answer } post :create, params: { poll_question_option: option_attributes, option_id: future_option }
expect(response).to redirect_to admin_answer_images_path(future_answer) expect(response).to redirect_to admin_option_images_path(future_option)
expect(flash[:notice]).to eq "Image uploaded successfully" expect(flash[:notice]).to eq "Image uploaded successfully"
expect(Image.count).to eq 1 expect(Image.count).to eq 1
end end
@@ -35,7 +35,7 @@ describe Admin::Poll::Questions::Answers::ImagesController, :admin do
describe "DELETE destroy" do describe "DELETE destroy" do
it "is not possible for an already started poll" do it "is not possible for an already started poll" do
current_image = create(:image, imageable: current_answer) current_image = create(:image, imageable: current_option)
delete :destroy, xhr: true, params: { id: current_image } delete :destroy, xhr: true, params: { id: current_image }
expect(flash[:alert]).to eq "You do not have permission to carry out the action 'destroy' on Image." expect(flash[:alert]).to eq "You do not have permission to carry out the action 'destroy' on Image."
@@ -43,7 +43,7 @@ describe Admin::Poll::Questions::Answers::ImagesController, :admin do
end end
it "is possible for a not started poll" do it "is possible for a not started poll" do
future_image = create(:image, imageable: future_answer) future_image = create(:image, imageable: future_option)
delete :destroy, xhr: true, params: { id: future_image } delete :destroy, xhr: true, params: { id: future_image }
expect(Image.count).to eq 0 expect(Image.count).to eq 0

View File

@@ -1,48 +1,48 @@
require "rails_helper" require "rails_helper"
describe Admin::Poll::Questions::Answers::VideosController, :admin do describe Admin::Poll::Questions::Options::VideosController, :admin do
let(:current_answer) { create(:poll_question_answer, poll: create(:poll)) } let(:current_option) { create(:poll_question_option, poll: create(:poll)) }
let(:future_answer) { create(:poll_question_answer, poll: create(:poll, :future)) } let(:future_option) { create(:poll_question_option, poll: create(:poll, :future)) }
describe "POST create" do describe "POST create" do
it "is not possible for an already started poll" do it "is not possible for an already started poll" do
post :create, params: { post :create, params: {
poll_question_answer_video: { poll_question_option_video: {
title: "Video from started poll", title: "Video from started poll",
url: "https://www.youtube.com/watch?v=-JMf43st-1A" url: "https://www.youtube.com/watch?v=-JMf43st-1A"
}, },
answer_id: current_answer option_id: current_option
} }
expect(flash[:alert]).to eq "You do not have permission to carry out the action 'create' on Video." expect(flash[:alert]).to eq "You do not have permission to carry out the action 'create' on Video."
expect(Poll::Question::Answer::Video.count).to eq 0 expect(Poll::Question::Option::Video.count).to eq 0
end end
it "is possible for a not started poll" do it "is possible for a not started poll" do
post :create, params: { post :create, params: {
poll_question_answer_video: { poll_question_option_video: {
title: "Video from not started poll", title: "Video from not started poll",
url: "https://www.youtube.com/watch?v=-JMf43st-1A" url: "https://www.youtube.com/watch?v=-JMf43st-1A"
}, },
answer_id: future_answer option_id: future_option
} }
expect(response).to redirect_to admin_answer_videos_path(future_answer) expect(response).to redirect_to admin_option_videos_path(future_option)
expect(flash[:notice]).to eq "Video created successfully" expect(flash[:notice]).to eq "Video created successfully"
expect(Poll::Question::Answer::Video.count).to eq 1 expect(Poll::Question::Option::Video.count).to eq 1
end end
end end
describe "PATCH update" do describe "PATCH update" do
it "is not possible for an already started poll" do it "is not possible for an already started poll" do
current_video = create(:poll_answer_video, answer: current_answer, title: "Sample title") current_video = create(:poll_option_video, option: current_option, title: "Sample title")
patch :update, params: { patch :update, params: {
poll_question_answer_video: { poll_question_option_video: {
title: "New title" title: "New title"
}, },
id: current_video, id: current_video,
answer_id: current_answer option_id: current_option
} }
expect(flash[:alert]).to eq "You do not have permission to carry out the action 'update' on Video." expect(flash[:alert]).to eq "You do not have permission to carry out the action 'update' on Video."
@@ -50,17 +50,17 @@ describe Admin::Poll::Questions::Answers::VideosController, :admin do
end end
it "is possible for a not started poll" do it "is possible for a not started poll" do
future_video = create(:poll_answer_video, answer: future_answer) future_video = create(:poll_option_video, option: future_option)
patch :update, params: { patch :update, params: {
poll_question_answer_video: { poll_question_option_video: {
title: "New title" title: "New title"
}, },
id: future_video, id: future_video,
answer_id: future_answer option_id: future_option
} }
expect(response).to redirect_to admin_answer_videos_path(future_answer) expect(response).to redirect_to admin_option_videos_path(future_option)
expect(flash[:notice]).to eq "Changes saved" expect(flash[:notice]).to eq "Changes saved"
expect(future_video.reload.title).to eq "New title" expect(future_video.reload.title).to eq "New title"
end end
@@ -68,20 +68,20 @@ describe Admin::Poll::Questions::Answers::VideosController, :admin do
describe "DELETE destroy" do describe "DELETE destroy" do
it "is not possible for an already started poll" do it "is not possible for an already started poll" do
current_video = create(:poll_answer_video, answer: current_answer) current_video = create(:poll_option_video, option: current_option)
delete :destroy, params: { answer_id: current_answer, id: current_video } delete :destroy, params: { option_id: current_option, id: current_video }
expect(flash[:alert]).to eq "You do not have permission to carry out the action 'destroy' on Video." expect(flash[:alert]).to eq "You do not have permission to carry out the action 'destroy' on Video."
expect(Poll::Question::Answer::Video.count).to eq 1 expect(Poll::Question::Option::Video.count).to eq 1
end end
it "is possible for a not started poll" do it "is possible for a not started poll" do
future_video = create(:poll_answer_video, answer: future_answer) future_video = create(:poll_option_video, option: future_option)
delete :destroy, params: { answer_id: future_answer, id: future_video } delete :destroy, params: { option_id: future_option, id: future_video }
expect(response).to redirect_to admin_answer_videos_path(future_answer) expect(response).to redirect_to admin_option_videos_path(future_option)
expect(flash[:notice]).to eq "Answer video deleted successfully." expect(flash[:notice]).to eq "Answer video deleted successfully."
expect(Poll::Question::Answer::Video.count).to eq 0 expect(Poll::Question::Option::Video.count).to eq 0
end end
end end
end end

Some files were not shown because too many files have changed in this diff Show More