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 @@ @@ -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 @@ @@ -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 \ No newline at end of file 113 \ No newline at end of file
@@ -16,4 +16,6 @@ urlpatterns = [ @@ -16,4 +16,6 @@ urlpatterns = [
16 url(r'^unanswered_report/(?P<slug>[\w_-]+)/$', views.UnansweredReport.as_view(), name = 'unanswered_report'), 16 url(r'^unanswered_report/(?P<slug>[\w_-]+)/$', views.UnansweredReport.as_view(), name = 'unanswered_report'),
17 url(r'^history_report/(?P<slug>[\w_-]+)/$', views.HistoryReport.as_view(), name = 'history_report'), 17 url(r'^history_report/(?P<slug>[\w_-]+)/$', views.HistoryReport.as_view(), name = 'history_report'),
18 url(r'^view_log/(?P<goal>[\w_-]+)/(?P<report>[\w_-]+)/$', views.reports_log, name = 'reports_log'), 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,6 +20,22 @@ from users.models import User
20 from .forms import GoalsForm, MyGoalsForm, InlinePendenciesFormset, InlineGoalItemFormset 20 from .forms import GoalsForm, MyGoalsForm, InlinePendenciesFormset, InlineGoalItemFormset
21 from .models import Goals, MyGoals 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 class Reports(LoginRequiredMixin, generic.ListView): 39 class Reports(LoginRequiredMixin, generic.ListView):
24 login_url = reverse_lazy("users:login") 40 login_url = reverse_lazy("users:login")
25 redirect_field_name = 'next' 41 redirect_field_name = 'next'
@@ -966,4 +982,185 @@ def reports_log(request, goal, report): @@ -966,4 +982,185 @@ def reports_log(request, goal, report):
966 982
967 return JsonResponse({'message': 'ok', 'log_id': log_id}) 983 return JsonResponse({'message': 'ok', 'log_id': log_id})
968 984
969 - return JsonResponse({'message': 'ok'})  
970 \ No newline at end of file 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,7 +401,7 @@
401 } 401 }
402 } 402 }
403 } 403 }
404 - console.log(search); 404 +
405 if (!load_histoty){ 405 if (!load_histoty){
406 drawTable(column_n_did,pagination(search,1),false); 406 drawTable(column_n_did,pagination(search,1),false);
407 } else { 407 } else {