Commit 1fc91c860fdac093d738e91128b19fe4f9599f84

Authored by Jailson Dias
1 parent 4f57a60c

criando a página de relatórios para goals

goals/templates/goals/relatorios.html 0 → 100644
... ... @@ -0,0 +1,492 @@
  1 +{% extends "subjects/view.html" %}
  2 +
  3 +{% load static i18n pagination permissions_tags subject_counter %}
  4 +{% load django_bootstrap_breadcrumbs %}
  5 +
  6 +{% block javascript%}
  7 + {{ block.super }}
  8 + <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
  9 + <script type="text/javascript">
  10 + var tabela_atual = true;
  11 +
  12 + var array_history = [];
  13 + {%for data_json in json_history.data %}
  14 + array_history.push(["{{data_json.0}}","{{data_json.1}}","{% if data_json.2 == 'view' %} {{view}} {% elif data_json.2 == 'submit' %} {{submit}} {% endif %}",{% if data_json.3 is not None %}new Date('{{data_json.3.isoformat}}'){% else%}null{% endif %}]);
  15 + {% endfor%}
  16 + var json_history = {"data":array_history};
  17 + var column_history = [{"string":'{% trans "User" %}'},{"string":'{% trans "Group" %}'},{"string":'{% trans "Action" %}'},{"date":'{% trans "Date of Action" %}'}];
  18 +
  19 + var search = [];
  20 + for (var i in json_history["data"]){
  21 + search.push([json_history["data"][i][0],json_history["data"][i][1],
  22 + json_history["data"][i][2],json_history["data"][i][3]]);
  23 + }
  24 +
  25 + var array_n_did = [];
  26 + var checkbox = {};
  27 + {%for data_json in json_n_did.data%}
  28 + var input = '<div class="checkbox">\
  29 + <label for="{{data_json.0}}_google_table">\
  30 + <input id="{{data_json.0}}_google_table" name="{{data_json.0}}_google_table" type="checkbox"><span class="checkbox-material"><span class="check"></span></span>\
  31 + </label>\
  32 + </div>'
  33 + checkbox["{{data_json.0}}_google_table"] = "{{data_json.4}}";
  34 + array_n_did.push([input,"{{data_json.1}}","{{data_json.2}}","{{data_json.3}}"]);
  35 + {% endfor%}
  36 + var json_n_did = {"data":array_n_did};
  37 + var column_n_did = [{"string":'<a href="javascript:void(0);" onclick="return openmodal();"> {% trans "Send message" %}</a>'},{"string":'{% trans "User" %}'},{"string":'{% trans "Group" %}'},{"string":"{% trans "Action don't realized" %}"}];
  38 + </script>
  39 +
  40 +
  41 + <script type="text/javascript">
  42 + google.charts.load('current', {'packages':['corechart',"table"]});
  43 + google.charts.setOnLoadCallback(drawChart);
  44 + google.charts.setOnLoadCallback(drawTable);
  45 +
  46 + function drawChart() {
  47 + var data = google.visualization.arrayToDataTable({{db_data|safe}});
  48 + var options = {
  49 + title: '{{title_chart}}',
  50 + // legend: {position: 'right', maxLines: 1},
  51 + bar: { groupWidth: '50%' },
  52 + chartArea:{width:"50%"},
  53 + titlePosition: 'out',
  54 + vAxis: {
  55 + title: '{{title_vAxis}}',
  56 + ticks: [0, .20, .40, .60, .80, 1],
  57 + viewWindow: {
  58 + min: 0,
  59 + max: 1
  60 + }
  61 + },
  62 + isStacked: "percent",
  63 + };
  64 +
  65 + function selectHandler() {
  66 + var selectedItem = chart.getSelection()[0];
  67 + var col = data.getColumnLabel(selectedItem.column);
  68 + if (selectedItem) {
  69 + if (selectedItem.row == 0 && selectedItem.column == 1){
  70 + tabela_atual = true;
  71 + search = [];
  72 + var text = "{{view}}";
  73 + for (var i in json_history["data"]){
  74 + if (json_history["data"][i][2].toLowerCase().includes(text.toLowerCase())){
  75 + search.push([json_history["data"][i][0],json_history["data"][i][1],
  76 + json_history["data"][i][2],json_history["data"][i][3]]);
  77 + }
  78 + }
  79 + drawTable(column_history,pagination(search,1),true,3);
  80 + alterTitleTable(search.length);
  81 + putpagination(search,tabela_atual);
  82 + } else if(selectedItem.row == 0 && selectedItem.column == 2){
  83 + tabela_atual = false;
  84 + search = [];
  85 + var text = "{{view}}";
  86 + for (var i in json_n_did["data"]){
  87 + if (json_n_did["data"][i][3].toLowerCase().includes(text.toLowerCase())){
  88 + search.push([json_n_did["data"][i][0],json_n_did["data"][i][1],
  89 + json_n_did["data"][i][2],json_n_did["data"][i][3]]);
  90 + }
  91 + }
  92 + drawTable(column_n_did,pagination(search,1),false);
  93 + alterTitleTable(search.length);
  94 + putpagination(search,tabela_atual);
  95 + } else if (selectedItem.row == 1 && selectedItem.column == 1){
  96 + tabela_atual = true;
  97 + search = [];
  98 + var text = "{{submit}}";
  99 + for (var i in json_history["data"]){
  100 + if (json_history["data"][i][2].toLowerCase().includes(text.toLowerCase())){
  101 + search.push([json_history["data"][i][0],json_history["data"][i][1],
  102 + json_history["data"][i][2],json_history["data"][i][3]]);
  103 + }
  104 + }
  105 + drawTable(column_history,pagination(search,1),true,3);
  106 + alterTitleTable(search.length);
  107 + putpagination(search,tabela_atual);
  108 + } else if(selectedItem.row == 1 && selectedItem.column == 2){
  109 + tabela_atual = false;
  110 + search = [];
  111 + var text = "{{submit}}";
  112 + for (var i in json_n_did["data"]){
  113 + if (json_n_did["data"][i][3].toLowerCase().includes(text.toLowerCase())){
  114 + search.push([json_n_did["data"][i][0],json_n_did["data"][i][1],
  115 + json_n_did["data"][i][2],json_n_did["data"][i][3]]);
  116 + }
  117 + }
  118 + drawTable(column_n_did,pagination(search,1),false);
  119 + alterTitleTable(search.length);
  120 + putpagination(search,tabela_atual);
  121 + } else if (col == "{{n_did_table}}"){
  122 + tabela_atual = false;
  123 + search = [];
  124 + for (var i in json_n_did["data"]){
  125 + search.push([json_n_did["data"][i][0],json_n_did["data"][i][1],
  126 + json_n_did["data"][i][2],json_n_did["data"][i][3]]);
  127 + }
  128 + searcher(col, tabela_atual,true);
  129 +
  130 + } else if (col == "{{did_table}}"){
  131 + tabela_atual = true;
  132 + search = [];
  133 + for (var i in json_history["data"]){
  134 + search.push([json_history["data"][i][0],json_history["data"][i][1],
  135 + json_history["data"][i][2],json_history["data"][i][3]]);
  136 + }
  137 + searcher(col, tabela_atual,true);
  138 + }
  139 + scroll("#title-table");
  140 + }
  141 + chart.setSelection([])
  142 + }
  143 +
  144 + var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
  145 + google.visualization.events.addListener(chart, 'select', selectHandler);
  146 + chart.draw(data, options);
  147 +
  148 + }
  149 +
  150 + var sortAscending = {0:false,1:false,2:false,3:false};
  151 + function drawTable(columns = column_history,rows = pagination(json_history["data"],1),isdate = true,columndate = 3) {
  152 + var data_table = new google.visualization.DataTable();
  153 + for (var i in columns){
  154 + for (var item in columns[i]){
  155 + data_table.addColumn(item,columns[i][item]);
  156 + }
  157 + }
  158 +
  159 + data_table.addRows(rows);
  160 + var formate_date = new google.visualization.DateFormat({pattern: 'dd/MM/yyyy HH:mm'});
  161 + if (isdate) formate_date.format(data_table, columndate);
  162 +
  163 + // var methods = [];
  164 + // for (var m in data_table) {
  165 + // if (typeof data_table[m] == "function") {
  166 + // methods.push(m);
  167 + // }
  168 + // }
  169 + // console.log(methods.join(","));
  170 + var options = {
  171 + sort: "event",
  172 + allowHtml: true,
  173 + cssClassNames : {
  174 + tableRow: 'text-center',
  175 + tableCell: 'text-center',
  176 + headerCell: 'text-center'
  177 + },
  178 + showRowNumber: true,
  179 + width: '100%',
  180 + height: '100%',
  181 + }
  182 + function ordenar(properties){
  183 + var columnIndex = properties['column'];
  184 + if (columnIndex > 0) {
  185 + options["sortColumn"] = columnIndex;
  186 + options["sortAscending"] = sortAscending[columnIndex];
  187 + data_table.sort({column:columnIndex,desc:sortAscending[columnIndex]});
  188 + sortAscending = {0:false,1:false,2:false,3:false};
  189 + sortAscending[columnIndex] = !sortAscending[columnIndex];
  190 + // console.log(sortAscending);
  191 + table.draw(data_table, options);
  192 + }
  193 + }
  194 +
  195 + var table = new google.visualization.Table(document.getElementById('table_div'));
  196 + google.visualization.events.addListener(table, 'sort', function(e) {ordenar(e)});
  197 + table.draw(data_table, options);
  198 + }
  199 + </script>
  200 +{% endblock%}
  201 +
  202 +{% block breadcrumbs %}
  203 + {{ block.super }}
  204 + {% breadcrumb topic 'subjects:topic_view' subject.slug topic.slug %}
  205 + {% breadcrumb goal 'goals:submit' goal.slug %}
  206 + {% trans 'Reports' as bread %}
  207 + {% breadcrumb bread goal %}
  208 +{% endblock %}
  209 +
  210 +{% block content %}
  211 + <div id="message-top">
  212 + {% if messages %}
  213 + {% for message in messages %}
  214 + <div class="alert alert-{{ message.tags }} alert-dismissible" role="alert">
  215 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  216 + <span aria-hidden="true">&times;</span>
  217 + </button>
  218 + <p>{{ message }}</p>
  219 + </div>
  220 + {% endfor %}
  221 + {% endif %}
  222 + </div>
  223 + <div class="panel panel-info topic-panel">
  224 + <div class="panel-heading">
  225 + <div class="row">
  226 + <div class="col-md-12 category-header">
  227 + <h4 class="panel-title" style="margin-top: 10px; margin-bottom: 8px">
  228 + <span>{{goal}} / {% trans "Reports" %}</span>
  229 + </h4>
  230 + </div>
  231 + </div>
  232 + </div>
  233 + <div class="row">
  234 + <div class="col-md-12 text-center">
  235 + <h4 style="margin-top: 15px; margin-bottom: 10px" ><strong>{% trans "Report of the resource " %}{{goal}}</strong></h4>
  236 + </div>
  237 + </div>
  238 + <div class="row">
  239 + <div class="col-md-12">
  240 +
  241 + <ul class="list-inline nav-justified">
  242 + <div id="general-parameters-div">
  243 + <div class="general-parameters-field">
  244 + <li class="text-right"><h4>{% trans "Select the period: " %}</h4></li>
  245 + </div>
  246 + <form id="period-form" action="" method="get">
  247 + <div class="general-parameters-field">
  248 + <li> <input class="form-control datetime-picker" name="init_date" type="text" required="" value="{% if LANGUAGE_CODE == 'pt-br' %}{{init_date|date:'d/m/Y H:i'}} {% else %} {{init_date|date:'m/d/Y H:i P'}} {% endif %}"></li>
  249 + </div>
  250 + <div class="general-parameters-field">
  251 + <li><input id="inputdate" class="form-control datetime-picker" name="end_date" type="text" required="" value="{% if LANGUAGE_CODE == 'pt-br' %}{{end_date|date:'d/m/Y H:i'}} {% else %} {{end_date|date:'m/d/Y H:i P'}} {% endif %}"></li>
  252 + </div>
  253 + <li><input type="submit" value="{% trans 'Search' %}" style="margin-left: 15px;" class="btn btn-success btn-raised"></li>
  254 + </form>
  255 + </div>
  256 + <ul>
  257 + </div>
  258 + </div>
  259 +
  260 + <div class="row">
  261 + <div class="col-md-10 col-md-offset-1">
  262 + <div id="chart_div" style="height: 500px; margin-top: -50px;"></div>
  263 + </div>
  264 + </div>
  265 +
  266 + <div class="row">
  267 + <div class="col-md-10 col-md-offset-1">
  268 + <div class="text-center">
  269 + <ul class="list-inline nav-justified">
  270 + <li>
  271 + <ul id="view-table" class="list-inline text-right">
  272 + <li><h3 id="title-table"></h3></li>
  273 + </ul>
  274 + </li>
  275 + <li>
  276 + <ul class="list-inline text-right">
  277 + <li><p>{% trans "Filter: " %}</p></li>
  278 + <li><input id="search-input" class="form-control" type="text" name="search" value=""></li>
  279 + </ul>
  280 + </li>
  281 + </ul>
  282 + </div>
  283 + <form id="google-chart-checkbox" action="" method="get">
  284 + <div id="table_div"></div>
  285 + </form>
  286 + <div class="col-md-12 col-lg-12 col-sm-12 col-xs-12 text-center">
  287 + <ul class="pagination">
  288 +
  289 + </ul>
  290 + </div>
  291 + </div>
  292 + </div>
  293 + <div id="modal-message"></div>
  294 + <div class="row">
  295 + <br><br>
  296 + </div>
  297 + </div>
  298 +
  299 + <script type="text/javascript">
  300 +
  301 + $("#title-table").text(search.length + " {% trans 'record(s)' %}");
  302 + function putpagination(data = json_history["data"], load_histoty = true){
  303 + var len = Math.ceil(data.length / 20);
  304 + $(".pagination").empty();
  305 + $(".pagination").append('<li class="disabled"><span>«</span></li>');
  306 + $(".pagination").append('<li id="1" class="active">\
  307 + <a href="javascript:void(0);" onclick="return clickPagination(1, '+ load_histoty +');">1</a>\
  308 + </li>');
  309 + for (var i = 2; i <= len;i++){
  310 + $(".pagination").append('<li id="' + i + '">\
  311 + <a href="javascript:void(0);" onclick="return clickPagination(' + i +', ' + load_histoty + ');">' + i + '</a>\
  312 + </li>');
  313 + }
  314 + if (len > 1) $(".pagination").append('<li><a href="javascript:void(0);" onclick="return clickPagination(2, '+ load_histoty +');"><span>»</span></a></li>');
  315 + else $(".pagination").append('<li class="disabled"><span>»</span></li>');
  316 + };
  317 + putpagination();
  318 +
  319 + $('#period-form').submit(function(event) {
  320 + $('<input />').attr('type', 'hidden')
  321 + .attr('name', "language")
  322 + .attr('value', '{{ LANGUAGE_CODE }}')
  323 + .appendTo('#period-form');
  324 + });
  325 + function add(element,local, first = false){
  326 + if (first) $(local).prepend(element);
  327 + else $(local).append(element);
  328 + }
  329 + function text(element){
  330 + return $(element).text();
  331 + }
  332 + function length(element) {
  333 + return $(element).length;
  334 + }
  335 +
  336 + $("#search-input").on("keyup",function(){
  337 + search = [];
  338 + var text = $("#search-input").val();
  339 + searcher(text,tabela_atual);
  340 + });
  341 +
  342 + function searcher(text, load_histoty = false,apaga=false){
  343 + if(apaga){
  344 + $("#search-input").val("");
  345 + }
  346 + var data = [];
  347 + if (!load_histoty){
  348 + data = $.map(json_n_did["data"], function (obj) {
  349 + return $.extend(true, {}, obj);
  350 + });
  351 + } else {
  352 + data = $.map(json_history["data"], function (obj) {
  353 + return $.extend(true, {}, obj);
  354 + });
  355 + }
  356 + if (load_histoty){
  357 + for (var i in data){
  358 + data[i][3] = moment(data[i][3]).format("DD/MM/YYYY HH:mm");
  359 + }
  360 + }
  361 + if (load_histoty){
  362 + for (var i in data){
  363 + if (data[i][0].toLowerCase().includes(text.toLowerCase())
  364 + || data[i][1].toLowerCase().includes(text.toLowerCase())
  365 + || data[i][2].toLowerCase().includes(text.toLowerCase())
  366 + || data[i][3].toLowerCase().includes(text.toLowerCase())){
  367 + search.push(json_history["data"][i]);
  368 + }
  369 + }
  370 + }
  371 + else {
  372 + for (var i in data){
  373 + if (data[i][1].toLowerCase().includes(text.toLowerCase())
  374 + || data[i][2].toLowerCase().includes(text.toLowerCase())
  375 + || data[i][3].toLowerCase().includes(text.toLowerCase())){
  376 + search.push(json_n_did["data"][i]);
  377 + }
  378 + }
  379 + }
  380 + console.log(search);
  381 + if (!load_histoty){
  382 + drawTable(column_n_did,pagination(search,1),false);
  383 + } else {
  384 + drawTable(column_history,pagination(search,1),true,3);
  385 + }
  386 + $("#title-table").text(search.length + " {% trans 'record(s)' %}");
  387 + putpagination(search,load_histoty);
  388 + }
  389 +
  390 + function pagination(data,pag){
  391 + var len = data.length;
  392 + var first = (pag * 20 - 20 < len) ? pag * 20 - 20:len;
  393 + var end = (pag * 20 < len) ? pag * 20:len;
  394 + var search = data.slice(first,end);
  395 + return search;
  396 + }
  397 +
  398 + function clickPagination(pag, load_histoty = false){
  399 + $(".pagination > li").last().remove();
  400 + $(".pagination > li").first().remove();
  401 +
  402 + if (!load_histoty){
  403 + drawTable(column_n_did,pagination(search,pag),false);
  404 + } else {
  405 + drawTable(column_history,pagination(search,pag),true,3);
  406 + }
  407 +
  408 + if (pag < Math.ceil(search.length / 20))
  409 + $(".pagination").append('<li><a href="javascript:void(0);" onclick="return clickPagination(' + (pag + 1) + ', '+ load_histoty +');"><span>»</span></a></li>');
  410 + else $(".pagination").append('<li class="disabled"><span>»</span></li>');
  411 + if (pag > 1)
  412 + $(".pagination").prepend('<li><a href="javascript:void(0);" onclick="return clickPagination(' + (pag - 1) + ', '+ load_histoty +');"><span>«</span></a></li>');
  413 + else $(".pagination").prepend('<li class="disabled"><span>«</span></li>');
  414 + $(".active").removeClass("active");
  415 + $("#" + pag).addClass("active");
  416 + }
  417 +
  418 + function openmodal(){
  419 + $( "#modal-message" ).empty();
  420 + $.get( "{% url 'goals:send_message' goal.slug %}", function( data ) {
  421 + $( "#modal-message" ).append( data );
  422 + $("#send-message-modal").modal("show");
  423 + });
  424 + }
  425 +
  426 + function sendMessage(){
  427 + $("#send-message-modal").modal("hide");
  428 + var checked = $("#google-chart-checkbox").serializeArray();
  429 + var email = [];
  430 + for (var i in checked){
  431 + email.push(checkbox[checked[i]["name"]]);
  432 + }
  433 + $('<input />').attr('type', 'hidden')
  434 + .attr('name', "users[]")
  435 + .attr('value', email)
  436 + .appendTo('#text_chat_form');
  437 +
  438 + var formData = new FormData($('#text_chat_form').get(0));
  439 + $.ajax({
  440 + url: "{% url 'goals:send_message' goal.slug %}",
  441 + type: "POST",
  442 + data: formData,
  443 + cache: false,
  444 + processData: false,
  445 + contentType: false,
  446 + success: function(data) {
  447 + if (data["message"]){
  448 + console.log("success");
  449 + $("body").removeClass("modal-open");
  450 + $( "#modal-message" ).empty();
  451 + $(".modal-backdrop.fade.in").remove();
  452 + $("#message-top").empty();
  453 + $("#message-top").append('\
  454 + <div class="alert alert-success alert-dismissible" role="alert">\
  455 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">\
  456 + <span aria-hidden="true">&times;</span>\
  457 + </button>\
  458 + <p>' + data["message"] + '</p>\
  459 + </div>\
  460 + ');
  461 + $("html, body").animate({ scrollTop: 0 }, "slow");
  462 + $('#google-chart-checkbox')[0].reset();
  463 + } else {
  464 + $( "#modal-message" ).empty();
  465 + $(".modal-backdrop.fade.in").remove();
  466 + $( "#modal-message" ).append( data );
  467 + $("#send-message-modal").modal("show");
  468 + $("html, body").animate({ scrollTop: 0 }, "slow");
  469 + }
  470 + },
  471 + error: function(data){
  472 + $("#message-top").empty();
  473 + $("#message-top").append('\
  474 + <div class="alert alert-danger alert-dismissible" role="alert">\
  475 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">\
  476 + <span aria-hidden="true">&times;</span>\
  477 + </button>\
  478 + <p>' + data.responseText + '</p>\
  479 + </div>\
  480 + ');
  481 + $("html, body").animate({ scrollTop: 0 }, "slow");
  482 + }
  483 + });
  484 + }
  485 + function scroll(to){
  486 + $("html, body").animate({ scrollTop: $(to).offset().top }, "slow");
  487 + }
  488 + function alterTitleTable (quant){
  489 + $("#title-table").text(quant + " {% trans 'record(s)' %}");
  490 + }
  491 + </script>
  492 +{% endblock %}
... ...
goals/templates/goals/send_message.html 0 → 100644
... ... @@ -0,0 +1,112 @@
  1 +
  2 + {% load widget_tweaks i18n %}
  3 + <!-- Modal (remember to change the ids!!!) -->
  4 +<div class="modal fade" id="send-message-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
  5 + <div class="modal-dialog" role="document">
  6 + <div class="modal-content">
  7 + <!-- Modal Body -->
  8 + <div class="modal-body">
  9 + <form id="text_chat_form" action="" method="POST" enctype="multipart/form-data">
  10 + {% csrf_token %}
  11 + {% comment %}Area para o Texto{% endcomment %}
  12 + <div class="form-group{% if form.has_error %} has-error {% endif %}">
  13 + <label for="{{ form.comment.auto_id }}">{{ form.comment.label }}: <span>*</span></label>
  14 + {% render_field form.comment class='form-control text_simple_wysiwyg' %}
  15 +
  16 + <span id="helpBlock" class="help-block">{{ form.comment.help_text }}</span>
  17 +
  18 + {% if form.comment.errors %}
  19 + <div class="alert alert-danger alert-dismissible" role="alert">
  20 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  21 + <span aria-hidden="true">&times;</span>
  22 + </button>
  23 + <ul>
  24 + {% for error in form.comment.errors %}
  25 + <li>{{ error }}</li>
  26 + {% endfor %}
  27 + </ul>
  28 + </div>
  29 + {% endif %}
  30 + </div>
  31 + {% comment %}Area para anexar a imagem {% endcomment %}
  32 + <div class="form-group{% if form.has_error %} has-error {% endif %} is-fileinput">
  33 + {% render_field form.image %}
  34 +
  35 + <div class="filedrag">
  36 + {% trans 'Click or drop the picture here' %}<br />
  37 +
  38 + <small>{% trans 'The picture could not exceed 5MB.' %}</small>
  39 + </div>
  40 +
  41 + {% if form.image.errors %}
  42 + <div class="alert alert-danger alert-dismissible" role="alert">
  43 + <button type="button" class="close" data-dismiss="alert" aria-label="Close">
  44 + <span aria-hidden="true">&times;</span>
  45 + </button>
  46 + <ul>
  47 + {% for error in form.image.errors %}
  48 + <li>{{ error }}</li>
  49 + {% endfor %}
  50 + </ul>
  51 + </div>
  52 + {% endif %}
  53 +
  54 + </div>
  55 + </form>
  56 + </div>
  57 + <!-- Modal Footer -->
  58 + <div id="delete-category-footer"class="modal-footer">
  59 + <!-- Don't remove that!!! -->
  60 + <button type="button" class="btn btn-default btn-raised" data-dismiss="modal">{% trans "Close" %}</button>
  61 + <a href="javascript:void(0)" onclick="return sendMessage()" form="text_chat_form" class="btn btn-success btn-raised erase-button">{% trans "Send" %}</a>
  62 + </div>
  63 + </div>
  64 + </div>
  65 +</div>
  66 +
  67 +<script type="text/javascript">
  68 +
  69 + $('.text_simple_wysiwyg').summernote({
  70 + dialogsInBody: true,
  71 + disableDragAndDrop: true,
  72 + height: 150,
  73 + toolbar: [
  74 + // [groupName, [list of button]]
  75 + ['style', ['bold', 'italic']],
  76 + ['insert', ['link']]
  77 + ]
  78 + });
  79 +
  80 + if (window.File && window.FileList && window.FileReader) {
  81 + Init();
  82 + }
  83 +
  84 + function Init() {
  85 + var small = $("#id_image"),
  86 + filedrag = $(".filedrag"),
  87 + common = $(".common-file-input");
  88 +
  89 + // file select
  90 + small.on("change", FileSelectHandler);
  91 +
  92 + // is XHR2 available?
  93 + var xhr = new XMLHttpRequest();
  94 + if (xhr.upload) {
  95 + // file drop
  96 + filedrag.on("drop", FileSelectHandler);
  97 + filedrag.attr('style', 'display:block');
  98 + common.attr('style', 'display:none');
  99 + }
  100 + }
  101 +
  102 + // file selection
  103 + function FileSelectHandler(e) {
  104 + var files = e.target.files || e.dataTransfer.files,
  105 + parent = $(e.target.offsetParent);
  106 +
  107 + // process all File objects
  108 + for (var i = 0, f; f = files[i]; i++) {
  109 + parent.find('.filedrag').html(f.name);
  110 + }
  111 + }
  112 +</script>
0 113 \ No newline at end of file
... ...
goals/urls.py
... ... @@ -16,4 +16,6 @@ urlpatterns = [
16 16 url(r'^unanswered_report/(?P<slug>[\w_-]+)/$', views.UnansweredReport.as_view(), name = 'unanswered_report'),
17 17 url(r'^history_report/(?P<slug>[\w_-]+)/$', views.HistoryReport.as_view(), name = 'history_report'),
18 18 url(r'^view_log/(?P<goal>[\w_-]+)/(?P<report>[\w_-]+)/$', views.reports_log, name = 'reports_log'),
  19 + url(r'^chart/(?P<slug>[\w_-]+)/$', views.StatisticsView.as_view(), name = 'get_chart'),
  20 + url(r'^send-message/(?P<slug>[\w_-]+)/$', views.SendMessage.as_view(), name = 'send_message'),
19 21 ]
... ...
goals/views.py
... ... @@ -20,6 +20,22 @@ from users.models import User
20 20 from .forms import GoalsForm, MyGoalsForm, InlinePendenciesFormset, InlineGoalItemFormset
21 21 from .models import Goals, MyGoals
22 22  
  23 +import datetime
  24 +from log.models import Log
  25 +from chat.models import Conversation, TalkMessages, ChatVisualizations
  26 +from users.models import User
  27 +from subjects.models import Subject
  28 +
  29 +from webpage.forms import FormModalMessage
  30 +
  31 +from django.db.models import Q
  32 +from django.template.loader import render_to_string
  33 +from django.utils import formats
  34 +import textwrap
  35 +from django.utils.html import strip_tags
  36 +import json
  37 +from channels import Group
  38 +
23 39 class Reports(LoginRequiredMixin, generic.ListView):
24 40 login_url = reverse_lazy("users:login")
25 41 redirect_field_name = 'next'
... ... @@ -966,4 +982,185 @@ def reports_log(request, goal, report):
966 982  
967 983 return JsonResponse({'message': 'ok', 'log_id': log_id})
968 984  
969   - return JsonResponse({'message': 'ok'})
970 985 \ No newline at end of file
  986 + return JsonResponse({'message': 'ok'})
  987 +
  988 +class StatisticsView(LoginRequiredMixin, LogMixin, generic.DetailView):
  989 + log_component = 'resources'
  990 + log_action = 'view_statistics'
  991 + log_resource = 'goals'
  992 + log_context = {}
  993 +
  994 + login_url = reverse_lazy("users:login")
  995 + redirect_field_name = 'next'
  996 + model = Goals
  997 + template_name = 'goals/relatorios.html'
  998 +
  999 + def dispatch(self, request, *args, **kwargs):
  1000 + slug = self.kwargs.get('slug', '')
  1001 + goal = get_object_or_404(Goals, slug = slug)
  1002 +
  1003 + if not has_subject_permissions(request.user, goal.topic.subject):
  1004 + return redirect(reverse_lazy('subjects:home'))
  1005 +
  1006 + return super(StatisticsView, self).dispatch(request, *args, **kwargs)
  1007 +
  1008 + def get_context_data(self, **kwargs):
  1009 + context = super(StatisticsView, self).get_context_data(**kwargs)
  1010 +
  1011 + self.log_context['category_id'] = self.object.topic.subject.category.id
  1012 + self.log_context['category_name'] = self.object.topic.subject.category.name
  1013 + self.log_context['category_slug'] = self.object.topic.subject.category.slug
  1014 + self.log_context['subject_id'] = self.object.topic.subject.id
  1015 + self.log_context['subject_name'] = self.object.topic.subject.name
  1016 + self.log_context['subject_slug'] = self.object.topic.subject.slug
  1017 + self.log_context['topic_id'] = self.object.topic.id
  1018 + self.log_context['topic_name'] = self.object.topic.name
  1019 + self.log_context['topic_slug'] = self.object.topic.slug
  1020 + self.log_context['goals_id'] = self.object.id
  1021 + self.log_context['goals_name'] = self.object.name
  1022 + self.log_context['goals_slug'] = self.object.slug
  1023 +
  1024 + super(StatisticsView, self).createLog(self.request.user, self.log_component, self.log_action, self.log_resource, self.log_context)
  1025 +
  1026 +
  1027 + context['title'] = _('Goals Reports')
  1028 +
  1029 + slug = self.kwargs.get('slug')
  1030 + goal = get_object_or_404(Goals, slug = slug)
  1031 +
  1032 + date_format = "%d/%m/%Y %H:%M" if self.request.GET.get('language','') == 'pt-br' else "%m/%d/%Y %I:%M %p"
  1033 + if self.request.GET.get('language','') == "":
  1034 + start_date = datetime.datetime.now() - datetime.timedelta(30)
  1035 + end_date = datetime.datetime.now()
  1036 + else :
  1037 + start_date = datetime.datetime.strptime(self.request.GET.get('init_date',''),date_format)
  1038 + end_date = datetime.datetime.strptime(self.request.GET.get('end_date',''),date_format)
  1039 + context["init_date"] = start_date
  1040 + context["end_date"] = end_date
  1041 + alunos = goal.students.all()
  1042 + if goal.all_students :
  1043 + alunos = goal.topic.subject.students.all()
  1044 +
  1045 + vis_ou = Log.objects.filter(context__contains={'goals_id':goal.id},resource="goals",user_email__in=(aluno.email for aluno in alunos), datetime__range=(start_date,end_date + datetime.timedelta(minutes = 1))).filter(Q(action="view") | Q(action="submit"))
  1046 + did,n_did,history = str(_("Realized")),str(_("Unrealized")),str(_("Historic"))
  1047 + re = []
  1048 + data_n_did,data_history = [],[]
  1049 + json_n_did, json_history = {},{}
  1050 +
  1051 + for log_al in vis_ou.order_by("datetime"):
  1052 + data_history.append([str(alunos.get(email=log_al.user_email)),
  1053 + ", ".join([str(x) for x in goal.topic.subject.group_subject.filter(participants__email=log_al.user_email)]),
  1054 + log_al.action,log_al.datetime])
  1055 +
  1056 + json_history["data"] = data_history
  1057 +
  1058 + column_view,column_submit = str(_('View')),str(_('Submitted'))
  1059 +
  1060 + not_view = alunos.exclude(email__in=[log.user_email for log in vis_ou.filter(action="view").distinct("user_email")])
  1061 + index = 0
  1062 + for alun in not_view:
  1063 + data_n_did.append([index,str(alun),", ".join([str(x) for x in goal.topic.subject.group_subject.filter(participants__email=alun.email)]),column_view, str(alun.email)])
  1064 + index += 1
  1065 +
  1066 + not_watch = alunos.exclude(email__in=[log.user_email for log in vis_ou.filter(action="submit").distinct("user_email")])
  1067 + for alun in not_watch:
  1068 + data_n_did.append([index,str(alun),", ".join([str(x) for x in goal.topic.subject.group_subject.filter(participants__email=alun.email)]),column_submit, str(alun.email)])
  1069 + index += 1
  1070 +
  1071 + json_n_did["data"] = data_n_did
  1072 +
  1073 +
  1074 + context["json_n_did"] = json_n_did
  1075 + context["json_history"] = json_history
  1076 + c_visualizou = vis_ou.filter(action="view").distinct("user_email").count()
  1077 + c_submit = vis_ou.filter(action="submit").distinct("user_email").count()
  1078 + re.append([str(_('Goals')),did,n_did])
  1079 +
  1080 + re.append([column_view,c_visualizou, alunos.count() - c_visualizou])
  1081 + re.append([column_submit,c_submit, alunos.count() - c_submit])
  1082 +
  1083 + context['view'] = column_view
  1084 + context['submit'] = column_submit
  1085 + context['topic'] = goal.topic
  1086 + context['subject'] = goal.topic.subject
  1087 + context['goal'] = goal
  1088 + context['db_data'] = re
  1089 + context['title_chart'] = _('Actions about resource')
  1090 + context['title_vAxis'] = _('Quantity')
  1091 +
  1092 + context["n_did_table"] = n_did
  1093 + context["did_table"] = did
  1094 + context["history_table"] = history
  1095 + return context
  1096 +
  1097 +from django.http import HttpResponse #used to send HTTP 404 error to ajax
  1098 +
  1099 +class SendMessage(LoginRequiredMixin, LogMixin, generic.edit.FormView):
  1100 + log_component = 'resources'
  1101 + log_action = 'send'
  1102 + log_resource = 'goals'
  1103 + log_context = {}
  1104 +
  1105 + login_url = reverse_lazy("users:login")
  1106 + redirect_field_name = 'next'
  1107 +
  1108 + template_name = 'goals/send_message.html'
  1109 + form_class = FormModalMessage
  1110 +
  1111 + def dispatch(self, request, *args, **kwargs):
  1112 + slug = self.kwargs.get('slug', '')
  1113 + goal = get_object_or_404(Goals, slug = slug)
  1114 + self.goal = goal
  1115 +
  1116 + if not has_subject_permissions(request.user, goal.topic.subject):
  1117 + return redirect(reverse_lazy('subjects:home'))
  1118 +
  1119 + return super(SendMessage, self).dispatch(request, *args, **kwargs)
  1120 +
  1121 + def form_valid(self, form):
  1122 + message = form.cleaned_data.get('comment')
  1123 + image = form.cleaned_data.get("image",'')
  1124 + users = (self.request.POST.get('users[]','')).split(",")
  1125 + user = self.request.user
  1126 + subject = self.goal.topic.subject
  1127 +
  1128 + if (users[0] is not ''):
  1129 + for u in users:
  1130 + to_user = User.objects.get(email=u)
  1131 + talk, create = Conversation.objects.get_or_create(user_one=user,user_two=to_user)
  1132 + created = TalkMessages.objects.create(text=message,talk=talk,user=user,subject=subject,image=image)
  1133 +
  1134 + simple_notify = textwrap.shorten(strip_tags(message), width = 30, placeholder = "...")
  1135 +
  1136 + if image is not '':
  1137 + simple_notify += " ".join(_("[Photo]"))
  1138 +
  1139 + notification = {
  1140 + "type": "chat",
  1141 + "subtype": "subject",
  1142 + "space": subject.slug,
  1143 + "user_icon": created.user.image_url,
  1144 + "notify_title": str(created.user),
  1145 + "simple_notify": simple_notify,
  1146 + "view_url": reverse("chat:view_message", args = (created.id, ), kwargs = {}),
  1147 + "complete": render_to_string("chat/_message.html", {"talk_msg": created}, self.request),
  1148 + "container": "chat-" + str(created.user.id),
  1149 + "last_date": _("Last message in %s")%(formats.date_format(created.create_date, "SHORT_DATETIME_FORMAT"))
  1150 + }
  1151 +
  1152 + notification = json.dumps(notification)
  1153 +
  1154 + Group("user-%s" % to_user.id).send({'text': notification})
  1155 +
  1156 + ChatVisualizations.objects.create(viewed = False, message = created, user = to_user)
  1157 + success = str(_('The message was successfull sent!'))
  1158 + return JsonResponse({"message":success})
  1159 + erro = HttpResponse(str(_("No user selected!")))
  1160 + erro.status_code = 404
  1161 + return erro
  1162 +
  1163 + def get_context_data(self, **kwargs):
  1164 + context = super(SendMessage,self).get_context_data()
  1165 + context["goal"] = get_object_or_404(Goals, slug=self.kwargs.get('slug', ''))
  1166 + return context
  1167 +
... ...
youtube_video/templates/youtube/relatorios.html
... ... @@ -401,7 +401,7 @@
401 401 }
402 402 }
403 403 }
404   - console.log(search);
  404 +
405 405 if (!load_histoty){
406 406 drawTable(column_n_did,pagination(search,1),false);
407 407 } else {
... ...