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 map
|
||||||
//= require polls
|
//= require polls
|
||||||
//= require sortable
|
//= require sortable
|
||||||
|
//= require table_sortable
|
||||||
|
|
||||||
var initialize_modules = function() {
|
var initialize_modules = function() {
|
||||||
App.Comments.initialize();
|
App.Comments.initialize();
|
||||||
@@ -113,6 +114,7 @@ var initialize_modules = function() {
|
|||||||
App.Map.initialize();
|
App.Map.initialize();
|
||||||
App.Polls.initialize();
|
App.Polls.initialize();
|
||||||
App.Sortable.initialize();
|
App.Sortable.initialize();
|
||||||
|
App.TableSortable.initialize();
|
||||||
};
|
};
|
||||||
|
|
||||||
$(function(){
|
$(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
|
// * English: https://github.com/consul/consul/blob/master/CUSTOMIZE_EN.md#css
|
||||||
// * Spanish: https://github.com/consul/consul/blob/master/CUSTOMIZE_ES.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
|
@users_who_have_sent_message = DirectMessage.select(:sender_id).distinct.count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def polls
|
||||||
|
@polls = ::Poll.current
|
||||||
|
@participants = ::Poll::Voter.where(poll: @polls)
|
||||||
|
end
|
||||||
|
|
||||||
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>
|
<h1 class="inline-block"><%= t "admin.stats.show.stats_title" %></h1>
|
||||||
|
|
||||||
<div class="float-right clear">
|
<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"),
|
<%= link_to t("admin.stats.show.direct_messages"),
|
||||||
direct_messages_admin_stats_path, class: "button hollow" %>
|
direct_messages_admin_stats_path, class: "button hollow" %>
|
||||||
<%= link_to t("admin.stats.show.proposal_notifications"),
|
<%= link_to t("admin.stats.show.proposal_notifications"),
|
||||||
|
|||||||
@@ -958,6 +958,7 @@ en:
|
|||||||
direct_messages: Direct messages
|
direct_messages: Direct messages
|
||||||
proposal_notifications: Proposal notifications
|
proposal_notifications: Proposal notifications
|
||||||
incomplete_verifications: Incomplete verifications
|
incomplete_verifications: Incomplete verifications
|
||||||
|
polls: Polls
|
||||||
direct_messages:
|
direct_messages:
|
||||||
title: Direct messages
|
title: Direct messages
|
||||||
total: Total
|
total: Total
|
||||||
@@ -966,6 +967,17 @@ en:
|
|||||||
title: Proposal notifications
|
title: Proposal notifications
|
||||||
total: Total
|
total: Total
|
||||||
proposals_with_notifications: Proposals with notifications
|
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:
|
tags:
|
||||||
create: Create topic
|
create: Create topic
|
||||||
destroy: Destroy topic
|
destroy: Destroy topic
|
||||||
|
|||||||
@@ -958,6 +958,7 @@ es:
|
|||||||
direct_messages: Mensajes directos
|
direct_messages: Mensajes directos
|
||||||
proposal_notifications: Notificaciones de propuestas
|
proposal_notifications: Notificaciones de propuestas
|
||||||
incomplete_verifications: Verificaciones incompletas
|
incomplete_verifications: Verificaciones incompletas
|
||||||
|
polls: Votaciones
|
||||||
direct_messages:
|
direct_messages:
|
||||||
title: Mensajes directos
|
title: Mensajes directos
|
||||||
total: Total
|
total: Total
|
||||||
@@ -966,6 +967,17 @@ es:
|
|||||||
title: Notificaciones de propuestas
|
title: Notificaciones de propuestas
|
||||||
total: Total
|
total: Total
|
||||||
proposals_with_notifications: Propuestas con notificaciones
|
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:
|
tags:
|
||||||
create: Crear tema
|
create: Crear tema
|
||||||
destroy: Eliminar tema
|
destroy: Eliminar tema
|
||||||
|
|||||||
@@ -339,6 +339,7 @@ Rails.application.routes.draw do
|
|||||||
resource :stats, only: :show do
|
resource :stats, only: :show do
|
||||||
get :proposal_notifications, on: :collection
|
get :proposal_notifications, on: :collection
|
||||||
get :direct_messages, on: :collection
|
get :direct_messages, on: :collection
|
||||||
|
get :polls, on: :collection
|
||||||
end
|
end
|
||||||
|
|
||||||
namespace :legislation do
|
namespace :legislation do
|
||||||
|
|||||||
@@ -162,4 +162,99 @@ feature 'Stats' do
|
|||||||
|
|
||||||
end
|
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
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user