Correção visual dashboard contábil - cliente

This commit is contained in:
Gabriel 2026-09-21 15:01:50 -03:00
parent 568d087fa6
commit 7651ae23be
4 changed files with 50 additions and 7 deletions

View File

@ -116,7 +116,23 @@
"Bash(grep -vE \"\\\\.md$\")", "Bash(grep -vE \"\\\\.md$\")",
"Bash(grep \"\\\\.md$\")", "Bash(grep \"\\\\.md$\")",
"Bash(xargs -n1 basename)", "Bash(xargs -n1 basename)",
"Bash(.venv/Scripts/python.exe -c \"import ast,sys; [ast.parse\\(open\\(f,encoding='utf-8'\\).read\\(\\)\\) for f in ['portal_api/views.py','portal_api/models.py']]; print\\(' .py intactos'\\)\")" "Bash(.venv/Scripts/python.exe -c \"import ast,sys; [ast.parse\\(open\\(f,encoding='utf-8'\\).read\\(\\)\\) for f in ['portal_api/views.py','portal_api/models.py']]; print\\(' .py intactos'\\)\")",
"Bash(mkdir -p /c/Users/Depaula/AppData/Local/Temp/claude/c--Users-Depaula-Documents-Portal/3ea0ee22-e5fd-4030-98b1-ee2e71c16ce0/scratchpad/halloween-design/project)",
"Bash(start \"\" \"C:\\\\Users\\\\Depaula\\\\AppData\\\\Local\\\\Temp\\\\claude\\\\c--Users-Depaula-Documents-Portal\\\\3ea0ee22-e5fd-4030-98b1-ee2e71c16ce0\\\\scratchpad\\\\halloween-design\\\\halloween-prototype.html\")",
"Bash(mkdir -p /c/Users/Depaula/AppData/Local/Temp/claude/c--Users-Depaula-Documents-Portal/3ea0ee22-e5fd-4030-98b1-ee2e71c16ce0/scratchpad/aniversario-design)",
"Bash(start \"\" \"C:\\\\Users\\\\Depaula\\\\AppData\\\\Local\\\\Temp\\\\claude\\\\c--Users-Depaula-Documents-Portal\\\\3ea0ee22-e5fd-4030-98b1-ee2e71c16ce0\\\\scratchpad\\\\aniversario-design\\\\aniversario-prototype.html\")",
"Bash(mkdir -p \"C:\\\\Users\\\\Depaula\\\\Documents\\\\Logos\\\\P.I.D. Logo Design Aniversário\\\\pid-marca-aniversario\" \"C:\\\\Users\\\\Depaula\\\\Documents\\\\Logos\\\\P.I.D. Logo Design Aniversário\\\\Logo intro animation Aniversário\")",
"Bash(start \"\" \"C:\\\\Users\\\\Depaula\\\\Documents\\\\Logos\\\\P.I.D. Logo Design Aniversário\\\\Logo intro animation Aniversário\\\\pid-intro-aniversario.html\")",
"Bash(start \"\" \"C:\\\\Users\\\\Depaula\\\\Documents\\\\Logos\\\\P.I.D. Logo Design Aniversário\\\\pid-marca-aniversario\\\\pid-aniversario-logo-horizontal-escuro.svg\")",
"Bash(start \"\" \"C:\\\\Users\\\\Depaula\\\\Documents\\\\Logos\\\\P.I.D. Logo Design Aniversário\\\\pid-marca-aniversario\\\\pid-aniversario-icone-escuro.svg\")",
"Bash(rm -rf \"C:\\\\Users\\\\Depaula\\\\Documents\\\\Logos\\\\P.I.D. Logo Design Aniversário\")"
],
"additionalDirectories": [
"C:\\Users\\Depaula\\AppData\\Local\\Temp\\claude\\c--Users-Depaula-Documents-Portal\\3ea0ee22-e5fd-4030-98b1-ee2e71c16ce0\\scratchpad\\halloween-design",
"C:\\Users\\Depaula\\AppData\\Local\\Temp\\claude\\c--Users-Depaula-Documents-Portal\\3ea0ee22-e5fd-4030-98b1-ee2e71c16ce0\\scratchpad",
"C:\\Users\\Depaula\\Documents\\Logos\\P.I.D. Logo Design Aniversário",
"C:\\Users\\Depaula\\Documents\\Logos\\P.I.D. Logo Design Aniversário\\pid-marca-aniversario",
"C:\\Users\\Depaula\\Documents\\Logos\\P.I.D. Logo Design Aniversário\\Logo intro animation Aniversário"
] ]
} }
} }

View File

@ -429,3 +429,9 @@ O `CLAUDE.md` desta pasta tinha virado um segundo changelog: 65% dele (129 KB de
- **Ganhou uma tabela de API** com os 22 endpoints da ferramenta, que não existia em lugar nenhum: a tabela do `CLAUDE.md` da raiz tinha (e agora tem de propósito) zero linha `contabil-*`. - **Ganhou uma tabela de API** com os 22 endpoints da ferramenta, que não existia em lugar nenhum: a tabela do `CLAUDE.md` da raiz tinha (e agora tem de propósito) zero linha `contabil-*`.
- Uma seção nova de "Riscos conhecidos e armadilhas" reúne o que antes estava espalhado: códigos de classificação fixos, as duas cópias mantidas à mão (ícones SVG, lógica de árvore), o N+1 de `total_achados_pendentes` e o fato de que testar exclusão nesta ViewSet destrói o PDF de verdade. - Uma seção nova de "Riscos conhecidos e armadilhas" reúne o que antes estava espalhado: códigos de classificação fixos, as duas cópias mantidas à mão (ícones SVG, lógica de árvore), o N+1 de `total_achados_pendentes` e o fato de que testar exclusão nesta ViewSet destrói o PDF de verdade.
- O título deste changelog passou de "Dashboard Contábil" para "Relatório Contábil" (o rename de rótulo aconteceu na rodada 120 e nunca tinha chegado aqui), e as 58 entradas passaram de `### N. Título` para `### Rodada N — Título`, o formato usado pelos outros 11 changelogs do projeto. - O título deste changelog passou de "Dashboard Contábil" para "Relatório Contábil" (o rename de rótulo aconteceu na rodada 120 e nunca tinha chegado aqui), e as 58 entradas passaram de `### N. Título` para `### Rodada N — Título`, o formato usado pelos outros 11 changelogs do projeto.
### Rodada 150 — Coluna "Observação" fixa na borda direita do relatório do cliente
Bug reportado pelo usuário: em balancetes largos (empresa com muitas contas/valores grandes), o botão "Restaurar formatação padrão" no cabeçalho "Observação" (e o ícone de observação de cada linha) ficava fora da área visível de `.dcr-tabela-wrap`, só alcançável arrastando a tabela inteira pro lado — o comentário em `dashboard-contabil-relatorio.html` que introduziu o `overflow-x:auto` do wrap (ver `CLAUDE.md` desta pasta) assumia que Balancete/D.R.E. sempre coubessem sem precisar de scroll, o que não é verdade pra toda empresa/competência.
Corrigido com `position: sticky; right: 0` na última coluna (`th`/`td.dcr-col-observacao`, nova classe) das três tabelas (Balancete, D.R.E., Análise Vertical) — a coluna some da rolagem: fica sempre visível na borda direita, aconteça o que acontecer com a largura das demais. Não se aplica à linha de observação expandida (`<td colspan>`), que não recebe a classe nova. Sem mudança de comportamento pra quem não precisa rolar (tabela estreita continua igual); a rolagem em si continua existindo como rede de segurança pras demais colunas.

View File

@ -433,6 +433,12 @@ Essa tabela pode ter bem mais colunas (Descrição + 2 por mês + Observação =
- `.dcr-tabela-wrap { overflow-x: auto }` (era `overflow:hidden`, que zerava os dois eixos; `overflow-y` continua `hidden`) e `table.dcr-tabela th { white-space: nowrap }` — sem isso o navegador espremia as colunas até quebrar o cabeçalho em 3 linhas e cortar a última coluna para fora da área visível. - `.dcr-tabela-wrap { overflow-x: auto }` (era `overflow:hidden`, que zerava os dois eixos; `overflow-y` continua `hidden`) e `table.dcr-tabela th { white-space: nowrap }` — sem isso o navegador espremia as colunas até quebrar o cabeçalho em 3 linhas e cortar a última coluna para fora da área visível.
- `.dcr-tabela--compacta` (só no `<table>` da Análise Vertical): fontes e paddings menores, ícones menores, e o filtro **`mes_curto`** no cabeçalho (`"mai/2026"` → `"mai/26"`), já que "— Valor"/"— Variação" repetido por mês era o maior consumidor de largura. Objetivo: o caso comum (3 meses) caber sem rolar. O `overflow-x` continua como rede de segurança para mais meses. - `.dcr-tabela--compacta` (só no `<table>` da Análise Vertical): fontes e paddings menores, ícones menores, e o filtro **`mes_curto`** no cabeçalho (`"mai/2026"` → `"mai/26"`), já que "— Valor"/"— Variação" repetido por mês era o maior consumidor de largura. Objetivo: o caso comum (3 meses) caber sem rolar. O `overflow-x` continua como rede de segurança para mais meses.
### Coluna "Observação" fixa na borda direita (as três tabelas)
Balancete e D.R.E. não são compactadas como a Análise Vertical (ver acima) porque a expectativa era que sempre coubessem em `.dcr-page` sem precisar rolar — na prática, uma empresa com valores grandes (muitos dígitos em Saldo Anterior/Débito/Crédito/Saldo Atual) ou plano de contas mais fundo (indentação de `nivel_px` na Descrição) pode ultrapassar a largura disponível, e nesse caso o `overflow-x:auto` do wrap entra em ação. Sem nenhum tratamento a mais, isso empurrava o botão "Restaurar formatação padrão" e o ícone de observação por linha (última coluna) pra fora da área visível — só alcançáveis arrastando a tabela pro lado, achado real do usuário contra um balancete de empresa grande.
A última `<th>`/`<td>` de cada uma das três tabelas (Balancete, D.R.E., Análise Vertical) ganhou a classe `dcr-col-observacao`, com `position: sticky; right: 0`. A coluna passa a ficar sempre colada na borda direita de `.dcr-tabela-wrap`, visível independente de quanto as outras colunas precisem rolar — sem precisar limitar largura/fonte das demais colunas (o que arriscaria regressão no caso comum, que já cabe). O fundo já vem de propriedades existentes (`background` do `th` genérico, `--dcr-row-bg` por linha no `td`), então não precisou de override de cor: como o valor de `--dcr-row-bg` é o mesmo em toda célula da mesma linha, a composição da coluna fixa sobre as células que passam por baixo dela ao rolar é visualmente idêntica a uma cor sólida. **Não se aplica** à `<tr class="dcr-obs-inline-row">` (o `<td colspan>` da observação expandida) — só a linha "normal" da conta/linha tem a classe.
### Filtros de template (`portal_api/templatetags/contabil_extras.py`) ### Filtros de template (`portal_api/templatetags/contabil_extras.py`)
Primeiro (e único) uso de template tags customizadas no projeto. `moeda`/`percentual`/`indice`/`competencia` no padrão brasileiro; `None` sempre vira "—", nunca "R$ 0,00"/"0,00%". `numero_bruto` devolve o valor cru só para o atributo `data-count` da animação, nunca para texto exibido. `mes_curto` para o cabeçalho da Análise Vertical. Primeiro (e único) uso de template tags customizadas no projeto. `moeda`/`percentual`/`indice`/`competencia` no padrão brasileiro; `None` sempre vira "—", nunca "R$ 0,00"/"0,00%". `numero_bruto` devolve o valor cru só para o atributo `data-count` da animação, nunca para texto exibido. `mes_curto` para o cabeçalho da Análise Vertical.

View File

@ -439,6 +439,21 @@
transition: background 160ms ease, opacity 160ms ease; transition: background 160ms ease, opacity 160ms ease;
} }
.dcr-th-reset-btn:hover { background: #fff; opacity: 1; } .dcr-th-reset-btn:hover { background: #fff; opacity: 1; }
/* Coluna "Observação" (última de cada tabela) fixa na borda direita de
`.dcr-tabela-wrap` durante a rolagem horizontal — em balancetes largos
(empresa com muitas contas/valores grandes), o botão "Restaurar
formatação" e o ícone de observação por linha ficavam fora da área
visível, só alcançáveis arrastando a tabela inteira. `right:0` mantém
a coluna sempre visível independente da posição do scroll; o fundo já
vem de `th`/`--dcr-row-bg` (mesma cor da própria linha), então não
precisa de um `background` extra aqui. Não se aplica à linha de
observação expandida (`<td colspan>`), que não recebe esta classe. */
.dcr-tabela th.dcr-col-observacao,
.dcr-tabela td.dcr-col-observacao {
position: sticky;
right: 0;
}
table.dcr-tabela tbody tr { transition: background 120ms ease; } table.dcr-tabela tbody tr { transition: background 120ms ease; }
tr.dcr-linha-total td { font-weight: 700; } tr.dcr-linha-total td { font-weight: 700; }
.dcr-row-in { animation: dcrFadeIn 220ms ease; } .dcr-row-in { animation: dcrFadeIn 220ms ease; }
@ -706,7 +721,7 @@
<th class="dcr-valor">Débito</th> <th class="dcr-valor">Débito</th>
<th class="dcr-valor">Crédito</th> <th class="dcr-valor">Crédito</th>
<th class="dcr-valor">Saldo Atual</th> <th class="dcr-valor">Saldo Atual</th>
<th> <th class="dcr-col-observacao">
<span class="dcr-th-linha">Observação <span class="dcr-th-linha">Observação
<button type="button" class="dcr-th-reset-btn" data-dcr-reset="dcr-balancete-body" aria-label="Restaurar formatação padrão do Balancete" title="Restaurar formatação padrão (recolher grupos como no início)"> <button type="button" class="dcr-th-reset-btn" data-dcr-reset="dcr-balancete-body" aria-label="Restaurar formatação padrão do Balancete" title="Restaurar formatação padrão (recolher grupos como no início)">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 2.64-6.36"/><path d="M3 3v6h6"/></svg> <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 2.64-6.36"/><path d="M3 3v6h6"/></svg>
@ -735,7 +750,7 @@
<td class="dcr-valor">{{ item.conta.debito|moeda }}</td> <td class="dcr-valor">{{ item.conta.debito|moeda }}</td>
<td class="dcr-valor">{{ item.conta.credito|moeda }}</td> <td class="dcr-valor">{{ item.conta.credito|moeda }}</td>
<td class="dcr-valor">{{ item.conta.saldo_atual|moeda }}</td> <td class="dcr-valor">{{ item.conta.saldo_atual|moeda }}</td>
<td> <td class="dcr-col-observacao">
{% if item.observacoes %} {% if item.observacoes %}
<button type="button" class="dcr-obs-btn" data-dcr-obs-toggle="conta-{{ item.conta.id }}" aria-label="Ver observação"> <button type="button" class="dcr-obs-btn" data-dcr-obs-toggle="conta-{{ item.conta.id }}" aria-label="Ver observação">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg> <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>
@ -797,7 +812,7 @@
</h2> </h2>
<div class="dcr-tabela-wrap"> <div class="dcr-tabela-wrap">
<table class="dcr-tabela"> <table class="dcr-tabela">
<thead><tr><th>Descrição</th><th class="dcr-valor">Valor</th><th> <thead><tr><th>Descrição</th><th class="dcr-valor">Valor</th><th class="dcr-col-observacao">
<span class="dcr-th-linha">Observação <span class="dcr-th-linha">Observação
<button type="button" class="dcr-th-reset-btn" data-dcr-reset="dcr-dre-body" aria-label="Restaurar formatação padrão da DRE" title="Restaurar formatação padrão (recolher grupos como no início)"> <button type="button" class="dcr-th-reset-btn" data-dcr-reset="dcr-dre-body" aria-label="Restaurar formatação padrão da DRE" title="Restaurar formatação padrão (recolher grupos como no início)">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 2.64-6.36"/><path d="M3 3v6h6"/></svg> <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 2.64-6.36"/><path d="M3 3v6h6"/></svg>
@ -820,7 +835,7 @@
</span> </span>
</td> </td>
<td class="dcr-valor">{{ item.linha.valor|moeda }}</td> <td class="dcr-valor">{{ item.linha.valor|moeda }}</td>
<td> <td class="dcr-col-observacao">
{% if item.observacoes %} {% if item.observacoes %}
<button type="button" class="dcr-obs-btn" data-dcr-obs-toggle="linha-{{ item.linha.id }}" aria-label="Ver observação"> <button type="button" class="dcr-obs-btn" data-dcr-obs-toggle="linha-{{ item.linha.id }}" aria-label="Ver observação">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg> <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>
@ -886,7 +901,7 @@
<th class="dcr-valor">{{ mes|mes_curto|capfirst }} — Valor</th> <th class="dcr-valor">{{ mes|mes_curto|capfirst }} — Valor</th>
<th class="dcr-valor">{{ mes|mes_curto|capfirst }} — Variação</th> <th class="dcr-valor">{{ mes|mes_curto|capfirst }} — Variação</th>
{% endfor %} {% endfor %}
<th> <th class="dcr-col-observacao">
<span class="dcr-th-linha">Observação <span class="dcr-th-linha">Observação
<button type="button" class="dcr-th-reset-btn" data-dcr-reset="dcr-av-body" aria-label="Restaurar formatação padrão da Análise Vertical" title="Restaurar formatação padrão (recolher grupos como no início)"> <button type="button" class="dcr-th-reset-btn" data-dcr-reset="dcr-av-body" aria-label="Restaurar formatação padrão da Análise Vertical" title="Restaurar formatação padrão (recolher grupos como no início)">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 2.64-6.36"/><path d="M3 3v6h6"/></svg> <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 2.64-6.36"/><path d="M3 3v6h6"/></svg>
@ -914,7 +929,7 @@
<td class="dcr-valor">{{ v.valor|moeda_av }}</td> <td class="dcr-valor">{{ v.valor|moeda_av }}</td>
<td class="dcr-valor">{{ v.percentual|percentual_av }}</td> <td class="dcr-valor">{{ v.percentual|percentual_av }}</td>
{% endfor %} {% endfor %}
<td> <td class="dcr-col-observacao">
{% if item.observacoes %} {% if item.observacoes %}
<button type="button" class="dcr-obs-btn" data-dcr-obs-toggle="av-{{ item.linha.id }}" aria-label="Ver observação"> <button type="button" class="dcr-obs-btn" data-dcr-obs-toggle="av-{{ item.linha.id }}" aria-label="Ver observação">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg> <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg>