mirror of https://github.com/interlegis/sigi.git
Sesostris Vieira
2 years ago
10 changed files with 217 additions and 19 deletions
@ -0,0 +1,12 @@ |
|||||
|
from django.contrib import admin |
||||
|
from sigi.apps.utils.models import SigiAlert |
||||
|
from tinymce.models import HTMLField |
||||
|
from tinymce.widgets import AdminTinyMCE |
||||
|
|
||||
|
|
||||
|
@admin.register(SigiAlert) |
||||
|
class SigiAlertAdmin(admin.ModelAdmin): |
||||
|
list_display = ("titulo", "caminho", "destinatarios") |
||||
|
search_fields = ("titulo", "caminho") |
||||
|
formfield_overrides = {HTMLField: {"widget": AdminTinyMCE}} |
||||
|
list_filter = ("destinatarios",) |
@ -0,0 +1,53 @@ |
|||||
|
from django.contrib.auth.models import AnonymousUser |
||||
|
from django.db.models import Q |
||||
|
from sigi.apps.utils.models import SigiAlert |
||||
|
from django.template.loader import render_to_string |
||||
|
|
||||
|
|
||||
|
class SigiAlertsMiddleware: |
||||
|
def __init__(self, get_response): |
||||
|
self.get_response = get_response |
||||
|
|
||||
|
def __call__(self, request): |
||||
|
response = self.get_response(request) |
||||
|
if response.streaming: |
||||
|
return response |
||||
|
if ( |
||||
|
request.method == "GET" |
||||
|
and response.status_code == 200 |
||||
|
and "Content-Type" in response.headers |
||||
|
and "html" in response.headers["Content-Type"] |
||||
|
and b"</body>" in response.content |
||||
|
): |
||||
|
if hasattr(request, "user"): |
||||
|
user = request.user |
||||
|
else: |
||||
|
user = AnonymousUser() |
||||
|
|
||||
|
destinos = ["A"] |
||||
|
if user.is_anonymous or not user.is_authenticated: |
||||
|
destinos.append("N") |
||||
|
if user.is_staff: |
||||
|
destinos.append("S") |
||||
|
if user.is_superuser: |
||||
|
destinos.append("D") |
||||
|
|
||||
|
alertas = SigiAlert.objects.filter( |
||||
|
Q(caminho=request.path_info) |
||||
|
& Q(destinatarios__in=destinos) |
||||
|
# & Q(Q(grupos__icontains=user.groups.all()) | Q(grupo__isnull=True)) |
||||
|
) |
||||
|
|
||||
|
if len(alertas) > 0: |
||||
|
avisos = {} |
||||
|
context = {"alertas": alertas} |
||||
|
snippet = render_to_string( |
||||
|
"sigialerts/alert_snippet.html", |
||||
|
request=request, |
||||
|
context=context, |
||||
|
) |
||||
|
snippet += "</body>" |
||||
|
response.content = response.content.replace( |
||||
|
b"</body>", snippet.encode("utf-8") |
||||
|
) |
||||
|
return response |
@ -0,0 +1,30 @@ |
|||||
|
# Generated by Django 4.0.6 on 2022-07-12 20:41 |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
import tinymce.models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
initial = True |
||||
|
|
||||
|
dependencies = [ |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.CreateModel( |
||||
|
name='SigiAlert', |
||||
|
fields=[ |
||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('caminho', models.CharField(max_length=200, verbose_name='caminho da tela')), |
||||
|
('destinatarios', models.CharField(choices=[('A', 'Todo e qualquer usuário'), ('N', 'Usuários anônimos / não autenticados'), ('S', 'Membros da equipe Interlegis'), ('D', 'Administradores do sistema')], max_length=1, verbose_name='destinatários')), |
||||
|
('titulo', models.CharField(max_length=60, verbose_name='título')), |
||||
|
('mensagem', tinymce.models.HTMLField(verbose_name='mensagem')), |
||||
|
], |
||||
|
options={ |
||||
|
'verbose_name': 'alerta SIGI', |
||||
|
'verbose_name_plural': 'alertas SIGI', |
||||
|
'ordering': ('caminho', 'destinatarios'), |
||||
|
}, |
||||
|
), |
||||
|
] |
@ -0,0 +1,28 @@ |
|||||
|
from pyexpat import model |
||||
|
from django.db import models |
||||
|
from django.contrib.auth.models import Group |
||||
|
from django.utils.translation import gettext as _ |
||||
|
from tinymce.models import HTMLField |
||||
|
|
||||
|
|
||||
|
class SigiAlert(models.Model): |
||||
|
DESTINATARIOS_CHOICES = ( |
||||
|
("A", _("Todo e qualquer usuário")), |
||||
|
("N", _("Usuários anônimos / não autenticados")), |
||||
|
("S", _("Membros da equipe Interlegis")), |
||||
|
("D", _("Administradores do sistema")), |
||||
|
) |
||||
|
caminho = models.CharField(_("caminho da tela"), max_length=200) |
||||
|
destinatarios = models.CharField( |
||||
|
_("destinatários"), max_length=1, choices=DESTINATARIOS_CHOICES |
||||
|
) |
||||
|
titulo = models.CharField(_("título"), max_length=60) |
||||
|
mensagem = HTMLField(_("mensagem")) |
||||
|
|
||||
|
class Meta: |
||||
|
ordering = ("caminho", "destinatarios") |
||||
|
verbose_name = _("alerta SIGI") |
||||
|
verbose_name_plural = _("alertas SIGI") |
||||
|
|
||||
|
def __str__(self): |
||||
|
return self.titulo |
@ -0,0 +1,90 @@ |
|||||
|
{% load i18n %} |
||||
|
<style> |
||||
|
.carrossel { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
min-height: 300px; |
||||
|
} |
||||
|
.carrossel .carrossel-item { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
min-height: 300px; |
||||
|
} |
||||
|
.carrossel .carrossel-controls { |
||||
|
display: block; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.carrossel .carrossel-controls .carrossel-control { |
||||
|
background-color: var(--body-quiet-color); |
||||
|
cursor: pointer; |
||||
|
height: 18px; |
||||
|
width: 18px; |
||||
|
margin: 0 6px; |
||||
|
padding: 2px; |
||||
|
border-radius: 50%; |
||||
|
display: inline-block; |
||||
|
font-size: 10px; |
||||
|
color: white; |
||||
|
} |
||||
|
.carrossel .carrossel-controls .carrossel-control.active { |
||||
|
background-color: var(--main-bg-color); |
||||
|
font-weight: 400; |
||||
|
} |
||||
|
</style> |
||||
|
<div class="fixed-action-btn left"> |
||||
|
<a id="botao-info" class="btn-floating btn-medium modal-trigger green" href="#modal-info"> |
||||
|
<i class="large material-icons">info</i> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div id="discovery-info" class="tap-target" data-target="botao-info"> |
||||
|
<div class="tap-target-content"> |
||||
|
<h5>{% trans "Novidades!" %}</h5> |
||||
|
<p> |
||||
|
{% blocktranslate count counter=alertas.count|default:0 %} |
||||
|
Existe um aviso para você. Clique no botão para visualizar |
||||
|
{% plural %} |
||||
|
Existem {{ counter }} avisos para você. Clique no botão para visualizar |
||||
|
{% endblocktranslate %} |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div id="modal-info" class="modal"> |
||||
|
<div class="modal-content"> |
||||
|
<div class="carrossel"> |
||||
|
{% for alerta in alertas %} |
||||
|
<div id="{{ alerta.titulo|slugify }}" class="carrossel-item"> |
||||
|
<h5>{{ alerta.titulo }}</h5> |
||||
|
{{ alerta.mensagem|safe }} |
||||
|
</div> |
||||
|
{% endfor %} |
||||
|
{% if alertas.count > 1 %} |
||||
|
<div class="carrossel-controls"> |
||||
|
{% for alerta in alertas %} |
||||
|
<div class="carrossel-control" title="{{ alerta.titulo }}" href="#{{ alerta.titulo|slugify }}">{{ forloop.counter }}</div> |
||||
|
{% endfor %} |
||||
|
</div> |
||||
|
{% endif %} |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="modal-footer"> |
||||
|
<a href="#!" class="modal-close waves-effect btn-flat right">{% trans "Close" %}</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
<script> |
||||
|
$(document).ready(function () { |
||||
|
M.Modal.init($("#modal-info")); |
||||
|
var discovery = M.TapTarget.init($("#discovery-info")); |
||||
|
discovery[0].open(); |
||||
|
$(".carrossel-item").hide(); |
||||
|
$(".carrossel-item").first().fadeIn(); |
||||
|
$(".carrossel-control").first().addClass("active") |
||||
|
$(".carrossel-control").on("click", function() { |
||||
|
var $this = $(this); |
||||
|
$(".carrossel-control").removeClass("active"); |
||||
|
$this.addClass("active"); |
||||
|
$(".carrossel-item").hide(); |
||||
|
$($this.attr("href")).fadeIn(); |
||||
|
}) |
||||
|
}); |
||||
|
</script> |
Loading…
Reference in new issue