diff --git a/app/static/estilo.css b/app/static/estilo.css index 7929402..6fa014b 100644 --- a/app/static/estilo.css +++ b/app/static/estilo.css @@ -235,6 +235,12 @@ a.botao:hover { border-color: var(--cor-acento); color: var(--cor-acento); } } .paginacao { display: flex; align-items: center; gap: 12px; justify-content: center; margin-top: 16px; } +.paginacao-rodape { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px; margin-top: 16px; } +.paginacao-rodape .paginacao { margin-top: 0; } +.paginacao-por-pagina { display: flex; align-items: center; gap: 8px; } +.paginacao-por-pagina label { margin: 0; white-space: nowrap; } +.paginacao-atual { display: inline-flex; align-items: center; justify-content: center; min-width: 32px; height: 32px; padding: 0 6px; border-radius: 6px; background: var(--cor-acento); color: var(--cor-acento-texto); font-weight: 600; } +.paginacao-reticencias { padding: 0 4px; color: var(--cor-texto-secundario); } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; } diff --git a/app/templates/clientes_lista.html b/app/templates/clientes_lista.html index 2f9eddd..d7e9b98 100644 --- a/app/templates/clientes_lista.html +++ b/app/templates/clientes_lista.html @@ -17,6 +17,8 @@

+ Novo cliente

+ {% set busca_qs = ('&busca=' + (busca | urlencode)) if busca else '' %} + {% set qs_base = ('&ordenar_por=' + ordenar_por + '&direcao=' + direcao + '&por_pagina=' + (por_pagina | string) + busca_qs) | safe %}
@@ -24,7 +26,7 @@ {% for campo, rotulo in colunas_tabela %} {% set nova_direcao = "desc" if (ordenar_por == campo and direcao == "asc") else "asc" %} @@ -42,15 +44,40 @@ {% endfor %}
- + {{ rotulo }}{% if ordenar_por == campo %}{{ " ▲" if direcao == "asc" else " ▼" }}{% endif %}
- {% if total_paginas and total_paginas > 1 %} -
- {% if pagina > 1 %} - ← Anterior - {% endif %} - Página {{ pagina }} de {{ total_paginas }} ({{ total }} clientes) - {% if pagina < total_paginas %} - Próxima → - {% endif %} -
- {% endif %} +
+
+ + + + {% if busca %}{% endif %} + + +
+ Exibindo {{ primeiro_item }} a {{ ultimo_item }} de {{ total }} clientes + {% if total_paginas and total_paginas > 1 %} +
+ {% if pagina > 1 %} + « + ‹ + {% endif %} + {% for p in janela_paginas %} + {% if p is none %} + … + {% elif p == pagina %} + {{ p }} + {% else %} + {{ p }} + {% endif %} + {% endfor %} + {% if pagina < total_paginas %} + › + » + {% endif %} +
+ {% endif %} +
{% endblock %} diff --git a/tests/test_router_clientes.py b/tests/test_router_clientes.py index 831bb5c..8777d3f 100644 --- a/tests/test_router_clientes.py +++ b/tests/test_router_clientes.py @@ -186,10 +186,38 @@ def test_listar_clientes_pagina_com_controles_de_paginacao(monkeypatch): resposta = client.get("/clientes?pagina=2&por_pagina=100") assert resposta.status_code == 200 - assert "Página 2 de 3" in resposta.text - assert "250 clientes" in resposta.text - assert "Anterior" in resposta.text - assert "Próxima" in resposta.text + assert "Exibindo 101 a 200 de 250 clientes" in resposta.text + assert "pagina=1&ordenar_por=razao&direcao=asc&por_pagina=100" in resposta.text + assert "pagina=3&ordenar_por=razao&direcao=asc&por_pagina=100" in resposta.text + + +def test_listar_clientes_footer_com_selecao_de_por_pagina(monkeypatch): + monkeypatch.setattr( + router_clientes.db_clientes, + "listar_clientes", + lambda busca=None, limite=100, offset=0, ordenar_por="razao", direcao="asc": [ + {"ID": i, "CODIGO": f"{i:06d}", "RAZAO": f"Cliente {i}", "FANTASIA": f"C{i}", "CNPJ": "1"} + for i in range(1, 16) + ], + ) + monkeypatch.setattr(router_clientes.db_clientes, "contar_clientes", lambda busca=None, ordenar_por="razao": 98) + + resposta = client.get("/clientes?pagina=1") + assert resposta.status_code == 200 + assert 'value="15" selected' in resposta.text + assert "Exibindo 1 a 15 de 98 clientes" in resposta.text + # 98 / 15 = 7 paginas -> <=7, sem reticencias, todas visiveis + assert "pagina=7&ordenar_por=razao&direcao=asc&por_pagina=15" in resposta.text + + +def test_listar_clientes_paginacao_com_reticencias_quando_muitas_paginas(monkeypatch): + monkeypatch.setattr(router_clientes.db_clientes, "listar_clientes", lambda **kwargs: []) + monkeypatch.setattr(router_clientes.db_clientes, "contar_clientes", lambda busca=None, ordenar_por="razao": 500) + + # 500 / 5 = 100 paginas, pedindo a pagina 10 (no meio) -> tem reticencias + resposta = client.get("/clientes?pagina=10&por_pagina=5") + assert resposta.status_code == 200 + assert "…" in resposta.text def test_listar_clientes_ordenar_por_invalido_cai_no_padrao(monkeypatch):