# Tabela de Clientes UI/UX Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Ajustar largura de colunas, alinhamento/centralização e densidade das linhas da tabela em `/clientes`, igual para os dois perfis de usuário, sem alterar comportamento, dados ou permissões. **Architecture:** Adicionar uma classe `table-clientes` só nessa tabela (escopando o CSS pra não afetar outras telas), colunas com largura e alinhamento fixos via CSS (`nth-child` ou classes por coluna), padding vertical reduzido, e uma classe de botão mais compacta pras ações da linha. **Tech Stack:** Jinja2 (`app/templates/clientes_lista.html`), CSS puro (`app/static/estilo.css`), pytest + `fastapi.testclient.TestClient` (`tests/test_router_clientes.py`). ## Global Constraints - Nenhuma mudança de permissão/visibilidade por perfil (admin vs. padrão) nesta tela — confirmado explicitamente fora de escopo. - Nenhuma mudança em dados exibidos, busca, filtro de status, ordenação, paginação, no toggle de status ou no botão "Gerar chave" — só a apresentação visual muda. - Os ajustes de CSS ficam restritos à classe `table-clientes` — não alterar as regras genéricas `table`/`th`/`td` (usadas por `/funcionarios`, `/log`, etc.). - Larguras/alinhamento por coluna (da spec): Código centralizado/estreito, Razão e Fantasia flexíveis à esquerda (dividindo o espaço igualmente), CNPJ centralizado/fixo sem quebrar linha, Status centralizado/estreito, Ações à direita. --- ### Task 1: Classe de escopo, larguras/alinhamento e densidade **Files:** - Modify: `app/templates/clientes_lista.html` - Modify: `app/static/estilo.css` - Test: `tests/test_router_clientes.py` **Interfaces:** - Consumes: contexto já passado pela rota `GET /clientes` em `app/routers/clientes.py` (`clientes`, `ordenar_por`, `direcao`, `status`, `busca`, `csrf_token`, `redirecionar_para`, paginação) — nenhuma mudança nesse router nesta tarefa. - Produces: nada consumido por outras tasks (task única). - [ ] **Step 1: Escrever o teste que falha** Adicionar ao final de `tests/test_router_clientes.py`: ```python def test_listar_clientes_tabela_tem_classe_de_escopo(): resposta = client.get("/clientes") assert resposta.status_code == 200 assert '' in resposta.text ``` - [ ] **Step 2: Rodar o teste para confirmar que falha** Run: `pytest tests/test_router_clientes.py::test_listar_clientes_tabela_tem_classe_de_escopo -v` Expected: FAIL — a tabela hoje é `
` sem classe. - [ ] **Step 3: Editar `app/templates/clientes_lista.html`** No bloco da tabela (linhas atuais 28-71), aplicar a classe `table-clientes` na tag `
` e alinhar os `
`/`` com classes de coluna. Substituir o trecho: ```html
{% set colunas_tabela = [("codigo", "Código"), ("razao", "Razão"), ("fantasia", "Fantasia"), ("cnpj", "CNPJ")] %} {% for campo, rotulo in colunas_tabela %} {% set nova_direcao = "desc" if (ordenar_por == campo and direcao == "asc") else "asc" %} {% endfor %} {% for c in clientes %} {% endfor %}
{{ rotulo }}{% if ordenar_por == campo %}{{ " ▲" if direcao == "asc" else " ▼" }}{% endif %} Status
{{ c.CODIGO }} {{ c.RAZAO }} {{ c.FANTASIA }} {{ c.CNPJ }}
Abrir
``` por: ```html
{% set colunas_tabela = [("codigo", "Código", "col-codigo"), ("razao", "Razão", "col-razao"), ("fantasia", "Fantasia", "col-fantasia"), ("cnpj", "CNPJ", "col-cnpj")] %} {% for campo, rotulo, classe_coluna in colunas_tabela %} {% set nova_direcao = "desc" if (ordenar_por == campo and direcao == "asc") else "asc" %} {% endfor %} {% for c in clientes %} {% endfor %}
{{ rotulo }}{% if ordenar_por == campo %}{{ " ▲" if direcao == "asc" else " ▼" }}{% endif %} Status
{{ c.CODIGO }} {{ c.RAZAO }} {{ c.FANTASIA }} {{ c.CNPJ }}
Abrir
``` Notas: - `colunas_tabela` ganhou um terceiro elemento (a classe da coluna) — o `{% for %}` foi ajustado para desempacotar os 3 valores. - `botao-tabela` foi adicionado junto de `botao` nos dois botões de ação (não substitui `botao`, soma-se a ele — `botao-gerar-chave` continua presente também). - [ ] **Step 4: Adicionar CSS em `app/static/estilo.css`** Adicionar ao final do arquivo: ```css .table-clientes th.col-codigo, .table-clientes td.col-codigo, .table-clientes th.col-cnpj, .table-clientes td.col-cnpj, .table-clientes th.col-status, .table-clientes td.col-status { text-align: center; } .table-clientes th.col-acoes, .table-clientes td.col-acoes { text-align: right; } .table-clientes td.col-codigo, .table-clientes td.col-cnpj { font-variant-numeric: tabular-nums; } .table-clientes td.col-cnpj { white-space: nowrap; } .table-clientes col.col-codigo { width: 90px; } .table-clientes col.col-razao, .table-clientes col.col-fantasia { width: 27%; } .table-clientes col.col-cnpj { width: 160px; } .table-clientes col.col-status { width: 70px; } .table-clientes col.col-acoes { width: 230px; } .table-clientes th, .table-clientes td { padding: 7px 14px; } .botao-tabela { margin-top: 0; padding: 7px 12px; } ``` E, no `` do template (Step 3), adicionar um `` logo após a abertura da tag, antes da primeira ``, para que as larguras acima sejam aplicadas: ```html
``` - [ ] **Step 5: Rodar o teste para confirmar que passa** Run: `pytest tests/test_router_clientes.py -v` Expected: PASS em todos os testes do arquivo (existentes + o novo). - [ ] **Step 6: Rodar a suíte completa** Run: `pytest` Expected: PASS em todos os testes do projeto. - [ ] **Step 7: Commit** ```bash git add app/templates/clientes_lista.html app/static/estilo.css tests/test_router_clientes.py git commit -m "feat: ajusta colunas, alinhamento e densidade da tabela de clientes" ``` --- ## Self-Review Notes - **Spec coverage:** classe de escopo `table-clientes` (spec: "escopo do CSS"); larguras/alinhamento por coluna via `` + classes (spec: tabela de larguras/alinhamento); cabeçalhos alinhados junto com as colunas (spec: "cabeçalhos"); padding `10px→7px` e `.botao-tabela` sem margem superior (spec: "densidade"); nenhuma mudança de dado/ordenação/ paginação/permissão (spec: "sem mudança de comportamento" e "fora de escopo"). Teste cobre a classe de escopo aplicada. - **Placeholder scan:** nenhum "TBD"/"implementar depois" — HTML e CSS completos, prontos pra colar. - **Type consistency:** task única, sem assinaturas cruzando tasks.