From 008ea4f6f2fca644417d3266792adc92f22af0c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ses=C3=B3stris=20Vieira?= Date: Mon, 11 Sep 2023 15:25:48 -0300 Subject: [PATCH] =?UTF-8?q?Melhorias=20no=20calend=C3=A1rio=20de=20eventos?= =?UTF-8?q?.=20Gertiq=20#160528?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sigi/apps/eventos/static/css/calendario.css | 32 +++++- .../eventos/templates/eventos/calendario.html | 102 ++++++++++------- .../templates/eventos/calendario_pdf.html | 80 ++++++++++++-- .../eventos/snippets/calendario_cal.html | 38 ++++--- .../eventos/snippets/calendario_lista.html | 10 +- sigi/apps/eventos/views.py | 104 ++++++++++++------ 6 files changed, 262 insertions(+), 104 deletions(-) diff --git a/sigi/apps/eventos/static/css/calendario.css b/sigi/apps/eventos/static/css/calendario.css index 6e39cde..8c644b2 100644 --- a/sigi/apps/eventos/static/css/calendario.css +++ b/sigi/apps/eventos/static/css/calendario.css @@ -2,14 +2,18 @@ display: block; } +.evento { + padding: 0 6px; +} + .data-evento { - font-size: 0.6em; + font-size: 0.9em; color: var(--body-quiet-color); display: block; } .tipo-evento { - font-size: 0.6em; + font-size: 0.9em; color: var(--body-quiet-color); display: block; margin-bottom: 8px; @@ -32,11 +36,27 @@ table { table-layout: fixed; } -table td, -table td * { - vertical-align: top; +tr { + border-bottom: none; +} + +tr td { + padding: 0px 10px; +} + +tr.linha-dias { + background: var(--darkened-bg); } + span.numero-dia { - font-size: 0.5em; + font-size: 1em; +} + +tr.linha-evento { + background: var(--body-bg); +} + +.calendar-wrapper { + width: 100%; } \ No newline at end of file diff --git a/sigi/apps/eventos/templates/eventos/calendario.html b/sigi/apps/eventos/templates/eventos/calendario.html index 229c80e..9be77f5 100644 --- a/sigi/apps/eventos/templates/eventos/calendario.html +++ b/sigi/apps/eventos/templates/eventos/calendario.html @@ -1,54 +1,79 @@ {% extends "admin/base_site.html" %} -{% load i18n %} -{% load static %} +{% load i18n static %} {% block extrastyle %} - {{ block.super }} - + {{ block.super }} + {% endblock %} {% block breadcrumbs %}{% endblock %} {% block coltype %}colMS{% endblock %} {% block content %} -
- - mode_edit - - +
+ + mode_edit + + +
+
+
+
+ {% for ano, lista in meses.items %} +
+ {% for mes, nome in lista.items %} + {{ nome }} + {% endfor %} +
+ {% endfor %} +
+
+ + +
-
- + {% for key, data in categorias.items %} +
+
- {% for ano, lista in meses.items %} -
- {% for mes, nome in lista.items %} - {{ nome }} - {% endfor %} + {% endfor %} +
+
+ {% for key, data in status.items %} +
+
- {% endfor %} + {% endfor %}
- {% if formato == "cal" %} - {% include "eventos/snippets/calendario_cal.html" %} - {% else %} - {% include "eventos/snippets/calendario_lista.html" %} - {% endif %} - {% include "eventos/snippets/calendario_modals.html" %} + + {% if formato == "cal" %} + {% include "eventos/snippets/calendario_cal.html" %} + {% else %} + {% include "eventos/snippets/calendario_lista.html" %} + {% endif %} + {% include "eventos/snippets/calendario_modals.html" %} {% endblock %} {% block footer %} @@ -58,6 +83,9 @@ M.Tabs.init($('.tabs'), {}); M.Modal.init($(".modal"), {}); M.FloatingActionButton.init($(".fixed-action-btn"), {hoverEnabled: false}); + $("input[name='categoria']").on("change", function() { + $("#form_flags").submit(); + }); }); {% endblock %} diff --git a/sigi/apps/eventos/templates/eventos/calendario_pdf.html b/sigi/apps/eventos/templates/eventos/calendario_pdf.html index f5847c9..552c110 100644 --- a/sigi/apps/eventos/templates/eventos/calendario_pdf.html +++ b/sigi/apps/eventos/templates/eventos/calendario_pdf.html @@ -9,13 +9,28 @@ } table { table-layout: fixed; -} + } + .calendar-table { + border-collapse: collapse; + border-spacing: 0; + border: 1px solid #d2d2d2; + } + .calendar-table td+td { + border-left: 1px solid #d2d2d2 !important; + } table td, table td * { vertical-align: top; } + .calendar-table tr:nth-child(even) { + background-color: white !important; + } + tr.linha-dias { + background: #d2d2d2; + border-top: 1px solid #d2d2d2; + } span.numero-dia { - font-size: 0.5em; + font-size: 1em; } .card { background-color: #fff; @@ -33,27 +48,70 @@ margin-bottom: -6px !important; } .data-evento { - font-size: 0.7em; + font-size: 1em; display: block; } .tipo-evento { - font-size: 0.7em; + font-size: 1em; color: var(--body-quiet-color); display: block; margin-bottom: 8px; } - .cyan.lighten-4 { background-color: #b2ebf2 !important; } + .evento { + margin: 0; + padding: 5px 10px; + } + .cyan.lighten-4 { background-color: #b2ebf2!important; } + .red.lighten-4 { background-color: #ffcdd2!important; } + .purple.lighten-4 { background-color: #e1bee7!important; } + .blue.lighten-4 { background-color: #bbdefb!important; } + .orange.lighten-4 { background-color: #ffe0b2!important; } .brown.lighten-4 { background-color: #d7ccc8 !important; } - .deep-orange.lighten-4 { background-color: #ffccbc !important; } - .cyan.lighten-4 { background-color: #b2ebf2 !important; } - .green.lighten-4 { background-color: #c8e6c9 !important; } - .lime.lighten-4 { background-color: #f0f4c3 !important; } + @font-face { + font-family: 'Material Icons'; + font-style: normal; + font-weight: 400; + src: url('/static/material/fonts/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2') format('woff2'); + } + i.tiny { font-size: 1rem; } + .material-icons { + font-family: "Material Icons"; + font-weight: 400; + font-style: normal; + font-size: 24px; + line-height: 1; + letter-spacing: normal; + text-transform: none; + display: inline-block; + white-space: nowrap; + word-wrap: normal; + direction: ltr; + -webkit-font-feature-settings: "liga"; + -webkit-font-smoothing: antialiased; + } {% endblock %} {% block main_content %} -

- {% blocktrans with month=mes_pesquisa|stringformat:"02d" year=ano_pesquisa|stringformat:"04d" %}Ref: {{ month }}/{{year}}{% endblocktrans %} +

+ {% blocktrans with month=mes_pesquisa|stringformat:"02d" year=ano_pesquisa|stringformat:"04d" %}Mês: {{ month }}/{{year}}{% endblocktrans %}

+ + + + {% for key, data in categorias.items %} + {% if key in sel_categorias %}{% endif %} + {% endfor %} + +
Categorias:{{ data.label }}
+ + + + {% for key, data in status.items %} + {% if key in sel_status %}{% endif %} + {% endfor %} + +
Status: {{ data.icon }} {{ data.label }}
+
{% include "eventos/snippets/calendario_cal.html" %} {% include "eventos/snippets/calendario_lista.html" %} {% endblock main_content %} \ No newline at end of file diff --git a/sigi/apps/eventos/templates/eventos/snippets/calendario_cal.html b/sigi/apps/eventos/templates/eventos/snippets/calendario_cal.html index e5db603..df0ce1a 100644 --- a/sigi/apps/eventos/templates/eventos/snippets/calendario_cal.html +++ b/sigi/apps/eventos/templates/eventos/snippets/calendario_cal.html @@ -1,8 +1,7 @@ -{% load i18n %} -{% load static %} +{% load i18n static dict_get %} -
- +
+
{% for name in day_names %} @@ -10,18 +9,29 @@ {% for semana in semanas %} - - {% for dia in semana %} - + {% for dia in semana.datas %} + {% endfor %} - + + {% for evento, tupla in semana.eventos %} + + {% for x in ""|ljust:tupla.0|make_list %}{% endfor %} + + {% for x in ""|ljust:tupla.2|make_list %}{% endfor %} + + {% empty %} + {% endfor %} - {% endfor %}
{{ name }}
- {{ dia.0 }} - {% for evento in dia.1 %} -

- {{ evento.nome }} -

+
+ + {% if dia.month == mes_pesquisa %}{{ dia.day }}{% endif %} + +
+

+ {{ status|get:evento.status|get:"icon" }} + {{ evento.nome }} +

+
 
diff --git a/sigi/apps/eventos/templates/eventos/snippets/calendario_lista.html b/sigi/apps/eventos/templates/eventos/snippets/calendario_lista.html index e9354bd..8785369 100644 --- a/sigi/apps/eventos/templates/eventos/snippets/calendario_lista.html +++ b/sigi/apps/eventos/templates/eventos/snippets/calendario_lista.html @@ -1,12 +1,14 @@ -{% load i18n %} -{% load static %} +{% load i18n static dict_get %} {% for evento in eventos %}
-
+
- {{ evento.nome }} + + {{ status|get:evento.status|get:"icon" }} + {{ evento.nome }} + {{ evento.data_inicio }} a {{ evento.data_termino }} {{ evento.tipo_evento }} - diff --git a/sigi/apps/eventos/views.py b/sigi/apps/eventos/views.py index 12dccf6..e7dce1e 100644 --- a/sigi/apps/eventos/views.py +++ b/sigi/apps/eventos/views.py @@ -27,7 +27,7 @@ from django_weasyprint.views import WeasyTemplateResponse from weasyprint import HTML from sigi.apps.casas.models import Funcionario, Orgao from sigi.apps.convenios.models import Projeto -from sigi.apps.eventos.models import Evento, Convite, Anexo +from sigi.apps.eventos.models import TipoEvento, Evento from sigi.apps.eventos.forms import ( SelecionaModeloForm, ConviteForm, @@ -44,6 +44,12 @@ from sigi.apps.servidores.models import Servidor def calendario(request): mes_pesquisa = int(request.GET.get("mes", timezone.localdate().month)) ano_pesquisa = int(request.GET.get("ano", timezone.localdate().year)) + sel_categorias = request.GET.getlist( + "categoria", [c[0] for c in TipoEvento.CATEGORIA_CHOICES] + ) + sel_status = request.GET.getlist( + "status", [s[0] for s in Evento.STATUS_CHOICES] + ) formato = request.GET.get("fmt", "cal") pdf = bool(request.GET.get("pdf", 0)) @@ -66,49 +72,83 @@ def calendario(request): Evento.objects.exclude(data_inicio=None) .exclude(data_termino=None) .filter( - data_inicio__year=ano_pesquisa, data_inicio__month=mes_pesquisa + data_inicio__year=ano_pesquisa, + data_inicio__month=mes_pesquisa, + status__in=sel_status, + tipo_evento__categoria__in=sel_categorias, ) + .order_by("data_inicio") ) - context = {} + context = { + "ano_pesquisa": ano_pesquisa, + "mes_pesquisa": mes_pesquisa, + "formato": formato, + "sel_categorias": sel_categorias, + "categorias": dict( + map( + lambda x, y: (x[0], {"label": x[1], "color": y}), + TipoEvento.CATEGORIA_CHOICES, + ["red", "purple", "blue", "orange", "brown"], + ) + ), + "sel_status": sel_status, + "status": dict( + map( + lambda x, y: (x[0], {"label": x[1], "icon": y}), + Evento.STATUS_CHOICES, + [ + "assignment", + "hourglass_empty", + "access_time", + "thumbs_up_down", + "thumb_up", + "done_all", + "mood_bad", + "archive", + ], + ) + ), + "meses": meses, + "day_names": calendar.day_abbr, + "eventos": eventos, + } if formato == "cal" or pdf: - semanas = calendar.Calendar().monthdatescalendar( - ano_pesquisa, mes_pesquisa - ) - for semana in semanas: - for dia in semana: - if dia.month == mes_pesquisa: - semana[dia.weekday()] = ( - dia.day, - [ - e - for e in eventos - if e.data_inicio.day - <= dia.day - <= e.data_termino.day - ], + semanas = [ + {"datas": s, "eventos": []} + for s in calendar.Calendar().monthdatescalendar( + ano_pesquisa, mes_pesquisa + ) + ] + + for e in eventos: + for s in semanas: + if not ( + (e.data_termino.date() < s["datas"][0]) + or (e.data_inicio.date() > s["datas"][-1]) + ): + start = max(s["datas"][0], e.data_inicio.date()) + end = min(s["datas"][-1], e.data_termino.date()) + s["eventos"].append( + ( + e, + ( + start.weekday(), + end.weekday() - start.weekday() + 1, + 6 - end.weekday(), + ), + ) ) - else: - semana[dia.weekday()] = ("", []) - context["semanas"] = semanas - context.update( - { - "ano_pesquisa": ano_pesquisa, - "mes_pesquisa": mes_pesquisa, - "formato": formato, - "meses": meses, - "day_names": calendar.day_abbr, - "eventos": eventos, - } - ) + context["semanas"] = semanas if pdf: context["title"] = _("Calendário de eventos") context["pdf"] = True + # return render(request, "eventos/calendario_pdf.html", context) return WeasyTemplateResponse( - filename="calendario_mensal.pdf", + filename=f"calendario_{ano_pesquisa:04}{mes_pesquisa:02}.pdf", request=request, template="eventos/calendario_pdf.html", context=context,