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