mirror of https://github.com/interlegis/sapl.git
Cesar Augusto de Carvalho
5 years ago
committed by
Edward
19 changed files with 1005 additions and 43 deletions
@ -0,0 +1,91 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Generated by Django 1.11.20 on 2019-12-09 11:28 |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('parlamentares', '0035_merge_20190802_0954'), |
|||
('painel', '0011_cronometro_last_stop_duration'), |
|||
('sessao', '0051_merge_20191209_0910'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.CreateModel( |
|||
name='CronometroLista', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('cronometro', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='painel.Cronometro')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Tipo de Lista de Discurso - Cronômetro', |
|||
'verbose_name_plural': 'Tipo de Listas de Discurso - Cronômetros', |
|||
'ordering': ['tipo_lista', 'cronometro'], |
|||
}, |
|||
), |
|||
migrations.CreateModel( |
|||
name='ListaDiscurso', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('orador_atual', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='parlamentares.Parlamentar')), |
|||
('sessao_plenaria', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='sessao.SessaoPlenaria', verbose_name='Sessão Plenária')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Lista de Discurso', |
|||
'verbose_name_plural': 'Listas de Discurso', |
|||
'ordering': ['tipo', 'sessao_plenaria'], |
|||
}, |
|||
), |
|||
migrations.CreateModel( |
|||
name='ParlamentarLista', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('ordenacao', models.PositiveIntegerField(blank=True, null=True, verbose_name='Ordenação')), |
|||
('lista', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='sessao.ListaDiscurso')), |
|||
('parlamentar', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='parlamentares.Parlamentar')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Lista de Discurso - Parlamentar', |
|||
'verbose_name_plural': 'Listas de Discurso - Parlamentares', |
|||
'ordering': ['lista', 'parlamentar', 'ordenacao'], |
|||
}, |
|||
), |
|||
migrations.CreateModel( |
|||
name='TipoListaDiscurso', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('nome', models.CharField(max_length=100, verbose_name='Tipo')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Tipo de Lista de Discurso', |
|||
'verbose_name_plural': 'Tipos de Lista de Discurso', |
|||
'ordering': ['nome'], |
|||
}, |
|||
), |
|||
migrations.AddField( |
|||
model_name='listadiscurso', |
|||
name='tipo', |
|||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='sessao.TipoListaDiscurso', verbose_name='Tipo de Lista de Discurso'), |
|||
), |
|||
migrations.AddField( |
|||
model_name='cronometrolista', |
|||
name='tipo_lista', |
|||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='sessao.TipoListaDiscurso'), |
|||
), |
|||
migrations.AlterUniqueTogether( |
|||
name='parlamentarlista', |
|||
unique_together=set([('lista', 'parlamentar')]), |
|||
), |
|||
migrations.AlterUniqueTogether( |
|||
name='listadiscurso', |
|||
unique_together=set([('tipo', 'sessao_plenaria')]), |
|||
), |
|||
migrations.AlterUniqueTogether( |
|||
name='cronometrolista', |
|||
unique_together=set([('tipo_lista', 'cronometro')]), |
|||
), |
|||
] |
@ -0,0 +1,289 @@ |
|||
{% load i18n %} |
|||
{% load common_tags %} |
|||
|
|||
{% load render_bundle from webpack_loader %} |
|||
{% load webpack_static from webpack_loader %} |
|||
|
|||
<!DOCTYPE HTML> |
|||
<!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]--> |
|||
<!--[if gt IE 8]><!--> |
|||
<html lang="en"> |
|||
<!--<![endif]--> |
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|||
<!-- TODO: does it need this head_title here? --> |
|||
<title>{% block head_title %}{% trans 'SAPL - Sistema de Apoio ao Processo Legislativo' %}{% endblock %}</title> |
|||
|
|||
{% block webpack_loader_css %} |
|||
{% render_chunk_vendors 'css' %} |
|||
{% render_bundle 'global' 'css' %} |
|||
{% render_bundle 'painel' 'css' %} |
|||
{% endblock webpack_loader_css %} |
|||
|
|||
</head> |
|||
<body class="painel-principal"> |
|||
<audio type="hidden" id="audio" src="{% webpack_static 'audio/ring.mp3' %}"></audio> |
|||
|
|||
{% if painel_config.exibir_nome_casa %} |
|||
<div class="d-flex justify-content-center"> |
|||
<h1 id="casa_legislativa" class="title text-title" style="color:red">{{casa.nome}}</h1> |
|||
</div> |
|||
{% endif %} |
|||
<div class="d-flex justify-content-center"> |
|||
<h1 id="sessao_plenaria" class="title text-title"></h1> |
|||
</div> |
|||
<div class="row "> |
|||
<div class="col text-center"> |
|||
<span id="sessao_plenaria_data" class="text-value"></span> |
|||
</div> |
|||
<div class="col text-center"> |
|||
<span id="sessao_plenaria_hora_inicio" class="text-value"></span> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="row justify-content-center"> |
|||
<div class="col-1"> |
|||
<img src="" id="logo-painel" class="logo-painel" alt=""/> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="row justify-content-center"> |
|||
<h2 class="text-danger"><span id="message"></span></h2> |
|||
<h2 class="text-danger">{{lista.tipo}}</h2> |
|||
</div> |
|||
|
|||
<div class="row"> |
|||
<div class="col text-center"><span class="text-value data-hora" id="date"></span></div> |
|||
<div class="col text-center"><span class="text-value data-hora" id="relogio"></span></div> |
|||
</div> |
|||
|
|||
<div class="d-flex justify-content-start"> |
|||
|
|||
<div class="col-md-4"> |
|||
<div class="text-center painel"> |
|||
<h2 class="text-subtitle">Parlamentares</h2> |
|||
<span id="oradores" class="text-value text-center"></span> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="col-md-4"> |
|||
<div id="orador-div" class="text-center painel"> |
|||
<h2 class="text-subtitle">Orador(a)</h2> |
|||
<span id="orador" class="text-value text-center"></span> |
|||
<br><br> |
|||
<div id="foto-div"></div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="col-md-4 text-center painel"> |
|||
<h2 class="text-subtitle">{% if cronometros|length == 1 %}Cronômetro{% elif cronometros|length > 1%}Cronômetros{% endif %}</h2> |
|||
<div class="text-value"> |
|||
{% for cronometro in cronometros %} |
|||
{{cronometro}}: <span id="cronometro_{{cronometro.id}}"></span><br> |
|||
{% endfor %} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
|
|||
{% block webpack_loader_js %} |
|||
{% render_chunk_vendors 'js' %} |
|||
{% render_bundle 'global' 'js' %} |
|||
{% render_bundle 'painel' 'js' %} |
|||
{% endblock webpack_loader_js %} |
|||
|
|||
{% block webpack_loader_chunks_js %} |
|||
{% endblock webpack_loader_chunks_js %} |
|||
|
|||
<script type="text/javascript"> |
|||
var d = new Date(); |
|||
var n = d.toLocaleDateString(); |
|||
document.getElementById("date").innerHTML = n; |
|||
|
|||
function checkTime(i) { |
|||
if (i<10) {i = "0" + i}; // add zero in front of numbers < 10 |
|||
return i; |
|||
} |
|||
|
|||
function startTime() { |
|||
var today=new Date(); |
|||
var h=today.getHours(); |
|||
var m=today.getMinutes(); |
|||
var s=today.getSeconds(); |
|||
m = checkTime(m); |
|||
s = checkTime(s); |
|||
$("#relogio").text(h+":"+m+":"+s) |
|||
var t = setTimeout(function(){ |
|||
startTime() |
|||
}, 500); |
|||
} |
|||
|
|||
function playAudioNumVezes(audio, times, ended) { |
|||
if (times <= 0) { |
|||
return; |
|||
} |
|||
let played = 0; |
|||
audio.addEventListener("ended", function() { |
|||
played++; |
|||
if (played < times) { |
|||
audio.play(); |
|||
} else if (ended) { |
|||
ended(); |
|||
} |
|||
}); |
|||
audio.play(); |
|||
} |
|||
|
|||
function convertValueToDuration(value){ |
|||
let h = Math.floor((value/1000) / 3600); |
|||
h = checkTime(h); |
|||
let m = Math.floor((value/1000) % 3600 / 60); |
|||
m = checkTime(m); |
|||
let s = Math.floor((value/1000) % 3600 % 60); |
|||
s = checkTime(s); |
|||
return h.toString() + ":" + m.toString() + ":" + s.toString(); |
|||
} |
|||
|
|||
$(document).ready(function() { |
|||
//TODO: replace by a fancy jQuery clock |
|||
startTime(); |
|||
|
|||
var audioAlertFinish = document.getElementById("audio"); |
|||
|
|||
// Obtém duração do disparo ao término do tempo e converte para segundos |
|||
var duracao_disparo = "{{ painel_config.tempo_disparo_termino }}"; |
|||
let tmp = duracao_disparo.split(":"); |
|||
duracao_disparo = parseInt(tmp[0])*3600 + parseInt(tmp[1])*60 + parseInt(tmp[2]); |
|||
var num_vezes_toca_audio = Math.round(duracao_disparo/audioAlertFinish.duration); |
|||
|
|||
var cronometros_previous = []; |
|||
{% for cron in cronometros %} |
|||
cronometros_previous.push(0); |
|||
$('#cronometro_' + "{{cron.id}}").runner({ |
|||
autostart: {% if cron.status == "I"%} true {% else %} false {% endif %}, |
|||
countdown: true, |
|||
startAt: |
|||
{% if cron.status == "R" %} |
|||
parseInt("{{cron.duracao_cronometro|duration_to_seconds}}") * 1000 |
|||
{% elif cron.status == "S" %} |
|||
{% if cron.last_stop_duration %} |
|||
parseInt("{{cron.last_stop_duration|duration_to_seconds}}") * 1000 |
|||
{% else %} |
|||
parseInt("{{cron.duracao_cronometro|duration_to_seconds}}") * 1000 |
|||
{% endif %} |
|||
{% elif cron.status == "I" %} |
|||
parseInt("{{cron.duracao_cronometro|duration_difference:cron.ultima_alteracao_status}}") * 1000 |
|||
{% endif %}, |
|||
stopAt: 0, |
|||
milliseconds: false, |
|||
format: convertValueToDuration |
|||
}).on('runnerFinish', function(eventObject, info){ |
|||
playAudioNumVezes(audioAlertFinish, num_vezes_toca_audio); |
|||
}); |
|||
{% endfor %} |
|||
|
|||
var tempo_disparo_antecedencia = "{{ painel_config.tempo_disparo_antecedencia }}" |
|||
tmp = tempo_disparo_antecedencia.split(":"); |
|||
tempo_disparo_antecedencia = checkTime(parseInt(tmp[0])) + ":" + checkTime(parseInt(tmp[1])) + ":" + checkTime(parseInt(tmp[2])); |
|||
|
|||
(function poll() { |
|||
$.ajax({ |
|||
url: "{% url 'sapl.painel:dados_painel_discurso' sessao_id lista.tipo.pk %}", |
|||
type: "GET", |
|||
success: function(data) { |
|||
$("#sessao_plenaria").text(data["sessao_plenaria"]) |
|||
$("#sessao_plenaria_data").text("Data Início: " + data["sessao_plenaria_data"]) |
|||
$("#sessao_plenaria_hora_inicio").text("Hora Início: " + data["sessao_plenaria_hora_inicio"]) |
|||
|
|||
$("#orador").text(data['orador']); |
|||
|
|||
if (data["brasao"] != null) |
|||
$("#logo-painel").attr("src", data["brasao"]); |
|||
$("#foto-div").children().remove(); |
|||
if (data["orador_img"] != null){ |
|||
$("#foto-div").children().remove(); |
|||
$("#foto-div").append('<img style="width:300px; height:300px" src=' + |
|||
data["orador_img"] + ' id="foto-orador" alt=""/>') |
|||
} |
|||
|
|||
var oradores = $("#oradores"); |
|||
oradores.children().remove(); |
|||
|
|||
var oradores_list = data["oradores"]; |
|||
|
|||
oradores.append('<table style="margin-left:30%" id="oradores_list">'); |
|||
$.each(oradores_list, function (index, parlamentar) { |
|||
if(parlamentar != data['orador']){ |
|||
$('#oradores_list').append('<tr><td class="text-value" style="color:white" >' + |
|||
' ' + (index+1) + '.  ' + parlamentar + '</td></tr>') |
|||
} |
|||
else{ |
|||
$('#oradores_list').append('<tr><td class="text-value" style="color:yellow" >' + |
|||
' ' + (index+1) + '.  ' + parlamentar + '</td></tr>') |
|||
} |
|||
}); |
|||
|
|||
// obtém todos os ids em uma lista e |
|||
// converte os dados do status dos cronômetros de dicionário para uma lista |
|||
var ids = []; |
|||
var status_cronometros = []; |
|||
for (var key in data['cronometros']) { |
|||
if (data['cronometros'].hasOwnProperty(key)) { |
|||
ids.push(key); |
|||
status_cronometros.push(data['cronometros'][key]); |
|||
} |
|||
} |
|||
//console.log(data['cronometros']) |
|||
|
|||
// converte os dados de dicionário para uma lista |
|||
var duracao_cronometros = []; |
|||
for (let id of ids) { |
|||
duracao_cronometros.push(data['duracao_cronometros'][id]); |
|||
} |
|||
|
|||
for(let i=0; i<status_cronometros.length; i++){ |
|||
if (!cronometros_previous[i]) |
|||
cronometros_previous[i] = '' |
|||
|
|||
// se houve alteração de status |
|||
if (status_cronometros[i] != cronometros_previous[i]) { |
|||
if(status_cronometros[i] == 'reset'){ |
|||
// é necessário recriar o cronômetro com o valor da duração original devido a limitações da API |
|||
$('#cronometro_' + ids[i]).runner({ |
|||
autostart: false, |
|||
countdown: true, |
|||
startAt: parseInt(duracao_cronometros[i]) * 1000, |
|||
stopAt: 0, |
|||
milliseconds: false, |
|||
format: convertValueToDuration |
|||
}).on('runnerFinish', function(eventObject, info){ |
|||
playAudioNumVezes(audioAlertFinish, num_vezes_toca_audio); |
|||
}); |
|||
} |
|||
// ações de start e stop |
|||
else{ |
|||
$('#cronometro_' + ids[i]).runner(status_cronometros[i]); |
|||
} |
|||
cronometros_previous[i] = status_cronometros[i]; |
|||
} |
|||
|
|||
// Dispara aviso prévio se estiver configurado |
|||
if($('#cronometro_' + ids[i]).runner('info').formattedTime == tempo_disparo_antecedencia |
|||
&& "{{ painel_config.disparo_cronometro }}" == "True" ){ |
|||
audioAlertFinish.play(); |
|||
} |
|||
} |
|||
}, |
|||
error: function(err) { |
|||
console.error(err); |
|||
}, |
|||
dataType: "json", |
|||
complete: setTimeout(function() {poll()}, 500), |
|||
timeout: 20000 // TODO: decrease |
|||
}) |
|||
})(); |
|||
}); |
|||
</script> |
|||
</html> |
|||
|
@ -0,0 +1,2 @@ |
|||
{% extends "crud/form.html" %} |
|||
{% load i18n %} |
@ -0,0 +1,153 @@ |
|||
{% extends "base.html" %} |
|||
{% load i18n staticfiles menus %} |
|||
|
|||
{% load common_tags %} |
|||
{% load render_bundle from webpack_loader %} |
|||
{% load webpack_static from webpack_loader %} |
|||
|
|||
|
|||
{% block title %} |
|||
<h1 class="page-header"> |
|||
Lista de Discurso <small>({{sessaoplenaria}})</small> |
|||
</h1> |
|||
{% endblock %} |
|||
|
|||
{% block base_content %} |
|||
{{block.super}} |
|||
<div id="lista-discurso"> |
|||
<br> |
|||
|
|||
<div v-if="tipo_listas.length > 0"> |
|||
<h3>Selecione um Tipo de Lista de Discurso</h3> |
|||
<select class="form-control" v-model="lista_selecionada"> |
|||
<option v-for="l in tipo_listas" v-bind:value="{id:l.id, nome:l.nome}"> |
|||
[[ l.nome ]] |
|||
</option> |
|||
</select> |
|||
</div> |
|||
|
|||
<h3 v-else> |
|||
Não há <a href="{% url 'sapl.sessao:tipolistadiscurso_create' %}"> |
|||
<b>Tipos de Lista de Discurso</b></a> criadas. Para criar, vá em |
|||
<b>Sistema -> Tabelas Auxiliares -> Tipo de Lista de Discurso.</b> |
|||
</h3> |
|||
<br> |
|||
|
|||
<div v-if="lista_selecionada" class="form-group row"> |
|||
<div class="col-md-6"> |
|||
<button @click="selecionado_add = !selecionado_add; selecionado_painel = false;" :class="{btSelecionado:selecionado_add,}" class="btn btn-secondary btn-lg form-control" type="button"> |
|||
Adicionar Parlamentar à Lista de Discurso |
|||
</button> |
|||
</div> |
|||
<div class="col-md-6"> |
|||
<button @click="selecionado_add = false; selecionado_painel = !selecionado_painel;" :class="{btSelecionado:selecionado_painel,}" class="btn btn-secondary btn-lg form-control" type="button"> |
|||
Painel da Lista de Discurso |
|||
</button> |
|||
</div> |
|||
</div> |
|||
|
|||
<br> |
|||
<br> |
|||
|
|||
<div v-if="selecionado_add" id="collapseAddParlamentar"> |
|||
<div v-if="lista_selecionada" class="row"> |
|||
<div class="col-md-6"> |
|||
<h3>Parlamentares</h3> |
|||
<h6>Aperte CTRL para selecionar mais de um</h6> |
|||
<br> |
|||
<select v-if="parlamentares" v-model="parlamentares_selecionados" multiple size="15" class="form-control"> |
|||
<option v-for="p in parlamentares" v-bind:value="{nome:p.nome, id:p.id}"> |
|||
[[ p.nome ]] |
|||
</option> |
|||
</select> |
|||
|
|||
</div> |
|||
<div v-if="parlamentares_selecionados.length > 0" class="col-md-6"> |
|||
<h3>Lista de Discurso<h3> |
|||
<h6>Arraste para ordenar</h6> |
|||
<br> |
|||
|
|||
{% comment %} <h3 v-for="p in parlamentares_selecionados">[[p.nome]] </h3> {% endcomment %} |
|||
|
|||
<draggable v-model="parlamentares_selecionados" class="list-group" ghost-class="ghost"> |
|||
<div class="list-group-item" v-for="(element,index) in parlamentares_selecionados" :key="element.id"> |
|||
[[index+1]]. [[element.nome]] |
|||
</div> |
|||
</draggable> |
|||
</div> |
|||
|
|||
</div> |
|||
<br><br> |
|||
|
|||
<div v-if="lista_selecionada" class="row"> |
|||
<div style="align:center" class="col-md-12 text-center"> |
|||
<button v-on:click="saveParlamentarLista" type="button" class="btn btn-primary">Salvar Lista</button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div v-if="selecionado_painel" id="collapsePainelLista"> |
|||
<div v-if="lista_selecionada" class="row"> |
|||
<div v-if="parlamentares_selecionados.length > 0" class="col-md-6"> |
|||
<h3>Lista de Discurso<h3> |
|||
<h6>Clique uma vez para escolher o orador e uma segunda vez para desmarcar o orador.</h6> |
|||
<br> |
|||
<b-list-group v-for="(element,index) in parlamentares_selecionados" :key="element.id"> |
|||
<b-list-group-item button @click='setOrador(index)' :class="{current:parlamentares_selecionados[index].id == orador}"> |
|||
[[index+1]]. [[element.nome]] |
|||
</b-list-group-item> |
|||
</b-list-group> |
|||
</div> |
|||
<div class="col-md-6"> |
|||
<h3>Cronômetros<h3> |
|||
<br><br> |
|||
<div v-for="(cron,index) in cronometros_lista"> |
|||
|
|||
<div class="row"> |
|||
<div class="col-md-12 mb-2"><h3><a :href="'/sistema/cronometro/'+ cron.id">[[cron.tipo]]</a></h3></div> |
|||
</div> |
|||
|
|||
<countdown ref="countdown" :time="cron.duracao_cronometro._atual" :auto-start="counting[index]" :transform="transform" @end="handleCountdownEnd(index)"> |
|||
<template slot-scope="props"> |
|||
<input size="6" :id='"cronometro_"+cron.id' :value="props.hours+':'+props.minutes+':'+props.seconds" readyonly="true" class="form-control"> |
|||
</template> |
|||
</countdown> |
|||
<br> |
|||
|
|||
<div class="row"> |
|||
<div v-if="!counting[index]" class="col-md-6"> |
|||
<button type="button" :id='"cronometro_" + cron.id + "_Start"' class="btn btn-success" @click="startCountdown(index)">Iniciar</button> |
|||
</div> |
|||
<div v-else class="col-md-6"> |
|||
<button type="button" :id='"cronometro_" + cron.id + "_Stop"' class="btn btn-danger" @click="stopCountdown(index)">Parar</button> |
|||
</div> |
|||
<div v-if="!counting[index]" class="col-md-6"> |
|||
<button type="button" :id='"cronometro_" + cron.id + "_Reset"' class="btn btn-success" @click="resetCountdown(index)">Reiniciar</button> |
|||
</div> |
|||
</div> |
|||
|
|||
<br><br> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<br><br> |
|||
<div v-if="lista_selecionada" class="row" > |
|||
<div style="text-align: center" class="col-md-12"> |
|||
<div class="col-md-12"> |
|||
<a @click="abrir_painel" |
|||
class="btn btn-primary active"> |
|||
Abrir Painel |
|||
</a> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
</div> |
|||
{% endblock %} |
|||
|
|||
{% block webpack_loader_js %} |
|||
{% render_chunk_vendors 'js' %} |
|||
{% render_bundle 'global' 'js' %} |
|||
{% render_bundle 'sessao' 'js' %} |
|||
{% endblock webpack_loader_js %} |
@ -0,0 +1,57 @@ |
|||
{% extends "crud/detail.html" %} |
|||
{% load i18n %} |
|||
|
|||
{% block sub_actions %} |
|||
{{block.super}} |
|||
<div class="actions btn-group btn-group-sm" role="group"> |
|||
<a href="{% url 'sapl.sessao:cronometrolista_form' object.pk %}" class="btn btn-outline-primary">Vincular Cronômetro</a> |
|||
</div> |
|||
{% endblock sub_actions %} |
|||
|
|||
{% block detail_content %} |
|||
{{block.super}} |
|||
{% if cronometros_lista %} |
|||
<h2 class="legend">Cronômetros vinculados</h2> |
|||
<table class="table table-striped table-hover table-link-ordering"> |
|||
<thead> |
|||
<tr> |
|||
<th>Cronômetros</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
{% for cl in cronometros_lista %} |
|||
<tr> |
|||
<td><a href="{% url 'sapl.painel:cronometro_detail' cl.cronometro.pk %}">{{cl.cronometro}}</a></td> |
|||
<td> |
|||
<button type="button" class="btn btn-danger float-right" onclick='desvincular("{{cl.pk}}")'> |
|||
Desvincular |
|||
</button> |
|||
</td> |
|||
</tr> |
|||
{% endfor %} |
|||
</tbody> |
|||
</table> |
|||
{% endif %} |
|||
{% endblock %} |
|||
|
|||
{% block extra_js %} |
|||
|
|||
<script type="text/javascript"> |
|||
function desvincular(pk){ |
|||
var csrftoken = '{{ csrf_token }}'; |
|||
$.ajax({ |
|||
url: "/api/sessao/cronometrolista/"+pk, |
|||
headers: { |
|||
'X-CSRFToken':csrftoken, |
|||
}, |
|||
type: 'delete', |
|||
contentType: 'application/json', |
|||
success: function(result){ |
|||
console.log("Cronômetro desvinculado."); |
|||
} |
|||
}); |
|||
location.reload(); |
|||
} |
|||
</script> |
|||
|
|||
{% endblock %} |
Loading…
Reference in new issue