Merge pull request #2102 from wairbut-m2c/iagirre-admin-poll-stats

Iagirre admin poll stats
This commit is contained in:
María Checa
2017-11-29 20:07:53 +01:00
committed by GitHub
10 changed files with 245 additions and 1 deletions

View File

@@ -73,6 +73,7 @@
//= require map
//= require polls
//= require sortable
//= require table_sortable
var initialize_modules = function() {
App.Comments.initialize();
@@ -113,6 +114,7 @@ var initialize_modules = function() {
App.Map.initialize();
App.Polls.initialize();
App.Sortable.initialize();
App.TableSortable.initialize();
};
$(function(){

View File

@@ -0,0 +1,23 @@
App.TableSortable =
getCellValue: (row, index) ->
$(row).children('td').eq(index).text()
comparer: (index) ->
(a, b) ->
valA = App.TableSortable.getCellValue(a, index)
valB = App.TableSortable.getCellValue(b, index)
return if $.isNumeric(valA) and $.isNumeric(valB) then valA - valB else valA.localeCompare(valB)
initialize: ->
$('table.sortable th').click ->
table = $(this).parents('table').eq(0)
rows = table.find('tr:gt(0)').not('tfoot tr').toArray().sort(App.TableSortable.comparer($(this).index()))
@asc = !@asc
if !@asc
rows = rows.reverse()
i = 0
while i < rows.length
table.append rows[i]
i++
return

View File

@@ -3,3 +3,8 @@
// * English: https://github.com/consul/consul/blob/master/CUSTOMIZE_EN.md#css
// * Spanish: https://github.com/consul/consul/blob/master/CUSTOMIZE_ES.md#css
//
table.sortable thead th:hover {
text-decoration: underline;
cursor: pointer;
}

View File

@@ -36,4 +36,9 @@ class Admin::StatsController < Admin::BaseController
@users_who_have_sent_message = DirectMessage.select(:sender_id).distinct.count
end
def polls
@polls = ::Poll.current
@participants = ::Poll::Voter.where(poll: @polls)
end
end

View File

@@ -0,0 +1,87 @@
<%= back_link_to %>
<h2 id="top"><%= t("admin.stats.polls.title")%></h2>
<div class="stats">
<div class="row stats-numbers">
<div class="small-12 medium-3 column">
<p class="featured">
<%= t("admin.stats.polls.web_participants") %><br>
<span id="web_participants" class="number">
<%= @participants.web.select(:user_id).distinct.count %>
</span>
</p>
</div>
<div class="small-12 medium-3 column end">
<p class="featured">
<%= t("admin.stats.polls.total_participants") %><br>
<span id="participants" class="number">
<%= @participants.select(:user_id).distinct.count %>
</span>
</p>
</div>
</div>
</div>
<h2><%= t("admin.stats.polls.all") %></h2>
<table id="polls" class="stack sortable">
<thead>
<tr>
<th><%= t("admin.stats.polls.table.poll_name") %></th>
<th class="name text-right"><%= t("admin.stats.polls.total_participants") %></th>
<th class="name text-right"><%= t("admin.stats.polls.table.origin_web") %></th>
</tr>
</thead>
<% @polls.each do |poll| %>
<tr id="<%= dom_id(poll) %>">
<td class="name">
<a href="#<%= dom_id(poll) %>_questions"><%= poll.name %></a>
</td>
<td class="name text-right">
<%= poll.voters.select(:user_id).distinct.count %>
</td>
<td class="name text-right">
<%= poll.voters.web.select(:user_id).distinct.count %>
</td>
</tr>
<% end %>
</table>
<% @polls.each do |poll| %>
<h3 id="<%= dom_id(poll) %>_questions">
<%= t("admin.stats.polls.poll_questions", poll: poll.name) %>
</h3>
<table class="stack sortable">
<thead>
<tr>
<th><%= t("admin.stats.polls.table.question_name") %></th>
<th class="name text-right">
<%= t("admin.stats.polls.table.origin_web") %>
</th>
</tr>
</thead>
<% poll.questions.each do |question| %>
<tr id="<%= dom_id(question) %>">
<td class="name">
<%= question.title %>
</td>
<td class="name text-right">
<%= ::Poll::Answer.by_question(question).count %>
</td>
</tr>
<% end %>
<tfoot>
<tr id="<%= dom_id(poll) %>_questions_total">
<th></th>
<th class="name text-right">
<strong>
<%= t("admin.stats.polls.table.origin_total") %>:
<%= ::Poll::Answer.where(question: poll.questions)
.select(:author_id).distinct.count %>
</strong>
</th>
</tr>
</tfoot>
</table>
<% end %>

View File

@@ -7,6 +7,8 @@
<h1 class="inline-block"><%= t "admin.stats.show.stats_title" %></h1>
<div class="float-right clear">
<%= link_to t("admin.stats.show.polls"),
polls_admin_stats_path, class: "button hollow" %>
<%= link_to t("admin.stats.show.direct_messages"),
direct_messages_admin_stats_path, class: "button hollow" %>
<%= link_to t("admin.stats.show.proposal_notifications"),

View File

@@ -958,6 +958,7 @@ en:
direct_messages: Direct messages
proposal_notifications: Proposal notifications
incomplete_verifications: Incomplete verifications
polls: Polls
direct_messages:
title: Direct messages
total: Total
@@ -966,6 +967,17 @@ en:
title: Proposal notifications
total: Total
proposals_with_notifications: Proposals with notifications
polls:
title: Poll Stats
all: Polls
web_participants: Web participants
total_participants: Total Participants
poll_questions: "Questions from poll: %{poll}"
table:
poll_name: Poll
question_name: Question
origin_web: Web participants
origin_total: Total participants
tags:
create: Create topic
destroy: Destroy topic

View File

@@ -958,6 +958,7 @@ es:
direct_messages: Mensajes directos
proposal_notifications: Notificaciones de propuestas
incomplete_verifications: Verificaciones incompletas
polls: Votaciones
direct_messages:
title: Mensajes directos
total: Total
@@ -966,6 +967,17 @@ es:
title: Notificaciones de propuestas
total: Total
proposals_with_notifications: Propuestas con notificaciones
polls:
title: Estadísticas de votaciones
all: Votaciones
web_participants: Participantes en Web
total_participants: Participantes totales
poll_questions: "Preguntas de votación: %{poll}"
table:
poll_name: Votación
question_name: Pregunta
origin_web: Participantes Web
origin_total: Participantes Totales
tags:
create: Crear tema
destroy: Eliminar tema

View File

@@ -339,6 +339,7 @@ Rails.application.routes.draw do
resource :stats, only: :show do
get :proposal_notifications, on: :collection
get :direct_messages, on: :collection
get :polls, on: :collection
end
namespace :legislation do

View File

@@ -162,4 +162,99 @@ feature 'Stats' do
end
context "Polls" do
scenario "Total participants by origin" do
oa = create(:poll_officer_assignment)
3.times { create(:poll_voter, origin: "web") }
visit admin_stats_path
within(".stats") do
click_link "Polls"
end
within("#web_participants") do
expect(page).to have_content "3"
end
end
scenario "Total participants" do
user = create(:user, :level_two)
3.times { create(:poll_voter, user: user) }
create(:poll_voter)
visit admin_stats_path
within(".stats") do
click_link "Polls"
end
within("#participants") do
expect(page).to have_content "2"
end
end
scenario "Participants by poll" do
oa = create(:poll_officer_assignment)
poll1 = create(:poll)
poll2 = create(:poll)
1.times { create(:poll_voter, poll: poll1, origin: "web") }
2.times { create(:poll_voter, poll: poll2, origin: "web") }
visit admin_stats_path
within(".stats") do
click_link "Polls"
end
within("#polls") do
within("#poll_#{poll1.id}") do
expect(page).to have_content "1"
end
within("#poll_#{poll2.id}") do
expect(page).to have_content "2"
end
end
end
scenario "Participants by poll question" do
user1 = create(:user, :level_two)
user2 = create(:user, :level_two)
poll = create(:poll)
question1 = create(:poll_question, :with_answers, poll: poll)
question2 = create(:poll_question, :with_answers, poll: poll)
create(:poll_answer, question: question1, author: user1)
create(:poll_answer, question: question2, author: user1)
create(:poll_answer, question: question2, author: user2)
visit admin_stats_path
within(".stats") do
click_link "Polls"
end
within("#poll_question_#{question1.id}") do
expect(page).to have_content "1"
end
within("#poll_question_#{question2.id}") do
expect(page).to have_content "2"
end
within("#poll_#{poll.id}_questions_total") do
expect(page).to have_content "2"
end
end
end
end