Merge pull request #2102 from wairbut-m2c/iagirre-admin-poll-stats
Iagirre admin poll stats
This commit is contained in:
@@ -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(){
|
||||
|
||||
23
app/assets/javascripts/table_sortable.js.coffee
Normal file
23
app/assets/javascripts/table_sortable.js.coffee
Normal 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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
87
app/views/admin/stats/polls.html.erb
Normal file
87
app/views/admin/stats/polls.html.erb
Normal 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 %>
|
||||
@@ -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"),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user