diff --git a/app/static/estilo.css b/app/static/estilo.css index 9efd0dd..e858973 100644 --- a/app/static/estilo.css +++ b/app/static/estilo.css @@ -252,6 +252,25 @@ a.botao:hover { border-color: var(--cor-acento); color: var(--cor-acento); } .status-dot-ativo { background: var(--cor-sucesso); } .status-dot-inativo { background: var(--cor-perigo); } +.secao-log { margin-bottom: 20px; } +.secao-log summary { + display: flex; align-items: center; gap: 10px; cursor: pointer; + list-style: none; padding: 10px 0; user-select: none; +} +.secao-log summary::-webkit-details-marker { display: none; } +.secao-log summary::before { + content: "▸"; display: inline-block; color: var(--cor-texto-secundario); + transition: transform 0.15s ease; +} +.secao-log[open] summary::before { transform: rotate(90deg); } +.secao-log-titulo { font-size: 1.17em; font-weight: 700; } +.botao-toggle-log { + margin-top: 0; padding: 6px 12px; font-size: 0.85rem; font-weight: 400; + background: transparent; border: 1px solid var(--cor-borda); color: var(--cor-texto); +} +.botao-toggle-log:hover { border-color: var(--cor-acento); color: var(--cor-acento); } +.secao-log-conteudo { padding-top: 4px; } + @media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; } } diff --git a/app/templates/log.html b/app/templates/log.html index 19ecac0..379f0c3 100644 --- a/app/templates/log.html +++ b/app/templates/log.html @@ -4,63 +4,90 @@ {% block conteudo %}

Log

-

Ações no painel

- {% if eh_admin %} -
- - -
- {% endif %} - {% if acoes %} -
- - - {% for a in acoes %} - - - - - - - - - {% endfor %} -
QuandoUsuárioAçãoEntidadeStatusDetalhe
{{ a.CRIADO_EM }}{{ a.USUARIO }}{{ a.ACAO }}{{ a.ENTIDADE }}{% if a.ENTIDADE_ID %} #{{ a.ENTIDADE_ID }}{% endif %}{{ "OK" if a.SUCESSO else "ERRO" }}{{ a.DETALHE or "" }}
+
+ + Ações no painel + + +
+ {% if eh_admin %} +
+ + +
+ {% endif %} + {% if acoes %} +
+ + + {% for a in acoes %} + + + + + + + + + {% endfor %} +
QuandoUsuárioAçãoEntidadeStatusDetalhe
{{ a.CRIADO_EM }}{{ a.USUARIO }}{{ a.ACAO }}{{ a.ENTIDADE }}{% if a.ENTIDADE_ID %} #{{ a.ENTIDADE_ID }}{% endif %}{{ "OK" if a.SUCESSO else "ERRO" }}{{ a.DETALHE or "" }}
+
+ {% else %} +

Nenhuma ação registrada ainda.

+ {% endif %}
- {% else %} -

Nenhuma ação registrada ainda.

- {% endif %} +
-

Envios automáticos de chave (n8n)

- {% if not envios_configurado %} -
-

- Integração com o n8n não configurada — defina N8N_API_URL e - N8N_API_KEY no ambiente (ver .env.example) para ver - aqui os envios automáticos de chave feitos pelo workflow do n8n. -

+
+ + Envios automáticos de chave (n8n) + + +
+ {% if not envios_configurado %} +
+

+ Integração com o n8n não configurada — defina N8N_API_URL e + N8N_API_KEY no ambiente (ver .env.example) para ver + aqui os envios automáticos de chave feitos pelo workflow do n8n. +

+
+ {% elif not envios %} +

Nenhum envio encontrado (ou não foi possível consultar o n8n agora).

+ {% else %} +
+ + + + + + {% for e in envios %} + + + + + + + + + + {% endfor %} +
DataClienteCódigoCompetênciaStatusTelefones enviadosTelefones com erro
{{ e.data_processamento }}{{ e.nome_cliente }}{{ e.codigo_cliente }}{{ e.competencia }}{{ e.status }}{{ e.telefones_enviados }}{{ e.telefones_com_erro or "" }}
+
+ {% endif %}
- {% elif not envios %} -

Nenhum envio encontrado (ou não foi possível consultar o n8n agora).

- {% else %} -
- - - - - - {% for e in envios %} - - - - - - - - - - {% endfor %} -
DataClienteCódigoCompetênciaStatusTelefones enviadosTelefones com erro
{{ e.data_processamento }}{{ e.nome_cliente }}{{ e.codigo_cliente }}{{ e.competencia }}{{ e.status }}{{ e.telefones_enviados }}{{ e.telefones_com_erro or "" }}
-
- {% endif %} +
+ + {% endblock %} diff --git a/tests/test_router_log.py b/tests/test_router_log.py index 5a1020e..0b8d101 100644 --- a/tests/test_router_log.py +++ b/tests/test_router_log.py @@ -105,3 +105,16 @@ def test_limpar_log_usuario_padrao_toma_403(): app_teste.dependency_overrides[exigir_login] = lambda: UsuarioLogado(login="fulano", nome="Fulano", perfil="PADRAO") resposta = client.post("/log/limpar", data={"csrf_token": CSRF_TESTE}) assert resposta.status_code == 403 + + +def test_pagina_log_secoes_comecam_fechadas(monkeypatch): + monkeypatch.setattr(router_log.db_log, "listar", lambda limite=20: []) + monkeypatch.setattr(router_log.n8n_client, "listar_envios", lambda limite=50: []) + monkeypatch.setattr(router_log.n8n_client, "configurado", lambda: False) + + resposta = client.get("/log") + assert resposta.status_code == 200 + texto = resposta.text + assert texto.count('
') == 2 + assert "
" not in texto + assert "
" not in texto