Browse Source

Paineis de ocorrências para bootstrap

sigi-4.0
Sesóstris Vieira 4 weeks ago
parent
commit
4ac5916287
  1. 56
      sigi/apps/ocorrencias/static/ocorrencias/css/painel_ocorrencias.css
  2. 102
      sigi/apps/ocorrencias/templates/ocorrencias/painel.html
  3. 169
      sigi/apps/ocorrencias/templates/ocorrencias/painel_snippet.html
  4. 33
      sigi/apps/ocorrencias/views.py

56
sigi/apps/ocorrencias/static/ocorrencias/css/painel_ocorrencias.css

@ -1,14 +1,11 @@
#content {
display: block;
}
.user-image {
width: 64px;
height: 64px;
font-size: 64px !important;
display: block;
}
commenter-image {
.user-image-sm {
width: 32px;
height: 32px;
font-size: 32px !important;
@ -17,53 +14,4 @@ commenter-image {
.card-details,
.user-name {
font-size: 10px;
}
.priority {
background-color: grey;
}
.priority {
background-color: antiquewhite;
margin-left: 5px;
min-width: 60px;
}
.chip>img {
float: left;
margin: 0 8px 0 -12px;
height: 32px;
width: 32px;
border-radius: 50%;
}
.span-list {
padding: 2px 6px;
margin-left: 4px;
background-color: var(--selected-bg);
line-height: 24px;
border-radius: 12px;
white-space: nowrap;
}
.card-inbox {
width: 100%;
border: 1px solid var(--hairline-color);
padding: 12px;
border-radius: 12px;
}
.card-inbox p {
margin-bottom: 6px !important;
}
.inbox-title {
font-weight: bold;
text-transform: uppercase;
font-size: smaller;
}
.strong {
font-weight: 800;
text-transform: uppercase;
}

102
sigi/apps/ocorrencias/templates/ocorrencias/painel.html

@ -0,0 +1,102 @@
{% extends "admin/base_site.html" %}
{% load i18n static admin_urls djbs_extras %}
{% block extrastyle %}
{{ block.super }}
<link rel="stylesheet" href="{% static 'ocorrencias/css/painel_ocorrencias.css' %}">
{% endblock %}
{% block content_title %}
<h3>{{ panel_title }}</h3>
{% endblock content_title %}
{% block content_subtitle %}
{% if panel_subtitles %}
<div class="card border-light m-4">
<div class="card-body">
<h6 class="card-title">{% trans "Filtros aplicados:" %}</h6>
<div class="d-md-flex gap-2">
{% for subt in panel_subtitles %}
<span class="badge text-bg-info">{{ subt }}</span>
{% endfor %}
</div>
</div>
</div>
{% endif %}
{% endblock %}
{% block search %}
<form class="d-flex gap-2 ms-2" role="search" action="">
{% for field in filter.form %}
{% if field != filter.form.nome_casa %}
{{ field.as_hidden }}
{% endif %}
{% endfor %}
{% icon "search" "d-none d-lg-inline-block navbar-text" %}
{{ filter.form.nome_casa }}
<button class="btn btn-outline-secondary" type="submit">
<span class="d-none d-lg-inline-block">{% translate "Search" %}</span>
{% icon "search" "d-inline-block d-lg-none" %}
</button>
</form>
{% endblock %}
{% block object-tools %}
{% if has_add_permission %}
<a class="addlink nav-link" href="{% url 'admin:ocorrencias_ocorrencia_add' %}" aria-labelledby="text-tool-add" title="{% translate "Nova Ocorrência" %}">
{% icon 'add' %} <span id="text-tool-add" class="d-lg-none">{% translate "Nova Ocorrência" %}</span>
</a>
{% endif %}
{% endblock %}
{% block breadcrumbs %}
<li class="breadcrumb-item"><a href="{% url 'admin:app_list' app_label="ocorrencias" %}">{% translate "Ocorrências" %}</a></li>
<li class="breadcrumb-item active" aria-current="page">{% translate "Painel" %}</li>
{% endblock %}
{% block content %}
{% block ocorrencia_cards %}
{% for ocorrencia in ocorrencias %}
{% include 'ocorrencias/painel_snippet.html' %}
{% endfor %}
{% endblock ocorrencia_cards %}
{% block paginator %}
{% if is_paginated %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li class="waves-effect"><a href="?{{ filter.preserve_filter }}&page={{ page_obj.previous_page_number }}"><i class="material-icons">chevron_left</i></a></li>
{% else %}
<li class="disabled"><a href="?{{ filter.preserve_filter }}"><i class="material-icons">chevron_left</i></a></li>
{% endif %}
{% for page_number in page_obj.paginator.page_range %}
<li class=" {% if page_number == page_obj.number %}active{% else %}waves-effect{% endif %}"><a href="?{{ filter.preserve_filter }}&page={{ page_number }}">{{ page_number }}</a></li>
{% endfor %}
{% if page_obj.has_next %}
<li class="waves-effect"><a href="?{{ filter.preserve_filter }}&page={{ page_obj.next_page_number }}"><i class="material-icons">chevron_right</i></a></li>
{% else %}
<li class="disabled"><a href="?{{ filter.preserve_filter }}"><i class="material-icons">chevron_right</i></a></li>
{% endif %}
</ul>
{% endif %}
{% endblock paginator %}
{% endblock %}
{% block sidebar-title %}{% translate 'Filter' %}{% endblock sidebar-title %}
{% block sidebar-body %}
<div id="panel-filter">
<div id="changelist-filter-extra-actions" class="nav bg-body-tertiary shadow-sm mb-3">
<a href="?" class="nav-link">{% icon "dismiss" %} {% trans "Clear all filters" %}</a>
</div>
<form id="filter-form" method="get">
{{ filter.form }}
<button id="apply-filters" type="submit" class="btn btn-outline-secondary">{% translate 'Filter' %}</button>
</form>
</div>
{% endblock %}
{% block footer %}
{{ block.super }}
<script type="text/javascript" src="{% static 'ocorrencias/js/painel_ocorrencias.js' %}"></script>
{% endblock %}

169
sigi/apps/ocorrencias/templates/ocorrencias/painel_snippet.html

@ -0,0 +1,169 @@
{% load i18n djbs_extras %}
<div id="ocorrencia-{{ ocorrencia.id|safe }}" class="card mb-2">
<div class="card-header">
{% block edit_link %}
{% if user.is_staff %}
{% if has_change_permission %}
<a href="{% url "admin:ocorrencias_ocorrencia_change" ocorrencia.id %}" title="{% translate "Editar" %}">{% icon "edit" %}</a>
{% endif %}
{{ ocorrencia.casa_legislativa.nome }}, {{ ocorrencia.casa_legislativa.municipio.uf.sigla }}
{% else %}
{{ ocorrencia.assunto }}
{% endif %}
{% endblock edit_link %}
<p class="card-details">
{% blocktrans with data_criacao=ocorrencia.data_criacao|date:"SHORT_DATE_FORMAT" tipo_contato=ocorrencia.tipo_contato categoria=ocorrencia.categoria status=ocorrencia.get_status_display prioridade=ocorrencia.get_prioridade_display %}
Criado em {{ data_criacao }} via {{ tipo_contato }} solicitando {{ categoria }}, com status {{ status }}. Prioridade: {{ prioridade }}
{% endblocktrans %}
</p>
</div>
<div class="card-body">
<div class="d-flex align-items-center gap-2 mb-2">
<div class="text-center text-wrap">
{% if ocorrencia.servidor_registro.foto %}
<img class="rounded-circle user-image" src="{{ MEDIA_URL }}{{ ocorrencia.servidor_registro.foto }}"/>
{% else %}
{% icon "user" "user-image" %}
{% endif %}
<span class="user-name">{{ ocorrencia.servidor_registro.get_apelido }}</span>
</div>
<p class="flex-grow-1">{{ ocorrencia.descricao }}</p>
</div>
{% block card-adesao %}
{% if 'solicita_convenio' in ocorrencia.infos %}
<div class="mb-2">
<div class="d-flex align-items-center">
<h6 class="card-title text-uppercase me-auto">{% trans "Solicitação de convênio" %}</h6>
{% if user.is_staff %}
<a class="btn btn-outline-primary btn-sm" href="{% url 'ocorrencias_painel_convenio' ocorrencia.id %}{% if filter.preserve_filter %}?list_filter={{ filter.preserve_filter|urlencode }}{% endif %}" role="button">{% icon "config" %} Gerenciar</a>
{% endif %}
</div>
<div class="d-md-flex gap-2">
<span class="ms-4 fs-6 fw-bold">{% translate "Etapas:" %}</span>
{% for key, value in ocorrencia.get_infos_details.items %}
<span class="badge text-bg-light">
{% if value.0 %}{% icon "check" "text-success" %}{% else %}{% icon "dismiss" "text-danger" %}{% endif %}
{{ value.1 }}
</span>
{% endfor %}
</div>
</div>
{% endif %}
{% endblock card-adesao %}
{% block card-oficina %}
{% if 'solicita_oficinas' in ocorrencia.infos %}
<div class="mb-2">
<div class="d-flex align-items-center">
<h6 class="card-title text-uppercase me-auto">{% trans "Solicitação de oficinas" %}</h6>
{% if user.is_staff %}
<a class="btn btn-outline-primary btn-sm" href="{% url 'ocorrencias_painel_oficina' ocorrencia.id %}{% if filter.preserve_filter %}?list_filter={{ filter.preserve_filter|urlencode }}{% endif %}" role="button">{% icon "config" %} Gerenciar</a>
{% endif %}
</div>
<div class="table-responsive">
<table class="table table-sm">
<tr>
<th>{% trans "Oficinas solicitadas:" %}</th>
<td>
{% for oficina in ocorrencia.get_infos_oficinas %}
<span class="badge text-bg-secondary">{{ oficina.nome }}</span>
{% endfor %}
</td>
</tr>
<tr>
<th>{% trans "Oficinas autorizadas:" %}</th>
<td>
{% for oficina in ocorrencia.evento_set.all %}
<span class="badge text-bg-secondary">{{ oficina }}</span>
{% empty %}
<span class="badge text-bg-secondary">{% trans "Nenhuma" %}</span>
{% endfor %}
</td>
</tr>
<tr>
<th>{% trans "Senadores selecionados:" %}</th>
<td>
{% for senador in ocorrencia.get_infos_senadores %}
<span class="badge text-bg-secondary">{{ senador.nome_completo }} ({{ senador.partido.sigla }})</span>
{% endfor %}
</td>
</tr>
</table>
</div>
</div>
{% endif %}
{% endblock card-oficina %}
{% block card-anexos %}
<div class="mb-2">
<h6 class="card-title text-uppercase">{% trans "Anexos" %}</h6>
<div class="table-responsive">
<table class="table table-sm table-striped">
<thead>
<tr>
<th>{% trans "Data de publicação" %}</th>
<th>{% trans "Descrição" %}</th>
<th>{% trans "Arquivo" %}</th>
</tr>
</thead>
<tbody class="table-group-divider">
{% for anexo in ocorrencia.anexo_set.all %}
<tr>
<td>{{ anexo.data_pub|date:"SHORT_DATE_FORMAT" }}</td>
<td>{{ anexo.descricao }}</td>
<td><a href="{{ anexo.arquivo.url }}" download>{% icon anexo.arquivo.name|filesuffix|default:"upload" %} {{ anexo.arquivo.name|filename }}</a></td>
</tr>
{% empty %}
<tr><td colspan="3">{% trans "Nenhum anexo" %}</td></tr>
{% endfor %}
</tbody>
</table>
</div>
{% if anexo_form %}
<form action="" method="post" enctype="multipart/form-data">{% csrf_token %}
<button class="btn btn-outline-primary btn-sm" type="submit" name="anexo_save">{% icon "save" %} {% translate "Submit" %}</button>
{{ anexo_form }}
<input type="hidden" name="ocorrencia_id" value="{{ ocorrencia.id|safe }}"/>
</form>
{% endif %}
</div>
{% endblock card-anexos %}
{% block card-comentarios %}
<div class="mb-2">
<h6 class="card-title text-uppercase">{% trans "Comentários" %}</h6>
<ul class="list-group list-group-flush">
{% for comentario in ocorrencia.comentarios.all %}
{% if user.is_staff or comentario.interno == False %}
<li class="list-group-item">
{% if comentario.usuario.foto %}
<img class="rounded-circle user-image-sm" src="{{ comentario.usuario.foto.url }}"/>
{% else %}
{% icon "user" %}
{% endif %}
{% blocktranslate with data=comentario.data_criacao nome=comentario.usuario.get_apelido %}Em {{ data }}, {{ nome }} disse:{% endblocktranslate %}
<span class="title">{{ comentario.descricao }}</span>
{% if comentario.novo_status %}
{% blocktranslate with status=comentario.get_novo_status_display|default:"-" %}Status: {{ status }}{% endblocktranslate %}
{% endif %}
</li>
{% endif %}
{% empty %}
<li class="list-group-item">{% trans "Nenhum comentário" %}</li>
{% endfor %}
{% if comentario_form %}
<li class="list-group-item">
<form action="" method="post">{% csrf_token %}
<button type="submit" name="comentario_save" class="btn btn-outline-primary btn-sm">{% icon "save" %}{% translate "Submit" %}</button>
{{ comentario_form }}
<input type="hidden" name="ocorrencia_id" value="{{ ocorrencia.id|safe }}"/>
</form>
</li>
{% endif %}
</ul>
</div>
{% endblock card-comentarios %}
</div>
</div>

33
sigi/apps/ocorrencias/views.py

@ -56,6 +56,7 @@ class PainelOcorrenciaFilter(django_filters.FilterSet):
label=_("Nome da casa contém"),
field_name="casa_legislativa__search_text",
lookup_expr=_("icontains"),
method="nome_casa_filter",
)
gerente = django_filters.ModelChoiceFilter(
label=_("Casas gerenciadas por"),
@ -92,6 +93,10 @@ class PainelOcorrenciaFilter(django_filters.FilterSet):
"categoria",
]
def nome_casa_filter(self, queryset, name, value):
value = to_ascii(value).lower()
return queryset.filter(**{f"{name}__icontains": value})
def servidor_filter(self, queryset, name, value):
return queryset.filter(
Q(servidor_registro=value) | Q(comentarios__usuario=value)
@ -311,9 +316,11 @@ class OficinaChangeView(BaseOcorrenciaChangeView):
f"{tipo_evento.nome} na {ocorrencia.casa_legislativa.nome}, oriunda da Ocorrência #{ocorrencia.id}"
),
virtual=dados["virtual"],
solicitante=ocorrencia.casa_legislativa.presidente.nome_completo
if ocorrencia.casa_legislativa.presidente
else "",
solicitante=(
ocorrencia.casa_legislativa.presidente.nome_completo
if ocorrencia.casa_legislativa.presidente
else ""
),
num_processo=ocorrencia.processo_sigad,
data_pedido=ocorrencia.data_criacao,
solicitacao=ocorrencia,
@ -602,13 +609,19 @@ class SolicitaConvenioCreateView(ContatoInterlegisViewMixin, UpdateView):
self.tab = (
"casa"
if "casa_legislativa" not in self.infos
else "presidente"
if "presidente" not in self.infos
else "contato"
if "contato" not in self.infos
else "documentos"
if "documento" in self.infos
else "resumo"
else (
"presidente"
if "presidente" not in self.infos
else (
"contato"
if "contato" not in self.infos
else (
"documentos"
if "documento" in self.infos
else "resumo"
)
)
)
)
else:
return self.cria_solicitacao(request, *args, **kwargs)

Loading…
Cancel
Save