From 902fc722a17bbc119e6b53d7c882d15c44bfc75a Mon Sep 17 00:00:00 2001 From: Giovanne Marcelo <gms15@inf.ufpr.br> Date: Wed, 17 Feb 2016 19:39:34 -0200 Subject: [PATCH] Adding collections statistics and fixing views --- app/assets/javascripts/management.js | 24 ++-- .../javascripts/management/colections.js | 58 +++----- .../management/complaints_controller.rb | 9 +- .../management/statistics_controller.rb | 38 ++---- .../management/welcome_controller.rb | 5 + .../management/complaints/index.html.erb | 13 +- app/views/management/complaints/show.html.erb | 126 ------------------ .../statistics/_general_stats.html.erb | 10 +- .../statistics/collections.html.erb | 38 ++++-- .../management/statistics/complaints.html.erb | 21 +-- .../management/statistics/index.html.erb | 2 +- .../statistics/learning_objects.html.erb | 5 +- .../management/statistics/users.html.erb | 5 +- app/views/management/welcome/index.html.erb | 2 +- 14 files changed, 121 insertions(+), 235 deletions(-) delete mode 100644 app/views/management/complaints/show.html.erb diff --git a/app/assets/javascripts/management.js b/app/assets/javascripts/management.js index 4f0fe003..47fb7677 100644 --- a/app/assets/javascripts/management.js +++ b/app/assets/javascripts/management.js @@ -35,25 +35,31 @@ $(document).ready(function(){ var data_users = dataUsers(teachers,curators,admins); } - if(document.getElementById("lcomplaints") != null) { + if(document.getElementById("lcomplaints") != null) { - false_user = document.getElementById("lcomplaints").value; - agressive_user = document.getElementById("lcomplaints_false").value; - offensive_object = document.getElementById("lcomplaints_offensive").value; - violates_copyright = document.getElementById("lcomplaints_violates").value; + false_user = document.getElementById("lcomplaints").value; + agressive_user = document.getElementById("lcomplaints_false").value; + offensive_object = document.getElementById("lcomplaints_offensive").value; + violates_copyright = document.getElementById("lcomplaints_violates").value; + var data_complaints = dataComplaints(false_user,agressive_user,offensive_object,violates_copyright); + } - var data_complaints = dataComplaints(false_user,agressive_user,offensive_object,violates_copyright); + if (document.getElementById("lcollection") !== null) { + visualised = document.getElementById("lcollection").value; + non_visualised = document.getElementById("lcollection_non").value; + var data_collections = dataCollections(visualised,non_visualised); } - var charts = ["colections","users","learning_objects","accesses","complaints"]; + + var charts = ["collections","users","learning_objects","accesses","complaints"]; for(i=0;i<charts.length;i++) { if ( document.getElementById(charts[i]) ) { var ctx = document.getElementById(charts[i]).getContext("2d"); switch ( charts[i] ){ - case "colections": - new Chart(ctx).Pie(data_colections,pie_options); + case "collections": + new Chart(ctx).Pie(data_collections,pie_options); var colections_chart = new Chart(ctx).Pie(data_colections); break; case "users": diff --git a/app/assets/javascripts/management/colections.js b/app/assets/javascripts/management/colections.js index 296fe716..62afadb2 100644 --- a/app/assets/javascripts/management/colections.js +++ b/app/assets/javascripts/management/colections.js @@ -1,48 +1,28 @@ -//Configurações de gráficos PIE -// //mais infos: www.chartjs.org/docs/ -var data_colections = [ +//confurações dos gráficos de linha +//mais infos: www.chartjs.org/docs/ + + + +//var visual = document.getElementById("object").value; +//alert(visual); +function dataCollections(visualised,non_visualised) { + var data = [ { - value: 92, + value: visualised, color:"#F7464A", highlight: "#FF5A5E", - label: "Matemática" - }, - { - value: 57, + label: "Visualizados" + }, + { + value: non_visualised, color: "#46BFBD", highlight: "#5AD3D1", - label: "História" - }, - { - value: 78, - color: "#FDB45C", - highlight: "#FFC870", - label: "LÃngua Portuguesa" - }, - { - value: 43, - color: "#FAAAAA", - highlight: "#FBBBBB", - label: "FÃsica" - }, - { - value: 3, - color: "#876543", - highlight: "#887766", - label: "Artes" - }, - { - value: 40, - color: "#B3F8A1", - highlight: "#BBFABB", - label: "Sociologia" - } - -]; - - - + label: "Não Visualizados" + } + ]; + return data; +} var pie_options = { //Boolean - Whether we should show a stroke on each segment diff --git a/app/controllers/management/complaints_controller.rb b/app/controllers/management/complaints_controller.rb index 82dc018d..52ad6a8b 100644 --- a/app/controllers/management/complaints_controller.rb +++ b/app/controllers/management/complaints_controller.rb @@ -3,6 +3,8 @@ class Management::ComplaintsController < ManagementController before_action :set_complaint, only: :destroy def index + @complaints = Complaint.all + @date = params[:period] @date_limit = case @date.to_i when 1 then @@ -15,16 +17,13 @@ class Management::ComplaintsController < ManagementController 1.month.ago when 5 then 6.month.ago - when 7 then + when 6 then 1.year.ago else - 10.year.ago + -DateTime::Infinity.new end - - @complaints = Complaint.all @complaints_in_period = @complaints.select{ |complaint| complaint.created_at >= @date_limit} @complaints_objs = @complaints_in_period.uniq{|x| x.complaintable.name}.size - end diff --git a/app/controllers/management/statistics_controller.rb b/app/controllers/management/statistics_controller.rb index f5267628..6e36f417 100644 --- a/app/controllers/management/statistics_controller.rb +++ b/app/controllers/management/statistics_controller.rb @@ -1,23 +1,18 @@ class Management::StatisticsController < ManagementController - include RepositoriesProxy + before_action :set_statistics before_action :authenticate_user!, except: [:index, :show, :like] - #inicialização, primeira query - @@flag = 0 - def index - set_statistics @n_users = @@n_users @n_collections = @@n_collections @n_non_visualised = @@n_non_visualised @n_learning_objects = @@n_learning_objects - @n_complaints == @@n_complaints + @n_complaints = @@n_complaints @total_accesses= User.sum("sign_in_count") end def users - #missing roles @n_users = User.count @n_curators = Role.find_by(name: "curator").users.size @n_admins = Role.find_by(name: "admin").users.size @@ -29,7 +24,9 @@ class Management::StatisticsController < ManagementController end def collections - @n_collections = @@n_collections || [] + @n_collections ||= @@n_collections + @collections_most_visualised = @@collections_most_visualised + @n_collections_non_visualised = @@n_collections_non_visualised end @@ -41,7 +38,7 @@ class Management::StatisticsController < ManagementController end def complaints - @complaints = Complaint.all + @complaints = @@complaints @n_complaints = @@n_complaints @complaints_objs = @@complaints_objs @complaints_per_message = @@complaints_per_message @@ -49,31 +46,18 @@ class Management::StatisticsController < ManagementController def set_statistics - - Rails.cache.fetch("cache/management_statistics", expires_in: 1.hours) do - @complaints = Complaint.all + @@complaints = Complaint.all @@n_users = User.count @@n_collections = Collection.all.size + @@collections_most_visualised = Collection.order(:views_count) + @@n_collections_non_visualised = Collection.where(views_count: 0).size @@n_learning_objects = LearningObject.all.size @@n_non_visualised = LearningObject.where(views_count: 0).size @@most_visualised = LearningObject.order(:views_count) @@n_views = LearningObject.sum(:views_count) @@n_complaints = Complaint.all.size - @@complaints_per_message = Hash.new(0) - @@complaints_objs = Hash.new(0) - - @complaints.map{ |complaint| complaint.reason }.each do |message| - @@complaints_per_message[message] += 1 - end - - @complaints.map{ |complaint| complaint.complaintable }.each do |object| - @@complaints_objs[object] += 1 - end - end + @@complaints_per_message = Complaint.group(:complaint_reason_id).count + @@complaints_objs = @@complaints.map{|complaint| complaint.complaintable.name}.inject(Hash.new(0)) { |h,e| h[e] += 1; h } end - def views - - end - end diff --git a/app/controllers/management/welcome_controller.rb b/app/controllers/management/welcome_controller.rb index 20e2db62..ca96383e 100644 --- a/app/controllers/management/welcome_controller.rb +++ b/app/controllers/management/welcome_controller.rb @@ -1,4 +1,9 @@ class Management::WelcomeController < ManagementController def index + @n_users = User.all.size + @n_collections = Collection.all.size + @n_learning_objects = LearningObject.all.size + @n_complaints = Complaint.all.size + @total_accesses = User.sum("sign_in_count") end end diff --git a/app/views/management/complaints/index.html.erb b/app/views/management/complaints/index.html.erb index 30845f6e..23a286e5 100644 --- a/app/views/management/complaints/index.html.erb +++ b/app/views/management/complaints/index.html.erb @@ -13,13 +13,13 @@ <div class="ls-custom-select"> <select name="period" id="select_period" class="ls-select"> + <option value=7>Todos</option> <option value=6>Últimos 12 meses</option> <option value=1>Hoje</option> <option value=2>Ontem</option> <option value=3>Última semana</option> <option value=4>Últimos 30 dias</option> <option value=5>Últimos 6 meses</option> - </select> </div> </label> @@ -79,9 +79,9 @@ <strong><%= complaint.complaintable.name %></strong> <small><%= @complaints.select{ |x| x.complaintable.name == complaint.complaintable.name}.map{|x| x.reason }.each_with_object(Hash.new(0)){ |frequency,message| message[frequency] += 1 }.sort_by{ |k,v| v }.reverse.each{|x| x}.map{ |k,v| "#{k}(#{v})"}.join(",")%></small> - <div data-ls-module="collapse" data-target="#<%= complaint.complaintable.name.tr('^A-Za-z0-9', '') %>" class="ls-collapse "> + <div data-ls-module="collapse" data-target="#<%= complaint.complaintable.id %>" class="ls-collapse "> <a href="#" class="ls-collapse-header"><h5 class="ls-collapse-title"><strong>Descrições</strong></h5></a> - <div class="ls-collapse-body" id="<%= complaint.complaintable.name.tr('^A-Za-z0-9', '') %>"> + <div class="ls-collapse-body" id="<%= complaint.complaintable.id %>"> <% @complaints.sort {|left, right| left.description.length <=> right.description.length}.reverse.select{ |x| x.complaintable.name == complaint.complaintable.name }.each do |complaint_description| %> <table class="ls-table ls-no-hover ls-table-striped"> <thead> @@ -106,7 +106,7 @@ <li><a href="#" role="option" title="Funcionalidade em desenvolvimento!">Suspender conteúdo</a></li> <li> <% @complaints.select{ |x| x.complaintable.name == complaint.complaintable.name }.each do |complaint_ignore| %> - <%= link_to 'Ignorar denúncia de ' + complaint_ignore.user.name , management_complaint_path(id: complaint_ignore.id), {method: :delete, data: {confirm: 'Tem certeza que deseja ignorar esta denúncia?'}, title: 'Ignorar denúncia', class: 'ls-btn ls-btn-sm', role: 'option'} %> + <%= link_to 'Ignorar denúncia', management_complaint_path(id: complaint_ignore.id), {method: :delete, data: {confirm: 'Tem certeza que deseja ignorar esta denúncia?'}, title: 'Ignorar denúncia', class: 'ls-btn ls-btn-sm', role: 'option'} %> <% end %> </li> </ul> @@ -117,9 +117,9 @@ <div class="ls-list-content "> <div class="col-xs-12 col-md-6"> - <div data-ls-module="collapse" data-target="#<%= complaint.complaintable.name.tr('^A-Za-z0-9', '') + "complaint"%>" class="ls-collapse "> + <div data-ls-module="collapse" data-target="#<%= complaint.complaintable.id.to_s + "complaint" %>" class="ls-collapse "> <a href="#" class="ls-collapse-header"><strong class="ls-collapse-title">Denunciado por</strong></a> - <div class="ls-collapse-body" id="<%= complaint.complaintable.name.tr('^A-Za-z0-9', '') + "complaint" %>"> + <div class="ls-collapse-body" id="<%= complaint.complaintable.id.to_s + "complaint" %>"> <% @complaints.select{ |x| x.complaintable.name == complaint.complaintable.name}.map{|x| x.user }.each do |user| %> <table class="ls-table ls-no-hover ls-table-striped"> <tbody> @@ -138,7 +138,6 @@ </div> </div> </div> - </div> <% end %> <% end %> </div> diff --git a/app/views/management/complaints/show.html.erb b/app/views/management/complaints/show.html.erb deleted file mode 100644 index 4a706713..00000000 --- a/app/views/management/complaints/show.html.erb +++ /dev/null @@ -1,126 +0,0 @@ -<h1 class="ls-title-intro ls-ico-stats">Denúncias</h1> - -<div class="ls-box-filter"> - - <form action="" class="ls-form ls-form-inline"> - - <input type="hidden" name="status" value=""> - - <label class="ls-label col-lg-3 col-md-6 col-sm-12"> - <b class="ls-label-text">PerÃodo</b> - - <div class="ls-custom-select"> - <select name="period" id="select_period" class="ls-select"> - <option>Hoje</option> - <option>Ontem</option> - <option>Última semana</option> - <option>Últimos 30 dias</option> - <option>Últimos 6 meses</option> - <option>Últimos 12 meses</option> - </select> - </div> - </label> - - <input type="submit" class="ls-btn-primary" value="Filtrar" aria-expanded="false"> - </form> - -</div> - - -<h2 class="ls-title-4">Relatório de Denúncias</h2> - -<div class="row"> - <div class="col-md-6 col-sm-6"><p>Número de vezes que os usuários marcaram objetos educacionais como spam.</p></div> - <div class="col-md-6 col-sm-6"> - <p class="ls-float-right ls-float-none-xs">PerÃodo selecionado: <strong>últimos 30 dias</strong></p></div> -</div> - -<div class="ls-clearfix"></div> - -<div class="ls-board-box"> - - <div id="sending-stats" class="row ls-box-group"> - <div class="col-sm-12 col-lg-5"> - <div class="ls-box"> - <div class="ls-box-head"> - <h6 class="ls-title-4">Total de denúncias</h6> - </div> - <div class="ls-box-body"> - <strong>80</strong> - <small>spam</small> - </div> - </div> - </div> - - <div class="col-sm-12 col-lg-7"> - <div class="ls-box"> - <div class="ls-box-head"> - <h6 class="ls-title-4">Percentual comparado ao último mês</h6> - </div> - <div class="ls-box-body"> - <div class="col-lg-offset-3 col-lg-3 col-xs-6"> - <strong class="ls-color-theme" data-prefix="%">-3,60</strong> - <small>usuário falso</small> - </div> - <div class="col-lg-3 col-xs-6"> - <strong class="ls-color-danger" data-prefix="%">+0,90</strong> - <small>direitos autorais</small> - </div> - <div class="col-lg-3 col-xs-6"> - <strong class="ls-color-danger" data-prefix="%">+32</strong> - <small>conteúdo ofensivo</small> - </div> - </div> - </div> - </div> - </div> - - - - <div class="ls-tabs-container" id="awesome-tab-content"> - <div id="infoAll" class="ls-tab-content" role="tabpanel" style="display: block;"> - <% @complaints.each do |complaint| %> - - <div class="ls-list"> - <header class="ls-list-header"> - <div class="ls-list-title col-md-9"> - <strong><%= complaint.object.name %></strong> - <small><%= complaint.message %></small> - - <% if !complaint.description.blank? %> - <p><%= complaint.description %></p> - <% end %> - - </div> - <div class="col-md-3 ls-txt-right"> - <div data-ls-module="dropdown" class="ls-dropdown ls-pos-right"> - <a href="#" class="ls-btn-primary" aria-expanded="false" role="combobox">Administrar</a> - <ul class="ls-dropdown-nav" aria-hidden="true"> - <li><a href="#" role="option" title="Funcionalidade em desenvolvimento!">Suspender conteúdo</a></li> - <li> - <%= link_to 'Ignorar denúncia', destroy_mana %> - <a href="#" role="option">Ignorar denúncia</a> - </li> - </ul> - </div> - </div> - </header> - <div class="ls-list-content "> - <div class="col-xs-12 col-md-6"> - <span class="ls-list-label">Denunciado por</span> - <strong><%= complaint.user.name %></strong> - </div> - <div class="col-xs-12 col-md-6"> - <span class="ls-list-label">Data</span> - <strong><%= complaint.created_at %></strong> - </div> - </div> - </div> - - <% end %> - </div> - </div> - - </div> - -</div> \ No newline at end of file diff --git a/app/views/management/statistics/_general_stats.html.erb b/app/views/management/statistics/_general_stats.html.erb index 2c9d4308..ef832455 100644 --- a/app/views/management/statistics/_general_stats.html.erb +++ b/app/views/management/statistics/_general_stats.html.erb @@ -35,5 +35,13 @@ <%= link_to "Mais detalhes" , accesses_management_statistics_path, class: "ls-btn ls-btn-sm" %> </div> </div> + <div class="col-sm-6 col-md-3"> + <div class="ls-box"> + <h6 class="ls-title-4 ">Denúncias</h6> + <strong class="ls-color-theme"><%= complaints %></strong> + + <%= link_to "Mais detalhes" , complaints_management_statistics_path, class: "ls-btn ls-btn-sm" %> + </div> + </div> </div> -</div> \ No newline at end of file +</div> diff --git a/app/views/management/statistics/collections.html.erb b/app/views/management/statistics/collections.html.erb index 786b2684..f34a4f7e 100644 --- a/app/views/management/statistics/collections.html.erb +++ b/app/views/management/statistics/collections.html.erb @@ -18,16 +18,38 @@ </div> </div> </div> + <div id="sending-stats" class="row"> + <div class="col-sm-6 col-md-12"> + <div class="ls-box"> + <h6 class="ls-title-6">Visualizadas</h6> + <strong class="ls-color-theme"><%= @n_collections - @n_collections_non_visualised %></strong> + </div> + </div> + <div class="col-sm-6 col-md-12"> + <div class="ls-box"> + <h6 class="ls-title-6">Não visualizadas</h6> + <strong class="ls-color-theme"><%= @n_collections_non_visualised %></strong> + </div> + </div> + </div> </div> +<input type="hidden" id="lcollection" value="<%= @n_collections - @n_collections_non_visualised %>"/> +<input type="hidden" id="lcollection_non" value="<%= @n_collections_non_visualised %>"/> + + +<div> + <div style="float: left; margin-left: 85px; margin-top: 100px"> + <canvas id="collections" width="700" height="600"></canvas> + </div> -<div align="center"> - Por Ãrea do conhecimento -</div> -<br> -<!-- Gráfico ainda não populado -<div align="center"> - <canvas id="colections" width="400" height="350"></canvas> + <div style="margin-left: 900px"> + <h3><th><b> 10 mais visualisadas </b></th></h3><br> + <div class="row collections-columns"> + <% @collections_most_visualised.first(10).each do |most| %> + <li><%= link_to most["name"], collections_path(most["id"]) %></li><BR> + <% end %> + </div> + </div> </div> ---> diff --git a/app/views/management/statistics/complaints.html.erb b/app/views/management/statistics/complaints.html.erb index 086c8219..5542a969 100644 --- a/app/views/management/statistics/complaints.html.erb +++ b/app/views/management/statistics/complaints.html.erb @@ -19,13 +19,15 @@ <strong class="ls-color-theme"><%=@n_complaints%></strong> </div> </div> + </div> + <div id="sending-stats" class="row"> - <% @complaints.map{|x| x.reason}.uniq.each do |message| %> - <div class="col-sm-6 col-md-3"> + <% @complaints.map{|x| x}.uniq{|x| x.complaint_reason}.each do |complaint| %> + <div class="col-sm-6 col-md-6"> <div class="ls-box"> - <h6 class="ls-title-4"><%= message %></h6> - <strong class="ls-color-theme"><%= @complaints_per_message[message] %></strong> + <h6 class="ls-title-4"><%= complaint.reason %></h6> + <strong class="ls-color-theme"><%= @complaints_per_message[complaint.complaint_reason_id] %></strong> </div> </div> @@ -33,11 +35,12 @@ </div> </div> +</div> -<input type="hidden" id="lcomplaints" value="<%= @complaints_per_message["Usuário falso"] %>"/> -<input type="hidden" id="lcomplaints_false" value="<%= @complaints_per_message["Usuário ofensivo/agressivo"] %>"/> -<input type="hidden" id="lcomplaints_offensive" value="<%= @complaints_per_message["Objeto contém conteúdo ofensivo/abusivo"] %>"/> -<input type="hidden" id="lcomplaints_violates" value="<%= @complaints_per_message["Objeto viola direitos autorais"] %>"/> +<input type="hidden" id="lcomplaints" value="<%= @complaints_per_message[1] %>"/> +<input type="hidden" id="lcomplaints_false" value="<%= @complaints_per_message[2] %>"/> +<input type="hidden" id="lcomplaints_offensive" value="<%= @complaints_per_message[3] %>"/> +<input type="hidden" id="lcomplaints_violates" value="<%= @complaints_per_message[4] %>"/> <div align="right" > </div> @@ -52,7 +55,7 @@ <h3><th><b>10 Mais denunciados </b></th></h3><br> <div class="row learning-object-columns"> <% @complaints_objs.sort_by{|name,frequency| frequency }.reverse.first(10).each do |object| %> - <li><%= link_to object[0].name + '->' + object[1].to_s + ' denúncia(s)' , learning_object_path(object[0].id) %></li><BR> + <li><%= link_to object[0].to_s + '->' + object[1].to_s + ' denúncia(s)' , learning_object_path(object[0]) %></li><BR> <%end %> </div> </div> diff --git a/app/views/management/statistics/index.html.erb b/app/views/management/statistics/index.html.erb index 35e6504b..d1579a70 100644 --- a/app/views/management/statistics/index.html.erb +++ b/app/views/management/statistics/index.html.erb @@ -4,4 +4,4 @@ <li>EstatÃsticas</li> </ol> -<%= render 'general_stats', users_number: @n_users, collections_number: @n_collections, learning_objects_number: @n_learning_objects, total_accesses: @total_accesses %> +<%= render 'general_stats', users_number: @n_users, collections_number: @n_collections, learning_objects_number: @n_learning_objects, total_accesses: @total_accesses, complaints: @n_complaints %> diff --git a/app/views/management/statistics/learning_objects.html.erb b/app/views/management/statistics/learning_objects.html.erb index d80c432f..2b6f9d19 100644 --- a/app/views/management/statistics/learning_objects.html.erb +++ b/app/views/management/statistics/learning_objects.html.erb @@ -13,13 +13,15 @@ </header> <div id="sending-stats" class="row"> - <div class="col-sm-6 col-md-12"> + <div class="col-sm-6"> <div class="ls-box"> <h6 class="ls-title-6">Total</h6> <strong class="ls-color-theme"><%= @n_learning_objects %></strong> </div> </div> + </div> + <div id="sending-stats" class="row"> <div class="col-sm-6 col-md-6"> <div class="ls-box"> <h6 class="ls-title-6">Visualizados</h6> @@ -35,6 +37,7 @@ </div> </div> </div> +</div> diff --git a/app/views/management/statistics/users.html.erb b/app/views/management/statistics/users.html.erb index 0956e471..53531269 100644 --- a/app/views/management/statistics/users.html.erb +++ b/app/views/management/statistics/users.html.erb @@ -11,7 +11,7 @@ <p class="ls-float-right ls-float-none-xs ls-small-info">Apurado em <strong><%= Date.today.to_s %></strong></p> </header> <div id="sending-stats" class="row"> - <div class="col-sm-6 col-md-12"> + <div class="col-sm-6 "> <div class="ls-box"> <h6 class="ls-title-6">Total</h6> <strong class="ls-color-theme"><%=@n_users%></strong> @@ -19,7 +19,9 @@ <%#= link_to "Mais detalhes" , management_statistics_users_path, class: "ls-btn ls-btn-sm" %> </div> </div> + </div> + <div id="sending-stats" class="row"> <div class="col-sm-6 col-md-4"> <div class="ls-box"> <h6 class="ls-title-4">Professores</h6> @@ -47,6 +49,7 @@ </div> </div> + </div> </div> <div align="right" > diff --git a/app/views/management/welcome/index.html.erb b/app/views/management/welcome/index.html.erb index 3b3f18bd..1265366a 100644 --- a/app/views/management/welcome/index.html.erb +++ b/app/views/management/welcome/index.html.erb @@ -1,3 +1,3 @@ <h1 class="ls-title-intro ls-ico-home">Sistema de Gerenciamento do Portal</h1> -<%= render 'management/statistics/general_stats', users_number: 10, collections_number: 20, learning_objects_number: 12333, total_accesses: 1000283474 %> \ No newline at end of file +<%= render 'management/statistics/general_stats', users_number: @n_users, collections_number: @n_collections, learning_objects_number: @n_learning_objects, total_accesses: @total_accesses, complaints: @n_complaints %> -- GitLab